test/bonding: fix RSS test when disable RSS
[dpdk.git] / drivers / crypto / ipsec_mb / pmd_aesni_mb.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2021 Intel Corporation
3  */
4
5 #include "pmd_aesni_mb_priv.h"
6
7 struct aesni_mb_op_buf_data {
8         struct rte_mbuf *m;
9         uint32_t offset;
10 };
11
12 /**
13  * Calculate the authentication pre-computes
14  *
15  * @param one_block_hash        Function pointer
16  *                              to calculate digest on ipad/opad
17  * @param ipad                  Inner pad output byte array
18  * @param opad                  Outer pad output byte array
19  * @param hkey                  Authentication key
20  * @param hkey_len              Authentication key length
21  * @param blocksize             Block size of selected hash algo
22  */
23 static void
24 calculate_auth_precomputes(hash_one_block_t one_block_hash,
25                 uint8_t *ipad, uint8_t *opad,
26                 const uint8_t *hkey, uint16_t hkey_len,
27                 uint16_t blocksize)
28 {
29         uint32_t i, length;
30
31         uint8_t ipad_buf[blocksize] __rte_aligned(16);
32         uint8_t opad_buf[blocksize] __rte_aligned(16);
33
34         /* Setup inner and outer pads */
35         memset(ipad_buf, HMAC_IPAD_VALUE, blocksize);
36         memset(opad_buf, HMAC_OPAD_VALUE, blocksize);
37
38         /* XOR hash key with inner and outer pads */
39         length = hkey_len > blocksize ? blocksize : hkey_len;
40
41         for (i = 0; i < length; i++) {
42                 ipad_buf[i] ^= hkey[i];
43                 opad_buf[i] ^= hkey[i];
44         }
45
46         /* Compute partial hashes */
47         (*one_block_hash)(ipad_buf, ipad);
48         (*one_block_hash)(opad_buf, opad);
49
50         /* Clean up stack */
51         memset(ipad_buf, 0, blocksize);
52         memset(opad_buf, 0, blocksize);
53 }
54
55 static inline int
56 is_aead_algo(IMB_HASH_ALG hash_alg, IMB_CIPHER_MODE cipher_mode)
57 {
58         return (hash_alg == IMB_AUTH_CHACHA20_POLY1305 ||
59                 hash_alg == IMB_AUTH_AES_CCM ||
60                 (hash_alg == IMB_AUTH_AES_GMAC &&
61                 cipher_mode == IMB_CIPHER_GCM));
62 }
63
64 /** Set session authentication parameters */
65 static int
66 aesni_mb_set_session_auth_parameters(const IMB_MGR *mb_mgr,
67                 struct aesni_mb_session *sess,
68                 const struct rte_crypto_sym_xform *xform)
69 {
70         hash_one_block_t hash_oneblock_fn = NULL;
71         unsigned int key_larger_block_size = 0;
72         uint8_t hashed_key[HMAC_MAX_BLOCK_SIZE] = { 0 };
73         uint32_t auth_precompute = 1;
74
75         if (xform == NULL) {
76                 sess->auth.algo = IMB_AUTH_NULL;
77                 return 0;
78         }
79
80         if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH) {
81                 IPSEC_MB_LOG(ERR, "Crypto xform struct not of type auth");
82                 return -1;
83         }
84
85         /* Set IV parameters */
86         sess->auth_iv.offset = xform->auth.iv.offset;
87         sess->auth_iv.length = xform->auth.iv.length;
88
89         /* Set the request digest size */
90         sess->auth.req_digest_len = xform->auth.digest_length;
91
92         /* Select auth generate/verify */
93         sess->auth.operation = xform->auth.op;
94
95         /* Set Authentication Parameters */
96         if (xform->auth.algo == RTE_CRYPTO_AUTH_NULL) {
97                 sess->auth.algo = IMB_AUTH_NULL;
98                 sess->auth.gen_digest_len = 0;
99                 return 0;
100         }
101
102         if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) {
103                 sess->auth.algo = IMB_AUTH_AES_XCBC;
104
105                 uint16_t xcbc_mac_digest_len =
106                         get_truncated_digest_byte_length(IMB_AUTH_AES_XCBC);
107                 if (sess->auth.req_digest_len != xcbc_mac_digest_len) {
108                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
109                         return -EINVAL;
110                 }
111                 sess->auth.gen_digest_len = sess->auth.req_digest_len;
112
113                 IMB_AES_XCBC_KEYEXP(mb_mgr, xform->auth.key.data,
114                                 sess->auth.xcbc.k1_expanded,
115                                 sess->auth.xcbc.k2, sess->auth.xcbc.k3);
116                 return 0;
117         }
118
119         if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_CMAC) {
120                 uint32_t dust[4*15];
121
122                 sess->auth.algo = IMB_AUTH_AES_CMAC;
123
124                 uint16_t cmac_digest_len =
125                                 get_digest_byte_length(IMB_AUTH_AES_CMAC);
126
127                 if (sess->auth.req_digest_len > cmac_digest_len) {
128                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
129                         return -EINVAL;
130                 }
131                 /*
132                  * Multi-buffer lib supports digest sizes from 4 to 16 bytes
133                  * in version 0.50 and sizes of 12 and 16 bytes,
134                  * in version 0.49.
135                  * If size requested is different, generate the full digest
136                  * (16 bytes) in a temporary location and then memcpy
137                  * the requested number of bytes.
138                  */
139                 if (sess->auth.req_digest_len < 4)
140                         sess->auth.gen_digest_len = cmac_digest_len;
141                 else
142                         sess->auth.gen_digest_len = sess->auth.req_digest_len;
143
144                 IMB_AES_KEYEXP_128(mb_mgr, xform->auth.key.data,
145                                 sess->auth.cmac.expkey, dust);
146                 IMB_AES_CMAC_SUBKEY_GEN_128(mb_mgr, sess->auth.cmac.expkey,
147                                 sess->auth.cmac.skey1, sess->auth.cmac.skey2);
148                 return 0;
149         }
150
151         if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
152                 if (xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) {
153                         sess->cipher.direction = IMB_DIR_ENCRYPT;
154                         sess->chain_order = IMB_ORDER_CIPHER_HASH;
155                 } else
156                         sess->cipher.direction = IMB_DIR_DECRYPT;
157
158                 sess->auth.algo = IMB_AUTH_AES_GMAC;
159                 if (sess->auth.req_digest_len >
160                         get_digest_byte_length(IMB_AUTH_AES_GMAC)) {
161                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
162                         return -EINVAL;
163                 }
164                 sess->auth.gen_digest_len = sess->auth.req_digest_len;
165                 sess->iv.length = xform->auth.iv.length;
166                 sess->iv.offset = xform->auth.iv.offset;
167
168                 switch (xform->auth.key.length) {
169                 case IMB_KEY_128_BYTES:
170                         IMB_AES128_GCM_PRE(mb_mgr, xform->auth.key.data,
171                                 &sess->cipher.gcm_key);
172                         sess->cipher.key_length_in_bytes = IMB_KEY_128_BYTES;
173                         break;
174                 case IMB_KEY_192_BYTES:
175                         IMB_AES192_GCM_PRE(mb_mgr, xform->auth.key.data,
176                                 &sess->cipher.gcm_key);
177                         sess->cipher.key_length_in_bytes = IMB_KEY_192_BYTES;
178                         break;
179                 case IMB_KEY_256_BYTES:
180                         IMB_AES256_GCM_PRE(mb_mgr, xform->auth.key.data,
181                                 &sess->cipher.gcm_key);
182                         sess->cipher.key_length_in_bytes = IMB_KEY_256_BYTES;
183                         break;
184                 default:
185                         IPSEC_MB_LOG(ERR, "Invalid authentication key length\n");
186                         return -EINVAL;
187                 }
188
189                 return 0;
190         }
191
192         if (xform->auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3) {
193                 if (xform->auth.key.length == 16) {
194                         sess->auth.algo = IMB_AUTH_ZUC_EIA3_BITLEN;
195                 } else if (xform->auth.key.length == 32) {
196                         sess->auth.algo = IMB_AUTH_ZUC256_EIA3_BITLEN;
197                 } else {
198                         IPSEC_MB_LOG(ERR, "Invalid authentication key length\n");
199                         return -EINVAL;
200                 }
201
202                 uint16_t zuc_eia3_digest_len =
203                         get_truncated_digest_byte_length(
204                                                 IMB_AUTH_ZUC_EIA3_BITLEN);
205                 if (sess->auth.req_digest_len != zuc_eia3_digest_len) {
206                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
207                         return -EINVAL;
208                 }
209                 sess->auth.gen_digest_len = sess->auth.req_digest_len;
210
211                 memcpy(sess->auth.zuc_auth_key, xform->auth.key.data,
212                         xform->auth.key.length);
213                 return 0;
214         } else if (xform->auth.algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2) {
215                 sess->auth.algo = IMB_AUTH_SNOW3G_UIA2_BITLEN;
216                 uint16_t snow3g_uia2_digest_len =
217                         get_truncated_digest_byte_length(
218                                                 IMB_AUTH_SNOW3G_UIA2_BITLEN);
219                 if (sess->auth.req_digest_len != snow3g_uia2_digest_len) {
220                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
221                         return -EINVAL;
222                 }
223                 sess->auth.gen_digest_len = sess->auth.req_digest_len;
224
225                 IMB_SNOW3G_INIT_KEY_SCHED(mb_mgr, xform->auth.key.data,
226                                         &sess->auth.pKeySched_snow3g_auth);
227                 return 0;
228         } else if (xform->auth.algo == RTE_CRYPTO_AUTH_KASUMI_F9) {
229                 sess->auth.algo = IMB_AUTH_KASUMI_UIA1;
230                 uint16_t kasumi_f9_digest_len =
231                         get_truncated_digest_byte_length(IMB_AUTH_KASUMI_UIA1);
232                 if (sess->auth.req_digest_len != kasumi_f9_digest_len) {
233                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
234                         return -EINVAL;
235                 }
236                 sess->auth.gen_digest_len = sess->auth.req_digest_len;
237
238                 IMB_KASUMI_INIT_F9_KEY_SCHED(mb_mgr, xform->auth.key.data,
239                                         &sess->auth.pKeySched_kasumi_auth);
240                 return 0;
241         }
242
243         switch (xform->auth.algo) {
244         case RTE_CRYPTO_AUTH_MD5_HMAC:
245                 sess->auth.algo = IMB_AUTH_MD5;
246                 hash_oneblock_fn = mb_mgr->md5_one_block;
247                 break;
248         case RTE_CRYPTO_AUTH_SHA1_HMAC:
249                 sess->auth.algo = IMB_AUTH_HMAC_SHA_1;
250                 hash_oneblock_fn = mb_mgr->sha1_one_block;
251                 if (xform->auth.key.length > get_auth_algo_blocksize(
252                                 IMB_AUTH_HMAC_SHA_1)) {
253                         IMB_SHA1(mb_mgr,
254                                 xform->auth.key.data,
255                                 xform->auth.key.length,
256                                 hashed_key);
257                         key_larger_block_size = 1;
258                 }
259                 break;
260         case RTE_CRYPTO_AUTH_SHA1:
261                 sess->auth.algo = IMB_AUTH_SHA_1;
262                 auth_precompute = 0;
263                 break;
264         case RTE_CRYPTO_AUTH_SHA224_HMAC:
265                 sess->auth.algo = IMB_AUTH_HMAC_SHA_224;
266                 hash_oneblock_fn = mb_mgr->sha224_one_block;
267                 if (xform->auth.key.length > get_auth_algo_blocksize(
268                                 IMB_AUTH_HMAC_SHA_224)) {
269                         IMB_SHA224(mb_mgr,
270                                 xform->auth.key.data,
271                                 xform->auth.key.length,
272                                 hashed_key);
273                         key_larger_block_size = 1;
274                 }
275                 break;
276         case RTE_CRYPTO_AUTH_SHA224:
277                 sess->auth.algo = IMB_AUTH_SHA_224;
278                 auth_precompute = 0;
279                 break;
280         case RTE_CRYPTO_AUTH_SHA256_HMAC:
281                 sess->auth.algo = IMB_AUTH_HMAC_SHA_256;
282                 hash_oneblock_fn = mb_mgr->sha256_one_block;
283                 if (xform->auth.key.length > get_auth_algo_blocksize(
284                                 IMB_AUTH_HMAC_SHA_256)) {
285                         IMB_SHA256(mb_mgr,
286                                 xform->auth.key.data,
287                                 xform->auth.key.length,
288                                 hashed_key);
289                         key_larger_block_size = 1;
290                 }
291                 break;
292         case RTE_CRYPTO_AUTH_SHA256:
293                 sess->auth.algo = IMB_AUTH_SHA_256;
294                 auth_precompute = 0;
295                 break;
296         case RTE_CRYPTO_AUTH_SHA384_HMAC:
297                 sess->auth.algo = IMB_AUTH_HMAC_SHA_384;
298                 hash_oneblock_fn = mb_mgr->sha384_one_block;
299                 if (xform->auth.key.length > get_auth_algo_blocksize(
300                                 IMB_AUTH_HMAC_SHA_384)) {
301                         IMB_SHA384(mb_mgr,
302                                 xform->auth.key.data,
303                                 xform->auth.key.length,
304                                 hashed_key);
305                         key_larger_block_size = 1;
306                 }
307                 break;
308         case RTE_CRYPTO_AUTH_SHA384:
309                 sess->auth.algo = IMB_AUTH_SHA_384;
310                 auth_precompute = 0;
311                 break;
312         case RTE_CRYPTO_AUTH_SHA512_HMAC:
313                 sess->auth.algo = IMB_AUTH_HMAC_SHA_512;
314                 hash_oneblock_fn = mb_mgr->sha512_one_block;
315                 if (xform->auth.key.length > get_auth_algo_blocksize(
316                                 IMB_AUTH_HMAC_SHA_512)) {
317                         IMB_SHA512(mb_mgr,
318                                 xform->auth.key.data,
319                                 xform->auth.key.length,
320                                 hashed_key);
321                         key_larger_block_size = 1;
322                 }
323                 break;
324         case RTE_CRYPTO_AUTH_SHA512:
325                 sess->auth.algo = IMB_AUTH_SHA_512;
326                 auth_precompute = 0;
327                 break;
328         default:
329                 IPSEC_MB_LOG(ERR,
330                         "Unsupported authentication algorithm selection");
331                 return -ENOTSUP;
332         }
333         uint16_t trunc_digest_size =
334                         get_truncated_digest_byte_length(sess->auth.algo);
335         uint16_t full_digest_size =
336                         get_digest_byte_length(sess->auth.algo);
337
338         if (sess->auth.req_digest_len > full_digest_size ||
339                         sess->auth.req_digest_len == 0) {
340                 IPSEC_MB_LOG(ERR, "Invalid digest size\n");
341                 return -EINVAL;
342         }
343
344         if (sess->auth.req_digest_len != trunc_digest_size &&
345                         sess->auth.req_digest_len != full_digest_size)
346                 sess->auth.gen_digest_len = full_digest_size;
347         else
348                 sess->auth.gen_digest_len = sess->auth.req_digest_len;
349
350         /* Plain SHA does not require precompute key */
351         if (auth_precompute == 0)
352                 return 0;
353
354         /* Calculate Authentication precomputes */
355         if (key_larger_block_size) {
356                 calculate_auth_precomputes(hash_oneblock_fn,
357                         sess->auth.pads.inner, sess->auth.pads.outer,
358                         hashed_key,
359                         xform->auth.key.length,
360                         get_auth_algo_blocksize(sess->auth.algo));
361         } else {
362                 calculate_auth_precomputes(hash_oneblock_fn,
363                         sess->auth.pads.inner, sess->auth.pads.outer,
364                         xform->auth.key.data,
365                         xform->auth.key.length,
366                         get_auth_algo_blocksize(sess->auth.algo));
367         }
368
369         return 0;
370 }
371
372 /** Set session cipher parameters */
373 static int
374 aesni_mb_set_session_cipher_parameters(const IMB_MGR *mb_mgr,
375                 struct aesni_mb_session *sess,
376                 const struct rte_crypto_sym_xform *xform)
377 {
378         uint8_t is_aes = 0;
379         uint8_t is_3DES = 0;
380         uint8_t is_docsis = 0;
381         uint8_t is_zuc = 0;
382         uint8_t is_snow3g = 0;
383         uint8_t is_kasumi = 0;
384
385         if (xform == NULL) {
386                 sess->cipher.mode = IMB_CIPHER_NULL;
387                 return 0;
388         }
389
390         if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) {
391                 IPSEC_MB_LOG(ERR, "Crypto xform struct not of type cipher");
392                 return -EINVAL;
393         }
394
395         /* Select cipher direction */
396         switch (xform->cipher.op) {
397         case RTE_CRYPTO_CIPHER_OP_ENCRYPT:
398                 sess->cipher.direction = IMB_DIR_ENCRYPT;
399                 break;
400         case RTE_CRYPTO_CIPHER_OP_DECRYPT:
401                 sess->cipher.direction = IMB_DIR_DECRYPT;
402                 break;
403         default:
404                 IPSEC_MB_LOG(ERR, "Invalid cipher operation parameter");
405                 return -EINVAL;
406         }
407
408         /* Select cipher mode */
409         switch (xform->cipher.algo) {
410         case RTE_CRYPTO_CIPHER_AES_CBC:
411                 sess->cipher.mode = IMB_CIPHER_CBC;
412                 is_aes = 1;
413                 break;
414         case RTE_CRYPTO_CIPHER_AES_CTR:
415                 sess->cipher.mode = IMB_CIPHER_CNTR;
416                 is_aes = 1;
417                 break;
418         case RTE_CRYPTO_CIPHER_AES_DOCSISBPI:
419                 sess->cipher.mode = IMB_CIPHER_DOCSIS_SEC_BPI;
420                 is_docsis = 1;
421                 break;
422         case RTE_CRYPTO_CIPHER_DES_CBC:
423                 sess->cipher.mode = IMB_CIPHER_DES;
424                 break;
425         case RTE_CRYPTO_CIPHER_DES_DOCSISBPI:
426                 sess->cipher.mode = IMB_CIPHER_DOCSIS_DES;
427                 break;
428         case RTE_CRYPTO_CIPHER_3DES_CBC:
429                 sess->cipher.mode = IMB_CIPHER_DES3;
430                 is_3DES = 1;
431                 break;
432         case RTE_CRYPTO_CIPHER_AES_ECB:
433                 sess->cipher.mode = IMB_CIPHER_ECB;
434                 is_aes = 1;
435                 break;
436         case RTE_CRYPTO_CIPHER_ZUC_EEA3:
437                 sess->cipher.mode = IMB_CIPHER_ZUC_EEA3;
438                 is_zuc = 1;
439                 break;
440         case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
441                 sess->cipher.mode = IMB_CIPHER_SNOW3G_UEA2_BITLEN;
442                 is_snow3g = 1;
443                 break;
444         case RTE_CRYPTO_CIPHER_KASUMI_F8:
445                 sess->cipher.mode = IMB_CIPHER_KASUMI_UEA1_BITLEN;
446                 is_kasumi = 1;
447                 break;
448         case RTE_CRYPTO_CIPHER_NULL:
449                 sess->cipher.mode = IMB_CIPHER_NULL;
450                 sess->cipher.key_length_in_bytes = 0;
451                 sess->iv.offset = xform->cipher.iv.offset;
452                 sess->iv.length = xform->cipher.iv.length;
453                 return 0;
454         default:
455                 IPSEC_MB_LOG(ERR, "Unsupported cipher mode parameter");
456                 return -ENOTSUP;
457         }
458
459         /* Set IV parameters */
460         sess->iv.offset = xform->cipher.iv.offset;
461         sess->iv.length = xform->cipher.iv.length;
462
463         /* Check key length and choose key expansion function for AES */
464         if (is_aes) {
465                 switch (xform->cipher.key.length) {
466                 case IMB_KEY_128_BYTES:
467                         sess->cipher.key_length_in_bytes = IMB_KEY_128_BYTES;
468                         IMB_AES_KEYEXP_128(mb_mgr, xform->cipher.key.data,
469                                         sess->cipher.expanded_aes_keys.encode,
470                                         sess->cipher.expanded_aes_keys.decode);
471                         break;
472                 case IMB_KEY_192_BYTES:
473                         sess->cipher.key_length_in_bytes = IMB_KEY_192_BYTES;
474                         IMB_AES_KEYEXP_192(mb_mgr, xform->cipher.key.data,
475                                         sess->cipher.expanded_aes_keys.encode,
476                                         sess->cipher.expanded_aes_keys.decode);
477                         break;
478                 case IMB_KEY_256_BYTES:
479                         sess->cipher.key_length_in_bytes = IMB_KEY_256_BYTES;
480                         IMB_AES_KEYEXP_256(mb_mgr, xform->cipher.key.data,
481                                         sess->cipher.expanded_aes_keys.encode,
482                                         sess->cipher.expanded_aes_keys.decode);
483                         break;
484                 default:
485                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
486                         return -EINVAL;
487                 }
488         } else if (is_docsis) {
489                 switch (xform->cipher.key.length) {
490                 case IMB_KEY_128_BYTES:
491                         sess->cipher.key_length_in_bytes = IMB_KEY_128_BYTES;
492                         IMB_AES_KEYEXP_128(mb_mgr, xform->cipher.key.data,
493                                         sess->cipher.expanded_aes_keys.encode,
494                                         sess->cipher.expanded_aes_keys.decode);
495                         break;
496                 case IMB_KEY_256_BYTES:
497                         sess->cipher.key_length_in_bytes = IMB_KEY_256_BYTES;
498                         IMB_AES_KEYEXP_256(mb_mgr, xform->cipher.key.data,
499                                         sess->cipher.expanded_aes_keys.encode,
500                                         sess->cipher.expanded_aes_keys.decode);
501                         break;
502                 default:
503                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
504                         return -EINVAL;
505                 }
506         } else if (is_3DES) {
507                 uint64_t *keys[3] = {sess->cipher.exp_3des_keys.key[0],
508                                 sess->cipher.exp_3des_keys.key[1],
509                                 sess->cipher.exp_3des_keys.key[2]};
510
511                 switch (xform->cipher.key.length) {
512                 case  24:
513                         IMB_DES_KEYSCHED(mb_mgr, keys[0],
514                                         xform->cipher.key.data);
515                         IMB_DES_KEYSCHED(mb_mgr, keys[1],
516                                         xform->cipher.key.data + 8);
517                         IMB_DES_KEYSCHED(mb_mgr, keys[2],
518                                         xform->cipher.key.data + 16);
519
520                         /* Initialize keys - 24 bytes: [K1-K2-K3] */
521                         sess->cipher.exp_3des_keys.ks_ptr[0] = keys[0];
522                         sess->cipher.exp_3des_keys.ks_ptr[1] = keys[1];
523                         sess->cipher.exp_3des_keys.ks_ptr[2] = keys[2];
524                         break;
525                 case 16:
526                         IMB_DES_KEYSCHED(mb_mgr, keys[0],
527                                         xform->cipher.key.data);
528                         IMB_DES_KEYSCHED(mb_mgr, keys[1],
529                                         xform->cipher.key.data + 8);
530                         /* Initialize keys - 16 bytes: [K1=K1,K2=K2,K3=K1] */
531                         sess->cipher.exp_3des_keys.ks_ptr[0] = keys[0];
532                         sess->cipher.exp_3des_keys.ks_ptr[1] = keys[1];
533                         sess->cipher.exp_3des_keys.ks_ptr[2] = keys[0];
534                         break;
535                 case 8:
536                         IMB_DES_KEYSCHED(mb_mgr, keys[0],
537                                         xform->cipher.key.data);
538
539                         /* Initialize keys - 8 bytes: [K1 = K2 = K3] */
540                         sess->cipher.exp_3des_keys.ks_ptr[0] = keys[0];
541                         sess->cipher.exp_3des_keys.ks_ptr[1] = keys[0];
542                         sess->cipher.exp_3des_keys.ks_ptr[2] = keys[0];
543                         break;
544                 default:
545                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
546                         return -EINVAL;
547                 }
548
549                 sess->cipher.key_length_in_bytes = 24;
550         } else if (is_zuc) {
551                 if (xform->cipher.key.length != 16 &&
552                                 xform->cipher.key.length != 32) {
553                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
554                         return -EINVAL;
555                 }
556                 sess->cipher.key_length_in_bytes = xform->cipher.key.length;
557                 memcpy(sess->cipher.zuc_cipher_key, xform->cipher.key.data,
558                         xform->cipher.key.length);
559         } else if (is_snow3g) {
560                 if (xform->cipher.key.length != 16) {
561                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
562                         return -EINVAL;
563                 }
564                 sess->cipher.key_length_in_bytes = 16;
565                 IMB_SNOW3G_INIT_KEY_SCHED(mb_mgr, xform->cipher.key.data,
566                                         &sess->cipher.pKeySched_snow3g_cipher);
567         } else if (is_kasumi) {
568                 if (xform->cipher.key.length != 16) {
569                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
570                         return -EINVAL;
571                 }
572                 sess->cipher.key_length_in_bytes = 16;
573                 IMB_KASUMI_INIT_F8_KEY_SCHED(mb_mgr, xform->cipher.key.data,
574                                         &sess->cipher.pKeySched_kasumi_cipher);
575         } else {
576                 if (xform->cipher.key.length != 8) {
577                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
578                         return -EINVAL;
579                 }
580                 sess->cipher.key_length_in_bytes = 8;
581
582                 IMB_DES_KEYSCHED(mb_mgr,
583                         (uint64_t *)sess->cipher.expanded_aes_keys.encode,
584                                 xform->cipher.key.data);
585                 IMB_DES_KEYSCHED(mb_mgr,
586                         (uint64_t *)sess->cipher.expanded_aes_keys.decode,
587                                 xform->cipher.key.data);
588         }
589
590         return 0;
591 }
592
593 static int
594 aesni_mb_set_session_aead_parameters(const IMB_MGR *mb_mgr,
595                 struct aesni_mb_session *sess,
596                 const struct rte_crypto_sym_xform *xform)
597 {
598         switch (xform->aead.op) {
599         case RTE_CRYPTO_AEAD_OP_ENCRYPT:
600                 sess->cipher.direction = IMB_DIR_ENCRYPT;
601                 sess->auth.operation = RTE_CRYPTO_AUTH_OP_GENERATE;
602                 break;
603         case RTE_CRYPTO_AEAD_OP_DECRYPT:
604                 sess->cipher.direction = IMB_DIR_DECRYPT;
605                 sess->auth.operation = RTE_CRYPTO_AUTH_OP_VERIFY;
606                 break;
607         default:
608                 IPSEC_MB_LOG(ERR, "Invalid aead operation parameter");
609                 return -EINVAL;
610         }
611
612         /* Set IV parameters */
613         sess->iv.offset = xform->aead.iv.offset;
614         sess->iv.length = xform->aead.iv.length;
615
616         /* Set digest sizes */
617         sess->auth.req_digest_len = xform->aead.digest_length;
618         sess->auth.gen_digest_len = sess->auth.req_digest_len;
619
620         switch (xform->aead.algo) {
621         case RTE_CRYPTO_AEAD_AES_CCM:
622                 sess->cipher.mode = IMB_CIPHER_CCM;
623                 sess->auth.algo = IMB_AUTH_AES_CCM;
624
625                 /* Check key length and choose key expansion function for AES */
626                 switch (xform->aead.key.length) {
627                 case IMB_KEY_128_BYTES:
628                         sess->cipher.key_length_in_bytes = IMB_KEY_128_BYTES;
629                         IMB_AES_KEYEXP_128(mb_mgr, xform->aead.key.data,
630                                         sess->cipher.expanded_aes_keys.encode,
631                                         sess->cipher.expanded_aes_keys.decode);
632                         break;
633                 case IMB_KEY_256_BYTES:
634                         sess->cipher.key_length_in_bytes = IMB_KEY_256_BYTES;
635                         IMB_AES_KEYEXP_256(mb_mgr, xform->aead.key.data,
636                                         sess->cipher.expanded_aes_keys.encode,
637                                         sess->cipher.expanded_aes_keys.decode);
638                         break;
639                 default:
640                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
641                         return -EINVAL;
642                 }
643
644                 /* CCM digests must be between 4 and 16 and an even number */
645                 if (sess->auth.req_digest_len < AES_CCM_DIGEST_MIN_LEN ||
646                         sess->auth.req_digest_len > AES_CCM_DIGEST_MAX_LEN ||
647                         (sess->auth.req_digest_len & 1) == 1) {
648                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
649                         return -EINVAL;
650                 }
651                 break;
652
653         case RTE_CRYPTO_AEAD_AES_GCM:
654                 sess->cipher.mode = IMB_CIPHER_GCM;
655                 sess->auth.algo = IMB_AUTH_AES_GMAC;
656
657                 switch (xform->aead.key.length) {
658                 case IMB_KEY_128_BYTES:
659                         sess->cipher.key_length_in_bytes = IMB_KEY_128_BYTES;
660                         IMB_AES128_GCM_PRE(mb_mgr, xform->aead.key.data,
661                                 &sess->cipher.gcm_key);
662                         break;
663                 case IMB_KEY_192_BYTES:
664                         sess->cipher.key_length_in_bytes = IMB_KEY_192_BYTES;
665                         IMB_AES192_GCM_PRE(mb_mgr, xform->aead.key.data,
666                                 &sess->cipher.gcm_key);
667                         break;
668                 case IMB_KEY_256_BYTES:
669                         sess->cipher.key_length_in_bytes = IMB_KEY_256_BYTES;
670                         IMB_AES256_GCM_PRE(mb_mgr, xform->aead.key.data,
671                                 &sess->cipher.gcm_key);
672                         break;
673                 default:
674                         IPSEC_MB_LOG(ERR, "Invalid cipher key length");
675                         return -EINVAL;
676                 }
677
678                 /* GCM digest size must be between 1 and 16 */
679                 if (sess->auth.req_digest_len == 0 ||
680                                 sess->auth.req_digest_len > 16) {
681                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
682                         return -EINVAL;
683                 }
684                 break;
685
686         case RTE_CRYPTO_AEAD_CHACHA20_POLY1305:
687                 sess->cipher.mode = IMB_CIPHER_CHACHA20_POLY1305;
688                 sess->auth.algo = IMB_AUTH_CHACHA20_POLY1305;
689
690                 if (xform->aead.key.length != 32) {
691                         IPSEC_MB_LOG(ERR, "Invalid key length");
692                         return -EINVAL;
693                 }
694                 sess->cipher.key_length_in_bytes = 32;
695                 memcpy(sess->cipher.expanded_aes_keys.encode,
696                         xform->aead.key.data, 32);
697                 if (sess->auth.req_digest_len != 16) {
698                         IPSEC_MB_LOG(ERR, "Invalid digest size\n");
699                         return -EINVAL;
700                 }
701                 break;
702         default:
703                 IPSEC_MB_LOG(ERR, "Unsupported aead mode parameter");
704                 return -ENOTSUP;
705         }
706
707         return 0;
708 }
709
710 /** Configure a aesni multi-buffer session from a crypto xform chain */
711 static int
712 aesni_mb_session_configure(IMB_MGR *mb_mgr,
713                 void *priv_sess,
714                 const struct rte_crypto_sym_xform *xform)
715 {
716         const struct rte_crypto_sym_xform *auth_xform = NULL;
717         const struct rte_crypto_sym_xform *cipher_xform = NULL;
718         const struct rte_crypto_sym_xform *aead_xform = NULL;
719         enum ipsec_mb_operation mode;
720         struct aesni_mb_session *sess = (struct aesni_mb_session *) priv_sess;
721         int ret;
722
723         ret = ipsec_mb_parse_xform(xform, &mode, &auth_xform,
724                                 &cipher_xform, &aead_xform);
725         if (ret)
726                 return ret;
727
728         /* Select Crypto operation - hash then cipher / cipher then hash */
729         switch (mode) {
730         case IPSEC_MB_OP_HASH_VERIFY_THEN_DECRYPT:
731                 sess->chain_order = IMB_ORDER_HASH_CIPHER;
732                 break;
733         case IPSEC_MB_OP_ENCRYPT_THEN_HASH_GEN:
734         case IPSEC_MB_OP_DECRYPT_THEN_HASH_VERIFY:
735                 sess->chain_order = IMB_ORDER_CIPHER_HASH;
736                 break;
737         case IPSEC_MB_OP_HASH_GEN_ONLY:
738         case IPSEC_MB_OP_HASH_VERIFY_ONLY:
739         case IPSEC_MB_OP_HASH_GEN_THEN_ENCRYPT:
740                 sess->chain_order = IMB_ORDER_HASH_CIPHER;
741                 break;
742         /*
743          * Multi buffer library operates only at two modes,
744          * IMB_ORDER_CIPHER_HASH and IMB_ORDER_HASH_CIPHER.
745          * When doing ciphering only, chain order depends
746          * on cipher operation: encryption is always
747          * the first operation and decryption the last one.
748          */
749         case IPSEC_MB_OP_ENCRYPT_ONLY:
750                 sess->chain_order = IMB_ORDER_CIPHER_HASH;
751                 break;
752         case IPSEC_MB_OP_DECRYPT_ONLY:
753                 sess->chain_order = IMB_ORDER_HASH_CIPHER;
754                 break;
755         case IPSEC_MB_OP_AEAD_AUTHENTICATED_ENCRYPT:
756                 sess->chain_order = IMB_ORDER_CIPHER_HASH;
757                 sess->aead.aad_len = xform->aead.aad_length;
758                 break;
759         case IPSEC_MB_OP_AEAD_AUTHENTICATED_DECRYPT:
760                 sess->chain_order = IMB_ORDER_HASH_CIPHER;
761                 sess->aead.aad_len = xform->aead.aad_length;
762                 break;
763         case IPSEC_MB_OP_NOT_SUPPORTED:
764         default:
765                 IPSEC_MB_LOG(ERR,
766                         "Unsupported operation chain order parameter");
767                 return -ENOTSUP;
768         }
769
770         /* Default IV length = 0 */
771         sess->iv.length = 0;
772         sess->auth_iv.length = 0;
773
774         ret = aesni_mb_set_session_auth_parameters(mb_mgr, sess, auth_xform);
775         if (ret != 0) {
776                 IPSEC_MB_LOG(ERR,
777                         "Invalid/unsupported authentication parameters");
778                 return ret;
779         }
780
781         ret = aesni_mb_set_session_cipher_parameters(mb_mgr, sess,
782                         cipher_xform);
783         if (ret != 0) {
784                 IPSEC_MB_LOG(ERR, "Invalid/unsupported cipher parameters");
785                 return ret;
786         }
787
788         if (aead_xform) {
789                 ret = aesni_mb_set_session_aead_parameters(mb_mgr, sess,
790                                 aead_xform);
791                 if (ret != 0) {
792                         IPSEC_MB_LOG(ERR,
793                                 "Invalid/unsupported aead parameters");
794                         return ret;
795                 }
796         }
797
798         return 0;
799 }
800
801 #ifdef AESNI_MB_DOCSIS_SEC_ENABLED
802 /** Check DOCSIS security session configuration is valid */
803 static int
804 check_docsis_sec_session(struct rte_security_session_conf *conf)
805 {
806         struct rte_crypto_sym_xform *crypto_sym = conf->crypto_xform;
807         struct rte_security_docsis_xform *docsis = &conf->docsis;
808
809         /* Downlink: CRC generate -> Cipher encrypt */
810         if (docsis->direction == RTE_SECURITY_DOCSIS_DOWNLINK) {
811
812                 if (crypto_sym != NULL &&
813                     crypto_sym->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
814                     crypto_sym->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
815                     crypto_sym->cipher.algo ==
816                                         RTE_CRYPTO_CIPHER_AES_DOCSISBPI &&
817                     (crypto_sym->cipher.key.length == IMB_KEY_128_BYTES ||
818                      crypto_sym->cipher.key.length == IMB_KEY_256_BYTES) &&
819                     crypto_sym->cipher.iv.length == IMB_AES_BLOCK_SIZE &&
820                     crypto_sym->next == NULL) {
821                         return 0;
822                 }
823         /* Uplink: Cipher decrypt -> CRC verify */
824         } else if (docsis->direction == RTE_SECURITY_DOCSIS_UPLINK) {
825
826                 if (crypto_sym != NULL &&
827                     crypto_sym->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
828                     crypto_sym->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT &&
829                     crypto_sym->cipher.algo ==
830                                         RTE_CRYPTO_CIPHER_AES_DOCSISBPI &&
831                     (crypto_sym->cipher.key.length == IMB_KEY_128_BYTES ||
832                      crypto_sym->cipher.key.length == IMB_KEY_256_BYTES) &&
833                     crypto_sym->cipher.iv.length == IMB_AES_BLOCK_SIZE &&
834                     crypto_sym->next == NULL) {
835                         return 0;
836                 }
837         }
838
839         return -EINVAL;
840 }
841
842 /** Set DOCSIS security session auth (CRC) parameters */
843 static int
844 aesni_mb_set_docsis_sec_session_auth_parameters(struct aesni_mb_session *sess,
845                 struct rte_security_docsis_xform *xform)
846 {
847         if (xform == NULL) {
848                 IPSEC_MB_LOG(ERR, "Invalid DOCSIS xform");
849                 return -EINVAL;
850         }
851
852         /* Select CRC generate/verify */
853         if (xform->direction == RTE_SECURITY_DOCSIS_UPLINK) {
854                 sess->auth.algo = IMB_AUTH_DOCSIS_CRC32;
855                 sess->auth.operation = RTE_CRYPTO_AUTH_OP_VERIFY;
856         } else if (xform->direction == RTE_SECURITY_DOCSIS_DOWNLINK) {
857                 sess->auth.algo = IMB_AUTH_DOCSIS_CRC32;
858                 sess->auth.operation = RTE_CRYPTO_AUTH_OP_GENERATE;
859         } else {
860                 IPSEC_MB_LOG(ERR, "Unsupported DOCSIS direction");
861                 return -ENOTSUP;
862         }
863
864         sess->auth.req_digest_len = RTE_ETHER_CRC_LEN;
865         sess->auth.gen_digest_len = RTE_ETHER_CRC_LEN;
866
867         return 0;
868 }
869
870 /**
871  * Parse DOCSIS security session configuration and set private session
872  * parameters
873  */
874 static int
875 aesni_mb_set_docsis_sec_session_parameters(
876                 __rte_unused struct rte_cryptodev *dev,
877                 struct rte_security_session_conf *conf,
878                 void *sess)
879 {
880         IMB_MGR  *mb_mgr = alloc_init_mb_mgr();
881         struct rte_security_docsis_xform *docsis_xform;
882         struct rte_crypto_sym_xform *cipher_xform;
883         struct aesni_mb_session *ipsec_sess = sess;
884         int ret = 0;
885
886         if (!mb_mgr)
887                 return -ENOMEM;
888
889         ret = check_docsis_sec_session(conf);
890         if (ret) {
891                 IPSEC_MB_LOG(ERR, "Unsupported DOCSIS security configuration");
892                 goto error_exit;
893         }
894
895         switch (conf->docsis.direction) {
896         case RTE_SECURITY_DOCSIS_UPLINK:
897                 ipsec_sess->chain_order = IMB_ORDER_CIPHER_HASH;
898                 docsis_xform = &conf->docsis;
899                 cipher_xform = conf->crypto_xform;
900                 break;
901         case RTE_SECURITY_DOCSIS_DOWNLINK:
902                 ipsec_sess->chain_order = IMB_ORDER_HASH_CIPHER;
903                 cipher_xform = conf->crypto_xform;
904                 docsis_xform = &conf->docsis;
905                 break;
906         default:
907                 IPSEC_MB_LOG(ERR, "Unsupported DOCSIS security configuration");
908                 ret = -EINVAL;
909                 goto error_exit;
910         }
911
912         /* Default IV length = 0 */
913         ipsec_sess->iv.length = 0;
914
915         ret = aesni_mb_set_docsis_sec_session_auth_parameters(ipsec_sess,
916                         docsis_xform);
917         if (ret != 0) {
918                 IPSEC_MB_LOG(ERR, "Invalid/unsupported DOCSIS parameters");
919                 goto error_exit;
920         }
921
922         ret = aesni_mb_set_session_cipher_parameters(mb_mgr,
923                         ipsec_sess, cipher_xform);
924
925         if (ret != 0) {
926                 IPSEC_MB_LOG(ERR, "Invalid/unsupported cipher parameters");
927                 goto error_exit;
928         }
929
930 error_exit:
931         free_mb_mgr(mb_mgr);
932         return ret;
933 }
934 #endif
935
936 static inline uint64_t
937 auth_start_offset(struct rte_crypto_op *op, struct aesni_mb_session *session,
938                 uint32_t oop, const uint32_t auth_offset,
939                 const uint32_t cipher_offset, const uint32_t auth_length,
940                 const uint32_t cipher_length)
941 {
942         struct rte_mbuf *m_src, *m_dst;
943         uint8_t *p_src, *p_dst;
944         uintptr_t u_src, u_dst;
945         uint32_t cipher_end, auth_end;
946
947         /* Only cipher then hash needs special calculation. */
948         if (!oop || session->chain_order != IMB_ORDER_CIPHER_HASH)
949                 return auth_offset;
950
951         m_src = op->sym->m_src;
952         m_dst = op->sym->m_dst;
953
954         p_src = rte_pktmbuf_mtod(m_src, uint8_t *);
955         p_dst = rte_pktmbuf_mtod(m_dst, uint8_t *);
956         u_src = (uintptr_t)p_src;
957         u_dst = (uintptr_t)p_dst + auth_offset;
958
959         /**
960          * Copy the content between cipher offset and auth offset for generating
961          * correct digest.
962          */
963         if (cipher_offset > auth_offset)
964                 memcpy(p_dst + auth_offset,
965                                 p_src + auth_offset,
966                                 cipher_offset -
967                                 auth_offset);
968
969         /**
970          * Copy the content between (cipher offset + length) and (auth offset +
971          * length) for generating correct digest
972          */
973         cipher_end = cipher_offset + cipher_length;
974         auth_end = auth_offset + auth_length;
975         if (cipher_end < auth_end)
976                 memcpy(p_dst + cipher_end, p_src + cipher_end,
977                                 auth_end - cipher_end);
978
979         /**
980          * Since intel-ipsec-mb only supports positive values,
981          * we need to deduct the correct offset between src and dst.
982          */
983
984         return u_src < u_dst ? (u_dst - u_src) :
985                         (UINT64_MAX - u_src + u_dst + 1);
986 }
987
988 static inline void
989 set_cpu_mb_job_params(IMB_JOB *job, struct aesni_mb_session *session,
990                 union rte_crypto_sym_ofs sofs, void *buf, uint32_t len,
991                 struct rte_crypto_va_iova_ptr *iv,
992                 struct rte_crypto_va_iova_ptr *aad, void *digest, void *udata)
993 {
994         /* Set crypto operation */
995         job->chain_order = session->chain_order;
996
997         /* Set cipher parameters */
998         job->cipher_direction = session->cipher.direction;
999         job->cipher_mode = session->cipher.mode;
1000
1001         job->key_len_in_bytes = session->cipher.key_length_in_bytes;
1002
1003         /* Set authentication parameters */
1004         job->hash_alg = session->auth.algo;
1005         job->iv = iv->va;
1006
1007         switch (job->hash_alg) {
1008         case IMB_AUTH_AES_XCBC:
1009                 job->u.XCBC._k1_expanded = session->auth.xcbc.k1_expanded;
1010                 job->u.XCBC._k2 = session->auth.xcbc.k2;
1011                 job->u.XCBC._k3 = session->auth.xcbc.k3;
1012
1013                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1014                 job->dec_keys = session->cipher.expanded_aes_keys.decode;
1015                 break;
1016
1017         case IMB_AUTH_AES_CCM:
1018                 job->u.CCM.aad = (uint8_t *)aad->va + 18;
1019                 job->u.CCM.aad_len_in_bytes = session->aead.aad_len;
1020                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1021                 job->dec_keys = session->cipher.expanded_aes_keys.decode;
1022                 job->iv++;
1023                 break;
1024
1025         case IMB_AUTH_AES_CMAC:
1026                 job->u.CMAC._key_expanded = session->auth.cmac.expkey;
1027                 job->u.CMAC._skey1 = session->auth.cmac.skey1;
1028                 job->u.CMAC._skey2 = session->auth.cmac.skey2;
1029                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1030                 job->dec_keys = session->cipher.expanded_aes_keys.decode;
1031                 break;
1032
1033         case IMB_AUTH_AES_GMAC:
1034                 if (session->cipher.mode == IMB_CIPHER_GCM) {
1035                         job->u.GCM.aad = aad->va;
1036                         job->u.GCM.aad_len_in_bytes = session->aead.aad_len;
1037                 } else {
1038                         /* For GMAC */
1039                         job->u.GCM.aad = buf;
1040                         job->u.GCM.aad_len_in_bytes = len;
1041                         job->cipher_mode = IMB_CIPHER_GCM;
1042                 }
1043                 job->enc_keys = &session->cipher.gcm_key;
1044                 job->dec_keys = &session->cipher.gcm_key;
1045                 break;
1046
1047         case IMB_AUTH_CHACHA20_POLY1305:
1048                 job->u.CHACHA20_POLY1305.aad = aad->va;
1049                 job->u.CHACHA20_POLY1305.aad_len_in_bytes =
1050                         session->aead.aad_len;
1051                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1052                 job->dec_keys = session->cipher.expanded_aes_keys.encode;
1053                 break;
1054         default:
1055                 job->u.HMAC._hashed_auth_key_xor_ipad =
1056                                 session->auth.pads.inner;
1057                 job->u.HMAC._hashed_auth_key_xor_opad =
1058                                 session->auth.pads.outer;
1059
1060                 if (job->cipher_mode == IMB_CIPHER_DES3) {
1061                         job->enc_keys = session->cipher.exp_3des_keys.ks_ptr;
1062                         job->dec_keys = session->cipher.exp_3des_keys.ks_ptr;
1063                 } else {
1064                         job->enc_keys = session->cipher.expanded_aes_keys.encode;
1065                         job->dec_keys = session->cipher.expanded_aes_keys.decode;
1066                 }
1067         }
1068
1069         /*
1070          * Multi-buffer library current only support returning a truncated
1071          * digest length as specified in the relevant IPsec RFCs
1072          */
1073
1074         /* Set digest location and length */
1075         job->auth_tag_output = digest;
1076         job->auth_tag_output_len_in_bytes = session->auth.gen_digest_len;
1077
1078         /* Set IV parameters */
1079         job->iv_len_in_bytes = session->iv.length;
1080
1081         /* Data Parameters */
1082         job->src = buf;
1083         job->dst = (uint8_t *)buf + sofs.ofs.cipher.head;
1084         job->cipher_start_src_offset_in_bytes = sofs.ofs.cipher.head;
1085         job->hash_start_src_offset_in_bytes = sofs.ofs.auth.head;
1086         if (job->hash_alg == IMB_AUTH_AES_GMAC &&
1087                         session->cipher.mode != IMB_CIPHER_GCM) {
1088                 job->msg_len_to_hash_in_bytes = 0;
1089                 job->msg_len_to_cipher_in_bytes = 0;
1090         } else {
1091                 job->msg_len_to_hash_in_bytes = len - sofs.ofs.auth.head -
1092                         sofs.ofs.auth.tail;
1093                 job->msg_len_to_cipher_in_bytes = len - sofs.ofs.cipher.head -
1094                         sofs.ofs.cipher.tail;
1095         }
1096
1097         job->user_data = udata;
1098 }
1099
1100 static int
1101 handle_aead_sgl_job(IMB_JOB *job, IMB_MGR *mb_mgr,
1102                 uint32_t *total_len,
1103                 struct aesni_mb_op_buf_data *src_data,
1104                 struct aesni_mb_op_buf_data *dst_data)
1105 {
1106         uint32_t data_len, part_len;
1107
1108         if (*total_len == 0) {
1109                 job->sgl_state = IMB_SGL_COMPLETE;
1110                 return 0;
1111         }
1112
1113         if (src_data->m == NULL) {
1114                 IPSEC_MB_LOG(ERR, "Invalid source buffer");
1115                 return -EINVAL;
1116         }
1117
1118         job->sgl_state = IMB_SGL_UPDATE;
1119
1120         data_len = src_data->m->data_len - src_data->offset;
1121
1122         job->src = rte_pktmbuf_mtod_offset(src_data->m, uint8_t *,
1123                         src_data->offset);
1124
1125         if (dst_data->m != NULL) {
1126                 if (dst_data->m->data_len - dst_data->offset == 0) {
1127                         dst_data->m = dst_data->m->next;
1128                         if (dst_data->m == NULL) {
1129                                 IPSEC_MB_LOG(ERR, "Invalid destination buffer");
1130                                 return -EINVAL;
1131                         }
1132                         dst_data->offset = 0;
1133                 }
1134                 part_len = RTE_MIN(data_len, (dst_data->m->data_len -
1135                                 dst_data->offset));
1136                 job->dst = rte_pktmbuf_mtod_offset(dst_data->m,
1137                                 uint8_t *, dst_data->offset);
1138                 dst_data->offset += part_len;
1139         } else {
1140                 part_len = RTE_MIN(data_len, *total_len);
1141                 job->dst = rte_pktmbuf_mtod_offset(src_data->m, uint8_t *,
1142                         src_data->offset);
1143         }
1144
1145         job->msg_len_to_cipher_in_bytes = part_len;
1146         job->msg_len_to_hash_in_bytes = part_len;
1147
1148         job = IMB_SUBMIT_JOB(mb_mgr);
1149
1150         *total_len -= part_len;
1151
1152         if (part_len != data_len) {
1153                 src_data->offset += part_len;
1154         } else {
1155                 src_data->m = src_data->m->next;
1156                 src_data->offset = 0;
1157         }
1158
1159         return 0;
1160 }
1161
1162
1163 /**
1164  * Process a crypto operation and complete a IMB_JOB job structure for
1165  * submission to the multi buffer library for processing.
1166  *
1167  * @param       qp              queue pair
1168  * @param       job             IMB_JOB structure to fill
1169  * @param       op              crypto op to process
1170  * @param       digest_idx      ID for digest to use
1171  *
1172  * @return
1173  * - 0 on success, the IMB_JOB will be filled
1174  * - -1 if invalid session, IMB_JOB will not be filled
1175  */
1176 static inline int
1177 set_mb_job_params(IMB_JOB *job, struct ipsec_mb_qp *qp,
1178                 struct rte_crypto_op *op, uint8_t *digest_idx,
1179                 IMB_MGR *mb_mgr)
1180 {
1181         struct rte_mbuf *m_src = op->sym->m_src, *m_dst;
1182         struct aesni_mb_qp_data *qp_data = ipsec_mb_get_qp_private_data(qp);
1183         struct aesni_mb_op_buf_data src_sgl = {0};
1184         struct aesni_mb_op_buf_data dst_sgl = {0};
1185         struct aesni_mb_session *session;
1186         uint32_t m_offset, oop;
1187         uint32_t auth_off_in_bytes;
1188         uint32_t ciph_off_in_bytes;
1189         uint32_t auth_len_in_bytes;
1190         uint32_t ciph_len_in_bytes;
1191         uint32_t total_len;
1192         IMB_JOB base_job;
1193         uint8_t sgl = 0;
1194         int ret;
1195
1196         session = ipsec_mb_get_session_private(qp, op);
1197         if (session == NULL) {
1198                 op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
1199                 return -1;
1200         }
1201
1202         if (op->sym->m_src->nb_segs > 1) {
1203                 if (session->cipher.mode != IMB_CIPHER_GCM
1204                                 && session->cipher.mode !=
1205                                 IMB_CIPHER_CHACHA20_POLY1305) {
1206                         op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
1207                         IPSEC_MB_LOG(ERR, "Device only supports SGL for AES-GCM"
1208                                         " or CHACHA20_POLY1305 algorithms.");
1209                         return -1;
1210                 }
1211                 sgl = 1;
1212         }
1213
1214         /* Set crypto operation */
1215         job->chain_order = session->chain_order;
1216
1217         /* Set cipher parameters */
1218         job->cipher_direction = session->cipher.direction;
1219         job->cipher_mode = session->cipher.mode;
1220
1221         job->key_len_in_bytes = session->cipher.key_length_in_bytes;
1222
1223         /* Set authentication parameters */
1224         job->hash_alg = session->auth.algo;
1225
1226         const int aead = is_aead_algo(job->hash_alg, job->cipher_mode);
1227
1228         if (job->cipher_mode == IMB_CIPHER_DES3) {
1229                 job->enc_keys = session->cipher.exp_3des_keys.ks_ptr;
1230                 job->dec_keys = session->cipher.exp_3des_keys.ks_ptr;
1231         } else {
1232                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1233                 job->dec_keys = session->cipher.expanded_aes_keys.decode;
1234         }
1235
1236         switch (job->hash_alg) {
1237         case IMB_AUTH_AES_XCBC:
1238                 job->u.XCBC._k1_expanded = session->auth.xcbc.k1_expanded;
1239                 job->u.XCBC._k2 = session->auth.xcbc.k2;
1240                 job->u.XCBC._k3 = session->auth.xcbc.k3;
1241
1242                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1243                 job->dec_keys = session->cipher.expanded_aes_keys.decode;
1244                 break;
1245
1246         case IMB_AUTH_AES_CCM:
1247                 job->u.CCM.aad = op->sym->aead.aad.data + 18;
1248                 job->u.CCM.aad_len_in_bytes = session->aead.aad_len;
1249                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1250                 job->dec_keys = session->cipher.expanded_aes_keys.decode;
1251                 break;
1252
1253         case IMB_AUTH_AES_CMAC:
1254                 job->u.CMAC._key_expanded = session->auth.cmac.expkey;
1255                 job->u.CMAC._skey1 = session->auth.cmac.skey1;
1256                 job->u.CMAC._skey2 = session->auth.cmac.skey2;
1257                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1258                 job->dec_keys = session->cipher.expanded_aes_keys.decode;
1259                 break;
1260
1261         case IMB_AUTH_AES_GMAC:
1262                 if (session->cipher.mode == IMB_CIPHER_GCM) {
1263                         job->u.GCM.aad = op->sym->aead.aad.data;
1264                         job->u.GCM.aad_len_in_bytes = session->aead.aad_len;
1265                         if (sgl) {
1266                                 job->u.GCM.ctx = &qp_data->gcm_sgl_ctx;
1267                                 job->cipher_mode = IMB_CIPHER_GCM_SGL;
1268                                 job->hash_alg = IMB_AUTH_GCM_SGL;
1269                         }
1270                 } else {
1271                         /* For GMAC */
1272                         job->u.GCM.aad = rte_pktmbuf_mtod_offset(m_src,
1273                                         uint8_t *, op->sym->auth.data.offset);
1274                         job->u.GCM.aad_len_in_bytes = op->sym->auth.data.length;
1275                         job->cipher_mode = IMB_CIPHER_GCM;
1276                 }
1277                 job->enc_keys = &session->cipher.gcm_key;
1278                 job->dec_keys = &session->cipher.gcm_key;
1279                 break;
1280         case IMB_AUTH_ZUC_EIA3_BITLEN:
1281         case IMB_AUTH_ZUC256_EIA3_BITLEN:
1282                 job->u.ZUC_EIA3._key = session->auth.zuc_auth_key;
1283                 job->u.ZUC_EIA3._iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1284                                                 session->auth_iv.offset);
1285                 break;
1286         case IMB_AUTH_SNOW3G_UIA2_BITLEN:
1287                 job->u.SNOW3G_UIA2._key = (void *)
1288                         &session->auth.pKeySched_snow3g_auth;
1289                 job->u.SNOW3G_UIA2._iv =
1290                         rte_crypto_op_ctod_offset(op, uint8_t *,
1291                                                 session->auth_iv.offset);
1292                 break;
1293         case IMB_AUTH_KASUMI_UIA1:
1294                 job->u.KASUMI_UIA1._key = (void *)
1295                         &session->auth.pKeySched_kasumi_auth;
1296                 break;
1297         case IMB_AUTH_CHACHA20_POLY1305:
1298                 job->u.CHACHA20_POLY1305.aad = op->sym->aead.aad.data;
1299                 job->u.CHACHA20_POLY1305.aad_len_in_bytes =
1300                         session->aead.aad_len;
1301                 if (sgl) {
1302                         job->u.CHACHA20_POLY1305.ctx = &qp_data->chacha_sgl_ctx;
1303                         job->cipher_mode = IMB_CIPHER_CHACHA20_POLY1305_SGL;
1304                         job->hash_alg = IMB_AUTH_CHACHA20_POLY1305_SGL;
1305                 }
1306                 job->enc_keys = session->cipher.expanded_aes_keys.encode;
1307                 job->dec_keys = session->cipher.expanded_aes_keys.encode;
1308                 break;
1309         default:
1310                 job->u.HMAC._hashed_auth_key_xor_ipad =
1311                         session->auth.pads.inner;
1312                 job->u.HMAC._hashed_auth_key_xor_opad =
1313                         session->auth.pads.outer;
1314
1315         }
1316
1317         if (aead)
1318                 m_offset = op->sym->aead.data.offset;
1319         else
1320                 m_offset = op->sym->cipher.data.offset;
1321
1322         if (job->cipher_mode == IMB_CIPHER_ZUC_EEA3) {
1323                 job->enc_keys = session->cipher.zuc_cipher_key;
1324                 job->dec_keys = session->cipher.zuc_cipher_key;
1325                 m_offset >>= 3;
1326         } else if (job->cipher_mode == IMB_CIPHER_SNOW3G_UEA2_BITLEN) {
1327                 job->enc_keys = &session->cipher.pKeySched_snow3g_cipher;
1328                 m_offset = 0;
1329         } else if (job->cipher_mode == IMB_CIPHER_KASUMI_UEA1_BITLEN) {
1330                 job->enc_keys = &session->cipher.pKeySched_kasumi_cipher;
1331                 m_offset = 0;
1332         }
1333
1334         if (!op->sym->m_dst) {
1335                 /* in-place operation */
1336                 m_dst = m_src;
1337                 oop = 0;
1338         } else if (op->sym->m_dst == op->sym->m_src) {
1339                 /* in-place operation */
1340                 m_dst = m_src;
1341                 oop = 0;
1342         } else {
1343                 /* out-of-place operation */
1344                 m_dst = op->sym->m_dst;
1345                 oop = 1;
1346         }
1347
1348         /* Set digest output location */
1349         if (job->hash_alg != IMB_AUTH_NULL &&
1350                         session->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
1351                 job->auth_tag_output = qp_data->temp_digests[*digest_idx];
1352                 *digest_idx = (*digest_idx + 1) % IMB_MAX_JOBS;
1353         } else {
1354                 if (aead)
1355                         job->auth_tag_output = op->sym->aead.digest.data;
1356                 else
1357                         job->auth_tag_output = op->sym->auth.digest.data;
1358
1359                 if (session->auth.req_digest_len !=
1360                                 session->auth.gen_digest_len) {
1361                         job->auth_tag_output =
1362                                 qp_data->temp_digests[*digest_idx];
1363                         *digest_idx = (*digest_idx + 1) % IMB_MAX_JOBS;
1364                 }
1365         }
1366         /*
1367          * Multi-buffer library current only support returning a truncated
1368          * digest length as specified in the relevant IPsec RFCs
1369          */
1370
1371         /* Set digest length */
1372         job->auth_tag_output_len_in_bytes = session->auth.gen_digest_len;
1373
1374         /* Set IV parameters */
1375         job->iv_len_in_bytes = session->iv.length;
1376
1377         /* Data Parameters */
1378         if (sgl) {
1379                 job->src = NULL;
1380                 job->dst = NULL;
1381         } else {
1382                 job->src = rte_pktmbuf_mtod(m_src, uint8_t *);
1383                 job->dst = rte_pktmbuf_mtod_offset(m_dst, uint8_t *, m_offset);
1384         }
1385
1386         switch (job->hash_alg) {
1387         case IMB_AUTH_AES_CCM:
1388                 job->hash_start_src_offset_in_bytes = op->sym->aead.data.offset;
1389                 job->msg_len_to_hash_in_bytes = op->sym->aead.data.length;
1390
1391                 job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1392                         session->iv.offset + 1);
1393                 break;
1394
1395         case IMB_AUTH_AES_GMAC:
1396                 if (session->cipher.mode == IMB_CIPHER_GCM) {
1397                         job->hash_start_src_offset_in_bytes =
1398                                         op->sym->aead.data.offset;
1399                         job->msg_len_to_hash_in_bytes =
1400                                         op->sym->aead.data.length;
1401                 } else { /* AES-GMAC only, only AAD used */
1402                         job->msg_len_to_hash_in_bytes = 0;
1403                         job->hash_start_src_offset_in_bytes = 0;
1404                 }
1405
1406                 job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1407                                 session->iv.offset);
1408                 break;
1409
1410         case IMB_AUTH_GCM_SGL:
1411         case IMB_AUTH_CHACHA20_POLY1305_SGL:
1412                 job->hash_start_src_offset_in_bytes = 0;
1413                 job->msg_len_to_hash_in_bytes = 0;
1414                 job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1415                         session->iv.offset);
1416                 break;
1417
1418         case IMB_AUTH_CHACHA20_POLY1305:
1419                 job->hash_start_src_offset_in_bytes =
1420                         op->sym->aead.data.offset;
1421                 job->msg_len_to_hash_in_bytes =
1422                                         op->sym->aead.data.length;
1423                 job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1424                                 session->iv.offset);
1425                 break;
1426         /* ZUC and SNOW3G require length in bits and offset in bytes */
1427         case IMB_AUTH_ZUC_EIA3_BITLEN:
1428         case IMB_AUTH_ZUC256_EIA3_BITLEN:
1429         case IMB_AUTH_SNOW3G_UIA2_BITLEN:
1430                 auth_off_in_bytes = op->sym->auth.data.offset >> 3;
1431                 ciph_off_in_bytes = op->sym->cipher.data.offset >> 3;
1432                 auth_len_in_bytes = op->sym->auth.data.length >> 3;
1433                 ciph_len_in_bytes = op->sym->cipher.data.length >> 3;
1434
1435                 job->hash_start_src_offset_in_bytes = auth_start_offset(op,
1436                                 session, oop, auth_off_in_bytes,
1437                                 ciph_off_in_bytes, auth_len_in_bytes,
1438                                 ciph_len_in_bytes);
1439                 job->msg_len_to_hash_in_bits = op->sym->auth.data.length;
1440
1441                 job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1442                         session->iv.offset);
1443                 break;
1444
1445         /* KASUMI requires lengths and offset in bytes */
1446         case IMB_AUTH_KASUMI_UIA1:
1447                 auth_off_in_bytes = op->sym->auth.data.offset >> 3;
1448                 ciph_off_in_bytes = op->sym->cipher.data.offset >> 3;
1449                 auth_len_in_bytes = op->sym->auth.data.length >> 3;
1450                 ciph_len_in_bytes = op->sym->cipher.data.length >> 3;
1451
1452                 job->hash_start_src_offset_in_bytes = auth_start_offset(op,
1453                                 session, oop, auth_off_in_bytes,
1454                                 ciph_off_in_bytes, auth_len_in_bytes,
1455                                 ciph_len_in_bytes);
1456                 job->msg_len_to_hash_in_bytes = auth_len_in_bytes;
1457
1458                 job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1459                         session->iv.offset);
1460                 break;
1461
1462         default:
1463                 job->hash_start_src_offset_in_bytes = auth_start_offset(op,
1464                                 session, oop, op->sym->auth.data.offset,
1465                                 op->sym->cipher.data.offset,
1466                                 op->sym->auth.data.length,
1467                                 op->sym->cipher.data.length);
1468                 job->msg_len_to_hash_in_bytes = op->sym->auth.data.length;
1469
1470                 job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1471                         session->iv.offset);
1472         }
1473
1474         switch (job->cipher_mode) {
1475         /* ZUC requires length and offset in bytes */
1476         case IMB_CIPHER_ZUC_EEA3:
1477                 job->cipher_start_src_offset_in_bytes =
1478                                         op->sym->cipher.data.offset >> 3;
1479                 job->msg_len_to_cipher_in_bytes =
1480                                         op->sym->cipher.data.length >> 3;
1481                 break;
1482         /* ZUC and SNOW3G require length and offset in bits */
1483         case IMB_CIPHER_SNOW3G_UEA2_BITLEN:
1484         case IMB_CIPHER_KASUMI_UEA1_BITLEN:
1485                 job->cipher_start_src_offset_in_bits =
1486                                         op->sym->cipher.data.offset;
1487                 job->msg_len_to_cipher_in_bits =
1488                                         op->sym->cipher.data.length;
1489                 break;
1490         case IMB_CIPHER_GCM:
1491                 if (session->cipher.mode == IMB_CIPHER_NULL) {
1492                         /* AES-GMAC only (only AAD used) */
1493                         job->msg_len_to_cipher_in_bytes = 0;
1494                         job->cipher_start_src_offset_in_bytes = 0;
1495                 } else {
1496                         job->cipher_start_src_offset_in_bytes =
1497                                         op->sym->aead.data.offset;
1498                         job->msg_len_to_cipher_in_bytes = op->sym->aead.data.length;
1499                 }
1500                 break;
1501         case IMB_CIPHER_CCM:
1502         case IMB_CIPHER_CHACHA20_POLY1305:
1503                 job->cipher_start_src_offset_in_bytes =
1504                                 op->sym->aead.data.offset;
1505                 job->msg_len_to_cipher_in_bytes = op->sym->aead.data.length;
1506                 break;
1507         case IMB_CIPHER_GCM_SGL:
1508         case IMB_CIPHER_CHACHA20_POLY1305_SGL:
1509                 job->msg_len_to_cipher_in_bytes = 0;
1510                 job->cipher_start_src_offset_in_bytes = 0;
1511                 break;
1512         default:
1513                 job->cipher_start_src_offset_in_bytes =
1514                                         op->sym->cipher.data.offset;
1515                 job->msg_len_to_cipher_in_bytes = op->sym->cipher.data.length;
1516         }
1517
1518         if (job->cipher_mode == IMB_CIPHER_NULL && oop) {
1519                 memcpy(job->dst + job->cipher_start_src_offset_in_bytes,
1520                         job->src + job->cipher_start_src_offset_in_bytes,
1521                         job->msg_len_to_cipher_in_bytes);
1522         }
1523
1524         /* Set user data to be crypto operation data struct */
1525         job->user_data = op;
1526
1527         if (sgl) {
1528                 base_job = *job;
1529                 job->sgl_state = IMB_SGL_INIT;
1530                 job = IMB_SUBMIT_JOB(mb_mgr);
1531                 total_len = op->sym->aead.data.length;
1532
1533                 src_sgl.m = m_src;
1534                 src_sgl.offset = m_offset;
1535
1536                 while (src_sgl.offset >= src_sgl.m->data_len) {
1537                         src_sgl.offset -= src_sgl.m->data_len;
1538                         src_sgl.m = src_sgl.m->next;
1539
1540                         RTE_ASSERT(src_sgl.m != NULL);
1541                 }
1542
1543                 if (oop) {
1544                         dst_sgl.m = m_dst;
1545                         dst_sgl.offset = m_offset;
1546
1547                         while (dst_sgl.offset >= dst_sgl.m->data_len) {
1548                                 dst_sgl.offset -= dst_sgl.m->data_len;
1549                                 dst_sgl.m = dst_sgl.m->next;
1550
1551                                 RTE_ASSERT(dst_sgl.m != NULL);
1552                         }
1553                 }
1554
1555                 while (job->sgl_state != IMB_SGL_COMPLETE) {
1556                         job = IMB_GET_NEXT_JOB(mb_mgr);
1557                         *job = base_job;
1558                         ret = handle_aead_sgl_job(job, mb_mgr, &total_len,
1559                                 &src_sgl, &dst_sgl);
1560                         if (ret < 0)
1561                                 return ret;
1562                 }
1563         }
1564
1565         return 0;
1566 }
1567
1568 #ifdef AESNI_MB_DOCSIS_SEC_ENABLED
1569 /**
1570  * Process a crypto operation containing a security op and complete a
1571  * IMB_JOB job structure for submission to the multi buffer library for
1572  * processing.
1573  */
1574 static inline int
1575 set_sec_mb_job_params(IMB_JOB *job, struct ipsec_mb_qp *qp,
1576                         struct rte_crypto_op *op, uint8_t *digest_idx)
1577 {
1578         struct aesni_mb_qp_data *qp_data = ipsec_mb_get_qp_private_data(qp);
1579         struct rte_mbuf *m_src, *m_dst;
1580         struct rte_crypto_sym_op *sym;
1581         struct aesni_mb_session *session = NULL;
1582
1583         if (unlikely(op->sess_type != RTE_CRYPTO_OP_SECURITY_SESSION)) {
1584                 op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
1585                 return -1;
1586         }
1587         session = (struct aesni_mb_session *)
1588                 get_sec_session_private_data(op->sym->sec_session);
1589
1590         if (unlikely(session == NULL)) {
1591                 op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
1592                 return -1;
1593         }
1594         /* Only DOCSIS protocol operations supported now */
1595         if (session->cipher.mode != IMB_CIPHER_DOCSIS_SEC_BPI ||
1596                         session->auth.algo != IMB_AUTH_DOCSIS_CRC32) {
1597                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1598                 return -1;
1599         }
1600
1601         sym = op->sym;
1602         m_src = sym->m_src;
1603
1604         if (likely(sym->m_dst == NULL || sym->m_dst == m_src)) {
1605                 /* in-place operation */
1606                 m_dst = m_src;
1607         } else {
1608                 /* out-of-place operation not supported */
1609                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1610                 return -ENOTSUP;
1611         }
1612
1613         /* Set crypto operation */
1614         job->chain_order = session->chain_order;
1615
1616         /* Set cipher parameters */
1617         job->cipher_direction = session->cipher.direction;
1618         job->cipher_mode = session->cipher.mode;
1619
1620         job->key_len_in_bytes = session->cipher.key_length_in_bytes;
1621         job->enc_keys = session->cipher.expanded_aes_keys.encode;
1622         job->dec_keys = session->cipher.expanded_aes_keys.decode;
1623
1624         /* Set IV parameters */
1625         job->iv_len_in_bytes = session->iv.length;
1626         job->iv = (uint8_t *)op + session->iv.offset;
1627
1628         /* Set authentication parameters */
1629         job->hash_alg = session->auth.algo;
1630
1631         /* Set digest output location */
1632         job->auth_tag_output = qp_data->temp_digests[*digest_idx];
1633         *digest_idx = (*digest_idx + 1) % IMB_MAX_JOBS;
1634
1635         /* Set digest length */
1636         job->auth_tag_output_len_in_bytes = session->auth.gen_digest_len;
1637
1638         /* Set data parameters */
1639         job->src = rte_pktmbuf_mtod(m_src, uint8_t *);
1640         job->dst = rte_pktmbuf_mtod_offset(m_dst, uint8_t *,
1641                                                 sym->cipher.data.offset);
1642
1643         job->cipher_start_src_offset_in_bytes = sym->cipher.data.offset;
1644         job->msg_len_to_cipher_in_bytes = sym->cipher.data.length;
1645
1646         job->hash_start_src_offset_in_bytes = sym->auth.data.offset;
1647         job->msg_len_to_hash_in_bytes = sym->auth.data.length;
1648
1649         job->user_data = op;
1650
1651         return 0;
1652 }
1653
1654 static inline void
1655 verify_docsis_sec_crc(IMB_JOB *job, uint8_t *status)
1656 {
1657         uint16_t crc_offset;
1658         uint8_t *crc;
1659
1660         if (!job->msg_len_to_hash_in_bytes)
1661                 return;
1662
1663         crc_offset = job->hash_start_src_offset_in_bytes +
1664                         job->msg_len_to_hash_in_bytes -
1665                         job->cipher_start_src_offset_in_bytes;
1666         crc = job->dst + crc_offset;
1667
1668         /* Verify CRC (at the end of the message) */
1669         if (memcmp(job->auth_tag_output, crc, RTE_ETHER_CRC_LEN) != 0)
1670                 *status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
1671 }
1672 #endif
1673
1674 static inline void
1675 verify_digest(IMB_JOB *job, void *digest, uint16_t len, uint8_t *status)
1676 {
1677         /* Verify digest if required */
1678         if (memcmp(job->auth_tag_output, digest, len) != 0)
1679                 *status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
1680 }
1681
1682 static inline void
1683 generate_digest(IMB_JOB *job, struct rte_crypto_op *op,
1684                 struct aesni_mb_session *sess)
1685 {
1686         /* No extra copy needed */
1687         if (likely(sess->auth.req_digest_len == sess->auth.gen_digest_len))
1688                 return;
1689
1690         /*
1691          * This can only happen for HMAC, so only digest
1692          * for authentication algos is required
1693          */
1694         memcpy(op->sym->auth.digest.data, job->auth_tag_output,
1695                         sess->auth.req_digest_len);
1696 }
1697
1698 /**
1699  * Process a completed job and return rte_mbuf which job processed
1700  *
1701  * @param qp    Queue Pair to process
1702  * @param job   IMB_JOB job to process
1703  *
1704  * @return
1705  * - Returns processed crypto operation.
1706  * - Returns NULL on invalid job
1707  */
1708 static inline struct rte_crypto_op *
1709 post_process_mb_job(struct ipsec_mb_qp *qp, IMB_JOB *job)
1710 {
1711         struct rte_crypto_op *op = (struct rte_crypto_op *)job->user_data;
1712         struct aesni_mb_session *sess = NULL;
1713         uint32_t driver_id = ipsec_mb_get_driver_id(
1714                                                 IPSEC_MB_PMD_TYPE_AESNI_MB);
1715
1716 #ifdef AESNI_MB_DOCSIS_SEC_ENABLED
1717         uint8_t is_docsis_sec = 0;
1718
1719         if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
1720                 /*
1721                  * Assuming at this point that if it's a security type op, that
1722                  * this is for DOCSIS
1723                  */
1724                 is_docsis_sec = 1;
1725                 sess = get_sec_session_private_data(op->sym->sec_session);
1726         } else
1727 #endif
1728         {
1729                 sess = get_sym_session_private_data(op->sym->session,
1730                                                 driver_id);
1731         }
1732
1733         if (unlikely(sess == NULL)) {
1734                 op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
1735                 return op;
1736         }
1737
1738         if (likely(op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)) {
1739                 switch (job->status) {
1740                 case IMB_STATUS_COMPLETED:
1741                         op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1742
1743                         if (job->hash_alg == IMB_AUTH_NULL)
1744                                 break;
1745
1746                         if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
1747                                 if (is_aead_algo(job->hash_alg,
1748                                                 sess->cipher.mode))
1749                                         verify_digest(job,
1750                                                 op->sym->aead.digest.data,
1751                                                 sess->auth.req_digest_len,
1752                                                 &op->status);
1753 #ifdef AESNI_MB_DOCSIS_SEC_ENABLED
1754                                 else if (is_docsis_sec)
1755                                         verify_docsis_sec_crc(job,
1756                                                 &op->status);
1757 #endif
1758                                 else
1759                                         verify_digest(job,
1760                                                 op->sym->auth.digest.data,
1761                                                 sess->auth.req_digest_len,
1762                                                 &op->status);
1763                         } else
1764                                 generate_digest(job, op, sess);
1765                         break;
1766                 default:
1767                         op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1768                 }
1769         }
1770
1771         /* Free session if a session-less crypto op */
1772         if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
1773                 memset(sess, 0, sizeof(struct aesni_mb_session));
1774                 memset(op->sym->session, 0,
1775                         rte_cryptodev_sym_get_existing_header_session_size(
1776                                 op->sym->session));
1777                 rte_mempool_put(qp->sess_mp_priv, sess);
1778                 rte_mempool_put(qp->sess_mp, op->sym->session);
1779                 op->sym->session = NULL;
1780         }
1781
1782         return op;
1783 }
1784
1785 static inline void
1786 post_process_mb_sync_job(IMB_JOB *job)
1787 {
1788         uint32_t *st;
1789
1790         st = job->user_data;
1791         st[0] = (job->status == IMB_STATUS_COMPLETED) ? 0 : EBADMSG;
1792 }
1793
1794 /**
1795  * Process a completed IMB_JOB job and keep processing jobs until
1796  * get_completed_job return NULL
1797  *
1798  * @param qp            Queue Pair to process
1799  * @param mb_mgr        IMB_MGR to use
1800  * @param job           IMB_JOB job
1801  * @param ops           crypto ops to fill
1802  * @param nb_ops        number of crypto ops
1803  *
1804  * @return
1805  * - Number of processed jobs
1806  */
1807 static unsigned
1808 handle_completed_jobs(struct ipsec_mb_qp *qp, IMB_MGR *mb_mgr,
1809                 IMB_JOB *job, struct rte_crypto_op **ops,
1810                 uint16_t nb_ops)
1811 {
1812         struct rte_crypto_op *op = NULL;
1813         uint16_t processed_jobs = 0;
1814
1815         while (job != NULL) {
1816                 op = post_process_mb_job(qp, job);
1817
1818                 if (op) {
1819                         ops[processed_jobs++] = op;
1820                         qp->stats.dequeued_count++;
1821                 } else {
1822                         qp->stats.dequeue_err_count++;
1823                         break;
1824                 }
1825                 if (processed_jobs == nb_ops)
1826                         break;
1827
1828                 job = IMB_GET_COMPLETED_JOB(mb_mgr);
1829         }
1830
1831         return processed_jobs;
1832 }
1833
1834 static inline uint32_t
1835 handle_completed_sync_jobs(IMB_JOB *job, IMB_MGR *mb_mgr)
1836 {
1837         uint32_t i;
1838
1839         for (i = 0; job != NULL; i++, job = IMB_GET_COMPLETED_JOB(mb_mgr))
1840                 post_process_mb_sync_job(job);
1841
1842         return i;
1843 }
1844
1845 static inline uint32_t
1846 flush_mb_sync_mgr(IMB_MGR *mb_mgr)
1847 {
1848         IMB_JOB *job;
1849
1850         job = IMB_FLUSH_JOB(mb_mgr);
1851         return handle_completed_sync_jobs(job, mb_mgr);
1852 }
1853
1854 static inline uint16_t
1855 flush_mb_mgr(struct ipsec_mb_qp *qp, IMB_MGR *mb_mgr,
1856                 struct rte_crypto_op **ops, uint16_t nb_ops)
1857 {
1858         int processed_ops = 0;
1859
1860         /* Flush the remaining jobs */
1861         IMB_JOB *job = IMB_FLUSH_JOB(mb_mgr);
1862
1863         if (job)
1864                 processed_ops += handle_completed_jobs(qp, mb_mgr, job,
1865                                 &ops[processed_ops], nb_ops - processed_ops);
1866
1867         return processed_ops;
1868 }
1869
1870 static inline IMB_JOB *
1871 set_job_null_op(IMB_JOB *job, struct rte_crypto_op *op)
1872 {
1873         job->chain_order = IMB_ORDER_HASH_CIPHER;
1874         job->cipher_mode = IMB_CIPHER_NULL;
1875         job->hash_alg = IMB_AUTH_NULL;
1876         job->cipher_direction = IMB_DIR_DECRYPT;
1877
1878         /* Set user data to be crypto operation data struct */
1879         job->user_data = op;
1880
1881         return job;
1882 }
1883
1884 static uint16_t
1885 aesni_mb_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
1886                 uint16_t nb_ops)
1887 {
1888         struct ipsec_mb_qp *qp = queue_pair;
1889         IMB_MGR *mb_mgr = qp->mb_mgr;
1890         struct rte_crypto_op *op;
1891         IMB_JOB *job;
1892         int retval, processed_jobs = 0;
1893
1894         if (unlikely(nb_ops == 0 || mb_mgr == NULL))
1895                 return 0;
1896
1897         uint8_t digest_idx = qp->digest_idx;
1898
1899         do {
1900                 /* Get next free mb job struct from mb manager */
1901                 job = IMB_GET_NEXT_JOB(mb_mgr);
1902                 if (unlikely(job == NULL)) {
1903                         /* if no free mb job structs we need to flush mb_mgr */
1904                         processed_jobs += flush_mb_mgr(qp, mb_mgr,
1905                                         &ops[processed_jobs],
1906                                         nb_ops - processed_jobs);
1907
1908                         if (nb_ops == processed_jobs)
1909                                 break;
1910
1911                         job = IMB_GET_NEXT_JOB(mb_mgr);
1912                 }
1913
1914                 /*
1915                  * Get next operation to process from ingress queue.
1916                  * There is no need to return the job to the IMB_MGR
1917                  * if there are no more operations to process, since the IMB_MGR
1918                  * can use that pointer again in next get_next calls.
1919                  */
1920                 retval = rte_ring_dequeue(qp->ingress_queue, (void **)&op);
1921                 if (retval < 0)
1922                         break;
1923
1924 #ifdef AESNI_MB_DOCSIS_SEC_ENABLED
1925                 if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION)
1926                         retval = set_sec_mb_job_params(job, qp, op,
1927                                                 &digest_idx);
1928                 else
1929 #endif
1930                         retval = set_mb_job_params(job, qp, op,
1931                                 &digest_idx, mb_mgr);
1932
1933                 if (unlikely(retval != 0)) {
1934                         qp->stats.dequeue_err_count++;
1935                         set_job_null_op(job, op);
1936                 }
1937
1938                 /* Submit job to multi-buffer for processing */
1939 #ifdef RTE_LIBRTE_PMD_AESNI_MB_DEBUG
1940                 job = IMB_SUBMIT_JOB(mb_mgr);
1941 #else
1942                 job = IMB_SUBMIT_JOB_NOCHECK(mb_mgr);
1943 #endif
1944                 /*
1945                  * If submit returns a processed job then handle it,
1946                  * before submitting subsequent jobs
1947                  */
1948                 if (job)
1949                         processed_jobs += handle_completed_jobs(qp, mb_mgr,
1950                                         job, &ops[processed_jobs],
1951                                         nb_ops - processed_jobs);
1952
1953         } while (processed_jobs < nb_ops);
1954
1955         qp->digest_idx = digest_idx;
1956
1957         if (processed_jobs < 1)
1958                 processed_jobs += flush_mb_mgr(qp, mb_mgr,
1959                                 &ops[processed_jobs],
1960                                 nb_ops - processed_jobs);
1961
1962         return processed_jobs;
1963 }
1964
1965
1966 static inline void
1967 ipsec_mb_fill_error_code(struct rte_crypto_sym_vec *vec, int32_t err)
1968 {
1969         uint32_t i;
1970
1971         for (i = 0; i != vec->num; ++i)
1972                 vec->status[i] = err;
1973 }
1974
1975 static inline int
1976 check_crypto_sgl(union rte_crypto_sym_ofs so, const struct rte_crypto_sgl *sgl)
1977 {
1978         /* no multi-seg support with current AESNI-MB PMD */
1979         if (sgl->num != 1)
1980                 return -ENOTSUP;
1981         else if (so.ofs.cipher.head + so.ofs.cipher.tail > sgl->vec[0].len)
1982                 return -EINVAL;
1983         return 0;
1984 }
1985
1986 static inline IMB_JOB *
1987 submit_sync_job(IMB_MGR *mb_mgr)
1988 {
1989 #ifdef RTE_LIBRTE_PMD_AESNI_MB_DEBUG
1990         return IMB_SUBMIT_JOB(mb_mgr);
1991 #else
1992         return IMB_SUBMIT_JOB_NOCHECK(mb_mgr);
1993 #endif
1994 }
1995
1996 static inline uint32_t
1997 generate_sync_dgst(struct rte_crypto_sym_vec *vec,
1998         const uint8_t dgst[][DIGEST_LENGTH_MAX], uint32_t len)
1999 {
2000         uint32_t i, k;
2001
2002         for (i = 0, k = 0; i != vec->num; i++) {
2003                 if (vec->status[i] == 0) {
2004                         memcpy(vec->digest[i].va, dgst[i], len);
2005                         k++;
2006                 }
2007         }
2008
2009         return k;
2010 }
2011
2012 static inline uint32_t
2013 verify_sync_dgst(struct rte_crypto_sym_vec *vec,
2014         const uint8_t dgst[][DIGEST_LENGTH_MAX], uint32_t len)
2015 {
2016         uint32_t i, k;
2017
2018         for (i = 0, k = 0; i != vec->num; i++) {
2019                 if (vec->status[i] == 0) {
2020                         if (memcmp(vec->digest[i].va, dgst[i], len) != 0)
2021                                 vec->status[i] = EBADMSG;
2022                         else
2023                                 k++;
2024                 }
2025         }
2026
2027         return k;
2028 }
2029
2030 static uint32_t
2031 aesni_mb_process_bulk(struct rte_cryptodev *dev,
2032         struct rte_cryptodev_sym_session *sess, union rte_crypto_sym_ofs sofs,
2033         struct rte_crypto_sym_vec *vec)
2034 {
2035         int32_t ret;
2036         uint32_t i, j, k, len;
2037         void *buf;
2038         IMB_JOB *job;
2039         IMB_MGR *mb_mgr;
2040         struct aesni_mb_session *s;
2041         uint8_t tmp_dgst[vec->num][DIGEST_LENGTH_MAX];
2042
2043         s = get_sym_session_private_data(sess, dev->driver_id);
2044         if (s == NULL) {
2045                 ipsec_mb_fill_error_code(vec, EINVAL);
2046                 return 0;
2047         }
2048
2049         /* get per-thread MB MGR, create one if needed */
2050         mb_mgr = get_per_thread_mb_mgr();
2051         if (unlikely(mb_mgr == NULL))
2052                 return 0;
2053
2054         for (i = 0, j = 0, k = 0; i != vec->num; i++) {
2055                 ret = check_crypto_sgl(sofs, vec->src_sgl + i);
2056                 if (ret != 0) {
2057                         vec->status[i] = ret;
2058                         continue;
2059                 }
2060
2061                 buf = vec->src_sgl[i].vec[0].base;
2062                 len = vec->src_sgl[i].vec[0].len;
2063
2064                 job = IMB_GET_NEXT_JOB(mb_mgr);
2065                 if (job == NULL) {
2066                         k += flush_mb_sync_mgr(mb_mgr);
2067                         job = IMB_GET_NEXT_JOB(mb_mgr);
2068                         RTE_ASSERT(job != NULL);
2069                 }
2070
2071                 /* Submit job for processing */
2072                 set_cpu_mb_job_params(job, s, sofs, buf, len, &vec->iv[i],
2073                         &vec->aad[i], tmp_dgst[i], &vec->status[i]);
2074                 job = submit_sync_job(mb_mgr);
2075                 j++;
2076
2077                 /* handle completed jobs */
2078                 k += handle_completed_sync_jobs(job, mb_mgr);
2079         }
2080
2081         /* flush remaining jobs */
2082         while (k != j)
2083                 k += flush_mb_sync_mgr(mb_mgr);
2084
2085         /* finish processing for successful jobs: check/update digest */
2086         if (k != 0) {
2087                 if (s->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY)
2088                         k = verify_sync_dgst(vec,
2089                                 (const uint8_t (*)[DIGEST_LENGTH_MAX])tmp_dgst,
2090                                 s->auth.req_digest_len);
2091                 else
2092                         k = generate_sync_dgst(vec,
2093                                 (const uint8_t (*)[DIGEST_LENGTH_MAX])tmp_dgst,
2094                                 s->auth.req_digest_len);
2095         }
2096
2097         return k;
2098 }
2099
2100 struct rte_cryptodev_ops aesni_mb_pmd_ops = {
2101         .dev_configure = ipsec_mb_config,
2102         .dev_start = ipsec_mb_start,
2103         .dev_stop = ipsec_mb_stop,
2104         .dev_close = ipsec_mb_close,
2105
2106         .stats_get = ipsec_mb_stats_get,
2107         .stats_reset = ipsec_mb_stats_reset,
2108
2109         .dev_infos_get = ipsec_mb_info_get,
2110
2111         .queue_pair_setup = ipsec_mb_qp_setup,
2112         .queue_pair_release = ipsec_mb_qp_release,
2113
2114         .sym_cpu_process = aesni_mb_process_bulk,
2115
2116         .sym_session_get_size = ipsec_mb_sym_session_get_size,
2117         .sym_session_configure = ipsec_mb_sym_session_configure,
2118         .sym_session_clear = ipsec_mb_sym_session_clear
2119 };
2120
2121 #ifdef AESNI_MB_DOCSIS_SEC_ENABLED
2122 /**
2123  * Configure a aesni multi-buffer session from a security session
2124  * configuration
2125  */
2126 static int
2127 aesni_mb_pmd_sec_sess_create(void *dev, struct rte_security_session_conf *conf,
2128                 struct rte_security_session *sess,
2129                 struct rte_mempool *mempool)
2130 {
2131         void *sess_private_data;
2132         struct rte_cryptodev *cdev = (struct rte_cryptodev *)dev;
2133         int ret;
2134
2135         if (conf->action_type != RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL ||
2136                         conf->protocol != RTE_SECURITY_PROTOCOL_DOCSIS) {
2137                 IPSEC_MB_LOG(ERR, "Invalid security protocol");
2138                 return -EINVAL;
2139         }
2140
2141         if (rte_mempool_get(mempool, &sess_private_data)) {
2142                 IPSEC_MB_LOG(ERR, "Couldn't get object from session mempool");
2143                 return -ENOMEM;
2144         }
2145
2146         ret = aesni_mb_set_docsis_sec_session_parameters(cdev, conf,
2147                         sess_private_data);
2148
2149         if (ret != 0) {
2150                 IPSEC_MB_LOG(ERR, "Failed to configure session parameters");
2151
2152                 /* Return session to mempool */
2153                 rte_mempool_put(mempool, sess_private_data);
2154                 return ret;
2155         }
2156
2157         set_sec_session_private_data(sess, sess_private_data);
2158
2159         return ret;
2160 }
2161
2162 /** Clear the memory of session so it does not leave key material behind */
2163 static int
2164 aesni_mb_pmd_sec_sess_destroy(void *dev __rte_unused,
2165                 struct rte_security_session *sess)
2166 {
2167         void *sess_priv = get_sec_session_private_data(sess);
2168
2169         if (sess_priv) {
2170                 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
2171
2172                 memset(sess_priv, 0, sizeof(struct aesni_mb_session));
2173                 set_sec_session_private_data(sess, NULL);
2174                 rte_mempool_put(sess_mp, sess_priv);
2175         }
2176         return 0;
2177 }
2178
2179 /** Get security capabilities for aesni multi-buffer */
2180 static const struct rte_security_capability *
2181 aesni_mb_pmd_sec_capa_get(void *device __rte_unused)
2182 {
2183         return aesni_mb_pmd_security_cap;
2184 }
2185
2186 static struct rte_security_ops aesni_mb_pmd_sec_ops = {
2187                 .session_create = aesni_mb_pmd_sec_sess_create,
2188                 .session_update = NULL,
2189                 .session_stats_get = NULL,
2190                 .session_destroy = aesni_mb_pmd_sec_sess_destroy,
2191                 .set_pkt_metadata = NULL,
2192                 .capabilities_get = aesni_mb_pmd_sec_capa_get
2193 };
2194
2195 struct rte_security_ops *rte_aesni_mb_pmd_sec_ops = &aesni_mb_pmd_sec_ops;
2196
2197 static int
2198 aesni_mb_configure_dev(struct rte_cryptodev *dev)
2199 {
2200         struct rte_security_ctx *security_instance;
2201
2202         security_instance = rte_malloc("aesni_mb_sec",
2203                                 sizeof(struct rte_security_ctx),
2204                                 RTE_CACHE_LINE_SIZE);
2205         if (security_instance != NULL) {
2206                 security_instance->device = (void *)dev;
2207                 security_instance->ops = rte_aesni_mb_pmd_sec_ops;
2208                 security_instance->sess_cnt = 0;
2209                 dev->security_ctx = security_instance;
2210
2211                 return 0;
2212         }
2213
2214         return -ENOMEM;
2215 }
2216
2217 #endif
2218
2219 static int
2220 aesni_mb_probe(struct rte_vdev_device *vdev)
2221 {
2222         return ipsec_mb_create(vdev, IPSEC_MB_PMD_TYPE_AESNI_MB);
2223 }
2224
2225 static struct rte_vdev_driver cryptodev_aesni_mb_pmd_drv = {
2226         .probe = aesni_mb_probe,
2227         .remove = ipsec_mb_remove
2228 };
2229
2230 static struct cryptodev_driver aesni_mb_crypto_drv;
2231
2232 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_AESNI_MB_PMD,
2233         cryptodev_aesni_mb_pmd_drv);
2234 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_AESNI_MB_PMD, cryptodev_aesni_mb_pmd);
2235 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_AESNI_MB_PMD,
2236                         "max_nb_queue_pairs=<int> socket_id=<int>");
2237 RTE_PMD_REGISTER_CRYPTO_DRIVER(
2238         aesni_mb_crypto_drv,
2239         cryptodev_aesni_mb_pmd_drv.driver,
2240         pmd_driver_id_aesni_mb);
2241
2242 /* Constructor function to register aesni-mb PMD */
2243 RTE_INIT(ipsec_mb_register_aesni_mb)
2244 {
2245         struct ipsec_mb_internals *aesni_mb_data =
2246                 &ipsec_mb_pmds[IPSEC_MB_PMD_TYPE_AESNI_MB];
2247
2248         aesni_mb_data->caps = aesni_mb_capabilities;
2249         aesni_mb_data->dequeue_burst = aesni_mb_dequeue_burst;
2250         aesni_mb_data->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
2251                         RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
2252                         RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
2253                         RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO |
2254                         RTE_CRYPTODEV_FF_NON_BYTE_ALIGNED_DATA |
2255                         RTE_CRYPTODEV_FF_SYM_SESSIONLESS;
2256
2257         aesni_mb_data->internals_priv_size = 0;
2258         aesni_mb_data->ops = &aesni_mb_pmd_ops;
2259         aesni_mb_data->qp_priv_size = sizeof(struct aesni_mb_qp_data);
2260         aesni_mb_data->queue_pair_configure = NULL;
2261 #ifdef AESNI_MB_DOCSIS_SEC_ENABLED
2262         aesni_mb_data->security_ops = &aesni_mb_pmd_sec_ops;
2263         aesni_mb_data->dev_config = aesni_mb_configure_dev;
2264         aesni_mb_data->feature_flags |= RTE_CRYPTODEV_FF_SECURITY;
2265 #endif
2266         aesni_mb_data->session_configure = aesni_mb_session_configure;
2267         aesni_mb_data->session_priv_size = sizeof(struct aesni_mb_session);
2268 }