cc1ec394ea2f3d0023b9bb89eff251e79145988b
[dpdk.git] / drivers / crypto / openssl / rte_openssl_pmd.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Intel Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <rte_common.h>
34 #include <rte_hexdump.h>
35 #include <rte_cryptodev.h>
36 #include <rte_cryptodev_pmd.h>
37 #include <rte_cryptodev_vdev.h>
38 #include <rte_vdev.h>
39 #include <rte_malloc.h>
40 #include <rte_cpuflags.h>
41
42 #include <openssl/hmac.h>
43 #include <openssl/evp.h>
44
45 #include "rte_openssl_pmd_private.h"
46
47 #define DES_BLOCK_SIZE 8
48
49 static uint8_t cryptodev_driver_id;
50
51 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
52 static HMAC_CTX *HMAC_CTX_new(void)
53 {
54         HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
55
56         if (ctx != NULL)
57                 HMAC_CTX_init(ctx);
58         return ctx;
59 }
60
61 static void HMAC_CTX_free(HMAC_CTX *ctx)
62 {
63         if (ctx != NULL) {
64                 HMAC_CTX_cleanup(ctx);
65                 OPENSSL_free(ctx);
66         }
67 }
68 #endif
69
70 static int cryptodev_openssl_remove(struct rte_vdev_device *vdev);
71
72 /*----------------------------------------------------------------------------*/
73
74 /**
75  * Increment counter by 1
76  * Counter is 64 bit array, big-endian
77  */
78 static void
79 ctr_inc(uint8_t *ctr)
80 {
81         uint64_t *ctr64 = (uint64_t *)ctr;
82
83         *ctr64 = __builtin_bswap64(*ctr64);
84         (*ctr64)++;
85         *ctr64 = __builtin_bswap64(*ctr64);
86 }
87
88 /*
89  *------------------------------------------------------------------------------
90  * Session Prepare
91  *------------------------------------------------------------------------------
92  */
93
94 /** Get xform chain order */
95 static enum openssl_chain_order
96 openssl_get_chain_order(const struct rte_crypto_sym_xform *xform)
97 {
98         enum openssl_chain_order res = OPENSSL_CHAIN_NOT_SUPPORTED;
99
100         if (xform != NULL) {
101                 if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
102                         if (xform->next == NULL)
103                                 res =  OPENSSL_CHAIN_ONLY_AUTH;
104                         else if (xform->next->type ==
105                                         RTE_CRYPTO_SYM_XFORM_CIPHER)
106                                 res =  OPENSSL_CHAIN_AUTH_CIPHER;
107                 }
108                 if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
109                         if (xform->next == NULL)
110                                 res =  OPENSSL_CHAIN_ONLY_CIPHER;
111                         else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
112                                 res =  OPENSSL_CHAIN_CIPHER_AUTH;
113                 }
114                 if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
115                         res = OPENSSL_CHAIN_COMBINED;
116         }
117
118         return res;
119 }
120
121 /** Get session cipher key from input cipher key */
122 static void
123 get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key)
124 {
125         memcpy(session_key, input_key, keylen);
126 }
127
128 /** Get key ede 24 bytes standard from input key */
129 static int
130 get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede)
131 {
132         int res = 0;
133
134         /* Initialize keys - 24 bytes: [key1-key2-key3] */
135         switch (keylen) {
136         case 24:
137                 memcpy(key_ede, key, 24);
138                 break;
139         case 16:
140                 /* K3 = K1 */
141                 memcpy(key_ede, key, 16);
142                 memcpy(key_ede + 16, key, 8);
143                 break;
144         case 8:
145                 /* K1 = K2 = K3 (DES compatibility) */
146                 memcpy(key_ede, key, 8);
147                 memcpy(key_ede + 8, key, 8);
148                 memcpy(key_ede + 16, key, 8);
149                 break;
150         default:
151                 OPENSSL_LOG_ERR("Unsupported key size");
152                 res = -EINVAL;
153         }
154
155         return res;
156 }
157
158 /** Get adequate openssl function for input cipher algorithm */
159 static uint8_t
160 get_cipher_algo(enum rte_crypto_cipher_algorithm sess_algo, size_t keylen,
161                 const EVP_CIPHER **algo)
162 {
163         int res = 0;
164
165         if (algo != NULL) {
166                 switch (sess_algo) {
167                 case RTE_CRYPTO_CIPHER_3DES_CBC:
168                         switch (keylen) {
169                         case 16:
170                                 *algo = EVP_des_ede_cbc();
171                                 break;
172                         case 24:
173                                 *algo = EVP_des_ede3_cbc();
174                                 break;
175                         default:
176                                 res = -EINVAL;
177                         }
178                         break;
179                 case RTE_CRYPTO_CIPHER_3DES_CTR:
180                         break;
181                 case RTE_CRYPTO_CIPHER_AES_CBC:
182                         switch (keylen) {
183                         case 16:
184                                 *algo = EVP_aes_128_cbc();
185                                 break;
186                         case 24:
187                                 *algo = EVP_aes_192_cbc();
188                                 break;
189                         case 32:
190                                 *algo = EVP_aes_256_cbc();
191                                 break;
192                         default:
193                                 res = -EINVAL;
194                         }
195                         break;
196                 case RTE_CRYPTO_CIPHER_AES_CTR:
197                         switch (keylen) {
198                         case 16:
199                                 *algo = EVP_aes_128_ctr();
200                                 break;
201                         case 24:
202                                 *algo = EVP_aes_192_ctr();
203                                 break;
204                         case 32:
205                                 *algo = EVP_aes_256_ctr();
206                                 break;
207                         default:
208                                 res = -EINVAL;
209                         }
210                         break;
211                 default:
212                         res = -EINVAL;
213                         break;
214                 }
215         } else {
216                 res = -EINVAL;
217         }
218
219         return res;
220 }
221
222 /** Get adequate openssl function for input auth algorithm */
223 static uint8_t
224 get_auth_algo(enum rte_crypto_auth_algorithm sessalgo,
225                 const EVP_MD **algo)
226 {
227         int res = 0;
228
229         if (algo != NULL) {
230                 switch (sessalgo) {
231                 case RTE_CRYPTO_AUTH_MD5:
232                 case RTE_CRYPTO_AUTH_MD5_HMAC:
233                         *algo = EVP_md5();
234                         break;
235                 case RTE_CRYPTO_AUTH_SHA1:
236                 case RTE_CRYPTO_AUTH_SHA1_HMAC:
237                         *algo = EVP_sha1();
238                         break;
239                 case RTE_CRYPTO_AUTH_SHA224:
240                 case RTE_CRYPTO_AUTH_SHA224_HMAC:
241                         *algo = EVP_sha224();
242                         break;
243                 case RTE_CRYPTO_AUTH_SHA256:
244                 case RTE_CRYPTO_AUTH_SHA256_HMAC:
245                         *algo = EVP_sha256();
246                         break;
247                 case RTE_CRYPTO_AUTH_SHA384:
248                 case RTE_CRYPTO_AUTH_SHA384_HMAC:
249                         *algo = EVP_sha384();
250                         break;
251                 case RTE_CRYPTO_AUTH_SHA512:
252                 case RTE_CRYPTO_AUTH_SHA512_HMAC:
253                         *algo = EVP_sha512();
254                         break;
255                 default:
256                         res = -EINVAL;
257                         break;
258                 }
259         } else {
260                 res = -EINVAL;
261         }
262
263         return res;
264 }
265
266 /** Get adequate openssl function for input cipher algorithm */
267 static uint8_t
268 get_aead_algo(enum rte_crypto_aead_algorithm sess_algo, size_t keylen,
269                 const EVP_CIPHER **algo)
270 {
271         int res = 0;
272
273         if (algo != NULL) {
274                 switch (sess_algo) {
275                 case RTE_CRYPTO_AEAD_AES_GCM:
276                         switch (keylen) {
277                         case 16:
278                                 *algo = EVP_aes_128_gcm();
279                                 break;
280                         case 24:
281                                 *algo = EVP_aes_192_gcm();
282                                 break;
283                         case 32:
284                                 *algo = EVP_aes_256_gcm();
285                                 break;
286                         default:
287                                 res = -EINVAL;
288                         }
289                         break;
290                 default:
291                         res = -EINVAL;
292                         break;
293                 }
294         } else {
295                 res = -EINVAL;
296         }
297
298         return res;
299 }
300
301 /** Set session cipher parameters */
302 static int
303 openssl_set_session_cipher_parameters(struct openssl_session *sess,
304                 const struct rte_crypto_sym_xform *xform)
305 {
306         /* Select cipher direction */
307         sess->cipher.direction = xform->cipher.op;
308         /* Select cipher key */
309         sess->cipher.key.length = xform->cipher.key.length;
310
311         /* Set IV parameters */
312         sess->iv.offset = xform->cipher.iv.offset;
313         sess->iv.length = xform->cipher.iv.length;
314
315         /* Select cipher algo */
316         switch (xform->cipher.algo) {
317         case RTE_CRYPTO_CIPHER_3DES_CBC:
318         case RTE_CRYPTO_CIPHER_AES_CBC:
319         case RTE_CRYPTO_CIPHER_AES_CTR:
320                 sess->cipher.mode = OPENSSL_CIPHER_LIB;
321                 sess->cipher.algo = xform->cipher.algo;
322                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
323
324                 if (get_cipher_algo(sess->cipher.algo, sess->cipher.key.length,
325                                 &sess->cipher.evp_algo) != 0)
326                         return -EINVAL;
327
328                 get_cipher_key(xform->cipher.key.data, sess->cipher.key.length,
329                         sess->cipher.key.data);
330                 if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
331                         if (EVP_EncryptInit_ex(sess->cipher.ctx,
332                                         sess->cipher.evp_algo,
333                                         NULL, xform->cipher.key.data,
334                                         NULL) != 1) {
335                                 return -EINVAL;
336                         }
337                 } else if (sess->cipher.direction ==
338                                 RTE_CRYPTO_CIPHER_OP_DECRYPT) {
339                         if (EVP_DecryptInit_ex(sess->cipher.ctx,
340                                         sess->cipher.evp_algo,
341                                         NULL, xform->cipher.key.data,
342                                         NULL) != 1) {
343                                 return -EINVAL;
344                         }
345                 }
346
347                 break;
348
349         case RTE_CRYPTO_CIPHER_3DES_CTR:
350                 sess->cipher.mode = OPENSSL_CIPHER_DES3CTR;
351                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
352
353                 if (get_cipher_key_ede(xform->cipher.key.data,
354                                 sess->cipher.key.length,
355                                 sess->cipher.key.data) != 0)
356                         return -EINVAL;
357                 break;
358
359         case RTE_CRYPTO_CIPHER_DES_CBC:
360                 sess->cipher.algo = xform->cipher.algo;
361                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
362                 sess->cipher.evp_algo = EVP_des_cbc();
363
364                 get_cipher_key(xform->cipher.key.data, sess->cipher.key.length,
365                         sess->cipher.key.data);
366                 if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
367                         if (EVP_EncryptInit_ex(sess->cipher.ctx,
368                                         sess->cipher.evp_algo,
369                                         NULL, xform->cipher.key.data,
370                                         NULL) != 1) {
371                                 return -EINVAL;
372                         }
373                 } else if (sess->cipher.direction ==
374                                 RTE_CRYPTO_CIPHER_OP_DECRYPT) {
375                         if (EVP_DecryptInit_ex(sess->cipher.ctx,
376                                         sess->cipher.evp_algo,
377                                         NULL, xform->cipher.key.data,
378                                         NULL) != 1) {
379                                 return -EINVAL;
380                         }
381                 }
382
383                 break;
384
385         case RTE_CRYPTO_CIPHER_DES_DOCSISBPI:
386                 sess->cipher.algo = xform->cipher.algo;
387                 sess->chain_order = OPENSSL_CHAIN_CIPHER_BPI;
388                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
389                 sess->cipher.evp_algo = EVP_des_cbc();
390
391                 sess->cipher.bpi_ctx = EVP_CIPHER_CTX_new();
392                 /* IV will be ECB encrypted whether direction is encrypt or decrypt */
393                 if (EVP_EncryptInit_ex(sess->cipher.bpi_ctx, EVP_des_ecb(),
394                                 NULL, xform->cipher.key.data, 0) != 1)
395                         return -EINVAL;
396
397                 get_cipher_key(xform->cipher.key.data, sess->cipher.key.length,
398                         sess->cipher.key.data);
399                 if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
400                         if (EVP_EncryptInit_ex(sess->cipher.ctx,
401                                         sess->cipher.evp_algo,
402                                         NULL, xform->cipher.key.data,
403                                         NULL) != 1) {
404                                 return -EINVAL;
405                         }
406                 } else if (sess->cipher.direction ==
407                                 RTE_CRYPTO_CIPHER_OP_DECRYPT) {
408                         if (EVP_DecryptInit_ex(sess->cipher.ctx,
409                                         sess->cipher.evp_algo,
410                                         NULL, xform->cipher.key.data,
411                                         NULL) != 1) {
412                                 return -EINVAL;
413                         }
414                 }
415
416                 break;
417         default:
418                 sess->cipher.algo = RTE_CRYPTO_CIPHER_NULL;
419                 return -ENOTSUP;
420         }
421
422         return 0;
423 }
424
425 /* Set session auth parameters */
426 static int
427 openssl_set_session_auth_parameters(struct openssl_session *sess,
428                 const struct rte_crypto_sym_xform *xform)
429 {
430         /* Select auth generate/verify */
431         sess->auth.operation = xform->auth.op;
432         sess->auth.algo = xform->auth.algo;
433
434         /* Select auth algo */
435         switch (xform->auth.algo) {
436         case RTE_CRYPTO_AUTH_AES_GMAC:
437                 sess->chain_order = OPENSSL_CHAIN_COMBINED;
438
439                 /* Set IV parameters */
440                 sess->iv.offset = xform->auth.iv.offset;
441                 sess->iv.length = xform->auth.iv.length;
442
443                 /*
444                  * OpenSSL requires GMAC to be a GCM operation
445                  * with no cipher data length
446                  */
447                 sess->cipher.mode = OPENSSL_CIPHER_LIB;
448                 if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_GENERATE)
449                         sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
450                 else
451                         sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_DECRYPT;
452
453                 sess->cipher.key.length = xform->auth.key.length;
454                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
455
456                 if (get_aead_algo(RTE_CRYPTO_AEAD_AES_GCM,
457                                 sess->cipher.key.length,
458                                 &sess->cipher.evp_algo) != 0)
459                         return -EINVAL;
460
461                 get_cipher_key(xform->auth.key.data, xform->auth.key.length,
462                         sess->cipher.key.data);
463
464                 break;
465
466         case RTE_CRYPTO_AUTH_MD5:
467         case RTE_CRYPTO_AUTH_SHA1:
468         case RTE_CRYPTO_AUTH_SHA224:
469         case RTE_CRYPTO_AUTH_SHA256:
470         case RTE_CRYPTO_AUTH_SHA384:
471         case RTE_CRYPTO_AUTH_SHA512:
472                 sess->auth.mode = OPENSSL_AUTH_AS_AUTH;
473                 if (get_auth_algo(xform->auth.algo,
474                                 &sess->auth.auth.evp_algo) != 0)
475                         return -EINVAL;
476                 sess->auth.auth.ctx = EVP_MD_CTX_create();
477                 break;
478
479         case RTE_CRYPTO_AUTH_MD5_HMAC:
480         case RTE_CRYPTO_AUTH_SHA1_HMAC:
481         case RTE_CRYPTO_AUTH_SHA224_HMAC:
482         case RTE_CRYPTO_AUTH_SHA256_HMAC:
483         case RTE_CRYPTO_AUTH_SHA384_HMAC:
484         case RTE_CRYPTO_AUTH_SHA512_HMAC:
485                 sess->auth.mode = OPENSSL_AUTH_AS_HMAC;
486                 sess->auth.hmac.ctx = HMAC_CTX_new();
487                 if (get_auth_algo(xform->auth.algo,
488                                 &sess->auth.hmac.evp_algo) != 0)
489                         return -EINVAL;
490
491                 if (HMAC_Init_ex(sess->auth.hmac.ctx,
492                                 xform->auth.key.data,
493                                 xform->auth.key.length,
494                                 sess->auth.hmac.evp_algo, NULL) != 1)
495                         return -EINVAL;
496                 break;
497
498         default:
499                 return -ENOTSUP;
500         }
501
502         sess->auth.digest_length = xform->auth.digest_length;
503
504         return 0;
505 }
506
507 /* Set session AEAD parameters */
508 static int
509 openssl_set_session_aead_parameters(struct openssl_session *sess,
510                 const struct rte_crypto_sym_xform *xform)
511 {
512         /* Select cipher direction and auth operation */
513         if (xform->aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
514                 sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
515                 sess->auth.operation = RTE_CRYPTO_AUTH_OP_GENERATE;
516         } else {
517                 sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_DECRYPT;
518                 sess->auth.operation = RTE_CRYPTO_AUTH_OP_VERIFY;
519         }
520
521         /* Select cipher key */
522         sess->cipher.key.length = xform->aead.key.length;
523
524         /* Set IV parameters */
525         sess->iv.offset = xform->aead.iv.offset;
526         sess->iv.length = xform->aead.iv.length;
527
528         /* Select auth algo */
529         switch (xform->aead.algo) {
530         case RTE_CRYPTO_AEAD_AES_GCM:
531                 sess->cipher.mode = OPENSSL_CIPHER_LIB;
532                 sess->aead_algo = xform->aead.algo;
533                 sess->cipher.ctx = EVP_CIPHER_CTX_new();
534
535                 if (get_aead_algo(sess->aead_algo, sess->cipher.key.length,
536                                 &sess->cipher.evp_algo) != 0)
537                         return -EINVAL;
538
539                 get_cipher_key(xform->cipher.key.data, sess->cipher.key.length,
540                         sess->cipher.key.data);
541
542                 sess->chain_order = OPENSSL_CHAIN_COMBINED;
543                 break;
544         default:
545                 return -ENOTSUP;
546         }
547
548         sess->auth.aad_length = xform->aead.aad_length;
549         sess->auth.digest_length = xform->aead.digest_length;
550
551         return 0;
552 }
553
554 /** Parse crypto xform chain and set private session parameters */
555 int
556 openssl_set_session_parameters(struct openssl_session *sess,
557                 const struct rte_crypto_sym_xform *xform)
558 {
559         const struct rte_crypto_sym_xform *cipher_xform = NULL;
560         const struct rte_crypto_sym_xform *auth_xform = NULL;
561         const struct rte_crypto_sym_xform *aead_xform = NULL;
562         int ret;
563
564         sess->chain_order = openssl_get_chain_order(xform);
565         switch (sess->chain_order) {
566         case OPENSSL_CHAIN_ONLY_CIPHER:
567                 cipher_xform = xform;
568                 break;
569         case OPENSSL_CHAIN_ONLY_AUTH:
570                 auth_xform = xform;
571                 break;
572         case OPENSSL_CHAIN_CIPHER_AUTH:
573                 cipher_xform = xform;
574                 auth_xform = xform->next;
575                 break;
576         case OPENSSL_CHAIN_AUTH_CIPHER:
577                 auth_xform = xform;
578                 cipher_xform = xform->next;
579                 break;
580         case OPENSSL_CHAIN_COMBINED:
581                 aead_xform = xform;
582                 break;
583         default:
584                 return -EINVAL;
585         }
586
587         /* Default IV length = 0 */
588         sess->iv.length = 0;
589
590         /* cipher_xform must be check before auth_xform */
591         if (cipher_xform) {
592                 ret = openssl_set_session_cipher_parameters(
593                                 sess, cipher_xform);
594                 if (ret != 0) {
595                         OPENSSL_LOG_ERR(
596                                 "Invalid/unsupported cipher parameters");
597                         return ret;
598                 }
599         }
600
601         if (auth_xform) {
602                 ret = openssl_set_session_auth_parameters(sess, auth_xform);
603                 if (ret != 0) {
604                         OPENSSL_LOG_ERR(
605                                 "Invalid/unsupported auth parameters");
606                         return ret;
607                 }
608         }
609
610         if (aead_xform) {
611                 ret = openssl_set_session_aead_parameters(sess, aead_xform);
612                 if (ret != 0) {
613                         OPENSSL_LOG_ERR(
614                                 "Invalid/unsupported AEAD parameters");
615                         return ret;
616                 }
617         }
618
619         return 0;
620 }
621
622 /** Reset private session parameters */
623 void
624 openssl_reset_session(struct openssl_session *sess)
625 {
626         EVP_CIPHER_CTX_free(sess->cipher.ctx);
627
628         if (sess->chain_order == OPENSSL_CHAIN_CIPHER_BPI)
629                 EVP_CIPHER_CTX_free(sess->cipher.bpi_ctx);
630
631         switch (sess->auth.mode) {
632         case OPENSSL_AUTH_AS_AUTH:
633                 EVP_MD_CTX_destroy(sess->auth.auth.ctx);
634                 break;
635         case OPENSSL_AUTH_AS_HMAC:
636                 EVP_PKEY_free(sess->auth.hmac.pkey);
637                 HMAC_CTX_free(sess->auth.hmac.ctx);
638                 break;
639         default:
640                 break;
641         }
642 }
643
644 /** Provide session for operation */
645 static struct openssl_session *
646 get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
647 {
648         struct openssl_session *sess = NULL;
649
650         if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
651                 /* get existing session */
652                 if (likely(op->sym->session != NULL))
653                         sess = (struct openssl_session *)
654                                         get_session_private_data(
655                                         op->sym->session,
656                                         cryptodev_driver_id);
657         } else {
658                 /* provide internal session */
659                 void *_sess = NULL;
660                 void *_sess_private_data = NULL;
661
662                 if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
663                         return NULL;
664
665                 if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
666                         return NULL;
667
668                 sess = (struct openssl_session *)_sess_private_data;
669
670                 if (unlikely(openssl_set_session_parameters(sess,
671                                 op->sym->xform) != 0)) {
672                         rte_mempool_put(qp->sess_mp, _sess);
673                         rte_mempool_put(qp->sess_mp, _sess_private_data);
674                         sess = NULL;
675                 }
676                 op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
677                 set_session_private_data(op->sym->session, cryptodev_driver_id,
678                         _sess_private_data);
679         }
680
681         if (sess == NULL)
682                 op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
683
684         return sess;
685 }
686
687 /*
688  *------------------------------------------------------------------------------
689  * Process Operations
690  *------------------------------------------------------------------------------
691  */
692 static inline int
693 process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
694                 uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
695 {
696         struct rte_mbuf *m;
697         int dstlen;
698         int l, n = srclen;
699         uint8_t *src;
700
701         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
702                         m = m->next)
703                 offset -= rte_pktmbuf_data_len(m);
704
705         if (m == 0)
706                 return -1;
707
708         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
709
710         l = rte_pktmbuf_data_len(m) - offset;
711         if (srclen <= l) {
712                 if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, srclen) <= 0)
713                         return -1;
714                 *dst += l;
715                 return 0;
716         }
717
718         if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
719                 return -1;
720
721         *dst += dstlen;
722         n -= l;
723
724         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
725                 src = rte_pktmbuf_mtod(m, uint8_t *);
726                 l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
727                 if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
728                         return -1;
729                 *dst += dstlen;
730                 n -= l;
731         }
732
733         return 0;
734 }
735
736 static inline int
737 process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
738                 uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
739 {
740         struct rte_mbuf *m;
741         int dstlen;
742         int l, n = srclen;
743         uint8_t *src;
744
745         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
746                         m = m->next)
747                 offset -= rte_pktmbuf_data_len(m);
748
749         if (m == 0)
750                 return -1;
751
752         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
753
754         l = rte_pktmbuf_data_len(m) - offset;
755         if (srclen <= l) {
756                 if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, srclen) <= 0)
757                         return -1;
758                 *dst += l;
759                 return 0;
760         }
761
762         if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
763                 return -1;
764
765         *dst += dstlen;
766         n -= l;
767
768         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
769                 src = rte_pktmbuf_mtod(m, uint8_t *);
770                 l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
771                 if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
772                         return -1;
773                 *dst += dstlen;
774                 n -= l;
775         }
776
777         return 0;
778 }
779
780 /** Process standard openssl cipher encryption */
781 static int
782 process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
783                 int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
784 {
785         int totlen;
786
787         if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
788                 goto process_cipher_encrypt_err;
789
790         EVP_CIPHER_CTX_set_padding(ctx, 0);
791
792         if (process_openssl_encryption_update(mbuf_src, offset, &dst,
793                         srclen, ctx))
794                 goto process_cipher_encrypt_err;
795
796         if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0)
797                 goto process_cipher_encrypt_err;
798
799         return 0;
800
801 process_cipher_encrypt_err:
802         OPENSSL_LOG_ERR("Process openssl cipher encrypt failed");
803         return -EINVAL;
804 }
805
806 /** Process standard openssl cipher encryption */
807 static int
808 process_openssl_cipher_bpi_encrypt(uint8_t *src, uint8_t *dst,
809                 uint8_t *iv, int srclen,
810                 EVP_CIPHER_CTX *ctx)
811 {
812         uint8_t i;
813         uint8_t encrypted_iv[DES_BLOCK_SIZE];
814         int encrypted_ivlen;
815
816         if (EVP_EncryptUpdate(ctx, encrypted_iv, &encrypted_ivlen,
817                         iv, DES_BLOCK_SIZE) <= 0)
818                 goto process_cipher_encrypt_err;
819
820         for (i = 0; i < srclen; i++)
821                 *(dst + i) = *(src + i) ^ (encrypted_iv[i]);
822
823         return 0;
824
825 process_cipher_encrypt_err:
826         OPENSSL_LOG_ERR("Process openssl cipher bpi encrypt failed");
827         return -EINVAL;
828 }
829 /** Process standard openssl cipher decryption */
830 static int
831 process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
832                 int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
833 {
834         int totlen;
835
836         if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
837                 goto process_cipher_decrypt_err;
838
839         EVP_CIPHER_CTX_set_padding(ctx, 0);
840
841         if (process_openssl_decryption_update(mbuf_src, offset, &dst,
842                         srclen, ctx))
843                 goto process_cipher_decrypt_err;
844
845         if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0)
846                 goto process_cipher_decrypt_err;
847         return 0;
848
849 process_cipher_decrypt_err:
850         OPENSSL_LOG_ERR("Process openssl cipher decrypt failed");
851         return -EINVAL;
852 }
853
854 /** Process cipher des 3 ctr encryption, decryption algorithm */
855 static int
856 process_openssl_cipher_des3ctr(struct rte_mbuf *mbuf_src, uint8_t *dst,
857                 int offset, uint8_t *iv, uint8_t *key, int srclen,
858                 EVP_CIPHER_CTX *ctx)
859 {
860         uint8_t ebuf[8], ctr[8];
861         int unused, n;
862         struct rte_mbuf *m;
863         uint8_t *src;
864         int l;
865
866         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
867                         m = m->next)
868                 offset -= rte_pktmbuf_data_len(m);
869
870         if (m == 0)
871                 goto process_cipher_des3ctr_err;
872
873         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
874         l = rte_pktmbuf_data_len(m) - offset;
875
876         /* We use 3DES encryption also for decryption.
877          * IV is not important for 3DES ecb
878          */
879         if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) <= 0)
880                 goto process_cipher_des3ctr_err;
881
882         memcpy(ctr, iv, 8);
883
884         for (n = 0; n < srclen; n++) {
885                 if (n % 8 == 0) {
886                         if (EVP_EncryptUpdate(ctx,
887                                         (unsigned char *)&ebuf, &unused,
888                                         (const unsigned char *)&ctr, 8) <= 0)
889                                 goto process_cipher_des3ctr_err;
890                         ctr_inc(ctr);
891                 }
892                 dst[n] = *(src++) ^ ebuf[n % 8];
893
894                 l--;
895                 if (!l) {
896                         m = m->next;
897                         if (m) {
898                                 src = rte_pktmbuf_mtod(m, uint8_t *);
899                                 l = rte_pktmbuf_data_len(m);
900                         }
901                 }
902         }
903
904         return 0;
905
906 process_cipher_des3ctr_err:
907         OPENSSL_LOG_ERR("Process openssl cipher des 3 ede ctr failed");
908         return -EINVAL;
909 }
910
911 /** Process auth/encription aes-gcm algorithm */
912 static int
913 process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset,
914                 int srclen, uint8_t *aad, int aadlen, uint8_t *iv, int ivlen,
915                 uint8_t *key, uint8_t *dst, uint8_t *tag,
916                 EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
917 {
918         int len = 0, unused = 0;
919         uint8_t empty[] = {};
920
921         if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
922                 goto process_auth_encryption_gcm_err;
923
924         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0)
925                 goto process_auth_encryption_gcm_err;
926
927         if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
928                 goto process_auth_encryption_gcm_err;
929
930         if (aadlen > 0)
931                 if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0)
932                         goto process_auth_encryption_gcm_err;
933
934         if (srclen > 0)
935                 if (process_openssl_encryption_update(mbuf_src, offset, &dst,
936                                 srclen, ctx))
937                         goto process_auth_encryption_gcm_err;
938
939         /* Workaround open ssl bug in version less then 1.0.1f */
940         if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
941                 goto process_auth_encryption_gcm_err;
942
943         if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0)
944                 goto process_auth_encryption_gcm_err;
945
946         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0)
947                 goto process_auth_encryption_gcm_err;
948
949         return 0;
950
951 process_auth_encryption_gcm_err:
952         OPENSSL_LOG_ERR("Process openssl auth encryption gcm failed");
953         return -EINVAL;
954 }
955
956 static int
957 process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
958                 int srclen, uint8_t *aad, int aadlen, uint8_t *iv, int ivlen,
959                 uint8_t *key, uint8_t *dst, uint8_t *tag, EVP_CIPHER_CTX *ctx,
960                 const EVP_CIPHER *algo)
961 {
962         int len = 0, unused = 0;
963         uint8_t empty[] = {};
964
965         if (EVP_DecryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
966                 goto process_auth_decryption_gcm_err;
967
968         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0)
969                 goto process_auth_decryption_gcm_err;
970
971         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) <= 0)
972                 goto process_auth_decryption_gcm_err;
973
974         if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
975                 goto process_auth_decryption_gcm_err;
976
977         if (aadlen > 0)
978                 if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0)
979                         goto process_auth_decryption_gcm_err;
980
981         if (srclen > 0)
982                 if (process_openssl_decryption_update(mbuf_src, offset, &dst,
983                                 srclen, ctx))
984                         goto process_auth_decryption_gcm_err;
985
986         /* Workaround open ssl bug in version less then 1.0.1f */
987         if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
988                 goto process_auth_decryption_gcm_err;
989
990         if (EVP_DecryptFinal_ex(ctx, dst, &len) <= 0)
991                 goto process_auth_decryption_gcm_final_err;
992
993         return 0;
994
995 process_auth_decryption_gcm_err:
996         OPENSSL_LOG_ERR("Process openssl auth description gcm failed");
997         return -EINVAL;
998
999 process_auth_decryption_gcm_final_err:
1000         return -EFAULT;
1001 }
1002
1003 /** Process standard openssl auth algorithms */
1004 static int
1005 process_openssl_auth(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset,
1006                 __rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey,
1007                 int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo)
1008 {
1009         size_t dstlen;
1010         struct rte_mbuf *m;
1011         int l, n = srclen;
1012         uint8_t *src;
1013
1014         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
1015                         m = m->next)
1016                 offset -= rte_pktmbuf_data_len(m);
1017
1018         if (m == 0)
1019                 goto process_auth_err;
1020
1021         if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0)
1022                 goto process_auth_err;
1023
1024         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
1025
1026         l = rte_pktmbuf_data_len(m) - offset;
1027         if (srclen <= l) {
1028                 if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0)
1029                         goto process_auth_err;
1030                 goto process_auth_final;
1031         }
1032
1033         if (EVP_DigestUpdate(ctx, (char *)src, l) <= 0)
1034                 goto process_auth_err;
1035
1036         n -= l;
1037
1038         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
1039                 src = rte_pktmbuf_mtod(m, uint8_t *);
1040                 l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
1041                 if (EVP_DigestUpdate(ctx, (char *)src, l) <= 0)
1042                         goto process_auth_err;
1043                 n -= l;
1044         }
1045
1046 process_auth_final:
1047         if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0)
1048                 goto process_auth_err;
1049         return 0;
1050
1051 process_auth_err:
1052         OPENSSL_LOG_ERR("Process openssl auth failed");
1053         return -EINVAL;
1054 }
1055
1056 /** Process standard openssl auth algorithms with hmac */
1057 static int
1058 process_openssl_auth_hmac(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset,
1059                 int srclen, HMAC_CTX *ctx)
1060 {
1061         unsigned int dstlen;
1062         struct rte_mbuf *m;
1063         int l, n = srclen;
1064         uint8_t *src;
1065
1066         for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
1067                         m = m->next)
1068                 offset -= rte_pktmbuf_data_len(m);
1069
1070         if (m == 0)
1071                 goto process_auth_err;
1072
1073         src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
1074
1075         l = rte_pktmbuf_data_len(m) - offset;
1076         if (srclen <= l) {
1077                 if (HMAC_Update(ctx, (unsigned char *)src, srclen) != 1)
1078                         goto process_auth_err;
1079                 goto process_auth_final;
1080         }
1081
1082         if (HMAC_Update(ctx, (unsigned char *)src, l) != 1)
1083                 goto process_auth_err;
1084
1085         n -= l;
1086
1087         for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
1088                 src = rte_pktmbuf_mtod(m, uint8_t *);
1089                 l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
1090                 if (HMAC_Update(ctx, (unsigned char *)src, l) != 1)
1091                         goto process_auth_err;
1092                 n -= l;
1093         }
1094
1095 process_auth_final:
1096         if (HMAC_Final(ctx, dst, &dstlen) != 1)
1097                 goto process_auth_err;
1098
1099         if (unlikely(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL) != 1))
1100                 goto process_auth_err;
1101
1102         return 0;
1103
1104 process_auth_err:
1105         OPENSSL_LOG_ERR("Process openssl auth failed");
1106         return -EINVAL;
1107 }
1108
1109 /*----------------------------------------------------------------------------*/
1110
1111 /** Process auth/cipher combined operation */
1112 static void
1113 process_openssl_combined_op
1114                 (struct rte_crypto_op *op, struct openssl_session *sess,
1115                 struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
1116 {
1117         /* cipher */
1118         uint8_t *dst = NULL, *iv, *tag, *aad;
1119         int srclen, ivlen, aadlen, status = -1;
1120         uint32_t offset;
1121
1122         /*
1123          * Segmented destination buffer is not supported for
1124          * encryption/decryption
1125          */
1126         if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
1127                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1128                 return;
1129         }
1130
1131         iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1132                         sess->iv.offset);
1133         ivlen = sess->iv.length;
1134         if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
1135                 srclen = 0;
1136                 offset = op->sym->auth.data.offset;
1137                 aadlen = op->sym->auth.data.length;
1138                 aad = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
1139                                 op->sym->auth.data.offset);
1140                 tag = op->sym->auth.digest.data;
1141                 if (tag == NULL)
1142                         tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1143                                 offset + aadlen);
1144         } else {
1145                 srclen = op->sym->aead.data.length;
1146                 dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1147                                 op->sym->aead.data.offset);
1148                 offset = op->sym->aead.data.offset;
1149                 aad = op->sym->aead.aad.data;
1150                 aadlen = sess->auth.aad_length;
1151                 tag = op->sym->aead.digest.data;
1152                 if (tag == NULL)
1153                         tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1154                                 offset + srclen);
1155         }
1156
1157         if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
1158                 status = process_openssl_auth_encryption_gcm(
1159                                 mbuf_src, offset, srclen,
1160                                 aad, aadlen, iv, ivlen, sess->cipher.key.data,
1161                                 dst, tag, sess->cipher.ctx,
1162                                 sess->cipher.evp_algo);
1163         else
1164                 status = process_openssl_auth_decryption_gcm(
1165                                 mbuf_src, offset, srclen,
1166                                 aad, aadlen, iv, ivlen, sess->cipher.key.data,
1167                                 dst, tag, sess->cipher.ctx,
1168                                 sess->cipher.evp_algo);
1169
1170         if (status != 0) {
1171                 if (status == (-EFAULT) &&
1172                                 sess->auth.operation ==
1173                                                 RTE_CRYPTO_AUTH_OP_VERIFY)
1174                         op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
1175                 else
1176                         op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1177         }
1178 }
1179
1180 /** Process cipher operation */
1181 static void
1182 process_openssl_cipher_op
1183                 (struct rte_crypto_op *op, struct openssl_session *sess,
1184                 struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
1185 {
1186         uint8_t *dst, *iv;
1187         int srclen, status;
1188
1189         /*
1190          * Segmented destination buffer is not supported for
1191          * encryption/decryption
1192          */
1193         if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
1194                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1195                 return;
1196         }
1197
1198         srclen = op->sym->cipher.data.length;
1199         dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1200                         op->sym->cipher.data.offset);
1201
1202         iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1203                         sess->iv.offset);
1204
1205         if (sess->cipher.mode == OPENSSL_CIPHER_LIB)
1206                 if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
1207                         status = process_openssl_cipher_encrypt(mbuf_src, dst,
1208                                         op->sym->cipher.data.offset, iv,
1209                                         srclen, sess->cipher.ctx);
1210                 else
1211                         status = process_openssl_cipher_decrypt(mbuf_src, dst,
1212                                         op->sym->cipher.data.offset, iv,
1213                                         srclen, sess->cipher.ctx);
1214         else
1215                 status = process_openssl_cipher_des3ctr(mbuf_src, dst,
1216                                 op->sym->cipher.data.offset, iv,
1217                                 sess->cipher.key.data, srclen,
1218                                 sess->cipher.ctx);
1219
1220         if (status != 0)
1221                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1222 }
1223
1224 /** Process cipher operation */
1225 static void
1226 process_openssl_docsis_bpi_op(struct rte_crypto_op *op,
1227                 struct openssl_session *sess, struct rte_mbuf *mbuf_src,
1228                 struct rte_mbuf *mbuf_dst)
1229 {
1230         uint8_t *src, *dst, *iv;
1231         uint8_t block_size, last_block_len;
1232         int srclen, status = 0;
1233
1234         srclen = op->sym->cipher.data.length;
1235         src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
1236                         op->sym->cipher.data.offset);
1237         dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1238                         op->sym->cipher.data.offset);
1239
1240         iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1241                         sess->iv.offset);
1242
1243         block_size = DES_BLOCK_SIZE;
1244
1245         last_block_len = srclen % block_size;
1246         if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
1247                 /* Encrypt only with ECB mode XOR IV */
1248                 if (srclen < block_size) {
1249                         status = process_openssl_cipher_bpi_encrypt(src, dst,
1250                                         iv, srclen,
1251                                         sess->cipher.bpi_ctx);
1252                 } else {
1253                         srclen -= last_block_len;
1254                         /* Encrypt with the block aligned stream with CBC mode */
1255                         status = process_openssl_cipher_encrypt(mbuf_src, dst,
1256                                         op->sym->cipher.data.offset, iv,
1257                                         srclen, sess->cipher.ctx);
1258                         if (last_block_len) {
1259                                 /* Point at last block */
1260                                 dst += srclen;
1261                                 /*
1262                                  * IV is the last encrypted block from
1263                                  * the previous operation
1264                                  */
1265                                 iv = dst - block_size;
1266                                 src += srclen;
1267                                 srclen = last_block_len;
1268                                 /* Encrypt the last frame with ECB mode */
1269                                 status |= process_openssl_cipher_bpi_encrypt(src,
1270                                                 dst, iv,
1271                                                 srclen, sess->cipher.bpi_ctx);
1272                         }
1273                 }
1274         } else {
1275                 /* Decrypt only with ECB mode (encrypt, as it is same operation) */
1276                 if (srclen < block_size) {
1277                         status = process_openssl_cipher_bpi_encrypt(src, dst,
1278                                         iv,
1279                                         srclen,
1280                                         sess->cipher.bpi_ctx);
1281                 } else {
1282                         if (last_block_len) {
1283                                 /* Point at last block */
1284                                 dst += srclen - last_block_len;
1285                                 src += srclen - last_block_len;
1286                                 /*
1287                                  * IV is the last full block
1288                                  */
1289                                 iv = src - block_size;
1290                                 /*
1291                                  * Decrypt the last frame with ECB mode
1292                                  * (encrypt, as it is the same operation)
1293                                  */
1294                                 status = process_openssl_cipher_bpi_encrypt(src,
1295                                                 dst, iv,
1296                                                 last_block_len, sess->cipher.bpi_ctx);
1297                                 /* Prepare parameters for CBC mode op */
1298                                 iv = rte_crypto_op_ctod_offset(op, uint8_t *,
1299                                                 sess->iv.offset);
1300                                 dst += last_block_len - srclen;
1301                                 srclen -= last_block_len;
1302                         }
1303
1304                         /* Decrypt with CBC mode */
1305                         status |= process_openssl_cipher_decrypt(mbuf_src, dst,
1306                                         op->sym->cipher.data.offset, iv,
1307                                         srclen, sess->cipher.ctx);
1308                 }
1309         }
1310
1311         if (status != 0)
1312                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1313 }
1314
1315 /** Process auth operation */
1316 static void
1317 process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op,
1318                 struct openssl_session *sess, struct rte_mbuf *mbuf_src,
1319                 struct rte_mbuf *mbuf_dst)
1320 {
1321         uint8_t *dst;
1322         int srclen, status;
1323
1324         srclen = op->sym->auth.data.length;
1325
1326         if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY)
1327                 dst = qp->temp_digest;
1328         else {
1329                 dst = op->sym->auth.digest.data;
1330                 if (dst == NULL)
1331                         dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
1332                                         op->sym->auth.data.offset +
1333                                         op->sym->auth.data.length);
1334         }
1335
1336         switch (sess->auth.mode) {
1337         case OPENSSL_AUTH_AS_AUTH:
1338                 status = process_openssl_auth(mbuf_src, dst,
1339                                 op->sym->auth.data.offset, NULL, NULL, srclen,
1340                                 sess->auth.auth.ctx, sess->auth.auth.evp_algo);
1341                 break;
1342         case OPENSSL_AUTH_AS_HMAC:
1343                 status = process_openssl_auth_hmac(mbuf_src, dst,
1344                                 op->sym->auth.data.offset, srclen,
1345                                 sess->auth.hmac.ctx);
1346                 break;
1347         default:
1348                 status = -1;
1349                 break;
1350         }
1351
1352         if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
1353                 if (memcmp(dst, op->sym->auth.digest.data,
1354                                 sess->auth.digest_length) != 0) {
1355                         op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
1356                 }
1357         }
1358
1359         if (status != 0)
1360                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1361 }
1362
1363 /** Process crypto operation for mbuf */
1364 static int
1365 process_op(struct openssl_qp *qp, struct rte_crypto_op *op,
1366                 struct openssl_session *sess)
1367 {
1368         struct rte_mbuf *msrc, *mdst;
1369         int retval;
1370
1371         msrc = op->sym->m_src;
1372         mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
1373
1374         op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
1375
1376         switch (sess->chain_order) {
1377         case OPENSSL_CHAIN_ONLY_CIPHER:
1378                 process_openssl_cipher_op(op, sess, msrc, mdst);
1379                 break;
1380         case OPENSSL_CHAIN_ONLY_AUTH:
1381                 process_openssl_auth_op(qp, op, sess, msrc, mdst);
1382                 break;
1383         case OPENSSL_CHAIN_CIPHER_AUTH:
1384                 process_openssl_cipher_op(op, sess, msrc, mdst);
1385                 process_openssl_auth_op(qp, op, sess, mdst, mdst);
1386                 break;
1387         case OPENSSL_CHAIN_AUTH_CIPHER:
1388                 process_openssl_auth_op(qp, op, sess, msrc, mdst);
1389                 process_openssl_cipher_op(op, sess, msrc, mdst);
1390                 break;
1391         case OPENSSL_CHAIN_COMBINED:
1392                 process_openssl_combined_op(op, sess, msrc, mdst);
1393                 break;
1394         case OPENSSL_CHAIN_CIPHER_BPI:
1395                 process_openssl_docsis_bpi_op(op, sess, msrc, mdst);
1396                 break;
1397         default:
1398                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
1399                 break;
1400         }
1401
1402         /* Free session if a session-less crypto op */
1403         if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
1404                 openssl_reset_session(sess);
1405                 memset(sess, 0, sizeof(struct openssl_session));
1406                 memset(op->sym->session, 0,
1407                                 rte_cryptodev_get_header_session_size());
1408                 rte_mempool_put(qp->sess_mp, sess);
1409                 rte_mempool_put(qp->sess_mp, op->sym->session);
1410                 op->sym->session = NULL;
1411         }
1412
1413         if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
1414                 op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1415
1416         if (op->status != RTE_CRYPTO_OP_STATUS_ERROR)
1417                 retval = rte_ring_enqueue(qp->processed_ops, (void *)op);
1418         else
1419                 retval = -1;
1420
1421         return retval;
1422 }
1423
1424 /*
1425  *------------------------------------------------------------------------------
1426  * PMD Framework
1427  *------------------------------------------------------------------------------
1428  */
1429
1430 /** Enqueue burst */
1431 static uint16_t
1432 openssl_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
1433                 uint16_t nb_ops)
1434 {
1435         struct openssl_session *sess;
1436         struct openssl_qp *qp = queue_pair;
1437         int i, retval;
1438
1439         for (i = 0; i < nb_ops; i++) {
1440                 sess = get_session(qp, ops[i]);
1441                 if (unlikely(sess == NULL))
1442                         goto enqueue_err;
1443
1444                 retval = process_op(qp, ops[i], sess);
1445                 if (unlikely(retval < 0))
1446                         goto enqueue_err;
1447         }
1448
1449         qp->stats.enqueued_count += i;
1450         return i;
1451
1452 enqueue_err:
1453         qp->stats.enqueue_err_count++;
1454         return i;
1455 }
1456
1457 /** Dequeue burst */
1458 static uint16_t
1459 openssl_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
1460                 uint16_t nb_ops)
1461 {
1462         struct openssl_qp *qp = queue_pair;
1463
1464         unsigned int nb_dequeued = 0;
1465
1466         nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops,
1467                         (void **)ops, nb_ops, NULL);
1468         qp->stats.dequeued_count += nb_dequeued;
1469
1470         return nb_dequeued;
1471 }
1472
1473 /** Create OPENSSL crypto device */
1474 static int
1475 cryptodev_openssl_create(const char *name,
1476                         struct rte_vdev_device *vdev,
1477                         struct rte_crypto_vdev_init_params *init_params)
1478 {
1479         struct rte_cryptodev *dev;
1480         struct openssl_private *internals;
1481
1482         if (init_params->name[0] == '\0')
1483                 snprintf(init_params->name, sizeof(init_params->name),
1484                                 "%s", name);
1485
1486         dev = rte_cryptodev_vdev_pmd_init(init_params->name,
1487                         sizeof(struct openssl_private),
1488                         init_params->socket_id,
1489                         vdev);
1490         if (dev == NULL) {
1491                 OPENSSL_LOG_ERR("failed to create cryptodev vdev");
1492                 goto init_error;
1493         }
1494
1495         dev->driver_id = cryptodev_driver_id;
1496         dev->dev_ops = rte_openssl_pmd_ops;
1497
1498         /* register rx/tx burst functions for data path */
1499         dev->dequeue_burst = openssl_pmd_dequeue_burst;
1500         dev->enqueue_burst = openssl_pmd_enqueue_burst;
1501
1502         dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
1503                         RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
1504                         RTE_CRYPTODEV_FF_CPU_AESNI |
1505                         RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER;
1506
1507         /* Set vector instructions mode supported */
1508         internals = dev->data->dev_private;
1509
1510         internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
1511         internals->max_nb_sessions = init_params->max_nb_sessions;
1512
1513         return 0;
1514
1515 init_error:
1516         OPENSSL_LOG_ERR("driver %s: cryptodev_openssl_create failed",
1517                         init_params->name);
1518
1519         cryptodev_openssl_remove(vdev);
1520         return -EFAULT;
1521 }
1522
1523 /** Initialise OPENSSL crypto device */
1524 static int
1525 cryptodev_openssl_probe(struct rte_vdev_device *vdev)
1526 {
1527         struct rte_crypto_vdev_init_params init_params = {
1528                 RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS,
1529                 RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS,
1530                 rte_socket_id(),
1531                 {0}
1532         };
1533         const char *name;
1534         const char *input_args;
1535
1536         name = rte_vdev_device_name(vdev);
1537         if (name == NULL)
1538                 return -EINVAL;
1539         input_args = rte_vdev_device_args(vdev);
1540
1541         rte_cryptodev_vdev_parse_init_params(&init_params, input_args);
1542
1543         RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name,
1544                         init_params.socket_id);
1545         if (init_params.name[0] != '\0')
1546                 RTE_LOG(INFO, PMD, "  User defined name = %s\n",
1547                         init_params.name);
1548         RTE_LOG(INFO, PMD, "  Max number of queue pairs = %d\n",
1549                         init_params.max_nb_queue_pairs);
1550         RTE_LOG(INFO, PMD, "  Max number of sessions = %d\n",
1551                         init_params.max_nb_sessions);
1552
1553         return cryptodev_openssl_create(name, vdev, &init_params);
1554 }
1555
1556 /** Uninitialise OPENSSL crypto device */
1557 static int
1558 cryptodev_openssl_remove(struct rte_vdev_device *vdev)
1559 {
1560         const char *name;
1561
1562         name = rte_vdev_device_name(vdev);
1563         if (name == NULL)
1564                 return -EINVAL;
1565
1566         RTE_LOG(INFO, PMD,
1567                 "Closing OPENSSL crypto device %s on numa socket %u\n",
1568                 name, rte_socket_id());
1569
1570         return 0;
1571 }
1572
1573 static struct rte_vdev_driver cryptodev_openssl_pmd_drv = {
1574         .probe = cryptodev_openssl_probe,
1575         .remove = cryptodev_openssl_remove
1576 };
1577
1578 static struct cryptodev_driver openssl_crypto_drv;
1579
1580 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_OPENSSL_PMD,
1581         cryptodev_openssl_pmd_drv);
1582 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_OPENSSL_PMD,
1583         "max_nb_queue_pairs=<int> "
1584         "max_nb_sessions=<int> "
1585         "socket_id=<int>");
1586 RTE_PMD_REGISTER_CRYPTO_DRIVER(openssl_crypto_drv, cryptodev_openssl_pmd_drv,
1587                 cryptodev_driver_id);