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