1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Intel Corporation 3 */ 4 5 #include <sys/stat.h> 6 #include <getopt.h> 7 #include <dirent.h> 8 #include <stdlib.h> 9 10 #include <rte_cryptodev.h> 11 #include <rte_malloc.h> 12 #include <rte_mempool.h> 13 #include <rte_mbuf.h> 14 #include <rte_string_fns.h> 15 #include <rte_random.h> 16 17 #include "fips_validation.h" 18 #include "fips_dev_self_test.h" 19 20 enum { 21 #define OPT_REQ_FILE_PATH "req-file" 22 OPT_REQ_FILE_PATH_NUM = 256, 23 #define OPT_RSP_FILE_PATH "rsp-file" 24 OPT_RSP_FILE_PATH_NUM, 25 #define OPT_MBUF_DATAROOM "mbuf-dataroom" 26 OPT_MBUF_DATAROOM_NUM, 27 #define OPT_FOLDER "path-is-folder" 28 OPT_FOLDER_NUM, 29 #define OPT_CRYPTODEV "cryptodev" 30 OPT_CRYPTODEV_NUM, 31 #define OPT_CRYPTODEV_ID "cryptodev-id" 32 OPT_CRYPTODEV_ID_NUM, 33 #define OPT_CRYPTODEV_ST "self-test" 34 OPT_CRYPTODEV_ST_NUM, 35 #define OPT_CRYPTODEV_BK_ID "broken-test-id" 36 OPT_CRYPTODEV_BK_ID_NUM, 37 #define OPT_CRYPTODEV_BK_DIR_KEY "broken-test-dir" 38 OPT_CRYPTODEV_BK_DIR_KEY_NUM, 39 #define OPT_USE_JSON "use-json" 40 OPT_USE_JSON_NUM, 41 #define OPT_CRYPTODEV_ASYM "asymmetric" 42 OPT_CRYPTODEV_ASYM_NUM, 43 }; 44 45 struct fips_test_vector vec; 46 struct fips_test_interim_info info; 47 48 #ifdef USE_JANSSON 49 struct fips_test_json_info json_info; 50 #endif /* USE_JANSSON */ 51 52 struct cryptodev_fips_validate_env { 53 const char *req_path; 54 const char *rsp_path; 55 uint32_t is_path_folder; 56 uint8_t dev_id; 57 struct rte_mempool *mpool; 58 struct fips_sym_env { 59 struct rte_mempool *sess_mpool; 60 struct rte_mempool *op_pool; 61 struct rte_cryptodev_sym_session *sess; 62 struct rte_crypto_op *op; 63 } sym; 64 struct fips_asym_env { 65 struct rte_mempool *sess_mpool; 66 struct rte_mempool *op_pool; 67 struct rte_cryptodev_asym_session *sess; 68 struct rte_crypto_op *op; 69 } asym; 70 struct rte_crypto_op *op; 71 uint8_t dev_support_sgl; 72 uint16_t mbuf_data_room; 73 struct rte_mbuf *mbuf; 74 uint8_t *digest; 75 uint16_t digest_len; 76 bool is_asym_test; 77 uint16_t self_test; 78 struct fips_dev_broken_test_config *broken_test_config; 79 } env; 80 81 static int 82 cryptodev_fips_validate_app_sym_init(void) 83 { 84 uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size( 85 env.dev_id); 86 struct rte_cryptodev_info dev_info; 87 struct fips_sym_env *sym = &env.sym; 88 int ret; 89 90 rte_cryptodev_info_get(env.dev_id, &dev_info); 91 if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL) 92 env.dev_support_sgl = 1; 93 else 94 env.dev_support_sgl = 0; 95 96 ret = -ENOMEM; 97 sym->sess_mpool = rte_cryptodev_sym_session_pool_create( 98 "FIPS_SYM_SESS_MEMPOOL", 16, sess_sz, 0, 0, rte_socket_id()); 99 if (!sym->sess_mpool) 100 goto error_exit; 101 102 sym->op_pool = rte_crypto_op_pool_create( 103 "FIPS_OP_SYM_POOL", 104 RTE_CRYPTO_OP_TYPE_SYMMETRIC, 105 1, 0, 106 16, 107 rte_socket_id()); 108 if (!sym->op_pool) 109 goto error_exit; 110 111 sym->op = rte_crypto_op_alloc(sym->op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 112 if (!sym->op) 113 goto error_exit; 114 115 return 0; 116 117 error_exit: 118 rte_mempool_free(sym->sess_mpool); 119 rte_mempool_free(sym->op_pool); 120 return ret; 121 } 122 123 static void 124 cryptodev_fips_validate_app_sym_uninit(void) 125 { 126 struct fips_sym_env *sym = &env.sym; 127 128 rte_pktmbuf_free(env.mbuf); 129 rte_crypto_op_free(sym->op); 130 rte_cryptodev_sym_session_free(env.dev_id, sym->sess); 131 rte_mempool_free(sym->sess_mpool); 132 rte_mempool_free(sym->op_pool); 133 } 134 135 static int 136 cryptodev_fips_validate_app_asym_init(void) 137 { 138 struct fips_asym_env *asym = &env.asym; 139 int ret; 140 141 ret = -ENOMEM; 142 asym->sess_mpool = rte_cryptodev_asym_session_pool_create( 143 "FIPS_ASYM_SESS_MEMPOOL", 16, 0, 0, rte_socket_id()); 144 if (!asym->sess_mpool) 145 goto error_exit; 146 147 asym->op_pool = rte_crypto_op_pool_create( 148 "FIPS_OP_ASYM_POOL", 149 RTE_CRYPTO_OP_TYPE_ASYMMETRIC, 150 1, 0, 151 16, 152 rte_socket_id()); 153 if (!asym->op_pool) 154 goto error_exit; 155 156 asym->op = rte_crypto_op_alloc(asym->op_pool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); 157 if (!asym->op) 158 goto error_exit; 159 160 return 0; 161 162 error_exit: 163 rte_mempool_free(asym->sess_mpool); 164 rte_mempool_free(asym->op_pool); 165 return ret; 166 } 167 168 static void 169 cryptodev_fips_validate_app_asym_uninit(void) 170 { 171 struct fips_asym_env *asym = &env.asym; 172 173 rte_crypto_op_free(asym->op); 174 rte_cryptodev_asym_session_free(env.dev_id, asym->sess); 175 rte_mempool_free(asym->sess_mpool); 176 rte_mempool_free(asym->op_pool); 177 } 178 179 static int 180 cryptodev_fips_validate_app_init(void) 181 { 182 struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0}; 183 struct rte_cryptodev_qp_conf qp_conf = {128, NULL}; 184 uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1; 185 int ret; 186 187 if (env.self_test) { 188 ret = fips_dev_self_test(env.dev_id, env.broken_test_config); 189 if (ret < 0) { 190 rte_cryptodev_stop(env.dev_id); 191 rte_cryptodev_close(env.dev_id); 192 193 return ret; 194 } 195 } 196 197 ret = rte_cryptodev_configure(env.dev_id, &conf); 198 if (ret < 0) 199 return ret; 200 201 ret = -ENOMEM; 202 env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs, 203 0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM + 204 env.mbuf_data_room, rte_socket_id()); 205 if (!env.mpool) 206 return ret; 207 208 ret = cryptodev_fips_validate_app_sym_init(); 209 if (ret < 0) 210 goto error_exit; 211 212 if (env.is_asym_test) { 213 ret = cryptodev_fips_validate_app_asym_init(); 214 if (ret < 0) 215 goto error_exit; 216 } 217 218 qp_conf.mp_session = env.sym.sess_mpool; 219 220 ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf, 221 rte_socket_id()); 222 if (ret < 0) 223 goto error_exit; 224 225 ret = rte_cryptodev_start(env.dev_id); 226 if (ret < 0) 227 goto error_exit; 228 229 return 0; 230 231 error_exit: 232 rte_mempool_free(env.mpool); 233 return ret; 234 } 235 236 static void 237 cryptodev_fips_validate_app_uninit(void) 238 { 239 cryptodev_fips_validate_app_sym_uninit(); 240 241 if (env.is_asym_test) 242 cryptodev_fips_validate_app_asym_uninit(); 243 244 rte_mempool_free(env.mpool); 245 rte_cryptodev_stop(env.dev_id); 246 rte_cryptodev_close(env.dev_id); 247 } 248 249 static int 250 fips_test_one_file(void); 251 252 #ifdef USE_JANSSON 253 static int 254 fips_test_one_json_file(void); 255 #endif /* USE_JANSSON */ 256 257 static int 258 parse_cryptodev_arg(char *arg) 259 { 260 int id = rte_cryptodev_get_dev_id(arg); 261 262 if (id < 0) { 263 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n", 264 id, arg); 265 return id; 266 } 267 268 env.dev_id = (uint8_t)id; 269 270 return 0; 271 } 272 273 static int 274 parse_cryptodev_id_arg(char *arg) 275 { 276 uint32_t cryptodev_id; 277 278 if (parser_read_uint32(&cryptodev_id, arg) < 0) { 279 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", 280 -EINVAL, arg); 281 return -1; 282 } 283 284 285 if (!rte_cryptodev_is_valid_dev(cryptodev_id)) { 286 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", 287 cryptodev_id, arg); 288 return -1; 289 } 290 291 env.dev_id = (uint8_t)cryptodev_id; 292 293 return 0; 294 } 295 296 static void 297 cryptodev_fips_validate_usage(const char *prgname) 298 { 299 uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE; 300 printf("%s [EAL options] --\n" 301 " --%s: REQUEST-FILE-PATH\n" 302 " --%s: RESPONSE-FILE-PATH\n" 303 " --%s: indicating both paths are folders\n" 304 " --%s: mbuf dataroom size (default %u bytes)\n" 305 " --%s: CRYPTODEV-NAME\n" 306 " --%s: CRYPTODEV-ID-NAME\n" 307 " --%s: self test indicator\n" 308 " --%s: self broken test ID\n" 309 " --%s: self broken test direction\n", 310 prgname, OPT_REQ_FILE_PATH, OPT_RSP_FILE_PATH, 311 OPT_FOLDER, OPT_MBUF_DATAROOM, def_mbuf_seg_size, 312 OPT_CRYPTODEV, OPT_CRYPTODEV_ID, OPT_CRYPTODEV_ST, 313 OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY); 314 } 315 316 static int 317 cryptodev_fips_validate_parse_args(int argc, char **argv) 318 { 319 int opt, ret; 320 char *prgname = argv[0]; 321 char **argvopt; 322 int option_index; 323 struct option lgopts[] = { 324 {OPT_REQ_FILE_PATH, required_argument, 325 NULL, OPT_REQ_FILE_PATH_NUM}, 326 {OPT_RSP_FILE_PATH, required_argument, 327 NULL, OPT_RSP_FILE_PATH_NUM}, 328 {OPT_FOLDER, no_argument, 329 NULL, OPT_FOLDER_NUM}, 330 {OPT_MBUF_DATAROOM, required_argument, 331 NULL, OPT_MBUF_DATAROOM_NUM}, 332 {OPT_CRYPTODEV, required_argument, 333 NULL, OPT_CRYPTODEV_NUM}, 334 {OPT_CRYPTODEV_ID, required_argument, 335 NULL, OPT_CRYPTODEV_ID_NUM}, 336 {OPT_CRYPTODEV_ST, no_argument, 337 NULL, OPT_CRYPTODEV_ST_NUM}, 338 {OPT_CRYPTODEV_BK_ID, required_argument, 339 NULL, OPT_CRYPTODEV_BK_ID_NUM}, 340 {OPT_CRYPTODEV_BK_DIR_KEY, required_argument, 341 NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM}, 342 {OPT_CRYPTODEV_ASYM, no_argument, 343 NULL, OPT_CRYPTODEV_ASYM_NUM}, 344 {NULL, 0, 0, 0} 345 }; 346 347 argvopt = argv; 348 349 env.mbuf_data_room = DEF_MBUF_SEG_SIZE; 350 if (rte_cryptodev_count()) 351 env.dev_id = 0; 352 else { 353 cryptodev_fips_validate_usage(prgname); 354 return -EINVAL; 355 } 356 357 while ((opt = getopt_long(argc, argvopt, "s:", 358 lgopts, &option_index)) != EOF) { 359 360 switch (opt) { 361 case OPT_REQ_FILE_PATH_NUM: 362 env.req_path = optarg; 363 break; 364 365 case OPT_RSP_FILE_PATH_NUM: 366 env.rsp_path = optarg; 367 break; 368 369 case OPT_FOLDER_NUM: 370 env.is_path_folder = 1; 371 break; 372 373 case OPT_CRYPTODEV_NUM: 374 ret = parse_cryptodev_arg(optarg); 375 if (ret < 0) { 376 cryptodev_fips_validate_usage(prgname); 377 return -EINVAL; 378 } 379 break; 380 381 case OPT_CRYPTODEV_ID_NUM: 382 ret = parse_cryptodev_id_arg(optarg); 383 if (ret < 0) { 384 cryptodev_fips_validate_usage(prgname); 385 return -EINVAL; 386 } 387 break; 388 389 case OPT_CRYPTODEV_ST_NUM: 390 env.self_test = 1; 391 break; 392 393 case OPT_CRYPTODEV_BK_ID_NUM: 394 if (!env.broken_test_config) { 395 env.broken_test_config = rte_malloc( 396 NULL, 397 sizeof(*env.broken_test_config), 398 0); 399 if (!env.broken_test_config) 400 return -ENOMEM; 401 402 env.broken_test_config->expect_fail_dir = 403 self_test_dir_enc_auth_gen; 404 } 405 406 if (parser_read_uint32( 407 &env.broken_test_config->expect_fail_test_idx, 408 optarg) < 0) { 409 rte_free(env.broken_test_config); 410 cryptodev_fips_validate_usage(prgname); 411 return -EINVAL; 412 } 413 break; 414 415 case OPT_CRYPTODEV_BK_DIR_KEY_NUM: 416 if (!env.broken_test_config) { 417 env.broken_test_config = rte_malloc( 418 NULL, 419 sizeof(*env.broken_test_config), 420 0); 421 if (!env.broken_test_config) 422 return -ENOMEM; 423 424 env.broken_test_config->expect_fail_test_idx = 425 0; 426 } 427 428 if (strcmp(optarg, "enc") == 0) 429 env.broken_test_config->expect_fail_dir = 430 self_test_dir_enc_auth_gen; 431 else if (strcmp(optarg, "dec") 432 == 0) 433 env.broken_test_config->expect_fail_dir = 434 self_test_dir_dec_auth_verify; 435 else { 436 rte_free(env.broken_test_config); 437 cryptodev_fips_validate_usage(prgname); 438 return -EINVAL; 439 } 440 break; 441 442 443 case OPT_MBUF_DATAROOM_NUM: 444 if (parser_read_uint16(&env.mbuf_data_room, 445 optarg) < 0) { 446 cryptodev_fips_validate_usage(prgname); 447 return -EINVAL; 448 } 449 450 if (env.mbuf_data_room == 0) { 451 cryptodev_fips_validate_usage(prgname); 452 return -EINVAL; 453 } 454 break; 455 456 case OPT_CRYPTODEV_ASYM_NUM: 457 env.is_asym_test = true; 458 break; 459 460 default: 461 cryptodev_fips_validate_usage(prgname); 462 return -EINVAL; 463 } 464 } 465 466 if ((env.req_path == NULL && env.rsp_path != NULL) || 467 (env.req_path != NULL && env.rsp_path == NULL)) { 468 RTE_LOG(ERR, USER1, "Missing req path or rsp path\n"); 469 cryptodev_fips_validate_usage(prgname); 470 return -EINVAL; 471 } 472 473 if (env.req_path == NULL && env.self_test == 0) { 474 RTE_LOG(ERR, USER1, "--self-test must be set if req path is missing\n"); 475 cryptodev_fips_validate_usage(prgname); 476 return -EINVAL; 477 } 478 479 return 0; 480 } 481 482 int 483 main(int argc, char *argv[]) 484 { 485 int ret; 486 487 ret = rte_eal_init(argc, argv); 488 if (ret < 0) { 489 RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); 490 return -1; 491 } 492 493 argc -= ret; 494 argv += ret; 495 496 ret = cryptodev_fips_validate_parse_args(argc, argv); 497 if (ret < 0) 498 rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n"); 499 500 ret = cryptodev_fips_validate_app_init(); 501 if (ret < 0) { 502 RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); 503 return -1; 504 } 505 506 if (env.req_path == NULL || env.rsp_path == NULL) { 507 printf("No request, exit.\n"); 508 goto exit; 509 } 510 511 if (!env.is_path_folder) { 512 printf("Processing file %s... ", env.req_path); 513 514 ret = fips_test_init(env.req_path, env.rsp_path, 515 rte_cryptodev_name_get(env.dev_id)); 516 if (ret < 0) { 517 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 518 ret, env.req_path); 519 goto exit; 520 } 521 522 #ifdef USE_JANSSON 523 if (info.file_type == FIPS_TYPE_JSON) { 524 ret = fips_test_one_json_file(); 525 json_decref(json_info.json_root); 526 } else { 527 ret = fips_test_one_file(); 528 } 529 #else /* USE_JANSSON */ 530 ret = fips_test_one_file(); 531 #endif /* USE_JANSSON */ 532 533 if (ret < 0) { 534 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 535 ret, env.req_path); 536 goto exit; 537 } 538 539 printf("Done\n"); 540 541 } else { 542 struct dirent *dir; 543 DIR *d_req, *d_rsp; 544 char req_path[1024]; 545 char rsp_path[1024]; 546 547 d_req = opendir(env.req_path); 548 if (!d_req) { 549 RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n", 550 -EINVAL, env.req_path); 551 goto exit; 552 } 553 554 d_rsp = opendir(env.rsp_path); 555 if (!d_rsp) { 556 ret = mkdir(env.rsp_path, 0700); 557 if (ret == 0) 558 d_rsp = opendir(env.rsp_path); 559 else { 560 RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n", 561 -EINVAL, env.rsp_path); 562 goto exit; 563 } 564 } 565 closedir(d_rsp); 566 567 while ((dir = readdir(d_req)) != NULL) { 568 if (strstr(dir->d_name, "req") == NULL) 569 continue; 570 571 snprintf(req_path, 1023, "%s/%s", env.req_path, 572 dir->d_name); 573 snprintf(rsp_path, 1023, "%s/%s", env.rsp_path, 574 dir->d_name); 575 strlcpy(strstr(rsp_path, "req"), "rsp", 4); 576 577 printf("Processing file %s... ", req_path); 578 579 ret = fips_test_init(req_path, rsp_path, 580 rte_cryptodev_name_get(env.dev_id)); 581 if (ret < 0) { 582 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 583 ret, req_path); 584 break; 585 } 586 587 #ifdef USE_JANSSON 588 if (info.file_type == FIPS_TYPE_JSON) { 589 ret = fips_test_one_json_file(); 590 json_decref(json_info.json_root); 591 } else { 592 ret = fips_test_one_file(); 593 } 594 #else /* USE_JANSSON */ 595 ret = fips_test_one_file(); 596 #endif /* USE_JANSSON */ 597 598 if (ret < 0) { 599 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 600 ret, req_path); 601 break; 602 } 603 604 printf("Done\n"); 605 } 606 607 closedir(d_req); 608 } 609 610 611 exit: 612 fips_test_clear(); 613 cryptodev_fips_validate_app_uninit(); 614 615 /* clean up the EAL */ 616 rte_eal_cleanup(); 617 618 return ret; 619 620 } 621 622 #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op)) 623 #define CRYPTODEV_FIPS_MAX_RETRIES 16 624 625 struct fips_test_ops test_ops; 626 627 static int 628 prepare_data_mbufs(struct fips_val *val) 629 { 630 struct rte_mbuf *m, *head = 0; 631 uint8_t *src = val->val; 632 uint32_t total_len = val->len; 633 uint16_t nb_seg; 634 int ret = 0; 635 636 rte_pktmbuf_free(env.mbuf); 637 638 if (total_len > RTE_MBUF_MAX_NB_SEGS) { 639 RTE_LOG(ERR, USER1, "Data len %u too big\n", total_len); 640 return -EPERM; 641 } 642 643 nb_seg = total_len / env.mbuf_data_room; 644 if (total_len % env.mbuf_data_room) 645 nb_seg++; 646 647 m = rte_pktmbuf_alloc(env.mpool); 648 if (!m) { 649 RTE_LOG(ERR, USER1, "Error %i: Not enough mbuf\n", 650 -ENOMEM); 651 return -ENOMEM; 652 } 653 head = m; 654 655 while (nb_seg) { 656 uint16_t len = RTE_MIN(total_len, env.mbuf_data_room); 657 uint8_t *dst = (uint8_t *)rte_pktmbuf_append(m, len); 658 659 if (!dst) { 660 RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", 661 -ENOMEM); 662 ret = -ENOMEM; 663 goto error_exit; 664 } 665 666 memcpy(dst, src, len); 667 668 if (head != m) { 669 ret = rte_pktmbuf_chain(head, m); 670 if (ret) { 671 rte_pktmbuf_free(m); 672 RTE_LOG(ERR, USER1, "Error %i: SGL build\n", 673 ret); 674 goto error_exit; 675 } 676 } 677 total_len -= len; 678 679 if (total_len) { 680 if (!env.dev_support_sgl) { 681 RTE_LOG(ERR, USER1, "SGL not supported\n"); 682 ret = -EPERM; 683 goto error_exit; 684 } 685 686 m = rte_pktmbuf_alloc(env.mpool); 687 if (!m) { 688 RTE_LOG(ERR, USER1, "Error %i: No memory\n", 689 -ENOMEM); 690 goto error_exit; 691 } 692 } else 693 break; 694 695 src += len; 696 nb_seg--; 697 } 698 699 if (total_len) { 700 RTE_LOG(ERR, USER1, "Error %i: Failed to store all data\n", 701 -ENOMEM); 702 goto error_exit; 703 } 704 705 env.mbuf = head; 706 707 return 0; 708 709 error_exit: 710 rte_pktmbuf_free(head); 711 return ret; 712 } 713 714 static int 715 prepare_cipher_op(void) 716 { 717 struct rte_crypto_sym_op *sym = env.op->sym; 718 uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); 719 int ret; 720 721 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 722 723 memcpy(iv, vec.iv.val, vec.iv.len); 724 725 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 726 ret = prepare_data_mbufs(&vec.pt); 727 if (ret < 0) 728 return ret; 729 730 sym->cipher.data.length = vec.pt.len; 731 } else { 732 ret = prepare_data_mbufs(&vec.ct); 733 if (ret < 0) 734 return ret; 735 736 sym->cipher.data.length = vec.ct.len; 737 } 738 739 rte_crypto_op_attach_sym_session(env.op, env.sym.sess); 740 741 sym->m_src = env.mbuf; 742 sym->cipher.data.offset = 0; 743 744 return 0; 745 } 746 747 int 748 prepare_auth_op(void) 749 { 750 struct rte_crypto_sym_op *sym = env.op->sym; 751 int ret; 752 753 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 754 755 if (info.interim_info.gcm_data.gen_iv == 1) { 756 uint32_t i; 757 758 if (!vec.iv.val) { 759 vec.iv.val = rte_malloc(0, vec.iv.len, 0); 760 if (!vec.iv.val) 761 return -ENOMEM; 762 } 763 764 for (i = 0; i < vec.iv.len; i++) { 765 int random = rte_rand(); 766 vec.iv.val[i] = (uint8_t)random; 767 } 768 } 769 770 if (vec.iv.len) { 771 uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, 772 IV_OFF); 773 memset(iv, 0, vec.iv.len); 774 if (vec.iv.val) 775 memcpy(iv, vec.iv.val, vec.iv.len); 776 } 777 778 ret = prepare_data_mbufs(&vec.pt); 779 if (ret < 0) 780 return ret; 781 782 rte_free(env.digest); 783 784 env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len, 785 RTE_CACHE_LINE_SIZE); 786 if (!env.digest) { 787 RTE_LOG(ERR, USER1, "Not enough memory\n"); 788 return -ENOMEM; 789 } 790 env.digest_len = vec.cipher_auth.digest.len; 791 792 sym->m_src = env.mbuf; 793 sym->auth.data.offset = 0; 794 sym->auth.data.length = vec.pt.len; 795 sym->auth.digest.data = env.digest; 796 sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest); 797 798 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 799 memcpy(env.digest, vec.cipher_auth.digest.val, 800 vec.cipher_auth.digest.len); 801 802 rte_crypto_op_attach_sym_session(env.op, env.sym.sess); 803 804 return 0; 805 } 806 807 int 808 prepare_aead_op(void) 809 { 810 struct rte_crypto_sym_op *sym = env.op->sym; 811 uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); 812 int ret; 813 814 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 815 816 if (info.algo == FIPS_TEST_ALGO_AES_CCM) 817 iv++; 818 819 if (vec.iv.val) 820 memcpy(iv, vec.iv.val, vec.iv.len); 821 else 822 /* if REQ file has iv length but not data, default as all 0 */ 823 memset(iv, 0, vec.iv.len); 824 825 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 826 ret = prepare_data_mbufs(&vec.pt); 827 if (ret < 0) 828 return ret; 829 830 rte_free(env.digest); 831 env.digest = rte_zmalloc(NULL, vec.aead.digest.len, 832 RTE_CACHE_LINE_SIZE); 833 if (!env.digest) { 834 RTE_LOG(ERR, USER1, "Not enough memory\n"); 835 return -ENOMEM; 836 } 837 env.digest_len = vec.aead.digest.len; 838 839 sym->aead.data.length = vec.pt.len; 840 sym->aead.digest.data = env.digest; 841 sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest); 842 } else { 843 ret = prepare_data_mbufs(&vec.ct); 844 if (ret < 0) 845 return ret; 846 env.digest_len = vec.aead.digest.len; 847 sym->aead.data.length = vec.ct.len; 848 sym->aead.digest.data = vec.aead.digest.val; 849 sym->aead.digest.phys_addr = rte_malloc_virt2iova( 850 sym->aead.digest.data); 851 } 852 853 sym->m_src = env.mbuf; 854 sym->aead.data.offset = 0; 855 sym->aead.aad.data = vec.aead.aad.val; 856 sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data); 857 858 rte_crypto_op_attach_sym_session(env.op, env.sym.sess); 859 860 return 0; 861 } 862 863 static int 864 get_hash_oid(enum rte_crypto_auth_algorithm hash, uint8_t *buf) 865 { 866 uint8_t id_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 867 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 868 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 869 0x40}; 870 uint8_t id_sha384[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 871 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 872 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 873 0x30}; 874 uint8_t id_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 875 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 876 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 877 0x20}; 878 uint8_t id_sha224[] = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 879 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 880 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 881 0x1c}; 882 uint8_t id_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 883 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 884 0x00, 0x04, 0x14}; 885 uint8_t *id = NULL; 886 int id_len = 0; 887 888 switch (hash) { 889 case RTE_CRYPTO_AUTH_SHA1: 890 id = id_sha1; 891 id_len = sizeof(id_sha1); 892 break; 893 case RTE_CRYPTO_AUTH_SHA224: 894 id = id_sha224; 895 id_len = sizeof(id_sha224); 896 break; 897 case RTE_CRYPTO_AUTH_SHA256: 898 id = id_sha256; 899 id_len = sizeof(id_sha256); 900 break; 901 case RTE_CRYPTO_AUTH_SHA384: 902 id = id_sha384; 903 id_len = sizeof(id_sha384); 904 break; 905 case RTE_CRYPTO_AUTH_SHA512: 906 id = id_sha512; 907 id_len = sizeof(id_sha512); 908 break; 909 default: 910 id_len = -1; 911 break; 912 } 913 914 if (id != NULL) 915 rte_memcpy(buf, id, id_len); 916 917 return id_len; 918 } 919 920 static int 921 prepare_rsa_op(void) 922 { 923 struct rte_crypto_asym_op *asym; 924 struct fips_val msg; 925 926 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); 927 928 asym = env.op->asym; 929 asym->rsa.padding.type = info.interim_info.rsa_data.padding; 930 asym->rsa.padding.hash = info.interim_info.rsa_data.auth; 931 932 if (env.digest) { 933 if (asym->rsa.padding.type == RTE_CRYPTO_RSA_PADDING_PKCS1_5) { 934 int b_len = 0; 935 uint8_t b[32]; 936 937 b_len = get_hash_oid(asym->rsa.padding.hash, b); 938 if (b_len < 0) { 939 RTE_LOG(ERR, USER1, "Failed to get digest info for hash %d\n", 940 asym->rsa.padding.hash); 941 return -EINVAL; 942 } 943 944 if (b_len) { 945 msg.len = env.digest_len + b_len; 946 msg.val = rte_zmalloc(NULL, msg.len, 0); 947 rte_memcpy(msg.val, b, b_len); 948 rte_memcpy(msg.val + b_len, env.digest, env.digest_len); 949 rte_free(env.digest); 950 env.digest = msg.val; 951 env.digest_len = msg.len; 952 } 953 } 954 msg.val = env.digest; 955 msg.len = env.digest_len; 956 } else { 957 msg.val = vec.pt.val; 958 msg.len = vec.pt.len; 959 } 960 961 if (info.op == FIPS_TEST_ASYM_SIGGEN) { 962 asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; 963 asym->rsa.message.data = msg.val; 964 asym->rsa.message.length = msg.len; 965 966 rte_free(vec.rsa.signature.val); 967 968 vec.rsa.signature.val = rte_zmalloc(NULL, vec.rsa.n.len, 0); 969 vec.rsa.signature.len = vec.rsa.n.len; 970 asym->rsa.sign.data = vec.rsa.signature.val; 971 asym->rsa.sign.length = 0; 972 } else if (info.op == FIPS_TEST_ASYM_SIGVER) { 973 asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; 974 asym->rsa.message.data = msg.val; 975 asym->rsa.message.length = msg.len; 976 asym->rsa.sign.data = vec.rsa.signature.val; 977 asym->rsa.sign.length = vec.rsa.signature.len; 978 } else { 979 RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op); 980 return -EINVAL; 981 } 982 983 rte_crypto_op_attach_asym_session(env.op, env.asym.sess); 984 985 return 0; 986 } 987 988 static int 989 prepare_ecdsa_op(void) 990 { 991 struct rte_crypto_asym_op *asym; 992 struct fips_val msg; 993 994 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); 995 996 asym = env.op->asym; 997 if (env.digest) { 998 msg.val = env.digest; 999 msg.len = env.digest_len; 1000 } else { 1001 msg.val = vec.pt.val; 1002 msg.len = vec.pt.len; 1003 } 1004 1005 if (info.op == FIPS_TEST_ASYM_SIGGEN) { 1006 asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; 1007 asym->ecdsa.message.data = msg.val; 1008 asym->ecdsa.message.length = msg.len; 1009 asym->ecdsa.k.data = vec.ecdsa.k.val; 1010 asym->ecdsa.k.length = vec.ecdsa.k.len; 1011 1012 rte_free(vec.ecdsa.r.val); 1013 1014 rte_free(vec.ecdsa.s.val); 1015 1016 vec.ecdsa.r.len = info.interim_info.ecdsa_data.curve_len; 1017 vec.ecdsa.r.val = rte_zmalloc(NULL, vec.ecdsa.r.len, 0); 1018 1019 vec.ecdsa.s.len = vec.ecdsa.r.len; 1020 vec.ecdsa.s.val = rte_zmalloc(NULL, vec.ecdsa.s.len, 0); 1021 1022 asym->ecdsa.r.data = vec.ecdsa.r.val; 1023 asym->ecdsa.r.length = 0; 1024 asym->ecdsa.s.data = vec.ecdsa.s.val; 1025 asym->ecdsa.s.length = 0; 1026 } else if (info.op == FIPS_TEST_ASYM_SIGVER) { 1027 asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; 1028 asym->ecdsa.message.data = msg.val; 1029 asym->ecdsa.message.length = msg.len; 1030 asym->ecdsa.r.data = vec.ecdsa.r.val; 1031 asym->ecdsa.r.length = vec.ecdsa.r.len; 1032 asym->ecdsa.s.data = vec.ecdsa.s.val; 1033 asym->ecdsa.s.length = vec.ecdsa.s.len; 1034 } else { 1035 RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op); 1036 return -EINVAL; 1037 } 1038 1039 rte_crypto_op_attach_asym_session(env.op, env.asym.sess); 1040 1041 return 0; 1042 } 1043 1044 static int 1045 prepare_eddsa_op(void) 1046 { 1047 struct rte_crypto_asym_op *asym; 1048 struct fips_val msg; 1049 1050 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); 1051 1052 asym = env.op->asym; 1053 if (env.digest) { 1054 msg.val = env.digest; 1055 msg.len = env.digest_len; 1056 } else { 1057 msg.val = vec.pt.val; 1058 msg.len = vec.pt.len; 1059 } 1060 1061 if (info.op == FIPS_TEST_ASYM_SIGGEN) { 1062 asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; 1063 asym->eddsa.message.data = msg.val; 1064 asym->eddsa.message.length = msg.len; 1065 asym->eddsa.context.data = vec.eddsa.ctx.val; 1066 asym->eddsa.context.length = vec.eddsa.ctx.len; 1067 1068 rte_free(vec.eddsa.sign.val); 1069 1070 vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len; 1071 vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0); 1072 1073 asym->eddsa.sign.data = vec.eddsa.sign.val; 1074 asym->eddsa.sign.length = 0; 1075 } else if (info.op == FIPS_TEST_ASYM_SIGVER) { 1076 asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; 1077 asym->eddsa.message.data = msg.val; 1078 asym->eddsa.message.length = msg.len; 1079 asym->eddsa.sign.data = vec.eddsa.sign.val; 1080 asym->eddsa.sign.length = vec.eddsa.sign.len; 1081 } else { 1082 RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op); 1083 return -EINVAL; 1084 } 1085 1086 if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) { 1087 asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519; 1088 if (info.interim_info.eddsa_data.prehash) 1089 asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH; 1090 if (vec.eddsa.ctx.len > 0) 1091 asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX; 1092 } else { 1093 asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448; 1094 if (info.interim_info.eddsa_data.prehash) 1095 asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH; 1096 } 1097 rte_crypto_op_attach_asym_session(env.op, env.asym.sess); 1098 1099 return 0; 1100 } 1101 1102 static int 1103 prepare_ecfpm_op(void) 1104 { 1105 struct rte_crypto_asym_op *asym; 1106 1107 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); 1108 1109 asym = env.op->asym; 1110 asym->ecpm.scalar.data = vec.ecdsa.pkey.val; 1111 asym->ecpm.scalar.length = vec.ecdsa.pkey.len; 1112 1113 rte_free(vec.ecdsa.qx.val); 1114 1115 rte_free(vec.ecdsa.qy.val); 1116 1117 vec.ecdsa.qx.len = info.interim_info.ecdsa_data.curve_len; 1118 vec.ecdsa.qx.val = rte_zmalloc(NULL, vec.ecdsa.qx.len, 0); 1119 1120 vec.ecdsa.qy.len = vec.ecdsa.qx.len; 1121 vec.ecdsa.qy.val = rte_zmalloc(NULL, vec.ecdsa.qy.len, 0); 1122 1123 asym->ecpm.r.x.data = vec.ecdsa.qx.val; 1124 asym->ecpm.r.x.length = 0; 1125 asym->ecpm.r.y.data = vec.ecdsa.qy.val; 1126 asym->ecpm.r.y.length = 0; 1127 1128 rte_crypto_op_attach_asym_session(env.op, env.asym.sess); 1129 1130 return 0; 1131 } 1132 1133 static int 1134 prepare_edfpm_op(void) 1135 { 1136 struct rte_crypto_asym_op *asym; 1137 1138 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); 1139 1140 asym = env.op->asym; 1141 asym->ecpm.scalar.data = vec.eddsa.pkey.val; 1142 asym->ecpm.scalar.length = vec.eddsa.pkey.len; 1143 1144 rte_free(vec.eddsa.q.val); 1145 1146 vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len; 1147 vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0); 1148 1149 asym->ecpm.r.x.data = vec.eddsa.q.val; 1150 asym->ecpm.r.x.length = 0; 1151 asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED; 1152 1153 rte_crypto_op_attach_asym_session(env.op, env.asym.sess); 1154 1155 return 0; 1156 } 1157 1158 static int 1159 prepare_aes_xform(struct rte_crypto_sym_xform *xform) 1160 { 1161 const struct rte_cryptodev_symmetric_capability *cap; 1162 struct rte_cryptodev_sym_capability_idx cap_idx; 1163 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1164 1165 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1166 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) 1167 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC; 1168 else if (info.interim_info.aes_data.cipher_algo == 1169 RTE_CRYPTO_CIPHER_AES_CTR) 1170 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR; 1171 else 1172 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB; 1173 1174 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1175 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1176 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1177 cipher_xform->key.data = vec.cipher_auth.key.val; 1178 cipher_xform->key.length = vec.cipher_auth.key.len; 1179 if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC || 1180 cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) { 1181 cipher_xform->iv.length = vec.iv.len; 1182 cipher_xform->iv.offset = IV_OFF; 1183 } else { 1184 cipher_xform->iv.length = 0; 1185 cipher_xform->iv.offset = 0; 1186 } 1187 cap_idx.algo.cipher = cipher_xform->algo; 1188 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1189 1190 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1191 if (!cap) { 1192 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1193 env.dev_id); 1194 return -EINVAL; 1195 } 1196 1197 if (rte_cryptodev_sym_capability_check_cipher(cap, 1198 cipher_xform->key.length, 1199 cipher_xform->iv.length) != 0) { 1200 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1201 info.device_name, cipher_xform->key.length, 1202 cipher_xform->iv.length); 1203 return -EPERM; 1204 } 1205 1206 return 0; 1207 } 1208 1209 static int 1210 prepare_tdes_xform(struct rte_crypto_sym_xform *xform) 1211 { 1212 const struct rte_cryptodev_symmetric_capability *cap; 1213 struct rte_cryptodev_sym_capability_idx cap_idx; 1214 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1215 1216 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1217 1218 if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC) 1219 cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC; 1220 else 1221 cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB; 1222 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1223 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1224 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1225 cipher_xform->key.data = vec.cipher_auth.key.val; 1226 cipher_xform->key.length = vec.cipher_auth.key.len; 1227 1228 if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) { 1229 cipher_xform->iv.length = vec.iv.len; 1230 cipher_xform->iv.offset = IV_OFF; 1231 } else { 1232 cipher_xform->iv.length = 0; 1233 cipher_xform->iv.offset = 0; 1234 } 1235 cap_idx.algo.cipher = cipher_xform->algo; 1236 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1237 1238 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1239 if (!cap) { 1240 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1241 env.dev_id); 1242 return -EINVAL; 1243 } 1244 1245 if (rte_cryptodev_sym_capability_check_cipher(cap, 1246 cipher_xform->key.length, 1247 cipher_xform->iv.length) != 0) { 1248 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1249 info.device_name, cipher_xform->key.length, 1250 cipher_xform->iv.length); 1251 return -EPERM; 1252 } 1253 1254 return 0; 1255 } 1256 1257 static int 1258 prepare_hmac_xform(struct rte_crypto_sym_xform *xform) 1259 { 1260 const struct rte_cryptodev_symmetric_capability *cap; 1261 struct rte_cryptodev_sym_capability_idx cap_idx; 1262 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1263 1264 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1265 1266 auth_xform->algo = info.interim_info.hmac_data.algo; 1267 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 1268 auth_xform->digest_length = vec.cipher_auth.digest.len; 1269 auth_xform->key.data = vec.cipher_auth.key.val; 1270 auth_xform->key.length = vec.cipher_auth.key.len; 1271 1272 cap_idx.algo.auth = auth_xform->algo; 1273 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1274 1275 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1276 if (!cap) { 1277 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1278 env.dev_id); 1279 return -EINVAL; 1280 } 1281 1282 if (rte_cryptodev_sym_capability_check_auth(cap, 1283 auth_xform->key.length, 1284 auth_xform->digest_length, 0) != 0) { 1285 RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n", 1286 info.device_name, auth_xform->key.length, 1287 auth_xform->digest_length); 1288 return -EPERM; 1289 } 1290 1291 return 0; 1292 } 1293 1294 int 1295 prepare_gcm_xform(struct rte_crypto_sym_xform *xform) 1296 { 1297 const struct rte_cryptodev_symmetric_capability *cap; 1298 struct rte_cryptodev_sym_capability_idx cap_idx; 1299 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 1300 1301 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 1302 1303 aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM; 1304 aead_xform->aad_length = vec.aead.aad.len; 1305 aead_xform->digest_length = vec.aead.digest.len; 1306 aead_xform->iv.offset = IV_OFF; 1307 aead_xform->iv.length = vec.iv.len; 1308 aead_xform->key.data = vec.aead.key.val; 1309 aead_xform->key.length = vec.aead.key.len; 1310 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1311 RTE_CRYPTO_AEAD_OP_ENCRYPT : 1312 RTE_CRYPTO_AEAD_OP_DECRYPT; 1313 1314 cap_idx.algo.aead = aead_xform->algo; 1315 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 1316 1317 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1318 if (!cap) { 1319 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1320 env.dev_id); 1321 return -EINVAL; 1322 } 1323 1324 if (rte_cryptodev_sym_capability_check_aead(cap, 1325 aead_xform->key.length, 1326 aead_xform->digest_length, aead_xform->aad_length, 1327 aead_xform->iv.length) != 0) { 1328 RTE_LOG(ERR, USER1, 1329 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 1330 info.device_name, aead_xform->key.length, 1331 aead_xform->digest_length, 1332 aead_xform->aad_length, 1333 aead_xform->iv.length); 1334 return -EPERM; 1335 } 1336 1337 return 0; 1338 } 1339 1340 int 1341 prepare_gmac_xform(struct rte_crypto_sym_xform *xform) 1342 { 1343 const struct rte_cryptodev_symmetric_capability *cap; 1344 struct rte_cryptodev_sym_capability_idx cap_idx; 1345 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1346 1347 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1348 1349 auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC; 1350 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1351 RTE_CRYPTO_AUTH_OP_GENERATE : 1352 RTE_CRYPTO_AUTH_OP_VERIFY; 1353 auth_xform->iv.offset = IV_OFF; 1354 auth_xform->iv.length = vec.iv.len; 1355 auth_xform->digest_length = vec.aead.digest.len; 1356 auth_xform->key.data = vec.aead.key.val; 1357 auth_xform->key.length = vec.aead.key.len; 1358 1359 cap_idx.algo.auth = auth_xform->algo; 1360 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1361 1362 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1363 if (!cap) { 1364 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1365 env.dev_id); 1366 return -EINVAL; 1367 } 1368 1369 if (rte_cryptodev_sym_capability_check_auth(cap, 1370 auth_xform->key.length, 1371 auth_xform->digest_length, 1372 auth_xform->iv.length) != 0) { 1373 1374 RTE_LOG(ERR, USER1, 1375 "PMD %s key length %u Digest length %u IV length %u\n", 1376 info.device_name, auth_xform->key.length, 1377 auth_xform->digest_length, 1378 auth_xform->iv.length); 1379 return -EPERM; 1380 } 1381 1382 return 0; 1383 } 1384 1385 static int 1386 prepare_cmac_xform(struct rte_crypto_sym_xform *xform) 1387 { 1388 const struct rte_cryptodev_symmetric_capability *cap; 1389 struct rte_cryptodev_sym_capability_idx cap_idx; 1390 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1391 1392 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1393 1394 auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC; 1395 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1396 RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY; 1397 auth_xform->digest_length = vec.cipher_auth.digest.len; 1398 auth_xform->key.data = vec.cipher_auth.key.val; 1399 auth_xform->key.length = vec.cipher_auth.key.len; 1400 1401 cap_idx.algo.auth = auth_xform->algo; 1402 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1403 1404 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1405 if (!cap) { 1406 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1407 env.dev_id); 1408 return -EINVAL; 1409 } 1410 1411 if (rte_cryptodev_sym_capability_check_auth(cap, 1412 auth_xform->key.length, 1413 auth_xform->digest_length, 0) != 0) { 1414 RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n", 1415 info.device_name, auth_xform->key.length, 1416 auth_xform->digest_length); 1417 return -EPERM; 1418 } 1419 1420 return 0; 1421 } 1422 1423 static int 1424 prepare_ccm_xform(struct rte_crypto_sym_xform *xform) 1425 { 1426 const struct rte_cryptodev_symmetric_capability *cap; 1427 struct rte_cryptodev_sym_capability_idx cap_idx; 1428 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 1429 1430 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 1431 1432 aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM; 1433 aead_xform->aad_length = vec.aead.aad.len; 1434 aead_xform->digest_length = vec.aead.digest.len; 1435 aead_xform->iv.offset = IV_OFF; 1436 aead_xform->iv.length = vec.iv.len; 1437 aead_xform->key.data = vec.aead.key.val; 1438 aead_xform->key.length = vec.aead.key.len; 1439 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1440 RTE_CRYPTO_AEAD_OP_ENCRYPT : 1441 RTE_CRYPTO_AEAD_OP_DECRYPT; 1442 1443 cap_idx.algo.aead = aead_xform->algo; 1444 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 1445 1446 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1447 if (!cap) { 1448 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1449 env.dev_id); 1450 return -EINVAL; 1451 } 1452 1453 if (rte_cryptodev_sym_capability_check_aead(cap, 1454 aead_xform->key.length, 1455 aead_xform->digest_length, aead_xform->aad_length, 1456 aead_xform->iv.length) != 0) { 1457 RTE_LOG(ERR, USER1, 1458 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 1459 info.device_name, aead_xform->key.length, 1460 aead_xform->digest_length, 1461 aead_xform->aad_length, 1462 aead_xform->iv.length); 1463 return -EPERM; 1464 } 1465 1466 return 0; 1467 } 1468 1469 static int 1470 prepare_sha_xform(struct rte_crypto_sym_xform *xform) 1471 { 1472 const struct rte_cryptodev_symmetric_capability *cap; 1473 struct rte_cryptodev_sym_capability_idx cap_idx; 1474 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1475 1476 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1477 1478 auth_xform->algo = info.interim_info.sha_data.algo; 1479 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 1480 auth_xform->digest_length = vec.cipher_auth.digest.len; 1481 1482 cap_idx.algo.auth = auth_xform->algo; 1483 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1484 1485 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1486 if (!cap) { 1487 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1488 env.dev_id); 1489 return -EINVAL; 1490 } 1491 1492 if (rte_cryptodev_sym_capability_check_auth(cap, 1493 auth_xform->key.length, 1494 auth_xform->digest_length, 0) != 0) { 1495 RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n", 1496 info.device_name, auth_xform->key.length, 1497 auth_xform->digest_length); 1498 return -EPERM; 1499 } 1500 1501 return 0; 1502 } 1503 1504 static int 1505 prepare_xts_xform(struct rte_crypto_sym_xform *xform) 1506 { 1507 const struct rte_cryptodev_symmetric_capability *cap; 1508 struct rte_cryptodev_sym_capability_idx cap_idx; 1509 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1510 1511 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1512 1513 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS; 1514 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1515 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1516 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1517 cipher_xform->key.data = vec.cipher_auth.key.val; 1518 cipher_xform->key.length = vec.cipher_auth.key.len; 1519 cipher_xform->iv.length = vec.iv.len; 1520 cipher_xform->iv.offset = IV_OFF; 1521 1522 cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS; 1523 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1524 1525 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1526 if (!cap) { 1527 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1528 env.dev_id); 1529 return -EINVAL; 1530 } 1531 1532 if (rte_cryptodev_sym_capability_check_cipher(cap, 1533 cipher_xform->key.length, 1534 cipher_xform->iv.length) != 0) { 1535 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1536 info.device_name, cipher_xform->key.length, 1537 cipher_xform->iv.length); 1538 return -EPERM; 1539 } 1540 1541 return 0; 1542 } 1543 1544 static int 1545 prepare_rsa_xform(struct rte_crypto_asym_xform *xform) 1546 { 1547 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1548 struct rte_cryptodev_asym_capability_idx cap_idx; 1549 struct rte_cryptodev_info dev_info; 1550 1551 xform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA; 1552 xform->next = NULL; 1553 1554 cap_idx.type = xform->xform_type; 1555 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1556 if (!cap) { 1557 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1558 env.dev_id); 1559 return -EINVAL; 1560 } 1561 1562 switch (info.op) { 1563 case FIPS_TEST_ASYM_SIGGEN: 1564 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1565 RTE_CRYPTO_ASYM_OP_SIGN)) { 1566 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1567 info.device_name, RTE_CRYPTO_ASYM_OP_SIGN); 1568 return -EPERM; 1569 } 1570 break; 1571 case FIPS_TEST_ASYM_SIGVER: 1572 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1573 RTE_CRYPTO_ASYM_OP_VERIFY)) { 1574 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1575 info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY); 1576 return -EPERM; 1577 } 1578 break; 1579 case FIPS_TEST_ASYM_KEYGEN: 1580 break; 1581 default: 1582 break; 1583 } 1584 1585 rte_cryptodev_info_get(env.dev_id, &dev_info); 1586 xform->rsa.key_type = info.interim_info.rsa_data.privkey; 1587 switch (xform->rsa.key_type) { 1588 case RTE_RSA_KEY_TYPE_QT: 1589 if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) { 1590 RTE_LOG(ERR, USER1, "PMD %s does not support QT key type\n", 1591 info.device_name); 1592 return -EPERM; 1593 } 1594 xform->rsa.qt.p.data = vec.rsa.p.val; 1595 xform->rsa.qt.p.length = vec.rsa.p.len; 1596 xform->rsa.qt.q.data = vec.rsa.q.val; 1597 xform->rsa.qt.q.length = vec.rsa.q.len; 1598 xform->rsa.qt.dP.data = vec.rsa.dp.val; 1599 xform->rsa.qt.dP.length = vec.rsa.dp.len; 1600 xform->rsa.qt.dQ.data = vec.rsa.dq.val; 1601 xform->rsa.qt.dQ.length = vec.rsa.dq.len; 1602 xform->rsa.qt.qInv.data = vec.rsa.qinv.val; 1603 xform->rsa.qt.qInv.length = vec.rsa.qinv.len; 1604 break; 1605 case RTE_RSA_KEY_TYPE_EXP: 1606 if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) { 1607 RTE_LOG(ERR, USER1, "PMD %s does not support EXP key type\n", 1608 info.device_name); 1609 return -EPERM; 1610 } 1611 xform->rsa.d.data = vec.rsa.d.val; 1612 xform->rsa.d.length = vec.rsa.d.len; 1613 break; 1614 default: 1615 break; 1616 } 1617 1618 xform->rsa.e.data = vec.rsa.e.val; 1619 xform->rsa.e.length = vec.rsa.e.len; 1620 xform->rsa.n.data = vec.rsa.n.val; 1621 xform->rsa.n.length = vec.rsa.n.len; 1622 return 0; 1623 } 1624 1625 static int 1626 prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform) 1627 { 1628 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1629 struct rte_cryptodev_asym_capability_idx cap_idx; 1630 1631 xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA; 1632 xform->next = NULL; 1633 1634 cap_idx.type = xform->xform_type; 1635 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1636 if (!cap) { 1637 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1638 env.dev_id); 1639 return -EINVAL; 1640 } 1641 1642 switch (info.op) { 1643 case FIPS_TEST_ASYM_SIGGEN: 1644 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1645 RTE_CRYPTO_ASYM_OP_SIGN)) { 1646 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1647 info.device_name, RTE_CRYPTO_ASYM_OP_SIGN); 1648 return -EPERM; 1649 } 1650 1651 xform->ec.pkey.data = vec.ecdsa.pkey.val; 1652 xform->ec.pkey.length = vec.ecdsa.pkey.len; 1653 break; 1654 case FIPS_TEST_ASYM_SIGVER: 1655 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1656 RTE_CRYPTO_ASYM_OP_VERIFY)) { 1657 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1658 info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY); 1659 return -EPERM; 1660 } 1661 1662 xform->ec.q.x.data = vec.ecdsa.qx.val; 1663 xform->ec.q.x.length = vec.ecdsa.qx.len; 1664 xform->ec.q.y.data = vec.ecdsa.qy.val; 1665 xform->ec.q.y.length = vec.ecdsa.qy.len; 1666 break; 1667 default: 1668 break; 1669 } 1670 1671 xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id; 1672 return 0; 1673 } 1674 1675 static int 1676 prepare_eddsa_xform(struct rte_crypto_asym_xform *xform) 1677 { 1678 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1679 struct rte_cryptodev_asym_capability_idx cap_idx; 1680 1681 xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA; 1682 xform->next = NULL; 1683 1684 cap_idx.type = xform->xform_type; 1685 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1686 if (!cap) { 1687 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1688 env.dev_id); 1689 return -EINVAL; 1690 } 1691 1692 switch (info.op) { 1693 case FIPS_TEST_ASYM_SIGGEN: 1694 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1695 RTE_CRYPTO_ASYM_OP_SIGN)) { 1696 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1697 info.device_name, RTE_CRYPTO_ASYM_OP_SIGN); 1698 return -EPERM; 1699 } 1700 1701 xform->ec.pkey.data = vec.eddsa.pkey.val; 1702 xform->ec.pkey.length = vec.eddsa.pkey.len; 1703 xform->ec.q.x.data = vec.eddsa.q.val; 1704 xform->ec.q.x.length = vec.eddsa.q.len; 1705 break; 1706 case FIPS_TEST_ASYM_SIGVER: 1707 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1708 RTE_CRYPTO_ASYM_OP_VERIFY)) { 1709 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1710 info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY); 1711 return -EPERM; 1712 } 1713 1714 xform->ec.q.x.data = vec.eddsa.q.val; 1715 xform->ec.q.x.length = vec.eddsa.q.len; 1716 break; 1717 default: 1718 break; 1719 } 1720 1721 xform->ec.curve_id = info.interim_info.eddsa_data.curve_id; 1722 return 0; 1723 } 1724 1725 static int 1726 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform) 1727 { 1728 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1729 struct rte_cryptodev_asym_capability_idx cap_idx; 1730 1731 xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM; 1732 xform->next = NULL; 1733 1734 cap_idx.type = xform->xform_type; 1735 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1736 if (!cap) { 1737 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1738 env.dev_id); 1739 return -EINVAL; 1740 } 1741 1742 xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id; 1743 return 0; 1744 } 1745 1746 static int 1747 prepare_edfpm_xform(struct rte_crypto_asym_xform *xform) 1748 { 1749 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1750 struct rte_cryptodev_asym_capability_idx cap_idx; 1751 1752 xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM; 1753 xform->next = NULL; 1754 1755 cap_idx.type = xform->xform_type; 1756 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1757 if (!cap) { 1758 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1759 env.dev_id); 1760 return -EINVAL; 1761 } 1762 1763 xform->ec.curve_id = info.interim_info.eddsa_data.curve_id; 1764 return 0; 1765 } 1766 1767 static int 1768 get_writeback_data(struct fips_val *val) 1769 { 1770 struct rte_mbuf *m = env.mbuf; 1771 uint16_t data_len = rte_pktmbuf_pkt_len(m); 1772 uint16_t total_len = data_len + env.digest_len; 1773 uint8_t *src, *dst, *wb_data; 1774 1775 /* in case val is reused for MCT test, try to free the buffer first */ 1776 if (val->val) { 1777 rte_free(val->val); 1778 val->val = NULL; 1779 } 1780 1781 wb_data = dst = rte_malloc(NULL, total_len, 0); 1782 if (!dst) { 1783 RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM); 1784 return -ENOMEM; 1785 } 1786 1787 while (m && data_len) { 1788 uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len); 1789 1790 src = rte_pktmbuf_mtod(m, uint8_t *); 1791 memcpy(dst, src, seg_len); 1792 m = m->next; 1793 data_len -= seg_len; 1794 dst += seg_len; 1795 } 1796 1797 if (data_len) { 1798 RTE_LOG(ERR, USER1, "Error -1: write back data\n"); 1799 rte_free(wb_data); 1800 return -1; 1801 } 1802 1803 if (env.digest) 1804 memcpy(dst, env.digest, env.digest_len); 1805 1806 val->val = wb_data; 1807 val->len = total_len; 1808 1809 return 0; 1810 } 1811 1812 static int 1813 fips_run_sym_test(void) 1814 { 1815 struct rte_crypto_sym_xform xform = {0}; 1816 uint16_t n_deqd; 1817 int ret; 1818 1819 if (!test_ops.prepare_sym_xform || !test_ops.prepare_sym_op) 1820 return -EINVAL; 1821 1822 ret = test_ops.prepare_sym_xform(&xform); 1823 if (ret < 0) 1824 return ret; 1825 1826 env.sym.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform, 1827 env.sym.sess_mpool); 1828 if (!env.sym.sess) 1829 return -ENOMEM; 1830 1831 ret = test_ops.prepare_sym_op(); 1832 if (ret < 0) { 1833 RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", 1834 ret); 1835 goto exit; 1836 } 1837 1838 if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 1839 RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 1840 ret = -1; 1841 goto exit; 1842 } 1843 1844 do { 1845 struct rte_crypto_op *deqd_op; 1846 1847 n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1); 1848 } while (n_deqd == 0); 1849 1850 vec.status = env.op->status; 1851 1852 exit: 1853 rte_cryptodev_sym_session_free(env.dev_id, env.sym.sess); 1854 env.sym.sess = NULL; 1855 return ret; 1856 } 1857 1858 static int 1859 fips_run_asym_test(void) 1860 { 1861 struct rte_crypto_asym_xform xform = {0}; 1862 struct rte_crypto_asym_op *asym; 1863 struct rte_crypto_op *deqd_op; 1864 int ret; 1865 1866 if (info.op == FIPS_TEST_ASYM_KEYGEN && 1867 (info.algo != FIPS_TEST_ALGO_ECDSA && 1868 info.algo != FIPS_TEST_ALGO_EDDSA)) { 1869 RTE_SET_USED(asym); 1870 ret = 0; 1871 goto exit; 1872 } 1873 1874 if (!test_ops.prepare_asym_xform || !test_ops.prepare_asym_op) 1875 return -EINVAL; 1876 1877 asym = env.op->asym; 1878 ret = test_ops.prepare_asym_xform(&xform); 1879 if (ret < 0) 1880 return ret; 1881 1882 ret = rte_cryptodev_asym_session_create(env.dev_id, &xform, env.asym.sess_mpool, 1883 (void *)&env.asym.sess); 1884 if (ret < 0) 1885 return ret; 1886 1887 ret = test_ops.prepare_asym_op(); 1888 if (ret < 0) { 1889 RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", ret); 1890 goto exit; 1891 } 1892 1893 if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 1894 RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 1895 ret = -1; 1896 goto exit; 1897 } 1898 1899 while (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0) 1900 rte_pause(); 1901 1902 vec.status = env.op->status; 1903 1904 exit: 1905 if (env.asym.sess) 1906 rte_cryptodev_asym_session_free(env.dev_id, env.asym.sess); 1907 1908 env.asym.sess = NULL; 1909 return ret; 1910 } 1911 1912 static int 1913 fips_run_test(void) 1914 { 1915 int ret; 1916 1917 env.op = NULL; 1918 if (!env.is_asym_test) { 1919 env.op = env.sym.op; 1920 return fips_run_sym_test(); 1921 } 1922 1923 if (info.op == FIPS_TEST_ASYM_KEYGEN) { 1924 if (info.algo == FIPS_TEST_ALGO_ECDSA) { 1925 test_ops.prepare_asym_xform = prepare_ecfpm_xform; 1926 test_ops.prepare_asym_op = prepare_ecfpm_op; 1927 info.interim_info.ecdsa_data.pubkey_gen = 0; 1928 1929 } else if (info.algo == FIPS_TEST_ALGO_EDDSA) { 1930 test_ops.prepare_asym_xform = prepare_edfpm_xform; 1931 test_ops.prepare_asym_op = prepare_edfpm_op; 1932 info.interim_info.eddsa_data.pubkey_gen = 0; 1933 } 1934 1935 env.op = env.asym.op; 1936 return fips_run_asym_test(); 1937 } 1938 1939 if (info.algo == FIPS_TEST_ALGO_ECDSA) { 1940 vec.cipher_auth.digest.len = 1941 parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth); 1942 test_ops.prepare_sym_xform = prepare_sha_xform; 1943 test_ops.prepare_sym_op = prepare_auth_op; 1944 1945 env.op = env.sym.op; 1946 ret = fips_run_sym_test(); 1947 if (ret < 0) 1948 return ret; 1949 } 1950 1951 env.op = env.asym.op; 1952 if (info.op == FIPS_TEST_ASYM_SIGGEN) { 1953 fips_prepare_asym_xform_t old_xform; 1954 fips_prepare_op_t old_op; 1955 1956 old_xform = test_ops.prepare_asym_xform; 1957 old_op = test_ops.prepare_asym_op; 1958 1959 if (info.algo == FIPS_TEST_ALGO_ECDSA && 1960 info.interim_info.ecdsa_data.pubkey_gen == 1) { 1961 info.op = FIPS_TEST_ASYM_KEYGEN; 1962 test_ops.prepare_asym_xform = prepare_ecfpm_xform; 1963 test_ops.prepare_asym_op = prepare_ecfpm_op; 1964 1965 ret = fips_run_asym_test(); 1966 if (ret < 0) 1967 return ret; 1968 1969 info.post_interim_writeback(NULL); 1970 info.interim_info.ecdsa_data.pubkey_gen = 0; 1971 1972 } else if (info.algo == FIPS_TEST_ALGO_EDDSA && 1973 info.interim_info.eddsa_data.pubkey_gen == 1) { 1974 info.op = FIPS_TEST_ASYM_KEYGEN; 1975 test_ops.prepare_asym_xform = prepare_edfpm_xform; 1976 test_ops.prepare_asym_op = prepare_edfpm_op; 1977 1978 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1979 struct rte_cryptodev_asym_capability_idx cap_idx; 1980 1981 cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA; 1982 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1983 if (!cap) { 1984 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1985 env.dev_id); 1986 return -EINVAL; 1987 } 1988 1989 if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) { 1990 ret = fips_run_asym_test(); 1991 if (ret < 0) 1992 return ret; 1993 } else { 1994 /* Below is only a workaround by using known keys. */ 1995 struct rte_crypto_asym_xform xform = {0}; 1996 1997 prepare_edfpm_xform(&xform); 1998 prepare_edfpm_op(); 1999 uint8_t pkey25519[] = { 2000 0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d, 2001 0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e, 2002 0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b, 2003 0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42 2004 }; 2005 uint8_t q25519[] = { 2006 0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b, 2007 0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34, 2008 0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64, 2009 0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf 2010 }; 2011 uint8_t pkey448[] = { 2012 0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08, 2013 0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d, 2014 0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5, 2015 0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf, 2016 0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f, 2017 0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa, 2018 0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f, 2019 0x01 2020 }; 2021 uint8_t q448[] = { 2022 0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80, 2023 0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a, 2024 0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd, 2025 0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a, 2026 0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd, 2027 0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5, 2028 0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f, 2029 0x00 2030 }; 2031 if (info.interim_info.eddsa_data.curve_id == 2032 RTE_CRYPTO_EC_GROUP_ED25519) { 2033 memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519)); 2034 vec.eddsa.pkey.len = 32; 2035 memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519)); 2036 vec.eddsa.q.len = 32; 2037 } else { 2038 memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448)); 2039 vec.eddsa.pkey.len = 32; 2040 memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448)); 2041 vec.eddsa.q.len = 32; 2042 } 2043 } 2044 info.post_interim_writeback(NULL); 2045 info.interim_info.eddsa_data.pubkey_gen = 0; 2046 2047 } 2048 2049 test_ops.prepare_asym_xform = old_xform; 2050 test_ops.prepare_asym_op = old_op; 2051 info.op = FIPS_TEST_ASYM_SIGGEN; 2052 ret = fips_run_asym_test(); 2053 } else { 2054 ret = fips_run_asym_test(); 2055 } 2056 2057 return ret; 2058 } 2059 2060 static int 2061 fips_generic_test(void) 2062 { 2063 struct fips_val val = {NULL, 0}; 2064 int ret; 2065 2066 if (info.file_type != FIPS_TYPE_JSON) 2067 fips_test_write_one_case(); 2068 2069 ret = fips_run_test(); 2070 if (ret < 0) { 2071 if (ret == -EPERM || ret == -ENOTSUP) { 2072 if (info.file_type == FIPS_TYPE_JSON) 2073 return ret; 2074 2075 fprintf(info.fp_wr, "Bypass\n\n"); 2076 return 0; 2077 } 2078 2079 return ret; 2080 } 2081 2082 if (!env.is_asym_test) { 2083 ret = get_writeback_data(&val); 2084 if (ret < 0) 2085 return ret; 2086 } 2087 2088 switch (info.file_type) { 2089 case FIPS_TYPE_REQ: 2090 case FIPS_TYPE_RSP: 2091 case FIPS_TYPE_JSON: 2092 if (info.parse_writeback == NULL) 2093 return -EPERM; 2094 ret = info.parse_writeback(&val); 2095 if (ret < 0) 2096 return ret; 2097 break; 2098 case FIPS_TYPE_FAX: 2099 if (info.kat_check == NULL) 2100 return -EPERM; 2101 ret = info.kat_check(&val); 2102 if (ret < 0) 2103 return ret; 2104 break; 2105 default: 2106 break; 2107 } 2108 2109 if (info.file_type != FIPS_TYPE_JSON) 2110 fprintf(info.fp_wr, "\n"); 2111 rte_free(val.val); 2112 2113 return 0; 2114 } 2115 2116 static int 2117 fips_mct_tdes_test(void) 2118 { 2119 #define TDES_BLOCK_SIZE 8 2120 #define TDES_EXTERN_ITER 400 2121 #define TDES_INTERN_ITER 10000 2122 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 2123 uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; 2124 uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; 2125 uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; 2126 uint32_t i, j, k; 2127 int ret; 2128 int test_mode = info.interim_info.tdes_data.test_mode; 2129 2130 pt.len = vec.pt.len; 2131 pt.val = rte_malloc(NULL, pt.len, 0); 2132 ct.len = vec.ct.len; 2133 ct.val = rte_malloc(NULL, ct.len, 0); 2134 iv.len = vec.iv.len; 2135 iv.val = rte_malloc(NULL, iv.len, 0); 2136 2137 for (i = 0; i < TDES_EXTERN_ITER; i++) { 2138 if (info.file_type != FIPS_TYPE_JSON) { 2139 if ((i == 0) && (info.version == 21.4f)) { 2140 if (!(strstr(info.vec[0], "COUNT"))) 2141 fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0); 2142 } 2143 2144 if (i != 0) 2145 update_info_vec(i); 2146 2147 fips_test_write_one_case(); 2148 } 2149 2150 for (j = 0; j < TDES_INTERN_ITER; j++) { 2151 ret = fips_run_test(); 2152 if (ret < 0) { 2153 if (ret == -EPERM) { 2154 if (info.file_type == FIPS_TYPE_JSON) 2155 return ret; 2156 2157 fprintf(info.fp_wr, "Bypass\n"); 2158 return 0; 2159 } 2160 return ret; 2161 } 2162 2163 ret = get_writeback_data(&val[0]); 2164 if (ret < 0) 2165 return ret; 2166 2167 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 2168 memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 2169 2170 if (j == 0) { 2171 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 2172 memcpy(pt.val, vec.pt.val, pt.len); 2173 memcpy(ct.val, vec.ct.val, ct.len); 2174 memcpy(iv.val, vec.iv.val, iv.len); 2175 2176 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2177 if (test_mode == TDES_MODE_ECB) { 2178 memcpy(vec.pt.val, val[0].val, 2179 TDES_BLOCK_SIZE); 2180 } else { 2181 memcpy(vec.pt.val, vec.iv.val, 2182 TDES_BLOCK_SIZE); 2183 memcpy(vec.iv.val, val[0].val, 2184 TDES_BLOCK_SIZE); 2185 } 2186 val[1].val = pt.val; 2187 val[1].len = pt.len; 2188 val[2].val = iv.val; 2189 val[2].len = iv.len; 2190 } else { 2191 if (test_mode == TDES_MODE_ECB) { 2192 memcpy(vec.ct.val, val[0].val, 2193 TDES_BLOCK_SIZE); 2194 } else { 2195 memcpy(vec.iv.val, vec.ct.val, 2196 TDES_BLOCK_SIZE); 2197 memcpy(vec.ct.val, val[0].val, 2198 TDES_BLOCK_SIZE); 2199 } 2200 val[1].val = ct.val; 2201 val[1].len = ct.len; 2202 val[2].val = iv.val; 2203 val[2].len = iv.len; 2204 } 2205 continue; 2206 } 2207 2208 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2209 if (test_mode == TDES_MODE_ECB) { 2210 memcpy(vec.pt.val, val[0].val, 2211 TDES_BLOCK_SIZE); 2212 } else { 2213 memcpy(vec.iv.val, val[0].val, 2214 TDES_BLOCK_SIZE); 2215 memcpy(vec.pt.val, prev_out, 2216 TDES_BLOCK_SIZE); 2217 } 2218 } else { 2219 if (test_mode == TDES_MODE_ECB) { 2220 memcpy(vec.ct.val, val[0].val, 2221 TDES_BLOCK_SIZE); 2222 } else { 2223 memcpy(vec.iv.val, vec.ct.val, 2224 TDES_BLOCK_SIZE); 2225 memcpy(vec.ct.val, val[0].val, 2226 TDES_BLOCK_SIZE); 2227 } 2228 } 2229 2230 if (j == TDES_INTERN_ITER - 1) 2231 continue; 2232 2233 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 2234 2235 if (j == TDES_INTERN_ITER - 3) 2236 memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE); 2237 } 2238 2239 info.parse_writeback(val); 2240 if (info.file_type != FIPS_TYPE_JSON) 2241 fprintf(info.fp_wr, "\n"); 2242 2243 if (i == TDES_EXTERN_ITER - 1) 2244 continue; 2245 2246 /** update key */ 2247 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2248 2249 if (info.interim_info.tdes_data.nb_keys == 0) { 2250 if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 2251 info.interim_info.tdes_data.nb_keys = 1; 2252 else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 2253 info.interim_info.tdes_data.nb_keys = 2; 2254 else 2255 info.interim_info.tdes_data.nb_keys = 3; 2256 2257 } 2258 2259 for (k = 0; k < TDES_BLOCK_SIZE; k++) { 2260 2261 switch (info.interim_info.tdes_data.nb_keys) { 2262 case 3: 2263 val_key.val[k] ^= val[0].val[k]; 2264 val_key.val[k + 8] ^= prev_out[k]; 2265 val_key.val[k + 16] ^= prev_prev_out[k]; 2266 break; 2267 case 2: 2268 val_key.val[k] ^= val[0].val[k]; 2269 val_key.val[k + 8] ^= prev_out[k]; 2270 val_key.val[k + 16] ^= val[0].val[k]; 2271 break; 2272 default: /* case 1 */ 2273 val_key.val[k] ^= val[0].val[k]; 2274 val_key.val[k + 8] ^= val[0].val[k]; 2275 val_key.val[k + 16] ^= val[0].val[k]; 2276 break; 2277 } 2278 2279 } 2280 2281 for (k = 0; k < 24; k++) 2282 val_key.val[k] = (rte_popcount32(val_key.val[k]) & 2283 0x1) ? 2284 val_key.val[k] : (val_key.val[k] ^ 0x1); 2285 2286 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2287 if (test_mode == TDES_MODE_ECB) { 2288 memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE); 2289 } else { 2290 memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE); 2291 memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 2292 } 2293 } else { 2294 if (test_mode == TDES_MODE_ECB) { 2295 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 2296 } else { 2297 memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 2298 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 2299 } 2300 } 2301 } 2302 2303 rte_free(val[0].val); 2304 rte_free(pt.val); 2305 rte_free(ct.val); 2306 rte_free(iv.val); 2307 2308 return 0; 2309 } 2310 2311 static int 2312 fips_mct_aes_ecb_test(void) 2313 { 2314 #define AES_BLOCK_SIZE 16 2315 #define AES_EXTERN_ITER 100 2316 #define AES_INTERN_ITER 1000 2317 struct fips_val val = {NULL, 0}, val_key; 2318 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 2319 uint32_t i, j, k; 2320 int ret; 2321 2322 for (i = 0; i < AES_EXTERN_ITER; i++) { 2323 if (i != 0) 2324 update_info_vec(i); 2325 2326 fips_test_write_one_case(); 2327 2328 for (j = 0; j < AES_INTERN_ITER; j++) { 2329 ret = fips_run_test(); 2330 if (ret < 0) { 2331 if (ret == -EPERM) { 2332 if (info.file_type == FIPS_TYPE_JSON) 2333 return ret; 2334 2335 fprintf(info.fp_wr, "Bypass\n"); 2336 return 0; 2337 } 2338 2339 return ret; 2340 } 2341 2342 ret = get_writeback_data(&val); 2343 if (ret < 0) 2344 return ret; 2345 2346 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 2347 memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); 2348 else 2349 memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); 2350 2351 if (j == AES_INTERN_ITER - 1) 2352 continue; 2353 2354 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 2355 } 2356 2357 info.parse_writeback(&val); 2358 fprintf(info.fp_wr, "\n"); 2359 2360 if (i == AES_EXTERN_ITER - 1) 2361 continue; 2362 2363 /** update key */ 2364 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2365 for (k = 0; k < vec.cipher_auth.key.len; k++) { 2366 switch (vec.cipher_auth.key.len) { 2367 case 16: 2368 val_key.val[k] ^= val.val[k]; 2369 break; 2370 case 24: 2371 if (k < 8) 2372 val_key.val[k] ^= prev_out[k + 8]; 2373 else 2374 val_key.val[k] ^= val.val[k - 8]; 2375 break; 2376 case 32: 2377 if (k < 16) 2378 val_key.val[k] ^= prev_out[k]; 2379 else 2380 val_key.val[k] ^= val.val[k - 16]; 2381 break; 2382 default: 2383 return -1; 2384 } 2385 } 2386 } 2387 2388 rte_free(val.val); 2389 2390 return 0; 2391 } 2392 static int 2393 fips_mct_aes_test(void) 2394 { 2395 #define AES_BLOCK_SIZE 16 2396 #define AES_EXTERN_ITER 100 2397 #define AES_INTERN_ITER 1000 2398 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 2399 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 2400 uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 2401 uint32_t i, j, k; 2402 int ret; 2403 2404 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) 2405 return fips_mct_aes_ecb_test(); 2406 2407 pt.len = vec.pt.len; 2408 pt.val = rte_malloc(NULL, pt.len, 0); 2409 ct.len = vec.ct.len; 2410 ct.val = rte_malloc(NULL, ct.len, 0); 2411 iv.len = vec.iv.len; 2412 iv.val = rte_malloc(NULL, iv.len, 0); 2413 for (i = 0; i < AES_EXTERN_ITER; i++) { 2414 if (info.file_type != FIPS_TYPE_JSON) { 2415 if (i != 0) 2416 update_info_vec(i); 2417 2418 fips_test_write_one_case(); 2419 } 2420 2421 for (j = 0; j < AES_INTERN_ITER; j++) { 2422 ret = fips_run_test(); 2423 if (ret < 0) { 2424 if (ret == -EPERM) { 2425 if (info.file_type == FIPS_TYPE_JSON) 2426 return ret; 2427 2428 fprintf(info.fp_wr, "Bypass\n"); 2429 return 0; 2430 } 2431 2432 return ret; 2433 } 2434 2435 ret = get_writeback_data(&val[0]); 2436 if (ret < 0) 2437 return ret; 2438 2439 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 2440 memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 2441 2442 if (j == 0) { 2443 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 2444 memcpy(pt.val, vec.pt.val, pt.len); 2445 memcpy(ct.val, vec.ct.val, ct.len); 2446 memcpy(iv.val, vec.iv.val, iv.len); 2447 2448 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2449 memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE); 2450 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2451 val[1].val = pt.val; 2452 val[1].len = pt.len; 2453 val[2].val = iv.val; 2454 val[2].len = iv.len; 2455 } else { 2456 memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE); 2457 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 2458 val[1].val = ct.val; 2459 val[1].len = ct.len; 2460 val[2].val = iv.val; 2461 val[2].len = iv.len; 2462 } 2463 continue; 2464 } 2465 2466 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2467 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2468 memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 2469 } else { 2470 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 2471 memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 2472 } 2473 2474 if (j == AES_INTERN_ITER - 1) 2475 continue; 2476 2477 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 2478 } 2479 2480 info.parse_writeback(val); 2481 if (info.file_type != FIPS_TYPE_JSON) 2482 fprintf(info.fp_wr, "\n"); 2483 2484 if (i == AES_EXTERN_ITER - 1) 2485 continue; 2486 2487 /** update key */ 2488 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2489 for (k = 0; k < vec.cipher_auth.key.len; k++) { 2490 switch (vec.cipher_auth.key.len) { 2491 case 16: 2492 val_key.val[k] ^= val[0].val[k]; 2493 break; 2494 case 24: 2495 if (k < 8) 2496 val_key.val[k] ^= prev_out[k + 8]; 2497 else 2498 val_key.val[k] ^= val[0].val[k - 8]; 2499 break; 2500 case 32: 2501 if (k < 16) 2502 val_key.val[k] ^= prev_out[k]; 2503 else 2504 val_key.val[k] ^= val[0].val[k - 16]; 2505 break; 2506 default: 2507 return -1; 2508 } 2509 } 2510 2511 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 2512 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2513 } 2514 2515 rte_free(val[0].val); 2516 rte_free(pt.val); 2517 rte_free(ct.val); 2518 rte_free(iv.val); 2519 2520 return 0; 2521 } 2522 2523 static int 2524 fips_mct_sha_test(void) 2525 { 2526 #define SHA_EXTERN_ITER 100 2527 #define SHA_INTERN_ITER 1000 2528 uint8_t md_blocks = info.interim_info.sha_data.md_blocks; 2529 struct fips_val val = {NULL, 0}; 2530 struct fips_val md[md_blocks]; 2531 int ret; 2532 uint32_t i, j, k, offset, max_outlen; 2533 2534 max_outlen = md_blocks * vec.cipher_auth.digest.len; 2535 2536 rte_free(vec.cipher_auth.digest.val); 2537 vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0); 2538 2539 if (vec.pt.val) 2540 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len); 2541 2542 rte_free(vec.pt.val); 2543 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*md_blocks), 0); 2544 2545 for (i = 0; i < md_blocks; i++) 2546 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 2547 2548 if (info.file_type != FIPS_TYPE_JSON) { 2549 fips_test_write_one_case(); 2550 fprintf(info.fp_wr, "\n"); 2551 } 2552 2553 for (j = 0; j < SHA_EXTERN_ITER; j++) { 2554 for (i = 0; i < md_blocks; i++) { 2555 memcpy(md[i].val, vec.cipher_auth.digest.val, 2556 vec.cipher_auth.digest.len); 2557 md[i].len = vec.cipher_auth.digest.len; 2558 } 2559 2560 for (i = 0; i < (SHA_INTERN_ITER); i++) { 2561 offset = 0; 2562 for (k = 0; k < md_blocks; k++) { 2563 memcpy(vec.pt.val + offset, md[k].val, (size_t)md[k].len); 2564 offset += md[k].len; 2565 } 2566 vec.pt.len = offset; 2567 2568 ret = fips_run_test(); 2569 if (ret < 0) { 2570 if (ret == -EPERM || ret == -ENOTSUP) { 2571 if (info.file_type == FIPS_TYPE_JSON) 2572 return ret; 2573 2574 fprintf(info.fp_wr, "Bypass\n\n"); 2575 return 0; 2576 } 2577 return ret; 2578 } 2579 2580 ret = get_writeback_data(&val); 2581 if (ret < 0) 2582 return ret; 2583 2584 for (k = 1; k < md_blocks; k++) { 2585 memcpy(md[k-1].val, md[k].val, md[k].len); 2586 md[k-1].len = md[k].len; 2587 } 2588 2589 memcpy(md[md_blocks-1].val, (val.val + vec.pt.len), 2590 vec.cipher_auth.digest.len); 2591 md[md_blocks-1].len = vec.cipher_auth.digest.len; 2592 } 2593 2594 memcpy(vec.cipher_auth.digest.val, md[md_blocks-1].val, md[md_blocks-1].len); 2595 vec.cipher_auth.digest.len = md[md_blocks-1].len; 2596 2597 if (info.file_type != FIPS_TYPE_JSON) 2598 fprintf(info.fp_wr, "COUNT = %u\n", j); 2599 2600 info.parse_writeback(&val); 2601 2602 if (info.file_type != FIPS_TYPE_JSON) 2603 fprintf(info.fp_wr, "\n"); 2604 } 2605 2606 for (i = 0; i < (md_blocks); i++) 2607 rte_free(md[i].val); 2608 2609 rte_free(vec.pt.val); 2610 2611 rte_free(val.val); 2612 return 0; 2613 } 2614 2615 static int 2616 fips_mct_shake_test(void) 2617 { 2618 #define SHAKE_EXTERN_ITER 100 2619 #define SHAKE_INTERN_ITER 1000 2620 uint32_t i, j, range, outlen, max_outlen; 2621 struct fips_val val = {NULL, 0}, md; 2622 uint8_t rightmost[2]; 2623 uint16_t *rightptr; 2624 int ret; 2625 2626 max_outlen = vec.cipher_auth.digest.len; 2627 2628 rte_free(vec.cipher_auth.digest.val); 2629 vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0); 2630 2631 if (vec.pt.val) 2632 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.pt.len); 2633 2634 rte_free(vec.pt.val); 2635 vec.pt.val = rte_malloc(NULL, 16, 0); 2636 vec.pt.len = 16; 2637 2638 md.val = rte_malloc(NULL, max_outlen, 0); 2639 md.len = max_outlen; 2640 2641 if (info.file_type != FIPS_TYPE_JSON) { 2642 fips_test_write_one_case(); 2643 fprintf(info.fp_wr, "\n"); 2644 } 2645 2646 range = max_outlen - info.interim_info.sha_data.min_outlen + 1; 2647 outlen = max_outlen; 2648 for (j = 0; j < SHAKE_EXTERN_ITER; j++) { 2649 memset(md.val, 0, max_outlen); 2650 memcpy(md.val, vec.cipher_auth.digest.val, 2651 vec.cipher_auth.digest.len); 2652 2653 for (i = 0; i < (SHAKE_INTERN_ITER); i++) { 2654 memset(vec.pt.val, 0, vec.pt.len); 2655 memcpy(vec.pt.val, md.val, vec.pt.len); 2656 vec.cipher_auth.digest.len = outlen; 2657 ret = fips_run_test(); 2658 if (ret < 0) { 2659 if (ret == -EPERM || ret == -ENOTSUP) { 2660 if (info.file_type == FIPS_TYPE_JSON) 2661 return ret; 2662 2663 fprintf(info.fp_wr, "Bypass\n\n"); 2664 return 0; 2665 } 2666 return ret; 2667 } 2668 2669 ret = get_writeback_data(&val); 2670 if (ret < 0) 2671 return ret; 2672 2673 memset(md.val, 0, max_outlen); 2674 memcpy(md.val, (val.val + vec.pt.len), 2675 vec.cipher_auth.digest.len); 2676 md.len = outlen; 2677 rightmost[0] = md.val[md.len-1]; 2678 rightmost[1] = md.val[md.len-2]; 2679 rightptr = (uint16_t *)rightmost; 2680 outlen = info.interim_info.sha_data.min_outlen + 2681 (*rightptr % range); 2682 } 2683 2684 memcpy(vec.cipher_auth.digest.val, md.val, md.len); 2685 vec.cipher_auth.digest.len = md.len; 2686 2687 if (info.file_type != FIPS_TYPE_JSON) 2688 fprintf(info.fp_wr, "COUNT = %u\n", j); 2689 2690 info.parse_writeback(&val); 2691 2692 if (info.file_type != FIPS_TYPE_JSON) 2693 fprintf(info.fp_wr, "\n"); 2694 } 2695 2696 rte_free(md.val); 2697 rte_free(vec.pt.val); 2698 rte_free(val.val); 2699 return 0; 2700 } 2701 2702 static int 2703 init_test_ops(void) 2704 { 2705 switch (info.algo) { 2706 case FIPS_TEST_ALGO_AES_CBC: 2707 case FIPS_TEST_ALGO_AES_CTR: 2708 case FIPS_TEST_ALGO_AES: 2709 test_ops.prepare_sym_op = prepare_cipher_op; 2710 test_ops.prepare_sym_xform = prepare_aes_xform; 2711 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 2712 test_ops.test = fips_mct_aes_test; 2713 else 2714 test_ops.test = fips_generic_test; 2715 break; 2716 case FIPS_TEST_ALGO_HMAC: 2717 test_ops.prepare_sym_op = prepare_auth_op; 2718 test_ops.prepare_sym_xform = prepare_hmac_xform; 2719 test_ops.test = fips_generic_test; 2720 break; 2721 case FIPS_TEST_ALGO_TDES: 2722 test_ops.prepare_sym_op = prepare_cipher_op; 2723 test_ops.prepare_sym_xform = prepare_tdes_xform; 2724 if (info.interim_info.tdes_data.test_type == TDES_MCT) 2725 test_ops.test = fips_mct_tdes_test; 2726 else 2727 test_ops.test = fips_generic_test; 2728 break; 2729 case FIPS_TEST_ALGO_AES_GMAC: 2730 test_ops.prepare_sym_op = prepare_auth_op; 2731 test_ops.prepare_sym_xform = prepare_gmac_xform; 2732 test_ops.test = fips_generic_test; 2733 break; 2734 case FIPS_TEST_ALGO_AES_GCM: 2735 test_ops.prepare_sym_op = prepare_aead_op; 2736 test_ops.prepare_sym_xform = prepare_gcm_xform; 2737 test_ops.test = fips_generic_test; 2738 break; 2739 case FIPS_TEST_ALGO_AES_CMAC: 2740 test_ops.prepare_sym_op = prepare_auth_op; 2741 test_ops.prepare_sym_xform = prepare_cmac_xform; 2742 test_ops.test = fips_generic_test; 2743 break; 2744 case FIPS_TEST_ALGO_AES_CCM: 2745 test_ops.prepare_sym_op = prepare_aead_op; 2746 test_ops.prepare_sym_xform = prepare_ccm_xform; 2747 test_ops.test = fips_generic_test; 2748 break; 2749 case FIPS_TEST_ALGO_SHA: 2750 test_ops.prepare_sym_op = prepare_auth_op; 2751 test_ops.prepare_sym_xform = prepare_sha_xform; 2752 if (info.interim_info.sha_data.test_type == SHA_MCT) 2753 if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 || 2754 info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256) 2755 test_ops.test = fips_mct_shake_test; 2756 else 2757 test_ops.test = fips_mct_sha_test; 2758 else 2759 test_ops.test = fips_generic_test; 2760 break; 2761 case FIPS_TEST_ALGO_AES_XTS: 2762 test_ops.prepare_sym_op = prepare_cipher_op; 2763 test_ops.prepare_sym_xform = prepare_xts_xform; 2764 test_ops.test = fips_generic_test; 2765 break; 2766 case FIPS_TEST_ALGO_RSA: 2767 test_ops.prepare_asym_op = prepare_rsa_op; 2768 test_ops.prepare_asym_xform = prepare_rsa_xform; 2769 test_ops.test = fips_generic_test; 2770 break; 2771 case FIPS_TEST_ALGO_ECDSA: 2772 if (info.op == FIPS_TEST_ASYM_KEYGEN) { 2773 test_ops.prepare_asym_op = prepare_ecfpm_op; 2774 test_ops.prepare_asym_xform = prepare_ecfpm_xform; 2775 test_ops.test = fips_generic_test; 2776 } else { 2777 test_ops.prepare_asym_op = prepare_ecdsa_op; 2778 test_ops.prepare_asym_xform = prepare_ecdsa_xform; 2779 test_ops.test = fips_generic_test; 2780 } 2781 break; 2782 case FIPS_TEST_ALGO_EDDSA: 2783 if (info.op == FIPS_TEST_ASYM_KEYGEN) { 2784 test_ops.prepare_asym_op = prepare_edfpm_op; 2785 test_ops.prepare_asym_xform = prepare_edfpm_xform; 2786 test_ops.test = fips_generic_test; 2787 } else { 2788 test_ops.prepare_asym_op = prepare_eddsa_op; 2789 test_ops.prepare_asym_xform = prepare_eddsa_xform; 2790 test_ops.test = fips_generic_test; 2791 } 2792 break; 2793 default: 2794 if (strstr(info.file_name, "TECB") || 2795 strstr(info.file_name, "TCBC")) { 2796 info.algo = FIPS_TEST_ALGO_TDES; 2797 test_ops.prepare_sym_op = prepare_cipher_op; 2798 test_ops.prepare_sym_xform = prepare_tdes_xform; 2799 if (info.interim_info.tdes_data.test_type == TDES_MCT) 2800 test_ops.test = fips_mct_tdes_test; 2801 else 2802 test_ops.test = fips_generic_test; 2803 break; 2804 } 2805 return -1; 2806 } 2807 2808 return 0; 2809 } 2810 2811 static void 2812 print_test_block(void) 2813 { 2814 uint32_t i; 2815 2816 for (i = 0; i < info.nb_vec_lines; i++) 2817 printf("%s\n", info.vec[i]); 2818 2819 printf("\n"); 2820 } 2821 2822 static int 2823 fips_test_one_file(void) 2824 { 2825 int fetch_ret = 0, ret; 2826 2827 ret = init_test_ops(); 2828 if (ret < 0) { 2829 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 2830 return ret; 2831 } 2832 2833 while (ret >= 0 && fetch_ret == 0) { 2834 fetch_ret = fips_test_fetch_one_block(); 2835 if (fetch_ret < 0) { 2836 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 2837 fetch_ret); 2838 ret = fetch_ret; 2839 goto error_one_case; 2840 } 2841 2842 if (info.nb_vec_lines == 0) { 2843 if (fetch_ret == -EOF) 2844 break; 2845 2846 fprintf(info.fp_wr, "\n"); 2847 continue; 2848 } 2849 2850 ret = fips_test_parse_one_case(); 2851 switch (ret) { 2852 case 0: 2853 ret = test_ops.test(); 2854 if (ret == 0) 2855 break; 2856 RTE_LOG(ERR, USER1, "Error %i: test block\n", 2857 ret); 2858 goto error_one_case; 2859 case 1: 2860 break; 2861 default: 2862 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 2863 ret); 2864 goto error_one_case; 2865 } 2866 2867 continue; 2868 error_one_case: 2869 print_test_block(); 2870 } 2871 2872 fips_test_clear(); 2873 2874 if (env.digest) { 2875 rte_free(env.digest); 2876 env.digest = NULL; 2877 env.digest_len = 0; 2878 } 2879 rte_pktmbuf_free(env.mbuf); 2880 2881 return ret; 2882 } 2883 2884 #ifdef USE_JANSSON 2885 static int 2886 fips_test_json_init_writeback(void) 2887 { 2888 json_t *session_info, *session_write; 2889 session_info = json_array_get(json_info.json_root, 0); 2890 session_write = json_object(); 2891 json_info.json_write_root = json_array(); 2892 2893 json_object_set(session_write, "jwt", 2894 json_object_get(session_info, "jwt")); 2895 json_object_set(session_write, "url", 2896 json_object_get(session_info, "url")); 2897 json_object_set(session_write, "isSample", 2898 json_object_get(session_info, "isSample")); 2899 2900 json_info.is_sample = json_boolean_value( 2901 json_object_get(session_info, "isSample")); 2902 2903 json_array_append_new(json_info.json_write_root, session_write); 2904 return 0; 2905 } 2906 2907 static int 2908 fips_test_one_test_case(void) 2909 { 2910 int ret; 2911 2912 ret = fips_test_parse_one_json_case(); 2913 2914 switch (ret) { 2915 case 0: 2916 ret = test_ops.test(); 2917 if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP)) 2918 break; 2919 RTE_LOG(ERR, USER1, "Error %i: test block\n", 2920 ret); 2921 break; 2922 default: 2923 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 2924 ret); 2925 } 2926 return ret; 2927 } 2928 2929 static int 2930 fips_test_one_test_group(void) 2931 { 2932 int ret; 2933 json_t *tests, *write_tests; 2934 size_t test_idx, tests_size; 2935 2936 write_tests = json_array(); 2937 json_info.json_write_group = json_object(); 2938 json_object_set(json_info.json_write_group, "tgId", 2939 json_object_get(json_info.json_test_group, "tgId")); 2940 json_object_set_new(json_info.json_write_group, "tests", write_tests); 2941 2942 switch (info.algo) { 2943 case FIPS_TEST_ALGO_AES_GMAC: 2944 case FIPS_TEST_ALGO_AES_GCM: 2945 ret = parse_test_gcm_json_init(); 2946 break; 2947 case FIPS_TEST_ALGO_AES_CCM: 2948 ret = parse_test_ccm_json_init(); 2949 break; 2950 case FIPS_TEST_ALGO_HMAC: 2951 ret = parse_test_hmac_json_init(); 2952 break; 2953 case FIPS_TEST_ALGO_AES_CMAC: 2954 ret = parse_test_cmac_json_init(); 2955 break; 2956 case FIPS_TEST_ALGO_AES_XTS: 2957 ret = parse_test_xts_json_init(); 2958 break; 2959 case FIPS_TEST_ALGO_AES_CBC: 2960 case FIPS_TEST_ALGO_AES_CTR: 2961 case FIPS_TEST_ALGO_AES: 2962 ret = parse_test_aes_json_init(); 2963 break; 2964 case FIPS_TEST_ALGO_SHA: 2965 ret = parse_test_sha_json_init(); 2966 break; 2967 case FIPS_TEST_ALGO_TDES: 2968 ret = parse_test_tdes_json_init(); 2969 break; 2970 case FIPS_TEST_ALGO_RSA: 2971 ret = parse_test_rsa_json_init(); 2972 break; 2973 case FIPS_TEST_ALGO_ECDSA: 2974 ret = parse_test_ecdsa_json_init(); 2975 break; 2976 case FIPS_TEST_ALGO_EDDSA: 2977 ret = parse_test_eddsa_json_init(); 2978 break; 2979 default: 2980 return -EINVAL; 2981 } 2982 2983 if (ret < 0) 2984 return ret; 2985 2986 ret = fips_test_parse_one_json_group(); 2987 if (ret < 0) 2988 return ret; 2989 2990 ret = init_test_ops(); 2991 if (ret < 0) 2992 return ret; 2993 2994 tests = json_object_get(json_info.json_test_group, "tests"); 2995 tests_size = json_array_size(tests); 2996 for (test_idx = 0; test_idx < tests_size; test_idx++) { 2997 json_info.json_test_case = json_array_get(tests, test_idx); 2998 if (fips_test_one_test_case() == 0) 2999 json_array_append_new(write_tests, json_info.json_write_case); 3000 } 3001 3002 return 0; 3003 } 3004 3005 static int 3006 fips_test_one_vector_set(void) 3007 { 3008 int ret; 3009 json_t *test_groups, *write_groups, *write_version, *write_set, *mode; 3010 size_t group_idx, num_groups; 3011 3012 test_groups = json_object_get(json_info.json_vector_set, "testGroups"); 3013 num_groups = json_array_size(test_groups); 3014 3015 json_info.json_write_set = json_array(); 3016 write_version = json_object(); 3017 json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION)); 3018 json_array_append_new(json_info.json_write_set, write_version); 3019 3020 write_set = json_object(); 3021 json_array_append(json_info.json_write_set, write_set); 3022 write_groups = json_array(); 3023 3024 json_object_set(write_set, "vsId", 3025 json_object_get(json_info.json_vector_set, "vsId")); 3026 json_object_set(write_set, "algorithm", 3027 json_object_get(json_info.json_vector_set, "algorithm")); 3028 mode = json_object_get(json_info.json_vector_set, "mode"); 3029 if (mode != NULL) 3030 json_object_set_new(write_set, "mode", mode); 3031 3032 json_object_set(write_set, "revision", 3033 json_object_get(json_info.json_vector_set, "revision")); 3034 json_object_set_new(write_set, "isSample", 3035 json_boolean(json_info.is_sample)); 3036 json_object_set_new(write_set, "testGroups", write_groups); 3037 3038 ret = fips_test_parse_one_json_vector_set(); 3039 if (ret < 0) { 3040 RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n", 3041 json_string_value(json_object_get(json_info.json_vector_set, "algorithm"))); 3042 return ret; 3043 } 3044 3045 for (group_idx = 0; group_idx < num_groups; group_idx++) { 3046 json_info.json_test_group = json_array_get(test_groups, group_idx); 3047 ret = fips_test_one_test_group(); 3048 json_array_append_new(write_groups, json_info.json_write_group); 3049 } 3050 3051 return 0; 3052 } 3053 3054 static int 3055 fips_test_one_json_file(void) 3056 { 3057 size_t vector_set_idx, root_size; 3058 3059 root_size = json_array_size(json_info.json_root); 3060 fips_test_json_init_writeback(); 3061 3062 for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) { 3063 /* Vector set index starts at 1, the 0th index contains test session 3064 * information. 3065 */ 3066 json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx); 3067 fips_test_one_vector_set(); 3068 json_array_append_new(json_info.json_write_root, json_info.json_write_set); 3069 json_incref(json_info.json_write_set); 3070 } 3071 3072 json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4)); 3073 json_decref(json_info.json_write_root); 3074 3075 return 0; 3076 } 3077 #endif /* USE_JANSSON */ 3078