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 }; 41 42 struct fips_test_vector vec; 43 struct fips_test_interim_info info; 44 45 #ifdef USE_JANSSON 46 struct fips_test_json_info json_info; 47 #endif /* USE_JANSSON */ 48 49 struct cryptodev_fips_validate_env { 50 const char *req_path; 51 const char *rsp_path; 52 uint32_t is_path_folder; 53 uint8_t dev_id; 54 uint8_t dev_support_sgl; 55 uint16_t mbuf_data_room; 56 struct rte_mempool *mpool; 57 struct rte_mempool *sess_mpool; 58 struct rte_mempool *op_pool; 59 struct rte_mbuf *mbuf; 60 uint8_t *digest; 61 uint16_t digest_len; 62 struct rte_crypto_op *op; 63 void *sess; 64 uint16_t self_test; 65 struct fips_dev_broken_test_config *broken_test_config; 66 } env; 67 68 static int 69 cryptodev_fips_validate_app_int(void) 70 { 71 struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0}; 72 struct rte_cryptodev_qp_conf qp_conf = {128, NULL}; 73 struct rte_cryptodev_info dev_info; 74 uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size( 75 env.dev_id); 76 uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1; 77 int ret; 78 79 if (env.self_test) { 80 ret = fips_dev_self_test(env.dev_id, env.broken_test_config); 81 if (ret < 0) { 82 rte_cryptodev_close(env.dev_id); 83 84 return ret; 85 } 86 } 87 88 ret = rte_cryptodev_configure(env.dev_id, &conf); 89 if (ret < 0) 90 return ret; 91 92 rte_cryptodev_info_get(env.dev_id, &dev_info); 93 if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL) 94 env.dev_support_sgl = 1; 95 else 96 env.dev_support_sgl = 0; 97 98 env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs, 99 0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM + 100 env.mbuf_data_room, rte_socket_id()); 101 if (!env.mpool) 102 return ret; 103 104 ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf, 105 rte_socket_id()); 106 if (ret < 0) 107 return ret; 108 109 ret = -ENOMEM; 110 111 env.sess_mpool = rte_cryptodev_sym_session_pool_create( 112 "FIPS_SESS_MEMPOOL", 16, sess_sz, 0, 0, 113 rte_socket_id()); 114 if (!env.sess_mpool) 115 goto error_exit; 116 117 env.op_pool = rte_crypto_op_pool_create( 118 "FIPS_OP_POOL", 119 RTE_CRYPTO_OP_TYPE_SYMMETRIC, 120 1, 0, 121 16, 122 rte_socket_id()); 123 if (!env.op_pool) 124 goto error_exit; 125 126 env.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 127 if (!env.op) 128 goto error_exit; 129 130 qp_conf.mp_session = env.sess_mpool; 131 132 ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf, 133 rte_socket_id()); 134 if (ret < 0) 135 goto error_exit; 136 137 ret = rte_cryptodev_start(env.dev_id); 138 if (ret < 0) 139 goto error_exit; 140 141 return 0; 142 143 error_exit: 144 145 rte_mempool_free(env.mpool); 146 rte_mempool_free(env.sess_mpool); 147 rte_mempool_free(env.op_pool); 148 149 return ret; 150 } 151 152 static void 153 cryptodev_fips_validate_app_uninit(void) 154 { 155 rte_pktmbuf_free(env.mbuf); 156 rte_crypto_op_free(env.op); 157 rte_cryptodev_sym_session_free(env.dev_id, env.sess); 158 rte_mempool_free(env.mpool); 159 rte_mempool_free(env.sess_mpool); 160 rte_mempool_free(env.op_pool); 161 } 162 163 static int 164 fips_test_one_file(void); 165 166 #ifdef USE_JANSSON 167 static int 168 fips_test_one_json_file(void); 169 #endif /* USE_JANSSON */ 170 171 static int 172 parse_cryptodev_arg(char *arg) 173 { 174 int id = rte_cryptodev_get_dev_id(arg); 175 176 if (id < 0) { 177 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n", 178 id, arg); 179 return id; 180 } 181 182 env.dev_id = (uint8_t)id; 183 184 return 0; 185 } 186 187 static int 188 parse_cryptodev_id_arg(char *arg) 189 { 190 uint32_t cryptodev_id; 191 192 if (parser_read_uint32(&cryptodev_id, arg) < 0) { 193 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", 194 -EINVAL, arg); 195 return -1; 196 } 197 198 199 if (!rte_cryptodev_is_valid_dev(cryptodev_id)) { 200 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", 201 cryptodev_id, arg); 202 return -1; 203 } 204 205 env.dev_id = (uint8_t)cryptodev_id; 206 207 return 0; 208 } 209 210 static void 211 cryptodev_fips_validate_usage(const char *prgname) 212 { 213 uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE; 214 printf("%s [EAL options] --\n" 215 " --%s: REQUEST-FILE-PATH\n" 216 " --%s: RESPONSE-FILE-PATH\n" 217 " --%s: indicating both paths are folders\n" 218 " --%s: mbuf dataroom size (default %u bytes)\n" 219 " --%s: CRYPTODEV-NAME\n" 220 " --%s: CRYPTODEV-ID-NAME\n" 221 " --%s: self test indicator\n" 222 " --%s: self broken test ID\n" 223 " --%s: self broken test direction\n", 224 prgname, OPT_REQ_FILE_PATH, OPT_RSP_FILE_PATH, 225 OPT_FOLDER, OPT_MBUF_DATAROOM, def_mbuf_seg_size, 226 OPT_CRYPTODEV, OPT_CRYPTODEV_ID, OPT_CRYPTODEV_ST, 227 OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY); 228 } 229 230 static int 231 cryptodev_fips_validate_parse_args(int argc, char **argv) 232 { 233 int opt, ret; 234 char *prgname = argv[0]; 235 char **argvopt; 236 int option_index; 237 struct option lgopts[] = { 238 {OPT_REQ_FILE_PATH, required_argument, 239 NULL, OPT_REQ_FILE_PATH_NUM}, 240 {OPT_RSP_FILE_PATH, required_argument, 241 NULL, OPT_RSP_FILE_PATH_NUM}, 242 {OPT_FOLDER, no_argument, 243 NULL, OPT_FOLDER_NUM}, 244 {OPT_MBUF_DATAROOM, required_argument, 245 NULL, OPT_MBUF_DATAROOM_NUM}, 246 {OPT_CRYPTODEV, required_argument, 247 NULL, OPT_CRYPTODEV_NUM}, 248 {OPT_CRYPTODEV_ID, required_argument, 249 NULL, OPT_CRYPTODEV_ID_NUM}, 250 {OPT_CRYPTODEV_ST, no_argument, 251 NULL, OPT_CRYPTODEV_ST_NUM}, 252 {OPT_CRYPTODEV_BK_ID, required_argument, 253 NULL, OPT_CRYPTODEV_BK_ID_NUM}, 254 {OPT_CRYPTODEV_BK_DIR_KEY, required_argument, 255 NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM}, 256 {NULL, 0, 0, 0} 257 }; 258 259 argvopt = argv; 260 261 env.mbuf_data_room = DEF_MBUF_SEG_SIZE; 262 if (rte_cryptodev_count()) 263 env.dev_id = 0; 264 else { 265 cryptodev_fips_validate_usage(prgname); 266 return -EINVAL; 267 } 268 269 while ((opt = getopt_long(argc, argvopt, "s:", 270 lgopts, &option_index)) != EOF) { 271 272 switch (opt) { 273 case OPT_REQ_FILE_PATH_NUM: 274 env.req_path = optarg; 275 break; 276 277 case OPT_RSP_FILE_PATH_NUM: 278 env.rsp_path = optarg; 279 break; 280 281 case OPT_FOLDER_NUM: 282 env.is_path_folder = 1; 283 break; 284 285 case OPT_CRYPTODEV_NUM: 286 ret = parse_cryptodev_arg(optarg); 287 if (ret < 0) { 288 cryptodev_fips_validate_usage(prgname); 289 return -EINVAL; 290 } 291 break; 292 293 case OPT_CRYPTODEV_ID_NUM: 294 ret = parse_cryptodev_id_arg(optarg); 295 if (ret < 0) { 296 cryptodev_fips_validate_usage(prgname); 297 return -EINVAL; 298 } 299 break; 300 301 case OPT_CRYPTODEV_ST_NUM: 302 env.self_test = 1; 303 break; 304 305 case OPT_CRYPTODEV_BK_ID_NUM: 306 if (!env.broken_test_config) { 307 env.broken_test_config = rte_malloc( 308 NULL, 309 sizeof(*env.broken_test_config), 310 0); 311 if (!env.broken_test_config) 312 return -ENOMEM; 313 314 env.broken_test_config->expect_fail_dir = 315 self_test_dir_enc_auth_gen; 316 } 317 318 if (parser_read_uint32( 319 &env.broken_test_config->expect_fail_test_idx, 320 optarg) < 0) { 321 rte_free(env.broken_test_config); 322 cryptodev_fips_validate_usage(prgname); 323 return -EINVAL; 324 } 325 break; 326 327 case OPT_CRYPTODEV_BK_DIR_KEY_NUM: 328 if (!env.broken_test_config) { 329 env.broken_test_config = rte_malloc( 330 NULL, 331 sizeof(*env.broken_test_config), 332 0); 333 if (!env.broken_test_config) 334 return -ENOMEM; 335 336 env.broken_test_config->expect_fail_test_idx = 337 0; 338 } 339 340 if (strcmp(optarg, "enc") == 0) 341 env.broken_test_config->expect_fail_dir = 342 self_test_dir_enc_auth_gen; 343 else if (strcmp(optarg, "dec") 344 == 0) 345 env.broken_test_config->expect_fail_dir = 346 self_test_dir_dec_auth_verify; 347 else { 348 rte_free(env.broken_test_config); 349 cryptodev_fips_validate_usage(prgname); 350 return -EINVAL; 351 } 352 break; 353 354 355 case OPT_MBUF_DATAROOM_NUM: 356 if (parser_read_uint16(&env.mbuf_data_room, 357 optarg) < 0) { 358 cryptodev_fips_validate_usage(prgname); 359 return -EINVAL; 360 } 361 362 if (env.mbuf_data_room == 0) { 363 cryptodev_fips_validate_usage(prgname); 364 return -EINVAL; 365 } 366 break; 367 368 default: 369 cryptodev_fips_validate_usage(prgname); 370 return -EINVAL; 371 } 372 } 373 374 if ((env.req_path == NULL && env.rsp_path != NULL) || 375 (env.req_path != NULL && env.rsp_path == NULL)) { 376 RTE_LOG(ERR, USER1, "Missing req path or rsp path\n"); 377 cryptodev_fips_validate_usage(prgname); 378 return -EINVAL; 379 } 380 381 if (env.req_path == NULL && env.self_test == 0) { 382 RTE_LOG(ERR, USER1, "--self-test must be set if req path is missing\n"); 383 cryptodev_fips_validate_usage(prgname); 384 return -EINVAL; 385 } 386 387 return 0; 388 } 389 390 int 391 main(int argc, char *argv[]) 392 { 393 int ret; 394 395 ret = rte_eal_init(argc, argv); 396 if (ret < 0) { 397 RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); 398 return -1; 399 } 400 401 argc -= ret; 402 argv += ret; 403 404 ret = cryptodev_fips_validate_parse_args(argc, argv); 405 if (ret < 0) 406 rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n"); 407 408 ret = cryptodev_fips_validate_app_int(); 409 if (ret < 0) { 410 RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); 411 return -1; 412 } 413 414 if (env.req_path == NULL || env.rsp_path == NULL) { 415 printf("No request, exit.\n"); 416 goto exit; 417 } 418 419 if (!env.is_path_folder) { 420 printf("Processing file %s... ", env.req_path); 421 422 ret = fips_test_init(env.req_path, env.rsp_path, 423 rte_cryptodev_name_get(env.dev_id)); 424 if (ret < 0) { 425 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 426 ret, env.req_path); 427 goto exit; 428 } 429 430 #ifdef USE_JANSSON 431 if (info.file_type == FIPS_TYPE_JSON) { 432 ret = fips_test_one_json_file(); 433 json_decref(json_info.json_root); 434 } else { 435 ret = fips_test_one_file(); 436 } 437 #else /* USE_JANSSON */ 438 ret = fips_test_one_file(); 439 #endif /* USE_JANSSON */ 440 441 if (ret < 0) { 442 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 443 ret, env.req_path); 444 goto exit; 445 } 446 447 printf("Done\n"); 448 449 } else { 450 struct dirent *dir; 451 DIR *d_req, *d_rsp; 452 char req_path[1024]; 453 char rsp_path[1024]; 454 455 d_req = opendir(env.req_path); 456 if (!d_req) { 457 RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n", 458 -EINVAL, env.req_path); 459 goto exit; 460 } 461 462 d_rsp = opendir(env.rsp_path); 463 if (!d_rsp) { 464 ret = mkdir(env.rsp_path, 0700); 465 if (ret == 0) 466 d_rsp = opendir(env.rsp_path); 467 else { 468 RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n", 469 -EINVAL, env.rsp_path); 470 goto exit; 471 } 472 } 473 closedir(d_rsp); 474 475 while ((dir = readdir(d_req)) != NULL) { 476 if (strstr(dir->d_name, "req") == NULL) 477 continue; 478 479 snprintf(req_path, 1023, "%s/%s", env.req_path, 480 dir->d_name); 481 snprintf(rsp_path, 1023, "%s/%s", env.rsp_path, 482 dir->d_name); 483 strlcpy(strstr(rsp_path, "req"), "rsp", 4); 484 485 printf("Processing file %s... ", req_path); 486 487 ret = fips_test_init(req_path, rsp_path, 488 rte_cryptodev_name_get(env.dev_id)); 489 if (ret < 0) { 490 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 491 ret, req_path); 492 break; 493 } 494 495 #ifdef USE_JANSSON 496 if (info.file_type == FIPS_TYPE_JSON) { 497 ret = fips_test_one_json_file(); 498 json_decref(json_info.json_root); 499 } else { 500 ret = fips_test_one_file(); 501 } 502 #else /* USE_JANSSON */ 503 ret = fips_test_one_file(); 504 #endif /* USE_JANSSON */ 505 506 if (ret < 0) { 507 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 508 ret, req_path); 509 break; 510 } 511 512 printf("Done\n"); 513 } 514 515 closedir(d_req); 516 } 517 518 519 exit: 520 fips_test_clear(); 521 cryptodev_fips_validate_app_uninit(); 522 523 /* clean up the EAL */ 524 rte_eal_cleanup(); 525 526 return ret; 527 528 } 529 530 #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op)) 531 #define CRYPTODEV_FIPS_MAX_RETRIES 16 532 533 struct fips_test_ops test_ops; 534 535 static int 536 prepare_data_mbufs(struct fips_val *val) 537 { 538 struct rte_mbuf *m, *head = 0; 539 uint8_t *src = val->val; 540 uint32_t total_len = val->len; 541 uint16_t nb_seg; 542 int ret = 0; 543 544 rte_pktmbuf_free(env.mbuf); 545 546 if (total_len > RTE_MBUF_MAX_NB_SEGS) { 547 RTE_LOG(ERR, USER1, "Data len %u too big\n", total_len); 548 return -EPERM; 549 } 550 551 nb_seg = total_len / env.mbuf_data_room; 552 if (total_len % env.mbuf_data_room) 553 nb_seg++; 554 555 m = rte_pktmbuf_alloc(env.mpool); 556 if (!m) { 557 RTE_LOG(ERR, USER1, "Error %i: Not enough mbuf\n", 558 -ENOMEM); 559 return -ENOMEM; 560 } 561 head = m; 562 563 while (nb_seg) { 564 uint16_t len = RTE_MIN(total_len, env.mbuf_data_room); 565 uint8_t *dst = (uint8_t *)rte_pktmbuf_append(m, len); 566 567 if (!dst) { 568 RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", 569 -ENOMEM); 570 ret = -ENOMEM; 571 goto error_exit; 572 } 573 574 memcpy(dst, src, len); 575 576 if (head != m) { 577 ret = rte_pktmbuf_chain(head, m); 578 if (ret) { 579 rte_pktmbuf_free(m); 580 RTE_LOG(ERR, USER1, "Error %i: SGL build\n", 581 ret); 582 goto error_exit; 583 } 584 } 585 total_len -= len; 586 587 if (total_len) { 588 if (!env.dev_support_sgl) { 589 RTE_LOG(ERR, USER1, "SGL not supported\n"); 590 ret = -EPERM; 591 goto error_exit; 592 } 593 594 m = rte_pktmbuf_alloc(env.mpool); 595 if (!m) { 596 RTE_LOG(ERR, USER1, "Error %i: No memory\n", 597 -ENOMEM); 598 goto error_exit; 599 } 600 } else 601 break; 602 603 src += len; 604 nb_seg--; 605 } 606 607 if (total_len) { 608 RTE_LOG(ERR, USER1, "Error %i: Failed to store all data\n", 609 -ENOMEM); 610 goto error_exit; 611 } 612 613 env.mbuf = head; 614 615 return 0; 616 617 error_exit: 618 rte_pktmbuf_free(head); 619 return ret; 620 } 621 622 static int 623 prepare_cipher_op(void) 624 { 625 struct rte_crypto_sym_op *sym = env.op->sym; 626 uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); 627 int ret; 628 629 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 630 631 memcpy(iv, vec.iv.val, vec.iv.len); 632 633 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 634 ret = prepare_data_mbufs(&vec.pt); 635 if (ret < 0) 636 return ret; 637 638 sym->cipher.data.length = vec.pt.len; 639 } else { 640 ret = prepare_data_mbufs(&vec.ct); 641 if (ret < 0) 642 return ret; 643 644 sym->cipher.data.length = vec.ct.len; 645 } 646 647 rte_crypto_op_attach_sym_session(env.op, env.sess); 648 649 sym->m_src = env.mbuf; 650 sym->cipher.data.offset = 0; 651 652 return 0; 653 } 654 655 int 656 prepare_auth_op(void) 657 { 658 struct rte_crypto_sym_op *sym = env.op->sym; 659 int ret; 660 661 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 662 663 if (vec.iv.len) { 664 uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, 665 IV_OFF); 666 memset(iv, 0, vec.iv.len); 667 if (vec.iv.val) 668 memcpy(iv, vec.iv.val, vec.iv.len); 669 } 670 671 ret = prepare_data_mbufs(&vec.pt); 672 if (ret < 0) 673 return ret; 674 675 rte_free(env.digest); 676 677 env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len, 678 RTE_CACHE_LINE_SIZE); 679 if (!env.digest) { 680 RTE_LOG(ERR, USER1, "Not enough memory\n"); 681 return -ENOMEM; 682 } 683 env.digest_len = vec.cipher_auth.digest.len; 684 685 sym->m_src = env.mbuf; 686 sym->auth.data.offset = 0; 687 sym->auth.data.length = vec.pt.len; 688 sym->auth.digest.data = env.digest; 689 sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest); 690 691 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 692 memcpy(env.digest, vec.cipher_auth.digest.val, 693 vec.cipher_auth.digest.len); 694 695 rte_crypto_op_attach_sym_session(env.op, env.sess); 696 697 return 0; 698 } 699 700 int 701 prepare_aead_op(void) 702 { 703 struct rte_crypto_sym_op *sym = env.op->sym; 704 uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); 705 int ret; 706 707 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 708 709 if (info.algo == FIPS_TEST_ALGO_AES_CCM) 710 iv++; 711 712 if (vec.iv.val) 713 memcpy(iv, vec.iv.val, vec.iv.len); 714 else 715 /* if REQ file has iv length but not data, default as all 0 */ 716 memset(iv, 0, vec.iv.len); 717 718 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 719 ret = prepare_data_mbufs(&vec.pt); 720 if (ret < 0) 721 return ret; 722 723 rte_free(env.digest); 724 env.digest = rte_zmalloc(NULL, vec.aead.digest.len, 725 RTE_CACHE_LINE_SIZE); 726 if (!env.digest) { 727 RTE_LOG(ERR, USER1, "Not enough memory\n"); 728 return -ENOMEM; 729 } 730 env.digest_len = vec.cipher_auth.digest.len; 731 732 sym->aead.data.length = vec.pt.len; 733 sym->aead.digest.data = env.digest; 734 sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest); 735 } else { 736 ret = prepare_data_mbufs(&vec.ct); 737 if (ret < 0) 738 return ret; 739 740 sym->aead.data.length = vec.ct.len; 741 sym->aead.digest.data = vec.aead.digest.val; 742 sym->aead.digest.phys_addr = rte_malloc_virt2iova( 743 sym->aead.digest.data); 744 } 745 746 sym->m_src = env.mbuf; 747 sym->aead.data.offset = 0; 748 sym->aead.aad.data = vec.aead.aad.val; 749 sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data); 750 751 rte_crypto_op_attach_sym_session(env.op, env.sess); 752 753 return 0; 754 } 755 756 static int 757 prepare_aes_xform(struct rte_crypto_sym_xform *xform) 758 { 759 const struct rte_cryptodev_symmetric_capability *cap; 760 struct rte_cryptodev_sym_capability_idx cap_idx; 761 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 762 763 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 764 765 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) 766 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC; 767 else 768 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB; 769 770 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 771 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 772 RTE_CRYPTO_CIPHER_OP_DECRYPT; 773 cipher_xform->key.data = vec.cipher_auth.key.val; 774 cipher_xform->key.length = vec.cipher_auth.key.len; 775 if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC) { 776 cipher_xform->iv.length = vec.iv.len; 777 cipher_xform->iv.offset = IV_OFF; 778 } else { 779 cipher_xform->iv.length = 0; 780 cipher_xform->iv.offset = 0; 781 } 782 cap_idx.algo.cipher = cipher_xform->algo; 783 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 784 785 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 786 if (!cap) { 787 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 788 env.dev_id); 789 return -EINVAL; 790 } 791 792 if (rte_cryptodev_sym_capability_check_cipher(cap, 793 cipher_xform->key.length, 794 cipher_xform->iv.length) != 0) { 795 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 796 info.device_name, cipher_xform->key.length, 797 cipher_xform->iv.length); 798 return -EPERM; 799 } 800 801 return 0; 802 } 803 804 static int 805 prepare_tdes_xform(struct rte_crypto_sym_xform *xform) 806 { 807 const struct rte_cryptodev_symmetric_capability *cap; 808 struct rte_cryptodev_sym_capability_idx cap_idx; 809 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 810 811 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 812 813 if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC) 814 cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC; 815 else 816 cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB; 817 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 818 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 819 RTE_CRYPTO_CIPHER_OP_DECRYPT; 820 cipher_xform->key.data = vec.cipher_auth.key.val; 821 cipher_xform->key.length = vec.cipher_auth.key.len; 822 823 if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) { 824 cipher_xform->iv.length = vec.iv.len; 825 cipher_xform->iv.offset = IV_OFF; 826 } else { 827 cipher_xform->iv.length = 0; 828 cipher_xform->iv.offset = 0; 829 } 830 cap_idx.algo.cipher = cipher_xform->algo; 831 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 832 833 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 834 if (!cap) { 835 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 836 env.dev_id); 837 return -EINVAL; 838 } 839 840 if (rte_cryptodev_sym_capability_check_cipher(cap, 841 cipher_xform->key.length, 842 cipher_xform->iv.length) != 0) { 843 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 844 info.device_name, cipher_xform->key.length, 845 cipher_xform->iv.length); 846 return -EPERM; 847 } 848 849 return 0; 850 } 851 852 static int 853 prepare_hmac_xform(struct rte_crypto_sym_xform *xform) 854 { 855 const struct rte_cryptodev_symmetric_capability *cap; 856 struct rte_cryptodev_sym_capability_idx cap_idx; 857 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 858 859 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 860 861 auth_xform->algo = info.interim_info.hmac_data.algo; 862 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 863 auth_xform->digest_length = vec.cipher_auth.digest.len; 864 auth_xform->key.data = vec.cipher_auth.key.val; 865 auth_xform->key.length = vec.cipher_auth.key.len; 866 867 cap_idx.algo.auth = auth_xform->algo; 868 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 869 870 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 871 if (!cap) { 872 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 873 env.dev_id); 874 return -EINVAL; 875 } 876 877 if (rte_cryptodev_sym_capability_check_auth(cap, 878 auth_xform->key.length, 879 auth_xform->digest_length, 0) != 0) { 880 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 881 info.device_name, auth_xform->key.length, 882 auth_xform->digest_length); 883 return -EPERM; 884 } 885 886 return 0; 887 } 888 889 int 890 prepare_gcm_xform(struct rte_crypto_sym_xform *xform) 891 { 892 const struct rte_cryptodev_symmetric_capability *cap; 893 struct rte_cryptodev_sym_capability_idx cap_idx; 894 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 895 896 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 897 898 aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM; 899 aead_xform->aad_length = vec.aead.aad.len; 900 aead_xform->digest_length = vec.aead.digest.len; 901 aead_xform->iv.offset = IV_OFF; 902 aead_xform->iv.length = vec.iv.len; 903 aead_xform->key.data = vec.aead.key.val; 904 aead_xform->key.length = vec.aead.key.len; 905 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 906 RTE_CRYPTO_AEAD_OP_ENCRYPT : 907 RTE_CRYPTO_AEAD_OP_DECRYPT; 908 909 cap_idx.algo.aead = aead_xform->algo; 910 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 911 912 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 913 if (!cap) { 914 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 915 env.dev_id); 916 return -EINVAL; 917 } 918 919 if (rte_cryptodev_sym_capability_check_aead(cap, 920 aead_xform->key.length, 921 aead_xform->digest_length, aead_xform->aad_length, 922 aead_xform->iv.length) != 0) { 923 RTE_LOG(ERR, USER1, 924 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 925 info.device_name, aead_xform->key.length, 926 aead_xform->digest_length, 927 aead_xform->aad_length, 928 aead_xform->iv.length); 929 return -EPERM; 930 } 931 932 return 0; 933 } 934 935 int 936 prepare_gmac_xform(struct rte_crypto_sym_xform *xform) 937 { 938 const struct rte_cryptodev_symmetric_capability *cap; 939 struct rte_cryptodev_sym_capability_idx cap_idx; 940 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 941 942 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 943 944 auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC; 945 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 946 RTE_CRYPTO_AUTH_OP_GENERATE : 947 RTE_CRYPTO_AUTH_OP_VERIFY; 948 auth_xform->iv.offset = IV_OFF; 949 auth_xform->iv.length = vec.iv.len; 950 auth_xform->digest_length = vec.aead.digest.len; 951 auth_xform->key.data = vec.aead.key.val; 952 auth_xform->key.length = vec.aead.key.len; 953 954 cap_idx.algo.auth = auth_xform->algo; 955 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 956 957 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 958 if (!cap) { 959 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 960 env.dev_id); 961 return -EINVAL; 962 } 963 964 if (rte_cryptodev_sym_capability_check_auth(cap, 965 auth_xform->key.length, 966 auth_xform->digest_length, 967 auth_xform->iv.length) != 0) { 968 969 RTE_LOG(ERR, USER1, 970 "PMD %s key length %u Digest length %u IV length %u\n", 971 info.device_name, auth_xform->key.length, 972 auth_xform->digest_length, 973 auth_xform->iv.length); 974 return -EPERM; 975 } 976 977 return 0; 978 } 979 980 static int 981 prepare_cmac_xform(struct rte_crypto_sym_xform *xform) 982 { 983 const struct rte_cryptodev_symmetric_capability *cap; 984 struct rte_cryptodev_sym_capability_idx cap_idx; 985 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 986 987 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 988 989 auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC; 990 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 991 RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY; 992 auth_xform->digest_length = vec.cipher_auth.digest.len; 993 auth_xform->key.data = vec.cipher_auth.key.val; 994 auth_xform->key.length = vec.cipher_auth.key.len; 995 996 cap_idx.algo.auth = auth_xform->algo; 997 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 998 999 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1000 if (!cap) { 1001 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1002 env.dev_id); 1003 return -EINVAL; 1004 } 1005 1006 if (rte_cryptodev_sym_capability_check_auth(cap, 1007 auth_xform->key.length, 1008 auth_xform->digest_length, 0) != 0) { 1009 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1010 info.device_name, auth_xform->key.length, 1011 auth_xform->digest_length); 1012 return -EPERM; 1013 } 1014 1015 return 0; 1016 } 1017 1018 static int 1019 prepare_ccm_xform(struct rte_crypto_sym_xform *xform) 1020 { 1021 const struct rte_cryptodev_symmetric_capability *cap; 1022 struct rte_cryptodev_sym_capability_idx cap_idx; 1023 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 1024 1025 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 1026 1027 aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM; 1028 aead_xform->aad_length = vec.aead.aad.len; 1029 aead_xform->digest_length = vec.aead.digest.len; 1030 aead_xform->iv.offset = IV_OFF; 1031 aead_xform->iv.length = vec.iv.len; 1032 aead_xform->key.data = vec.aead.key.val; 1033 aead_xform->key.length = vec.aead.key.len; 1034 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1035 RTE_CRYPTO_AEAD_OP_ENCRYPT : 1036 RTE_CRYPTO_AEAD_OP_DECRYPT; 1037 1038 cap_idx.algo.aead = aead_xform->algo; 1039 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 1040 1041 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1042 if (!cap) { 1043 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1044 env.dev_id); 1045 return -EINVAL; 1046 } 1047 1048 if (rte_cryptodev_sym_capability_check_aead(cap, 1049 aead_xform->key.length, 1050 aead_xform->digest_length, aead_xform->aad_length, 1051 aead_xform->iv.length) != 0) { 1052 RTE_LOG(ERR, USER1, 1053 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 1054 info.device_name, aead_xform->key.length, 1055 aead_xform->digest_length, 1056 aead_xform->aad_length, 1057 aead_xform->iv.length); 1058 return -EPERM; 1059 } 1060 1061 return 0; 1062 } 1063 1064 static int 1065 prepare_sha_xform(struct rte_crypto_sym_xform *xform) 1066 { 1067 const struct rte_cryptodev_symmetric_capability *cap; 1068 struct rte_cryptodev_sym_capability_idx cap_idx; 1069 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1070 1071 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1072 1073 auth_xform->algo = info.interim_info.sha_data.algo; 1074 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 1075 auth_xform->digest_length = vec.cipher_auth.digest.len; 1076 1077 cap_idx.algo.auth = auth_xform->algo; 1078 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1079 1080 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1081 if (!cap) { 1082 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1083 env.dev_id); 1084 return -EINVAL; 1085 } 1086 1087 if (rte_cryptodev_sym_capability_check_auth(cap, 1088 auth_xform->key.length, 1089 auth_xform->digest_length, 0) != 0) { 1090 RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n", 1091 info.device_name, auth_xform->key.length, 1092 auth_xform->digest_length); 1093 return -EPERM; 1094 } 1095 1096 return 0; 1097 } 1098 1099 static int 1100 prepare_xts_xform(struct rte_crypto_sym_xform *xform) 1101 { 1102 const struct rte_cryptodev_symmetric_capability *cap; 1103 struct rte_cryptodev_sym_capability_idx cap_idx; 1104 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1105 1106 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1107 1108 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS; 1109 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1110 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1111 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1112 cipher_xform->key.data = vec.cipher_auth.key.val; 1113 cipher_xform->key.length = vec.cipher_auth.key.len; 1114 cipher_xform->iv.length = vec.iv.len; 1115 cipher_xform->iv.offset = IV_OFF; 1116 1117 cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS; 1118 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1119 1120 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1121 if (!cap) { 1122 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1123 env.dev_id); 1124 return -EINVAL; 1125 } 1126 1127 if (rte_cryptodev_sym_capability_check_cipher(cap, 1128 cipher_xform->key.length, 1129 cipher_xform->iv.length) != 0) { 1130 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1131 info.device_name, cipher_xform->key.length, 1132 cipher_xform->iv.length); 1133 return -EPERM; 1134 } 1135 1136 return 0; 1137 } 1138 1139 static int 1140 get_writeback_data(struct fips_val *val) 1141 { 1142 struct rte_mbuf *m = env.mbuf; 1143 uint16_t data_len = rte_pktmbuf_pkt_len(m); 1144 uint16_t total_len = data_len + env.digest_len; 1145 uint8_t *src, *dst, *wb_data; 1146 1147 /* in case val is reused for MCT test, try to free the buffer first */ 1148 if (val->val) { 1149 free(val->val); 1150 val->val = NULL; 1151 } 1152 1153 wb_data = dst = calloc(1, total_len); 1154 if (!dst) { 1155 RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM); 1156 return -ENOMEM; 1157 } 1158 1159 while (m && data_len) { 1160 uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len); 1161 1162 src = rte_pktmbuf_mtod(m, uint8_t *); 1163 memcpy(dst, src, seg_len); 1164 m = m->next; 1165 data_len -= seg_len; 1166 dst += seg_len; 1167 } 1168 1169 if (data_len) { 1170 RTE_LOG(ERR, USER1, "Error -1: write back data\n"); 1171 free(wb_data); 1172 return -1; 1173 } 1174 1175 if (env.digest) 1176 memcpy(dst, env.digest, env.digest_len); 1177 1178 val->val = wb_data; 1179 val->len = total_len; 1180 1181 return 0; 1182 } 1183 1184 static int 1185 fips_run_test(void) 1186 { 1187 struct rte_crypto_sym_xform xform = {0}; 1188 uint16_t n_deqd; 1189 int ret; 1190 1191 ret = test_ops.prepare_xform(&xform); 1192 if (ret < 0) 1193 return ret; 1194 1195 env.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform, 1196 env.sess_mpool); 1197 if (!env.sess) { 1198 RTE_LOG(ERR, USER1, "Error %i: Init session\n", 1199 ret); 1200 goto exit; 1201 } 1202 1203 ret = test_ops.prepare_op(); 1204 if (ret < 0) { 1205 RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", 1206 ret); 1207 goto exit; 1208 } 1209 1210 if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 1211 RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 1212 ret = -1; 1213 goto exit; 1214 } 1215 1216 do { 1217 struct rte_crypto_op *deqd_op; 1218 1219 n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1220 1); 1221 } while (n_deqd == 0); 1222 1223 vec.status = env.op->status; 1224 1225 exit: 1226 if (env.sess) { 1227 rte_cryptodev_sym_session_free(env.dev_id, env.sess); 1228 env.sess = NULL; 1229 } 1230 1231 return ret; 1232 } 1233 1234 static int 1235 fips_generic_test(void) 1236 { 1237 struct fips_val val = {NULL, 0}; 1238 int ret; 1239 1240 if (info.file_type != FIPS_TYPE_JSON) 1241 fips_test_write_one_case(); 1242 1243 ret = fips_run_test(); 1244 if (ret < 0) { 1245 if (ret == -EPERM || ret == -ENOTSUP) { 1246 if (info.file_type == FIPS_TYPE_JSON) 1247 return ret; 1248 1249 fprintf(info.fp_wr, "Bypass\n\n"); 1250 return 0; 1251 } 1252 1253 return ret; 1254 } 1255 1256 ret = get_writeback_data(&val); 1257 if (ret < 0) 1258 return ret; 1259 1260 switch (info.file_type) { 1261 case FIPS_TYPE_REQ: 1262 case FIPS_TYPE_RSP: 1263 case FIPS_TYPE_JSON: 1264 if (info.parse_writeback == NULL) 1265 return -EPERM; 1266 ret = info.parse_writeback(&val); 1267 if (ret < 0) 1268 return ret; 1269 break; 1270 case FIPS_TYPE_FAX: 1271 if (info.kat_check == NULL) 1272 return -EPERM; 1273 ret = info.kat_check(&val); 1274 if (ret < 0) 1275 return ret; 1276 break; 1277 default: 1278 break; 1279 } 1280 1281 if (info.file_type != FIPS_TYPE_JSON) 1282 fprintf(info.fp_wr, "\n"); 1283 free(val.val); 1284 1285 return 0; 1286 } 1287 1288 static int 1289 fips_mct_tdes_test(void) 1290 { 1291 #define TDES_BLOCK_SIZE 8 1292 #define TDES_EXTERN_ITER 400 1293 #define TDES_INTERN_ITER 10000 1294 struct fips_val val = {NULL, 0}, val_key; 1295 uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; 1296 uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; 1297 uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; 1298 uint32_t i, j, k; 1299 int ret; 1300 int test_mode = info.interim_info.tdes_data.test_mode; 1301 1302 for (i = 0; i < TDES_EXTERN_ITER; i++) { 1303 if ((i == 0) && (info.version == 21.4f)) { 1304 if (!(strstr(info.vec[0], "COUNT"))) 1305 fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0); 1306 } 1307 1308 if (i != 0) 1309 update_info_vec(i); 1310 1311 fips_test_write_one_case(); 1312 1313 for (j = 0; j < TDES_INTERN_ITER; j++) { 1314 ret = fips_run_test(); 1315 if (ret < 0) { 1316 if (ret == -EPERM) { 1317 if (info.file_type == FIPS_TYPE_JSON) 1318 return ret; 1319 1320 fprintf(info.fp_wr, "Bypass\n"); 1321 return 0; 1322 } 1323 return ret; 1324 } 1325 1326 ret = get_writeback_data(&val); 1327 if (ret < 0) 1328 return ret; 1329 1330 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1331 memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 1332 1333 if (j == 0) { 1334 memcpy(prev_out, val.val, TDES_BLOCK_SIZE); 1335 1336 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1337 if (test_mode == TDES_MODE_ECB) { 1338 memcpy(vec.pt.val, val.val, 1339 TDES_BLOCK_SIZE); 1340 } else { 1341 memcpy(vec.pt.val, vec.iv.val, 1342 TDES_BLOCK_SIZE); 1343 memcpy(vec.iv.val, val.val, 1344 TDES_BLOCK_SIZE); 1345 } 1346 1347 } else { 1348 if (test_mode == TDES_MODE_ECB) { 1349 memcpy(vec.ct.val, val.val, 1350 TDES_BLOCK_SIZE); 1351 } else { 1352 memcpy(vec.iv.val, vec.ct.val, 1353 TDES_BLOCK_SIZE); 1354 memcpy(vec.ct.val, val.val, 1355 TDES_BLOCK_SIZE); 1356 } 1357 } 1358 continue; 1359 } 1360 1361 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1362 if (test_mode == TDES_MODE_ECB) { 1363 memcpy(vec.pt.val, val.val, 1364 TDES_BLOCK_SIZE); 1365 } else { 1366 memcpy(vec.iv.val, val.val, 1367 TDES_BLOCK_SIZE); 1368 memcpy(vec.pt.val, prev_out, 1369 TDES_BLOCK_SIZE); 1370 } 1371 } else { 1372 if (test_mode == TDES_MODE_ECB) { 1373 memcpy(vec.ct.val, val.val, 1374 TDES_BLOCK_SIZE); 1375 } else { 1376 memcpy(vec.iv.val, vec.ct.val, 1377 TDES_BLOCK_SIZE); 1378 memcpy(vec.ct.val, val.val, 1379 TDES_BLOCK_SIZE); 1380 } 1381 } 1382 1383 if (j == TDES_INTERN_ITER - 1) 1384 continue; 1385 1386 memcpy(prev_out, val.val, TDES_BLOCK_SIZE); 1387 1388 if (j == TDES_INTERN_ITER - 3) 1389 memcpy(prev_prev_out, val.val, TDES_BLOCK_SIZE); 1390 } 1391 1392 info.parse_writeback(&val); 1393 fprintf(info.fp_wr, "\n"); 1394 1395 if (i == TDES_EXTERN_ITER - 1) 1396 continue; 1397 1398 /** update key */ 1399 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1400 1401 if (info.interim_info.tdes_data.nb_keys == 0) { 1402 if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 1403 info.interim_info.tdes_data.nb_keys = 1; 1404 else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 1405 info.interim_info.tdes_data.nb_keys = 2; 1406 else 1407 info.interim_info.tdes_data.nb_keys = 3; 1408 1409 } 1410 1411 for (k = 0; k < TDES_BLOCK_SIZE; k++) { 1412 1413 switch (info.interim_info.tdes_data.nb_keys) { 1414 case 3: 1415 val_key.val[k] ^= val.val[k]; 1416 val_key.val[k + 8] ^= prev_out[k]; 1417 val_key.val[k + 16] ^= prev_prev_out[k]; 1418 break; 1419 case 2: 1420 val_key.val[k] ^= val.val[k]; 1421 val_key.val[k + 8] ^= prev_out[k]; 1422 val_key.val[k + 16] ^= val.val[k]; 1423 break; 1424 default: /* case 1 */ 1425 val_key.val[k] ^= val.val[k]; 1426 val_key.val[k + 8] ^= val.val[k]; 1427 val_key.val[k + 16] ^= val.val[k]; 1428 break; 1429 } 1430 1431 } 1432 1433 for (k = 0; k < 24; k++) 1434 val_key.val[k] = (__builtin_popcount(val_key.val[k]) & 1435 0x1) ? 1436 val_key.val[k] : (val_key.val[k] ^ 0x1); 1437 1438 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1439 if (test_mode == TDES_MODE_ECB) { 1440 memcpy(vec.pt.val, val.val, TDES_BLOCK_SIZE); 1441 } else { 1442 memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE); 1443 memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 1444 } 1445 } else { 1446 if (test_mode == TDES_MODE_ECB) { 1447 memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); 1448 } else { 1449 memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 1450 memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); 1451 } 1452 } 1453 } 1454 1455 free(val.val); 1456 1457 return 0; 1458 } 1459 1460 static int 1461 fips_mct_aes_ecb_test(void) 1462 { 1463 #define AES_BLOCK_SIZE 16 1464 #define AES_EXTERN_ITER 100 1465 #define AES_INTERN_ITER 1000 1466 struct fips_val val = {NULL, 0}, val_key; 1467 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1468 uint32_t i, j, k; 1469 int ret; 1470 1471 for (i = 0; i < AES_EXTERN_ITER; i++) { 1472 if (i != 0) 1473 update_info_vec(i); 1474 1475 fips_test_write_one_case(); 1476 1477 for (j = 0; j < AES_INTERN_ITER; j++) { 1478 ret = fips_run_test(); 1479 if (ret < 0) { 1480 if (ret == -EPERM) { 1481 if (info.file_type == FIPS_TYPE_JSON) 1482 return ret; 1483 1484 fprintf(info.fp_wr, "Bypass\n"); 1485 return 0; 1486 } 1487 1488 return ret; 1489 } 1490 1491 ret = get_writeback_data(&val); 1492 if (ret < 0) 1493 return ret; 1494 1495 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 1496 memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); 1497 else 1498 memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); 1499 1500 if (j == AES_INTERN_ITER - 1) 1501 continue; 1502 1503 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1504 } 1505 1506 info.parse_writeback(&val); 1507 fprintf(info.fp_wr, "\n"); 1508 1509 if (i == AES_EXTERN_ITER - 1) 1510 continue; 1511 1512 /** update key */ 1513 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1514 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1515 switch (vec.cipher_auth.key.len) { 1516 case 16: 1517 val_key.val[k] ^= val.val[k]; 1518 break; 1519 case 24: 1520 if (k < 8) 1521 val_key.val[k] ^= prev_out[k + 8]; 1522 else 1523 val_key.val[k] ^= val.val[k - 8]; 1524 break; 1525 case 32: 1526 if (k < 16) 1527 val_key.val[k] ^= prev_out[k]; 1528 else 1529 val_key.val[k] ^= val.val[k - 16]; 1530 break; 1531 default: 1532 return -1; 1533 } 1534 } 1535 } 1536 1537 free(val.val); 1538 1539 return 0; 1540 } 1541 static int 1542 fips_mct_aes_test(void) 1543 { 1544 #define AES_BLOCK_SIZE 16 1545 #define AES_EXTERN_ITER 100 1546 #define AES_INTERN_ITER 1000 1547 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 1548 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1549 uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 1550 uint32_t i, j, k; 1551 int ret; 1552 1553 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) 1554 return fips_mct_aes_ecb_test(); 1555 1556 memset(&pt, 0, sizeof(struct fips_val)); 1557 memset(&ct, 0, sizeof(struct fips_val)); 1558 memset(&iv, 0, sizeof(struct fips_val)); 1559 for (i = 0; i < AES_EXTERN_ITER; i++) { 1560 if (info.file_type != FIPS_TYPE_JSON) { 1561 if (i != 0) 1562 update_info_vec(i); 1563 1564 fips_test_write_one_case(); 1565 } 1566 1567 for (j = 0; j < AES_INTERN_ITER; j++) { 1568 ret = fips_run_test(); 1569 if (ret < 0) { 1570 if (ret == -EPERM) { 1571 if (info.file_type == FIPS_TYPE_JSON) 1572 return ret; 1573 1574 fprintf(info.fp_wr, "Bypass\n"); 1575 return 0; 1576 } 1577 1578 return ret; 1579 } 1580 1581 ret = get_writeback_data(&val[0]); 1582 if (ret < 0) 1583 return ret; 1584 1585 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1586 memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 1587 1588 if (j == 0) { 1589 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 1590 pt.len = vec.pt.len; 1591 pt.val = calloc(1, pt.len); 1592 memcpy(pt.val, vec.pt.val, pt.len); 1593 1594 ct.len = vec.ct.len; 1595 ct.val = calloc(1, ct.len); 1596 memcpy(ct.val, vec.ct.val, ct.len); 1597 1598 iv.len = vec.iv.len; 1599 iv.val = calloc(1, iv.len); 1600 memcpy(iv.val, vec.iv.val, iv.len); 1601 1602 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1603 memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE); 1604 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1605 val[1].val = pt.val; 1606 val[1].len = pt.len; 1607 val[2].val = iv.val; 1608 val[2].len = iv.len; 1609 } else { 1610 memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE); 1611 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1612 val[1].val = ct.val; 1613 val[1].len = ct.len; 1614 val[2].val = iv.val; 1615 val[2].len = iv.len; 1616 } 1617 continue; 1618 } 1619 1620 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1621 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1622 memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 1623 } else { 1624 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1625 memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 1626 } 1627 1628 if (j == AES_INTERN_ITER - 1) 1629 continue; 1630 1631 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 1632 } 1633 1634 info.parse_writeback(val); 1635 if (info.file_type != FIPS_TYPE_JSON) 1636 fprintf(info.fp_wr, "\n"); 1637 1638 if (i == AES_EXTERN_ITER - 1) { 1639 free(pt.val); 1640 free(ct.val); 1641 free(iv.val); 1642 continue; 1643 } 1644 1645 /** update key */ 1646 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1647 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1648 switch (vec.cipher_auth.key.len) { 1649 case 16: 1650 val_key.val[k] ^= val[0].val[k]; 1651 break; 1652 case 24: 1653 if (k < 8) 1654 val_key.val[k] ^= prev_out[k + 8]; 1655 else 1656 val_key.val[k] ^= val[0].val[k - 8]; 1657 break; 1658 case 32: 1659 if (k < 16) 1660 val_key.val[k] ^= prev_out[k]; 1661 else 1662 val_key.val[k] ^= val[0].val[k - 16]; 1663 break; 1664 default: 1665 return -1; 1666 } 1667 } 1668 1669 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1670 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1671 } 1672 1673 free(val[0].val); 1674 1675 return 0; 1676 } 1677 1678 static int 1679 fips_mct_sha_test(void) 1680 { 1681 #define SHA_EXTERN_ITER 100 1682 #define SHA_INTERN_ITER 1000 1683 #define SHA_MD_BLOCK 3 1684 /* val[0] is op result and other value is for parse_writeback callback */ 1685 struct fips_val val[2] = {{NULL, 0},}; 1686 struct fips_val md[SHA_MD_BLOCK], msg; 1687 char temp[MAX_DIGEST_SIZE*2]; 1688 int ret; 1689 uint32_t i, j; 1690 1691 msg.len = SHA_MD_BLOCK * vec.cipher_auth.digest.len; 1692 msg.val = calloc(1, msg.len); 1693 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len); 1694 for (i = 0; i < SHA_MD_BLOCK; i++) 1695 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 1696 1697 rte_free(vec.pt.val); 1698 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); 1699 1700 if (info.file_type != FIPS_TYPE_JSON) { 1701 fips_test_write_one_case(); 1702 fprintf(info.fp_wr, "\n"); 1703 } 1704 1705 for (j = 0; j < SHA_EXTERN_ITER; j++) { 1706 1707 memcpy(md[0].val, vec.cipher_auth.digest.val, 1708 vec.cipher_auth.digest.len); 1709 md[0].len = vec.cipher_auth.digest.len; 1710 memcpy(md[1].val, vec.cipher_auth.digest.val, 1711 vec.cipher_auth.digest.len); 1712 md[1].len = vec.cipher_auth.digest.len; 1713 memcpy(md[2].val, vec.cipher_auth.digest.val, 1714 vec.cipher_auth.digest.len); 1715 md[2].len = vec.cipher_auth.digest.len; 1716 1717 for (i = 0; i < SHA_MD_BLOCK; i++) 1718 memcpy(&msg.val[i * md[i].len], md[i].val, md[i].len); 1719 1720 for (i = 0; i < (SHA_INTERN_ITER); i++) { 1721 1722 memcpy(vec.pt.val, md[0].val, 1723 (size_t)md[0].len); 1724 memcpy((vec.pt.val + md[0].len), md[1].val, 1725 (size_t)md[1].len); 1726 memcpy((vec.pt.val + md[0].len + md[1].len), 1727 md[2].val, 1728 (size_t)md[2].len); 1729 vec.pt.len = md[0].len + md[1].len + md[2].len; 1730 1731 ret = fips_run_test(); 1732 if (ret < 0) { 1733 if (ret == -EPERM || ret == -ENOTSUP) { 1734 if (info.file_type == FIPS_TYPE_JSON) 1735 return ret; 1736 1737 fprintf(info.fp_wr, "Bypass\n\n"); 1738 return 0; 1739 } 1740 return ret; 1741 } 1742 1743 ret = get_writeback_data(&val[0]); 1744 if (ret < 0) 1745 return ret; 1746 1747 memcpy(md[0].val, md[1].val, md[1].len); 1748 md[0].len = md[1].len; 1749 memcpy(md[1].val, md[2].val, md[2].len); 1750 md[1].len = md[2].len; 1751 1752 memcpy(md[2].val, (val[0].val + vec.pt.len), 1753 vec.cipher_auth.digest.len); 1754 md[2].len = vec.cipher_auth.digest.len; 1755 } 1756 1757 memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len); 1758 vec.cipher_auth.digest.len = md[2].len; 1759 1760 if (info.file_type != FIPS_TYPE_JSON) { 1761 fprintf(info.fp_wr, "COUNT = %u\n", j); 1762 writeback_hex_str("", temp, &vec.cipher_auth.digest); 1763 fprintf(info.fp_wr, "MD = %s\n\n", temp); 1764 } 1765 val[1].val = msg.val; 1766 val[1].len = msg.len; 1767 info.parse_writeback(val); 1768 } 1769 1770 for (i = 0; i < (SHA_MD_BLOCK); i++) 1771 rte_free(md[i].val); 1772 1773 rte_free(vec.pt.val); 1774 1775 free(val[0].val); 1776 free(msg.val); 1777 1778 return 0; 1779 } 1780 1781 1782 static int 1783 init_test_ops(void) 1784 { 1785 switch (info.algo) { 1786 case FIPS_TEST_ALGO_AES_CBC: 1787 case FIPS_TEST_ALGO_AES: 1788 test_ops.prepare_op = prepare_cipher_op; 1789 test_ops.prepare_xform = prepare_aes_xform; 1790 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 1791 test_ops.test = fips_mct_aes_test; 1792 else 1793 test_ops.test = fips_generic_test; 1794 break; 1795 case FIPS_TEST_ALGO_HMAC: 1796 test_ops.prepare_op = prepare_auth_op; 1797 test_ops.prepare_xform = prepare_hmac_xform; 1798 test_ops.test = fips_generic_test; 1799 break; 1800 case FIPS_TEST_ALGO_TDES: 1801 test_ops.prepare_op = prepare_cipher_op; 1802 test_ops.prepare_xform = prepare_tdes_xform; 1803 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1804 test_ops.test = fips_mct_tdes_test; 1805 else 1806 test_ops.test = fips_generic_test; 1807 break; 1808 case FIPS_TEST_ALGO_AES_GCM: 1809 test_ops.prepare_op = prepare_aead_op; 1810 test_ops.prepare_xform = prepare_gcm_xform; 1811 test_ops.test = fips_generic_test; 1812 break; 1813 case FIPS_TEST_ALGO_AES_CMAC: 1814 test_ops.prepare_op = prepare_auth_op; 1815 test_ops.prepare_xform = prepare_cmac_xform; 1816 test_ops.test = fips_generic_test; 1817 break; 1818 case FIPS_TEST_ALGO_AES_CCM: 1819 test_ops.prepare_op = prepare_aead_op; 1820 test_ops.prepare_xform = prepare_ccm_xform; 1821 test_ops.test = fips_generic_test; 1822 break; 1823 case FIPS_TEST_ALGO_SHA: 1824 test_ops.prepare_op = prepare_auth_op; 1825 test_ops.prepare_xform = prepare_sha_xform; 1826 if (info.interim_info.sha_data.test_type == SHA_MCT) 1827 test_ops.test = fips_mct_sha_test; 1828 else 1829 test_ops.test = fips_generic_test; 1830 break; 1831 case FIPS_TEST_ALGO_AES_XTS: 1832 test_ops.prepare_op = prepare_cipher_op; 1833 test_ops.prepare_xform = prepare_xts_xform; 1834 test_ops.test = fips_generic_test; 1835 break; 1836 default: 1837 if (strstr(info.file_name, "TECB") || 1838 strstr(info.file_name, "TCBC")) { 1839 info.algo = FIPS_TEST_ALGO_TDES; 1840 test_ops.prepare_op = prepare_cipher_op; 1841 test_ops.prepare_xform = prepare_tdes_xform; 1842 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1843 test_ops.test = fips_mct_tdes_test; 1844 else 1845 test_ops.test = fips_generic_test; 1846 break; 1847 } 1848 return -1; 1849 } 1850 1851 return 0; 1852 } 1853 1854 static void 1855 print_test_block(void) 1856 { 1857 uint32_t i; 1858 1859 for (i = 0; i < info.nb_vec_lines; i++) 1860 printf("%s\n", info.vec[i]); 1861 1862 printf("\n"); 1863 } 1864 1865 static int 1866 fips_test_one_file(void) 1867 { 1868 int fetch_ret = 0, ret; 1869 1870 ret = init_test_ops(); 1871 if (ret < 0) { 1872 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 1873 return ret; 1874 } 1875 1876 while (ret >= 0 && fetch_ret == 0) { 1877 fetch_ret = fips_test_fetch_one_block(); 1878 if (fetch_ret < 0) { 1879 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 1880 fetch_ret); 1881 ret = fetch_ret; 1882 goto error_one_case; 1883 } 1884 1885 if (info.nb_vec_lines == 0) { 1886 if (fetch_ret == -EOF) 1887 break; 1888 1889 fprintf(info.fp_wr, "\n"); 1890 continue; 1891 } 1892 1893 ret = fips_test_parse_one_case(); 1894 switch (ret) { 1895 case 0: 1896 ret = test_ops.test(); 1897 if (ret == 0) 1898 break; 1899 RTE_LOG(ERR, USER1, "Error %i: test block\n", 1900 ret); 1901 goto error_one_case; 1902 case 1: 1903 break; 1904 default: 1905 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 1906 ret); 1907 goto error_one_case; 1908 } 1909 1910 continue; 1911 error_one_case: 1912 print_test_block(); 1913 } 1914 1915 fips_test_clear(); 1916 1917 if (env.digest) { 1918 rte_free(env.digest); 1919 env.digest = NULL; 1920 } 1921 rte_pktmbuf_free(env.mbuf); 1922 1923 return ret; 1924 } 1925 1926 #ifdef USE_JANSSON 1927 static int 1928 fips_test_json_init_writeback(void) 1929 { 1930 json_t *session_info, *session_write; 1931 session_info = json_array_get(json_info.json_root, 0); 1932 session_write = json_object(); 1933 json_info.json_write_root = json_array(); 1934 1935 json_object_set(session_write, "jwt", 1936 json_object_get(session_info, "jwt")); 1937 json_object_set(session_write, "url", 1938 json_object_get(session_info, "url")); 1939 json_object_set(session_write, "isSample", 1940 json_object_get(session_info, "isSample")); 1941 1942 json_info.is_sample = json_boolean_value( 1943 json_object_get(session_info, "isSample")); 1944 1945 json_array_append_new(json_info.json_write_root, session_write); 1946 return 0; 1947 } 1948 1949 static int 1950 fips_test_one_test_case(void) 1951 { 1952 int ret; 1953 1954 ret = fips_test_parse_one_json_case(); 1955 1956 switch (ret) { 1957 case 0: 1958 ret = test_ops.test(); 1959 if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP)) 1960 break; 1961 RTE_LOG(ERR, USER1, "Error %i: test block\n", 1962 ret); 1963 break; 1964 default: 1965 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 1966 ret); 1967 } 1968 return ret; 1969 } 1970 1971 static int 1972 fips_test_one_test_group(void) 1973 { 1974 int ret; 1975 json_t *tests, *write_tests; 1976 size_t test_idx, tests_size; 1977 1978 write_tests = json_array(); 1979 json_info.json_write_group = json_object(); 1980 json_object_set(json_info.json_write_group, "tgId", 1981 json_object_get(json_info.json_test_group, "tgId")); 1982 json_object_set_new(json_info.json_write_group, "tests", write_tests); 1983 1984 switch (info.algo) { 1985 case FIPS_TEST_ALGO_AES_GCM: 1986 ret = parse_test_gcm_json_init(); 1987 break; 1988 case FIPS_TEST_ALGO_HMAC: 1989 ret = parse_test_hmac_json_init(); 1990 break; 1991 case FIPS_TEST_ALGO_AES_CMAC: 1992 ret = parse_test_cmac_json_init(); 1993 break; 1994 case FIPS_TEST_ALGO_AES_XTS: 1995 ret = parse_test_xts_json_init(); 1996 break; 1997 case FIPS_TEST_ALGO_AES_CBC: 1998 case FIPS_TEST_ALGO_AES: 1999 ret = parse_test_aes_json_init(); 2000 break; 2001 case FIPS_TEST_ALGO_SHA: 2002 ret = parse_test_sha_json_init(); 2003 break; 2004 default: 2005 return -EINVAL; 2006 } 2007 2008 if (ret < 0) 2009 return ret; 2010 2011 ret = fips_test_parse_one_json_group(); 2012 if (ret < 0) 2013 return ret; 2014 2015 ret = init_test_ops(); 2016 if (ret < 0) 2017 return ret; 2018 2019 tests = json_object_get(json_info.json_test_group, "tests"); 2020 tests_size = json_array_size(tests); 2021 for (test_idx = 0; test_idx < tests_size; test_idx++) { 2022 json_info.json_test_case = json_array_get(tests, test_idx); 2023 if (fips_test_one_test_case() == 0) 2024 json_array_append_new(write_tests, json_info.json_write_case); 2025 } 2026 2027 return 0; 2028 } 2029 2030 static int 2031 fips_test_one_vector_set(void) 2032 { 2033 int ret; 2034 json_t *test_groups, *write_groups, *write_version, *write_set; 2035 size_t group_idx, num_groups; 2036 2037 test_groups = json_object_get(json_info.json_vector_set, "testGroups"); 2038 num_groups = json_array_size(test_groups); 2039 2040 json_info.json_write_set = json_array(); 2041 write_version = json_object(); 2042 json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION)); 2043 json_array_append_new(json_info.json_write_set, write_version); 2044 2045 write_set = json_object(); 2046 json_array_append(json_info.json_write_set, write_set); 2047 write_groups = json_array(); 2048 2049 json_object_set(write_set, "vsId", 2050 json_object_get(json_info.json_vector_set, "vsId")); 2051 json_object_set(write_set, "algorithm", 2052 json_object_get(json_info.json_vector_set, "algorithm")); 2053 json_object_set(write_set, "revision", 2054 json_object_get(json_info.json_vector_set, "revision")); 2055 json_object_set_new(write_set, "isSample", 2056 json_boolean(json_info.is_sample)); 2057 json_object_set_new(write_set, "testGroups", write_groups); 2058 2059 ret = fips_test_parse_one_json_vector_set(); 2060 if (ret < 0) { 2061 RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n", 2062 json_string_value(json_object_get(json_info.json_vector_set, "algorithm"))); 2063 return ret; 2064 } 2065 2066 for (group_idx = 0; group_idx < num_groups; group_idx++) { 2067 json_info.json_test_group = json_array_get(test_groups, group_idx); 2068 ret = fips_test_one_test_group(); 2069 json_array_append_new(write_groups, json_info.json_write_group); 2070 } 2071 2072 return 0; 2073 } 2074 2075 static int 2076 fips_test_one_json_file(void) 2077 { 2078 size_t vector_set_idx, root_size; 2079 2080 root_size = json_array_size(json_info.json_root); 2081 fips_test_json_init_writeback(); 2082 2083 for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) { 2084 /* Vector set index starts at 1, the 0th index contains test session 2085 * information. 2086 */ 2087 json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx); 2088 fips_test_one_vector_set(); 2089 json_array_append_new(json_info.json_write_root, json_info.json_write_set); 2090 json_incref(json_info.json_write_set); 2091 } 2092 2093 json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4)); 2094 json_decref(json_info.json_write_root); 2095 2096 return 0; 2097 } 2098 #endif /* USE_JANSSON */ 2099