crypto/openssl: update HMAC routine with 3.0 EVP API
[dpdk.git] / drivers / crypto / openssl / rte_openssl_pmd.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016-2017 Intel Corporation
3  */
4
5 #define OPENSSL_API_COMPAT 0x10100000L
6
7 #include <rte_common.h>
8 #include <rte_hexdump.h>
9 #include <rte_cryptodev.h>
10 #include <cryptodev_pmd.h>
11 #include <rte_bus_vdev.h>
12 #include <rte_malloc.h>
13 #include <rte_cpuflags.h>
14
15 #include <openssl/hmac.h>
16 #include <openssl/evp.h>
17
18 #include "openssl_pmd_private.h"
19 #include "compat.h"
20
21 #define DES_BLOCK_SIZE 8
22
23 static uint8_t cryptodev_driver_id;
24
25 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
26 static HMAC_CTX *HMAC_CTX_new(void)
27 {
28         HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
29
30         if (ctx != NULL)
31                 HMAC_CTX_init(ctx);
32         return ctx;
33 }
34
35 static void HMAC_CTX_free(HMAC_CTX *ctx)
36 {
37         if (ctx != NULL) {
38                 HMAC_CTX_cleanup(ctx);
39                 OPENSSL_free(ctx);
40         }
41 }
42 #endif
43
44 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
45
46 #include <openssl/provider.h>
47 #include <openssl/core_names.h>
48
49 #define MAX_OSSL_ALGO_NAME_SIZE         16
50
51 OSSL_PROVIDER *legacy;
52 OSSL_PROVIDER *deflt;
53
54 static void ossl_legacy_provider_load(void)
55 {
56         /* Load Multiple providers into the default (NULL) library context */
57         legacy = OSSL_PROVIDER_load(NULL, "legacy");
58         if (legacy == NULL) {
59                 OPENSSL_LOG(ERR, "Failed to load Legacy provider\n");
60                 return;
61         }
62
63         deflt = OSSL_PROVIDER_load(NULL, "default");
64         if (deflt == NULL) {
65                 OPENSSL_LOG(ERR, "Failed to load Default provider\n");
66                 OSSL_PROVIDER_unload(legacy);
67                 return;
68         }
69 }
70
71 static void ossl_legacy_provider_unload(void)
72 {
73         OSSL_PROVIDER_unload(legacy);
74         OSSL_PROVIDER_unload(deflt);
75 }
76
77 static __rte_always_inline const char *
78 digest_name_get(enum rte_crypto_auth_algorithm algo)
79 {
80         switch (algo) {
81         case RTE_CRYPTO_AUTH_MD5_HMAC:
82                 return OSSL_DIGEST_NAME_MD5;
83         case RTE_CRYPTO_AUTH_SHA1_HMAC:
84                 return OSSL_DIGEST_NAME_SHA1;
85         case RTE_CRYPTO_AUTH_SHA224_HMAC:
86                 return OSSL_DIGEST_NAME_SHA2_224;
87         case RTE_CRYPTO_AUTH_SHA256_HMAC:
88                 return OSSL_DIGEST_NAME_SHA2_256;
89         case RTE_CRYPTO_AUTH_SHA384_HMAC:
90                 return OSSL_DIGEST_NAME_SHA2_384;
91         case RTE_CRYPTO_AUTH_SHA512_HMAC:
92                 return OSSL_DIGEST_NAME_SHA2_512;
93         default:
94                 return NULL;
95         }
96 }
97 #endif
98
99 static int cryptodev_openssl_remove(struct rte_vdev_device *vdev);
100
101 /*----------------------------------------------------------------------------*/
102
103 /**
104  * Increment counter by 1
105  * Counter is 64 bit array, big-endian
106  */
107 static void
108 ctr_inc(uint8_t *ctr)
109 {
110         uint64_t *ctr64 = (uint64_t *)ctr;
111
112         *ctr64 = __builtin_bswap64(*ctr64);
113         (*ctr64)++;
114         *ctr64 = __builtin_bswap64(*ctr64);
115 }
116
117 /*
118  *------------------------------------------------------------------------------
119  * Session Prepare
120  *------------------------------------------------------------------------------
121  */
122
123 /** Get xform chain order */
124 static enum openssl_chain_order
125 openssl_get_chain_order(const struct rte_crypto_sym_xform *xform)
126 {
127         enum openssl_chain_order res = OPENSSL_CHAIN_NOT_SUPPORTED;
128
129         if (xform != NULL) {
130                 if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
131                         if (xform->next == NULL)
132                                 res =  OPENSSL_CHAIN_ONLY_AUTH;
133                         else if (xform->next->type ==
134                                         RTE_CRYPTO_SYM_XFORM_CIPHER)
135                                 res =  OPENSSL_CHAIN_AUTH_CIPHER;
136                 }
137                 if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
138                         if (xform->next == NULL)
139                                 res =  OPENSSL_CHAIN_ONLY_CIPHER;
140                         else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
141                                 res =  OPENSSL_CHAIN_CIPHER_AUTH;
142                 }
143                 if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
144                         res = OPENSSL_CHAIN_COMBINED;
145         }
146
147         return res;
148 }
149
150 /** Get session cipher key from input cipher key */
151 static void
152 get_cipher_key(const uint8_t *input_key, int keylen, uint8_t *session_key)
153 {
154         memcpy(session_key, input_key, keylen);
155 }
156
157 /** Get key ede 24 bytes standard from input key */
158 static int
159 get_cipher_key_ede(const uint8_t *key, int keylen, uint8_t *key_ede)
160 {
161         int res = 0;
162
163         /* Initialize keys - 24 bytes: [key1-key2-key3] */
164         switch (keylen) {
165         case 24:
166                 memcpy(key_ede, key, 24);
167                 break;
168         case 16:
169                 /* K3 = K1 */
170                 memcpy(key_ede, key, 16);
171                 memcpy(key_ede + 16, key, 8);
172                 break;
173         case 8:
174                 /* K1 = K2 = K3 (DES compatibility) */
175                 memcpy(key_ede, key, 8);
176                 memcpy(key_ede + 8, key, 8);
177                 memcpy(key_ede + 16, key, 8);
178                 break;
179         default:
180                 OPENSSL_LOG(ERR, "Unsupported key size");
181                 res = -EINVAL;
182         }
183
184         return res;
185 }
186
187 /** Get adequate openssl function for input cipher algorithm */
188 static uint8_t
189 get_cipher_algo(enum rte_crypto_cipher_algorithm sess_algo, size_t keylen,
190                 const EVP_CIPHER **algo)
191 {
192         int res = 0;
193
194         if (algo != NULL) {
195                 switch (sess_algo) {
196                 case RTE_CRYPTO_CIPHER_3DES_CBC:
197                         switch (keylen) {
198                         case 8:
199                                 *algo = EVP_des_cbc();
200                                 break;
201                         case 16:
202                                 *algo = EVP_des_ede_cbc();
203                                 break;
204                         case 24:
205                                 *algo = EVP_des_ede3_cbc();
206                                 break;
207                         default:
208                                 res = -EINVAL;
209                         }
210                         break;
211                 case RTE_CRYPTO_CIPHER_3DES_CTR:
212                         break;
213                 case RTE_CRYPTO_CIPHER_AES_CBC:
214                         switch (keylen) {
215                         case 16:
216                                 *algo = EVP_aes_128_cbc();
217                                 break;
218                         case 24:
219                                 *algo = EVP_aes_192_cbc();
220                                 break;
221                         case 32:
222                                 *algo = EVP_aes_256_cbc();
223                                 break;
224                         default:
225                                 res = -EINVAL;
226                         }
227                         break;
228                 case RTE_CRYPTO_CIPHER_AES_CTR:
229                         switch (keylen) {
230                         case 16:
231                                 *algo = EVP_aes_128_ctr();
232                                 break;
233                         case 24:
234                                 *algo = EVP_aes_192_ctr();
235                                 break;
236                         case 32:
237                                 *algo = EVP_aes_256_ctr();
238                                 break;
239                         default:
240                                 res = -EINVAL;
241                         }
242                         break;
243                 default:
244                         res = -EINVAL;
245                         break;
246                 }
247         } else {
248                 res = -EINVAL;
249         }
250
251         return res;
252 }
253
254 /** Get adequate openssl function for input auth algorithm */
255 static uint8_t
256 get_auth_algo(enum rte_crypto_auth_algorithm sessalgo,
257                 const EVP_MD **algo)
258 {
259         int res = 0;
260
261         if (algo != NULL) {
262                 switch (sessalgo) {
263                 case RTE_CRYPTO_AUTH_MD5:
264                 case RTE_CRYPTO_AUTH_MD5_HMAC:
265                         *algo = EVP_md5();
266                         break;
267                 case RTE_CRYPTO_AUTH_SHA1:
268                 case RTE_CRYPTO_AUTH_SHA1_HMAC:
269                         *algo = EVP_sha1();
270                         break;
271                 case RTE_CRYPTO_AUTH_SHA224:
272                 case RTE_CRYPTO_AUTH_SHA224_HMAC:
273                         *algo = EVP_sha224();
274                         break;
275                 case RTE_CRYPTO_AUTH_SHA256:
276                 case RTE_CRYPTO_AUTH_SHA256_HMAC:
277                         *algo = EVP_sha256();
278                         break;
279                 case RTE_CRYPTO_AUTH_SHA384:
280                 case RTE_CRYPTO_AUTH_SHA384_HMAC:
281                         *algo = EVP_sha384();
282                         break;
283                 case RTE_CRYPTO_AUTH_SHA512:
284                 case RTE_CRYPTO_AUTH_SHA512_HMAC:
285                         *algo = EVP_sha512();
286                         break;
287                 default:
288                         res = -EINVAL;
289                         break;
290                 }
291         } else {
292                 res = -EINVAL;
293         }
294
295         return res;
296 }
297
298 /** Get adequate openssl function for input cipher algorithm */
299 static uint8_t
300 get_aead_algo(enum rte_crypto_aead_algorithm sess_algo, size_t keylen,
301                 const EVP_CIPHER **algo)
302 {
303         int res = 0;
304
305         if (algo != NULL) {
306                 switch (sess_algo) {
307                 case RTE_CRYPTO_AEAD_AES_GCM:
308                         switch (keylen) {
309                         case 16:
310                                 *algo = EVP_aes_128_gcm();
311                                 break;
312                         case 24:
313                                 *algo = EVP_aes_192_gcm();
314                                 break;
315                         case 32:
316                                 *algo = EVP_aes_256_gcm();
317                                 break;
318                         default:
319                                 res = -EINVAL;
320                         }
321                         break;
322                 case RTE_CRYPTO_AEAD_AES_CCM:
323                         switch (keylen) {
324                         case 16:
325                                 *algo = EVP_aes_128_ccm();
326                                 break;
327                         case 24:
328                                 *algo = EVP_aes_192_ccm();
329                                 break;
330                         case 32:
331                                 *algo = EVP_aes_256_ccm();
332                                 break;
333                         default:
334                                 res = -EINVAL;
335                         }
336                         break;
337                 default:
338                         res = -EINVAL;
339                         break;
340                 }
341         } else {
342                 res = -EINVAL;
343         }
344
345         return res;
346 }
347
348 /* Set session AEAD encryption parameters */
349 static int
350 openssl_set_sess_aead_enc_param(struct openssl_session *sess,
351                 enum rte_crypto_aead_algorithm algo,
352                 uint8_t tag_len, const uint8_t *key)
353 {
354         int iv_type = 0;
355         unsigned int do_ccm;
356
357         sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
358         sess->auth.operation = RTE_CRYPTO_AUTH_OP_GENERATE;
359
360         /* Select AEAD algo */
361         switch (algo) {
362         case RTE_CRYPTO_AEAD_AES_GCM:
363                 iv_type = EVP_CTRL_GCM_SET_IVLEN;
364                 if (tag_len != 16)
365                         return -EINVAL;
366                 do_ccm = 0;
367                 break;
368         case RTE_CRYPTO_AEAD_AES_CCM:
369                 iv_type = EVP_CTRL_CCM_SET_IVLEN;
370                 /* Digest size can be 4, 6, 8, 10, 12, 14 or 16 bytes */
371                 if (tag_len < 4 || tag_len > 16 || (tag_len & 1) == 1)
372                         return -EINVAL;
373                 do_ccm = 1;
374                 break;
375         default:
376                 return -ENOTSUP;
377         }
378
379         sess->cipher.mode = OPENSSL_CIPHER_LIB;
380         sess->cipher.ctx = EVP_CIPHER_CTX_new();
381
382         if (get_aead_algo(algo, sess->cipher.key.length,
383                         &sess->cipher.evp_algo) != 0)
384                 return -EINVAL;
385
386         get_cipher_key(key, sess->cipher.key.length, sess->cipher.key.data);
387
388         sess->chain_order = OPENSSL_CHAIN_COMBINED;
389
390         if (EVP_EncryptInit_ex(sess->cipher.ctx, sess->cipher.evp_algo,
391                         NULL, NULL, NULL) <= 0)
392                 return -EINVAL;
393
394         if (EVP_CIPHER_CTX_ctrl(sess->cipher.ctx, iv_type, sess->iv.length,
395                         NULL) <= 0)
396                 return -EINVAL;
397
398         if (do_ccm)
399                 EVP_CIPHER_CTX_ctrl(sess->cipher.ctx, EVP_CTRL_CCM_SET_TAG,
400                                 tag_len, NULL);
401
402         if (EVP_EncryptInit_ex(sess->cipher.ctx, NULL, NULL, key, NULL) <= 0)
403                 return -EINVAL;
404
405         return 0;
406 }
407
408 /* Set session AEAD decryption parameters */
409 static int
410 openssl_set_sess_aead_dec_param(struct openssl_session *sess,
411                 enum rte_crypto_aead_algorithm algo,
412                 uint8_t tag_len, const uint8_t *key)
413 {
414         int iv_type = 0;
415         unsigned int do_ccm = 0;
416
417         sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_DECRYPT;
418         sess->auth.operation = RTE_CRYPTO_AUTH_OP_VERIFY;
419
420         /* Select AEAD algo */
421         switch (algo) {
422         case RTE_CRYPTO_AEAD_AES_GCM:
423                 iv_type = EVP_CTRL_GCM_SET_IVLEN;
424                 if (tag_len != 16)
425                         return -EINVAL;
426                 break;
427         case RTE_CRYPTO_AEAD_AES_CCM:
428                 iv_type = EVP_CTRL_CCM_SET_IVLEN;
429                 /* Digest size can be 4, 6, 8, 10, 12, 14 or 16 bytes */
430                 if (tag_len < 4 || tag_len > 16 || (tag_len & 1) == 1)
431                         return -EINVAL;
432                 do_ccm = 1;
433                 break;
434         default:
435                 return -ENOTSUP;
436         }
437
438         sess->cipher.mode = OPENSSL_CIPHER_LIB;
439         sess->cipher.ctx = EVP_CIPHER_CTX_new();
440
441         if (get_aead_algo(algo, sess->cipher.key.length,
442                         &sess->cipher.evp_algo) != 0)
443                 return -EINVAL;
444
445         get_cipher_key(key, sess->cipher.key.length, sess->cipher.key.data);
446
447         sess->chain_order = OPENSSL_CHAIN_COMBINED;
448
449         if (EVP_DecryptInit_ex(sess->cipher.ctx, sess->cipher.evp_algo,
450                         NULL, NULL, NULL) <= 0)
451                 return -EINVAL;
452
453         if (EVP_CIPHER_CTX_ctrl(sess->cipher.ctx, iv_type,
454                         sess->iv.length, NULL) <= 0)
455                 return -EINVAL;
456
457         if (do_ccm)
458                 EVP_CIPHER_CTX_ctrl(sess->cipher.ctx, EVP_CTRL_CCM_SET_TAG,
459                                 tag_len, NULL);
460
461         if (EVP_DecryptInit_ex(sess->cipher.ctx, NULL, NULL, key, NULL) <= 0)
462                 return -EINVAL;
463
464         return 0;
465 }
466
467 /** Set session cipher parameters */
468 static int
469 openssl_set_session_cipher_parameters(struct openssl_session *sess,
470                 const struct rte_crypto_sym_xform *xform)
471 {
472         /* Select cipher direction */
473         sess->cipher.direction = xform->cipher.op;
474         /* Select cipher key */
475         sess->cipher.key.length = xform->cipher.key.length;
476
477         /* Set IV parameters */
478         sess->iv.offset = xform->cipher.iv.offset;
479         sess->iv.length = xform->cipher.iv.length;
480
481         /* Select cipher algo */
482         switch (xform->cipher.algo) {
483         case RTE_CRYPTO_CIPHER_3DES_CBC:
484         case RTE_CRYPTO_CIPHER_AES_CBC:
485         case RTE_CRYPTO_CIPHER_AES_CTR:
486                 sess->cipher.mode = OPENSSL_CIPHER_LIB;
487                 sess->cipher.algo = xform->cipher.algo;
488                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
489
490                 if (get_cipher_algo(sess->cipher.algo, sess->cipher.key.length,
491                                 &sess->cipher.evp_algo) != 0)
492                         return -EINVAL;
493
494                 get_cipher_key(xform->cipher.key.data, sess->cipher.key.length,
495                         sess->cipher.key.data);
496                 if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
497                         if (EVP_EncryptInit_ex(sess->cipher.ctx,
498                                         sess->cipher.evp_algo,
499                                         NULL, xform->cipher.key.data,
500                                         NULL) != 1) {
501                                 return -EINVAL;
502                         }
503                 } else if (sess->cipher.direction ==
504                                 RTE_CRYPTO_CIPHER_OP_DECRYPT) {
505                         if (EVP_DecryptInit_ex(sess->cipher.ctx,
506                                         sess->cipher.evp_algo,
507                                         NULL, xform->cipher.key.data,
508                                         NULL) != 1) {
509                                 return -EINVAL;
510                         }
511                 }
512
513                 break;
514
515         case RTE_CRYPTO_CIPHER_3DES_CTR:
516                 sess->cipher.mode = OPENSSL_CIPHER_DES3CTR;
517                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
518
519                 if (get_cipher_key_ede(xform->cipher.key.data,
520                                 sess->cipher.key.length,
521                                 sess->cipher.key.data) != 0)
522                         return -EINVAL;
523                 break;
524
525         case RTE_CRYPTO_CIPHER_DES_CBC:
526                 sess->cipher.algo = xform->cipher.algo;
527                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
528                 sess->cipher.evp_algo = EVP_des_cbc();
529
530                 get_cipher_key(xform->cipher.key.data, sess->cipher.key.length,
531                         sess->cipher.key.data);
532                 if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
533                         if (EVP_EncryptInit_ex(sess->cipher.ctx,
534                                         sess->cipher.evp_algo,
535                                         NULL, xform->cipher.key.data,
536                                         NULL) != 1) {
537                                 return -EINVAL;
538                         }
539                 } else if (sess->cipher.direction ==
540                                 RTE_CRYPTO_CIPHER_OP_DECRYPT) {
541                         if (EVP_DecryptInit_ex(sess->cipher.ctx,
542                                         sess->cipher.evp_algo,
543                                         NULL, xform->cipher.key.data,
544                                         NULL) != 1) {
545                                 return -EINVAL;
546                         }
547                 }
548
549                 break;
550
551         case RTE_CRYPTO_CIPHER_DES_DOCSISBPI:
552                 sess->cipher.algo = xform->cipher.algo;
553                 sess->chain_order = OPENSSL_CHAIN_CIPHER_BPI;
554                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
555                 sess->cipher.evp_algo = EVP_des_cbc();
556
557                 sess->cipher.bpi_ctx = EVP_CIPHER_CTX_new();
558                 /* IV will be ECB encrypted whether direction is encrypt or decrypt */
559                 if (EVP_EncryptInit_ex(sess->cipher.bpi_ctx, EVP_des_ecb(),
560                                 NULL, xform->cipher.key.data, 0) != 1)
561                         return -EINVAL;
562
563                 get_cipher_key(xform->cipher.key.data, sess->cipher.key.length,
564                         sess->cipher.key.data);
565                 if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
566                         if (EVP_EncryptInit_ex(sess->cipher.ctx,
567                                         sess->cipher.evp_algo,
568                                         NULL, xform->cipher.key.data,
569                                         NULL) != 1) {
570                                 return -EINVAL;
571                         }
572                 } else if (sess->cipher.direction ==
573                                 RTE_CRYPTO_CIPHER_OP_DECRYPT) {
574                         if (EVP_DecryptInit_ex(sess->cipher.ctx,
575                                         sess->cipher.evp_algo,
576                                         NULL, xform->cipher.key.data,
577                                         NULL) != 1) {
578                                 return -EINVAL;
579                         }
580                 }
581
582                 break;
583         default:
584                 sess->cipher.algo = RTE_CRYPTO_CIPHER_NULL;
585                 return -ENOTSUP;
586         }
587
588         return 0;
589 }
590
591 /* Set session auth parameters */
592 static int
593 openssl_set_session_auth_parameters(struct openssl_session *sess,
594                 const struct rte_crypto_sym_xform *xform)
595 {
596         /* Select auth generate/verify */
597         sess->auth.operation = xform->auth.op;
598         sess->auth.algo = xform->auth.algo;
599
600         sess->auth.digest_length = xform->auth.digest_length;
601
602         /* Select auth algo */
603         switch (xform->auth.algo) {
604         case RTE_CRYPTO_AUTH_AES_GMAC:
605                 /*
606                  * OpenSSL requires GMAC to be a GCM operation
607                  * with no cipher data length
608                  */
609                 sess->cipher.key.length = xform->auth.key.length;
610
611                 /* Set IV parameters */
612                 sess->iv.offset = xform->auth.iv.offset;
613                 sess->iv.length = xform->auth.iv.length;
614
615                 if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_GENERATE)
616                         return openssl_set_sess_aead_enc_param(sess,
617                                                 RTE_CRYPTO_AEAD_AES_GCM,
618                                                 xform->auth.digest_length,
619                                                 xform->auth.key.data);
620                 else
621                         return openssl_set_sess_aead_dec_param(sess,
622                                                 RTE_CRYPTO_AEAD_AES_GCM,
623                                                 xform->auth.digest_length,
624                                                 xform->auth.key.data);
625                 break;
626
627         case RTE_CRYPTO_AUTH_MD5:
628         case RTE_CRYPTO_AUTH_SHA1:
629         case RTE_CRYPTO_AUTH_SHA224:
630         case RTE_CRYPTO_AUTH_SHA256:
631         case RTE_CRYPTO_AUTH_SHA384:
632         case RTE_CRYPTO_AUTH_SHA512:
633                 sess->auth.mode = OPENSSL_AUTH_AS_AUTH;
634                 if (get_auth_algo(xform->auth.algo,
635                                 &sess->auth.auth.evp_algo) != 0)
636                         return -EINVAL;
637                 sess->auth.auth.ctx = EVP_MD_CTX_create();
638                 break;
639
640 # if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
641         case RTE_CRYPTO_AUTH_MD5_HMAC:
642         case RTE_CRYPTO_AUTH_SHA1_HMAC:
643         case RTE_CRYPTO_AUTH_SHA224_HMAC:
644         case RTE_CRYPTO_AUTH_SHA256_HMAC:
645         case RTE_CRYPTO_AUTH_SHA384_HMAC:
646         case RTE_CRYPTO_AUTH_SHA512_HMAC:
647                 sess->auth.mode = OPENSSL_AUTH_AS_HMAC;
648
649                 OSSL_PARAM params[2];
650                 const char *algo;
651                 algo = digest_name_get(xform->auth.algo);
652                 if (!algo)
653                         return -EINVAL;
654                 char algo_name[MAX_OSSL_ALGO_NAME_SIZE];
655                 rte_memcpy(algo_name, algo, (sizeof(algo)+1));
656
657                 EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
658                 sess->auth.hmac.ctx = EVP_MAC_CTX_new(mac);
659                 EVP_MAC_free(mac);
660                 if (get_auth_algo(xform->auth.algo,
661                                 &sess->auth.hmac.evp_algo) != 0)
662                         return -EINVAL;
663
664                 params[0] = OSSL_PARAM_construct_utf8_string("digest",
665                                         algo_name, 0);
666                 params[1] = OSSL_PARAM_construct_end();
667                 if (EVP_MAC_init(sess->auth.hmac.ctx,
668                                 xform->auth.key.data,
669                                 xform->auth.key.length,
670                                 params) != 1)
671                         return -EINVAL;
672                 break;
673 # else
674         case RTE_CRYPTO_AUTH_MD5_HMAC:
675         case RTE_CRYPTO_AUTH_SHA1_HMAC:
676         case RTE_CRYPTO_AUTH_SHA224_HMAC:
677         case RTE_CRYPTO_AUTH_SHA256_HMAC:
678         case RTE_CRYPTO_AUTH_SHA384_HMAC:
679         case RTE_CRYPTO_AUTH_SHA512_HMAC:
680                 sess->auth.mode = OPENSSL_AUTH_AS_HMAC;
681                 sess->auth.hmac.ctx = HMAC_CTX_new();
682                 if (get_auth_algo(xform->auth.algo,
683                                 &sess->auth.hmac.evp_algo) != 0)
684                         return -EINVAL;
685
686                 if (HMAC_Init_ex(sess->auth.hmac.ctx,
687                                 xform->auth.key.data,
688                                 xform->auth.key.length,
689                                 sess->auth.hmac.evp_algo, NULL) != 1)
690                         return -EINVAL;
691                 break;
692 # endif
693         default:
694                 return -ENOTSUP;
695         }
696
697         return 0;
698 }
699
700 /* Set session AEAD parameters */
701 static int
702 openssl_set_session_aead_parameters(struct openssl_session *sess,
703                 const struct rte_crypto_sym_xform *xform)
704 {
705         /* Select cipher key */
706         sess->cipher.key.length = xform->aead.key.length;
707
708         /* Set IV parameters */
709         if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM)
710                 /*
711                  * For AES-CCM, the actual IV is placed
712                  * one byte after the start of the IV field,
713                  * according to the API.
714                  */
715                 sess->iv.offset = xform->aead.iv.offset + 1;
716         else
717                 sess->iv.offset = xform->aead.iv.offset;
718
719         sess->iv.length = xform->aead.iv.length;
720
721         sess->auth.aad_length = xform->aead.aad_length;
722         sess->auth.digest_length = xform->aead.digest_length;
723
724         sess->aead_algo = xform->aead.algo;
725         /* Select cipher direction */
726         if (xform->aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT)
727                 return openssl_set_sess_aead_enc_param(sess, xform->aead.algo,
728                                 xform->aead.digest_length, xform->aead.key.data);
729         else
730                 return openssl_set_sess_aead_dec_param(sess, xform->aead.algo,
731                                 xform->aead.digest_length, xform->aead.key.data);
732 }
733
734 /** Parse crypto xform chain and set private session parameters */
735 int
736 openssl_set_session_parameters(struct openssl_session *sess,
737                 const struct rte_crypto_sym_xform *xform)
738 {
739         const struct rte_crypto_sym_xform *cipher_xform = NULL;
740         const struct rte_crypto_sym_xform *auth_xform = NULL;
741         const struct rte_crypto_sym_xform *aead_xform = NULL;
742         int ret;
743
744         sess->chain_order = openssl_get_chain_order(xform);
745         switch (sess->chain_order) {
746         case OPENSSL_CHAIN_ONLY_CIPHER:
747                 cipher_xform = xform;
748                 break;
749         case OPENSSL_CHAIN_ONLY_AUTH:
750                 auth_xform = xform;
751                 break;
752         case OPENSSL_CHAIN_CIPHER_AUTH:
753                 cipher_xform = xform;
754                 auth_xform = xform->next;
755                 break;
756         case OPENSSL_CHAIN_AUTH_CIPHER:
757                 auth_xform = xform;
758                 cipher_xform = xform->next;
759                 break;
760         case OPENSSL_CHAIN_COMBINED:
761                 aead_xform = xform;
762                 break;
763         default:
764                 return -EINVAL;
765         }
766
767         /* Default IV length = 0 */
768         sess->iv.length = 0;
769
770         /* cipher_xform must be check before auth_xform */
771         if (cipher_xform) {
772                 ret = openssl_set_session_cipher_parameters(
773                                 sess, cipher_xform);
774                 if (ret != 0) {
775                         OPENSSL_LOG(ERR,
776                                 "Invalid/unsupported cipher parameters");
777                         return ret;
778                 }
779         }
780
781         if (auth_xform) {
782                 ret = openssl_set_session_auth_parameters(sess, auth_xform);
783                 if (ret != 0) {
784                         OPENSSL_LOG(ERR,
785                                 "Invalid/unsupported auth parameters");
786                         return ret;
787                 }
788         }
789
790         if (aead_xform) {
791                 ret = openssl_set_session_aead_parameters(sess, aead_xform);
792                 if (ret != 0) {
793                         OPENSSL_LOG(ERR,
794                                 "Invalid/unsupported AEAD parameters");
795                         return ret;
796                 }
797         }
798
799         return 0;
800 }
801
802 /** Reset private session parameters */
803 void
804 openssl_reset_session(struct openssl_session *sess)
805 {
806         EVP_CIPHER_CTX_free(sess->cipher.ctx);
807
808         if (sess->chain_order == OPENSSL_CHAIN_CIPHER_BPI)
809                 EVP_CIPHER_CTX_free(sess->cipher.bpi_ctx);
810
811         switch (sess->auth.mode) {
812         case OPENSSL_AUTH_AS_AUTH:
813                 EVP_MD_CTX_destroy(sess->auth.auth.ctx);
814                 break;
815         case OPENSSL_AUTH_AS_HMAC:
816                 EVP_PKEY_free(sess->auth.hmac.pkey);
817 # if OPENSSL_VERSION_NUMBER >= 0x30000000L
818                 EVP_MAC_CTX_free(sess->auth.hmac.ctx);
819 # else
820                 HMAC_CTX_free(sess->auth.hmac.ctx);
821 # endif
822                 break;
823         default:
824                 break;
825         }
826 }
827
828 /** Provide session for operation */
829 static void *
830 get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
831 {
832         struct openssl_session *sess = NULL;
833         struct openssl_asym_session *asym_sess = NULL;
834
835         if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
836                 if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
837                         /* get existing session */
838                         if (likely(op->sym->session != NULL))
839                                 sess = (struct openssl_session *)
840                                                 get_sym_session_private_data(
841                                                 op->sym->session,
842                                                 cryptodev_driver_id);
843                 } else {
844                         if (likely(op->asym->session != NULL))
845                                 asym_sess = (struct openssl_asym_session *)
846                                                 op->asym->session->sess_private_data;
847                         if (asym_sess == NULL)
848                                 op->status =
849                                         RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
850                         return asym_sess;
851                 }
852         } else {
853                 /* sessionless asymmetric not supported */
854                 if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
855                         return NULL;
856
857                 /* provide internal session */
858                 void *_sess = rte_cryptodev_sym_session_create(qp->sess_mp);
859                 void *_sess_private_data = NULL;
860
861                 if (_sess == NULL)
862                         return NULL;
863
864                 if (rte_mempool_get(qp->sess_mp_priv,
865                                 (void **)&_sess_private_data))
866                         return NULL;
867
868                 sess = (struct openssl_session *)_sess_private_data;
869
870                 if (unlikely(openssl_set_session_parameters(sess,
871                                 op->sym->xform) != 0)) {
872                         rte_mempool_put(qp->sess_mp, _sess);
873                         rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
874                         sess = NULL;
875                 }
876                 op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
877                 set_sym_session_private_data(op->sym->session,
878                                 cryptodev_driver_id, _sess_private_data);
879         }
880
881         if (sess == NULL)
882                 op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
883
884         return sess;
885 }
886
887 /*
888  *------------------------------------------------------------------------------
889  * Process Operations
890  *------------------------------------------------------------------------------
891  */
892 static inline int
893 process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
894                 uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
895 {
896         struct rte_mbuf *m;
897         int dstlen;
898         int l, n = srclen;
899         uint8_t *src, temp[EVP_CIPHER_CTX_block_size(ctx)];
900
901         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
902                         m = m->next)
903                 offset -= rte_pktmbuf_data_len(m);
904
905         if (m == 0)
906                 return -1;
907
908         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
909         if (inplace)
910                 *dst = src;
911
912         l = rte_pktmbuf_data_len(m) - offset;
913         if (srclen <= l) {
914                 if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, srclen) <= 0)
915                         return -1;
916                 *dst += l;
917                 return 0;
918         }
919
920         if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
921                 return -1;
922
923         *dst += dstlen;
924         n -= l;
925
926         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
927                 uint8_t diff = l - dstlen, rem;
928
929                 src = rte_pktmbuf_mtod(m, uint8_t *);
930                 l = RTE_MIN(rte_pktmbuf_data_len(m), n);
931                 if (diff && inplace) {
932                         rem = RTE_MIN(l,
933                                 (EVP_CIPHER_CTX_block_size(ctx) - diff));
934                         if (EVP_EncryptUpdate(ctx, temp,
935                                                 &dstlen, src, rem) <= 0)
936                                 return -1;
937                         n -= rem;
938                         rte_memcpy(*dst, temp, diff);
939                         rte_memcpy(src, temp + diff, rem);
940                         src += rem;
941                         l -= rem;
942                 }
943                 if (inplace)
944                         *dst = src;
945                 if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
946                         return -1;
947                 *dst += dstlen;
948                 n -= l;
949         }
950
951         return 0;
952 }
953
954 static inline int
955 process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
956                 uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
957 {
958         struct rte_mbuf *m;
959         int dstlen;
960         int l, n = srclen;
961         uint8_t *src, temp[EVP_CIPHER_CTX_block_size(ctx)];
962
963         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
964                         m = m->next)
965                 offset -= rte_pktmbuf_data_len(m);
966
967         if (m == 0)
968                 return -1;
969
970         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
971         if (inplace)
972                 *dst = src;
973
974         l = rte_pktmbuf_data_len(m) - offset;
975         if (srclen <= l) {
976                 if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, srclen) <= 0)
977                         return -1;
978                 *dst += l;
979                 return 0;
980         }
981
982         if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
983                 return -1;
984
985         *dst += dstlen;
986         n -= l;
987
988         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
989                 uint8_t diff = l - dstlen, rem;
990
991                 src = rte_pktmbuf_mtod(m, uint8_t *);
992                 l = RTE_MIN(rte_pktmbuf_data_len(m), n);
993                 if (diff && inplace) {
994                         rem = RTE_MIN(l,
995                                 (EVP_CIPHER_CTX_block_size(ctx) - diff));
996                         if (EVP_DecryptUpdate(ctx, temp,
997                                                 &dstlen, src, rem) <= 0)
998                                 return -1;
999                         n -= rem;
1000                         rte_memcpy(*dst, temp, diff);
1001                         rte_memcpy(src, temp + diff, rem);
1002                         src += rem;
1003                         l -= rem;
1004                 }
1005                 if (inplace)
1006                         *dst = src;
1007                 if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
1008                         return -1;
1009                 *dst += dstlen;
1010                 n -= l;
1011         }
1012
1013         return 0;
1014 }
1015
1016 /** Process standard openssl cipher encryption */
1017 static int
1018 process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
1019                 int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
1020                 uint8_t inplace)
1021 {
1022         int totlen;
1023
1024         if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
1025                 goto process_cipher_encrypt_err;
1026
1027         EVP_CIPHER_CTX_set_padding(ctx, 0);
1028
1029         if (process_openssl_encryption_update(mbuf_src, offset, &dst,
1030                         srclen, ctx, inplace))
1031                 goto process_cipher_encrypt_err;
1032
1033         if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0)
1034                 goto process_cipher_encrypt_err;
1035
1036         return 0;
1037
1038 process_cipher_encrypt_err:
1039         OPENSSL_LOG(ERR, "Process openssl cipher encrypt failed");
1040         return -EINVAL;
1041 }
1042
1043 /** Process standard openssl cipher encryption */
1044 static int
1045 process_openssl_cipher_bpi_encrypt(uint8_t *src, uint8_t *dst,
1046                 uint8_t *iv, int srclen,
1047                 EVP_CIPHER_CTX *ctx)
1048 {
1049         uint8_t i;
1050         uint8_t encrypted_iv[DES_BLOCK_SIZE];
1051         int encrypted_ivlen;
1052
1053         if (EVP_EncryptUpdate(ctx, encrypted_iv, &encrypted_ivlen,
1054                         iv, DES_BLOCK_SIZE) <= 0)
1055                 goto process_cipher_encrypt_err;
1056
1057         for (i = 0; i < srclen; i++)
1058                 *(dst + i) = *(src + i) ^ (encrypted_iv[i]);
1059
1060         return 0;
1061
1062 process_cipher_encrypt_err:
1063         OPENSSL_LOG(ERR, "Process openssl cipher bpi encrypt failed");
1064         return -EINVAL;
1065 }
1066 /** Process standard openssl cipher decryption */
1067 static int
1068 process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
1069                 int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
1070                 uint8_t inplace)
1071 {
1072         int totlen;
1073
1074         if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
1075                 goto process_cipher_decrypt_err;
1076
1077         EVP_CIPHER_CTX_set_padding(ctx, 0);
1078
1079         if (process_openssl_decryption_update(mbuf_src, offset, &dst,
1080                         srclen, ctx, inplace))
1081                 goto process_cipher_decrypt_err;
1082
1083         if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0)
1084                 goto process_cipher_decrypt_err;
1085         return 0;
1086
1087 process_cipher_decrypt_err:
1088         OPENSSL_LOG(ERR, "Process openssl cipher decrypt failed");
1089         return -EINVAL;
1090 }
1091
1092 /** Process cipher des 3 ctr encryption, decryption algorithm */
1093 static int
1094 process_openssl_cipher_des3ctr(struct rte_mbuf *mbuf_src, uint8_t *dst,
1095                 int offset, uint8_t *iv, uint8_t *key, int srclen,
1096                 EVP_CIPHER_CTX *ctx)
1097 {
1098         uint8_t ebuf[8], ctr[8];
1099         int unused, n;
1100         struct rte_mbuf *m;
1101         uint8_t *src;
1102         int l;
1103
1104         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
1105                         m = m->next)
1106                 offset -= rte_pktmbuf_data_len(m);
1107
1108         if (m == 0)
1109                 goto process_cipher_des3ctr_err;
1110
1111         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
1112         l = rte_pktmbuf_data_len(m) - offset;
1113
1114         /* We use 3DES encryption also for decryption.
1115          * IV is not important for 3DES ecb
1116          */
1117         if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) <= 0)
1118                 goto process_cipher_des3ctr_err;
1119
1120         memcpy(ctr, iv, 8);
1121
1122         for (n = 0; n < srclen; n++) {
1123                 if (n % 8 == 0) {
1124                         if (EVP_EncryptUpdate(ctx,
1125                                         (unsigned char *)&ebuf, &unused,
1126                                         (const unsigned char *)&ctr, 8) <= 0)
1127                                 goto process_cipher_des3ctr_err;
1128                         ctr_inc(ctr);
1129                 }
1130                 dst[n] = *(src++) ^ ebuf[n % 8];
1131
1132                 l--;
1133                 if (!l) {
1134                         m = m->next;
1135                         if (m) {
1136                                 src = rte_pktmbuf_mtod(m, uint8_t *);
1137                                 l = rte_pktmbuf_data_len(m);
1138                         }
1139                 }
1140         }
1141
1142         return 0;
1143
1144 process_cipher_des3ctr_err:
1145         OPENSSL_LOG(ERR, "Process openssl cipher des 3 ede ctr failed");
1146         return -EINVAL;
1147 }
1148
1149 /** Process AES-GCM encrypt algorithm */
1150 static int
1151 process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset,
1152                 int srclen, uint8_t *aad, int aadlen, uint8_t *iv,
1153                 uint8_t *dst, uint8_t *tag, EVP_CIPHER_CTX *ctx)
1154 {
1155         int len = 0, unused = 0;
1156         uint8_t empty[] = {};
1157
1158         if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
1159                 goto process_auth_encryption_gcm_err;
1160
1161         if (aadlen > 0)
1162                 if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0)
1163                         goto process_auth_encryption_gcm_err;
1164
1165         if (srclen > 0)
1166                 if (process_openssl_encryption_update(mbuf_src, offset, &dst,
1167                                 srclen, ctx, 0))
1168                         goto process_auth_encryption_gcm_err;
1169
1170         /* Workaround open ssl bug in version less then 1.0.1f */
1171         if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
1172                 goto process_auth_encryption_gcm_err;
1173
1174         if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0)
1175                 goto process_auth_encryption_gcm_err;
1176
1177         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0)
1178                 goto process_auth_encryption_gcm_err;
1179
1180         return 0;
1181
1182 process_auth_encryption_gcm_err:
1183         OPENSSL_LOG(ERR, "Process openssl auth encryption gcm failed");
1184         return -EINVAL;
1185 }
1186
1187 /** Process AES-CCM encrypt algorithm */
1188 static int
1189 process_openssl_auth_encryption_ccm(struct rte_mbuf *mbuf_src, int offset,
1190                 int srclen, uint8_t *aad, int aadlen, uint8_t *iv,
1191                 uint8_t *dst, uint8_t *tag, uint8_t taglen, EVP_CIPHER_CTX *ctx)
1192 {
1193         int len = 0;
1194
1195         if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
1196                 goto process_auth_encryption_ccm_err;
1197
1198         if (EVP_EncryptUpdate(ctx, NULL, &len, NULL, srclen) <= 0)
1199                 goto process_auth_encryption_ccm_err;
1200
1201         if (aadlen > 0)
1202                 /*
1203                  * For AES-CCM, the actual AAD is placed
1204                  * 18 bytes after the start of the AAD field,
1205                  * according to the API.
1206                  */
1207                 if (EVP_EncryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0)
1208                         goto process_auth_encryption_ccm_err;
1209
1210         if (srclen >= 0)
1211                 if (process_openssl_encryption_update(mbuf_src, offset, &dst,
1212                                 srclen, ctx, 0))
1213                         goto process_auth_encryption_ccm_err;
1214
1215         if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0)
1216                 goto process_auth_encryption_ccm_err;
1217
1218         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, taglen, tag) <= 0)
1219                 goto process_auth_encryption_ccm_err;
1220
1221         return 0;
1222
1223 process_auth_encryption_ccm_err:
1224         OPENSSL_LOG(ERR, "Process openssl auth encryption ccm failed");
1225         return -EINVAL;
1226 }
1227
1228 /** Process AES-GCM decrypt algorithm */
1229 static int
1230 process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
1231                 int srclen, uint8_t *aad, int aadlen, uint8_t *iv,
1232                 uint8_t *dst, uint8_t *tag, EVP_CIPHER_CTX *ctx)
1233 {
1234         int len = 0, unused = 0;
1235         uint8_t empty[] = {};
1236
1237         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) <= 0)
1238                 goto process_auth_decryption_gcm_err;
1239
1240         if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
1241                 goto process_auth_decryption_gcm_err;
1242
1243         if (aadlen > 0)
1244                 if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0)
1245                         goto process_auth_decryption_gcm_err;
1246
1247         if (srclen > 0)
1248                 if (process_openssl_decryption_update(mbuf_src, offset, &dst,
1249                                 srclen, ctx, 0))
1250                         goto process_auth_decryption_gcm_err;
1251
1252         /* Workaround open ssl bug in version less then 1.0.1f */
1253         if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
1254                 goto process_auth_decryption_gcm_err;
1255
1256         if (EVP_DecryptFinal_ex(ctx, dst, &len) <= 0)
1257                 return -EFAULT;
1258
1259         return 0;
1260
1261 process_auth_decryption_gcm_err:
1262         OPENSSL_LOG(ERR, "Process openssl auth decryption gcm failed");
1263         return -EINVAL;
1264 }
1265
1266 /** Process AES-CCM decrypt algorithm */
1267 static int
1268 process_openssl_auth_decryption_ccm(struct rte_mbuf *mbuf_src, int offset,
1269                 int srclen, uint8_t *aad, int aadlen, uint8_t *iv,
1270                 uint8_t *dst, uint8_t *tag, uint8_t tag_len,
1271                 EVP_CIPHER_CTX *ctx)
1272 {
1273         int len = 0;
1274
1275         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_len, tag) <= 0)
1276                 goto process_auth_decryption_ccm_err;
1277
1278         if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
1279                 goto process_auth_decryption_ccm_err;
1280
1281         if (EVP_DecryptUpdate(ctx, NULL, &len, NULL, srclen) <= 0)
1282                 goto process_auth_decryption_ccm_err;
1283
1284         if (aadlen > 0)
1285                 /*
1286                  * For AES-CCM, the actual AAD is placed
1287                  * 18 bytes after the start of the AAD field,
1288                  * according to the API.
1289                  */
1290                 if (EVP_DecryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0)
1291                         goto process_auth_decryption_ccm_err;
1292
1293         if (srclen >= 0)
1294                 if (process_openssl_decryption_update(mbuf_src, offset, &dst,
1295                                 srclen, ctx, 0))
1296                         return -EFAULT;
1297
1298         return 0;
1299
1300 process_auth_decryption_ccm_err:
1301         OPENSSL_LOG(ERR, "Process openssl auth decryption ccm failed");
1302         return -EINVAL;
1303 }
1304
1305 /** Process standard openssl auth algorithms */
1306 static int
1307 process_openssl_auth(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset,
1308                 __rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey,
1309                 int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo)
1310 {
1311         size_t dstlen;
1312         struct rte_mbuf *m;
1313         int l, n = srclen;
1314         uint8_t *src;
1315
1316         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
1317                         m = m->next)
1318                 offset -= rte_pktmbuf_data_len(m);
1319
1320         if (m == 0)
1321                 goto process_auth_err;
1322
1323         if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0)
1324                 goto process_auth_err;
1325
1326         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
1327
1328         l = rte_pktmbuf_data_len(m) - offset;
1329         if (srclen <= l) {
1330                 if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0)
1331                         goto process_auth_err;
1332                 goto process_auth_final;
1333         }
1334
1335         if (EVP_DigestUpdate(ctx, (char *)src, l) <= 0)
1336                 goto process_auth_err;
1337
1338         n -= l;
1339
1340         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
1341                 src = rte_pktmbuf_mtod(m, uint8_t *);
1342                 l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
1343                 if (EVP_DigestUpdate(ctx, (char *)src, l) <= 0)
1344                         goto process_auth_err;
1345                 n -= l;
1346         }
1347
1348 process_auth_final:
1349         if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0)
1350                 goto process_auth_err;
1351         return 0;
1352
1353 process_auth_err:
1354         OPENSSL_LOG(ERR, "Process openssl auth failed");
1355         return -EINVAL;
1356 }
1357
1358 # if OPENSSL_VERSION_NUMBER >= 0x30000000L
1359 /** Process standard openssl auth algorithms with hmac */
1360 static int
1361 process_openssl_auth_hmac(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset,
1362                 int srclen, EVP_MAC_CTX *ctx)
1363 {
1364         size_t dstlen;
1365         struct rte_mbuf *m;
1366         int l, n = srclen;
1367         uint8_t *src;
1368
1369         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
1370                         m = m->next)
1371                 offset -= rte_pktmbuf_data_len(m);
1372
1373         if (m == 0)
1374                 goto process_auth_err;
1375
1376         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
1377
1378         l = rte_pktmbuf_data_len(m) - offset;
1379         if (srclen <= l) {
1380                 if (EVP_MAC_update(ctx, (unsigned char *)src, srclen) != 1)
1381                         goto process_auth_err;
1382                 goto process_auth_final;
1383         }
1384
1385         if (EVP_MAC_update(ctx, (unsigned char *)src, l) != 1)
1386                 goto process_auth_err;
1387
1388         n -= l;
1389
1390         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
1391                 src = rte_pktmbuf_mtod(m, uint8_t *);
1392                 l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
1393                 if (EVP_MAC_update(ctx, (unsigned char *)src, l) != 1)
1394                         goto process_auth_err;
1395                 n -= l;
1396         }
1397
1398 process_auth_final:
1399         if (EVP_MAC_final(ctx, dst, &dstlen, sizeof(dst)) != 1)
1400                 goto process_auth_err;
1401
1402         EVP_MAC_CTX_free(ctx);
1403         return 0;
1404
1405 process_auth_err:
1406         EVP_MAC_CTX_free(ctx);
1407         OPENSSL_LOG(ERR, "Process openssl auth failed");
1408         return -EINVAL;
1409 }
1410 # else
1411 /** Process standard openssl auth algorithms with hmac */
1412 static int
1413 process_openssl_auth_hmac(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset,
1414                 int srclen, HMAC_CTX *ctx)
1415 {
1416         unsigned int dstlen;
1417         struct rte_mbuf *m;
1418         int l, n = srclen;
1419         uint8_t *src;
1420
1421         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
1422                         m = m->next)
1423                 offset -= rte_pktmbuf_data_len(m);
1424
1425         if (m == 0)
1426                 goto process_auth_err;
1427
1428         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
1429
1430         l = rte_pktmbuf_data_len(m) - offset;
1431         if (srclen <= l) {
1432                 if (HMAC_Update(ctx, (unsigned char *)src, srclen) != 1)
1433                         goto process_auth_err;
1434                 goto process_auth_final;
1435         }
1436
1437         if (HMAC_Update(ctx, (unsigned char *)src, l) != 1)
1438                 goto process_auth_err;
1439
1440         n -= l;
1441
1442         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
1443                 src = rte_pktmbuf_mtod(m, uint8_t *);
1444                 l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
1445                 if (HMAC_Update(ctx, (unsigned char *)src, l) != 1)
1446                         goto process_auth_err;
1447                 n -= l;
1448         }
1449
1450 process_auth_final:
1451         if (HMAC_Final(ctx, dst, &dstlen) != 1)
1452                 goto process_auth_err;
1453
1454         if (unlikely(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL) != 1))
1455                 goto process_auth_err;
1456
1457         return 0;
1458
1459 process_auth_err:
1460         OPENSSL_LOG(ERR, "Process openssl auth failed");
1461         return -EINVAL;
1462 }
1463 # endif
1464 /*----------------------------------------------------------------------------*/
1465
1466 /** Process auth/cipher combined operation */
1467 static void
1468 process_openssl_combined_op
1469                 (struct rte_crypto_op *op, struct openssl_session *sess,
1470                 struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
1471 {
1472         /* cipher */
1473         uint8_t *dst = NULL, *iv, *tag, *aad;
1474         int srclen, aadlen, status = -1;
1475         uint32_t offset;
1476         uint8_t taglen;
1477
1478         /*
1479          * Segmented destination buffer is not supported for
1480          * encryption/decryption
1481          */
1482         if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
1483                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1484                 return;
1485         }
1486
1487         iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1488                         sess->iv.offset);
1489         if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
1490                 srclen = 0;
1491                 offset = op->sym->auth.data.offset;
1492                 aadlen = op->sym->auth.data.length;
1493                 aad = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
1494                                 op->sym->auth.data.offset);
1495                 tag = op->sym->auth.digest.data;
1496                 if (tag == NULL)
1497                         tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1498                                 offset + aadlen);
1499         } else {
1500                 srclen = op->sym->aead.data.length;
1501                 dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1502                                 op->sym->aead.data.offset);
1503                 offset = op->sym->aead.data.offset;
1504                 aad = op->sym->aead.aad.data;
1505                 aadlen = sess->auth.aad_length;
1506                 tag = op->sym->aead.digest.data;
1507                 if (tag == NULL)
1508                         tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1509                                 offset + srclen);
1510         }
1511
1512         taglen = sess->auth.digest_length;
1513
1514         if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
1515                 if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC ||
1516                                 sess->aead_algo == RTE_CRYPTO_AEAD_AES_GCM)
1517                         status = process_openssl_auth_encryption_gcm(
1518                                         mbuf_src, offset, srclen,
1519                                         aad, aadlen, iv,
1520                                         dst, tag, sess->cipher.ctx);
1521                 else
1522                         status = process_openssl_auth_encryption_ccm(
1523                                         mbuf_src, offset, srclen,
1524                                         aad, aadlen, iv,
1525                                         dst, tag, taglen, sess->cipher.ctx);
1526
1527         } else {
1528                 if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC ||
1529                                 sess->aead_algo == RTE_CRYPTO_AEAD_AES_GCM)
1530                         status = process_openssl_auth_decryption_gcm(
1531                                         mbuf_src, offset, srclen,
1532                                         aad, aadlen, iv,
1533                                         dst, tag, sess->cipher.ctx);
1534                 else
1535                         status = process_openssl_auth_decryption_ccm(
1536                                         mbuf_src, offset, srclen,
1537                                         aad, aadlen, iv,
1538                                         dst, tag, taglen, sess->cipher.ctx);
1539         }
1540
1541         if (status != 0) {
1542                 if (status == (-EFAULT) &&
1543                                 sess->auth.operation ==
1544                                                 RTE_CRYPTO_AUTH_OP_VERIFY)
1545                         op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
1546                 else
1547                         op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1548         }
1549 }
1550
1551 /** Process cipher operation */
1552 static void
1553 process_openssl_cipher_op
1554                 (struct rte_crypto_op *op, struct openssl_session *sess,
1555                 struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
1556 {
1557         uint8_t *dst, *iv;
1558         int srclen, status;
1559         uint8_t inplace = (mbuf_src == mbuf_dst) ? 1 : 0;
1560         EVP_CIPHER_CTX *ctx_copy;
1561
1562         /*
1563          * Segmented OOP destination buffer is not supported for encryption/
1564          * decryption. In case of des3ctr, even inplace segmented buffers are
1565          * not supported.
1566          */
1567         if (!rte_pktmbuf_is_contiguous(mbuf_dst) &&
1568                         (!inplace || sess->cipher.mode != OPENSSL_CIPHER_LIB)) {
1569                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1570                 return;
1571         }
1572
1573         srclen = op->sym->cipher.data.length;
1574         dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1575                         op->sym->cipher.data.offset);
1576
1577         iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1578                         sess->iv.offset);
1579         ctx_copy = EVP_CIPHER_CTX_new();
1580         EVP_CIPHER_CTX_copy(ctx_copy, sess->cipher.ctx);
1581
1582         if (sess->cipher.mode == OPENSSL_CIPHER_LIB)
1583                 if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
1584                         status = process_openssl_cipher_encrypt(mbuf_src, dst,
1585                                         op->sym->cipher.data.offset, iv,
1586                                         srclen, ctx_copy, inplace);
1587                 else
1588                         status = process_openssl_cipher_decrypt(mbuf_src, dst,
1589                                         op->sym->cipher.data.offset, iv,
1590                                         srclen, ctx_copy, inplace);
1591         else
1592                 status = process_openssl_cipher_des3ctr(mbuf_src, dst,
1593                                 op->sym->cipher.data.offset, iv,
1594                                 sess->cipher.key.data, srclen,
1595                                 ctx_copy);
1596
1597         EVP_CIPHER_CTX_free(ctx_copy);
1598         if (status != 0)
1599                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1600 }
1601
1602 /** Process cipher operation */
1603 static void
1604 process_openssl_docsis_bpi_op(struct rte_crypto_op *op,
1605                 struct openssl_session *sess, struct rte_mbuf *mbuf_src,
1606                 struct rte_mbuf *mbuf_dst)
1607 {
1608         uint8_t *src, *dst, *iv;
1609         uint8_t block_size, last_block_len;
1610         int srclen, status = 0;
1611
1612         srclen = op->sym->cipher.data.length;
1613         src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
1614                         op->sym->cipher.data.offset);
1615         dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1616                         op->sym->cipher.data.offset);
1617
1618         iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1619                         sess->iv.offset);
1620
1621         block_size = DES_BLOCK_SIZE;
1622
1623         last_block_len = srclen % block_size;
1624         if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
1625                 /* Encrypt only with ECB mode XOR IV */
1626                 if (srclen < block_size) {
1627                         status = process_openssl_cipher_bpi_encrypt(src, dst,
1628                                         iv, srclen,
1629                                         sess->cipher.bpi_ctx);
1630                 } else {
1631                         srclen -= last_block_len;
1632                         /* Encrypt with the block aligned stream with CBC mode */
1633                         status = process_openssl_cipher_encrypt(mbuf_src, dst,
1634                                         op->sym->cipher.data.offset, iv,
1635                                         srclen, sess->cipher.ctx, 0);
1636                         if (last_block_len) {
1637                                 /* Point at last block */
1638                                 dst += srclen;
1639                                 /*
1640                                  * IV is the last encrypted block from
1641                                  * the previous operation
1642                                  */
1643                                 iv = dst - block_size;
1644                                 src += srclen;
1645                                 srclen = last_block_len;
1646                                 /* Encrypt the last frame with ECB mode */
1647                                 status |= process_openssl_cipher_bpi_encrypt(src,
1648                                                 dst, iv,
1649                                                 srclen, sess->cipher.bpi_ctx);
1650                         }
1651                 }
1652         } else {
1653                 /* Decrypt only with ECB mode (encrypt, as it is same operation) */
1654                 if (srclen < block_size) {
1655                         status = process_openssl_cipher_bpi_encrypt(src, dst,
1656                                         iv,
1657                                         srclen,
1658                                         sess->cipher.bpi_ctx);
1659                 } else {
1660                         if (last_block_len) {
1661                                 /* Point at last block */
1662                                 dst += srclen - last_block_len;
1663                                 src += srclen - last_block_len;
1664                                 /*
1665                                  * IV is the last full block
1666                                  */
1667                                 iv = src - block_size;
1668                                 /*
1669                                  * Decrypt the last frame with ECB mode
1670                                  * (encrypt, as it is the same operation)
1671                                  */
1672                                 status = process_openssl_cipher_bpi_encrypt(src,
1673                                                 dst, iv,
1674                                                 last_block_len, sess->cipher.bpi_ctx);
1675                                 /* Prepare parameters for CBC mode op */
1676                                 iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1677                                                 sess->iv.offset);
1678                                 dst += last_block_len - srclen;
1679                                 srclen -= last_block_len;
1680                         }
1681
1682                         /* Decrypt with CBC mode */
1683                         status |= process_openssl_cipher_decrypt(mbuf_src, dst,
1684                                         op->sym->cipher.data.offset, iv,
1685                                         srclen, sess->cipher.ctx, 0);
1686                 }
1687         }
1688
1689         if (status != 0)
1690                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1691 }
1692
1693 /** Process auth operation */
1694 static void
1695 process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op,
1696                 struct openssl_session *sess, struct rte_mbuf *mbuf_src,
1697                 struct rte_mbuf *mbuf_dst)
1698 {
1699         uint8_t *dst;
1700         int srclen, status;
1701         EVP_MD_CTX *ctx_a;
1702 # if OPENSSL_VERSION_NUMBER >= 0x30000000L
1703         EVP_MAC_CTX *ctx_h;
1704         EVP_MAC *mac;
1705 # else
1706         HMAC_CTX *ctx_h;
1707 # endif
1708
1709         srclen = op->sym->auth.data.length;
1710
1711         dst = qp->temp_digest;
1712
1713         switch (sess->auth.mode) {
1714         case OPENSSL_AUTH_AS_AUTH:
1715                 ctx_a = EVP_MD_CTX_create();
1716                 EVP_MD_CTX_copy_ex(ctx_a, sess->auth.auth.ctx);
1717                 status = process_openssl_auth(mbuf_src, dst,
1718                                 op->sym->auth.data.offset, NULL, NULL, srclen,
1719                                 ctx_a, sess->auth.auth.evp_algo);
1720                 EVP_MD_CTX_destroy(ctx_a);
1721                 break;
1722         case OPENSSL_AUTH_AS_HMAC:
1723 # if OPENSSL_VERSION_NUMBER >= 0x30000000L
1724                 mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
1725                 ctx_h = EVP_MAC_CTX_new(mac);
1726                 ctx_h = EVP_MAC_CTX_dup(sess->auth.hmac.ctx);
1727                 EVP_MAC_free(mac);
1728                 status = process_openssl_auth_hmac(mbuf_src, dst,
1729                                 op->sym->auth.data.offset, srclen,
1730                                 ctx_h);
1731 # else
1732                 ctx_h = HMAC_CTX_new();
1733                 HMAC_CTX_copy(ctx_h, sess->auth.hmac.ctx);
1734                 status = process_openssl_auth_hmac(mbuf_src, dst,
1735                                 op->sym->auth.data.offset, srclen,
1736                                 ctx_h);
1737                 HMAC_CTX_free(ctx_h);
1738 # endif
1739                 break;
1740         default:
1741                 status = -1;
1742                 break;
1743         }
1744
1745         if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
1746                 if (CRYPTO_memcmp(dst, op->sym->auth.digest.data,
1747                                 sess->auth.digest_length) != 0) {
1748                         op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
1749                 }
1750         } else {
1751                 uint8_t *auth_dst;
1752
1753                 auth_dst = op->sym->auth.digest.data;
1754                 if (auth_dst == NULL)
1755                         auth_dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1756                                         op->sym->auth.data.offset +
1757                                         op->sym->auth.data.length);
1758                 memcpy(auth_dst, dst, sess->auth.digest_length);
1759         }
1760
1761         if (status != 0)
1762                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1763 }
1764
1765 /* process dsa sign operation */
1766 static int
1767 process_openssl_dsa_sign_op(struct rte_crypto_op *cop,
1768                 struct openssl_asym_session *sess)
1769 {
1770         struct rte_crypto_dsa_op_param *op = &cop->asym->dsa;
1771         DSA *dsa = sess->u.s.dsa;
1772         DSA_SIG *sign = NULL;
1773
1774         sign = DSA_do_sign(op->message.data,
1775                         op->message.length,
1776                         dsa);
1777
1778         if (sign == NULL) {
1779                 OPENSSL_LOG(ERR, "%s:%d\n", __func__, __LINE__);
1780                 cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1781         } else {
1782                 const BIGNUM *r = NULL, *s = NULL;
1783                 get_dsa_sign(sign, &r, &s);
1784
1785                 op->r.length = BN_bn2bin(r, op->r.data);
1786                 op->s.length = BN_bn2bin(s, op->s.data);
1787                 cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1788         }
1789
1790         DSA_SIG_free(sign);
1791
1792         return 0;
1793 }
1794
1795 /* process dsa verify operation */
1796 static int
1797 process_openssl_dsa_verify_op(struct rte_crypto_op *cop,
1798                 struct openssl_asym_session *sess)
1799 {
1800         struct rte_crypto_dsa_op_param *op = &cop->asym->dsa;
1801         DSA *dsa = sess->u.s.dsa;
1802         int ret;
1803         DSA_SIG *sign = DSA_SIG_new();
1804         BIGNUM *r = NULL, *s = NULL;
1805         BIGNUM *pub_key = NULL;
1806
1807         if (sign == NULL) {
1808                 OPENSSL_LOG(ERR, " %s:%d\n", __func__, __LINE__);
1809                 cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
1810                 return -1;
1811         }
1812
1813         r = BN_bin2bn(op->r.data,
1814                         op->r.length,
1815                         r);
1816         s = BN_bin2bn(op->s.data,
1817                         op->s.length,
1818                         s);
1819         pub_key = BN_bin2bn(op->y.data,
1820                         op->y.length,
1821                         pub_key);
1822         if (!r || !s || !pub_key) {
1823                 BN_free(r);
1824                 BN_free(s);
1825                 BN_free(pub_key);
1826
1827                 cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
1828                 return -1;
1829         }
1830         set_dsa_sign(sign, r, s);
1831         set_dsa_pub_key(dsa, pub_key);
1832
1833         ret = DSA_do_verify(op->message.data,
1834                         op->message.length,
1835                         sign,
1836                         dsa);
1837
1838         if (ret != 1)
1839                 cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1840         else
1841                 cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1842
1843         DSA_SIG_free(sign);
1844
1845         return 0;
1846 }
1847
1848 /* process dh operation */
1849 static int
1850 process_openssl_dh_op(struct rte_crypto_op *cop,
1851                 struct openssl_asym_session *sess)
1852 {
1853         struct rte_crypto_dh_op_param *op = &cop->asym->dh;
1854         struct rte_crypto_asym_op *asym_op = cop->asym;
1855         DH *dh_key = sess->u.dh.dh_key;
1856         BIGNUM *priv_key = NULL;
1857         int ret = 0;
1858
1859         if (asym_op->dh.ke_type == RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE) {
1860                 /* compute shared secret using peer public key
1861                  * and current private key
1862                  * shared secret = peer_key ^ priv_key mod p
1863                  */
1864                 BIGNUM *peer_key = NULL;
1865
1866                 /* copy private key and peer key and compute shared secret */
1867                 peer_key = BN_bin2bn(op->pub_key.data,
1868                                 op->pub_key.length,
1869                                 peer_key);
1870                 if (peer_key == NULL) {
1871                         cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
1872                         return -1;
1873                 }
1874                 priv_key = BN_bin2bn(op->priv_key.data,
1875                                 op->priv_key.length,
1876                                 priv_key);
1877                 if (priv_key == NULL) {
1878                         BN_free(peer_key);
1879                         cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
1880                         return -1;
1881                 }
1882                 ret = set_dh_priv_key(dh_key, priv_key);
1883                 if (ret) {
1884                         OPENSSL_LOG(ERR, "Failed to set private key\n");
1885                         cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1886                         BN_free(peer_key);
1887                         BN_free(priv_key);
1888                         return 0;
1889                 }
1890
1891                 ret = DH_compute_key(
1892                                 op->shared_secret.data,
1893                                 peer_key, dh_key);
1894                 if (ret < 0) {
1895                         cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1896                         BN_free(peer_key);
1897                         /* priv key is already loaded into dh,
1898                          * let's not free that directly here.
1899                          * DH_free() will auto free it later.
1900                          */
1901                         return 0;
1902                 }
1903                 cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1904                 op->shared_secret.length = ret;
1905                 BN_free(peer_key);
1906                 return 0;
1907         }
1908
1909         /*
1910          * other options are public and private key generations.
1911          *
1912          * if user provides private key,
1913          * then first set DH with user provided private key
1914          */
1915         if (asym_op->dh.ke_type == RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE &&
1916                         op->priv_key.length) {
1917                 /* generate public key using user-provided private key
1918                  * pub_key = g ^ priv_key mod p
1919                  */
1920
1921                 /* load private key into DH */
1922                 priv_key = BN_bin2bn(op->priv_key.data,
1923                                 op->priv_key.length,
1924                                 priv_key);
1925                 if (priv_key == NULL) {
1926                         cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
1927                         return -1;
1928                 }
1929                 ret = set_dh_priv_key(dh_key, priv_key);
1930                 if (ret) {
1931                         OPENSSL_LOG(ERR, "Failed to set private key\n");
1932                         cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1933                         BN_free(priv_key);
1934                         return 0;
1935                 }
1936         }
1937
1938         /* generate public and private key pair.
1939          *
1940          * if private key already set, generates only public key.
1941          *
1942          * if private key is not already set, then set it to random value
1943          * and update internal private key.
1944          */
1945         if (!DH_generate_key(dh_key)) {
1946                 cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1947                 return 0;
1948         }
1949
1950         if (asym_op->dh.ke_type == RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE) {
1951                 const BIGNUM *pub_key = NULL;
1952
1953                 OPENSSL_LOG(DEBUG, "%s:%d update public key\n",
1954                                 __func__, __LINE__);
1955
1956                 /* get the generated keys */
1957                 get_dh_pub_key(dh_key, &pub_key);
1958
1959                 /* output public key */
1960                 op->pub_key.length = BN_bn2bin(pub_key,
1961                                 op->pub_key.data);
1962         }
1963
1964         if (asym_op->dh.ke_type == RTE_CRYPTO_ASYM_KE_PRIV_KEY_GENERATE) {
1965                 const BIGNUM *priv_key = NULL;
1966
1967                 OPENSSL_LOG(DEBUG, "%s:%d updated priv key\n",
1968                                 __func__, __LINE__);
1969
1970                 /* get the generated keys */
1971                 get_dh_priv_key(dh_key, &priv_key);
1972
1973                 /* provide generated private key back to user */
1974                 op->priv_key.length = BN_bn2bin(priv_key,
1975                                 op->priv_key.data);
1976         }
1977
1978         cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1979
1980         return 0;
1981 }
1982
1983 /* process modinv operation */
1984 static int
1985 process_openssl_modinv_op(struct rte_crypto_op *cop,
1986                 struct openssl_asym_session *sess)
1987 {
1988         struct rte_crypto_asym_op *op = cop->asym;
1989         BIGNUM *base = BN_CTX_get(sess->u.m.ctx);
1990         BIGNUM *res = BN_CTX_get(sess->u.m.ctx);
1991
1992         if (unlikely(base == NULL || res == NULL)) {
1993                 BN_free(base);
1994                 BN_free(res);
1995                 cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
1996                 return -1;
1997         }
1998
1999         base = BN_bin2bn((const unsigned char *)op->modinv.base.data,
2000                         op->modinv.base.length, base);
2001
2002         if (BN_mod_inverse(res, base, sess->u.m.modulus, sess->u.m.ctx)) {
2003                 cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
2004                 op->modinv.result.length = BN_bn2bin(res, op->modinv.result.data);
2005         } else {
2006                 cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
2007         }
2008
2009         BN_clear(res);
2010         BN_clear(base);
2011
2012         return 0;
2013 }
2014
2015 /* process modexp operation */
2016 static int
2017 process_openssl_modexp_op(struct rte_crypto_op *cop,
2018                 struct openssl_asym_session *sess)
2019 {
2020         struct rte_crypto_asym_op *op = cop->asym;
2021         BIGNUM *base = BN_CTX_get(sess->u.e.ctx);
2022         BIGNUM *res = BN_CTX_get(sess->u.e.ctx);
2023
2024         if (unlikely(base == NULL || res == NULL)) {
2025                 BN_free(base);
2026                 BN_free(res);
2027                 cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
2028                 return -1;
2029         }
2030
2031         base = BN_bin2bn((const unsigned char *)op->modex.base.data,
2032                         op->modex.base.length, base);
2033
2034         if (BN_mod_exp(res, base, sess->u.e.exp,
2035                                 sess->u.e.mod, sess->u.e.ctx)) {
2036                 op->modex.result.length = BN_bn2bin(res, op->modex.result.data);
2037                 cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
2038         } else {
2039                 cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
2040         }
2041
2042         BN_clear(res);
2043         BN_clear(base);
2044
2045         return 0;
2046 }
2047
2048 /* process rsa operations */
2049 static int
2050 process_openssl_rsa_op(struct rte_crypto_op *cop,
2051                 struct openssl_asym_session *sess)
2052 {
2053         int ret = 0;
2054         struct rte_crypto_asym_op *op = cop->asym;
2055         RSA *rsa = sess->u.r.rsa;
2056         uint32_t pad = (op->rsa.padding.type);
2057         uint8_t *tmp;
2058
2059         cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
2060
2061         switch (pad) {
2062         case RTE_CRYPTO_RSA_PADDING_PKCS1_5:
2063                 pad = RSA_PKCS1_PADDING;
2064                 break;
2065         case RTE_CRYPTO_RSA_PADDING_NONE:
2066                 pad = RSA_NO_PADDING;
2067                 break;
2068         default:
2069                 cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
2070                 OPENSSL_LOG(ERR,
2071                                 "rsa pad type not supported %d\n", pad);
2072                 return 0;
2073         }
2074
2075         switch (op->rsa.op_type) {
2076         case RTE_CRYPTO_ASYM_OP_ENCRYPT:
2077                 ret = RSA_public_encrypt(op->rsa.message.length,
2078                                 op->rsa.message.data,
2079                                 op->rsa.cipher.data,
2080                                 rsa,
2081                                 pad);
2082
2083                 if (ret > 0)
2084                         op->rsa.cipher.length = ret;
2085                 OPENSSL_LOG(DEBUG,
2086                                 "length of encrypted text %d\n", ret);
2087                 break;
2088
2089         case RTE_CRYPTO_ASYM_OP_DECRYPT:
2090                 ret = RSA_private_decrypt(op->rsa.cipher.length,
2091                                 op->rsa.cipher.data,
2092                                 op->rsa.message.data,
2093                                 rsa,
2094                                 pad);
2095                 if (ret > 0)
2096                         op->rsa.message.length = ret;
2097                 break;
2098
2099         case RTE_CRYPTO_ASYM_OP_SIGN:
2100                 ret = RSA_private_encrypt(op->rsa.message.length,
2101                                 op->rsa.message.data,
2102                                 op->rsa.sign.data,
2103                                 rsa,
2104                                 pad);
2105                 if (ret > 0)
2106                         op->rsa.sign.length = ret;
2107                 break;
2108
2109         case RTE_CRYPTO_ASYM_OP_VERIFY:
2110                 tmp = rte_malloc(NULL, op->rsa.sign.length, 0);
2111                 if (tmp == NULL) {
2112                         OPENSSL_LOG(ERR, "Memory allocation failed");
2113                         cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
2114                         break;
2115                 }
2116                 ret = RSA_public_decrypt(op->rsa.sign.length,
2117                                 op->rsa.sign.data,
2118                                 tmp,
2119                                 rsa,
2120                                 pad);
2121
2122                 OPENSSL_LOG(DEBUG,
2123                                 "Length of public_decrypt %d "
2124                                 "length of message %zd\n",
2125                                 ret, op->rsa.message.length);
2126                 if ((ret <= 0) || (CRYPTO_memcmp(tmp, op->rsa.message.data,
2127                                 op->rsa.message.length))) {
2128                         OPENSSL_LOG(ERR, "RSA sign Verification failed");
2129                         cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
2130                 }
2131                 rte_free(tmp);
2132                 break;
2133
2134         default:
2135                 /* allow ops with invalid args to be pushed to
2136                  * completion queue
2137                  */
2138                 cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
2139                 break;
2140         }
2141
2142         if (ret < 0)
2143                 cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
2144
2145         return 0;
2146 }
2147
2148 static int
2149 process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
2150                 struct openssl_asym_session *sess)
2151 {
2152         int retval = 0;
2153
2154         op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
2155
2156         switch (sess->xfrm_type) {
2157         case RTE_CRYPTO_ASYM_XFORM_RSA:
2158                 retval = process_openssl_rsa_op(op, sess);
2159                 break;
2160         case RTE_CRYPTO_ASYM_XFORM_MODEX:
2161                 retval = process_openssl_modexp_op(op, sess);
2162                 break;
2163         case RTE_CRYPTO_ASYM_XFORM_MODINV:
2164                 retval = process_openssl_modinv_op(op, sess);
2165                 break;
2166         case RTE_CRYPTO_ASYM_XFORM_DH:
2167                 retval = process_openssl_dh_op(op, sess);
2168                 break;
2169         case RTE_CRYPTO_ASYM_XFORM_DSA:
2170                 if (op->asym->dsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN)
2171                         retval = process_openssl_dsa_sign_op(op, sess);
2172                 else if (op->asym->dsa.op_type ==
2173                                 RTE_CRYPTO_ASYM_OP_VERIFY)
2174                         retval =
2175                                 process_openssl_dsa_verify_op(op, sess);
2176                 else
2177                         op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
2178                 break;
2179         default:
2180                 op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
2181                 break;
2182         }
2183         if (!retval) {
2184                 /* op processed so push to completion queue as processed */
2185                 retval = rte_ring_enqueue(qp->processed_ops, (void *)op);
2186                 if (retval)
2187                         /* return error if failed to put in completion queue */
2188                         retval = -1;
2189         }
2190
2191         return retval;
2192 }
2193
2194 static void
2195 copy_plaintext(struct rte_mbuf *m_src, struct rte_mbuf *m_dst,
2196                 struct rte_crypto_op *op)
2197 {
2198         uint8_t *p_src, *p_dst;
2199
2200         p_src = rte_pktmbuf_mtod(m_src, uint8_t *);
2201         p_dst = rte_pktmbuf_mtod(m_dst, uint8_t *);
2202
2203         /**
2204          * Copy the content between cipher offset and auth offset
2205          * for generating correct digest.
2206          */
2207         if (op->sym->cipher.data.offset > op->sym->auth.data.offset)
2208                 memcpy(p_dst + op->sym->auth.data.offset,
2209                                 p_src + op->sym->auth.data.offset,
2210                                 op->sym->cipher.data.offset -
2211                                 op->sym->auth.data.offset);
2212 }
2213
2214 /** Process crypto operation for mbuf */
2215 static int
2216 process_op(struct openssl_qp *qp, struct rte_crypto_op *op,
2217                 struct openssl_session *sess)
2218 {
2219         struct rte_mbuf *msrc, *mdst;
2220         int retval;
2221
2222         msrc = op->sym->m_src;
2223         mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
2224
2225         op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
2226
2227         switch (sess->chain_order) {
2228         case OPENSSL_CHAIN_ONLY_CIPHER:
2229                 process_openssl_cipher_op(op, sess, msrc, mdst);
2230                 break;
2231         case OPENSSL_CHAIN_ONLY_AUTH:
2232                 process_openssl_auth_op(qp, op, sess, msrc, mdst);
2233                 break;
2234         case OPENSSL_CHAIN_CIPHER_AUTH:
2235                 process_openssl_cipher_op(op, sess, msrc, mdst);
2236                 /* OOP */
2237                 if (msrc != mdst)
2238                         copy_plaintext(msrc, mdst, op);
2239                 process_openssl_auth_op(qp, op, sess, mdst, mdst);
2240                 break;
2241         case OPENSSL_CHAIN_AUTH_CIPHER:
2242                 process_openssl_auth_op(qp, op, sess, msrc, mdst);
2243                 process_openssl_cipher_op(op, sess, msrc, mdst);
2244                 break;
2245         case OPENSSL_CHAIN_COMBINED:
2246                 process_openssl_combined_op(op, sess, msrc, mdst);
2247                 break;
2248         case OPENSSL_CHAIN_CIPHER_BPI:
2249                 process_openssl_docsis_bpi_op(op, sess, msrc, mdst);
2250                 break;
2251         default:
2252                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
2253                 break;
2254         }
2255
2256         /* Free session if a session-less crypto op */
2257         if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
2258                 openssl_reset_session(sess);
2259                 memset(sess, 0, sizeof(struct openssl_session));
2260                 memset(op->sym->session, 0,
2261                         rte_cryptodev_sym_get_existing_header_session_size(
2262                                 op->sym->session));
2263                 rte_mempool_put(qp->sess_mp_priv, sess);
2264                 rte_mempool_put(qp->sess_mp, op->sym->session);
2265                 op->sym->session = NULL;
2266         }
2267
2268         if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
2269                 op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
2270
2271         if (op->status != RTE_CRYPTO_OP_STATUS_ERROR)
2272                 retval = rte_ring_enqueue(qp->processed_ops, (void *)op);
2273         else
2274                 retval = -1;
2275
2276         return retval;
2277 }
2278
2279 /*
2280  *------------------------------------------------------------------------------
2281  * PMD Framework
2282  *------------------------------------------------------------------------------
2283  */
2284
2285 /** Enqueue burst */
2286 static uint16_t
2287 openssl_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
2288                 uint16_t nb_ops)
2289 {
2290         void *sess;
2291         struct openssl_qp *qp = queue_pair;
2292         int i, retval;
2293
2294         for (i = 0; i < nb_ops; i++) {
2295                 sess = get_session(qp, ops[i]);
2296                 if (unlikely(sess == NULL))
2297                         goto enqueue_err;
2298
2299                 if (ops[i]->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC)
2300                         retval = process_op(qp, ops[i],
2301                                         (struct openssl_session *) sess);
2302                 else
2303                         retval = process_asym_op(qp, ops[i],
2304                                         (struct openssl_asym_session *) sess);
2305                 if (unlikely(retval < 0))
2306                         goto enqueue_err;
2307         }
2308
2309         qp->stats.enqueued_count += i;
2310         return i;
2311
2312 enqueue_err:
2313         qp->stats.enqueue_err_count++;
2314         return i;
2315 }
2316
2317 /** Dequeue burst */
2318 static uint16_t
2319 openssl_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
2320                 uint16_t nb_ops)
2321 {
2322         struct openssl_qp *qp = queue_pair;
2323
2324         unsigned int nb_dequeued = 0;
2325
2326         nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops,
2327                         (void **)ops, nb_ops, NULL);
2328         qp->stats.dequeued_count += nb_dequeued;
2329
2330         return nb_dequeued;
2331 }
2332
2333 /** Create OPENSSL crypto device */
2334 static int
2335 cryptodev_openssl_create(const char *name,
2336                         struct rte_vdev_device *vdev,
2337                         struct rte_cryptodev_pmd_init_params *init_params)
2338 {
2339         struct rte_cryptodev *dev;
2340         struct openssl_private *internals;
2341
2342         dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params);
2343         if (dev == NULL) {
2344                 OPENSSL_LOG(ERR, "failed to create cryptodev vdev");
2345                 goto init_error;
2346         }
2347
2348         dev->driver_id = cryptodev_driver_id;
2349         dev->dev_ops = rte_openssl_pmd_ops;
2350
2351         /* register rx/tx burst functions for data path */
2352         dev->dequeue_burst = openssl_pmd_dequeue_burst;
2353         dev->enqueue_burst = openssl_pmd_enqueue_burst;
2354
2355         dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
2356                         RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
2357                         RTE_CRYPTODEV_FF_CPU_AESNI |
2358                         RTE_CRYPTODEV_FF_IN_PLACE_SGL |
2359                         RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
2360                         RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
2361                         RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
2362                         RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP |
2363                         RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT |
2364                         RTE_CRYPTODEV_FF_SYM_SESSIONLESS;
2365
2366         internals = dev->data->dev_private;
2367
2368         internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
2369
2370         rte_cryptodev_pmd_probing_finish(dev);
2371
2372 # if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
2373         /* Load legacy provider
2374          * Some algorithms are no longer available in earlier version of openssl,
2375          * unless the legacy provider explicitly loaded. e.g. DES
2376          */
2377         ossl_legacy_provider_load();
2378 # endif
2379         return 0;
2380
2381 init_error:
2382         OPENSSL_LOG(ERR, "driver %s: create failed",
2383                         init_params->name);
2384
2385         cryptodev_openssl_remove(vdev);
2386         return -EFAULT;
2387 }
2388
2389 /** Initialise OPENSSL crypto device */
2390 static int
2391 cryptodev_openssl_probe(struct rte_vdev_device *vdev)
2392 {
2393         struct rte_cryptodev_pmd_init_params init_params = {
2394                 "",
2395                 sizeof(struct openssl_private),
2396                 rte_socket_id(),
2397                 RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
2398         };
2399         const char *name;
2400         const char *input_args;
2401
2402         name = rte_vdev_device_name(vdev);
2403         if (name == NULL)
2404                 return -EINVAL;
2405         input_args = rte_vdev_device_args(vdev);
2406
2407         rte_cryptodev_pmd_parse_input_args(&init_params, input_args);
2408
2409         return cryptodev_openssl_create(name, vdev, &init_params);
2410 }
2411
2412 /** Uninitialise OPENSSL crypto device */
2413 static int
2414 cryptodev_openssl_remove(struct rte_vdev_device *vdev)
2415 {
2416         struct rte_cryptodev *cryptodev;
2417         const char *name;
2418
2419         name = rte_vdev_device_name(vdev);
2420         if (name == NULL)
2421                 return -EINVAL;
2422
2423         cryptodev = rte_cryptodev_pmd_get_named_dev(name);
2424         if (cryptodev == NULL)
2425                 return -ENODEV;
2426
2427 # if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
2428         ossl_legacy_provider_unload();
2429 # endif
2430         return rte_cryptodev_pmd_destroy(cryptodev);
2431 }
2432
2433 static struct rte_vdev_driver cryptodev_openssl_pmd_drv = {
2434         .probe = cryptodev_openssl_probe,
2435         .remove = cryptodev_openssl_remove
2436 };
2437
2438 static struct cryptodev_driver openssl_crypto_drv;
2439
2440 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_OPENSSL_PMD,
2441         cryptodev_openssl_pmd_drv);
2442 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_OPENSSL_PMD,
2443         "max_nb_queue_pairs=<int> "
2444         "socket_id=<int>");
2445 RTE_PMD_REGISTER_CRYPTO_DRIVER(openssl_crypto_drv,
2446                 cryptodev_openssl_pmd_drv.driver, cryptodev_driver_id);
2447 RTE_LOG_REGISTER_DEFAULT(openssl_logtype_driver, INFO);