xref: /dpdk/app/test/test_cryptodev_asym.c (revision 2d0c29a37a9c080c1cccb1ad7941aba2ccf5437e)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Cavium Networks
3  * Copyright (c) 2019 Intel Corporation
4  */
5 
6 #include <rte_bus_vdev.h>
7 #include <rte_common.h>
8 #include <rte_hexdump.h>
9 #include <rte_mbuf.h>
10 #include <rte_malloc.h>
11 #include <rte_memcpy.h>
12 #include <rte_pause.h>
13 
14 #include <rte_cryptodev.h>
15 #include <rte_cryptodev_pmd.h>
16 #include <rte_crypto.h>
17 
18 #include "test_cryptodev.h"
19 #include "test_cryptodev_dh_test_vectors.h"
20 #include "test_cryptodev_dsa_test_vectors.h"
21 #include "test_cryptodev_mod_test_vectors.h"
22 #include "test_cryptodev_rsa_test_vectors.h"
23 #include "test_cryptodev_asym_util.h"
24 #include "test.h"
25 
26 #define TEST_NUM_BUFS 10
27 #define TEST_NUM_SESSIONS 4
28 
29 #ifndef ARRAY_SIZE
30 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
31 #endif
32 
33 #ifndef TEST_DATA_SIZE
34 	#define TEST_DATA_SIZE 4096
35 #endif
36 #define ASYM_TEST_MSG_LEN 256
37 #define TEST_VECTOR_SIZE 256
38 
39 static int gbl_driver_id;
40 struct crypto_testsuite_params {
41 	struct rte_mempool *op_mpool;
42 	struct rte_mempool *session_mpool;
43 	struct rte_cryptodev_config conf;
44 	struct rte_cryptodev_qp_conf qp_conf;
45 	uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS];
46 	uint8_t valid_dev_count;
47 };
48 
49 struct crypto_unittest_params {
50 	struct rte_cryptodev_asym_session *sess;
51 	struct rte_crypto_op *op;
52 };
53 
54 union test_case_structure {
55 	struct modex_test_data modex;
56 	struct modinv_test_data modinv;
57 };
58 
59 struct test_cases_array {
60 	uint32_t size;
61 	const void *address[TEST_VECTOR_SIZE];
62 };
63 static struct test_cases_array test_vector = {0, { NULL } };
64 
65 static uint32_t test_index;
66 
67 static struct crypto_testsuite_params testsuite_params = { NULL };
68 
69 static int
70 test_cryptodev_asym_ver(union test_case_structure *data_tc,
71 						struct rte_crypto_op *result_op)
72 {
73 	int status = TEST_SUCCESS;
74 	int ret = 0;
75 	uint8_t *data_expected = NULL, *data_received = NULL;
76 	size_t data_size = 0;
77 
78 	switch (data_tc->modex.xform_type) {
79 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
80 		data_expected = data_tc->modex.reminder.data;
81 		data_received = result_op->asym->modex.result.data;
82 		data_size = result_op->asym->modex.result.length;
83 		break;
84 	case RTE_CRYPTO_ASYM_XFORM_MODINV:
85 		data_expected = data_tc->modinv.inverse.data;
86 		data_received = result_op->asym->modinv.result.data;
87 		data_size = result_op->asym->modinv.result.length;
88 		break;
89 	case RTE_CRYPTO_ASYM_XFORM_DH:
90 	case RTE_CRYPTO_ASYM_XFORM_DSA:
91 	case RTE_CRYPTO_ASYM_XFORM_RSA:
92 	case RTE_CRYPTO_ASYM_XFORM_NONE:
93 	case RTE_CRYPTO_ASYM_XFORM_UNSPECIFIED:
94 	default:
95 		break;
96 	}
97 	ret = memcmp(data_expected, data_received, data_size);
98 	if (ret)
99 		status = TEST_FAILED;
100 
101 	return status;
102 }
103 
104 static int
105 test_cryptodev_asym_op(struct crypto_testsuite_params *ts_params,
106 	union test_case_structure *data_tc,
107 	char *test_msg)
108 {
109 	struct rte_crypto_asym_op *asym_op = NULL;
110 	struct rte_crypto_op *op = NULL;
111 	struct rte_crypto_op *result_op = NULL;
112 	struct rte_crypto_asym_xform xform_tc;
113 	struct rte_cryptodev_asym_session *sess = NULL;
114 	struct rte_cryptodev_asym_capability_idx cap_idx;
115 	const struct rte_cryptodev_asymmetric_xform_capability *capability;
116 	uint8_t dev_id = ts_params->valid_devs[0];
117 	uint8_t input[TEST_DATA_SIZE] = {0};
118 	uint8_t *result = NULL;
119 
120 	int status = TEST_SUCCESS;
121 
122 	/* Generate crypto op data structure */
123 	op = rte_crypto_op_alloc(ts_params->op_mpool,
124 		RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
125 
126 	if (!op) {
127 		snprintf(test_msg, ASYM_TEST_MSG_LEN,
128 			"line %u FAILED: %s",
129 			__LINE__, "Failed to allocate asymmetric crypto "
130 			"operation struct");
131 		status = TEST_FAILED;
132 		goto error_exit;
133 	}
134 
135 	asym_op = op->asym;
136 	xform_tc.next = NULL;
137 	xform_tc.xform_type = data_tc->modex.xform_type;
138 
139 	cap_idx.type = xform_tc.xform_type;
140 	capability = rte_cryptodev_asym_capability_get(dev_id, &cap_idx);
141 
142 	switch (xform_tc.xform_type) {
143 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
144 		result = rte_zmalloc(NULL, data_tc->modex.result_len, 0);
145 		xform_tc.modex.modulus.data = data_tc->modex.modulus.data;
146 		xform_tc.modex.modulus.length = data_tc->modex.modulus.len;
147 		xform_tc.modex.exponent.data = data_tc->modex.exponent.data;
148 		xform_tc.modex.exponent.length = data_tc->modex.exponent.len;
149 		memcpy(input, data_tc->modex.base.data,
150 			data_tc->modex.base.len);
151 		asym_op->modex.base.data = input;
152 		asym_op->modex.base.length = data_tc->modex.base.len;
153 		asym_op->modex.result.data = result;
154 		asym_op->modex.result.length = data_tc->modex.result_len;
155 		if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
156 				xform_tc.modex.modulus.length)) {
157 			snprintf(test_msg, ASYM_TEST_MSG_LEN,
158 				"line %u "
159 				"FAILED: %s", __LINE__,
160 				"Invalid MODULUS length specified");
161 			status = TEST_FAILED;
162 			goto error_exit;
163 		}
164 		break;
165 	case RTE_CRYPTO_ASYM_XFORM_MODINV:
166 		result = rte_zmalloc(NULL, data_tc->modinv.result_len, 0);
167 		xform_tc.modinv.modulus.data = data_tc->modinv.modulus.data;
168 		xform_tc.modinv.modulus.length = data_tc->modinv.modulus.len;
169 		memcpy(input, data_tc->modinv.base.data,
170 			data_tc->modinv.base.len);
171 		asym_op->modinv.base.data = input;
172 		asym_op->modinv.base.length = data_tc->modinv.base.len;
173 		asym_op->modinv.result.data = result;
174 		asym_op->modinv.result.length = data_tc->modinv.result_len;
175 		if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
176 				xform_tc.modinv.modulus.length)) {
177 			snprintf(test_msg, ASYM_TEST_MSG_LEN,
178 				"line %u "
179 				"FAILED: %s", __LINE__,
180 				"Invalid MODULUS length specified");
181 			status = TEST_FAILED;
182 			goto error_exit;
183 		}
184 		break;
185 	case RTE_CRYPTO_ASYM_XFORM_DH:
186 	case RTE_CRYPTO_ASYM_XFORM_DSA:
187 	case RTE_CRYPTO_ASYM_XFORM_RSA:
188 	case RTE_CRYPTO_ASYM_XFORM_NONE:
189 	case RTE_CRYPTO_ASYM_XFORM_UNSPECIFIED:
190 	default:
191 		snprintf(test_msg, ASYM_TEST_MSG_LEN,
192 				"line %u "
193 				"FAILED: %s", __LINE__,
194 				"Invalid ASYM algorithm specified");
195 		status = TEST_FAILED;
196 		goto error_exit;
197 	}
198 
199 	sess = rte_cryptodev_asym_session_create(ts_params->session_mpool);
200 	if (!sess) {
201 		snprintf(test_msg, ASYM_TEST_MSG_LEN,
202 				"line %u "
203 				"FAILED: %s", __LINE__,
204 				"Session creation failed");
205 		status = TEST_FAILED;
206 		goto error_exit;
207 	}
208 
209 	if (rte_cryptodev_asym_session_init(dev_id, sess, &xform_tc,
210 			ts_params->session_mpool) < 0) {
211 		snprintf(test_msg, ASYM_TEST_MSG_LEN,
212 				"line %u FAILED: %s",
213 				__LINE__, "unabled to config sym session");
214 		status = TEST_FAILED;
215 		goto error_exit;
216 	}
217 
218 	rte_crypto_op_attach_asym_session(op, sess);
219 
220 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
221 
222 	/* Process crypto operation */
223 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
224 		snprintf(test_msg, ASYM_TEST_MSG_LEN,
225 				"line %u FAILED: %s",
226 				__LINE__, "Error sending packet for operation");
227 		status = TEST_FAILED;
228 		goto error_exit;
229 	}
230 
231 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
232 		rte_pause();
233 
234 	if (result_op == NULL) {
235 		snprintf(test_msg, ASYM_TEST_MSG_LEN,
236 				"line %u FAILED: %s",
237 				__LINE__, "Failed to process asym crypto op");
238 		status = TEST_FAILED;
239 		goto error_exit;
240 	}
241 
242 	if (test_cryptodev_asym_ver(data_tc, result_op) != TEST_SUCCESS) {
243 		snprintf(test_msg, ASYM_TEST_MSG_LEN,
244 			"line %u FAILED: %s",
245 			__LINE__, "Verification failed ");
246 		status = TEST_FAILED;
247 		goto error_exit;
248 	}
249 
250 	snprintf(test_msg, ASYM_TEST_MSG_LEN, "PASS");
251 
252 error_exit:
253 		if (sess != NULL) {
254 			rte_cryptodev_asym_session_clear(dev_id, sess);
255 			rte_cryptodev_asym_session_free(sess);
256 		}
257 
258 		if (op != NULL)
259 			rte_crypto_op_free(op);
260 
261 		if (result != NULL)
262 			rte_free(result);
263 
264 	return status;
265 }
266 
267 static int
268 test_one_case(const void *test_case)
269 {
270 	int status = TEST_SUCCESS;
271 	char test_msg[ASYM_TEST_MSG_LEN + 1];
272 
273 	/* Map the case to union */
274 	union test_case_structure tc;
275 	memcpy(&tc, test_case, sizeof(tc));
276 
277 	status = test_cryptodev_asym_op(&testsuite_params, &tc, test_msg);
278 
279 	printf("  %u) TestCase %s %s\n", test_index++,
280 		tc.modex.description, test_msg);
281 
282 	return status;
283 }
284 
285 static int
286 load_test_vectors(void)
287 {
288 	uint32_t i = 0, v_size = 0;
289 	/* Load MODEX vector*/
290 	v_size = ARRAY_SIZE(modex_test_case);
291 	for (i = 0; i < v_size; i++) {
292 		if (test_vector.size >= (TEST_VECTOR_SIZE)) {
293 			RTE_LOG(DEBUG, USER1,
294 				"TEST_VECTOR_SIZE too small\n");
295 			return -1;
296 		}
297 		test_vector.address[test_vector.size] = &modex_test_case[i];
298 		test_vector.size++;
299 	}
300 	/* Load MODINV vector*/
301 	v_size = ARRAY_SIZE(modinv_test_case);
302 	for (i = 0; i < v_size; i++) {
303 		if (test_vector.size >= (TEST_VECTOR_SIZE)) {
304 			RTE_LOG(DEBUG, USER1,
305 				"TEST_VECTOR_SIZE too small\n");
306 			return -1;
307 		}
308 		test_vector.address[test_vector.size] = &modinv_test_case[i];
309 		test_vector.size++;
310 	}
311 	return 0;
312 }
313 
314 static int
315 test_one_by_one(void)
316 {
317 	int status = TEST_SUCCESS;
318 	uint32_t i = 0;
319 
320 	/* Go through all test cases */
321 	test_index = 0;
322 	for (i = 0; i < test_vector.size; i++) {
323 		if (test_one_case(test_vector.address[i]) != TEST_SUCCESS)
324 			status = TEST_FAILED;
325 	}
326 
327 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
328 	return status;
329 }
330 
331 static int
332 test_rsa_sign_verify(void)
333 {
334 	struct crypto_testsuite_params *ts_params = &testsuite_params;
335 	struct rte_mempool *op_mpool = ts_params->op_mpool;
336 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
337 	uint8_t dev_id = ts_params->valid_devs[0];
338 	struct rte_crypto_asym_op *asym_op = NULL;
339 	struct rte_crypto_op *op = NULL, *result_op = NULL;
340 	struct rte_cryptodev_asym_session *sess = NULL;
341 	int status = TEST_SUCCESS;
342 	uint8_t output_buf[TEST_DATA_SIZE] = {0};
343 	uint8_t input_buf[TEST_DATA_SIZE] = {0};
344 
345 	sess = rte_cryptodev_asym_session_create(sess_mpool);
346 
347 	if (!sess) {
348 		RTE_LOG(ERR, USER1, "line %u "
349 				"FAILED: %s", __LINE__,
350 				"Session creation failed");
351 		status = TEST_FAILED;
352 		goto error_exit;
353 	}
354 
355 	if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform,
356 				sess_mpool) < 0) {
357 		RTE_LOG(ERR, USER1,
358 				"line %u FAILED: %s",
359 				__LINE__, "unabled to config sym session");
360 		status = TEST_FAILED;
361 		goto error_exit;
362 	}
363 
364 	/* set up crypto op data structure */
365 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
366 	if (!op) {
367 		RTE_LOG(ERR, USER1,
368 				"line %u FAILED: %s",
369 				__LINE__,
370 				"Failed to allocate asymmetric crypto "
371 				"operation struct");
372 		status = TEST_FAILED;
373 		goto error_exit;
374 	}
375 
376 	asym_op = op->asym;
377 	/* Compute sign on the test vector */
378 	asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
379 
380 	memcpy(input_buf, &rsaplaintext.data,
381 			rsaplaintext.len);
382 	asym_op->rsa.message.data = input_buf;
383 	asym_op->rsa.message.length = rsaplaintext.len;
384 	asym_op->rsa.sign.data = output_buf;
385 	asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1;
386 
387 	debug_hexdump(stdout, "message", asym_op->rsa.message.data,
388 			asym_op->rsa.message.length);
389 
390 	/* attach asymmetric crypto session to crypto operations */
391 	rte_crypto_op_attach_asym_session(op, sess);
392 
393 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
394 
395 	/* Process crypto operation */
396 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
397 		RTE_LOG(ERR, USER1,
398 				"line %u FAILED: %s",
399 				__LINE__, "Error sending packet for operation");
400 		status = TEST_FAILED;
401 		goto error_exit;
402 	}
403 
404 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
405 		rte_pause();
406 
407 	if (result_op == NULL) {
408 		RTE_LOG(ERR, USER1,
409 				"line %u FAILED: %s",
410 				__LINE__, "Failed to process asym crypto op");
411 		status = TEST_FAILED;
412 		goto error_exit;
413 	}
414 	debug_hexdump(stdout, "signed message", asym_op->rsa.sign.data,
415 			asym_op->rsa.sign.length);
416 	asym_op = result_op->asym;
417 
418 	/* Verify sign */
419 	asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
420 	asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2;
421 
422 	/* Process crypto operation */
423 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
424 		RTE_LOG(ERR, USER1,
425 				"line %u FAILED: %s",
426 				__LINE__, "Error sending packet for operation");
427 		status = TEST_FAILED;
428 		goto error_exit;
429 	}
430 
431 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
432 		rte_pause();
433 
434 	if (result_op == NULL) {
435 		RTE_LOG(ERR, USER1,
436 				"line %u FAILED: %s",
437 				__LINE__, "Failed to process asym crypto op");
438 		status = TEST_FAILED;
439 		goto error_exit;
440 	}
441 	status = TEST_SUCCESS;
442 	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
443 		RTE_LOG(ERR, USER1,
444 				"line %u FAILED: %s",
445 				__LINE__, "Failed to process asym crypto op");
446 		status = TEST_FAILED;
447 		goto error_exit;
448 	}
449 
450 error_exit:
451 
452 	if (sess) {
453 		rte_cryptodev_asym_session_clear(dev_id, sess);
454 		rte_cryptodev_asym_session_free(sess);
455 	}
456 
457 	if (op)
458 		rte_crypto_op_free(op);
459 
460 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
461 
462 	return status;
463 }
464 
465 static int
466 test_rsa_enc_dec(void)
467 {
468 	struct crypto_testsuite_params *ts_params = &testsuite_params;
469 	struct rte_mempool *op_mpool = ts_params->op_mpool;
470 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
471 	uint8_t dev_id = ts_params->valid_devs[0];
472 	struct rte_crypto_asym_op *asym_op = NULL;
473 	struct rte_crypto_op *op = NULL, *result_op = NULL;
474 	struct rte_cryptodev_asym_session *sess = NULL;
475 	int status = TEST_SUCCESS;
476 	uint8_t input_buf[TEST_DATA_SIZE] = {0};
477 
478 	sess = rte_cryptodev_asym_session_create(sess_mpool);
479 
480 	if (!sess) {
481 		RTE_LOG(ERR, USER1, "line %u "
482 				"FAILED: %s", __LINE__,
483 				"Session creation failed");
484 		status = TEST_FAILED;
485 		goto error_exit;
486 	}
487 
488 	if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform,
489 				sess_mpool) < 0) {
490 		RTE_LOG(ERR, USER1,
491 				"line %u FAILED: %s",
492 				__LINE__, "unabled to config sym session");
493 		status = TEST_FAILED;
494 		goto error_exit;
495 	}
496 
497 	/* set up crypto op data structure */
498 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
499 	if (!op) {
500 		RTE_LOG(ERR, USER1,
501 				"line %u FAILED: %s",
502 				__LINE__,
503 				"Failed to allocate asymmetric crypto "
504 				"operation struct");
505 		status = TEST_FAILED;
506 		goto error_exit;
507 	}
508 
509 	asym_op = op->asym;
510 	/*Compute encryption on the test vector */
511 	asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT;
512 
513 	memcpy(input_buf, rsaplaintext.data,
514 			rsaplaintext.len);
515 	asym_op->rsa.message.data = input_buf;
516 	asym_op->rsa.message.length = rsaplaintext.len;
517 	asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2;
518 
519 	debug_hexdump(stdout, "message", asym_op->rsa.message.data,
520 			asym_op->rsa.message.length);
521 
522 	/* attach asymmetric crypto session to crypto operations */
523 	rte_crypto_op_attach_asym_session(op, sess);
524 
525 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
526 
527 	/* Process crypto operation */
528 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
529 		RTE_LOG(ERR, USER1,
530 				"line %u FAILED: %s",
531 				__LINE__, "Error sending packet for operation");
532 		status = TEST_FAILED;
533 		goto error_exit;
534 	}
535 
536 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
537 		rte_pause();
538 
539 	if (result_op == NULL) {
540 		RTE_LOG(ERR, USER1,
541 				"line %u FAILED: %s",
542 				__LINE__, "Failed to process asym crypto op");
543 		status = TEST_FAILED;
544 		goto error_exit;
545 	}
546 	debug_hexdump(stdout, "encrypted message", asym_op->rsa.message.data,
547 			asym_op->rsa.message.length);
548 	/* Use the resulted output as decryption Input vector*/
549 	asym_op = result_op->asym;
550 	asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_DECRYPT;
551 	asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1;
552 
553 	/* Process crypto operation */
554 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
555 		RTE_LOG(ERR, USER1,
556 				"line %u FAILED: %s",
557 				__LINE__, "Error sending packet for operation");
558 		status = TEST_FAILED;
559 		goto error_exit;
560 	}
561 
562 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
563 		rte_pause();
564 
565 	if (result_op == NULL) {
566 		RTE_LOG(ERR, USER1,
567 				"line %u FAILED: %s",
568 				__LINE__, "Failed to process asym crypto op");
569 		status = TEST_FAILED;
570 		goto error_exit;
571 	}
572 	status = TEST_SUCCESS;
573 	int ret = 0;
574 	ret = rsa_verify(&rsaplaintext, result_op);
575 	if (ret)
576 		status = TEST_FAILED;
577 
578 error_exit:
579 
580 	if (sess) {
581 		rte_cryptodev_asym_session_clear(dev_id, sess);
582 		rte_cryptodev_asym_session_free(sess);
583 	}
584 
585 	if (op)
586 		rte_crypto_op_free(op);
587 
588 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
589 
590 	return status;
591 }
592 
593 static int
594 testsuite_setup(void)
595 {
596 	struct crypto_testsuite_params *ts_params = &testsuite_params;
597 	struct rte_cryptodev_info info;
598 	uint32_t i = 0, nb_devs, dev_id;
599 	int ret;
600 	uint16_t qp_id;
601 
602 	memset(ts_params, 0, sizeof(*ts_params));
603 
604 	test_vector.size = 0;
605 	load_test_vectors();
606 
607 	ts_params->op_mpool = rte_crypto_op_pool_create(
608 			"CRYPTO_ASYM_OP_POOL",
609 			RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
610 			TEST_NUM_BUFS, 0,
611 			0,
612 			rte_socket_id());
613 	if (ts_params->op_mpool == NULL) {
614 		RTE_LOG(ERR, USER1, "Can't create ASYM_CRYPTO_OP_POOL\n");
615 		return TEST_FAILED;
616 	}
617 
618 	/* Create an OPENSSL device if required */
619 	if (gbl_driver_id == rte_cryptodev_driver_id_get(
620 			RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))) {
621 		nb_devs = rte_cryptodev_device_count_by_driver(
622 				rte_cryptodev_driver_id_get(
623 				RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)));
624 		if (nb_devs < 1) {
625 			ret = rte_vdev_init(
626 				RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD),
627 				NULL);
628 
629 			TEST_ASSERT(ret == 0, "Failed to create "
630 				"instance of pmd : %s",
631 				RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
632 		}
633 	}
634 
635 	nb_devs = rte_cryptodev_count();
636 	if (nb_devs < 1) {
637 		RTE_LOG(ERR, USER1, "No crypto devices found?\n");
638 		return TEST_FAILED;
639 	}
640 
641 	/* Create list of valid crypto devs */
642 	for (i = 0; i < nb_devs; i++) {
643 		rte_cryptodev_info_get(i, &info);
644 		if (info.driver_id == gbl_driver_id)
645 			ts_params->valid_devs[ts_params->valid_dev_count++] = i;
646 	}
647 
648 	if (ts_params->valid_dev_count < 1)
649 		return TEST_FAILED;
650 
651 	/* Set up all the qps on the first of the valid devices found */
652 
653 	dev_id = ts_params->valid_devs[0];
654 
655 	rte_cryptodev_info_get(dev_id, &info);
656 
657 	/* check if device support asymmetric, skip if not */
658 	if (!(info.feature_flags &
659 				RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) {
660 		RTE_LOG(ERR, USER1, "Device doesn't support asymmetric. "
661 				"Test Skipped.\n");
662 		return TEST_FAILED;
663 	}
664 
665 	/* configure device with num qp */
666 	ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs;
667 	ts_params->conf.socket_id = SOCKET_ID_ANY;
668 	TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id,
669 			&ts_params->conf),
670 			"Failed to configure cryptodev %u with %u qps",
671 			dev_id, ts_params->conf.nb_queue_pairs);
672 
673 	/* configure qp */
674 	ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
675 	ts_params->qp_conf.mp_session = ts_params->session_mpool;
676 	ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
677 	for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
678 		TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
679 			dev_id, qp_id, &ts_params->qp_conf,
680 			rte_cryptodev_socket_id(dev_id)),
681 			"Failed to setup queue pair %u on cryptodev %u ASYM",
682 			qp_id, dev_id);
683 	}
684 
685 	/* setup asym session pool */
686 	unsigned int session_size =
687 		rte_cryptodev_asym_get_private_session_size(dev_id);
688 	/*
689 	 * Create mempool with TEST_NUM_SESSIONS * 2,
690 	 * to include the session headers
691 	 */
692 	ts_params->session_mpool = rte_mempool_create(
693 				"test_asym_sess_mp",
694 				TEST_NUM_SESSIONS * 2,
695 				session_size,
696 				0, 0, NULL, NULL, NULL,
697 				NULL, SOCKET_ID_ANY,
698 				0);
699 
700 	TEST_ASSERT_NOT_NULL(ts_params->session_mpool,
701 			"session mempool allocation failed");
702 
703 	return TEST_SUCCESS;
704 }
705 
706 static void
707 testsuite_teardown(void)
708 {
709 	struct crypto_testsuite_params *ts_params = &testsuite_params;
710 
711 	if (ts_params->op_mpool != NULL) {
712 		RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n",
713 		rte_mempool_avail_count(ts_params->op_mpool));
714 	}
715 
716 	/* Free session mempools */
717 	if (ts_params->session_mpool != NULL) {
718 		rte_mempool_free(ts_params->session_mpool);
719 		ts_params->session_mpool = NULL;
720 	}
721 }
722 
723 static int
724 ut_setup(void)
725 {
726 	struct crypto_testsuite_params *ts_params = &testsuite_params;
727 
728 	uint16_t qp_id;
729 
730 	/* Reconfigure device to default parameters */
731 	ts_params->conf.socket_id = SOCKET_ID_ANY;
732 
733 	TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0],
734 			&ts_params->conf),
735 			"Failed to configure cryptodev %u",
736 			ts_params->valid_devs[0]);
737 
738 	for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs ; qp_id++) {
739 		TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
740 			ts_params->valid_devs[0], qp_id,
741 			&ts_params->qp_conf,
742 			rte_cryptodev_socket_id(ts_params->valid_devs[0])),
743 			"Failed to setup queue pair %u on cryptodev %u",
744 			qp_id, ts_params->valid_devs[0]);
745 	}
746 
747 	rte_cryptodev_stats_reset(ts_params->valid_devs[0]);
748 
749 	/* Start the device */
750 	TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_devs[0]),
751 						"Failed to start cryptodev %u",
752 						ts_params->valid_devs[0]);
753 
754 	return TEST_SUCCESS;
755 }
756 
757 static void
758 ut_teardown(void)
759 {
760 	struct crypto_testsuite_params *ts_params = &testsuite_params;
761 	struct rte_cryptodev_stats stats;
762 
763 	rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats);
764 
765 	/* Stop the device */
766 	rte_cryptodev_stop(ts_params->valid_devs[0]);
767 }
768 
769 static inline void print_asym_capa(
770 		const struct rte_cryptodev_asymmetric_xform_capability *capa)
771 {
772 	int i = 0;
773 
774 	printf("\nxform type: %s\n===================\n",
775 			rte_crypto_asym_xform_strings[capa->xform_type]);
776 	printf("operation supported -");
777 
778 	for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) {
779 		/* check supported operations */
780 		if (rte_cryptodev_asym_xform_capability_check_optype(capa, i))
781 			printf(" %s",
782 					rte_crypto_asym_op_strings[i]);
783 		}
784 		switch (capa->xform_type) {
785 		case RTE_CRYPTO_ASYM_XFORM_RSA:
786 		case RTE_CRYPTO_ASYM_XFORM_MODINV:
787 		case RTE_CRYPTO_ASYM_XFORM_MODEX:
788 		case RTE_CRYPTO_ASYM_XFORM_DH:
789 		case RTE_CRYPTO_ASYM_XFORM_DSA:
790 			printf(" modlen: min %d max %d increment %d\n",
791 					capa->modlen.min,
792 					capa->modlen.max,
793 					capa->modlen.increment);
794 		break;
795 		default:
796 			break;
797 		}
798 }
799 
800 static int
801 test_capability(void)
802 {
803 	struct crypto_testsuite_params *ts_params = &testsuite_params;
804 	uint8_t dev_id = ts_params->valid_devs[0];
805 	struct rte_cryptodev_info dev_info;
806 	const struct rte_cryptodev_capabilities *dev_capa;
807 	int i = 0;
808 	struct rte_cryptodev_asym_capability_idx idx;
809 	const struct rte_cryptodev_asymmetric_xform_capability *capa;
810 
811 	rte_cryptodev_info_get(dev_id, &dev_info);
812 	if (!(dev_info.feature_flags &
813 				RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) {
814 		RTE_LOG(INFO, USER1,
815 				"Device doesn't support asymmetric. Test Skipped\n");
816 		return TEST_SUCCESS;
817 	}
818 
819 	/* print xform capability */
820 	for (i = 0;
821 		dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
822 		i++) {
823 		dev_capa = &(dev_info.capabilities[i]);
824 		if (dev_info.capabilities[i].op ==
825 				RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
826 			idx.type = dev_capa->asym.xform_capa.xform_type;
827 
828 			capa = rte_cryptodev_asym_capability_get(dev_id,
829 				(const struct
830 				rte_cryptodev_asym_capability_idx *) &idx);
831 			print_asym_capa(capa);
832 			}
833 	}
834 	return TEST_SUCCESS;
835 }
836 
837 static int
838 test_dh_gen_shared_sec(struct rte_crypto_asym_xform *xfrm)
839 {
840 	struct crypto_testsuite_params *ts_params = &testsuite_params;
841 	struct rte_mempool *op_mpool = ts_params->op_mpool;
842 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
843 	uint8_t dev_id = ts_params->valid_devs[0];
844 	struct rte_crypto_asym_op *asym_op = NULL;
845 	struct rte_crypto_op *op = NULL, *result_op = NULL;
846 	struct rte_cryptodev_asym_session *sess = NULL;
847 	int status = TEST_SUCCESS;
848 	uint8_t output[TEST_DH_MOD_LEN];
849 	struct rte_crypto_asym_xform xform = *xfrm;
850 	uint8_t peer[] = "01234567890123456789012345678901234567890123456789";
851 
852 	sess = rte_cryptodev_asym_session_create(sess_mpool);
853 	if (sess == NULL) {
854 		RTE_LOG(ERR, USER1,
855 				"line %u FAILED: %s", __LINE__,
856 				"Session creation failed");
857 		status = TEST_FAILED;
858 		goto error_exit;
859 	}
860 	/* set up crypto op data structure */
861 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
862 	if (!op) {
863 		RTE_LOG(ERR, USER1,
864 			"line %u FAILED: %s",
865 			__LINE__, "Failed to allocate asymmetric crypto "
866 			"operation struct");
867 		status = TEST_FAILED;
868 		goto error_exit;
869 	}
870 	asym_op = op->asym;
871 
872 	/* Setup a xform and op to generate private key only */
873 	xform.dh.type = RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE;
874 	xform.next = NULL;
875 	asym_op->dh.priv_key.data = dh_test_params.priv_key.data;
876 	asym_op->dh.priv_key.length = dh_test_params.priv_key.length;
877 	asym_op->dh.pub_key.data = (uint8_t *)peer;
878 	asym_op->dh.pub_key.length = sizeof(peer);
879 	asym_op->dh.shared_secret.data = output;
880 	asym_op->dh.shared_secret.length = sizeof(output);
881 
882 	if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
883 			sess_mpool) < 0) {
884 		RTE_LOG(ERR, USER1,
885 				"line %u FAILED: %s",
886 				__LINE__, "unabled to config sym session");
887 		status = TEST_FAILED;
888 		goto error_exit;
889 	}
890 
891 	/* attach asymmetric crypto session to crypto operations */
892 	rte_crypto_op_attach_asym_session(op, sess);
893 
894 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
895 
896 	/* Process crypto operation */
897 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
898 		RTE_LOG(ERR, USER1,
899 			"line %u FAILED: %s",
900 			__LINE__, "Error sending packet for operation");
901 		status = TEST_FAILED;
902 		goto error_exit;
903 	}
904 
905 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
906 		rte_pause();
907 
908 	if (result_op == NULL) {
909 		RTE_LOG(ERR, USER1,
910 			"line %u FAILED: %s",
911 			__LINE__, "Failed to process asym crypto op");
912 		status = TEST_FAILED;
913 		goto error_exit;
914 	}
915 
916 	debug_hexdump(stdout, "shared secret:",
917 			asym_op->dh.shared_secret.data,
918 			asym_op->dh.shared_secret.length);
919 
920 error_exit:
921 	if (sess != NULL) {
922 		rte_cryptodev_asym_session_clear(dev_id, sess);
923 		rte_cryptodev_asym_session_free(sess);
924 	}
925 	if (op != NULL)
926 		rte_crypto_op_free(op);
927 	return status;
928 }
929 
930 static int
931 test_dh_gen_priv_key(struct rte_crypto_asym_xform *xfrm)
932 {
933 	struct crypto_testsuite_params *ts_params = &testsuite_params;
934 	struct rte_mempool *op_mpool = ts_params->op_mpool;
935 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
936 	uint8_t dev_id = ts_params->valid_devs[0];
937 	struct rte_crypto_asym_op *asym_op = NULL;
938 	struct rte_crypto_op *op = NULL, *result_op = NULL;
939 	struct rte_cryptodev_asym_session *sess = NULL;
940 	int status = TEST_SUCCESS;
941 	uint8_t output[TEST_DH_MOD_LEN];
942 	struct rte_crypto_asym_xform xform = *xfrm;
943 
944 	sess = rte_cryptodev_asym_session_create(sess_mpool);
945 	if (sess == NULL) {
946 		RTE_LOG(ERR, USER1,
947 				 "line %u FAILED: %s", __LINE__,
948 				"Session creation failed");
949 		status = TEST_FAILED;
950 		goto error_exit;
951 	}
952 	/* set up crypto op data structure */
953 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
954 	if (!op) {
955 		RTE_LOG(ERR, USER1,
956 			"line %u FAILED: %s",
957 			__LINE__, "Failed to allocate asymmetric crypto "
958 			"operation struct");
959 		status = TEST_FAILED;
960 		goto error_exit;
961 	}
962 	asym_op = op->asym;
963 
964 	/* Setup a xform and op to generate private key only */
965 	xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE;
966 	xform.next = NULL;
967 	asym_op->dh.priv_key.data = output;
968 	asym_op->dh.priv_key.length = sizeof(output);
969 
970 	if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
971 			sess_mpool) < 0) {
972 		RTE_LOG(ERR, USER1,
973 				"line %u FAILED: %s",
974 				__LINE__, "unabled to config sym session");
975 		status = TEST_FAILED;
976 		goto error_exit;
977 	}
978 
979 	/* attach asymmetric crypto session to crypto operations */
980 	rte_crypto_op_attach_asym_session(op, sess);
981 
982 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
983 
984 	/* Process crypto operation */
985 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
986 		RTE_LOG(ERR, USER1,
987 			"line %u FAILED: %s",
988 			__LINE__, "Error sending packet for operation");
989 		status = TEST_FAILED;
990 		goto error_exit;
991 	}
992 
993 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
994 		rte_pause();
995 
996 	if (result_op == NULL) {
997 		RTE_LOG(ERR, USER1,
998 			"line %u FAILED: %s",
999 			__LINE__, "Failed to process asym crypto op");
1000 		status = TEST_FAILED;
1001 		goto error_exit;
1002 	}
1003 
1004 	debug_hexdump(stdout, "private key:",
1005 			asym_op->dh.priv_key.data,
1006 			asym_op->dh.priv_key.length);
1007 
1008 
1009 error_exit:
1010 	if (sess != NULL) {
1011 		rte_cryptodev_asym_session_clear(dev_id, sess);
1012 		rte_cryptodev_asym_session_free(sess);
1013 	}
1014 	if (op != NULL)
1015 		rte_crypto_op_free(op);
1016 
1017 	return status;
1018 }
1019 
1020 
1021 static int
1022 test_dh_gen_pub_key(struct rte_crypto_asym_xform *xfrm)
1023 {
1024 	struct crypto_testsuite_params *ts_params = &testsuite_params;
1025 	struct rte_mempool *op_mpool = ts_params->op_mpool;
1026 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
1027 	uint8_t dev_id = ts_params->valid_devs[0];
1028 	struct rte_crypto_asym_op *asym_op = NULL;
1029 	struct rte_crypto_op *op = NULL, *result_op = NULL;
1030 	struct rte_cryptodev_asym_session *sess = NULL;
1031 	int status = TEST_SUCCESS;
1032 	uint8_t output[TEST_DH_MOD_LEN];
1033 	struct rte_crypto_asym_xform xform = *xfrm;
1034 
1035 	sess = rte_cryptodev_asym_session_create(sess_mpool);
1036 	if (sess == NULL) {
1037 		RTE_LOG(ERR, USER1,
1038 				 "line %u FAILED: %s", __LINE__,
1039 				"Session creation failed");
1040 		status = TEST_FAILED;
1041 		goto error_exit;
1042 	}
1043 	/* set up crypto op data structure */
1044 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1045 	if (!op) {
1046 		RTE_LOG(ERR, USER1,
1047 			"line %u FAILED: %s",
1048 			__LINE__, "Failed to allocate asymmetric crypto "
1049 			"operation struct");
1050 		status = TEST_FAILED;
1051 		goto error_exit;
1052 	}
1053 	asym_op = op->asym;
1054 	/* Setup a xform chain to generate public key
1055 	 * using test private key
1056 	 *
1057 	 */
1058 	xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE;
1059 	xform.next = NULL;
1060 
1061 	asym_op->dh.pub_key.data = output;
1062 	asym_op->dh.pub_key.length = sizeof(output);
1063 	/* load pre-defined private key */
1064 	asym_op->dh.priv_key.data = rte_malloc(NULL,
1065 					dh_test_params.priv_key.length,
1066 					0);
1067 	asym_op->dh.priv_key = dh_test_params.priv_key;
1068 
1069 	if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
1070 			sess_mpool) < 0) {
1071 		RTE_LOG(ERR, USER1,
1072 				"line %u FAILED: %s",
1073 				__LINE__, "unabled to config sym session");
1074 		status = TEST_FAILED;
1075 		goto error_exit;
1076 	}
1077 
1078 	/* attach asymmetric crypto session to crypto operations */
1079 	rte_crypto_op_attach_asym_session(op, sess);
1080 
1081 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
1082 
1083 	/* Process crypto operation */
1084 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
1085 		RTE_LOG(ERR, USER1,
1086 			"line %u FAILED: %s",
1087 			__LINE__, "Error sending packet for operation");
1088 		status = TEST_FAILED;
1089 		goto error_exit;
1090 	}
1091 
1092 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
1093 		rte_pause();
1094 
1095 	if (result_op == NULL) {
1096 		RTE_LOG(ERR, USER1,
1097 			"line %u FAILED: %s",
1098 			__LINE__, "Failed to process asym crypto op");
1099 		status = TEST_FAILED;
1100 		goto error_exit;
1101 	}
1102 
1103 	debug_hexdump(stdout, "pub key:",
1104 			asym_op->dh.pub_key.data, asym_op->dh.pub_key.length);
1105 
1106 	debug_hexdump(stdout, "priv key:",
1107 			asym_op->dh.priv_key.data, asym_op->dh.priv_key.length);
1108 
1109 error_exit:
1110 	if (sess != NULL) {
1111 		rte_cryptodev_asym_session_clear(dev_id, sess);
1112 		rte_cryptodev_asym_session_free(sess);
1113 	}
1114 	if (op != NULL)
1115 		rte_crypto_op_free(op);
1116 
1117 	return status;
1118 }
1119 
1120 static int
1121 test_dh_gen_kp(struct rte_crypto_asym_xform *xfrm)
1122 {
1123 	struct crypto_testsuite_params *ts_params = &testsuite_params;
1124 	struct rte_mempool *op_mpool = ts_params->op_mpool;
1125 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
1126 	uint8_t dev_id = ts_params->valid_devs[0];
1127 	struct rte_crypto_asym_op *asym_op = NULL;
1128 	struct rte_crypto_op *op = NULL, *result_op = NULL;
1129 	struct rte_cryptodev_asym_session *sess = NULL;
1130 	int status = TEST_SUCCESS;
1131 	uint8_t out_pub_key[TEST_DH_MOD_LEN];
1132 	uint8_t out_prv_key[TEST_DH_MOD_LEN];
1133 	struct rte_crypto_asym_xform pub_key_xform;
1134 	struct rte_crypto_asym_xform xform = *xfrm;
1135 
1136 	sess = rte_cryptodev_asym_session_create(sess_mpool);
1137 	if (sess == NULL) {
1138 		RTE_LOG(ERR, USER1,
1139 				 "line %u FAILED: %s", __LINE__,
1140 				"Session creation failed");
1141 		status = TEST_FAILED;
1142 		goto error_exit;
1143 	}
1144 
1145 	/* set up crypto op data structure */
1146 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1147 	if (!op) {
1148 		RTE_LOG(ERR, USER1,
1149 			"line %u FAILED: %s",
1150 			__LINE__, "Failed to allocate asymmetric crypto "
1151 			"operation struct");
1152 		status = TEST_FAILED;
1153 		goto error_exit;
1154 	}
1155 	asym_op = op->asym;
1156 	/* Setup a xform chain to generate
1157 	 * private key first followed by
1158 	 * public key
1159 	 */xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE;
1160 	pub_key_xform.xform_type = RTE_CRYPTO_ASYM_XFORM_DH;
1161 	pub_key_xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE;
1162 	xform.next = &pub_key_xform;
1163 
1164 	asym_op->dh.pub_key.data = out_pub_key;
1165 	asym_op->dh.pub_key.length = sizeof(out_pub_key);
1166 	asym_op->dh.priv_key.data = out_prv_key;
1167 	asym_op->dh.priv_key.length = sizeof(out_prv_key);
1168 	if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
1169 			sess_mpool) < 0) {
1170 		RTE_LOG(ERR, USER1,
1171 				"line %u FAILED: %s",
1172 				__LINE__, "unabled to config sym session");
1173 		status = TEST_FAILED;
1174 		goto error_exit;
1175 	}
1176 
1177 	/* attach asymmetric crypto session to crypto operations */
1178 	rte_crypto_op_attach_asym_session(op, sess);
1179 
1180 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
1181 
1182 	/* Process crypto operation */
1183 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
1184 		RTE_LOG(ERR, USER1,
1185 			"line %u FAILED: %s",
1186 			__LINE__, "Error sending packet for operation");
1187 		status = TEST_FAILED;
1188 		goto error_exit;
1189 	}
1190 
1191 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
1192 		rte_pause();
1193 
1194 	if (result_op == NULL) {
1195 		RTE_LOG(ERR, USER1,
1196 			"line %u FAILED: %s",
1197 			__LINE__, "Failed to process asym crypto op");
1198 		status = TEST_FAILED;
1199 		goto error_exit;
1200 	}
1201 	debug_hexdump(stdout, "priv key:",
1202 			out_prv_key, asym_op->dh.priv_key.length);
1203 	debug_hexdump(stdout, "pub key:",
1204 			out_pub_key, asym_op->dh.pub_key.length);
1205 
1206 error_exit:
1207 	if (sess != NULL) {
1208 		rte_cryptodev_asym_session_clear(dev_id, sess);
1209 		rte_cryptodev_asym_session_free(sess);
1210 	}
1211 	if (op != NULL)
1212 		rte_crypto_op_free(op);
1213 
1214 	return status;
1215 }
1216 
1217 static int
1218 test_mod_inv(void)
1219 {
1220 	struct crypto_testsuite_params *ts_params = &testsuite_params;
1221 	struct rte_mempool *op_mpool = ts_params->op_mpool;
1222 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
1223 	uint8_t dev_id = ts_params->valid_devs[0];
1224 	struct rte_crypto_asym_op *asym_op = NULL;
1225 	struct rte_crypto_op *op = NULL, *result_op = NULL;
1226 	struct rte_cryptodev_asym_session *sess = NULL;
1227 	int status = TEST_SUCCESS;
1228 	struct rte_cryptodev_asym_capability_idx cap_idx;
1229 	const struct rte_cryptodev_asymmetric_xform_capability *capability;
1230 	uint8_t input[TEST_DATA_SIZE] = {0};
1231 	int ret = 0;
1232 	uint8_t result[sizeof(mod_p)] = { 0 };
1233 
1234 	if (rte_cryptodev_asym_get_xform_enum(
1235 		&modinv_xform.xform_type, "modinv") < 0) {
1236 		RTE_LOG(ERR, USER1,
1237 				 "Invalid ASYNC algorithm specified\n");
1238 		return -1;
1239 	}
1240 
1241 	cap_idx.type = modinv_xform.xform_type;
1242 	capability = rte_cryptodev_asym_capability_get(dev_id,
1243 					&cap_idx);
1244 
1245 	if (rte_cryptodev_asym_xform_capability_check_modlen(
1246 		capability,
1247 		modinv_xform.modinv.modulus.length)) {
1248 		RTE_LOG(ERR, USER1,
1249 				 "Invalid MODULOUS length specified\n");
1250 				return -1;
1251 		}
1252 
1253 	sess = rte_cryptodev_asym_session_create(sess_mpool);
1254 	if (!sess) {
1255 		RTE_LOG(ERR, USER1, "line %u "
1256 				"FAILED: %s", __LINE__,
1257 				"Session creation failed");
1258 		status = TEST_FAILED;
1259 		goto error_exit;
1260 	}
1261 
1262 	if (rte_cryptodev_asym_session_init(dev_id, sess, &modinv_xform,
1263 			sess_mpool) < 0) {
1264 		RTE_LOG(ERR, USER1,
1265 				"line %u FAILED: %s",
1266 				__LINE__, "unabled to config sym session");
1267 		status = TEST_FAILED;
1268 		goto error_exit;
1269 	}
1270 
1271 	/* generate crypto op data structure */
1272 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1273 	if (!op) {
1274 		RTE_LOG(ERR, USER1,
1275 			"line %u FAILED: %s",
1276 			__LINE__, "Failed to allocate asymmetric crypto "
1277 			"operation struct");
1278 		status = TEST_FAILED;
1279 		goto error_exit;
1280 	}
1281 
1282 	asym_op = op->asym;
1283 	memcpy(input, base, sizeof(base));
1284 	asym_op->modinv.base.data = input;
1285 	asym_op->modinv.base.length = sizeof(base);
1286 	asym_op->modinv.result.data = result;
1287 	asym_op->modinv.result.length = sizeof(result);
1288 
1289 	/* attach asymmetric crypto session to crypto operations */
1290 	rte_crypto_op_attach_asym_session(op, sess);
1291 
1292 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
1293 
1294 	/* Process crypto operation */
1295 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
1296 		RTE_LOG(ERR, USER1,
1297 			"line %u FAILED: %s",
1298 			__LINE__, "Error sending packet for operation");
1299 		status = TEST_FAILED;
1300 		goto error_exit;
1301 	}
1302 
1303 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
1304 		rte_pause();
1305 
1306 	if (result_op == NULL) {
1307 		RTE_LOG(ERR, USER1,
1308 				"line %u FAILED: %s",
1309 				__LINE__, "Failed to process asym crypto op");
1310 		status = TEST_FAILED;
1311 		goto error_exit;
1312 	}
1313 
1314 	ret = verify_modinv(mod_inv, result_op);
1315 	if (ret) {
1316 		RTE_LOG(ERR, USER1,
1317 			 "operation verification failed\n");
1318 		status = TEST_FAILED;
1319 	}
1320 
1321 error_exit:
1322 	if (sess) {
1323 		rte_cryptodev_asym_session_clear(dev_id, sess);
1324 		rte_cryptodev_asym_session_free(sess);
1325 	}
1326 
1327 	if (op)
1328 		rte_crypto_op_free(op);
1329 
1330 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
1331 
1332 	return status;
1333 }
1334 
1335 static int
1336 test_mod_exp(void)
1337 {
1338 	struct crypto_testsuite_params *ts_params = &testsuite_params;
1339 	struct rte_mempool *op_mpool = ts_params->op_mpool;
1340 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
1341 	uint8_t dev_id = ts_params->valid_devs[0];
1342 	struct rte_crypto_asym_op *asym_op = NULL;
1343 	struct rte_crypto_op *op = NULL, *result_op = NULL;
1344 	struct rte_cryptodev_asym_session *sess = NULL;
1345 	int status = TEST_SUCCESS;
1346 	struct rte_cryptodev_asym_capability_idx cap_idx;
1347 	const struct rte_cryptodev_asymmetric_xform_capability *capability;
1348 	uint8_t input[TEST_DATA_SIZE] = {0};
1349 	int ret = 0;
1350 	uint8_t result[sizeof(mod_p)] = { 0 };
1351 
1352 	if (rte_cryptodev_asym_get_xform_enum(&modex_xform.xform_type,
1353 		"modexp")
1354 		< 0) {
1355 		RTE_LOG(ERR, USER1,
1356 				"Invalid ASYNC algorithm specified\n");
1357 		return -1;
1358 	}
1359 
1360 	/* check for modlen capability */
1361 	cap_idx.type = modex_xform.xform_type;
1362 	capability = rte_cryptodev_asym_capability_get(dev_id, &cap_idx);
1363 
1364 	if (rte_cryptodev_asym_xform_capability_check_modlen(
1365 			capability, modex_xform.modex.modulus.length)) {
1366 		RTE_LOG(ERR, USER1,
1367 				"Invalid MODULOUS length specified\n");
1368 				return -1;
1369 		}
1370 
1371 	/* generate crypto op data structure */
1372 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1373 	if (!op) {
1374 		RTE_LOG(ERR, USER1,
1375 			"line %u FAILED: %s",
1376 			__LINE__, "Failed to allocate asymmetric crypto "
1377 			"operation struct");
1378 		status = TEST_FAILED;
1379 		goto error_exit;
1380 	}
1381 
1382 	sess = rte_cryptodev_asym_session_create(sess_mpool);
1383 	if (!sess) {
1384 		RTE_LOG(ERR, USER1,
1385 				 "line %u "
1386 				"FAILED: %s", __LINE__,
1387 				"Session creation failed");
1388 		status = TEST_FAILED;
1389 		goto error_exit;
1390 	}
1391 
1392 	if (rte_cryptodev_asym_session_init(dev_id, sess, &modex_xform,
1393 			sess_mpool) < 0) {
1394 		RTE_LOG(ERR, USER1,
1395 				"line %u FAILED: %s",
1396 				__LINE__, "unabled to config sym session");
1397 		status = TEST_FAILED;
1398 		goto error_exit;
1399 	}
1400 
1401 	asym_op = op->asym;
1402 	memcpy(input, base, sizeof(base));
1403 	asym_op->modex.base.data = input;
1404 	asym_op->modex.base.length = sizeof(base);
1405 	asym_op->modex.result.data = result;
1406 	asym_op->modex.result.length = sizeof(result);
1407 	/* attach asymmetric crypto session to crypto operations */
1408 	rte_crypto_op_attach_asym_session(op, sess);
1409 
1410 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
1411 	/* Process crypto operation */
1412 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
1413 		RTE_LOG(ERR, USER1,
1414 				"line %u FAILED: %s",
1415 				__LINE__, "Error sending packet for operation");
1416 		status = TEST_FAILED;
1417 		goto error_exit;
1418 	}
1419 
1420 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
1421 		rte_pause();
1422 
1423 	if (result_op == NULL) {
1424 		RTE_LOG(ERR, USER1,
1425 				"line %u FAILED: %s",
1426 				__LINE__, "Failed to process asym crypto op");
1427 		status = TEST_FAILED;
1428 		goto error_exit;
1429 	}
1430 
1431 	ret = verify_modexp(mod_exp, result_op);
1432 	if (ret) {
1433 		RTE_LOG(ERR, USER1,
1434 			 "operation verification failed\n");
1435 		status = TEST_FAILED;
1436 	}
1437 
1438 error_exit:
1439 	if (sess != NULL) {
1440 		rte_cryptodev_asym_session_clear(dev_id, sess);
1441 		rte_cryptodev_asym_session_free(sess);
1442 	}
1443 
1444 	if (op != NULL)
1445 		rte_crypto_op_free(op);
1446 
1447 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
1448 
1449 	return status;
1450 }
1451 
1452 static int
1453 test_dh_keygenration(void)
1454 {
1455 	int status;
1456 
1457 	debug_hexdump(stdout, "p:", dh_xform.dh.p.data, dh_xform.dh.p.length);
1458 	debug_hexdump(stdout, "g:", dh_xform.dh.g.data, dh_xform.dh.g.length);
1459 	debug_hexdump(stdout, "priv_key:", dh_test_params.priv_key.data,
1460 			dh_test_params.priv_key.length);
1461 
1462 	RTE_LOG(INFO, USER1,
1463 		"Test Public and Private key pair generation\n");
1464 
1465 	status = test_dh_gen_kp(&dh_xform);
1466 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
1467 
1468 	RTE_LOG(INFO, USER1,
1469 		"Test Public Key Generation using pre-defined priv key\n");
1470 
1471 	status = test_dh_gen_pub_key(&dh_xform);
1472 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
1473 
1474 	RTE_LOG(INFO, USER1,
1475 		"Test Private Key Generation only\n");
1476 
1477 	status = test_dh_gen_priv_key(&dh_xform);
1478 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
1479 
1480 	RTE_LOG(INFO, USER1,
1481 		"Test shared secret compute\n");
1482 
1483 	status = test_dh_gen_shared_sec(&dh_xform);
1484 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
1485 
1486 	return status;
1487 }
1488 
1489 static int
1490 test_dsa_sign(void)
1491 {
1492 	struct crypto_testsuite_params *ts_params = &testsuite_params;
1493 	struct rte_mempool *op_mpool = ts_params->op_mpool;
1494 	struct rte_mempool *sess_mpool = ts_params->session_mpool;
1495 	uint8_t dev_id = ts_params->valid_devs[0];
1496 	struct rte_crypto_asym_op *asym_op = NULL;
1497 	struct rte_crypto_op *op = NULL, *result_op = NULL;
1498 	struct rte_cryptodev_asym_session *sess = NULL;
1499 	int status = TEST_SUCCESS;
1500 	uint8_t r[TEST_DH_MOD_LEN];
1501 	uint8_t s[TEST_DH_MOD_LEN];
1502 	uint8_t dgst[] = "35d81554afaad2cf18f3a1770d5fedc4ea5be344";
1503 
1504 	sess = rte_cryptodev_asym_session_create(sess_mpool);
1505 	if (sess == NULL) {
1506 		RTE_LOG(ERR, USER1,
1507 				 "line %u FAILED: %s", __LINE__,
1508 				"Session creation failed");
1509 		status = TEST_FAILED;
1510 		goto error_exit;
1511 	}
1512 	/* set up crypto op data structure */
1513 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1514 	if (!op) {
1515 		RTE_LOG(ERR, USER1,
1516 			"line %u FAILED: %s",
1517 			__LINE__, "Failed to allocate asymmetric crypto "
1518 			"operation struct");
1519 		status = TEST_FAILED;
1520 		goto error_exit;
1521 	}
1522 	asym_op = op->asym;
1523 
1524 	debug_hexdump(stdout, "p: ", dsa_xform.dsa.p.data,
1525 			dsa_xform.dsa.p.length);
1526 	debug_hexdump(stdout, "q: ", dsa_xform.dsa.q.data,
1527 			dsa_xform.dsa.q.length);
1528 	debug_hexdump(stdout, "g: ", dsa_xform.dsa.g.data,
1529 			dsa_xform.dsa.g.length);
1530 	debug_hexdump(stdout, "priv_key: ", dsa_xform.dsa.x.data,
1531 			dsa_xform.dsa.x.length);
1532 
1533 	if (rte_cryptodev_asym_session_init(dev_id, sess, &dsa_xform,
1534 				sess_mpool) < 0) {
1535 		RTE_LOG(ERR, USER1,
1536 				"line %u FAILED: %s",
1537 				__LINE__, "unabled to config sym session");
1538 		status = TEST_FAILED;
1539 		goto error_exit;
1540 	}
1541 
1542 	/* attach asymmetric crypto session to crypto operations */
1543 	rte_crypto_op_attach_asym_session(op, sess);
1544 	asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
1545 	asym_op->dsa.message.data = dgst;
1546 	asym_op->dsa.message.length = sizeof(dgst);
1547 	asym_op->dsa.r.length = sizeof(r);
1548 	asym_op->dsa.r.data = r;
1549 	asym_op->dsa.s.length = sizeof(s);
1550 	asym_op->dsa.s.data = s;
1551 
1552 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
1553 
1554 	/* Process crypto operation */
1555 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
1556 		RTE_LOG(ERR, USER1,
1557 			"line %u FAILED: %s",
1558 			__LINE__, "Error sending packet for operation");
1559 		status = TEST_FAILED;
1560 		goto error_exit;
1561 	}
1562 
1563 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
1564 		rte_pause();
1565 
1566 	if (result_op == NULL) {
1567 		RTE_LOG(ERR, USER1,
1568 			"line %u FAILED: %s",
1569 			__LINE__, "Failed to process asym crypto op");
1570 		status = TEST_FAILED;
1571 		goto error_exit;
1572 	}
1573 
1574 	asym_op = result_op->asym;
1575 
1576 	debug_hexdump(stdout, "r:",
1577 			asym_op->dsa.r.data, asym_op->dsa.r.length);
1578 	debug_hexdump(stdout, "s:",
1579 			asym_op->dsa.s.data, asym_op->dsa.s.length);
1580 
1581 	/* Test PMD DSA sign verification using signer public key */
1582 	asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
1583 
1584 	/* copy signer public key */
1585 	asym_op->dsa.y.data = dsa_test_params.y.data;
1586 	asym_op->dsa.y.length = dsa_test_params.y.length;
1587 
1588 	/* Process crypto operation */
1589 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
1590 		RTE_LOG(ERR, USER1,
1591 			"line %u FAILED: %s",
1592 			__LINE__, "Error sending packet for operation");
1593 		status = TEST_FAILED;
1594 		goto error_exit;
1595 	}
1596 
1597 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
1598 		rte_pause();
1599 
1600 	if (result_op == NULL) {
1601 		RTE_LOG(ERR, USER1,
1602 			"line %u FAILED: %s",
1603 			__LINE__, "Failed to process asym crypto op");
1604 		status = TEST_FAILED;
1605 		goto error_exit;
1606 	}
1607 
1608 	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
1609 		RTE_LOG(ERR, USER1,
1610 				"line %u FAILED: %s",
1611 				__LINE__, "Failed to process asym crypto op");
1612 		status = TEST_FAILED;
1613 	}
1614 error_exit:
1615 	if (sess != NULL) {
1616 		rte_cryptodev_asym_session_clear(dev_id, sess);
1617 		rte_cryptodev_asym_session_free(sess);
1618 	}
1619 	if (op != NULL)
1620 		rte_crypto_op_free(op);
1621 	return status;
1622 }
1623 
1624 static int
1625 test_dsa(void)
1626 {
1627 	int status;
1628 	status = test_dsa_sign();
1629 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
1630 	return status;
1631 }
1632 
1633 
1634 static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
1635 	.suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite",
1636 	.setup = testsuite_setup,
1637 	.teardown = testsuite_teardown,
1638 	.unit_test_cases = {
1639 		TEST_CASE_ST(ut_setup, ut_teardown, test_capability),
1640 		TEST_CASE_ST(ut_setup, ut_teardown, test_dsa),
1641 		TEST_CASE_ST(ut_setup, ut_teardown, test_dh_keygenration),
1642 		TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_enc_dec),
1643 		TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_sign_verify),
1644 		TEST_CASE_ST(ut_setup, ut_teardown, test_mod_inv),
1645 		TEST_CASE_ST(ut_setup, ut_teardown, test_mod_exp),
1646 		TEST_CASE_ST(ut_setup, ut_teardown, test_one_by_one),
1647 		TEST_CASES_END() /**< NULL terminate unit test array */
1648 	}
1649 };
1650 
1651 static struct unit_test_suite cryptodev_qat_asym_testsuite  = {
1652 	.suite_name = "Crypto Device QAT ASYM Unit Test Suite",
1653 	.setup = testsuite_setup,
1654 	.teardown = testsuite_teardown,
1655 	.unit_test_cases = {
1656 		TEST_CASE_ST(ut_setup, ut_teardown, test_one_by_one),
1657 		TEST_CASES_END() /**< NULL terminate unit test array */
1658 	}
1659 };
1660 
1661 static int
1662 test_cryptodev_openssl_asym(void)
1663 {
1664 	gbl_driver_id = rte_cryptodev_driver_id_get(
1665 			RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
1666 
1667 	if (gbl_driver_id == -1) {
1668 		RTE_LOG(ERR, USER1, "OPENSSL PMD must be loaded. Check if "
1669 				"CONFIG_RTE_LIBRTE_PMD_OPENSSL is enabled "
1670 				"in config file to run this testsuite.\n");
1671 		return TEST_FAILED;
1672 	}
1673 
1674 	return unit_test_suite_runner(&cryptodev_openssl_asym_testsuite);
1675 }
1676 
1677 static int
1678 test_cryptodev_qat_asym(void)
1679 {
1680 	gbl_driver_id = rte_cryptodev_driver_id_get(
1681 			RTE_STR(CRYPTODEV_NAME_QAT_ASYM_PMD));
1682 
1683 	if (gbl_driver_id == -1) {
1684 		RTE_LOG(ERR, USER1, "QAT PMD must be loaded. Check if "
1685 				    "CONFIG_RTE_LIBRTE_PMD_QAT_ASYM is enabled "
1686 				    "in config file to run this testsuite.\n");
1687 		return TEST_FAILED;
1688 	}
1689 
1690 	return unit_test_suite_runner(&cryptodev_qat_asym_testsuite);
1691 }
1692 
1693 REGISTER_TEST_COMMAND(cryptodev_openssl_asym_autotest,
1694 					  test_cryptodev_openssl_asym);
1695 
1696 REGISTER_TEST_COMMAND(cryptodev_qat_asym_autotest, test_cryptodev_qat_asym);
1697