1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Cavium Networks
5 #include <rte_bus_vdev.h>
6 #include <rte_common.h>
7 #include <rte_hexdump.h>
9 #include <rte_malloc.h>
10 #include <rte_memcpy.h>
11 #include <rte_pause.h>
13 #include <rte_cryptodev.h>
14 #include <rte_cryptodev_pmd.h>
15 #include <rte_crypto.h>
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"
23 #define TEST_NUM_BUFS 10
24 #define TEST_NUM_SESSIONS 4
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;
36 struct crypto_unittest_params {
37 struct rte_cryptodev_asym_session *sess;
38 struct rte_crypto_op *op;
41 static struct crypto_testsuite_params testsuite_params = { NULL };
44 test_rsa_sign_verify(void)
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};
57 sess = rte_cryptodev_asym_session_create(sess_mpool);
60 RTE_LOG(ERR, USER1, "line %u "
61 "FAILED: %s", __LINE__,
62 "Session creation failed");
67 if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform,
71 __LINE__, "unabled to config sym session");
76 /* set up crypto op data structure */
77 op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
82 "Failed to allocate asymmetric crypto "
89 /* Compute sign on the test vector */
90 asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
92 memcpy(input_buf, &rsaplaintext.data,
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;
99 debug_hexdump(stdout, "message", asym_op->rsa.message.data,
100 asym_op->rsa.message.length);
102 /* attach asymmetric crypto session to crypto operations */
103 rte_crypto_op_attach_asym_session(op, sess);
105 RTE_LOG(DEBUG, USER1, "Process ASYM operation");
107 /* Process crypto operation */
108 if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
110 "line %u FAILED: %s",
111 __LINE__, "Error sending packet for operation");
112 status = TEST_FAILED;
116 while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
119 if (result_op == NULL) {
121 "line %u FAILED: %s",
122 __LINE__, "Failed to process asym crypto op");
123 status = TEST_FAILED;
126 debug_hexdump(stdout, "signed message", asym_op->rsa.sign.data,
127 asym_op->rsa.sign.length);
128 asym_op = result_op->asym;
131 asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
132 asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2;
134 /* Process crypto operation */
135 if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
137 "line %u FAILED: %s",
138 __LINE__, "Error sending packet for operation");
139 status = TEST_FAILED;
143 while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
146 if (result_op == NULL) {
148 "line %u FAILED: %s",
149 __LINE__, "Failed to process asym crypto op");
150 status = TEST_FAILED;
153 status = TEST_SUCCESS;
155 ret = rsa_verify(&rsaplaintext, result_op);
157 status = TEST_FAILED;
162 rte_cryptodev_asym_session_clear(dev_id, sess);
163 rte_cryptodev_asym_session_free(sess);
167 rte_crypto_op_free(op);
169 TEST_ASSERT_EQUAL(status, 0, "Test failed");
175 test_rsa_enc_dec(void)
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};
187 sess = rte_cryptodev_asym_session_create(sess_mpool);
190 RTE_LOG(ERR, USER1, "line %u "
191 "FAILED: %s", __LINE__,
192 "Session creation failed");
193 status = TEST_FAILED;
197 if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform,
200 "line %u FAILED: %s",
201 __LINE__, "unabled to config sym session");
202 status = TEST_FAILED;
206 /* set up crypto op data structure */
207 op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
210 "line %u FAILED: %s",
212 "Failed to allocate asymmetric crypto "
214 status = TEST_FAILED;
219 /*Compute encryption on the test vector */
220 asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT;
222 memcpy(input_buf, rsaplaintext.data,
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;
228 debug_hexdump(stdout, "message", asym_op->rsa.message.data,
229 asym_op->rsa.message.length);
231 /* attach asymmetric crypto session to crypto operations */
232 rte_crypto_op_attach_asym_session(op, sess);
234 RTE_LOG(DEBUG, USER1, "Process ASYM operation");
236 /* Process crypto operation */
237 if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
239 "line %u FAILED: %s",
240 __LINE__, "Error sending packet for operation");
241 status = TEST_FAILED;
245 while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
248 if (result_op == NULL) {
250 "line %u FAILED: %s",
251 __LINE__, "Failed to process asym crypto op");
252 status = TEST_FAILED;
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;
262 /* Process crypto operation */
263 if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
265 "line %u FAILED: %s",
266 __LINE__, "Error sending packet for operation");
267 status = TEST_FAILED;
271 while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
274 if (result_op == NULL) {
276 "line %u FAILED: %s",
277 __LINE__, "Failed to process asym crypto op");
278 status = TEST_FAILED;
281 status = TEST_SUCCESS;
283 ret = rsa_verify(&rsaplaintext, result_op);
285 status = TEST_FAILED;
290 rte_cryptodev_asym_session_clear(dev_id, sess);
291 rte_cryptodev_asym_session_free(sess);
295 rte_crypto_op_free(op);
297 TEST_ASSERT_EQUAL(status, 0, "Test failed");
303 testsuite_setup(void)
305 struct crypto_testsuite_params *ts_params = &testsuite_params;
306 struct rte_cryptodev_info info;
307 uint32_t i = 0, nb_devs, dev_id;
311 memset(ts_params, 0, sizeof(*ts_params));
313 ts_params->op_mpool = rte_crypto_op_pool_create(
314 "CRYPTO_ASYM_OP_POOL",
315 RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
319 if (ts_params->op_mpool == NULL) {
320 RTE_LOG(ERR, USER1, "Can't create ASYM_CRYPTO_OP_POOL\n");
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)));
332 RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD),
335 TEST_ASSERT(ret == 0, "Failed to create "
336 "instance of pmd : %s",
337 RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
341 nb_devs = rte_cryptodev_count();
343 RTE_LOG(ERR, USER1, "No crypto devices found?\n");
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;
354 if (ts_params->valid_dev_count < 1)
357 /* Set up all the qps on the first of the valid devices found */
359 dev_id = ts_params->valid_devs[0];
361 rte_cryptodev_info_get(dev_id, &info);
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. "
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,
376 "Failed to configure cryptodev %u with %u qps",
377 dev_id, ts_params->conf.nb_queue_pairs);
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",
390 /* setup asym session pool */
391 unsigned int session_size =
392 rte_cryptodev_asym_get_private_session_size(dev_id);
394 * Create mempool with TEST_NUM_SESSIONS * 2,
395 * to include the session headers
397 ts_params->session_mpool = rte_mempool_create(
399 TEST_NUM_SESSIONS * 2,
401 0, 0, NULL, NULL, NULL,
405 TEST_ASSERT_NOT_NULL(ts_params->session_mpool,
406 "session mempool allocation failed");
412 testsuite_teardown(void)
414 struct crypto_testsuite_params *ts_params = &testsuite_params;
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));
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;
431 struct crypto_testsuite_params *ts_params = &testsuite_params;
435 /* Reconfigure device to default parameters */
436 ts_params->conf.socket_id = SOCKET_ID_ANY;
438 TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0],
440 "Failed to configure cryptodev %u",
441 ts_params->valid_devs[0]);
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,
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]);
453 rte_cryptodev_stats_reset(ts_params->valid_devs[0]);
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]);
466 struct crypto_testsuite_params *ts_params = &testsuite_params;
467 struct rte_cryptodev_stats stats;
469 rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats);
471 /* Stop the device */
472 rte_cryptodev_stop(ts_params->valid_devs[0]);
475 static inline void print_asym_capa(
476 const struct rte_cryptodev_asymmetric_xform_capability *capa)
480 printf("\nxform type: %s\n===================\n",
481 rte_crypto_asym_xform_strings[capa->xform_type]);
482 printf("operation supported -");
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))
488 rte_crypto_asym_op_strings[i]);
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",
499 capa->modlen.increment);
507 test_capability(void)
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;
514 struct rte_cryptodev_asym_capability_idx idx;
515 const struct rte_cryptodev_asymmetric_xform_capability *capa;
517 rte_cryptodev_info_get(dev_id, &dev_info);
518 if (!(dev_info.feature_flags &
519 RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) {
521 "Device doesn't support asymmetric. Test Skipped\n");
525 /* print xform capability */
527 dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
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;
534 capa = rte_cryptodev_asym_capability_get(dev_id,
536 rte_cryptodev_asym_capability_idx *) &idx);
537 print_asym_capa(capa);
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};
559 if (rte_cryptodev_asym_get_xform_enum(
560 &modinv_xform.xform_type, "modinv") < 0) {
562 "Invalid ASYNC algorithm specified\n");
566 cap_idx.type = modinv_xform.xform_type;
567 capability = rte_cryptodev_asym_capability_get(dev_id,
570 if (rte_cryptodev_asym_xform_capability_check_modlen(
572 modinv_xform.modinv.modulus.length)) {
574 "Invalid MODULOUS length specified\n");
578 sess = rte_cryptodev_asym_session_create(sess_mpool);
580 RTE_LOG(ERR, USER1, "line %u "
581 "FAILED: %s", __LINE__,
582 "Session creation failed");
583 status = TEST_FAILED;
587 if (rte_cryptodev_asym_session_init(dev_id, sess, &modinv_xform,
590 "line %u FAILED: %s",
591 __LINE__, "unabled to config sym session");
592 status = TEST_FAILED;
596 /* generate crypto op data structure */
597 op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
600 "line %u FAILED: %s",
601 __LINE__, "Failed to allocate asymmetric crypto "
603 status = TEST_FAILED;
608 memcpy(input, base, sizeof(base));
609 asym_op->modinv.base.data = input;
610 asym_op->modinv.base.length = sizeof(base);
612 /* attach asymmetric crypto session to crypto operations */
613 rte_crypto_op_attach_asym_session(op, sess);
615 RTE_LOG(DEBUG, USER1, "Process ASYM operation");
617 /* Process crypto operation */
618 if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
620 "line %u FAILED: %s",
621 __LINE__, "Error sending packet for operation");
622 status = TEST_FAILED;
626 while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
629 if (result_op == NULL) {
631 "line %u FAILED: %s",
632 __LINE__, "Failed to process asym crypto op");
633 status = TEST_FAILED;
637 ret = verify_modinv(mod_inv, result_op);
640 "operation verification failed\n");
641 status = TEST_FAILED;
646 rte_cryptodev_asym_session_clear(dev_id, sess);
647 rte_cryptodev_asym_session_free(sess);
651 rte_crypto_op_free(op);
653 TEST_ASSERT_EQUAL(status, 0, "Test failed");
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};
674 if (rte_cryptodev_asym_get_xform_enum(&modex_xform.xform_type,
678 "Invalid ASYNC algorithm specified\n");
682 /* check for modlen capability */
683 cap_idx.type = modex_xform.xform_type;
684 capability = rte_cryptodev_asym_capability_get(dev_id, &cap_idx);
686 if (rte_cryptodev_asym_xform_capability_check_modlen(
687 capability, modex_xform.modex.modulus.length)) {
689 "Invalid MODULOUS length specified\n");
693 /* generate crypto op data structure */
694 op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
697 "line %u FAILED: %s",
698 __LINE__, "Failed to allocate asymmetric crypto "
700 status = TEST_FAILED;
704 sess = rte_cryptodev_asym_session_create(sess_mpool);
708 "FAILED: %s", __LINE__,
709 "Session creation failed");
710 status = TEST_FAILED;
714 if (rte_cryptodev_asym_session_init(dev_id, sess, &modex_xform,
717 "line %u FAILED: %s",
718 __LINE__, "unabled to config sym session");
719 status = TEST_FAILED;
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);
730 RTE_LOG(DEBUG, USER1, "Process ASYM operation");
731 /* Process crypto operation */
732 if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
734 "line %u FAILED: %s",
735 __LINE__, "Error sending packet for operation");
736 status = TEST_FAILED;
740 while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
743 if (result_op == NULL) {
745 "line %u FAILED: %s",
746 __LINE__, "Failed to process asym crypto op");
747 status = TEST_FAILED;
751 ret = verify_modexp(mod_exp, result_op);
754 "operation verification failed\n");
755 status = TEST_FAILED;
760 rte_cryptodev_asym_session_clear(dev_id, sess);
761 rte_cryptodev_asym_session_free(sess);
765 rte_crypto_op_free(op);
767 TEST_ASSERT_EQUAL(status, 0, "Test failed");
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,
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 */
787 test_cryptodev_openssl_asym(void)
789 gbl_driver_id = rte_cryptodev_driver_id_get(
790 RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
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");
799 return unit_test_suite_runner(&cryptodev_openssl_asym_testsuite);
802 REGISTER_TEST_COMMAND(cryptodev_openssl_asym_autotest,
803 test_cryptodev_openssl_asym);