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