xref: /dpdk/drivers/crypto/openssl/rte_openssl_pmd_ops.c (revision 96db98db69f759cdb54c02ef72c4cae760b01ab3)
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;
1205