1aaf4363eSJerin Jacob /* SPDX-License-Identifier: BSD-3-Clause
2aaf4363eSJerin Jacob * Copyright(c) 2017 Cavium, Inc
3169ca3dbSZbigniew Bodek */
4169ca3dbSZbigniew Bodek
5169ca3dbSZbigniew Bodek #include <stdbool.h>
6169ca3dbSZbigniew Bodek
7169ca3dbSZbigniew Bodek #include <rte_common.h>
8169ca3dbSZbigniew Bodek #include <rte_hexdump.h>
9169ca3dbSZbigniew Bodek #include <rte_cryptodev.h>
10af668035SAkhil Goyal #include <cryptodev_pmd.h>
114851ef2bSDavid Marchand #include <bus_vdev_driver.h>
12169ca3dbSZbigniew Bodek #include <rte_malloc.h>
13169ca3dbSZbigniew Bodek #include <rte_cpuflags.h>
14169ca3dbSZbigniew Bodek
15bde43e8aSRuifeng Wang #include "AArch64cryptolib.h"
16169ca3dbSZbigniew Bodek
17b28f28aeSDharmik Thakkar #include "armv8_pmd_private.h"
18169ca3dbSZbigniew Bodek
197a364faeSSlawomir Mrozowicz static uint8_t cryptodev_driver_id;
207a364faeSSlawomir Mrozowicz
215d2aa461SJan Blunck static int cryptodev_armv8_crypto_uninit(struct rte_vdev_device *vdev);
22169ca3dbSZbigniew Bodek
23169ca3dbSZbigniew Bodek /**
24169ca3dbSZbigniew Bodek * Pointers to the supported combined mode crypto functions are stored
25169ca3dbSZbigniew Bodek * in the static tables. Each combined (chained) cryptographic operation
26169ca3dbSZbigniew Bodek * can be described by a set of numbers:
27169ca3dbSZbigniew Bodek * - order: order of operations (cipher, auth) or (auth, cipher)
28169ca3dbSZbigniew Bodek * - direction: encryption or decryption
29169ca3dbSZbigniew Bodek * - calg: cipher algorithm such as AES_CBC, AES_CTR, etc.
30169ca3dbSZbigniew Bodek * - aalg: authentication algorithm such as SHA1, SHA256, etc.
31169ca3dbSZbigniew Bodek * - keyl: cipher key length, for example 128, 192, 256 bits
32169ca3dbSZbigniew Bodek *
33169ca3dbSZbigniew Bodek * In order to quickly acquire each function pointer based on those numbers,
34169ca3dbSZbigniew Bodek * a hierarchy of arrays is maintained. The final level, 3D array is indexed
35169ca3dbSZbigniew Bodek * by the combined mode function parameters only (cipher algorithm,
36169ca3dbSZbigniew Bodek * authentication algorithm and key length).
37169ca3dbSZbigniew Bodek *
38169ca3dbSZbigniew Bodek * This gives 3 memory accesses to obtain a function pointer instead of
39169ca3dbSZbigniew Bodek * traversing the array manually and comparing function parameters on each loop.
40169ca3dbSZbigniew Bodek *
41169ca3dbSZbigniew Bodek * +--+CRYPTO_FUNC
42169ca3dbSZbigniew Bodek * +--+ENC|
43169ca3dbSZbigniew Bodek * +--+CA|
44169ca3dbSZbigniew Bodek * | +--+DEC
45169ca3dbSZbigniew Bodek * ORDER|
46169ca3dbSZbigniew Bodek * | +--+ENC
47169ca3dbSZbigniew Bodek * +--+AC|
48169ca3dbSZbigniew Bodek * +--+DEC
49169ca3dbSZbigniew Bodek *
50169ca3dbSZbigniew Bodek */
51169ca3dbSZbigniew Bodek
52169ca3dbSZbigniew Bodek /**
53169ca3dbSZbigniew Bodek * 3D array type for ARM Combined Mode crypto functions pointers.
54169ca3dbSZbigniew Bodek * CRYPTO_CIPHER_MAX: max cipher ID number
55169ca3dbSZbigniew Bodek * CRYPTO_AUTH_MAX: max auth ID number
56169ca3dbSZbigniew Bodek * CRYPTO_CIPHER_KEYLEN_MAX: max key length ID number
57169ca3dbSZbigniew Bodek */
58169ca3dbSZbigniew Bodek typedef const crypto_func_t
59169ca3dbSZbigniew Bodek crypto_func_tbl_t[CRYPTO_CIPHER_MAX][CRYPTO_AUTH_MAX][CRYPTO_CIPHER_KEYLEN_MAX];
60169ca3dbSZbigniew Bodek
61169ca3dbSZbigniew Bodek /* Evaluate to key length definition */
62169ca3dbSZbigniew Bodek #define KEYL(keyl) (ARMV8_CRYPTO_CIPHER_KEYLEN_ ## keyl)
63169ca3dbSZbigniew Bodek
64169ca3dbSZbigniew Bodek /* Local aliases for supported ciphers */
65169ca3dbSZbigniew Bodek #define CIPH_AES_CBC RTE_CRYPTO_CIPHER_AES_CBC
66169ca3dbSZbigniew Bodek /* Local aliases for supported hashes */
67169ca3dbSZbigniew Bodek #define AUTH_SHA1_HMAC RTE_CRYPTO_AUTH_SHA1_HMAC
68169ca3dbSZbigniew Bodek #define AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC
69169ca3dbSZbigniew Bodek
70169ca3dbSZbigniew Bodek /**
71169ca3dbSZbigniew Bodek * Arrays containing pointers to particular cryptographic,
72169ca3dbSZbigniew Bodek * combined mode functions.
73169ca3dbSZbigniew Bodek * crypto_op_ca_encrypt: cipher (encrypt), authenticate
74169ca3dbSZbigniew Bodek * crypto_op_ca_decrypt: cipher (decrypt), authenticate
75169ca3dbSZbigniew Bodek * crypto_op_ac_encrypt: authenticate, cipher (encrypt)
76169ca3dbSZbigniew Bodek * crypto_op_ac_decrypt: authenticate, cipher (decrypt)
77169ca3dbSZbigniew Bodek */
78169ca3dbSZbigniew Bodek static const crypto_func_tbl_t
79169ca3dbSZbigniew Bodek crypto_op_ca_encrypt = {
80169ca3dbSZbigniew Bodek /* [cipher alg][auth alg][key length] = crypto_function, */
81bde43e8aSRuifeng Wang [CIPH_AES_CBC][AUTH_SHA1_HMAC][KEYL(128)] =
82bde43e8aSRuifeng Wang armv8_enc_aes_cbc_sha1_128,
83bde43e8aSRuifeng Wang [CIPH_AES_CBC][AUTH_SHA256_HMAC][KEYL(128)] =
84bde43e8aSRuifeng Wang armv8_enc_aes_cbc_sha256_128,
85169ca3dbSZbigniew Bodek };
86169ca3dbSZbigniew Bodek
87169ca3dbSZbigniew Bodek static const crypto_func_tbl_t
88169ca3dbSZbigniew Bodek crypto_op_ca_decrypt = {
8994b686e5SRuifeng Wang { {NULL} }
90169ca3dbSZbigniew Bodek };
91169ca3dbSZbigniew Bodek
92169ca3dbSZbigniew Bodek static const crypto_func_tbl_t
93169ca3dbSZbigniew Bodek crypto_op_ac_encrypt = {
9494b686e5SRuifeng Wang { {NULL} }
95169ca3dbSZbigniew Bodek };
96169ca3dbSZbigniew Bodek
97169ca3dbSZbigniew Bodek static const crypto_func_tbl_t
98169ca3dbSZbigniew Bodek crypto_op_ac_decrypt = {
99169ca3dbSZbigniew Bodek /* [cipher alg][auth alg][key length] = crypto_function, */
100bde43e8aSRuifeng Wang [CIPH_AES_CBC][AUTH_SHA1_HMAC][KEYL(128)] =
101bde43e8aSRuifeng Wang armv8_dec_aes_cbc_sha1_128,
102bde43e8aSRuifeng Wang [CIPH_AES_CBC][AUTH_SHA256_HMAC][KEYL(128)] =
103bde43e8aSRuifeng Wang armv8_dec_aes_cbc_sha256_128,
104169ca3dbSZbigniew Bodek };
105169ca3dbSZbigniew Bodek
106169ca3dbSZbigniew Bodek /**
107169ca3dbSZbigniew Bodek * Arrays containing pointers to particular cryptographic function sets,
108169ca3dbSZbigniew Bodek * covering given cipher operation directions (encrypt, decrypt)
109169ca3dbSZbigniew Bodek * for each order of cipher and authentication pairs.
110169ca3dbSZbigniew Bodek */
111169ca3dbSZbigniew Bodek static const crypto_func_tbl_t *
112169ca3dbSZbigniew Bodek crypto_cipher_auth[] = {
113169ca3dbSZbigniew Bodek &crypto_op_ca_encrypt,
114169ca3dbSZbigniew Bodek &crypto_op_ca_decrypt,
115169ca3dbSZbigniew Bodek NULL
116169ca3dbSZbigniew Bodek };
117169ca3dbSZbigniew Bodek
118169ca3dbSZbigniew Bodek static const crypto_func_tbl_t *
119169ca3dbSZbigniew Bodek crypto_auth_cipher[] = {
120169ca3dbSZbigniew Bodek &crypto_op_ac_encrypt,
121169ca3dbSZbigniew Bodek &crypto_op_ac_decrypt,
122169ca3dbSZbigniew Bodek NULL
123169ca3dbSZbigniew Bodek };
124169ca3dbSZbigniew Bodek
125169ca3dbSZbigniew Bodek /**
126169ca3dbSZbigniew Bodek * Top level array containing pointers to particular cryptographic
127169ca3dbSZbigniew Bodek * function sets, covering given order of chained operations.
128169ca3dbSZbigniew Bodek * crypto_cipher_auth: cipher first, authenticate after
129169ca3dbSZbigniew Bodek * crypto_auth_cipher: authenticate first, cipher after
130169ca3dbSZbigniew Bodek */
131169ca3dbSZbigniew Bodek static const crypto_func_tbl_t **
132169ca3dbSZbigniew Bodek crypto_chain_order[] = {
133169ca3dbSZbigniew Bodek crypto_cipher_auth,
134169ca3dbSZbigniew Bodek crypto_auth_cipher,
135169ca3dbSZbigniew Bodek NULL
136169ca3dbSZbigniew Bodek };
137169ca3dbSZbigniew Bodek
138169ca3dbSZbigniew Bodek /**
139169ca3dbSZbigniew Bodek * Extract particular combined mode crypto function from the 3D array.
140169ca3dbSZbigniew Bodek */
141169ca3dbSZbigniew Bodek #define CRYPTO_GET_ALGO(order, cop, calg, aalg, keyl) \
142*93998f3cSTyler Retzlaff __extension__ ({ \
143169ca3dbSZbigniew Bodek crypto_func_tbl_t *func_tbl = \
144169ca3dbSZbigniew Bodek (crypto_chain_order[(order)])[(cop)]; \
145169ca3dbSZbigniew Bodek \
146087ed975SRuifeng Wang ((calg >= CRYPTO_CIPHER_MAX) || (aalg >= CRYPTO_AUTH_MAX)) ? \
147087ed975SRuifeng Wang NULL : ((*func_tbl)[(calg)][(aalg)][KEYL(keyl)]); \
148169ca3dbSZbigniew Bodek })
149169ca3dbSZbigniew Bodek
150169ca3dbSZbigniew Bodek /*----------------------------------------------------------------------------*/
151169ca3dbSZbigniew Bodek
152169ca3dbSZbigniew Bodek /**
153169ca3dbSZbigniew Bodek * 2D array type for ARM key schedule functions pointers.
154169ca3dbSZbigniew Bodek * CRYPTO_CIPHER_MAX: max cipher ID number
155169ca3dbSZbigniew Bodek * CRYPTO_CIPHER_KEYLEN_MAX: max key length ID number
156169ca3dbSZbigniew Bodek */
157169ca3dbSZbigniew Bodek typedef const crypto_key_sched_t
158169ca3dbSZbigniew Bodek crypto_key_sched_tbl_t[CRYPTO_CIPHER_MAX][CRYPTO_CIPHER_KEYLEN_MAX];
159169ca3dbSZbigniew Bodek
160169ca3dbSZbigniew Bodek static const crypto_key_sched_tbl_t
161169ca3dbSZbigniew Bodek crypto_key_sched_encrypt = {
162169ca3dbSZbigniew Bodek /* [cipher alg][key length] = key_expand_func, */
163bde43e8aSRuifeng Wang [CIPH_AES_CBC][KEYL(128)] = armv8_expandkeys_enc_aes_cbc_128,
164169ca3dbSZbigniew Bodek };
165169ca3dbSZbigniew Bodek
166169ca3dbSZbigniew Bodek static const crypto_key_sched_tbl_t
167169ca3dbSZbigniew Bodek crypto_key_sched_decrypt = {
168169ca3dbSZbigniew Bodek /* [cipher alg][key length] = key_expand_func, */
169bde43e8aSRuifeng Wang [CIPH_AES_CBC][KEYL(128)] = armv8_expandkeys_dec_aes_cbc_128,
170169ca3dbSZbigniew Bodek };
171169ca3dbSZbigniew Bodek
172169ca3dbSZbigniew Bodek /**
173169ca3dbSZbigniew Bodek * Top level array containing pointers to particular key generation
174169ca3dbSZbigniew Bodek * function sets, covering given operation direction.
175169ca3dbSZbigniew Bodek * crypto_key_sched_encrypt: keys for encryption
176169ca3dbSZbigniew Bodek * crypto_key_sched_decrypt: keys for decryption
177169ca3dbSZbigniew Bodek */
178169ca3dbSZbigniew Bodek static const crypto_key_sched_tbl_t *
179169ca3dbSZbigniew Bodek crypto_key_sched_dir[] = {
180169ca3dbSZbigniew Bodek &crypto_key_sched_encrypt,
181169ca3dbSZbigniew Bodek &crypto_key_sched_decrypt,
182169ca3dbSZbigniew Bodek NULL
183169ca3dbSZbigniew Bodek };
184169ca3dbSZbigniew Bodek
185169ca3dbSZbigniew Bodek /**
186169ca3dbSZbigniew Bodek * Extract particular combined mode crypto function from the 3D array.
187169ca3dbSZbigniew Bodek */
188169ca3dbSZbigniew Bodek #define CRYPTO_GET_KEY_SCHED(cop, calg, keyl) \
189*93998f3cSTyler Retzlaff __extension__ ({ \
190169ca3dbSZbigniew Bodek crypto_key_sched_tbl_t *ks_tbl = crypto_key_sched_dir[(cop)]; \
191169ca3dbSZbigniew Bodek \
192087ed975SRuifeng Wang (calg >= CRYPTO_CIPHER_MAX) ? \
193087ed975SRuifeng Wang NULL : ((*ks_tbl)[(calg)][KEYL(keyl)]); \
194169ca3dbSZbigniew Bodek })
195169ca3dbSZbigniew Bodek
196169ca3dbSZbigniew Bodek /*----------------------------------------------------------------------------*/
197169ca3dbSZbigniew Bodek
198169ca3dbSZbigniew Bodek /*
199169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------
200169ca3dbSZbigniew Bodek * Session Prepare
201169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------
202169ca3dbSZbigniew Bodek */
203169ca3dbSZbigniew Bodek
204169ca3dbSZbigniew Bodek /** Get xform chain order */
205169ca3dbSZbigniew Bodek static enum armv8_crypto_chain_order
armv8_crypto_get_chain_order(const struct rte_crypto_sym_xform * xform)206169ca3dbSZbigniew Bodek armv8_crypto_get_chain_order(const struct rte_crypto_sym_xform *xform)
207169ca3dbSZbigniew Bodek {
208169ca3dbSZbigniew Bodek
209169ca3dbSZbigniew Bodek /*
210169ca3dbSZbigniew Bodek * This driver currently covers only chained operations.
211169ca3dbSZbigniew Bodek * Ignore only cipher or only authentication operations
212169ca3dbSZbigniew Bodek * or chains longer than 2 xform structures.
213169ca3dbSZbigniew Bodek */
214169ca3dbSZbigniew Bodek if (xform->next == NULL || xform->next->next != NULL)
215169ca3dbSZbigniew Bodek return ARMV8_CRYPTO_CHAIN_NOT_SUPPORTED;
216169ca3dbSZbigniew Bodek
217169ca3dbSZbigniew Bodek if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
218169ca3dbSZbigniew Bodek if (xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
219169ca3dbSZbigniew Bodek return ARMV8_CRYPTO_CHAIN_AUTH_CIPHER;
220169ca3dbSZbigniew Bodek }
221169ca3dbSZbigniew Bodek
222169ca3dbSZbigniew Bodek if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
223169ca3dbSZbigniew Bodek if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
224169ca3dbSZbigniew Bodek return ARMV8_CRYPTO_CHAIN_CIPHER_AUTH;
225169ca3dbSZbigniew Bodek }
226169ca3dbSZbigniew Bodek
227169ca3dbSZbigniew Bodek return ARMV8_CRYPTO_CHAIN_NOT_SUPPORTED;
228169ca3dbSZbigniew Bodek }
229169ca3dbSZbigniew Bodek
230169ca3dbSZbigniew Bodek static inline void
auth_hmac_pad_prepare(struct armv8_crypto_session * sess,const struct rte_crypto_sym_xform * xform)231169ca3dbSZbigniew Bodek auth_hmac_pad_prepare(struct armv8_crypto_session *sess,
232169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *xform)
233169ca3dbSZbigniew Bodek {
234169ca3dbSZbigniew Bodek size_t i;
235169ca3dbSZbigniew Bodek
236169ca3dbSZbigniew Bodek /* Generate i_key_pad and o_key_pad */
237169ca3dbSZbigniew Bodek memset(sess->auth.hmac.i_key_pad, 0, sizeof(sess->auth.hmac.i_key_pad));
238169ca3dbSZbigniew Bodek rte_memcpy(sess->auth.hmac.i_key_pad, sess->auth.hmac.key,
239169ca3dbSZbigniew Bodek xform->auth.key.length);
240169ca3dbSZbigniew Bodek memset(sess->auth.hmac.o_key_pad, 0, sizeof(sess->auth.hmac.o_key_pad));
241169ca3dbSZbigniew Bodek rte_memcpy(sess->auth.hmac.o_key_pad, sess->auth.hmac.key,
242169ca3dbSZbigniew Bodek xform->auth.key.length);
243169ca3dbSZbigniew Bodek /*
244169ca3dbSZbigniew Bodek * XOR key with IPAD/OPAD values to obtain i_key_pad
245169ca3dbSZbigniew Bodek * and o_key_pad.
246169ca3dbSZbigniew Bodek * Byte-by-byte operation may seem to be the less efficient
247169ca3dbSZbigniew Bodek * here but in fact it's the opposite.
248169ca3dbSZbigniew Bodek * The result ASM code is likely operate on NEON registers
249169ca3dbSZbigniew Bodek * (load auth key to Qx, load IPAD/OPAD to multiple
250169ca3dbSZbigniew Bodek * elements of Qy, eor 128 bits at once).
251169ca3dbSZbigniew Bodek */
252169ca3dbSZbigniew Bodek for (i = 0; i < SHA_BLOCK_MAX; i++) {
253169ca3dbSZbigniew Bodek sess->auth.hmac.i_key_pad[i] ^= HMAC_IPAD_VALUE;
254169ca3dbSZbigniew Bodek sess->auth.hmac.o_key_pad[i] ^= HMAC_OPAD_VALUE;
255169ca3dbSZbigniew Bodek }
256169ca3dbSZbigniew Bodek }
257169ca3dbSZbigniew Bodek
258169ca3dbSZbigniew Bodek static inline int
auth_set_prerequisites(struct armv8_crypto_session * sess,const struct rte_crypto_sym_xform * xform)259169ca3dbSZbigniew Bodek auth_set_prerequisites(struct armv8_crypto_session *sess,
260169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *xform)
261169ca3dbSZbigniew Bodek {
262169ca3dbSZbigniew Bodek uint8_t partial[64] = { 0 };
263169ca3dbSZbigniew Bodek int error;
264169ca3dbSZbigniew Bodek
265169ca3dbSZbigniew Bodek switch (xform->auth.algo) {
266169ca3dbSZbigniew Bodek case RTE_CRYPTO_AUTH_SHA1_HMAC:
267169ca3dbSZbigniew Bodek /*
268169ca3dbSZbigniew Bodek * Generate authentication key, i_key_pad and o_key_pad.
269169ca3dbSZbigniew Bodek */
270169ca3dbSZbigniew Bodek /* Zero memory under key */
271473174a7SSrisivasubramanian S memset(sess->auth.hmac.key, 0, SHA1_BLOCK_SIZE);
272169ca3dbSZbigniew Bodek
273169ca3dbSZbigniew Bodek /*
274169ca3dbSZbigniew Bodek * Now copy the given authentication key to the session
275473174a7SSrisivasubramanian S * key.
276169ca3dbSZbigniew Bodek */
277169ca3dbSZbigniew Bodek rte_memcpy(sess->auth.hmac.key, xform->auth.key.data,
278169ca3dbSZbigniew Bodek xform->auth.key.length);
279169ca3dbSZbigniew Bodek
280169ca3dbSZbigniew Bodek /* Prepare HMAC padding: key|pattern */
281169ca3dbSZbigniew Bodek auth_hmac_pad_prepare(sess, xform);
282169ca3dbSZbigniew Bodek /*
283169ca3dbSZbigniew Bodek * Calculate partial hash values for i_key_pad and o_key_pad.
284169ca3dbSZbigniew Bodek * Will be used as initialization state for final HMAC.
285169ca3dbSZbigniew Bodek */
286bde43e8aSRuifeng Wang error = armv8_sha1_block_partial(NULL,
287bde43e8aSRuifeng Wang sess->auth.hmac.i_key_pad,
288169ca3dbSZbigniew Bodek partial, SHA1_BLOCK_SIZE);
289169ca3dbSZbigniew Bodek if (error != 0)
290169ca3dbSZbigniew Bodek return -1;
291169ca3dbSZbigniew Bodek memcpy(sess->auth.hmac.i_key_pad, partial, SHA1_BLOCK_SIZE);
292169ca3dbSZbigniew Bodek
293bde43e8aSRuifeng Wang error = armv8_sha1_block_partial(NULL,
294bde43e8aSRuifeng Wang sess->auth.hmac.o_key_pad,
295169ca3dbSZbigniew Bodek partial, SHA1_BLOCK_SIZE);
296169ca3dbSZbigniew Bodek if (error != 0)
297169ca3dbSZbigniew Bodek return -1;
298169ca3dbSZbigniew Bodek memcpy(sess->auth.hmac.o_key_pad, partial, SHA1_BLOCK_SIZE);
299169ca3dbSZbigniew Bodek
300169ca3dbSZbigniew Bodek break;
301169ca3dbSZbigniew Bodek case RTE_CRYPTO_AUTH_SHA256_HMAC:
302169ca3dbSZbigniew Bodek /*
303169ca3dbSZbigniew Bodek * Generate authentication key, i_key_pad and o_key_pad.
304169ca3dbSZbigniew Bodek */
305169ca3dbSZbigniew Bodek /* Zero memory under key */
306473174a7SSrisivasubramanian S memset(sess->auth.hmac.key, 0, SHA256_BLOCK_SIZE);
307169ca3dbSZbigniew Bodek
308169ca3dbSZbigniew Bodek /*
309169ca3dbSZbigniew Bodek * Now copy the given authentication key to the session
310473174a7SSrisivasubramanian S * key.
311169ca3dbSZbigniew Bodek */
312169ca3dbSZbigniew Bodek rte_memcpy(sess->auth.hmac.key, xform->auth.key.data,
313169ca3dbSZbigniew Bodek xform->auth.key.length);
314169ca3dbSZbigniew Bodek
315169ca3dbSZbigniew Bodek /* Prepare HMAC padding: key|pattern */
316169ca3dbSZbigniew Bodek auth_hmac_pad_prepare(sess, xform);
317169ca3dbSZbigniew Bodek /*
318169ca3dbSZbigniew Bodek * Calculate partial hash values for i_key_pad and o_key_pad.
319169ca3dbSZbigniew Bodek * Will be used as initialization state for final HMAC.
320169ca3dbSZbigniew Bodek */
321bde43e8aSRuifeng Wang error = armv8_sha256_block_partial(NULL,
322bde43e8aSRuifeng Wang sess->auth.hmac.i_key_pad,
323169ca3dbSZbigniew Bodek partial, SHA256_BLOCK_SIZE);
324169ca3dbSZbigniew Bodek if (error != 0)
325169ca3dbSZbigniew Bodek return -1;
326169ca3dbSZbigniew Bodek memcpy(sess->auth.hmac.i_key_pad, partial, SHA256_BLOCK_SIZE);
327169ca3dbSZbigniew Bodek
328bde43e8aSRuifeng Wang error = armv8_sha256_block_partial(NULL,
329bde43e8aSRuifeng Wang sess->auth.hmac.o_key_pad,
330169ca3dbSZbigniew Bodek partial, SHA256_BLOCK_SIZE);
331169ca3dbSZbigniew Bodek if (error != 0)
332169ca3dbSZbigniew Bodek return -1;
333169ca3dbSZbigniew Bodek memcpy(sess->auth.hmac.o_key_pad, partial, SHA256_BLOCK_SIZE);
334169ca3dbSZbigniew Bodek
335169ca3dbSZbigniew Bodek break;
336169ca3dbSZbigniew Bodek default:
337169ca3dbSZbigniew Bodek break;
338169ca3dbSZbigniew Bodek }
339169ca3dbSZbigniew Bodek
340169ca3dbSZbigniew Bodek return 0;
341169ca3dbSZbigniew Bodek }
342169ca3dbSZbigniew Bodek
343169ca3dbSZbigniew Bodek static inline int
cipher_set_prerequisites(struct armv8_crypto_session * sess,const struct rte_crypto_sym_xform * xform)344169ca3dbSZbigniew Bodek cipher_set_prerequisites(struct armv8_crypto_session *sess,
345169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *xform)
346169ca3dbSZbigniew Bodek {
347169ca3dbSZbigniew Bodek crypto_key_sched_t cipher_key_sched;
348169ca3dbSZbigniew Bodek
349169ca3dbSZbigniew Bodek cipher_key_sched = sess->cipher.key_sched;
350169ca3dbSZbigniew Bodek if (likely(cipher_key_sched != NULL)) {
351169ca3dbSZbigniew Bodek /* Set up cipher session key */
352169ca3dbSZbigniew Bodek cipher_key_sched(sess->cipher.key.data, xform->cipher.key.data);
353169ca3dbSZbigniew Bodek }
354169ca3dbSZbigniew Bodek
355169ca3dbSZbigniew Bodek return 0;
356169ca3dbSZbigniew Bodek }
357169ca3dbSZbigniew Bodek
358169ca3dbSZbigniew Bodek static int
armv8_crypto_set_session_chained_parameters(struct armv8_crypto_session * sess,const struct rte_crypto_sym_xform * cipher_xform,const struct rte_crypto_sym_xform * auth_xform)359169ca3dbSZbigniew Bodek armv8_crypto_set_session_chained_parameters(struct armv8_crypto_session *sess,
360169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *cipher_xform,
361169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *auth_xform)
362169ca3dbSZbigniew Bodek {
363169ca3dbSZbigniew Bodek enum armv8_crypto_chain_order order;
364169ca3dbSZbigniew Bodek enum armv8_crypto_cipher_operation cop;
365169ca3dbSZbigniew Bodek enum rte_crypto_cipher_algorithm calg;
366169ca3dbSZbigniew Bodek enum rte_crypto_auth_algorithm aalg;
367169ca3dbSZbigniew Bodek
368169ca3dbSZbigniew Bodek /* Validate and prepare scratch order of combined operations */
369169ca3dbSZbigniew Bodek switch (sess->chain_order) {
370169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH:
371169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER:
372169ca3dbSZbigniew Bodek order = sess->chain_order;
373169ca3dbSZbigniew Bodek break;
374169ca3dbSZbigniew Bodek default:
37527391b53SPablo de Lara return -ENOTSUP;
376169ca3dbSZbigniew Bodek }
377169ca3dbSZbigniew Bodek /* Select cipher direction */
378169ca3dbSZbigniew Bodek sess->cipher.direction = cipher_xform->cipher.op;
379169ca3dbSZbigniew Bodek /* Select cipher key */
380169ca3dbSZbigniew Bodek sess->cipher.key.length = cipher_xform->cipher.key.length;
381169ca3dbSZbigniew Bodek /* Set cipher direction */
38294b686e5SRuifeng Wang switch (sess->cipher.direction) {
38394b686e5SRuifeng Wang case RTE_CRYPTO_CIPHER_OP_ENCRYPT:
38494b686e5SRuifeng Wang cop = ARMV8_CRYPTO_CIPHER_OP_ENCRYPT;
38594b686e5SRuifeng Wang break;
38694b686e5SRuifeng Wang case RTE_CRYPTO_CIPHER_OP_DECRYPT:
38794b686e5SRuifeng Wang cop = ARMV8_CRYPTO_CIPHER_OP_DECRYPT;
38894b686e5SRuifeng Wang break;
38994b686e5SRuifeng Wang default:
39094b686e5SRuifeng Wang return -ENOTSUP;
39194b686e5SRuifeng Wang }
392169ca3dbSZbigniew Bodek /* Set cipher algorithm */
393169ca3dbSZbigniew Bodek calg = cipher_xform->cipher.algo;
394169ca3dbSZbigniew Bodek
395169ca3dbSZbigniew Bodek /* Select cipher algo */
396169ca3dbSZbigniew Bodek switch (calg) {
397169ca3dbSZbigniew Bodek /* Cover supported cipher algorithms */
398169ca3dbSZbigniew Bodek case RTE_CRYPTO_CIPHER_AES_CBC:
399169ca3dbSZbigniew Bodek sess->cipher.algo = calg;
400169ca3dbSZbigniew Bodek /* IV len is always 16 bytes (block size) for AES CBC */
4010fbd75a9SPablo de Lara sess->cipher.iv.length = 16;
402169ca3dbSZbigniew Bodek break;
403169ca3dbSZbigniew Bodek default:
40427391b53SPablo de Lara return -ENOTSUP;
405169ca3dbSZbigniew Bodek }
406169ca3dbSZbigniew Bodek /* Select auth generate/verify */
407169ca3dbSZbigniew Bodek sess->auth.operation = auth_xform->auth.op;
408169ca3dbSZbigniew Bodek
409169ca3dbSZbigniew Bodek /* Select auth algo */
410169ca3dbSZbigniew Bodek switch (auth_xform->auth.algo) {
411169ca3dbSZbigniew Bodek /* Cover supported hash algorithms */
412169ca3dbSZbigniew Bodek case RTE_CRYPTO_AUTH_SHA1_HMAC:
413169ca3dbSZbigniew Bodek case RTE_CRYPTO_AUTH_SHA256_HMAC: /* Fall through */
414169ca3dbSZbigniew Bodek aalg = auth_xform->auth.algo;
415169ca3dbSZbigniew Bodek sess->auth.mode = ARMV8_CRYPTO_AUTH_AS_HMAC;
416169ca3dbSZbigniew Bodek break;
417169ca3dbSZbigniew Bodek default:
41827391b53SPablo de Lara return -ENOTSUP;
419169ca3dbSZbigniew Bodek }
420169ca3dbSZbigniew Bodek
4217f003427SPablo de Lara /* Set the digest length */
4227f003427SPablo de Lara sess->auth.digest_length = auth_xform->auth.digest_length;
4237f003427SPablo de Lara
424169ca3dbSZbigniew Bodek /* Verify supported key lengths and extract proper algorithm */
425169ca3dbSZbigniew Bodek switch (cipher_xform->cipher.key.length << 3) {
426169ca3dbSZbigniew Bodek case 128:
427169ca3dbSZbigniew Bodek sess->crypto_func =
428169ca3dbSZbigniew Bodek CRYPTO_GET_ALGO(order, cop, calg, aalg, 128);
429169ca3dbSZbigniew Bodek sess->cipher.key_sched =
430169ca3dbSZbigniew Bodek CRYPTO_GET_KEY_SCHED(cop, calg, 128);
431169ca3dbSZbigniew Bodek break;
432169ca3dbSZbigniew Bodek case 192:
433169ca3dbSZbigniew Bodek case 256:
434169ca3dbSZbigniew Bodek /* These key lengths are not supported yet */
435169ca3dbSZbigniew Bodek default: /* Fall through */
436169ca3dbSZbigniew Bodek sess->crypto_func = NULL;
437169ca3dbSZbigniew Bodek sess->cipher.key_sched = NULL;
43827391b53SPablo de Lara return -ENOTSUP;
439169ca3dbSZbigniew Bodek }
440169ca3dbSZbigniew Bodek
441087ed975SRuifeng Wang if (unlikely(sess->crypto_func == NULL ||
442087ed975SRuifeng Wang sess->cipher.key_sched == NULL)) {
443169ca3dbSZbigniew Bodek /*
444169ca3dbSZbigniew Bodek * If we got here that means that there must be a bug
445169ca3dbSZbigniew Bodek * in the algorithms selection above. Nevertheless keep
446169ca3dbSZbigniew Bodek * it here to catch bug immediately and avoid NULL pointer
447169ca3dbSZbigniew Bodek * dereference in OPs processing.
448169ca3dbSZbigniew Bodek */
449169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR(
450169ca3dbSZbigniew Bodek "No appropriate crypto function for given parameters");
451169ca3dbSZbigniew Bodek return -EINVAL;
452169ca3dbSZbigniew Bodek }
453169ca3dbSZbigniew Bodek
454169ca3dbSZbigniew Bodek /* Set up cipher session prerequisites */
455169ca3dbSZbigniew Bodek if (cipher_set_prerequisites(sess, cipher_xform) != 0)
456169ca3dbSZbigniew Bodek return -EINVAL;
457169ca3dbSZbigniew Bodek
458169ca3dbSZbigniew Bodek /* Set up authentication session prerequisites */
459169ca3dbSZbigniew Bodek if (auth_set_prerequisites(sess, auth_xform) != 0)
460169ca3dbSZbigniew Bodek return -EINVAL;
461169ca3dbSZbigniew Bodek
462169ca3dbSZbigniew Bodek return 0;
463169ca3dbSZbigniew Bodek }
464169ca3dbSZbigniew Bodek
465169ca3dbSZbigniew Bodek /** Parse crypto xform chain and set private session parameters */
466169ca3dbSZbigniew Bodek int
armv8_crypto_set_session_parameters(struct armv8_crypto_session * sess,const struct rte_crypto_sym_xform * xform)467169ca3dbSZbigniew Bodek armv8_crypto_set_session_parameters(struct armv8_crypto_session *sess,
468169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *xform)
469169ca3dbSZbigniew Bodek {
470169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *cipher_xform = NULL;
471169ca3dbSZbigniew Bodek const struct rte_crypto_sym_xform *auth_xform = NULL;
472169ca3dbSZbigniew Bodek bool is_chained_op;
473169ca3dbSZbigniew Bodek int ret;
474169ca3dbSZbigniew Bodek
475169ca3dbSZbigniew Bodek /* Filter out spurious/broken requests */
476169ca3dbSZbigniew Bodek if (xform == NULL)
477169ca3dbSZbigniew Bodek return -EINVAL;
478169ca3dbSZbigniew Bodek
479169ca3dbSZbigniew Bodek sess->chain_order = armv8_crypto_get_chain_order(xform);
480169ca3dbSZbigniew Bodek switch (sess->chain_order) {
481169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH:
482169ca3dbSZbigniew Bodek cipher_xform = xform;
483169ca3dbSZbigniew Bodek auth_xform = xform->next;
484169ca3dbSZbigniew Bodek is_chained_op = true;
485169ca3dbSZbigniew Bodek break;
486169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER:
487169ca3dbSZbigniew Bodek auth_xform = xform;
488169ca3dbSZbigniew Bodek cipher_xform = xform->next;
489169ca3dbSZbigniew Bodek is_chained_op = true;
490169ca3dbSZbigniew Bodek break;
491169ca3dbSZbigniew Bodek default:
492169ca3dbSZbigniew Bodek is_chained_op = false;
49327391b53SPablo de Lara return -ENOTSUP;
494169ca3dbSZbigniew Bodek }
495169ca3dbSZbigniew Bodek
4960fbd75a9SPablo de Lara /* Set IV offset */
4970fbd75a9SPablo de Lara sess->cipher.iv.offset = cipher_xform->cipher.iv.offset;
4980fbd75a9SPablo de Lara
499169ca3dbSZbigniew Bodek if (is_chained_op) {
500169ca3dbSZbigniew Bodek ret = armv8_crypto_set_session_chained_parameters(sess,
501169ca3dbSZbigniew Bodek cipher_xform, auth_xform);
502169ca3dbSZbigniew Bodek if (unlikely(ret != 0)) {
503169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR(
504169ca3dbSZbigniew Bodek "Invalid/unsupported chained (cipher/auth) parameters");
50527391b53SPablo de Lara return ret;
506169ca3dbSZbigniew Bodek }
507169ca3dbSZbigniew Bodek } else {
508169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR("Invalid/unsupported operation");
50927391b53SPablo de Lara return -ENOTSUP;
510169ca3dbSZbigniew Bodek }
511169ca3dbSZbigniew Bodek
512169ca3dbSZbigniew Bodek return 0;
513169ca3dbSZbigniew Bodek }
514169ca3dbSZbigniew Bodek
515169ca3dbSZbigniew Bodek /** Provide session for operation */
516169ca3dbSZbigniew Bodek static inline struct armv8_crypto_session *
get_session(struct armv8_crypto_qp * qp,struct rte_crypto_op * op)517169ca3dbSZbigniew Bodek get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
518169ca3dbSZbigniew Bodek {
519169ca3dbSZbigniew Bodek struct armv8_crypto_session *sess = NULL;
520169ca3dbSZbigniew Bodek
5215209df0dSPablo de Lara if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
522169ca3dbSZbigniew Bodek /* get existing session */
52370c5c3d1SSlawomir Mrozowicz if (likely(op->sym->session != NULL)) {
524bdce2564SAkhil Goyal sess = CRYPTODEV_GET_SYM_SESS_PRIV(op->sym->session);
525169ca3dbSZbigniew Bodek }
526169ca3dbSZbigniew Bodek } else {
527169ca3dbSZbigniew Bodek /* provide internal session */
528bdce2564SAkhil Goyal struct rte_cryptodev_sym_session *_sess = NULL;
529169ca3dbSZbigniew Bodek
530b3bbd9e5SSlawomir Mrozowicz if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
531b3bbd9e5SSlawomir Mrozowicz return NULL;
532169ca3dbSZbigniew Bodek
533bdce2564SAkhil Goyal sess = (struct armv8_crypto_session *)_sess->driver_priv_data;
534b3bbd9e5SSlawomir Mrozowicz
535b3bbd9e5SSlawomir Mrozowicz if (unlikely(armv8_crypto_set_session_parameters(sess,
536b3bbd9e5SSlawomir Mrozowicz op->sym->xform) != 0)) {
537169ca3dbSZbigniew Bodek rte_mempool_put(qp->sess_mp, _sess);
538169ca3dbSZbigniew Bodek sess = NULL;
539169ca3dbSZbigniew Bodek }
540b3bbd9e5SSlawomir Mrozowicz op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
541169ca3dbSZbigniew Bodek }
542169ca3dbSZbigniew Bodek
543169ca3dbSZbigniew Bodek if (unlikely(sess == NULL))
544169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
545169ca3dbSZbigniew Bodek
546169ca3dbSZbigniew Bodek return sess;
547169ca3dbSZbigniew Bodek }
548169ca3dbSZbigniew Bodek
549169ca3dbSZbigniew Bodek /*
550169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------
551169ca3dbSZbigniew Bodek * Process Operations
552169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------
553169ca3dbSZbigniew Bodek */
554169ca3dbSZbigniew Bodek
555169ca3dbSZbigniew Bodek /*----------------------------------------------------------------------------*/
556169ca3dbSZbigniew Bodek
557169ca3dbSZbigniew Bodek /** Process cipher operation */
558169ca3dbSZbigniew Bodek static inline void
process_armv8_chained_op(struct armv8_crypto_qp * qp,struct rte_crypto_op * op,struct armv8_crypto_session * sess,struct rte_mbuf * mbuf_src,struct rte_mbuf * mbuf_dst)55940705eb3SPablo de Lara process_armv8_chained_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op,
56040705eb3SPablo de Lara struct armv8_crypto_session *sess,
561169ca3dbSZbigniew Bodek struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
562169ca3dbSZbigniew Bodek {
563169ca3dbSZbigniew Bodek crypto_func_t crypto_func;
564bde43e8aSRuifeng Wang armv8_cipher_digest_t arg;
565169ca3dbSZbigniew Bodek struct rte_mbuf *m_asrc, *m_adst;
566169ca3dbSZbigniew Bodek uint8_t *csrc, *cdst;
567169ca3dbSZbigniew Bodek uint8_t *adst, *asrc;
568169ca3dbSZbigniew Bodek uint64_t clen, alen;
569169ca3dbSZbigniew Bodek int error;
570169ca3dbSZbigniew Bodek
571169ca3dbSZbigniew Bodek clen = op->sym->cipher.data.length;
572169ca3dbSZbigniew Bodek alen = op->sym->auth.data.length;
573169ca3dbSZbigniew Bodek
574169ca3dbSZbigniew Bodek csrc = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
575169ca3dbSZbigniew Bodek op->sym->cipher.data.offset);
576169ca3dbSZbigniew Bodek cdst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
577169ca3dbSZbigniew Bodek op->sym->cipher.data.offset);
578169ca3dbSZbigniew Bodek
579169ca3dbSZbigniew Bodek switch (sess->chain_order) {
580169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH:
581169ca3dbSZbigniew Bodek m_asrc = m_adst = mbuf_dst;
582169ca3dbSZbigniew Bodek break;
583169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER:
584169ca3dbSZbigniew Bodek m_asrc = mbuf_src;
585169ca3dbSZbigniew Bodek m_adst = mbuf_dst;
586169ca3dbSZbigniew Bodek break;
587169ca3dbSZbigniew Bodek default:
588169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
589169ca3dbSZbigniew Bodek return;
590169ca3dbSZbigniew Bodek }
591169ca3dbSZbigniew Bodek asrc = rte_pktmbuf_mtod_offset(m_asrc, uint8_t *,
592169ca3dbSZbigniew Bodek op->sym->auth.data.offset);
593169ca3dbSZbigniew Bodek
594169ca3dbSZbigniew Bodek switch (sess->auth.mode) {
595169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_AUTH_AS_AUTH:
596169ca3dbSZbigniew Bodek /* Nothing to do here, just verify correct option */
597169ca3dbSZbigniew Bodek break;
598169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_AUTH_AS_HMAC:
599169ca3dbSZbigniew Bodek arg.digest.hmac.key = sess->auth.hmac.key;
600169ca3dbSZbigniew Bodek arg.digest.hmac.i_key_pad = sess->auth.hmac.i_key_pad;
601169ca3dbSZbigniew Bodek arg.digest.hmac.o_key_pad = sess->auth.hmac.o_key_pad;
602169ca3dbSZbigniew Bodek break;
603169ca3dbSZbigniew Bodek default:
604169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
605169ca3dbSZbigniew Bodek return;
606169ca3dbSZbigniew Bodek }
607169ca3dbSZbigniew Bodek
608169ca3dbSZbigniew Bodek if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_GENERATE) {
609169ca3dbSZbigniew Bodek adst = op->sym->auth.digest.data;
610169ca3dbSZbigniew Bodek if (adst == NULL) {
611169ca3dbSZbigniew Bodek adst = rte_pktmbuf_mtod_offset(m_adst,
612169ca3dbSZbigniew Bodek uint8_t *,
613169ca3dbSZbigniew Bodek op->sym->auth.data.offset +
614169ca3dbSZbigniew Bodek op->sym->auth.data.length);
615169ca3dbSZbigniew Bodek }
616169ca3dbSZbigniew Bodek } else {
61740705eb3SPablo de Lara adst = qp->temp_digest;
618169ca3dbSZbigniew Bodek }
619169ca3dbSZbigniew Bodek
6205082f991SPablo de Lara arg.cipher.iv = rte_crypto_op_ctod_offset(op, uint8_t *,
6210fbd75a9SPablo de Lara sess->cipher.iv.offset);
622169ca3dbSZbigniew Bodek arg.cipher.key = sess->cipher.key.data;
623169ca3dbSZbigniew Bodek /* Acquire combined mode function */
624169ca3dbSZbigniew Bodek crypto_func = sess->crypto_func;
6251ee3c4b4SRuifeng Wang RTE_VERIFY(crypto_func != NULL);
626169ca3dbSZbigniew Bodek error = crypto_func(csrc, cdst, clen, asrc, adst, alen, &arg);
627169ca3dbSZbigniew Bodek if (error != 0) {
628169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
629169ca3dbSZbigniew Bodek return;
630169ca3dbSZbigniew Bodek }
631169ca3dbSZbigniew Bodek
632169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
633169ca3dbSZbigniew Bodek if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
634169ca3dbSZbigniew Bodek if (memcmp(adst, op->sym->auth.digest.data,
6357f003427SPablo de Lara sess->auth.digest_length) != 0) {
636169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
637169ca3dbSZbigniew Bodek }
638169ca3dbSZbigniew Bodek }
639169ca3dbSZbigniew Bodek }
640169ca3dbSZbigniew Bodek
641169ca3dbSZbigniew Bodek /** Process crypto operation for mbuf */
642169ca3dbSZbigniew Bodek static inline int
process_op(struct armv8_crypto_qp * qp,struct rte_crypto_op * op,struct armv8_crypto_session * sess)64340705eb3SPablo de Lara process_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op,
644169ca3dbSZbigniew Bodek struct armv8_crypto_session *sess)
645169ca3dbSZbigniew Bodek {
646169ca3dbSZbigniew Bodek struct rte_mbuf *msrc, *mdst;
647169ca3dbSZbigniew Bodek
648169ca3dbSZbigniew Bodek msrc = op->sym->m_src;
649169ca3dbSZbigniew Bodek mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
650169ca3dbSZbigniew Bodek
651169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
652169ca3dbSZbigniew Bodek
653169ca3dbSZbigniew Bodek switch (sess->chain_order) {
654169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH:
655169ca3dbSZbigniew Bodek case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER: /* Fall through */
65640705eb3SPablo de Lara process_armv8_chained_op(qp, op, sess, msrc, mdst);
657169ca3dbSZbigniew Bodek break;
658169ca3dbSZbigniew Bodek default:
659169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_ERROR;
660169ca3dbSZbigniew Bodek break;
661169ca3dbSZbigniew Bodek }
662169ca3dbSZbigniew Bodek
663169ca3dbSZbigniew Bodek /* Free session if a session-less crypto op */
6645209df0dSPablo de Lara if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
665169ca3dbSZbigniew Bodek memset(sess, 0, sizeof(struct armv8_crypto_session));
66676a4ed5bSRuifeng Wang rte_mempool_put(qp->sess_mp, op->sym->session);
667169ca3dbSZbigniew Bodek op->sym->session = NULL;
668169ca3dbSZbigniew Bodek }
669169ca3dbSZbigniew Bodek
670169ca3dbSZbigniew Bodek if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
671169ca3dbSZbigniew Bodek op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
672169ca3dbSZbigniew Bodek
673169ca3dbSZbigniew Bodek if (unlikely(op->status == RTE_CRYPTO_OP_STATUS_ERROR))
674169ca3dbSZbigniew Bodek return -1;
675169ca3dbSZbigniew Bodek
676169ca3dbSZbigniew Bodek return 0;
677169ca3dbSZbigniew Bodek }
678169ca3dbSZbigniew Bodek
679169ca3dbSZbigniew Bodek /*
680169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------
681169ca3dbSZbigniew Bodek * PMD Framework
682169ca3dbSZbigniew Bodek *------------------------------------------------------------------------------
683169ca3dbSZbigniew Bodek */
684169ca3dbSZbigniew Bodek
685169ca3dbSZbigniew Bodek /** Enqueue burst */
686169ca3dbSZbigniew Bodek static uint16_t
armv8_crypto_pmd_enqueue_burst(void * queue_pair,struct rte_crypto_op ** ops,uint16_t nb_ops)687169ca3dbSZbigniew Bodek armv8_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
688169ca3dbSZbigniew Bodek uint16_t nb_ops)
689169ca3dbSZbigniew Bodek {
690169ca3dbSZbigniew Bodek struct armv8_crypto_session *sess;
691169ca3dbSZbigniew Bodek struct armv8_crypto_qp *qp = queue_pair;
692169ca3dbSZbigniew Bodek int i, retval;
693169ca3dbSZbigniew Bodek
694169ca3dbSZbigniew Bodek for (i = 0; i < nb_ops; i++) {
695169ca3dbSZbigniew Bodek sess = get_session(qp, ops[i]);
696169ca3dbSZbigniew Bodek if (unlikely(sess == NULL))
697169ca3dbSZbigniew Bodek goto enqueue_err;
698169ca3dbSZbigniew Bodek
699169ca3dbSZbigniew Bodek retval = process_op(qp, ops[i], sess);
700169ca3dbSZbigniew Bodek if (unlikely(retval < 0))
701169ca3dbSZbigniew Bodek goto enqueue_err;
702169ca3dbSZbigniew Bodek }
703169ca3dbSZbigniew Bodek
70414fbffb0SBruce Richardson retval = rte_ring_enqueue_burst(qp->processed_ops, (void *)ops, i,
70514fbffb0SBruce Richardson NULL);
706169ca3dbSZbigniew Bodek qp->stats.enqueued_count += retval;
707169ca3dbSZbigniew Bodek
708169ca3dbSZbigniew Bodek return retval;
709169ca3dbSZbigniew Bodek
710169ca3dbSZbigniew Bodek enqueue_err:
71114fbffb0SBruce Richardson retval = rte_ring_enqueue_burst(qp->processed_ops, (void *)ops, i,
71214fbffb0SBruce Richardson NULL);
713169ca3dbSZbigniew Bodek if (ops[i] != NULL)
714169ca3dbSZbigniew Bodek ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
715169ca3dbSZbigniew Bodek
716169ca3dbSZbigniew Bodek qp->stats.enqueue_err_count++;
717169ca3dbSZbigniew Bodek return retval;
718169ca3dbSZbigniew Bodek }
719169ca3dbSZbigniew Bodek
720169ca3dbSZbigniew Bodek /** Dequeue burst */
721169ca3dbSZbigniew Bodek static uint16_t
armv8_crypto_pmd_dequeue_burst(void * queue_pair,struct rte_crypto_op ** ops,uint16_t nb_ops)722169ca3dbSZbigniew Bodek armv8_crypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
723169ca3dbSZbigniew Bodek uint16_t nb_ops)
724169ca3dbSZbigniew Bodek {
725169ca3dbSZbigniew Bodek struct armv8_crypto_qp *qp = queue_pair;
726169ca3dbSZbigniew Bodek
727169ca3dbSZbigniew Bodek unsigned int nb_dequeued = 0;
728169ca3dbSZbigniew Bodek
729169ca3dbSZbigniew Bodek nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops,
730ecaed092SBruce Richardson (void **)ops, nb_ops, NULL);
731169ca3dbSZbigniew Bodek qp->stats.dequeued_count += nb_dequeued;
732169ca3dbSZbigniew Bodek
733169ca3dbSZbigniew Bodek return nb_dequeued;
734169ca3dbSZbigniew Bodek }
735169ca3dbSZbigniew Bodek
736169ca3dbSZbigniew Bodek /** Create ARMv8 crypto device */
737169ca3dbSZbigniew Bodek static int
cryptodev_armv8_crypto_create(const char * name,struct rte_vdev_device * vdev,struct rte_cryptodev_pmd_init_params * init_params)738168b9e76SPablo de Lara cryptodev_armv8_crypto_create(const char *name,
739168b9e76SPablo de Lara struct rte_vdev_device *vdev,
740f2f020d2SDeclan Doherty struct rte_cryptodev_pmd_init_params *init_params)
741169ca3dbSZbigniew Bodek {
742169ca3dbSZbigniew Bodek struct rte_cryptodev *dev;
743169ca3dbSZbigniew Bodek struct armv8_crypto_private *internals;
744169ca3dbSZbigniew Bodek
745169ca3dbSZbigniew Bodek /* Check CPU for support for AES instruction set */
746169ca3dbSZbigniew Bodek if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AES)) {
747169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR(
748169ca3dbSZbigniew Bodek "AES instructions not supported by CPU");
749169ca3dbSZbigniew Bodek return -EFAULT;
750169ca3dbSZbigniew Bodek }
751169ca3dbSZbigniew Bodek
752169ca3dbSZbigniew Bodek /* Check CPU for support for SHA instruction set */
753169ca3dbSZbigniew Bodek if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_SHA1) ||
754169ca3dbSZbigniew Bodek !rte_cpu_get_flag_enabled(RTE_CPUFLAG_SHA2)) {
755169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR(
756169ca3dbSZbigniew Bodek "SHA1/SHA2 instructions not supported by CPU");
757169ca3dbSZbigniew Bodek return -EFAULT;
758169ca3dbSZbigniew Bodek }
759169ca3dbSZbigniew Bodek
760169ca3dbSZbigniew Bodek /* Check CPU for support for Advance SIMD instruction set */
761169ca3dbSZbigniew Bodek if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) {
762169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR(
763169ca3dbSZbigniew Bodek "Advanced SIMD instructions not supported by CPU");
764169ca3dbSZbigniew Bodek return -EFAULT;
765169ca3dbSZbigniew Bodek }
766169ca3dbSZbigniew Bodek
767f2f020d2SDeclan Doherty dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params);
768169ca3dbSZbigniew Bodek if (dev == NULL) {
769169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR("failed to create cryptodev vdev");
770169ca3dbSZbigniew Bodek goto init_error;
771169ca3dbSZbigniew Bodek }
772169ca3dbSZbigniew Bodek
7737a364faeSSlawomir Mrozowicz dev->driver_id = cryptodev_driver_id;
774169ca3dbSZbigniew Bodek dev->dev_ops = rte_armv8_crypto_pmd_ops;
775169ca3dbSZbigniew Bodek
776169ca3dbSZbigniew Bodek /* register rx/tx burst functions for data path */
777169ca3dbSZbigniew Bodek dev->dequeue_burst = armv8_crypto_pmd_dequeue_burst;
778169ca3dbSZbigniew Bodek dev->enqueue_burst = armv8_crypto_pmd_enqueue_burst;
779169ca3dbSZbigniew Bodek
780169ca3dbSZbigniew Bodek dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
781c2fec022SZbigniew Bodek RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
782c2fec022SZbigniew Bodek RTE_CRYPTODEV_FF_CPU_NEON |
783b3aaf24dSPablo de Lara RTE_CRYPTODEV_FF_CPU_ARM_CE |
784b3aaf24dSPablo de Lara RTE_CRYPTODEV_FF_SYM_SESSIONLESS;
785169ca3dbSZbigniew Bodek
786169ca3dbSZbigniew Bodek internals = dev->data->dev_private;
787169ca3dbSZbigniew Bodek
788169ca3dbSZbigniew Bodek internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
789169ca3dbSZbigniew Bodek
790d54c72ecSAkhil Goyal rte_cryptodev_pmd_probing_finish(dev);
791d54c72ecSAkhil Goyal
792169ca3dbSZbigniew Bodek return 0;
793169ca3dbSZbigniew Bodek
794169ca3dbSZbigniew Bodek init_error:
795169ca3dbSZbigniew Bodek ARMV8_CRYPTO_LOG_ERR(
796169ca3dbSZbigniew Bodek "driver %s: cryptodev_armv8_crypto_create failed",
797169ca3dbSZbigniew Bodek init_params->name);
798169ca3dbSZbigniew Bodek
7995d2aa461SJan Blunck cryptodev_armv8_crypto_uninit(vdev);
800169ca3dbSZbigniew Bodek return -EFAULT;
801169ca3dbSZbigniew Bodek }
802169ca3dbSZbigniew Bodek
803169ca3dbSZbigniew Bodek /** Initialise ARMv8 crypto device */
804169ca3dbSZbigniew Bodek static int
cryptodev_armv8_crypto_init(struct rte_vdev_device * vdev)8055d2aa461SJan Blunck cryptodev_armv8_crypto_init(struct rte_vdev_device *vdev)
806169ca3dbSZbigniew Bodek {
807f2f020d2SDeclan Doherty struct rte_cryptodev_pmd_init_params init_params = {
808f2f020d2SDeclan Doherty "",
809f2f020d2SDeclan Doherty sizeof(struct armv8_crypto_private),
810169ca3dbSZbigniew Bodek rte_socket_id(),
811e1fc5b76SPablo de Lara RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
812169ca3dbSZbigniew Bodek };
8135d2aa461SJan Blunck const char *name;
8145d2aa461SJan Blunck const char *input_args;
815169ca3dbSZbigniew Bodek
8165d2aa461SJan Blunck name = rte_vdev_device_name(vdev);
8177e214771SPablo de Lara if (name == NULL)
8187e214771SPablo de Lara return -EINVAL;
8195d2aa461SJan Blunck input_args = rte_vdev_device_args(vdev);
820f2f020d2SDeclan Doherty rte_cryptodev_pmd_parse_input_args(&init_params, input_args);
821169ca3dbSZbigniew Bodek
822168b9e76SPablo de Lara return cryptodev_armv8_crypto_create(name, vdev, &init_params);
823169ca3dbSZbigniew Bodek }
824169ca3dbSZbigniew Bodek
825169ca3dbSZbigniew Bodek /** Uninitialise ARMv8 crypto device */
826169ca3dbSZbigniew Bodek static int
cryptodev_armv8_crypto_uninit(struct rte_vdev_device * vdev)8275d2aa461SJan Blunck cryptodev_armv8_crypto_uninit(struct rte_vdev_device *vdev)
828169ca3dbSZbigniew Bodek {
829f2f020d2SDeclan Doherty struct rte_cryptodev *cryptodev;
8305d2aa461SJan Blunck const char *name;
8315d2aa461SJan Blunck
8325d2aa461SJan Blunck name = rte_vdev_device_name(vdev);
833169ca3dbSZbigniew Bodek if (name == NULL)
834169ca3dbSZbigniew Bodek return -EINVAL;
835169ca3dbSZbigniew Bodek
836a247fcd9SStephen Hemminger ARMV8_CRYPTO_LOG_INFO(
837a247fcd9SStephen Hemminger "Closing ARMv8 crypto device %s on numa socket %u",
838169ca3dbSZbigniew Bodek name, rte_socket_id());
839169ca3dbSZbigniew Bodek
840f2f020d2SDeclan Doherty cryptodev = rte_cryptodev_pmd_get_named_dev(name);
841f2f020d2SDeclan Doherty if (cryptodev == NULL)
842f2f020d2SDeclan Doherty return -ENODEV;
843f2f020d2SDeclan Doherty
844f2f020d2SDeclan Doherty return rte_cryptodev_pmd_destroy(cryptodev);
845169ca3dbSZbigniew Bodek }
846169ca3dbSZbigniew Bodek
847effd3b9fSPablo de Lara static struct rte_vdev_driver armv8_crypto_pmd_drv = {
848169ca3dbSZbigniew Bodek .probe = cryptodev_armv8_crypto_init,
849169ca3dbSZbigniew Bodek .remove = cryptodev_armv8_crypto_uninit
850169ca3dbSZbigniew Bodek };
851169ca3dbSZbigniew Bodek
852effd3b9fSPablo de Lara static struct cryptodev_driver armv8_crypto_drv;
853effd3b9fSPablo de Lara
854eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(crypto_armv8_log_type, ERR);
85528b05145SRuifeng Wang
856effd3b9fSPablo de Lara RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ARMV8_PMD, armv8_crypto_pmd_drv);
857169ca3dbSZbigniew Bodek RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_ARMV8_PMD, cryptodev_armv8_pmd);
858169ca3dbSZbigniew Bodek RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ARMV8_PMD,
859169ca3dbSZbigniew Bodek "max_nb_queue_pairs=<int> "
860169ca3dbSZbigniew Bodek "socket_id=<int>");
861f737f5ceSFiona Trahe RTE_PMD_REGISTER_CRYPTO_DRIVER(armv8_crypto_drv, armv8_crypto_pmd_drv.driver,
862effd3b9fSPablo de Lara cryptodev_driver_id);
863