test/crypto: check asymmetric crypto
[dpdk.git] / app / test / test_cryptodev_asym.c
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);