cryptodev: move DH type from xform to DH op
[dpdk.git] / drivers / crypto / openssl / rte_openssl_pmd_ops.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016-2017 Intel Corporation
3  */
4
5 #define OPENSSL_API_COMPAT 0x10100000L
6
7 #include <string.h>
8
9 #include <rte_common.h>
10 #include <rte_malloc.h>
11 #include <cryptodev_pmd.h>
12
13 #include "openssl_pmd_private.h"
14 #include "compat.h"
15
16
17 static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
18         {       /* MD5 HMAC */
19                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
20                 {.sym = {
21                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
22                         {.auth = {
23                                 .algo = RTE_CRYPTO_AUTH_MD5_HMAC,
24                                 .block_size = 64,
25                                 .key_size = {
26                                         .min = 1,
27                                         .max = 64,
28                                         .increment = 1
29                                 },
30                                 .digest_size = {
31                                         .min = 1,
32                                         .max = 16,
33                                         .increment = 1
34                                 },
35                                 .iv_size = { 0 }
36                         }, }
37                 }, }
38         },
39         {       /* MD5 */
40                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
41                 {.sym = {
42                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
43                         {.auth = {
44                                 .algo = RTE_CRYPTO_AUTH_MD5,
45                                 .block_size = 64,
46                                 .key_size = {
47                                         .min = 0,
48                                         .max = 0,
49                                         .increment = 0
50                                 },
51                                 .digest_size = {
52                                         .min = 16,
53                                         .max = 16,
54                                         .increment = 0
55                                 },
56                                 .iv_size = { 0 }
57                         }, }
58                 }, }
59         },
60         {       /* SHA1 HMAC */
61                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
62                 {.sym = {
63                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
64                         {.auth = {
65                                 .algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
66                                 .block_size = 64,
67                                 .key_size = {
68                                         .min = 1,
69                                         .max = 64,
70                                         .increment = 1
71                                 },
72                                 .digest_size = {
73                                         .min = 1,
74                                         .max = 20,
75                                         .increment = 1
76                                 },
77                                 .iv_size = { 0 }
78                         }, }
79                 }, }
80         },
81         {       /* SHA1 */
82                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
83                 {.sym = {
84                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
85                         {.auth = {
86                                 .algo = RTE_CRYPTO_AUTH_SHA1,
87                                 .block_size = 64,
88                                 .key_size = {
89                                         .min = 0,
90                                         .max = 0,
91                                         .increment = 0
92                                 },
93                                 .digest_size = {
94                                         .min = 20,
95                                         .max = 20,
96                                         .increment = 0
97                                 },
98                                 .iv_size = { 0 }
99                         }, }
100                 }, }
101         },
102         {       /* SHA224 HMAC */
103                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
104                 {.sym = {
105                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
106                         {.auth = {
107                                 .algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
108                                 .block_size = 64,
109                                 .key_size = {
110                                         .min = 1,
111                                         .max = 64,
112                                         .increment = 1
113                                 },
114                                 .digest_size = {
115                                         .min = 1,
116                                         .max = 28,
117                                         .increment = 1
118                                 },
119                                 .iv_size = { 0 }
120                         }, }
121                 }, }
122         },
123         {       /* SHA224 */
124                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
125                 {.sym = {
126                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
127                         {.auth = {
128                                 .algo = RTE_CRYPTO_AUTH_SHA224,
129                                 .block_size = 64,
130                                 .key_size = {
131                                         .min = 0,
132                                         .max = 0,
133                                         .increment = 0
134                                 },
135                                 .digest_size = {
136                                         .min = 1,
137                                         .max = 28,
138                                         .increment = 1
139                                 },
140                                 .iv_size = { 0 }
141                         }, }
142                 }, }
143         },
144         {       /* SHA256 HMAC */
145                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
146                 {.sym = {
147                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
148                         {.auth = {
149                                 .algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
150                                 .block_size = 64,
151                                 .key_size = {
152                                         .min = 1,
153                                         .max = 64,
154                                         .increment = 1
155                                 },
156                                 .digest_size = {
157                                         .min = 1,
158                                         .max = 32,
159                                         .increment = 1
160                                 },
161                                 .iv_size = { 0 }
162                         }, }
163                 }, }
164         },
165         {       /* SHA256 */
166                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
167                 {.sym = {
168                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
169                         {.auth = {
170                                 .algo = RTE_CRYPTO_AUTH_SHA256,
171                                 .block_size = 64,
172                                 .key_size = {
173                                         .min = 0,
174                                         .max = 0,
175                                         .increment = 0
176                                 },
177                                 .digest_size = {
178                                         .min = 32,
179                                         .max = 32,
180                                         .increment = 0
181                                 },
182                                 .iv_size = { 0 }
183                         }, }
184                 }, }
185         },
186         {       /* SHA384 HMAC */
187                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
188                 {.sym = {
189                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
190                         {.auth = {
191                                 .algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
192                                 .block_size = 128,
193                                 .key_size = {
194                                         .min = 1,
195                                         .max = 128,
196                                         .increment = 1
197                                 },
198                                 .digest_size = {
199                                         .min = 1,
200                                         .max = 48,
201                                         .increment = 1
202                                 },
203                                 .iv_size = { 0 }
204                         }, }
205                 }, }
206         },
207         {       /* SHA384 */
208                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
209                 {.sym = {
210                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
211                         {.auth = {
212                                 .algo = RTE_CRYPTO_AUTH_SHA384,
213                                 .block_size = 128,
214                                 .key_size = {
215                                         .min = 0,
216                                         .max = 0,
217                                         .increment = 0
218                                 },
219                                 .digest_size = {
220                                         .min = 48,
221                                         .max = 48,
222                                         .increment = 0
223                                 },
224                                 .iv_size = { 0 }
225                         }, }
226                 }, }
227         },
228         {       /* SHA512 HMAC */
229                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
230                 {.sym = {
231                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
232                         {.auth = {
233                                 .algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
234                                 .block_size = 128,
235                                 .key_size = {
236                                         .min = 1,
237                                         .max = 128,
238                                         .increment = 1
239                                 },
240                                 .digest_size = {
241                                         .min = 1,
242                                         .max = 64,
243                                         .increment = 1
244                                 },
245                                 .iv_size = { 0 }
246                         }, }
247                 }, }
248         },
249         {       /* SHA512  */
250                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
251                 {.sym = {
252                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
253                         {.auth = {
254                                 .algo = RTE_CRYPTO_AUTH_SHA512,
255                                 .block_size = 128,
256                                 .key_size = {
257                                         .min = 0,
258                                         .max = 0,
259                                         .increment = 0
260                                 },
261                                 .digest_size = {
262                                         .min = 64,
263                                         .max = 64,
264                                         .increment = 0
265                                 },
266                                 .iv_size = { 0 }
267                         }, }
268                 }, }
269         },
270         {       /* AES CBC */
271                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
272                 {.sym = {
273                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
274                         {.cipher = {
275                                 .algo = RTE_CRYPTO_CIPHER_AES_CBC,
276                                 .block_size = 16,
277                                 .key_size = {
278                                         .min = 16,
279                                         .max = 32,
280                                         .increment = 8
281                                 },
282                                 .iv_size = {
283                                         .min = 16,
284                                         .max = 16,
285                                         .increment = 0
286                                 }
287                         }, }
288                 }, }
289         },
290         {       /* AES CTR */
291                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
292                 {.sym = {
293                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
294                         {.cipher = {
295                                 .algo = RTE_CRYPTO_CIPHER_AES_CTR,
296                                 .block_size = 16,
297                                 .key_size = {
298                                         .min = 16,
299                                         .max = 32,
300                                         .increment = 8
301                                 },
302                                 .iv_size = {
303                                         .min = 16,
304                                         .max = 16,
305                                         .increment = 0
306                                 }
307                         }, }
308                 }, }
309         },
310         {       /* AES GCM */
311                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
312                 {.sym = {
313                         .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
314                         {.aead = {
315                                 .algo = RTE_CRYPTO_AEAD_AES_GCM,
316                                 .block_size = 16,
317                                 .key_size = {
318                                         .min = 16,
319                                         .max = 32,
320                                         .increment = 8
321                                 },
322                                 .digest_size = {
323                                         .min = 16,
324                                         .max = 16,
325                                         .increment = 0
326                                 },
327                                 .aad_size = {
328                                         .min = 0,
329                                         .max = 65535,
330                                         .increment = 1
331                                 },
332                                 .iv_size = {
333                                         .min = 12,
334                                         .max = 16,
335                                         .increment = 4
336                                 },
337                         }, }
338                 }, }
339         },
340         {       /* AES CCM */
341                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
342                 {.sym = {
343                         .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
344                         {.aead = {
345                                 .algo = RTE_CRYPTO_AEAD_AES_CCM,
346                                 .block_size = 16,
347                                 .key_size = {
348                                         .min = 16,
349                                         .max = 32,
350                                         .increment = 8
351                                 },
352                                 .digest_size = {
353                                         .min = 4,
354                                         .max = 16,
355                                         .increment = 2
356                                 },
357                                 .aad_size = {
358                                         .min = 0,
359                                         .max = 65535,
360                                         .increment = 1
361                                 },
362                                 .iv_size = {
363                                         .min = 7,
364                                         .max = 13,
365                                         .increment = 1
366                                 },
367                         }, }
368                 }, }
369         },
370         {       /* AES GMAC (AUTH) */
371                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
372                 {.sym = {
373                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
374                         {.auth = {
375                                 .algo = RTE_CRYPTO_AUTH_AES_GMAC,
376                                 .block_size = 16,
377                                 .key_size = {
378                                         .min = 16,
379                                         .max = 32,
380                                         .increment = 8
381                                 },
382                                 .digest_size = {
383                                         .min = 16,
384                                         .max = 16,
385                                         .increment = 0
386                                 },
387                                 .iv_size = {
388                                         .min = 12,
389                                         .max = 16,
390                                         .increment = 4
391                                 }
392                         }, }
393                 }, }
394         },
395         {       /* 3DES CBC */
396                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
397                 {.sym = {
398                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
399                         {.cipher = {
400                                 .algo = RTE_CRYPTO_CIPHER_3DES_CBC,
401                                 .block_size = 8,
402                                 .key_size = {
403                                         .min = 8,
404                                         .max = 24,
405                                         .increment = 8
406                                 },
407                                 .iv_size = {
408                                         .min = 8,
409                                         .max = 8,
410                                         .increment = 0
411                                 }
412                         }, }
413                 }, }
414         },
415         {       /* 3DES CTR */
416                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
417                 {.sym = {
418                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
419                         {.cipher = {
420                                 .algo = RTE_CRYPTO_CIPHER_3DES_CTR,
421                                 .block_size = 8,
422                                 .key_size = {
423                                         .min = 16,
424                                         .max = 24,
425                                         .increment = 8
426                                 },
427                                 .iv_size = {
428                                         .min = 8,
429                                         .max = 8,
430                                         .increment = 0
431                                 }
432                         }, }
433                 }, }
434         },
435         {       /* DES CBC */
436                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
437                 {.sym = {
438                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
439                         {.cipher = {
440                                 .algo = RTE_CRYPTO_CIPHER_DES_CBC,
441                                 .block_size = 8,
442                                 .key_size = {
443                                         .min = 8,
444                                         .max = 8,
445                                         .increment = 0
446                                 },
447                                 .iv_size = {
448                                         .min = 8,
449                                         .max = 8,
450                                         .increment = 0
451                                 }
452                         }, }
453                 }, }
454         },
455         {       /* DES DOCSIS BPI */
456                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
457                 {.sym = {
458                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
459                         {.cipher = {
460                                 .algo = RTE_CRYPTO_CIPHER_DES_DOCSISBPI,
461                                 .block_size = 8,
462                                 .key_size = {
463                                         .min = 8,
464                                         .max = 8,
465                                         .increment = 0
466                                 },
467                                 .iv_size = {
468                                         .min = 8,
469                                         .max = 8,
470                                         .increment = 0
471                                 }
472                         }, }
473                 }, }
474         },
475         {       /* RSA */
476                 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
477                 {.asym = {
478                         .xform_capa = {
479                                 .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
480                                 .op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
481                                         (1 << RTE_CRYPTO_ASYM_OP_VERIFY) |
482                                         (1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) |
483                                         (1 << RTE_CRYPTO_ASYM_OP_DECRYPT)),
484                                 {
485                                 .modlen = {
486                                 /* min length is based on openssl rsa keygen */
487                                 .min = 30,
488                                 /* value 0 symbolizes no limit on max length */
489                                 .max = 0,
490                                 .increment = 1
491                                 }, }
492                         }
493                 },
494                 }
495         },
496         {       /* modexp */
497                 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
498                 {.asym = {
499                         .xform_capa = {
500                                 .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
501                                 .op_types = 0,
502                                 {
503                                 .modlen = {
504                                 /* value 0 symbolizes no limit on min length */
505                                 .min = 0,
506                                 /* value 0 symbolizes no limit on max length */
507                                 .max = 0,
508                                 .increment = 1
509                                 }, }
510                         }
511                 },
512                 }
513         },
514         {       /* modinv */
515                 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
516                 {.asym = {
517                         .xform_capa = {
518                                 .xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
519                                 .op_types = 0,
520                                 {
521                                 .modlen = {
522                                 /* value 0 symbolizes no limit on min length */
523                                 .min = 0,
524                                 /* value 0 symbolizes no limit on max length */
525                                 .max = 0,
526                                 .increment = 1
527                                 }, }
528                         }
529                 },
530                 }
531         },
532         {       /* dh */
533                 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
534                 {.asym = {
535                         .xform_capa = {
536                                 .xform_type = RTE_CRYPTO_ASYM_XFORM_DH,
537                                 .op_types =
538                                 ((1<<RTE_CRYPTO_ASYM_KE_PRIV_KEY_GENERATE) |
539                                 (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE |
540                                 (1 <<
541                                 RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE))),
542                                 {
543                                 .modlen = {
544                                 /* value 0 symbolizes no limit on min length */
545                                 .min = 0,
546                                 /* value 0 symbolizes no limit on max length */
547                                 .max = 0,
548                                 .increment = 1
549                                 }, }
550                         }
551                 },
552                 }
553         },
554         {       /* dsa */
555                 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
556                 {.asym = {
557                         .xform_capa = {
558                                 .xform_type = RTE_CRYPTO_ASYM_XFORM_DSA,
559                                 .op_types =
560                                 ((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
561                                 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
562                                 {
563                                 .modlen = {
564                                 /* value 0 symbolizes no limit on min length */
565                                 .min = 0,
566                                 /* value 0 symbolizes no limit on max length */
567                                 .max = 0,
568                                 .increment = 1
569                                 }, }
570                         }
571                 },
572                 }
573         },
574
575         RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
576 };
577
578
579 /** Configure device */
580 static int
581 openssl_pmd_config(__rte_unused struct rte_cryptodev *dev,
582                 __rte_unused struct rte_cryptodev_config *config)
583 {
584         return 0;
585 }
586
587 /** Start device */
588 static int
589 openssl_pmd_start(__rte_unused struct rte_cryptodev *dev)
590 {
591         return 0;
592 }
593
594 /** Stop device */
595 static void
596 openssl_pmd_stop(__rte_unused struct rte_cryptodev *dev)
597 {
598 }
599
600 /** Close device */
601 static int
602 openssl_pmd_close(__rte_unused struct rte_cryptodev *dev)
603 {
604         return 0;
605 }
606
607
608 /** Get device statistics */
609 static void
610 openssl_pmd_stats_get(struct rte_cryptodev *dev,
611                 struct rte_cryptodev_stats *stats)
612 {
613         int qp_id;
614
615         for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
616                 struct openssl_qp *qp = dev->data->queue_pairs[qp_id];
617
618                 stats->enqueued_count += qp->stats.enqueued_count;
619                 stats->dequeued_count += qp->stats.dequeued_count;
620
621                 stats->enqueue_err_count += qp->stats.enqueue_err_count;
622                 stats->dequeue_err_count += qp->stats.dequeue_err_count;
623         }
624 }
625
626 /** Reset device statistics */
627 static void
628 openssl_pmd_stats_reset(struct rte_cryptodev *dev)
629 {
630         int qp_id;
631
632         for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
633                 struct openssl_qp *qp = dev->data->queue_pairs[qp_id];
634
635                 memset(&qp->stats, 0, sizeof(qp->stats));
636         }
637 }
638
639
640 /** Get device info */
641 static void
642 openssl_pmd_info_get(struct rte_cryptodev *dev,
643                 struct rte_cryptodev_info *dev_info)
644 {
645         struct openssl_private *internals = dev->data->dev_private;
646
647         if (dev_info != NULL) {
648                 dev_info->driver_id = dev->driver_id;
649                 dev_info->feature_flags = dev->feature_flags;
650                 dev_info->capabilities = openssl_pmd_capabilities;
651                 dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
652                 /* No limit of number of sessions */
653                 dev_info->sym.max_nb_sessions = 0;
654         }
655 }
656
657 /** Release queue pair */
658 static int
659 openssl_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
660 {
661         if (dev->data->queue_pairs[qp_id] != NULL) {
662                 struct openssl_qp *qp = dev->data->queue_pairs[qp_id];
663
664                 rte_ring_free(qp->processed_ops);
665
666                 rte_free(dev->data->queue_pairs[qp_id]);
667                 dev->data->queue_pairs[qp_id] = NULL;
668         }
669         return 0;
670 }
671
672 /** set a unique name for the queue pair based on it's name, dev_id and qp_id */
673 static int
674 openssl_pmd_qp_set_unique_name(struct rte_cryptodev *dev,
675                 struct openssl_qp *qp)
676 {
677         unsigned int n = snprintf(qp->name, sizeof(qp->name),
678                         "openssl_pmd_%u_qp_%u",
679                         dev->data->dev_id, qp->id);
680
681         if (n >= sizeof(qp->name))
682                 return -1;
683
684         return 0;
685 }
686
687
688 /** Create a ring to place processed operations on */
689 static struct rte_ring *
690 openssl_pmd_qp_create_processed_ops_ring(struct openssl_qp *qp,
691                 unsigned int ring_size, int socket_id)
692 {
693         struct rte_ring *r;
694
695         r = rte_ring_lookup(qp->name);
696         if (r) {
697                 if (rte_ring_get_size(r) >= ring_size) {
698                         OPENSSL_LOG(INFO,
699                                         "Reusing existing ring %s for processed ops",
700                                  qp->name);
701                         return r;
702                 }
703
704                 OPENSSL_LOG(ERR,
705                                 "Unable to reuse existing ring %s for processed ops",
706                          qp->name);
707                 return NULL;
708         }
709
710         return rte_ring_create(qp->name, ring_size, socket_id,
711                         RING_F_SP_ENQ | RING_F_SC_DEQ);
712 }
713
714
715 /** Setup a queue pair */
716 static int
717 openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
718                 const struct rte_cryptodev_qp_conf *qp_conf,
719                 int socket_id)
720 {
721         struct openssl_qp *qp = NULL;
722
723         /* Free memory prior to re-allocation if needed. */
724         if (dev->data->queue_pairs[qp_id] != NULL)
725                 openssl_pmd_qp_release(dev, qp_id);
726
727         /* Allocate the queue pair data structure. */
728         qp = rte_zmalloc_socket("OPENSSL PMD Queue Pair", sizeof(*qp),
729                                         RTE_CACHE_LINE_SIZE, socket_id);
730         if (qp == NULL)
731                 return -ENOMEM;
732
733         qp->id = qp_id;
734         dev->data->queue_pairs[qp_id] = qp;
735
736         if (openssl_pmd_qp_set_unique_name(dev, qp))
737                 goto qp_setup_cleanup;
738
739         qp->processed_ops = openssl_pmd_qp_create_processed_ops_ring(qp,
740                         qp_conf->nb_descriptors, socket_id);
741         if (qp->processed_ops == NULL)
742                 goto qp_setup_cleanup;
743
744         qp->sess_mp = qp_conf->mp_session;
745         qp->sess_mp_priv = qp_conf->mp_session_private;
746
747         memset(&qp->stats, 0, sizeof(qp->stats));
748
749         return 0;
750
751 qp_setup_cleanup:
752         rte_free(qp);
753
754         return -1;
755 }
756
757 /** Returns the size of the symmetric session structure */
758 static unsigned
759 openssl_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
760 {
761         return sizeof(struct openssl_session);
762 }
763
764 /** Returns the size of the asymmetric session structure */
765 static unsigned
766 openssl_pmd_asym_session_get_size(struct rte_cryptodev *dev __rte_unused)
767 {
768         return sizeof(struct openssl_asym_session);
769 }
770
771 /** Configure the session from a crypto xform chain */
772 static int
773 openssl_pmd_sym_session_configure(struct rte_cryptodev *dev __rte_unused,
774                 struct rte_crypto_sym_xform *xform,
775                 struct rte_cryptodev_sym_session *sess,
776                 struct rte_mempool *mempool)
777 {
778         void *sess_private_data;
779         int ret;
780
781         if (unlikely(sess == NULL)) {
782                 OPENSSL_LOG(ERR, "invalid session struct");
783                 return -EINVAL;
784         }
785
786         if (rte_mempool_get(mempool, &sess_private_data)) {
787                 OPENSSL_LOG(ERR,
788                         "Couldn't get object from session mempool");
789                 return -ENOMEM;
790         }
791
792         ret = openssl_set_session_parameters(sess_private_data, xform);
793         if (ret != 0) {
794                 OPENSSL_LOG(ERR, "failed configure session parameters");
795
796                 /* Return session to mempool */
797                 rte_mempool_put(mempool, sess_private_data);
798                 return ret;
799         }
800
801         set_sym_session_private_data(sess, dev->driver_id,
802                         sess_private_data);
803
804         return 0;
805 }
806
807 static int openssl_set_asym_session_parameters(
808                 struct openssl_asym_session *asym_session,
809                 struct rte_crypto_asym_xform *xform)
810 {
811         int ret = 0;
812
813         if ((xform->xform_type != RTE_CRYPTO_ASYM_XFORM_DH) &&
814                 (xform->next != NULL)) {
815                 OPENSSL_LOG(ERR, "chained xfrms are not supported on %s",
816                         rte_crypto_asym_xform_strings[xform->xform_type]);
817                 return -1;
818         }
819
820         switch (xform->xform_type) {
821         case RTE_CRYPTO_ASYM_XFORM_RSA:
822         {
823                 BIGNUM *n = NULL;
824                 BIGNUM *e = NULL;
825                 BIGNUM *d = NULL;
826                 BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL;
827                 BIGNUM *iqmp = NULL, *dmq1 = NULL;
828
829                 /* copy xfrm data into rsa struct */
830                 n = BN_bin2bn((const unsigned char *)xform->rsa.n.data,
831                                 xform->rsa.n.length, n);
832                 e = BN_bin2bn((const unsigned char *)xform->rsa.e.data,
833                                 xform->rsa.e.length, e);
834
835                 if (!n || !e)
836                         goto err_rsa;
837
838                 RSA *rsa = RSA_new();
839                 if (rsa == NULL)
840                         goto err_rsa;
841
842                 if (xform->rsa.key_type == RTE_RSA_KEY_TYPE_EXP) {
843                         d = BN_bin2bn(
844                         (const unsigned char *)xform->rsa.d.data,
845                         xform->rsa.d.length,
846                         d);
847                         if (!d) {
848                                 RSA_free(rsa);
849                                 goto err_rsa;
850                         }
851                 } else {
852                         p = BN_bin2bn((const unsigned char *)
853                                         xform->rsa.qt.p.data,
854                                         xform->rsa.qt.p.length,
855                                         p);
856                         q = BN_bin2bn((const unsigned char *)
857                                         xform->rsa.qt.q.data,
858                                         xform->rsa.qt.q.length,
859                                         q);
860                         dmp1 = BN_bin2bn((const unsigned char *)
861                                         xform->rsa.qt.dP.data,
862                                         xform->rsa.qt.dP.length,
863                                         dmp1);
864                         dmq1 = BN_bin2bn((const unsigned char *)
865                                         xform->rsa.qt.dQ.data,
866                                         xform->rsa.qt.dQ.length,
867                                         dmq1);
868                         iqmp = BN_bin2bn((const unsigned char *)
869                                         xform->rsa.qt.qInv.data,
870                                         xform->rsa.qt.qInv.length,
871                                         iqmp);
872
873                         if (!p || !q || !dmp1 || !dmq1 || !iqmp) {
874                                 RSA_free(rsa);
875                                 goto err_rsa;
876                         }
877                         ret = set_rsa_params(rsa, p, q);
878                         if (ret) {
879                                 OPENSSL_LOG(ERR,
880                                         "failed to set rsa params\n");
881                                 RSA_free(rsa);
882                                 goto err_rsa;
883                         }
884                         ret = set_rsa_crt_params(rsa, dmp1, dmq1, iqmp);
885                         if (ret) {
886                                 OPENSSL_LOG(ERR,
887                                         "failed to set crt params\n");
888                                 RSA_free(rsa);
889                                 /*
890                                  * set already populated params to NULL
891                                  * as its freed by call to RSA_free
892                                  */
893                                 p = q = NULL;
894                                 goto err_rsa;
895                         }
896                 }
897
898                 ret = set_rsa_keys(rsa, n, e, d);
899                 if (ret) {
900                         OPENSSL_LOG(ERR, "Failed to load rsa keys\n");
901                         RSA_free(rsa);
902                         return -1;
903                 }
904                 asym_session->u.r.rsa = rsa;
905                 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_RSA;
906                 break;
907 err_rsa:
908                 BN_clear_free(n);
909                 BN_clear_free(e);
910                 BN_clear_free(d);
911                 BN_clear_free(p);
912                 BN_clear_free(q);
913                 BN_clear_free(dmp1);
914                 BN_clear_free(dmq1);
915                 BN_clear_free(iqmp);
916
917                 return -1;
918         }
919         case RTE_CRYPTO_ASYM_XFORM_MODEX:
920         {
921                 struct rte_crypto_modex_xform *xfrm = &(xform->modex);
922
923                 BN_CTX *ctx = BN_CTX_new();
924                 if (ctx == NULL) {
925                         OPENSSL_LOG(ERR,
926                                 " failed to allocate resources\n");
927                         return -1;
928                 }
929                 BN_CTX_start(ctx);
930                 BIGNUM *mod = BN_CTX_get(ctx);
931                 BIGNUM *exp = BN_CTX_get(ctx);
932                 if (mod == NULL || exp == NULL) {
933                         BN_CTX_end(ctx);
934                         BN_CTX_free(ctx);
935                         return -1;
936                 }
937
938                 mod = BN_bin2bn((const unsigned char *)
939                                 xfrm->modulus.data,
940                                 xfrm->modulus.length, mod);
941                 exp = BN_bin2bn((const unsigned char *)
942                                 xfrm->exponent.data,
943                                 xfrm->exponent.length, exp);
944                 asym_session->u.e.ctx = ctx;
945                 asym_session->u.e.mod = mod;
946                 asym_session->u.e.exp = exp;
947                 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODEX;
948                 break;
949         }
950         case RTE_CRYPTO_ASYM_XFORM_MODINV:
951         {
952                 struct rte_crypto_modinv_xform *xfrm = &(xform->modinv);
953
954                 BN_CTX *ctx = BN_CTX_new();
955                 if (ctx == NULL) {
956                         OPENSSL_LOG(ERR,
957                                 " failed to allocate resources\n");
958                         return -1;
959                 }
960                 BN_CTX_start(ctx);
961                 BIGNUM *mod = BN_CTX_get(ctx);
962                 if (mod == NULL) {
963                         BN_CTX_end(ctx);
964                         BN_CTX_free(ctx);
965                         return -1;
966                 }
967
968                 mod = BN_bin2bn((const unsigned char *)
969                                 xfrm->modulus.data,
970                                 xfrm->modulus.length,
971                                 mod);
972                 asym_session->u.m.ctx = ctx;
973                 asym_session->u.m.modulus = mod;
974                 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODINV;
975                 break;
976         }
977         case RTE_CRYPTO_ASYM_XFORM_DH:
978         {
979                 BIGNUM *p = NULL;
980                 BIGNUM *g = NULL;
981
982                 p = BN_bin2bn((const unsigned char *)
983                                 xform->dh.p.data,
984                                 xform->dh.p.length,
985                                 p);
986                 g = BN_bin2bn((const unsigned char *)
987                                 xform->dh.g.data,
988                                 xform->dh.g.length,
989                                 g);
990                 if (!p || !g)
991                         goto err_dh;
992
993                 DH *dh = DH_new();
994                 if (dh == NULL) {
995                         OPENSSL_LOG(ERR,
996                                 "failed to allocate resources\n");
997                         goto err_dh;
998                 }
999                 ret = set_dh_params(dh, p, g);
1000                 if (ret) {
1001                         DH_free(dh);
1002                         goto err_dh;
1003                 }
1004                 asym_session->u.dh.dh_key = dh;
1005                 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DH;
1006                 break;
1007
1008 err_dh:
1009                 OPENSSL_LOG(ERR, " failed to set dh params\n");
1010                 BN_free(p);
1011                 BN_free(g);
1012                 return -1;
1013         }
1014         case RTE_CRYPTO_ASYM_XFORM_DSA:
1015         {
1016                 BIGNUM *p = NULL, *g = NULL;
1017                 BIGNUM *q = NULL, *priv_key = NULL;
1018                 BIGNUM *pub_key = BN_new();
1019                 BN_zero(pub_key);
1020
1021                 p = BN_bin2bn((const unsigned char *)
1022                                 xform->dsa.p.data,
1023                                 xform->dsa.p.length,
1024                                 p);
1025
1026                 g = BN_bin2bn((const unsigned char *)
1027                                 xform->dsa.g.data,
1028                                 xform->dsa.g.length,
1029                                 g);
1030
1031                 q = BN_bin2bn((const unsigned char *)
1032                                 xform->dsa.q.data,
1033                                 xform->dsa.q.length,
1034                                 q);
1035                 if (!p || !q || !g)
1036                         goto err_dsa;
1037
1038                 priv_key = BN_bin2bn((const unsigned char *)
1039                                 xform->dsa.x.data,
1040                                 xform->dsa.x.length,
1041                                 priv_key);
1042                 if (priv_key == NULL)
1043                         goto err_dsa;
1044
1045                 DSA *dsa = DSA_new();
1046                 if (dsa == NULL) {
1047                         OPENSSL_LOG(ERR,
1048                                 " failed to allocate resources\n");
1049                         goto err_dsa;
1050                 }
1051
1052                 ret = set_dsa_params(dsa, p, q, g);
1053                 if (ret) {
1054                         DSA_free(dsa);
1055                         OPENSSL_LOG(ERR, "Failed to dsa params\n");
1056                         goto err_dsa;
1057                 }
1058
1059                 /*
1060                  * openssl 1.1.0 mandate that public key can't be
1061                  * NULL in very first call. so set a dummy pub key.
1062                  * to keep consistency, lets follow same approach for
1063                  * both versions
1064                  */
1065                 /* just set dummy public for very 1st call */
1066                 ret = set_dsa_keys(dsa, pub_key, priv_key);
1067                 if (ret) {
1068                         DSA_free(dsa);
1069                         OPENSSL_LOG(ERR, "Failed to set keys\n");
1070                         return -1;
1071                 }
1072                 asym_session->u.s.dsa = dsa;
1073                 asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA;
1074                 break;
1075
1076 err_dsa:
1077                 BN_free(p);
1078                 BN_free(q);
1079                 BN_free(g);
1080                 BN_free(priv_key);
1081                 BN_free(pub_key);
1082                 return -1;
1083         }
1084         default:
1085                 return -1;
1086         }
1087
1088         return 0;
1089 }
1090
1091 /** Configure the session from a crypto xform chain */
1092 static int
1093 openssl_pmd_asym_session_configure(struct rte_cryptodev *dev __rte_unused,
1094                 struct rte_crypto_asym_xform *xform,
1095                 struct rte_cryptodev_asym_session *sess)
1096 {
1097         void *asym_sess_private_data;
1098         int ret;
1099
1100         if (unlikely(sess == NULL)) {
1101                 OPENSSL_LOG(ERR, "invalid asymmetric session struct");
1102                 return -EINVAL;
1103         }
1104
1105         asym_sess_private_data = sess->sess_private_data;
1106         ret = openssl_set_asym_session_parameters(asym_sess_private_data,
1107                         xform);
1108         if (ret != 0) {
1109                 OPENSSL_LOG(ERR, "failed configure session parameters");
1110                 return ret;
1111         }
1112
1113         return 0;
1114 }
1115
1116 /** Clear the memory of session so it doesn't leave key material behind */
1117 static void
1118 openssl_pmd_sym_session_clear(struct rte_cryptodev *dev,
1119                 struct rte_cryptodev_sym_session *sess)
1120 {
1121         uint8_t index = dev->driver_id;
1122         void *sess_priv = get_sym_session_private_data(sess, index);
1123
1124         /* Zero out the whole structure */
1125         if (sess_priv) {
1126                 openssl_reset_session(sess_priv);
1127                 memset(sess_priv, 0, sizeof(struct openssl_session));
1128                 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
1129                 set_sym_session_private_data(sess, index, NULL);
1130                 rte_mempool_put(sess_mp, sess_priv);
1131         }
1132 }
1133
1134 static void openssl_reset_asym_session(struct openssl_asym_session *sess)
1135 {
1136         switch (sess->xfrm_type) {
1137         case RTE_CRYPTO_ASYM_XFORM_RSA:
1138                 if (sess->u.r.rsa)
1139                         RSA_free(sess->u.r.rsa);
1140                 break;
1141         case RTE_CRYPTO_ASYM_XFORM_MODEX:
1142                 if (sess->u.e.ctx) {
1143                         BN_CTX_end(sess->u.e.ctx);
1144                         BN_CTX_free(sess->u.e.ctx);
1145                 }
1146                 break;
1147         case RTE_CRYPTO_ASYM_XFORM_MODINV:
1148                 if (sess->u.m.ctx) {
1149                         BN_CTX_end(sess->u.m.ctx);
1150                         BN_CTX_free(sess->u.m.ctx);
1151                 }
1152                 break;
1153         case RTE_CRYPTO_ASYM_XFORM_DH:
1154                 if (sess->u.dh.dh_key)
1155                         DH_free(sess->u.dh.dh_key);
1156                 break;
1157         case RTE_CRYPTO_ASYM_XFORM_DSA:
1158                 if (sess->u.s.dsa)
1159                         DSA_free(sess->u.s.dsa);
1160                 break;
1161         default:
1162                 break;
1163         }
1164 }
1165
1166 /** Clear the memory of asymmetric session
1167  * so it doesn't leave key material behind
1168  */
1169 static void
1170 openssl_pmd_asym_session_clear(struct rte_cryptodev *dev __rte_unused,
1171                 struct rte_cryptodev_asym_session *sess)
1172 {
1173         void *sess_priv = sess->sess_private_data;
1174
1175         /* Zero out the whole structure */
1176         if (sess_priv) {
1177                 openssl_reset_asym_session(sess_priv);
1178                 memset(sess_priv, 0, sizeof(struct openssl_asym_session));
1179         }
1180 }
1181
1182 struct rte_cryptodev_ops openssl_pmd_ops = {
1183                 .dev_configure          = openssl_pmd_config,
1184                 .dev_start              = openssl_pmd_start,
1185                 .dev_stop               = openssl_pmd_stop,
1186                 .dev_close              = openssl_pmd_close,
1187
1188                 .stats_get              = openssl_pmd_stats_get,
1189                 .stats_reset            = openssl_pmd_stats_reset,
1190
1191                 .dev_infos_get          = openssl_pmd_info_get,
1192
1193                 .queue_pair_setup       = openssl_pmd_qp_setup,
1194                 .queue_pair_release     = openssl_pmd_qp_release,
1195
1196                 .sym_session_get_size   = openssl_pmd_sym_session_get_size,
1197                 .asym_session_get_size  = openssl_pmd_asym_session_get_size,
1198                 .sym_session_configure  = openssl_pmd_sym_session_configure,
1199                 .asym_session_configure = openssl_pmd_asym_session_configure,
1200                 .sym_session_clear      = openssl_pmd_sym_session_clear,
1201                 .asym_session_clear     = openssl_pmd_asym_session_clear
1202 };
1203
1204 struct rte_cryptodev_ops *rte_openssl_pmd_ops = &openssl_pmd_ops;