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