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 		struct openssl_qp *qp = dev->data->queue_pairs[qp_id];
661 
662 		if (qp->processed_ops)
663 			rte_ring_free(qp->processed_ops);
664 
665 		rte_free(dev->data->queue_pairs[qp_id]);
666 		dev->data->queue_pairs[qp_id] = NULL;
667 	}
668 	return 0;
669 }
670 
671 /** set a unique name for the queue pair based on it's name, dev_id and qp_id */
672 static int
673 openssl_pmd_qp_set_unique_name(struct rte_cryptodev *dev,
674 		struct openssl_qp *qp)
675 {
676 	unsigned int n = snprintf(qp->name, sizeof(qp->name),
677 			"openssl_pmd_%u_qp_%u",
678 			dev->data->dev_id, qp->id);
679 
680 	if (n >= sizeof(qp->name))
681 		return -1;
682 
683 	return 0;
684 }
685 
686 
687 /** Create a ring to place processed operations on */
688 static struct rte_ring *
689 openssl_pmd_qp_create_processed_ops_ring(struct openssl_qp *qp,
690 		unsigned int ring_size, int socket_id)
691 {
692 	struct rte_ring *r;
693 
694 	r = rte_ring_lookup(qp->name);
695 	if (r) {
696 		if (rte_ring_get_size(r) >= ring_size) {
697 			OPENSSL_LOG(INFO,
698 					"Reusing existing ring %s for processed ops",
699 				 qp->name);
700 			return r;
701 		}
702 
703 		OPENSSL_LOG(ERR,
704 				"Unable to reuse existing ring %s for processed ops",
705 			 qp->name);
706 		return NULL;
707 	}
708 
709 	return rte_ring_create(qp->name, ring_size, socket_id,
710 			RING_F_SP_ENQ | RING_F_SC_DEQ);
711 }
712 
713 
714 /** Setup a queue pair */
715 static int
716 openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
717 		const struct rte_cryptodev_qp_conf *qp_conf,
718 		int socket_id, struct rte_mempool *session_pool)
719 {
720 	struct openssl_qp *qp = NULL;
721 
722 	/* Free memory prior to re-allocation if needed. */
723 	if (dev->data->queue_pairs[qp_id] != NULL)
724 		openssl_pmd_qp_release(dev, qp_id);
725 
726 	/* Allocate the queue pair data structure. */
727 	qp = rte_zmalloc_socket("OPENSSL PMD Queue Pair", sizeof(*qp),
728 					RTE_CACHE_LINE_SIZE, socket_id);
729 	if (qp == NULL)
730 		return -ENOMEM;
731 
732 	qp->id = qp_id;
733 	dev->data->queue_pairs[qp_id] = qp;
734 
735 	if (openssl_pmd_qp_set_unique_name(dev, qp))
736 		goto qp_setup_cleanup;
737 
738 	qp->processed_ops = openssl_pmd_qp_create_processed_ops_ring(qp,
739 			qp_conf->nb_descriptors, socket_id);
740 	if (qp->processed_ops == NULL)
741 		goto qp_setup_cleanup;
742 
743 	qp->sess_mp = session_pool;
744 
745 	memset(&qp->stats, 0, sizeof(qp->stats));
746 
747 	return 0;
748 
749 qp_setup_cleanup:
750 	if (qp)
751 		rte_free(qp);
752 
753 	return -1;
754 }
755 
756 /** Return the number of allocated queue pairs */
757 static uint32_t
758 openssl_pmd_qp_count(struct rte_cryptodev *dev)
759 {
760 	return dev->data->nb_queue_pairs;
761 }
762 
763 /** Returns the size of the symmetric session structure */
764 static unsigned
765 openssl_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
766 {
767 	return sizeof(struct openssl_session);
768 }
769 
770 /** Returns the size of the asymmetric session structure */
771 static unsigned
772 openssl_pmd_asym_session_get_size(struct rte_cryptodev *dev __rte_unused)
773 {
774 	return sizeof(struct openssl_asym_session);
775 }
776 
777 /** Configure the session from a crypto xform chain */
778 static int
779 openssl_pmd_sym_session_configure(struct rte_cryptodev *dev __rte_unused,
780 		struct rte_crypto_sym_xform *xform,
781 		struct rte_cryptodev_sym_session *sess,
782 		struct rte_mempool *mempool)
783 {
784 	void *sess_private_data;
785 	int ret;
786 
787 	if (unlikely(sess == NULL)) {
788 		OPENSSL_LOG(ERR, "invalid session struct");
789 		return -EINVAL;
790 	}
791 
792 	if (rte_mempool_get(mempool, &sess_private_data)) {
793 		OPENSSL_LOG(ERR,
794 			"Couldn't get object from session mempool");
795 		return -ENOMEM;
796 	}
797 
798 	ret = openssl_set_session_parameters(sess_private_data, xform);
799 	if (ret != 0) {
800 		OPENSSL_LOG(ERR, "failed configure session parameters");
801 
802 		/* Return session to mempool */
803 		rte_mempool_put(mempool, sess_private_data);
804 		return ret;
805 	}
806 
807 	set_sym_session_private_data(sess, dev->driver_id,
808 			sess_private_data);
809 
810 	return 0;
811 }
812 
813 static int openssl_set_asym_session_parameters(
814 		struct openssl_asym_session *asym_session,
815 		struct rte_crypto_asym_xform *xform)
816 {
817 	int ret = 0;
818 
819 	if ((xform->xform_type != RTE_CRYPTO_ASYM_XFORM_DH) &&
820 		(xform->next != NULL)) {
821 		OPENSSL_LOG(ERR, "chained xfrms are not supported on %s",
822 			rte_crypto_asym_xform_strings[xform->xform_type]);
823 		return -1;
824 	}
825 
826 	switch (xform->xform_type) {
827 	case RTE_CRYPTO_ASYM_XFORM_RSA:
828 	{
829 		BIGNUM *n = NULL;
830 		BIGNUM *e = NULL;
831 		BIGNUM *d = NULL;
832 		BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL;
833 		BIGNUM *iqmp = NULL, *dmq1 = NULL;
834 
835 		/* copy xfrm data into rsa struct */
836 		n = BN_bin2bn((const unsigned char *)xform->rsa.n.data,
837 				xform->rsa.n.length, n);
838 		e = BN_bin2bn((const unsigned char *)xform->rsa.e.data,
839 				xform->rsa.e.length, e);
840 
841 		if (!n || !e)
842 			goto err_rsa;
843 
844 		RSA *rsa = RSA_new();
845 		if (rsa == NULL)
846 			goto err_rsa;
847 
848 		if (xform->rsa.key_type == RTE_RSA_KEY_TYPE_EXP) {
849 			d = BN_bin2bn(
850 			(const unsigned char *)xform->rsa.d.data,
851 			xform->rsa.d.length,
852 			d);
853 			if (!d) {
854 				RSA_free(rsa);
855 				goto err_rsa;
856 			}
857 		} else {
858 			p = BN_bin2bn((const unsigned char *)
859 					xform->rsa.qt.p.data,
860 					xform->rsa.qt.p.length,
861 					p);
862 			q = BN_bin2bn((const unsigned char *)
863 					xform->rsa.qt.q.data,
864 					xform->rsa.qt.q.length,
865 					q);
866 			dmp1 = BN_bin2bn((const unsigned char *)
867 					xform->rsa.qt.dP.data,
868 					xform->rsa.qt.dP.length,
869 					dmp1);
870 			dmq1 = BN_bin2bn((const unsigned char *)
871 					xform->rsa.qt.dQ.data,
872 					xform->rsa.qt.dQ.length,
873 					dmq1);
874 			iqmp = BN_bin2bn((const unsigned char *)
875 					xform->rsa.qt.qInv.data,
876 					xform->rsa.qt.qInv.length,
877 					iqmp);
878 
879 			if (!p || !q || !dmp1 || !dmq1 || !iqmp) {
880 				RSA_free(rsa);
881 				goto err_rsa;
882 			}
883 			ret = set_rsa_params(rsa, p, q);
884 			if (ret) {
885 				OPENSSL_LOG(ERR,
886 					"failed to set rsa params\n");
887 				RSA_free(rsa);
888 				goto err_rsa;
889 			}
890 			ret = set_rsa_crt_params(rsa, dmp1, dmq1, iqmp);
891 			if (ret) {
892 				OPENSSL_LOG(ERR,
893 					"failed to set crt params\n");
894 				RSA_free(rsa);
895 				/*
896 				 * set already populated params to NULL
897 				 * as its freed by call to RSA_free
898 				 */
899 				p = q = NULL;
900 				goto err_rsa;
901 			}
902 		}
903 
904 		ret = set_rsa_keys(rsa, n, e, d);
905 		if (ret) {
906 			OPENSSL_LOG(ERR, "Failed to load rsa keys\n");
907 			RSA_free(rsa);
908 			return -1;
909 		}
910 		asym_session->u.r.rsa = rsa;
911 		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_RSA;
912 		break;
913 err_rsa:
914 		if (n)
915 			BN_free(n);
916 		if (e)
917 			BN_free(e);
918 		if (d)
919 			BN_free(d);
920 		if (p)
921 			BN_free(p);
922 		if (q)
923 			BN_free(q);
924 		if (dmp1)
925 			BN_free(dmp1);
926 		if (dmq1)
927 			BN_free(dmq1);
928 		if (iqmp)
929 			BN_free(iqmp);
930 
931 		return -1;
932 	}
933 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
934 	{
935 		struct rte_crypto_modex_xform *xfrm = &(xform->modex);
936 
937 		BN_CTX *ctx = BN_CTX_new();
938 		if (ctx == NULL) {
939 			OPENSSL_LOG(ERR,
940 				" failed to allocate resources\n");
941 			return -1;
942 		}
943 		BN_CTX_start(ctx);
944 		BIGNUM *mod = BN_CTX_get(ctx);
945 		BIGNUM *exp = BN_CTX_get(ctx);
946 		if (mod == NULL || exp == NULL) {
947 			BN_CTX_end(ctx);
948 			BN_CTX_free(ctx);
949 			return -1;
950 		}
951 
952 		mod = BN_bin2bn((const unsigned char *)
953 				xfrm->modulus.data,
954 				xfrm->modulus.length, mod);
955 		exp = BN_bin2bn((const unsigned char *)
956 				xfrm->exponent.data,
957 				xfrm->exponent.length, exp);
958 		asym_session->u.e.ctx = ctx;
959 		asym_session->u.e.mod = mod;
960 		asym_session->u.e.exp = exp;
961 		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODEX;
962 		break;
963 	}
964 	case RTE_CRYPTO_ASYM_XFORM_MODINV:
965 	{
966 		struct rte_crypto_modinv_xform *xfrm = &(xform->modinv);
967 
968 		BN_CTX *ctx = BN_CTX_new();
969 		if (ctx == NULL) {
970 			OPENSSL_LOG(ERR,
971 				" failed to allocate resources\n");
972 			return -1;
973 		}
974 		BN_CTX_start(ctx);
975 		BIGNUM *mod = BN_CTX_get(ctx);
976 		if (mod == NULL) {
977 			BN_CTX_end(ctx);
978 			BN_CTX_free(ctx);
979 			return -1;
980 		}
981 
982 		mod = BN_bin2bn((const unsigned char *)
983 				xfrm->modulus.data,
984 				xfrm->modulus.length,
985 				mod);
986 		asym_session->u.m.ctx = ctx;
987 		asym_session->u.m.modulus = mod;
988 		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODINV;
989 		break;
990 	}
991 	case RTE_CRYPTO_ASYM_XFORM_DH:
992 	{
993 		BIGNUM *p = NULL;
994 		BIGNUM *g = NULL;
995 
996 		p = BN_bin2bn((const unsigned char *)
997 				xform->dh.p.data,
998 				xform->dh.p.length,
999 				p);
1000 		g = BN_bin2bn((const unsigned char *)
1001 				xform->dh.g.data,
1002 				xform->dh.g.length,
1003 				g);
1004 		if (!p || !g)
1005 			goto err_dh;
1006 
1007 		DH *dh = DH_new();
1008 		if (dh == NULL) {
1009 			OPENSSL_LOG(ERR,
1010 				"failed to allocate resources\n");
1011 			goto err_dh;
1012 		}
1013 		ret = set_dh_params(dh, p, g);
1014 		if (ret) {
1015 			DH_free(dh);
1016 			goto err_dh;
1017 		}
1018 
1019 		/*
1020 		 * setup xfrom for
1021 		 * public key generate, or
1022 		 * DH Priv key generate, or both
1023 		 * public and private key generate
1024 		 */
1025 		asym_session->u.dh.key_op = (1 << xform->dh.type);
1026 
1027 		if (xform->dh.type ==
1028 			RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE) {
1029 			/* check if next is pubkey */
1030 			if ((xform->next != NULL) &&
1031 				(xform->next->xform_type ==
1032 				RTE_CRYPTO_ASYM_XFORM_DH) &&
1033 				(xform->next->dh.type ==
1034 				RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE)
1035 				) {
1036 				/*
1037 				 * setup op as pub/priv key
1038 				 * pair generationi
1039 				 */
1040 				asym_session->u.dh.key_op |=
1041 				(1 <<
1042 				RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE);
1043 			}
1044 		}
1045 		asym_session->u.dh.dh_key = dh;
1046 		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DH;
1047 		break;
1048 
1049 err_dh:
1050 		OPENSSL_LOG(ERR, " failed to set dh params\n");
1051 		if (p)
1052 			BN_free(p);
1053 		if (g)
1054 			BN_free(g);
1055 		return -1;
1056 	}
1057 	case RTE_CRYPTO_ASYM_XFORM_DSA:
1058 	{
1059 		BIGNUM *p = NULL, *g = NULL;
1060 		BIGNUM *q = NULL, *priv_key = NULL;
1061 		BIGNUM *pub_key = BN_new();
1062 		BN_zero(pub_key);
1063 
1064 		p = BN_bin2bn((const unsigned char *)
1065 				xform->dsa.p.data,
1066 				xform->dsa.p.length,
1067 				p);
1068 
1069 		g = BN_bin2bn((const unsigned char *)
1070 				xform->dsa.g.data,
1071 				xform->dsa.g.length,
1072 				g);
1073 
1074 		q = BN_bin2bn((const unsigned char *)
1075 				xform->dsa.q.data,
1076 				xform->dsa.q.length,
1077 				q);
1078 		if (!p || !q || !g)
1079 			goto err_dsa;
1080 
1081 		priv_key = BN_bin2bn((const unsigned char *)
1082 				xform->dsa.x.data,
1083 				xform->dsa.x.length,
1084 				priv_key);
1085 		if (priv_key == NULL)
1086 			goto err_dsa;
1087 
1088 		DSA *dsa = DSA_new();
1089 		if (dsa == NULL) {
1090 			OPENSSL_LOG(ERR,
1091 				" failed to allocate resources\n");
1092 			goto err_dsa;
1093 		}
1094 
1095 		ret = set_dsa_params(dsa, p, q, g);
1096 		if (ret) {
1097 			DSA_free(dsa);
1098 			OPENSSL_LOG(ERR, "Failed to dsa params\n");
1099 			goto err_dsa;
1100 		}
1101 
1102 		/*
1103 		 * openssl 1.1.0 mandate that public key can't be
1104 		 * NULL in very first call. so set a dummy pub key.
1105 		 * to keep consistency, lets follow same approach for
1106 		 * both versions
1107 		 */
1108 		/* just set dummy public for very 1st call */
1109 		ret = set_dsa_keys(dsa, pub_key, priv_key);
1110 		if (ret) {
1111 			DSA_free(dsa);
1112 			OPENSSL_LOG(ERR, "Failed to set keys\n");
1113 			return -1;
1114 		}
1115 		asym_session->u.s.dsa = dsa;
1116 		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA;
1117 		break;
1118 
1119 err_dsa:
1120 		if (p)
1121 			BN_free(p);
1122 		if (q)
1123 			BN_free(q);
1124 		if (g)
1125 			BN_free(g);
1126 		if (priv_key)
1127 			BN_free(priv_key);
1128 		if (pub_key)
1129 			BN_free(pub_key);
1130 		return -1;
1131 	}
1132 	default:
1133 		return -1;
1134 	}
1135 
1136 	return 0;
1137 }
1138 
1139 /** Configure the session from a crypto xform chain */
1140 static int
1141 openssl_pmd_asym_session_configure(struct rte_cryptodev *dev __rte_unused,
1142 		struct rte_crypto_asym_xform *xform,
1143 		struct rte_cryptodev_asym_session *sess,
1144 		struct rte_mempool *mempool)
1145 {
1146 	void *asym_sess_private_data;
1147 	int ret;
1148 
1149 	if (unlikely(sess == NULL)) {
1150 		OPENSSL_LOG(ERR, "invalid asymmetric session struct");
1151 		return -EINVAL;
1152 	}
1153 
1154 	if (rte_mempool_get(mempool, &asym_sess_private_data)) {
1155 		CDEV_LOG_ERR(
1156 			"Couldn't get object from session mempool");
1157 		return -ENOMEM;
1158 	}
1159 
1160 	ret = openssl_set_asym_session_parameters(asym_sess_private_data,
1161 			xform);
1162 	if (ret != 0) {
1163 		OPENSSL_LOG(ERR, "failed configure session parameters");
1164 
1165 		/* Return session to mempool */
1166 		rte_mempool_put(mempool, asym_sess_private_data);
1167 		return ret;
1168 	}
1169 
1170 	set_asym_session_private_data(sess, dev->driver_id,
1171 			asym_sess_private_data);
1172 
1173 	return 0;
1174 }
1175 
1176 /** Clear the memory of session so it doesn't leave key material behind */
1177 static void
1178 openssl_pmd_sym_session_clear(struct rte_cryptodev *dev,
1179 		struct rte_cryptodev_sym_session *sess)
1180 {
1181 	uint8_t index = dev->driver_id;
1182 	void *sess_priv = get_sym_session_private_data(sess, index);
1183 
1184 	/* Zero out the whole structure */
1185 	if (sess_priv) {
1186 		openssl_reset_session(sess_priv);
1187 		memset(sess_priv, 0, sizeof(struct openssl_session));
1188 		struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
1189 		set_sym_session_private_data(sess, index, NULL);
1190 		rte_mempool_put(sess_mp, sess_priv);
1191 	}
1192 }
1193 
1194 static void openssl_reset_asym_session(struct openssl_asym_session *sess)
1195 {
1196 	switch (sess->xfrm_type) {
1197 	case RTE_CRYPTO_ASYM_XFORM_RSA:
1198 		if (sess->u.r.rsa)
1199 			RSA_free(sess->u.r.rsa);
1200 		break;
1201 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
1202 		if (sess->u.e.ctx) {
1203 			BN_CTX_end(sess->u.e.ctx);
1204 			BN_CTX_free(sess->u.e.ctx);
1205 		}
1206 		break;
1207 	case RTE_CRYPTO_ASYM_XFORM_MODINV:
1208 		if (sess->u.m.ctx) {
1209 			BN_CTX_end(sess->u.m.ctx);
1210 			BN_CTX_free(sess->u.m.ctx);
1211 		}
1212 		break;
1213 	case RTE_CRYPTO_ASYM_XFORM_DH:
1214 		if (sess->u.dh.dh_key)
1215 			DH_free(sess->u.dh.dh_key);
1216 		break;
1217 	case RTE_CRYPTO_ASYM_XFORM_DSA:
1218 		if (sess->u.s.dsa)
1219 			DSA_free(sess->u.s.dsa);
1220 		break;
1221 	default:
1222 		break;
1223 	}
1224 }
1225 
1226 /** Clear the memory of asymmetric session
1227  * so it doesn't leave key material behind
1228  */
1229 static void
1230 openssl_pmd_asym_session_clear(struct rte_cryptodev *dev,
1231 		struct rte_cryptodev_asym_session *sess)
1232 {
1233 	uint8_t index = dev->driver_id;
1234 	void *sess_priv = get_asym_session_private_data(sess, index);
1235 
1236 	/* Zero out the whole structure */
1237 	if (sess_priv) {
1238 		openssl_reset_asym_session(sess_priv);
1239 		memset(sess_priv, 0, sizeof(struct openssl_asym_session));
1240 		struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
1241 		set_asym_session_private_data(sess, index, NULL);
1242 		rte_mempool_put(sess_mp, sess_priv);
1243 	}
1244 }
1245 
1246 struct rte_cryptodev_ops openssl_pmd_ops = {
1247 		.dev_configure		= openssl_pmd_config,
1248 		.dev_start		= openssl_pmd_start,
1249 		.dev_stop		= openssl_pmd_stop,
1250 		.dev_close		= openssl_pmd_close,
1251 
1252 		.stats_get		= openssl_pmd_stats_get,
1253 		.stats_reset		= openssl_pmd_stats_reset,
1254 
1255 		.dev_infos_get		= openssl_pmd_info_get,
1256 
1257 		.queue_pair_setup	= openssl_pmd_qp_setup,
1258 		.queue_pair_release	= openssl_pmd_qp_release,
1259 		.queue_pair_count	= openssl_pmd_qp_count,
1260 
1261 		.sym_session_get_size	= openssl_pmd_sym_session_get_size,
1262 		.asym_session_get_size	= openssl_pmd_asym_session_get_size,
1263 		.sym_session_configure	= openssl_pmd_sym_session_configure,
1264 		.asym_session_configure	= openssl_pmd_asym_session_configure,
1265 		.sym_session_clear	= openssl_pmd_sym_session_clear,
1266 		.asym_session_clear	= openssl_pmd_asym_session_clear
1267 };
1268 
1269 struct rte_cryptodev_ops *rte_openssl_pmd_ops = &openssl_pmd_ops;
1270