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