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