net: add rte prefix to ether structures
[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         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);