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.pkey.data = vec.ecdsa.pkey.val; 1010 asym->ecdsa.pkey.length = vec.ecdsa.pkey.len; 1011 asym->ecdsa.k.data = vec.ecdsa.k.val; 1012 asym->ecdsa.k.length = vec.ecdsa.k.len; 1013 1014 rte_free(vec.ecdsa.r.val); 1015 1016 rte_free(vec.ecdsa.s.val); 1017 1018 vec.ecdsa.r.len = info.interim_info.ecdsa_data.curve_len; 1019 vec.ecdsa.r.val = rte_zmalloc(NULL, vec.ecdsa.r.len, 0); 1020 1021 vec.ecdsa.s.len = vec.ecdsa.r.len; 1022 vec.ecdsa.s.val = rte_zmalloc(NULL, vec.ecdsa.s.len, 0); 1023 1024 asym->ecdsa.r.data = vec.ecdsa.r.val; 1025 asym->ecdsa.r.length = 0; 1026 asym->ecdsa.s.data = vec.ecdsa.s.val; 1027 asym->ecdsa.s.length = 0; 1028 } else if (info.op == FIPS_TEST_ASYM_SIGVER) { 1029 asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; 1030 asym->ecdsa.message.data = msg.val; 1031 asym->ecdsa.message.length = msg.len; 1032 asym->ecdsa.q.x.data = vec.ecdsa.qx.val; 1033 asym->ecdsa.q.x.length = vec.ecdsa.qx.len; 1034 asym->ecdsa.q.y.data = vec.ecdsa.qy.val; 1035 asym->ecdsa.q.y.length = vec.ecdsa.qy.len; 1036 asym->ecdsa.r.data = vec.ecdsa.r.val; 1037 asym->ecdsa.r.length = vec.ecdsa.r.len; 1038 asym->ecdsa.s.data = vec.ecdsa.s.val; 1039 asym->ecdsa.s.length = vec.ecdsa.s.len; 1040 } else { 1041 RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op); 1042 return -EINVAL; 1043 } 1044 1045 rte_crypto_op_attach_asym_session(env.op, env.asym.sess); 1046 1047 return 0; 1048 } 1049 1050 static int 1051 prepare_ecfpm_op(void) 1052 { 1053 struct rte_crypto_asym_op *asym; 1054 1055 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); 1056 1057 asym = env.op->asym; 1058 asym->ecpm.scalar.data = vec.ecdsa.pkey.val; 1059 asym->ecpm.scalar.length = vec.ecdsa.pkey.len; 1060 1061 rte_free(vec.ecdsa.qx.val); 1062 1063 rte_free(vec.ecdsa.qy.val); 1064 1065 vec.ecdsa.qx.len = info.interim_info.ecdsa_data.curve_len; 1066 vec.ecdsa.qx.val = rte_zmalloc(NULL, vec.ecdsa.qx.len, 0); 1067 1068 vec.ecdsa.qy.len = vec.ecdsa.qx.len; 1069 vec.ecdsa.qy.val = rte_zmalloc(NULL, vec.ecdsa.qy.len, 0); 1070 1071 asym->ecpm.r.x.data = vec.ecdsa.qx.val; 1072 asym->ecpm.r.x.length = 0; 1073 asym->ecpm.r.y.data = vec.ecdsa.qy.val; 1074 asym->ecpm.r.y.length = 0; 1075 1076 rte_crypto_op_attach_asym_session(env.op, env.asym.sess); 1077 1078 return 0; 1079 } 1080 1081 static int 1082 prepare_aes_xform(struct rte_crypto_sym_xform *xform) 1083 { 1084 const struct rte_cryptodev_symmetric_capability *cap; 1085 struct rte_cryptodev_sym_capability_idx cap_idx; 1086 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1087 1088 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1089 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) 1090 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC; 1091 else if (info.interim_info.aes_data.cipher_algo == 1092 RTE_CRYPTO_CIPHER_AES_CTR) 1093 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR; 1094 else 1095 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB; 1096 1097 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1098 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1099 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1100 cipher_xform->key.data = vec.cipher_auth.key.val; 1101 cipher_xform->key.length = vec.cipher_auth.key.len; 1102 if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC || 1103 cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) { 1104 cipher_xform->iv.length = vec.iv.len; 1105 cipher_xform->iv.offset = IV_OFF; 1106 } else { 1107 cipher_xform->iv.length = 0; 1108 cipher_xform->iv.offset = 0; 1109 } 1110 cap_idx.algo.cipher = cipher_xform->algo; 1111 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1112 1113 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1114 if (!cap) { 1115 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1116 env.dev_id); 1117 return -EINVAL; 1118 } 1119 1120 if (rte_cryptodev_sym_capability_check_cipher(cap, 1121 cipher_xform->key.length, 1122 cipher_xform->iv.length) != 0) { 1123 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1124 info.device_name, cipher_xform->key.length, 1125 cipher_xform->iv.length); 1126 return -EPERM; 1127 } 1128 1129 return 0; 1130 } 1131 1132 static int 1133 prepare_tdes_xform(struct rte_crypto_sym_xform *xform) 1134 { 1135 const struct rte_cryptodev_symmetric_capability *cap; 1136 struct rte_cryptodev_sym_capability_idx cap_idx; 1137 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1138 1139 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1140 1141 if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC) 1142 cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC; 1143 else 1144 cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB; 1145 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1146 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1147 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1148 cipher_xform->key.data = vec.cipher_auth.key.val; 1149 cipher_xform->key.length = vec.cipher_auth.key.len; 1150 1151 if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) { 1152 cipher_xform->iv.length = vec.iv.len; 1153 cipher_xform->iv.offset = IV_OFF; 1154 } else { 1155 cipher_xform->iv.length = 0; 1156 cipher_xform->iv.offset = 0; 1157 } 1158 cap_idx.algo.cipher = cipher_xform->algo; 1159 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1160 1161 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1162 if (!cap) { 1163 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1164 env.dev_id); 1165 return -EINVAL; 1166 } 1167 1168 if (rte_cryptodev_sym_capability_check_cipher(cap, 1169 cipher_xform->key.length, 1170 cipher_xform->iv.length) != 0) { 1171 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1172 info.device_name, cipher_xform->key.length, 1173 cipher_xform->iv.length); 1174 return -EPERM; 1175 } 1176 1177 return 0; 1178 } 1179 1180 static int 1181 prepare_hmac_xform(struct rte_crypto_sym_xform *xform) 1182 { 1183 const struct rte_cryptodev_symmetric_capability *cap; 1184 struct rte_cryptodev_sym_capability_idx cap_idx; 1185 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1186 1187 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1188 1189 auth_xform->algo = info.interim_info.hmac_data.algo; 1190 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 1191 auth_xform->digest_length = vec.cipher_auth.digest.len; 1192 auth_xform->key.data = vec.cipher_auth.key.val; 1193 auth_xform->key.length = vec.cipher_auth.key.len; 1194 1195 cap_idx.algo.auth = auth_xform->algo; 1196 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1197 1198 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1199 if (!cap) { 1200 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1201 env.dev_id); 1202 return -EINVAL; 1203 } 1204 1205 if (rte_cryptodev_sym_capability_check_auth(cap, 1206 auth_xform->key.length, 1207 auth_xform->digest_length, 0) != 0) { 1208 RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n", 1209 info.device_name, auth_xform->key.length, 1210 auth_xform->digest_length); 1211 return -EPERM; 1212 } 1213 1214 return 0; 1215 } 1216 1217 int 1218 prepare_gcm_xform(struct rte_crypto_sym_xform *xform) 1219 { 1220 const struct rte_cryptodev_symmetric_capability *cap; 1221 struct rte_cryptodev_sym_capability_idx cap_idx; 1222 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 1223 1224 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 1225 1226 aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM; 1227 aead_xform->aad_length = vec.aead.aad.len; 1228 aead_xform->digest_length = vec.aead.digest.len; 1229 aead_xform->iv.offset = IV_OFF; 1230 aead_xform->iv.length = vec.iv.len; 1231 aead_xform->key.data = vec.aead.key.val; 1232 aead_xform->key.length = vec.aead.key.len; 1233 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1234 RTE_CRYPTO_AEAD_OP_ENCRYPT : 1235 RTE_CRYPTO_AEAD_OP_DECRYPT; 1236 1237 cap_idx.algo.aead = aead_xform->algo; 1238 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 1239 1240 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1241 if (!cap) { 1242 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1243 env.dev_id); 1244 return -EINVAL; 1245 } 1246 1247 if (rte_cryptodev_sym_capability_check_aead(cap, 1248 aead_xform->key.length, 1249 aead_xform->digest_length, aead_xform->aad_length, 1250 aead_xform->iv.length) != 0) { 1251 RTE_LOG(ERR, USER1, 1252 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 1253 info.device_name, aead_xform->key.length, 1254 aead_xform->digest_length, 1255 aead_xform->aad_length, 1256 aead_xform->iv.length); 1257 return -EPERM; 1258 } 1259 1260 return 0; 1261 } 1262 1263 int 1264 prepare_gmac_xform(struct rte_crypto_sym_xform *xform) 1265 { 1266 const struct rte_cryptodev_symmetric_capability *cap; 1267 struct rte_cryptodev_sym_capability_idx cap_idx; 1268 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1269 1270 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1271 1272 auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC; 1273 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1274 RTE_CRYPTO_AUTH_OP_GENERATE : 1275 RTE_CRYPTO_AUTH_OP_VERIFY; 1276 auth_xform->iv.offset = IV_OFF; 1277 auth_xform->iv.length = vec.iv.len; 1278 auth_xform->digest_length = vec.aead.digest.len; 1279 auth_xform->key.data = vec.aead.key.val; 1280 auth_xform->key.length = vec.aead.key.len; 1281 1282 cap_idx.algo.auth = auth_xform->algo; 1283 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1284 1285 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1286 if (!cap) { 1287 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1288 env.dev_id); 1289 return -EINVAL; 1290 } 1291 1292 if (rte_cryptodev_sym_capability_check_auth(cap, 1293 auth_xform->key.length, 1294 auth_xform->digest_length, 1295 auth_xform->iv.length) != 0) { 1296 1297 RTE_LOG(ERR, USER1, 1298 "PMD %s key length %u Digest length %u IV length %u\n", 1299 info.device_name, auth_xform->key.length, 1300 auth_xform->digest_length, 1301 auth_xform->iv.length); 1302 return -EPERM; 1303 } 1304 1305 return 0; 1306 } 1307 1308 static int 1309 prepare_cmac_xform(struct rte_crypto_sym_xform *xform) 1310 { 1311 const struct rte_cryptodev_symmetric_capability *cap; 1312 struct rte_cryptodev_sym_capability_idx cap_idx; 1313 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1314 1315 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1316 1317 auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC; 1318 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1319 RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY; 1320 auth_xform->digest_length = vec.cipher_auth.digest.len; 1321 auth_xform->key.data = vec.cipher_auth.key.val; 1322 auth_xform->key.length = vec.cipher_auth.key.len; 1323 1324 cap_idx.algo.auth = auth_xform->algo; 1325 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1326 1327 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1328 if (!cap) { 1329 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1330 env.dev_id); 1331 return -EINVAL; 1332 } 1333 1334 if (rte_cryptodev_sym_capability_check_auth(cap, 1335 auth_xform->key.length, 1336 auth_xform->digest_length, 0) != 0) { 1337 RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n", 1338 info.device_name, auth_xform->key.length, 1339 auth_xform->digest_length); 1340 return -EPERM; 1341 } 1342 1343 return 0; 1344 } 1345 1346 static int 1347 prepare_ccm_xform(struct rte_crypto_sym_xform *xform) 1348 { 1349 const struct rte_cryptodev_symmetric_capability *cap; 1350 struct rte_cryptodev_sym_capability_idx cap_idx; 1351 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 1352 1353 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 1354 1355 aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM; 1356 aead_xform->aad_length = vec.aead.aad.len; 1357 aead_xform->digest_length = vec.aead.digest.len; 1358 aead_xform->iv.offset = IV_OFF; 1359 aead_xform->iv.length = vec.iv.len; 1360 aead_xform->key.data = vec.aead.key.val; 1361 aead_xform->key.length = vec.aead.key.len; 1362 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1363 RTE_CRYPTO_AEAD_OP_ENCRYPT : 1364 RTE_CRYPTO_AEAD_OP_DECRYPT; 1365 1366 cap_idx.algo.aead = aead_xform->algo; 1367 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 1368 1369 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1370 if (!cap) { 1371 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1372 env.dev_id); 1373 return -EINVAL; 1374 } 1375 1376 if (rte_cryptodev_sym_capability_check_aead(cap, 1377 aead_xform->key.length, 1378 aead_xform->digest_length, aead_xform->aad_length, 1379 aead_xform->iv.length) != 0) { 1380 RTE_LOG(ERR, USER1, 1381 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 1382 info.device_name, aead_xform->key.length, 1383 aead_xform->digest_length, 1384 aead_xform->aad_length, 1385 aead_xform->iv.length); 1386 return -EPERM; 1387 } 1388 1389 return 0; 1390 } 1391 1392 static int 1393 prepare_sha_xform(struct rte_crypto_sym_xform *xform) 1394 { 1395 const struct rte_cryptodev_symmetric_capability *cap; 1396 struct rte_cryptodev_sym_capability_idx cap_idx; 1397 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1398 1399 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1400 1401 auth_xform->algo = info.interim_info.sha_data.algo; 1402 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 1403 auth_xform->digest_length = vec.cipher_auth.digest.len; 1404 1405 cap_idx.algo.auth = auth_xform->algo; 1406 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1407 1408 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1409 if (!cap) { 1410 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1411 env.dev_id); 1412 return -EINVAL; 1413 } 1414 1415 if (rte_cryptodev_sym_capability_check_auth(cap, 1416 auth_xform->key.length, 1417 auth_xform->digest_length, 0) != 0) { 1418 RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n", 1419 info.device_name, auth_xform->key.length, 1420 auth_xform->digest_length); 1421 return -EPERM; 1422 } 1423 1424 return 0; 1425 } 1426 1427 static int 1428 prepare_xts_xform(struct rte_crypto_sym_xform *xform) 1429 { 1430 const struct rte_cryptodev_symmetric_capability *cap; 1431 struct rte_cryptodev_sym_capability_idx cap_idx; 1432 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1433 1434 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1435 1436 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS; 1437 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1438 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1439 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1440 cipher_xform->key.data = vec.cipher_auth.key.val; 1441 cipher_xform->key.length = vec.cipher_auth.key.len; 1442 cipher_xform->iv.length = vec.iv.len; 1443 cipher_xform->iv.offset = IV_OFF; 1444 1445 cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS; 1446 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1447 1448 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1449 if (!cap) { 1450 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1451 env.dev_id); 1452 return -EINVAL; 1453 } 1454 1455 if (rte_cryptodev_sym_capability_check_cipher(cap, 1456 cipher_xform->key.length, 1457 cipher_xform->iv.length) != 0) { 1458 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1459 info.device_name, cipher_xform->key.length, 1460 cipher_xform->iv.length); 1461 return -EPERM; 1462 } 1463 1464 return 0; 1465 } 1466 1467 static int 1468 prepare_rsa_xform(struct rte_crypto_asym_xform *xform) 1469 { 1470 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1471 struct rte_cryptodev_asym_capability_idx cap_idx; 1472 struct rte_cryptodev_info dev_info; 1473 1474 xform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA; 1475 xform->next = NULL; 1476 1477 cap_idx.type = xform->xform_type; 1478 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1479 if (!cap) { 1480 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1481 env.dev_id); 1482 return -EINVAL; 1483 } 1484 1485 switch (info.op) { 1486 case FIPS_TEST_ASYM_SIGGEN: 1487 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1488 RTE_CRYPTO_ASYM_OP_SIGN)) { 1489 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1490 info.device_name, RTE_CRYPTO_ASYM_OP_SIGN); 1491 return -EPERM; 1492 } 1493 break; 1494 case FIPS_TEST_ASYM_SIGVER: 1495 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1496 RTE_CRYPTO_ASYM_OP_VERIFY)) { 1497 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1498 info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY); 1499 return -EPERM; 1500 } 1501 break; 1502 case FIPS_TEST_ASYM_KEYGEN: 1503 break; 1504 default: 1505 break; 1506 } 1507 1508 rte_cryptodev_info_get(env.dev_id, &dev_info); 1509 xform->rsa.key_type = info.interim_info.rsa_data.privkey; 1510 switch (xform->rsa.key_type) { 1511 case RTE_RSA_KEY_TYPE_QT: 1512 if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) { 1513 RTE_LOG(ERR, USER1, "PMD %s does not support QT key type\n", 1514 info.device_name); 1515 return -EPERM; 1516 } 1517 xform->rsa.qt.p.data = vec.rsa.p.val; 1518 xform->rsa.qt.p.length = vec.rsa.p.len; 1519 xform->rsa.qt.q.data = vec.rsa.q.val; 1520 xform->rsa.qt.q.length = vec.rsa.q.len; 1521 xform->rsa.qt.dP.data = vec.rsa.dp.val; 1522 xform->rsa.qt.dP.length = vec.rsa.dp.len; 1523 xform->rsa.qt.dQ.data = vec.rsa.dq.val; 1524 xform->rsa.qt.dQ.length = vec.rsa.dq.len; 1525 xform->rsa.qt.qInv.data = vec.rsa.qinv.val; 1526 xform->rsa.qt.qInv.length = vec.rsa.qinv.len; 1527 break; 1528 case RTE_RSA_KEY_TYPE_EXP: 1529 if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) { 1530 RTE_LOG(ERR, USER1, "PMD %s does not support EXP key type\n", 1531 info.device_name); 1532 return -EPERM; 1533 } 1534 xform->rsa.d.data = vec.rsa.d.val; 1535 xform->rsa.d.length = vec.rsa.d.len; 1536 break; 1537 default: 1538 break; 1539 } 1540 1541 xform->rsa.e.data = vec.rsa.e.val; 1542 xform->rsa.e.length = vec.rsa.e.len; 1543 xform->rsa.n.data = vec.rsa.n.val; 1544 xform->rsa.n.length = vec.rsa.n.len; 1545 return 0; 1546 } 1547 1548 static int 1549 prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform) 1550 { 1551 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1552 struct rte_cryptodev_asym_capability_idx cap_idx; 1553 1554 xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA; 1555 xform->next = NULL; 1556 1557 cap_idx.type = xform->xform_type; 1558 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1559 if (!cap) { 1560 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1561 env.dev_id); 1562 return -EINVAL; 1563 } 1564 1565 switch (info.op) { 1566 case FIPS_TEST_ASYM_SIGGEN: 1567 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1568 RTE_CRYPTO_ASYM_OP_SIGN)) { 1569 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1570 info.device_name, RTE_CRYPTO_ASYM_OP_SIGN); 1571 return -EPERM; 1572 } 1573 break; 1574 case FIPS_TEST_ASYM_SIGVER: 1575 if (!rte_cryptodev_asym_xform_capability_check_optype(cap, 1576 RTE_CRYPTO_ASYM_OP_VERIFY)) { 1577 RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n", 1578 info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY); 1579 return -EPERM; 1580 } 1581 break; 1582 default: 1583 break; 1584 } 1585 1586 xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id; 1587 return 0; 1588 } 1589 1590 static int 1591 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform) 1592 { 1593 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1594 struct rte_cryptodev_asym_capability_idx cap_idx; 1595 1596 xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM; 1597 xform->next = NULL; 1598 1599 cap_idx.type = xform->xform_type; 1600 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1601 if (!cap) { 1602 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1603 env.dev_id); 1604 return -EINVAL; 1605 } 1606 1607 xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id; 1608 return 0; 1609 } 1610 1611 static int 1612 get_writeback_data(struct fips_val *val) 1613 { 1614 struct rte_mbuf *m = env.mbuf; 1615 uint16_t data_len = rte_pktmbuf_pkt_len(m); 1616 uint16_t total_len = data_len + env.digest_len; 1617 uint8_t *src, *dst, *wb_data; 1618 1619 /* in case val is reused for MCT test, try to free the buffer first */ 1620 if (val->val) { 1621 rte_free(val->val); 1622 val->val = NULL; 1623 } 1624 1625 wb_data = dst = rte_malloc(NULL, total_len, 0); 1626 if (!dst) { 1627 RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM); 1628 return -ENOMEM; 1629 } 1630 1631 while (m && data_len) { 1632 uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len); 1633 1634 src = rte_pktmbuf_mtod(m, uint8_t *); 1635 memcpy(dst, src, seg_len); 1636 m = m->next; 1637 data_len -= seg_len; 1638 dst += seg_len; 1639 } 1640 1641 if (data_len) { 1642 RTE_LOG(ERR, USER1, "Error -1: write back data\n"); 1643 rte_free(wb_data); 1644 return -1; 1645 } 1646 1647 if (env.digest) 1648 memcpy(dst, env.digest, env.digest_len); 1649 1650 val->val = wb_data; 1651 val->len = total_len; 1652 1653 return 0; 1654 } 1655 1656 static int 1657 fips_run_sym_test(void) 1658 { 1659 struct rte_crypto_sym_xform xform = {0}; 1660 uint16_t n_deqd; 1661 int ret; 1662 1663 if (!test_ops.prepare_sym_xform || !test_ops.prepare_sym_op) 1664 return -EINVAL; 1665 1666 ret = test_ops.prepare_sym_xform(&xform); 1667 if (ret < 0) 1668 return ret; 1669 1670 env.sym.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform, 1671 env.sym.sess_mpool); 1672 if (!env.sym.sess) 1673 return -ENOMEM; 1674 1675 ret = test_ops.prepare_sym_op(); 1676 if (ret < 0) { 1677 RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", 1678 ret); 1679 goto exit; 1680 } 1681 1682 if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 1683 RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 1684 ret = -1; 1685 goto exit; 1686 } 1687 1688 do { 1689 struct rte_crypto_op *deqd_op; 1690 1691 n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1); 1692 } while (n_deqd == 0); 1693 1694 vec.status = env.op->status; 1695 1696 exit: 1697 rte_cryptodev_sym_session_free(env.dev_id, env.sym.sess); 1698 env.sym.sess = NULL; 1699 return ret; 1700 } 1701 1702 static int 1703 fips_run_asym_test(void) 1704 { 1705 struct rte_crypto_asym_xform xform = {0}; 1706 struct rte_crypto_asym_op *asym; 1707 struct rte_crypto_op *deqd_op; 1708 int ret; 1709 1710 if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != FIPS_TEST_ALGO_ECDSA) { 1711 RTE_SET_USED(asym); 1712 ret = 0; 1713 goto exit; 1714 } 1715 1716 if (!test_ops.prepare_asym_xform || !test_ops.prepare_asym_op) 1717 return -EINVAL; 1718 1719 asym = env.op->asym; 1720 ret = test_ops.prepare_asym_xform(&xform); 1721 if (ret < 0) 1722 return ret; 1723 1724 ret = rte_cryptodev_asym_session_create(env.dev_id, &xform, env.asym.sess_mpool, 1725 (void *)&env.asym.sess); 1726 if (ret < 0) 1727 return ret; 1728 1729 ret = test_ops.prepare_asym_op(); 1730 if (ret < 0) { 1731 RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", ret); 1732 goto exit; 1733 } 1734 1735 if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 1736 RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 1737 ret = -1; 1738 goto exit; 1739 } 1740 1741 while (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0) 1742 rte_pause(); 1743 1744 vec.status = env.op->status; 1745 1746 exit: 1747 if (env.asym.sess) 1748 rte_cryptodev_asym_session_free(env.dev_id, env.asym.sess); 1749 1750 env.asym.sess = NULL; 1751 return ret; 1752 } 1753 1754 static int 1755 fips_run_test(void) 1756 { 1757 int ret; 1758 1759 env.op = env.sym.op; 1760 if (env.is_asym_test) { 1761 if (info.op == FIPS_TEST_ASYM_KEYGEN && 1762 info.algo == FIPS_TEST_ALGO_ECDSA) { 1763 env.op = env.asym.op; 1764 test_ops.prepare_asym_xform = prepare_ecfpm_xform; 1765 test_ops.prepare_asym_op = prepare_ecfpm_op; 1766 ret = fips_run_asym_test(); 1767 if (ret < 0) 1768 return ret; 1769 1770 info.interim_info.ecdsa_data.pubkey_gen = 0; 1771 return ret; 1772 } 1773 1774 vec.cipher_auth.digest.len = parse_test_sha_hash_size( 1775 info.interim_info.rsa_data.auth); 1776 test_ops.prepare_sym_xform = prepare_sha_xform; 1777 test_ops.prepare_sym_op = prepare_auth_op; 1778 ret = fips_run_sym_test(); 1779 if (ret < 0) 1780 return ret; 1781 } else { 1782 return fips_run_sym_test(); 1783 } 1784 1785 env.op = env.asym.op; 1786 if (info.op == FIPS_TEST_ASYM_SIGGEN && 1787 info.algo == FIPS_TEST_ALGO_ECDSA && 1788 info.interim_info.ecdsa_data.pubkey_gen == 1) { 1789 fips_prepare_asym_xform_t ecdsa_xform; 1790 fips_prepare_op_t ecdsa_op; 1791 1792 ecdsa_xform = test_ops.prepare_asym_xform; 1793 ecdsa_op = test_ops.prepare_asym_op; 1794 info.op = FIPS_TEST_ASYM_KEYGEN; 1795 test_ops.prepare_asym_xform = prepare_ecfpm_xform; 1796 test_ops.prepare_asym_op = prepare_ecfpm_op; 1797 ret = fips_run_asym_test(); 1798 if (ret < 0) 1799 return ret; 1800 1801 info.post_interim_writeback(NULL); 1802 info.interim_info.ecdsa_data.pubkey_gen = 0; 1803 1804 test_ops.prepare_asym_xform = ecdsa_xform; 1805 test_ops.prepare_asym_op = ecdsa_op; 1806 info.op = FIPS_TEST_ASYM_SIGGEN; 1807 ret = fips_run_asym_test(); 1808 } else { 1809 ret = fips_run_asym_test(); 1810 } 1811 1812 return ret; 1813 } 1814 1815 static int 1816 fips_generic_test(void) 1817 { 1818 struct fips_val val = {NULL, 0}; 1819 int ret; 1820 1821 if (info.file_type != FIPS_TYPE_JSON) 1822 fips_test_write_one_case(); 1823 1824 ret = fips_run_test(); 1825 if (ret < 0) { 1826 if (ret == -EPERM || ret == -ENOTSUP) { 1827 if (info.file_type == FIPS_TYPE_JSON) 1828 return ret; 1829 1830 fprintf(info.fp_wr, "Bypass\n\n"); 1831 return 0; 1832 } 1833 1834 return ret; 1835 } 1836 1837 if (!env.is_asym_test) { 1838 ret = get_writeback_data(&val); 1839 if (ret < 0) 1840 return ret; 1841 } 1842 1843 switch (info.file_type) { 1844 case FIPS_TYPE_REQ: 1845 case FIPS_TYPE_RSP: 1846 case FIPS_TYPE_JSON: 1847 if (info.parse_writeback == NULL) 1848 return -EPERM; 1849 ret = info.parse_writeback(&val); 1850 if (ret < 0) 1851 return ret; 1852 break; 1853 case FIPS_TYPE_FAX: 1854 if (info.kat_check == NULL) 1855 return -EPERM; 1856 ret = info.kat_check(&val); 1857 if (ret < 0) 1858 return ret; 1859 break; 1860 default: 1861 break; 1862 } 1863 1864 if (info.file_type != FIPS_TYPE_JSON) 1865 fprintf(info.fp_wr, "\n"); 1866 rte_free(val.val); 1867 1868 return 0; 1869 } 1870 1871 static int 1872 fips_mct_tdes_test(void) 1873 { 1874 #define TDES_BLOCK_SIZE 8 1875 #define TDES_EXTERN_ITER 400 1876 #define TDES_INTERN_ITER 10000 1877 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 1878 uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; 1879 uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; 1880 uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; 1881 uint32_t i, j, k; 1882 int ret; 1883 int test_mode = info.interim_info.tdes_data.test_mode; 1884 1885 pt.len = vec.pt.len; 1886 pt.val = rte_malloc(NULL, pt.len, 0); 1887 ct.len = vec.ct.len; 1888 ct.val = rte_malloc(NULL, ct.len, 0); 1889 iv.len = vec.iv.len; 1890 iv.val = rte_malloc(NULL, iv.len, 0); 1891 1892 for (i = 0; i < TDES_EXTERN_ITER; i++) { 1893 if (info.file_type != FIPS_TYPE_JSON) { 1894 if ((i == 0) && (info.version == 21.4f)) { 1895 if (!(strstr(info.vec[0], "COUNT"))) 1896 fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0); 1897 } 1898 1899 if (i != 0) 1900 update_info_vec(i); 1901 1902 fips_test_write_one_case(); 1903 } 1904 1905 for (j = 0; j < TDES_INTERN_ITER; j++) { 1906 ret = fips_run_test(); 1907 if (ret < 0) { 1908 if (ret == -EPERM) { 1909 if (info.file_type == FIPS_TYPE_JSON) 1910 return ret; 1911 1912 fprintf(info.fp_wr, "Bypass\n"); 1913 return 0; 1914 } 1915 return ret; 1916 } 1917 1918 ret = get_writeback_data(&val[0]); 1919 if (ret < 0) 1920 return ret; 1921 1922 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1923 memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 1924 1925 if (j == 0) { 1926 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 1927 memcpy(pt.val, vec.pt.val, pt.len); 1928 memcpy(ct.val, vec.ct.val, ct.len); 1929 memcpy(iv.val, vec.iv.val, iv.len); 1930 1931 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1932 if (test_mode == TDES_MODE_ECB) { 1933 memcpy(vec.pt.val, val[0].val, 1934 TDES_BLOCK_SIZE); 1935 } else { 1936 memcpy(vec.pt.val, vec.iv.val, 1937 TDES_BLOCK_SIZE); 1938 memcpy(vec.iv.val, val[0].val, 1939 TDES_BLOCK_SIZE); 1940 } 1941 val[1].val = pt.val; 1942 val[1].len = pt.len; 1943 val[2].val = iv.val; 1944 val[2].len = iv.len; 1945 } else { 1946 if (test_mode == TDES_MODE_ECB) { 1947 memcpy(vec.ct.val, val[0].val, 1948 TDES_BLOCK_SIZE); 1949 } else { 1950 memcpy(vec.iv.val, vec.ct.val, 1951 TDES_BLOCK_SIZE); 1952 memcpy(vec.ct.val, val[0].val, 1953 TDES_BLOCK_SIZE); 1954 } 1955 val[1].val = ct.val; 1956 val[1].len = ct.len; 1957 val[2].val = iv.val; 1958 val[2].len = iv.len; 1959 } 1960 continue; 1961 } 1962 1963 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1964 if (test_mode == TDES_MODE_ECB) { 1965 memcpy(vec.pt.val, val[0].val, 1966 TDES_BLOCK_SIZE); 1967 } else { 1968 memcpy(vec.iv.val, val[0].val, 1969 TDES_BLOCK_SIZE); 1970 memcpy(vec.pt.val, prev_out, 1971 TDES_BLOCK_SIZE); 1972 } 1973 } else { 1974 if (test_mode == TDES_MODE_ECB) { 1975 memcpy(vec.ct.val, val[0].val, 1976 TDES_BLOCK_SIZE); 1977 } else { 1978 memcpy(vec.iv.val, vec.ct.val, 1979 TDES_BLOCK_SIZE); 1980 memcpy(vec.ct.val, val[0].val, 1981 TDES_BLOCK_SIZE); 1982 } 1983 } 1984 1985 if (j == TDES_INTERN_ITER - 1) 1986 continue; 1987 1988 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 1989 1990 if (j == TDES_INTERN_ITER - 3) 1991 memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE); 1992 } 1993 1994 info.parse_writeback(val); 1995 if (info.file_type != FIPS_TYPE_JSON) 1996 fprintf(info.fp_wr, "\n"); 1997 1998 if (i == TDES_EXTERN_ITER - 1) 1999 continue; 2000 2001 /** update key */ 2002 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2003 2004 if (info.interim_info.tdes_data.nb_keys == 0) { 2005 if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 2006 info.interim_info.tdes_data.nb_keys = 1; 2007 else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 2008 info.interim_info.tdes_data.nb_keys = 2; 2009 else 2010 info.interim_info.tdes_data.nb_keys = 3; 2011 2012 } 2013 2014 for (k = 0; k < TDES_BLOCK_SIZE; k++) { 2015 2016 switch (info.interim_info.tdes_data.nb_keys) { 2017 case 3: 2018 val_key.val[k] ^= val[0].val[k]; 2019 val_key.val[k + 8] ^= prev_out[k]; 2020 val_key.val[k + 16] ^= prev_prev_out[k]; 2021 break; 2022 case 2: 2023 val_key.val[k] ^= val[0].val[k]; 2024 val_key.val[k + 8] ^= prev_out[k]; 2025 val_key.val[k + 16] ^= val[0].val[k]; 2026 break; 2027 default: /* case 1 */ 2028 val_key.val[k] ^= val[0].val[k]; 2029 val_key.val[k + 8] ^= val[0].val[k]; 2030 val_key.val[k + 16] ^= val[0].val[k]; 2031 break; 2032 } 2033 2034 } 2035 2036 for (k = 0; k < 24; k++) 2037 val_key.val[k] = (__builtin_popcount(val_key.val[k]) & 2038 0x1) ? 2039 val_key.val[k] : (val_key.val[k] ^ 0x1); 2040 2041 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2042 if (test_mode == TDES_MODE_ECB) { 2043 memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE); 2044 } else { 2045 memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE); 2046 memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 2047 } 2048 } else { 2049 if (test_mode == TDES_MODE_ECB) { 2050 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 2051 } else { 2052 memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 2053 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 2054 } 2055 } 2056 } 2057 2058 rte_free(val[0].val); 2059 rte_free(pt.val); 2060 rte_free(ct.val); 2061 rte_free(iv.val); 2062 2063 return 0; 2064 } 2065 2066 static int 2067 fips_mct_aes_ecb_test(void) 2068 { 2069 #define AES_BLOCK_SIZE 16 2070 #define AES_EXTERN_ITER 100 2071 #define AES_INTERN_ITER 1000 2072 struct fips_val val = {NULL, 0}, val_key; 2073 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 2074 uint32_t i, j, k; 2075 int ret; 2076 2077 for (i = 0; i < AES_EXTERN_ITER; i++) { 2078 if (i != 0) 2079 update_info_vec(i); 2080 2081 fips_test_write_one_case(); 2082 2083 for (j = 0; j < AES_INTERN_ITER; j++) { 2084 ret = fips_run_test(); 2085 if (ret < 0) { 2086 if (ret == -EPERM) { 2087 if (info.file_type == FIPS_TYPE_JSON) 2088 return ret; 2089 2090 fprintf(info.fp_wr, "Bypass\n"); 2091 return 0; 2092 } 2093 2094 return ret; 2095 } 2096 2097 ret = get_writeback_data(&val); 2098 if (ret < 0) 2099 return ret; 2100 2101 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 2102 memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); 2103 else 2104 memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); 2105 2106 if (j == AES_INTERN_ITER - 1) 2107 continue; 2108 2109 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 2110 } 2111 2112 info.parse_writeback(&val); 2113 fprintf(info.fp_wr, "\n"); 2114 2115 if (i == AES_EXTERN_ITER - 1) 2116 continue; 2117 2118 /** update key */ 2119 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2120 for (k = 0; k < vec.cipher_auth.key.len; k++) { 2121 switch (vec.cipher_auth.key.len) { 2122 case 16: 2123 val_key.val[k] ^= val.val[k]; 2124 break; 2125 case 24: 2126 if (k < 8) 2127 val_key.val[k] ^= prev_out[k + 8]; 2128 else 2129 val_key.val[k] ^= val.val[k - 8]; 2130 break; 2131 case 32: 2132 if (k < 16) 2133 val_key.val[k] ^= prev_out[k]; 2134 else 2135 val_key.val[k] ^= val.val[k - 16]; 2136 break; 2137 default: 2138 return -1; 2139 } 2140 } 2141 } 2142 2143 rte_free(val.val); 2144 2145 return 0; 2146 } 2147 static int 2148 fips_mct_aes_test(void) 2149 { 2150 #define AES_BLOCK_SIZE 16 2151 #define AES_EXTERN_ITER 100 2152 #define AES_INTERN_ITER 1000 2153 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 2154 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 2155 uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 2156 uint32_t i, j, k; 2157 int ret; 2158 2159 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) 2160 return fips_mct_aes_ecb_test(); 2161 2162 pt.len = vec.pt.len; 2163 pt.val = rte_malloc(NULL, pt.len, 0); 2164 ct.len = vec.ct.len; 2165 ct.val = rte_malloc(NULL, ct.len, 0); 2166 iv.len = vec.iv.len; 2167 iv.val = rte_malloc(NULL, iv.len, 0); 2168 for (i = 0; i < AES_EXTERN_ITER; i++) { 2169 if (info.file_type != FIPS_TYPE_JSON) { 2170 if (i != 0) 2171 update_info_vec(i); 2172 2173 fips_test_write_one_case(); 2174 } 2175 2176 for (j = 0; j < AES_INTERN_ITER; j++) { 2177 ret = fips_run_test(); 2178 if (ret < 0) { 2179 if (ret == -EPERM) { 2180 if (info.file_type == FIPS_TYPE_JSON) 2181 return ret; 2182 2183 fprintf(info.fp_wr, "Bypass\n"); 2184 return 0; 2185 } 2186 2187 return ret; 2188 } 2189 2190 ret = get_writeback_data(&val[0]); 2191 if (ret < 0) 2192 return ret; 2193 2194 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 2195 memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 2196 2197 if (j == 0) { 2198 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 2199 memcpy(pt.val, vec.pt.val, pt.len); 2200 memcpy(ct.val, vec.ct.val, ct.len); 2201 memcpy(iv.val, vec.iv.val, iv.len); 2202 2203 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2204 memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE); 2205 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2206 val[1].val = pt.val; 2207 val[1].len = pt.len; 2208 val[2].val = iv.val; 2209 val[2].len = iv.len; 2210 } else { 2211 memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE); 2212 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 2213 val[1].val = ct.val; 2214 val[1].len = ct.len; 2215 val[2].val = iv.val; 2216 val[2].len = iv.len; 2217 } 2218 continue; 2219 } 2220 2221 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2222 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2223 memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 2224 } else { 2225 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 2226 memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 2227 } 2228 2229 if (j == AES_INTERN_ITER - 1) 2230 continue; 2231 2232 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 2233 } 2234 2235 info.parse_writeback(val); 2236 if (info.file_type != FIPS_TYPE_JSON) 2237 fprintf(info.fp_wr, "\n"); 2238 2239 if (i == AES_EXTERN_ITER - 1) 2240 continue; 2241 2242 /** update key */ 2243 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2244 for (k = 0; k < vec.cipher_auth.key.len; k++) { 2245 switch (vec.cipher_auth.key.len) { 2246 case 16: 2247 val_key.val[k] ^= val[0].val[k]; 2248 break; 2249 case 24: 2250 if (k < 8) 2251 val_key.val[k] ^= prev_out[k + 8]; 2252 else 2253 val_key.val[k] ^= val[0].val[k - 8]; 2254 break; 2255 case 32: 2256 if (k < 16) 2257 val_key.val[k] ^= prev_out[k]; 2258 else 2259 val_key.val[k] ^= val[0].val[k - 16]; 2260 break; 2261 default: 2262 return -1; 2263 } 2264 } 2265 2266 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 2267 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2268 } 2269 2270 rte_free(val[0].val); 2271 rte_free(pt.val); 2272 rte_free(ct.val); 2273 rte_free(iv.val); 2274 2275 return 0; 2276 } 2277 2278 static int 2279 fips_mct_sha_test(void) 2280 { 2281 #define SHA_EXTERN_ITER 100 2282 #define SHA_INTERN_ITER 1000 2283 uint8_t md_blocks = info.interim_info.sha_data.md_blocks; 2284 struct fips_val val = {NULL, 0}; 2285 struct fips_val md[md_blocks]; 2286 int ret; 2287 uint32_t i, j, k, offset, max_outlen; 2288 2289 max_outlen = md_blocks * vec.cipher_auth.digest.len; 2290 2291 rte_free(vec.cipher_auth.digest.val); 2292 vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0); 2293 2294 if (vec.pt.val) 2295 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len); 2296 2297 rte_free(vec.pt.val); 2298 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*md_blocks), 0); 2299 2300 for (i = 0; i < md_blocks; i++) 2301 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 2302 2303 if (info.file_type != FIPS_TYPE_JSON) { 2304 fips_test_write_one_case(); 2305 fprintf(info.fp_wr, "\n"); 2306 } 2307 2308 for (j = 0; j < SHA_EXTERN_ITER; j++) { 2309 for (i = 0; i < md_blocks; i++) { 2310 memcpy(md[i].val, vec.cipher_auth.digest.val, 2311 vec.cipher_auth.digest.len); 2312 md[i].len = vec.cipher_auth.digest.len; 2313 } 2314 2315 for (i = 0; i < (SHA_INTERN_ITER); i++) { 2316 offset = 0; 2317 for (k = 0; k < md_blocks; k++) { 2318 memcpy(vec.pt.val + offset, md[k].val, (size_t)md[k].len); 2319 offset += md[k].len; 2320 } 2321 vec.pt.len = offset; 2322 2323 ret = fips_run_test(); 2324 if (ret < 0) { 2325 if (ret == -EPERM || ret == -ENOTSUP) { 2326 if (info.file_type == FIPS_TYPE_JSON) 2327 return ret; 2328 2329 fprintf(info.fp_wr, "Bypass\n\n"); 2330 return 0; 2331 } 2332 return ret; 2333 } 2334 2335 ret = get_writeback_data(&val); 2336 if (ret < 0) 2337 return ret; 2338 2339 for (k = 1; k < md_blocks; k++) { 2340 memcpy(md[k-1].val, md[k].val, md[k].len); 2341 md[k-1].len = md[k].len; 2342 } 2343 2344 memcpy(md[md_blocks-1].val, (val.val + vec.pt.len), 2345 vec.cipher_auth.digest.len); 2346 md[md_blocks-1].len = vec.cipher_auth.digest.len; 2347 } 2348 2349 memcpy(vec.cipher_auth.digest.val, md[md_blocks-1].val, md[md_blocks-1].len); 2350 vec.cipher_auth.digest.len = md[md_blocks-1].len; 2351 2352 if (info.file_type != FIPS_TYPE_JSON) 2353 fprintf(info.fp_wr, "COUNT = %u\n", j); 2354 2355 info.parse_writeback(&val); 2356 2357 if (info.file_type != FIPS_TYPE_JSON) 2358 fprintf(info.fp_wr, "\n"); 2359 } 2360 2361 for (i = 0; i < (md_blocks); i++) 2362 rte_free(md[i].val); 2363 2364 rte_free(vec.pt.val); 2365 2366 rte_free(val.val); 2367 return 0; 2368 } 2369 2370 static int 2371 fips_mct_shake_test(void) 2372 { 2373 #define SHAKE_EXTERN_ITER 100 2374 #define SHAKE_INTERN_ITER 1000 2375 uint32_t i, j, range, outlen, max_outlen; 2376 struct fips_val val = {NULL, 0}, md; 2377 uint8_t rightmost[2]; 2378 uint16_t *rightptr; 2379 int ret; 2380 2381 max_outlen = vec.cipher_auth.digest.len; 2382 2383 rte_free(vec.cipher_auth.digest.val); 2384 vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0); 2385 2386 if (vec.pt.val) 2387 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.pt.len); 2388 2389 rte_free(vec.pt.val); 2390 vec.pt.val = rte_malloc(NULL, 16, 0); 2391 vec.pt.len = 16; 2392 2393 md.val = rte_malloc(NULL, max_outlen, 0); 2394 md.len = max_outlen; 2395 2396 if (info.file_type != FIPS_TYPE_JSON) { 2397 fips_test_write_one_case(); 2398 fprintf(info.fp_wr, "\n"); 2399 } 2400 2401 range = max_outlen - info.interim_info.sha_data.min_outlen + 1; 2402 outlen = max_outlen; 2403 for (j = 0; j < SHAKE_EXTERN_ITER; j++) { 2404 memset(md.val, 0, max_outlen); 2405 memcpy(md.val, vec.cipher_auth.digest.val, 2406 vec.cipher_auth.digest.len); 2407 2408 for (i = 0; i < (SHAKE_INTERN_ITER); i++) { 2409 memset(vec.pt.val, 0, vec.pt.len); 2410 memcpy(vec.pt.val, md.val, vec.pt.len); 2411 vec.cipher_auth.digest.len = outlen; 2412 ret = fips_run_test(); 2413 if (ret < 0) { 2414 if (ret == -EPERM || ret == -ENOTSUP) { 2415 if (info.file_type == FIPS_TYPE_JSON) 2416 return ret; 2417 2418 fprintf(info.fp_wr, "Bypass\n\n"); 2419 return 0; 2420 } 2421 return ret; 2422 } 2423 2424 ret = get_writeback_data(&val); 2425 if (ret < 0) 2426 return ret; 2427 2428 memset(md.val, 0, max_outlen); 2429 memcpy(md.val, (val.val + vec.pt.len), 2430 vec.cipher_auth.digest.len); 2431 md.len = outlen; 2432 rightmost[0] = md.val[md.len-1]; 2433 rightmost[1] = md.val[md.len-2]; 2434 rightptr = (uint16_t *)rightmost; 2435 outlen = info.interim_info.sha_data.min_outlen + 2436 (*rightptr % range); 2437 } 2438 2439 memcpy(vec.cipher_auth.digest.val, md.val, md.len); 2440 vec.cipher_auth.digest.len = md.len; 2441 2442 if (info.file_type != FIPS_TYPE_JSON) 2443 fprintf(info.fp_wr, "COUNT = %u\n", j); 2444 2445 info.parse_writeback(&val); 2446 2447 if (info.file_type != FIPS_TYPE_JSON) 2448 fprintf(info.fp_wr, "\n"); 2449 } 2450 2451 rte_free(md.val); 2452 rte_free(vec.pt.val); 2453 rte_free(val.val); 2454 return 0; 2455 } 2456 2457 static int 2458 init_test_ops(void) 2459 { 2460 switch (info.algo) { 2461 case FIPS_TEST_ALGO_AES_CBC: 2462 case FIPS_TEST_ALGO_AES_CTR: 2463 case FIPS_TEST_ALGO_AES: 2464 test_ops.prepare_sym_op = prepare_cipher_op; 2465 test_ops.prepare_sym_xform = prepare_aes_xform; 2466 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 2467 test_ops.test = fips_mct_aes_test; 2468 else 2469 test_ops.test = fips_generic_test; 2470 break; 2471 case FIPS_TEST_ALGO_HMAC: 2472 test_ops.prepare_sym_op = prepare_auth_op; 2473 test_ops.prepare_sym_xform = prepare_hmac_xform; 2474 test_ops.test = fips_generic_test; 2475 break; 2476 case FIPS_TEST_ALGO_TDES: 2477 test_ops.prepare_sym_op = prepare_cipher_op; 2478 test_ops.prepare_sym_xform = prepare_tdes_xform; 2479 if (info.interim_info.tdes_data.test_type == TDES_MCT) 2480 test_ops.test = fips_mct_tdes_test; 2481 else 2482 test_ops.test = fips_generic_test; 2483 break; 2484 case FIPS_TEST_ALGO_AES_GMAC: 2485 test_ops.prepare_sym_op = prepare_auth_op; 2486 test_ops.prepare_sym_xform = prepare_gmac_xform; 2487 test_ops.test = fips_generic_test; 2488 break; 2489 case FIPS_TEST_ALGO_AES_GCM: 2490 test_ops.prepare_sym_op = prepare_aead_op; 2491 test_ops.prepare_sym_xform = prepare_gcm_xform; 2492 test_ops.test = fips_generic_test; 2493 break; 2494 case FIPS_TEST_ALGO_AES_CMAC: 2495 test_ops.prepare_sym_op = prepare_auth_op; 2496 test_ops.prepare_sym_xform = prepare_cmac_xform; 2497 test_ops.test = fips_generic_test; 2498 break; 2499 case FIPS_TEST_ALGO_AES_CCM: 2500 test_ops.prepare_sym_op = prepare_aead_op; 2501 test_ops.prepare_sym_xform = prepare_ccm_xform; 2502 test_ops.test = fips_generic_test; 2503 break; 2504 case FIPS_TEST_ALGO_SHA: 2505 test_ops.prepare_sym_op = prepare_auth_op; 2506 test_ops.prepare_sym_xform = prepare_sha_xform; 2507 if (info.interim_info.sha_data.test_type == SHA_MCT) 2508 if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 || 2509 info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256) 2510 test_ops.test = fips_mct_shake_test; 2511 else 2512 test_ops.test = fips_mct_sha_test; 2513 else 2514 test_ops.test = fips_generic_test; 2515 break; 2516 case FIPS_TEST_ALGO_AES_XTS: 2517 test_ops.prepare_sym_op = prepare_cipher_op; 2518 test_ops.prepare_sym_xform = prepare_xts_xform; 2519 test_ops.test = fips_generic_test; 2520 break; 2521 case FIPS_TEST_ALGO_RSA: 2522 test_ops.prepare_asym_op = prepare_rsa_op; 2523 test_ops.prepare_asym_xform = prepare_rsa_xform; 2524 test_ops.test = fips_generic_test; 2525 break; 2526 case FIPS_TEST_ALGO_ECDSA: 2527 if (info.op == FIPS_TEST_ASYM_KEYGEN) { 2528 test_ops.prepare_asym_op = prepare_ecfpm_op; 2529 test_ops.prepare_asym_xform = prepare_ecfpm_xform; 2530 test_ops.test = fips_generic_test; 2531 } else { 2532 test_ops.prepare_asym_op = prepare_ecdsa_op; 2533 test_ops.prepare_asym_xform = prepare_ecdsa_xform; 2534 test_ops.test = fips_generic_test; 2535 } 2536 break; 2537 default: 2538 if (strstr(info.file_name, "TECB") || 2539 strstr(info.file_name, "TCBC")) { 2540 info.algo = FIPS_TEST_ALGO_TDES; 2541 test_ops.prepare_sym_op = prepare_cipher_op; 2542 test_ops.prepare_sym_xform = prepare_tdes_xform; 2543 if (info.interim_info.tdes_data.test_type == TDES_MCT) 2544 test_ops.test = fips_mct_tdes_test; 2545 else 2546 test_ops.test = fips_generic_test; 2547 break; 2548 } 2549 return -1; 2550 } 2551 2552 return 0; 2553 } 2554 2555 static void 2556 print_test_block(void) 2557 { 2558 uint32_t i; 2559 2560 for (i = 0; i < info.nb_vec_lines; i++) 2561 printf("%s\n", info.vec[i]); 2562 2563 printf("\n"); 2564 } 2565 2566 static int 2567 fips_test_one_file(void) 2568 { 2569 int fetch_ret = 0, ret; 2570 2571 ret = init_test_ops(); 2572 if (ret < 0) { 2573 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 2574 return ret; 2575 } 2576 2577 while (ret >= 0 && fetch_ret == 0) { 2578 fetch_ret = fips_test_fetch_one_block(); 2579 if (fetch_ret < 0) { 2580 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 2581 fetch_ret); 2582 ret = fetch_ret; 2583 goto error_one_case; 2584 } 2585 2586 if (info.nb_vec_lines == 0) { 2587 if (fetch_ret == -EOF) 2588 break; 2589 2590 fprintf(info.fp_wr, "\n"); 2591 continue; 2592 } 2593 2594 ret = fips_test_parse_one_case(); 2595 switch (ret) { 2596 case 0: 2597 ret = test_ops.test(); 2598 if (ret == 0) 2599 break; 2600 RTE_LOG(ERR, USER1, "Error %i: test block\n", 2601 ret); 2602 goto error_one_case; 2603 case 1: 2604 break; 2605 default: 2606 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 2607 ret); 2608 goto error_one_case; 2609 } 2610 2611 continue; 2612 error_one_case: 2613 print_test_block(); 2614 } 2615 2616 fips_test_clear(); 2617 2618 if (env.digest) { 2619 rte_free(env.digest); 2620 env.digest = NULL; 2621 env.digest_len = 0; 2622 } 2623 rte_pktmbuf_free(env.mbuf); 2624 2625 return ret; 2626 } 2627 2628 #ifdef USE_JANSSON 2629 static int 2630 fips_test_json_init_writeback(void) 2631 { 2632 json_t *session_info, *session_write; 2633 session_info = json_array_get(json_info.json_root, 0); 2634 session_write = json_object(); 2635 json_info.json_write_root = json_array(); 2636 2637 json_object_set(session_write, "jwt", 2638 json_object_get(session_info, "jwt")); 2639 json_object_set(session_write, "url", 2640 json_object_get(session_info, "url")); 2641 json_object_set(session_write, "isSample", 2642 json_object_get(session_info, "isSample")); 2643 2644 json_info.is_sample = json_boolean_value( 2645 json_object_get(session_info, "isSample")); 2646 2647 json_array_append_new(json_info.json_write_root, session_write); 2648 return 0; 2649 } 2650 2651 static int 2652 fips_test_one_test_case(void) 2653 { 2654 int ret; 2655 2656 ret = fips_test_parse_one_json_case(); 2657 2658 switch (ret) { 2659 case 0: 2660 ret = test_ops.test(); 2661 if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP)) 2662 break; 2663 RTE_LOG(ERR, USER1, "Error %i: test block\n", 2664 ret); 2665 break; 2666 default: 2667 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 2668 ret); 2669 } 2670 return ret; 2671 } 2672 2673 static int 2674 fips_test_one_test_group(void) 2675 { 2676 int ret; 2677 json_t *tests, *write_tests; 2678 size_t test_idx, tests_size; 2679 2680 write_tests = json_array(); 2681 json_info.json_write_group = json_object(); 2682 json_object_set(json_info.json_write_group, "tgId", 2683 json_object_get(json_info.json_test_group, "tgId")); 2684 json_object_set_new(json_info.json_write_group, "tests", write_tests); 2685 2686 switch (info.algo) { 2687 case FIPS_TEST_ALGO_AES_GMAC: 2688 case FIPS_TEST_ALGO_AES_GCM: 2689 ret = parse_test_gcm_json_init(); 2690 break; 2691 case FIPS_TEST_ALGO_AES_CCM: 2692 ret = parse_test_ccm_json_init(); 2693 break; 2694 case FIPS_TEST_ALGO_HMAC: 2695 ret = parse_test_hmac_json_init(); 2696 break; 2697 case FIPS_TEST_ALGO_AES_CMAC: 2698 ret = parse_test_cmac_json_init(); 2699 break; 2700 case FIPS_TEST_ALGO_AES_XTS: 2701 ret = parse_test_xts_json_init(); 2702 break; 2703 case FIPS_TEST_ALGO_AES_CBC: 2704 case FIPS_TEST_ALGO_AES_CTR: 2705 case FIPS_TEST_ALGO_AES: 2706 ret = parse_test_aes_json_init(); 2707 break; 2708 case FIPS_TEST_ALGO_SHA: 2709 ret = parse_test_sha_json_init(); 2710 break; 2711 case FIPS_TEST_ALGO_TDES: 2712 ret = parse_test_tdes_json_init(); 2713 break; 2714 case FIPS_TEST_ALGO_RSA: 2715 ret = parse_test_rsa_json_init(); 2716 break; 2717 case FIPS_TEST_ALGO_ECDSA: 2718 ret = parse_test_ecdsa_json_init(); 2719 break; 2720 default: 2721 return -EINVAL; 2722 } 2723 2724 if (ret < 0) 2725 return ret; 2726 2727 ret = fips_test_parse_one_json_group(); 2728 if (ret < 0) 2729 return ret; 2730 2731 ret = init_test_ops(); 2732 if (ret < 0) 2733 return ret; 2734 2735 tests = json_object_get(json_info.json_test_group, "tests"); 2736 tests_size = json_array_size(tests); 2737 for (test_idx = 0; test_idx < tests_size; test_idx++) { 2738 json_info.json_test_case = json_array_get(tests, test_idx); 2739 if (fips_test_one_test_case() == 0) 2740 json_array_append_new(write_tests, json_info.json_write_case); 2741 } 2742 2743 return 0; 2744 } 2745 2746 static int 2747 fips_test_one_vector_set(void) 2748 { 2749 int ret; 2750 json_t *test_groups, *write_groups, *write_version, *write_set, *mode; 2751 size_t group_idx, num_groups; 2752 2753 test_groups = json_object_get(json_info.json_vector_set, "testGroups"); 2754 num_groups = json_array_size(test_groups); 2755 2756 json_info.json_write_set = json_array(); 2757 write_version = json_object(); 2758 json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION)); 2759 json_array_append_new(json_info.json_write_set, write_version); 2760 2761 write_set = json_object(); 2762 json_array_append(json_info.json_write_set, write_set); 2763 write_groups = json_array(); 2764 2765 json_object_set(write_set, "vsId", 2766 json_object_get(json_info.json_vector_set, "vsId")); 2767 json_object_set(write_set, "algorithm", 2768 json_object_get(json_info.json_vector_set, "algorithm")); 2769 mode = json_object_get(json_info.json_vector_set, "mode"); 2770 if (mode != NULL) 2771 json_object_set_new(write_set, "mode", mode); 2772 2773 json_object_set(write_set, "revision", 2774 json_object_get(json_info.json_vector_set, "revision")); 2775 json_object_set_new(write_set, "isSample", 2776 json_boolean(json_info.is_sample)); 2777 json_object_set_new(write_set, "testGroups", write_groups); 2778 2779 ret = fips_test_parse_one_json_vector_set(); 2780 if (ret < 0) { 2781 RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n", 2782 json_string_value(json_object_get(json_info.json_vector_set, "algorithm"))); 2783 return ret; 2784 } 2785 2786 for (group_idx = 0; group_idx < num_groups; group_idx++) { 2787 json_info.json_test_group = json_array_get(test_groups, group_idx); 2788 ret = fips_test_one_test_group(); 2789 json_array_append_new(write_groups, json_info.json_write_group); 2790 } 2791 2792 return 0; 2793 } 2794 2795 static int 2796 fips_test_one_json_file(void) 2797 { 2798 size_t vector_set_idx, root_size; 2799 2800 root_size = json_array_size(json_info.json_root); 2801 fips_test_json_init_writeback(); 2802 2803 for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) { 2804 /* Vector set index starts at 1, the 0th index contains test session 2805 * information. 2806 */ 2807 json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx); 2808 fips_test_one_vector_set(); 2809 json_array_append_new(json_info.json_write_root, json_info.json_write_set); 2810 json_incref(json_info.json_write_set); 2811 } 2812 2813 json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4)); 2814 json_decref(json_info.json_write_root); 2815 2816 return 0; 2817 } 2818 #endif /* USE_JANSSON */ 2819