68ec6b0a47964e21bff227545942e096899294e9
[dpdk.git] / test / test / test_cryptodev_asym.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Cavium Networks
3  */
4
5 #include <rte_bus_vdev.h>
6 #include <rte_common.h>
7 #include <rte_hexdump.h>
8 #include <rte_mbuf.h>
9 #include <rte_malloc.h>
10 #include <rte_memcpy.h>
11 #include <rte_pause.h>
12
13 #include <rte_cryptodev.h>
14 #include <rte_cryptodev_pmd.h>
15 #include <rte_crypto.h>
16
17 #include "test_cryptodev.h"
18 #include "test_cryptodev_mod_test_vectors.h"
19 #include "test_cryptodev_rsa_test_vectors.h"
20 #include "test_cryptodev_asym_util.h"
21 #include "test.h"
22
23 #define TEST_NUM_BUFS 10
24 #define TEST_NUM_SESSIONS 4
25
26 static int gbl_driver_id;
27 struct crypto_testsuite_params {
28         struct rte_mempool *op_mpool;
29         struct rte_mempool *session_mpool;
30         struct rte_cryptodev_config conf;
31         struct rte_cryptodev_qp_conf qp_conf;
32         uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS];
33         uint8_t valid_dev_count;
34 };
35
36 struct crypto_unittest_params {
37         struct rte_cryptodev_asym_session *sess;
38         struct rte_crypto_op *op;
39 };
40
41 static struct crypto_testsuite_params testsuite_params = { NULL };
42
43 static int
44 test_rsa_sign_verify(void)
45 {
46         struct crypto_testsuite_params *ts_params = &testsuite_params;
47         struct rte_mempool *op_mpool = ts_params->op_mpool;
48         struct rte_mempool *sess_mpool = ts_params->session_mpool;
49         uint8_t dev_id = ts_params->valid_devs[0];
50         struct rte_crypto_asym_op *asym_op = NULL;
51         struct rte_crypto_op *op = NULL, *result_op = NULL;
52         struct rte_cryptodev_asym_session *sess = NULL;
53         int status = TEST_SUCCESS;
54         uint8_t output_buf[TEST_DATA_SIZE] = {0};
55         uint8_t input_buf[TEST_DATA_SIZE] = {0};
56
57         sess = rte_cryptodev_asym_session_create(sess_mpool);
58
59         if (!sess) {
60                 RTE_LOG(ERR, USER1, "line %u "
61                                 "FAILED: %s", __LINE__,
62                                 "Session creation failed");
63                 status = TEST_FAILED;
64                 goto error_exit;
65         }
66
67         if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform,
68                                 sess_mpool) < 0) {
69                 RTE_LOG(ERR, USER1,
70                                 "line %u FAILED: %s",
71                                 __LINE__, "unabled to config sym session");
72                 status = TEST_FAILED;
73                 goto error_exit;
74         }
75
76         /* set up crypto op data structure */
77         op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
78         if (!op) {
79                 RTE_LOG(ERR, USER1,
80                                 "line %u FAILED: %s",
81                                 __LINE__,
82                                 "Failed to allocate asymmetric crypto "
83                                 "operation struct");
84                 status = TEST_FAILED;
85                 goto error_exit;
86         }
87
88         asym_op = op->asym;
89         /* Compute sign on the test vector */
90         asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
91
92         memcpy(input_buf, &rsaplaintext.data,
93                         rsaplaintext.len);
94         asym_op->rsa.message.data = input_buf;
95         asym_op->rsa.message.length = rsaplaintext.len;
96         asym_op->rsa.sign.data = output_buf;
97         asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1;
98
99         debug_hexdump(stdout, "message", asym_op->rsa.message.data,
100                         asym_op->rsa.message.length);
101
102         /* attach asymmetric crypto session to crypto operations */
103         rte_crypto_op_attach_asym_session(op, sess);
104
105         RTE_LOG(DEBUG, USER1, "Process ASYM operation");
106
107         /* Process crypto operation */
108         if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
109                 RTE_LOG(ERR, USER1,
110                                 "line %u FAILED: %s",
111                                 __LINE__, "Error sending packet for operation");
112                 status = TEST_FAILED;
113                 goto error_exit;
114         }
115
116         while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
117                 rte_pause();
118
119         if (result_op == NULL) {
120                 RTE_LOG(ERR, USER1,
121                                 "line %u FAILED: %s",
122                                 __LINE__, "Failed to process asym crypto op");
123                 status = TEST_FAILED;
124                 goto error_exit;
125         }
126         debug_hexdump(stdout, "signed message", asym_op->rsa.sign.data,
127                         asym_op->rsa.sign.length);
128         asym_op = result_op->asym;
129
130         /* Verify sign */
131         asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
132         asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2;
133
134         /* Process crypto operation */
135         if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
136                 RTE_LOG(ERR, USER1,
137                                 "line %u FAILED: %s",
138                                 __LINE__, "Error sending packet for operation");
139                 status = TEST_FAILED;
140                 goto error_exit;
141         }
142
143         while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
144                 rte_pause();
145
146         if (result_op == NULL) {
147                 RTE_LOG(ERR, USER1,
148                                 "line %u FAILED: %s",
149                                 __LINE__, "Failed to process asym crypto op");
150                 status = TEST_FAILED;
151                 goto error_exit;
152         }
153         status = TEST_SUCCESS;
154         int ret = 0;
155         ret = rsa_verify(&rsaplaintext, result_op);
156         if (ret)
157                 status = TEST_FAILED;
158
159 error_exit:
160
161         if (sess) {
162                 rte_cryptodev_asym_session_clear(dev_id, sess);
163                 rte_cryptodev_asym_session_free(sess);
164         }
165
166         if (op)
167                 rte_crypto_op_free(op);
168
169         TEST_ASSERT_EQUAL(status, 0, "Test failed");
170
171         return status;
172 }
173
174 static int
175 test_rsa_enc_dec(void)
176 {
177         struct crypto_testsuite_params *ts_params = &testsuite_params;
178         struct rte_mempool *op_mpool = ts_params->op_mpool;
179         struct rte_mempool *sess_mpool = ts_params->session_mpool;
180         uint8_t dev_id = ts_params->valid_devs[0];
181         struct rte_crypto_asym_op *asym_op = NULL;
182         struct rte_crypto_op *op = NULL, *result_op = NULL;
183         struct rte_cryptodev_asym_session *sess = NULL;
184         int status = TEST_SUCCESS;
185         uint8_t input_buf[TEST_DATA_SIZE] = {0};
186
187         sess = rte_cryptodev_asym_session_create(sess_mpool);
188
189         if (!sess) {
190                 RTE_LOG(ERR, USER1, "line %u "
191                                 "FAILED: %s", __LINE__,
192                                 "Session creation failed");
193                 status = TEST_FAILED;
194                 goto error_exit;
195         }
196
197         if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform,
198                                 sess_mpool) < 0) {
199                 RTE_LOG(ERR, USER1,
200                                 "line %u FAILED: %s",
201                                 __LINE__, "unabled to config sym session");
202                 status = TEST_FAILED;
203                 goto error_exit;
204         }
205
206         /* set up crypto op data structure */
207         op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
208         if (!op) {
209                 RTE_LOG(ERR, USER1,
210                                 "line %u FAILED: %s",
211                                 __LINE__,
212                                 "Failed to allocate asymmetric crypto "
213                                 "operation struct");
214                 status = TEST_FAILED;
215                 goto error_exit;
216         }
217
218         asym_op = op->asym;
219         /*Compute encryption on the test vector */
220         asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT;
221
222         memcpy(input_buf, rsaplaintext.data,
223                         rsaplaintext.len);
224         asym_op->rsa.message.data = input_buf;
225         asym_op->rsa.message.length = rsaplaintext.len;
226         asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2;
227
228         debug_hexdump(stdout, "message", asym_op->rsa.message.data,
229                         asym_op->rsa.message.length);
230
231         /* attach asymmetric crypto session to crypto operations */
232         rte_crypto_op_attach_asym_session(op, sess);
233
234         RTE_LOG(DEBUG, USER1, "Process ASYM operation");
235
236         /* Process crypto operation */
237         if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
238                 RTE_LOG(ERR, USER1,
239                                 "line %u FAILED: %s",
240                                 __LINE__, "Error sending packet for operation");
241                 status = TEST_FAILED;
242                 goto error_exit;
243         }
244
245         while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
246                 rte_pause();
247
248         if (result_op == NULL) {
249                 RTE_LOG(ERR, USER1,
250                                 "line %u FAILED: %s",
251                                 __LINE__, "Failed to process asym crypto op");
252                 status = TEST_FAILED;
253                 goto error_exit;
254         }
255         debug_hexdump(stdout, "encrypted message", asym_op->rsa.message.data,
256                         asym_op->rsa.message.length);
257         /* Use the resulted output as decryption Input vector*/
258         asym_op = result_op->asym;
259         asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_DECRYPT;
260         asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1;
261
262         /* Process crypto operation */
263         if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
264                 RTE_LOG(ERR, USER1,
265                                 "line %u FAILED: %s",
266                                 __LINE__, "Error sending packet for operation");
267                 status = TEST_FAILED;
268                 goto error_exit;
269         }
270
271         while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
272                 rte_pause();
273
274         if (result_op == NULL) {
275                 RTE_LOG(ERR, USER1,
276                                 "line %u FAILED: %s",
277                                 __LINE__, "Failed to process asym crypto op");
278                 status = TEST_FAILED;
279                 goto error_exit;
280         }
281         status = TEST_SUCCESS;
282         int ret = 0;
283         ret = rsa_verify(&rsaplaintext, result_op);
284         if (ret)
285                 status = TEST_FAILED;
286
287 error_exit:
288
289         if (sess) {
290                 rte_cryptodev_asym_session_clear(dev_id, sess);
291                 rte_cryptodev_asym_session_free(sess);
292         }
293
294         if (op)
295                 rte_crypto_op_free(op);
296
297         TEST_ASSERT_EQUAL(status, 0, "Test failed");
298
299         return status;
300 }
301
302 static int
303 testsuite_setup(void)
304 {
305         struct crypto_testsuite_params *ts_params = &testsuite_params;
306         struct rte_cryptodev_info info;
307         uint32_t i = 0, nb_devs, dev_id;
308         int ret;
309         uint16_t qp_id;
310
311         memset(ts_params, 0, sizeof(*ts_params));
312
313         ts_params->op_mpool = rte_crypto_op_pool_create(
314                         "CRYPTO_ASYM_OP_POOL",
315                         RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
316                         TEST_NUM_BUFS, 0,
317                         0,
318                         rte_socket_id());
319         if (ts_params->op_mpool == NULL) {
320                 RTE_LOG(ERR, USER1, "Can't create ASYM_CRYPTO_OP_POOL\n");
321                 return TEST_FAILED;
322         }
323
324         /* Create an OPENSSL device if required */
325         if (gbl_driver_id == rte_cryptodev_driver_id_get(
326                         RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))) {
327                 nb_devs = rte_cryptodev_device_count_by_driver(
328                                 rte_cryptodev_driver_id_get(
329                                 RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)));
330                 if (nb_devs < 1) {
331                         ret = rte_vdev_init(
332                                 RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD),
333                                 NULL);
334
335                         TEST_ASSERT(ret == 0, "Failed to create "
336                                 "instance of pmd : %s",
337                                 RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
338                 }
339         }
340
341         nb_devs = rte_cryptodev_count();
342         if (nb_devs < 1) {
343                 RTE_LOG(ERR, USER1, "No crypto devices found?\n");
344                 return TEST_FAILED;
345         }
346
347         /* Create list of valid crypto devs */
348         for (i = 0; i < nb_devs; i++) {
349                 rte_cryptodev_info_get(i, &info);
350                 if (info.driver_id == gbl_driver_id)
351                         ts_params->valid_devs[ts_params->valid_dev_count++] = i;
352         }
353
354         if (ts_params->valid_dev_count < 1)
355                 return TEST_FAILED;
356
357         /* Set up all the qps on the first of the valid devices found */
358
359         dev_id = ts_params->valid_devs[0];
360
361         rte_cryptodev_info_get(dev_id, &info);
362
363         /* check if device support asymmetric, skip if not */
364         if (!(info.feature_flags &
365                                 RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) {
366                 RTE_LOG(ERR, USER1, "Device doesn't support asymmetric. "
367                                 "Test Skipped.\n");
368                 return TEST_FAILED;
369         }
370
371         /* configure device with num qp */
372         ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs;
373         ts_params->conf.socket_id = SOCKET_ID_ANY;
374         TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id,
375                         &ts_params->conf),
376                         "Failed to configure cryptodev %u with %u qps",
377                         dev_id, ts_params->conf.nb_queue_pairs);
378
379         /* configure qp */
380         ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
381         for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
382                 TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
383                         dev_id, qp_id, &ts_params->qp_conf,
384                         rte_cryptodev_socket_id(dev_id),
385                         ts_params->session_mpool),
386                         "Failed to setup queue pair %u on cryptodev %u ASYM",
387                         qp_id, dev_id);
388         }
389
390         /* setup asym session pool */
391         unsigned int session_size =
392                 rte_cryptodev_asym_get_private_session_size(dev_id);
393         /*
394          * Create mempool with TEST_NUM_SESSIONS * 2,
395          * to include the session headers
396          */
397         ts_params->session_mpool = rte_mempool_create(
398                                 "test_asym_sess_mp",
399                                 TEST_NUM_SESSIONS * 2,
400                                 session_size,
401                                 0, 0, NULL, NULL, NULL,
402                                 NULL, SOCKET_ID_ANY,
403                                 0);
404
405         TEST_ASSERT_NOT_NULL(ts_params->session_mpool,
406                         "session mempool allocation failed");
407
408         return TEST_SUCCESS;
409 }
410
411 static void
412 testsuite_teardown(void)
413 {
414         struct crypto_testsuite_params *ts_params = &testsuite_params;
415
416         if (ts_params->op_mpool != NULL) {
417                 RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n",
418                 rte_mempool_avail_count(ts_params->op_mpool));
419         }
420
421         /* Free session mempools */
422         if (ts_params->session_mpool != NULL) {
423                 rte_mempool_free(ts_params->session_mpool);
424                 ts_params->session_mpool = NULL;
425         }
426 }
427
428 static int
429 ut_setup(void)
430 {
431         struct crypto_testsuite_params *ts_params = &testsuite_params;
432
433         uint16_t qp_id;
434
435         /* Reconfigure device to default parameters */
436         ts_params->conf.socket_id = SOCKET_ID_ANY;
437
438         TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0],
439                         &ts_params->conf),
440                         "Failed to configure cryptodev %u",
441                         ts_params->valid_devs[0]);
442
443         for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs ; qp_id++) {
444                 TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
445                         ts_params->valid_devs[0], qp_id,
446                         &ts_params->qp_conf,
447                         rte_cryptodev_socket_id(ts_params->valid_devs[0]),
448                         ts_params->session_mpool),
449                         "Failed to setup queue pair %u on cryptodev %u",
450                         qp_id, ts_params->valid_devs[0]);
451         }
452
453         rte_cryptodev_stats_reset(ts_params->valid_devs[0]);
454
455         /* Start the device */
456         TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_devs[0]),
457                                                 "Failed to start cryptodev %u",
458                                                 ts_params->valid_devs[0]);
459
460         return TEST_SUCCESS;
461 }
462
463 static void
464 ut_teardown(void)
465 {
466         struct crypto_testsuite_params *ts_params = &testsuite_params;
467         struct rte_cryptodev_stats stats;
468
469         rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats);
470
471         /* Stop the device */
472         rte_cryptodev_stop(ts_params->valid_devs[0]);
473 }
474
475 static inline void print_asym_capa(
476                 const struct rte_cryptodev_asymmetric_xform_capability *capa)
477 {
478         int i = 0;
479
480         printf("\nxform type: %s\n===================\n",
481                         rte_crypto_asym_xform_strings[capa->xform_type]);
482         printf("operation supported -");
483
484         for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) {
485                 /* check supported operations */
486                 if (rte_cryptodev_asym_xform_capability_check_optype(capa, i))
487                         printf(" %s",
488                                         rte_crypto_asym_op_strings[i]);
489                 }
490                 switch (capa->xform_type) {
491                 case RTE_CRYPTO_ASYM_XFORM_RSA:
492                 case RTE_CRYPTO_ASYM_XFORM_MODINV:
493                 case RTE_CRYPTO_ASYM_XFORM_MODEX:
494                 case RTE_CRYPTO_ASYM_XFORM_DH:
495                 case RTE_CRYPTO_ASYM_XFORM_DSA:
496                         printf(" modlen: min %d max %d increment %d\n",
497                                         capa->modlen.min,
498                                         capa->modlen.max,
499                                         capa->modlen.increment);
500                 break;
501                 default:
502                         break;
503                 }
504 }
505
506 static int
507 test_capability(void)
508 {
509         struct crypto_testsuite_params *ts_params = &testsuite_params;
510         uint8_t dev_id = ts_params->valid_devs[0];
511         struct rte_cryptodev_info dev_info;
512         const struct rte_cryptodev_capabilities *dev_capa;
513         int i = 0;
514         struct rte_cryptodev_asym_capability_idx idx;
515         const struct rte_cryptodev_asymmetric_xform_capability *capa;
516
517         rte_cryptodev_info_get(dev_id, &dev_info);
518         if (!(dev_info.feature_flags &
519                                 RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) {
520                 RTE_LOG(INFO, USER1,
521                                 "Device doesn't support asymmetric. Test Skipped\n");
522                 return TEST_SUCCESS;
523         }
524
525         /* print xform capability */
526         for (i = 0;
527                 dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
528                 i++) {
529                 dev_capa = &(dev_info.capabilities[i]);
530                 if (dev_info.capabilities[i].op ==
531                                 RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
532                         idx.type = dev_capa->asym.xform_capa.xform_type;
533
534                         capa = rte_cryptodev_asym_capability_get(dev_id,
535                                 (const struct
536                                 rte_cryptodev_asym_capability_idx *) &idx);
537                         print_asym_capa(capa);
538                         }
539         }
540         return TEST_SUCCESS;
541 }
542
543 static int
544 test_mod_inv(void)
545 {
546         struct crypto_testsuite_params *ts_params = &testsuite_params;
547         struct rte_mempool *op_mpool = ts_params->op_mpool;
548         struct rte_mempool *sess_mpool = ts_params->session_mpool;
549         uint8_t dev_id = ts_params->valid_devs[0];
550         struct rte_crypto_asym_op *asym_op = NULL;
551         struct rte_crypto_op *op = NULL, *result_op = NULL;
552         struct rte_cryptodev_asym_session *sess = NULL;
553         int status = TEST_SUCCESS;
554         struct rte_cryptodev_asym_capability_idx cap_idx;
555         const struct rte_cryptodev_asymmetric_xform_capability *capability;
556         uint8_t input[TEST_DATA_SIZE] = {0};
557         int ret = 0;
558
559         if (rte_cryptodev_asym_get_xform_enum(
560                 &modinv_xform.xform_type, "modinv") < 0) {
561                 RTE_LOG(ERR, USER1,
562                                  "Invalid ASYNC algorithm specified\n");
563                 return -1;
564         }
565
566         cap_idx.type = modinv_xform.xform_type;
567         capability = rte_cryptodev_asym_capability_get(dev_id,
568                                         &cap_idx);
569
570         if (rte_cryptodev_asym_xform_capability_check_modlen(
571                 capability,
572                 modinv_xform.modinv.modulus.length)) {
573                 RTE_LOG(ERR, USER1,
574                                  "Invalid MODULOUS length specified\n");
575                                 return -1;
576                 }
577
578         sess = rte_cryptodev_asym_session_create(sess_mpool);
579         if (!sess) {
580                 RTE_LOG(ERR, USER1, "line %u "
581                                 "FAILED: %s", __LINE__,
582                                 "Session creation failed");
583                 status = TEST_FAILED;
584                 goto error_exit;
585         }
586
587         if (rte_cryptodev_asym_session_init(dev_id, sess, &modinv_xform,
588                         sess_mpool) < 0) {
589                 RTE_LOG(ERR, USER1,
590                                 "line %u FAILED: %s",
591                                 __LINE__, "unabled to config sym session");
592                 status = TEST_FAILED;
593                 goto error_exit;
594         }
595
596         /* generate crypto op data structure */
597         op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
598         if (!op) {
599                 RTE_LOG(ERR, USER1,
600                         "line %u FAILED: %s",
601                         __LINE__, "Failed to allocate asymmetric crypto "
602                         "operation struct");
603                 status = TEST_FAILED;
604                 goto error_exit;
605         }
606
607         asym_op = op->asym;
608         memcpy(input, base, sizeof(base));
609         asym_op->modinv.base.data = input;
610         asym_op->modinv.base.length = sizeof(base);
611
612         /* attach asymmetric crypto session to crypto operations */
613         rte_crypto_op_attach_asym_session(op, sess);
614
615         RTE_LOG(DEBUG, USER1, "Process ASYM operation");
616
617         /* Process crypto operation */
618         if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
619                 RTE_LOG(ERR, USER1,
620                         "line %u FAILED: %s",
621                         __LINE__, "Error sending packet for operation");
622                 status = TEST_FAILED;
623                 goto error_exit;
624         }
625
626         while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
627                 rte_pause();
628
629         if (result_op == NULL) {
630                 RTE_LOG(ERR, USER1,
631                                 "line %u FAILED: %s",
632                                 __LINE__, "Failed to process asym crypto op");
633                 status = TEST_FAILED;
634                 goto error_exit;
635         }
636
637         ret = verify_modinv(mod_inv, result_op);
638         if (ret) {
639                 RTE_LOG(ERR, USER1,
640                          "operation verification failed\n");
641                 status = TEST_FAILED;
642         }
643
644 error_exit:
645         if (sess) {
646                 rte_cryptodev_asym_session_clear(dev_id, sess);
647                 rte_cryptodev_asym_session_free(sess);
648         }
649
650         if (op)
651                 rte_crypto_op_free(op);
652
653         TEST_ASSERT_EQUAL(status, 0, "Test failed");
654
655         return status;
656 }
657
658 static int
659 test_mod_exp(void)
660 {
661         struct crypto_testsuite_params *ts_params = &testsuite_params;
662         struct rte_mempool *op_mpool = ts_params->op_mpool;
663         struct rte_mempool *sess_mpool = ts_params->session_mpool;
664         uint8_t dev_id = ts_params->valid_devs[0];
665         struct rte_crypto_asym_op *asym_op = NULL;
666         struct rte_crypto_op *op = NULL, *result_op = NULL;
667         struct rte_cryptodev_asym_session *sess = NULL;
668         int status = TEST_SUCCESS;
669         struct rte_cryptodev_asym_capability_idx cap_idx;
670         const struct rte_cryptodev_asymmetric_xform_capability *capability;
671         uint8_t input[TEST_DATA_SIZE] = {0};
672         int ret = 0;
673
674         if (rte_cryptodev_asym_get_xform_enum(&modex_xform.xform_type,
675                 "modexp")
676                 < 0) {
677                 RTE_LOG(ERR, USER1,
678                                 "Invalid ASYNC algorithm specified\n");
679                 return -1;
680         }
681
682         /* check for modlen capability */
683         cap_idx.type = modex_xform.xform_type;
684         capability = rte_cryptodev_asym_capability_get(dev_id, &cap_idx);
685
686         if (rte_cryptodev_asym_xform_capability_check_modlen(
687                         capability, modex_xform.modex.modulus.length)) {
688                 RTE_LOG(ERR, USER1,
689                                 "Invalid MODULOUS length specified\n");
690                                 return -1;
691                 }
692
693         /* generate crypto op data structure */
694         op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
695         if (!op) {
696                 RTE_LOG(ERR, USER1,
697                         "line %u FAILED: %s",
698                         __LINE__, "Failed to allocate asymmetric crypto "
699                         "operation struct");
700                 status = TEST_FAILED;
701                 goto error_exit;
702         }
703
704         sess = rte_cryptodev_asym_session_create(sess_mpool);
705         if (!sess) {
706                 RTE_LOG(ERR, USER1,
707                                  "line %u "
708                                 "FAILED: %s", __LINE__,
709                                 "Session creation failed");
710                 status = TEST_FAILED;
711                 goto error_exit;
712         }
713
714         if (rte_cryptodev_asym_session_init(dev_id, sess, &modex_xform,
715                         sess_mpool) < 0) {
716                 RTE_LOG(ERR, USER1,
717                                 "line %u FAILED: %s",
718                                 __LINE__, "unabled to config sym session");
719                 status = TEST_FAILED;
720                 goto error_exit;
721         }
722
723         asym_op = op->asym;
724         memcpy(input, base, sizeof(base));
725         asym_op->modex.base.data = input;
726         asym_op->modex.base.length = sizeof(base);
727         /* attach asymmetric crypto session to crypto operations */
728         rte_crypto_op_attach_asym_session(op, sess);
729
730         RTE_LOG(DEBUG, USER1, "Process ASYM operation");
731         /* Process crypto operation */
732         if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
733                 RTE_LOG(ERR, USER1,
734                                 "line %u FAILED: %s",
735                                 __LINE__, "Error sending packet for operation");
736                 status = TEST_FAILED;
737                 goto error_exit;
738         }
739
740         while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
741                 rte_pause();
742
743         if (result_op == NULL) {
744                 RTE_LOG(ERR, USER1,
745                                 "line %u FAILED: %s",
746                                 __LINE__, "Failed to process asym crypto op");
747                 status = TEST_FAILED;
748                 goto error_exit;
749         }
750
751         ret = verify_modexp(mod_exp, result_op);
752         if (ret) {
753                 RTE_LOG(ERR, USER1,
754                          "operation verification failed\n");
755                 status = TEST_FAILED;
756         }
757
758 error_exit:
759         if (sess != NULL) {
760                 rte_cryptodev_asym_session_clear(dev_id, sess);
761                 rte_cryptodev_asym_session_free(sess);
762         }
763
764         if (op != NULL)
765                 rte_crypto_op_free(op);
766
767         TEST_ASSERT_EQUAL(status, 0, "Test failed");
768
769         return status;
770 }
771
772 static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
773         .suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite",
774         .setup = testsuite_setup,
775         .teardown = testsuite_teardown,
776         .unit_test_cases = {
777                 TEST_CASE_ST(ut_setup, ut_teardown, test_capability),
778                 TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_enc_dec),
779                 TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_sign_verify),
780                 TEST_CASE_ST(ut_setup, ut_teardown, test_mod_inv),
781                 TEST_CASE_ST(ut_setup, ut_teardown, test_mod_exp),
782                 TEST_CASES_END() /**< NULL terminate unit test array */
783         }
784 };
785
786 static int
787 test_cryptodev_openssl_asym(void)
788 {
789         gbl_driver_id = rte_cryptodev_driver_id_get(
790                         RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
791
792         if (gbl_driver_id == -1) {
793                 RTE_LOG(ERR, USER1, "OPENSSL PMD must be loaded. Check if "
794                                 "CONFIG_RTE_LIBRTE_PMD_OPENSSL is enabled "
795                                 "in config file to run this testsuite.\n");
796                 return TEST_FAILED;
797         }
798
799         return unit_test_suite_runner(&cryptodev_openssl_asym_testsuite);
800 }
801
802 REGISTER_TEST_COMMAND(cryptodev_openssl_asym_autotest,
803                                           test_cryptodev_openssl_asym);