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