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