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[3] = {{NULL, 0},}, val_key, pt, ct, iv; 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 pt.len = vec.pt.len; 1303 pt.val = calloc(1, pt.len); 1304 ct.len = vec.ct.len; 1305 ct.val = calloc(1, ct.len); 1306 iv.len = vec.iv.len; 1307 iv.val = calloc(1, iv.len); 1308 1309 for (i = 0; i < TDES_EXTERN_ITER; i++) { 1310 if (info.file_type != FIPS_TYPE_JSON) { 1311 if ((i == 0) && (info.version == 21.4f)) { 1312 if (!(strstr(info.vec[0], "COUNT"))) 1313 fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0); 1314 } 1315 1316 if (i != 0) 1317 update_info_vec(i); 1318 1319 fips_test_write_one_case(); 1320 } 1321 1322 for (j = 0; j < TDES_INTERN_ITER; j++) { 1323 ret = fips_run_test(); 1324 if (ret < 0) { 1325 if (ret == -EPERM) { 1326 if (info.file_type == FIPS_TYPE_JSON) 1327 return ret; 1328 1329 fprintf(info.fp_wr, "Bypass\n"); 1330 return 0; 1331 } 1332 return ret; 1333 } 1334 1335 ret = get_writeback_data(&val[0]); 1336 if (ret < 0) 1337 return ret; 1338 1339 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1340 memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 1341 1342 if (j == 0) { 1343 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 1344 memcpy(pt.val, vec.pt.val, pt.len); 1345 memcpy(ct.val, vec.ct.val, ct.len); 1346 memcpy(iv.val, vec.iv.val, iv.len); 1347 1348 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1349 if (test_mode == TDES_MODE_ECB) { 1350 memcpy(vec.pt.val, val[0].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[0].val, 1356 TDES_BLOCK_SIZE); 1357 } 1358 val[1].val = pt.val; 1359 val[1].len = pt.len; 1360 val[2].val = iv.val; 1361 val[2].len = iv.len; 1362 } else { 1363 if (test_mode == TDES_MODE_ECB) { 1364 memcpy(vec.ct.val, val[0].val, 1365 TDES_BLOCK_SIZE); 1366 } else { 1367 memcpy(vec.iv.val, vec.ct.val, 1368 TDES_BLOCK_SIZE); 1369 memcpy(vec.ct.val, val[0].val, 1370 TDES_BLOCK_SIZE); 1371 } 1372 val[1].val = ct.val; 1373 val[1].len = ct.len; 1374 val[2].val = iv.val; 1375 val[2].len = iv.len; 1376 } 1377 continue; 1378 } 1379 1380 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1381 if (test_mode == TDES_MODE_ECB) { 1382 memcpy(vec.pt.val, val[0].val, 1383 TDES_BLOCK_SIZE); 1384 } else { 1385 memcpy(vec.iv.val, val[0].val, 1386 TDES_BLOCK_SIZE); 1387 memcpy(vec.pt.val, prev_out, 1388 TDES_BLOCK_SIZE); 1389 } 1390 } else { 1391 if (test_mode == TDES_MODE_ECB) { 1392 memcpy(vec.ct.val, val[0].val, 1393 TDES_BLOCK_SIZE); 1394 } else { 1395 memcpy(vec.iv.val, vec.ct.val, 1396 TDES_BLOCK_SIZE); 1397 memcpy(vec.ct.val, val[0].val, 1398 TDES_BLOCK_SIZE); 1399 } 1400 } 1401 1402 if (j == TDES_INTERN_ITER - 1) 1403 continue; 1404 1405 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 1406 1407 if (j == TDES_INTERN_ITER - 3) 1408 memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE); 1409 } 1410 1411 info.parse_writeback(val); 1412 if (info.file_type != FIPS_TYPE_JSON) 1413 fprintf(info.fp_wr, "\n"); 1414 1415 if (i == TDES_EXTERN_ITER - 1) 1416 continue; 1417 1418 /** update key */ 1419 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1420 1421 if (info.interim_info.tdes_data.nb_keys == 0) { 1422 if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 1423 info.interim_info.tdes_data.nb_keys = 1; 1424 else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 1425 info.interim_info.tdes_data.nb_keys = 2; 1426 else 1427 info.interim_info.tdes_data.nb_keys = 3; 1428 1429 } 1430 1431 for (k = 0; k < TDES_BLOCK_SIZE; k++) { 1432 1433 switch (info.interim_info.tdes_data.nb_keys) { 1434 case 3: 1435 val_key.val[k] ^= val[0].val[k]; 1436 val_key.val[k + 8] ^= prev_out[k]; 1437 val_key.val[k + 16] ^= prev_prev_out[k]; 1438 break; 1439 case 2: 1440 val_key.val[k] ^= val[0].val[k]; 1441 val_key.val[k + 8] ^= prev_out[k]; 1442 val_key.val[k + 16] ^= val[0].val[k]; 1443 break; 1444 default: /* case 1 */ 1445 val_key.val[k] ^= val[0].val[k]; 1446 val_key.val[k + 8] ^= val[0].val[k]; 1447 val_key.val[k + 16] ^= val[0].val[k]; 1448 break; 1449 } 1450 1451 } 1452 1453 for (k = 0; k < 24; k++) 1454 val_key.val[k] = (__builtin_popcount(val_key.val[k]) & 1455 0x1) ? 1456 val_key.val[k] : (val_key.val[k] ^ 0x1); 1457 1458 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1459 if (test_mode == TDES_MODE_ECB) { 1460 memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE); 1461 } else { 1462 memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE); 1463 memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 1464 } 1465 } else { 1466 if (test_mode == TDES_MODE_ECB) { 1467 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 1468 } else { 1469 memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 1470 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 1471 } 1472 } 1473 } 1474 1475 free(val[0].val); 1476 free(pt.val); 1477 free(ct.val); 1478 free(iv.val); 1479 1480 return 0; 1481 } 1482 1483 static int 1484 fips_mct_aes_ecb_test(void) 1485 { 1486 #define AES_BLOCK_SIZE 16 1487 #define AES_EXTERN_ITER 100 1488 #define AES_INTERN_ITER 1000 1489 struct fips_val val = {NULL, 0}, val_key; 1490 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1491 uint32_t i, j, k; 1492 int ret; 1493 1494 for (i = 0; i < AES_EXTERN_ITER; i++) { 1495 if (i != 0) 1496 update_info_vec(i); 1497 1498 fips_test_write_one_case(); 1499 1500 for (j = 0; j < AES_INTERN_ITER; j++) { 1501 ret = fips_run_test(); 1502 if (ret < 0) { 1503 if (ret == -EPERM) { 1504 if (info.file_type == FIPS_TYPE_JSON) 1505 return ret; 1506 1507 fprintf(info.fp_wr, "Bypass\n"); 1508 return 0; 1509 } 1510 1511 return ret; 1512 } 1513 1514 ret = get_writeback_data(&val); 1515 if (ret < 0) 1516 return ret; 1517 1518 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 1519 memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); 1520 else 1521 memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); 1522 1523 if (j == AES_INTERN_ITER - 1) 1524 continue; 1525 1526 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1527 } 1528 1529 info.parse_writeback(&val); 1530 fprintf(info.fp_wr, "\n"); 1531 1532 if (i == AES_EXTERN_ITER - 1) 1533 continue; 1534 1535 /** update key */ 1536 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1537 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1538 switch (vec.cipher_auth.key.len) { 1539 case 16: 1540 val_key.val[k] ^= val.val[k]; 1541 break; 1542 case 24: 1543 if (k < 8) 1544 val_key.val[k] ^= prev_out[k + 8]; 1545 else 1546 val_key.val[k] ^= val.val[k - 8]; 1547 break; 1548 case 32: 1549 if (k < 16) 1550 val_key.val[k] ^= prev_out[k]; 1551 else 1552 val_key.val[k] ^= val.val[k - 16]; 1553 break; 1554 default: 1555 return -1; 1556 } 1557 } 1558 } 1559 1560 free(val.val); 1561 1562 return 0; 1563 } 1564 static int 1565 fips_mct_aes_test(void) 1566 { 1567 #define AES_BLOCK_SIZE 16 1568 #define AES_EXTERN_ITER 100 1569 #define AES_INTERN_ITER 1000 1570 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 1571 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1572 uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 1573 uint32_t i, j, k; 1574 int ret; 1575 1576 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) 1577 return fips_mct_aes_ecb_test(); 1578 1579 pt.len = vec.pt.len; 1580 pt.val = calloc(1, pt.len); 1581 ct.len = vec.ct.len; 1582 ct.val = calloc(1, ct.len); 1583 iv.len = vec.iv.len; 1584 iv.val = calloc(1, iv.len); 1585 for (i = 0; i < AES_EXTERN_ITER; i++) { 1586 if (info.file_type != FIPS_TYPE_JSON) { 1587 if (i != 0) 1588 update_info_vec(i); 1589 1590 fips_test_write_one_case(); 1591 } 1592 1593 for (j = 0; j < AES_INTERN_ITER; j++) { 1594 ret = fips_run_test(); 1595 if (ret < 0) { 1596 if (ret == -EPERM) { 1597 if (info.file_type == FIPS_TYPE_JSON) 1598 return ret; 1599 1600 fprintf(info.fp_wr, "Bypass\n"); 1601 return 0; 1602 } 1603 1604 return ret; 1605 } 1606 1607 ret = get_writeback_data(&val[0]); 1608 if (ret < 0) 1609 return ret; 1610 1611 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1612 memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 1613 1614 if (j == 0) { 1615 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 1616 memcpy(pt.val, vec.pt.val, pt.len); 1617 memcpy(ct.val, vec.ct.val, ct.len); 1618 memcpy(iv.val, vec.iv.val, iv.len); 1619 1620 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1621 memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE); 1622 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1623 val[1].val = pt.val; 1624 val[1].len = pt.len; 1625 val[2].val = iv.val; 1626 val[2].len = iv.len; 1627 } else { 1628 memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE); 1629 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1630 val[1].val = ct.val; 1631 val[1].len = ct.len; 1632 val[2].val = iv.val; 1633 val[2].len = iv.len; 1634 } 1635 continue; 1636 } 1637 1638 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1639 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1640 memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 1641 } else { 1642 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1643 memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 1644 } 1645 1646 if (j == AES_INTERN_ITER - 1) 1647 continue; 1648 1649 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 1650 } 1651 1652 info.parse_writeback(val); 1653 if (info.file_type != FIPS_TYPE_JSON) 1654 fprintf(info.fp_wr, "\n"); 1655 1656 if (i == AES_EXTERN_ITER - 1) 1657 continue; 1658 1659 /** update key */ 1660 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1661 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1662 switch (vec.cipher_auth.key.len) { 1663 case 16: 1664 val_key.val[k] ^= val[0].val[k]; 1665 break; 1666 case 24: 1667 if (k < 8) 1668 val_key.val[k] ^= prev_out[k + 8]; 1669 else 1670 val_key.val[k] ^= val[0].val[k - 8]; 1671 break; 1672 case 32: 1673 if (k < 16) 1674 val_key.val[k] ^= prev_out[k]; 1675 else 1676 val_key.val[k] ^= val[0].val[k - 16]; 1677 break; 1678 default: 1679 return -1; 1680 } 1681 } 1682 1683 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1684 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1685 } 1686 1687 free(val[0].val); 1688 free(pt.val); 1689 free(ct.val); 1690 free(iv.val); 1691 1692 return 0; 1693 } 1694 1695 static int 1696 fips_mct_sha_test(void) 1697 { 1698 #define SHA_EXTERN_ITER 100 1699 #define SHA_INTERN_ITER 1000 1700 #define SHA_MD_BLOCK 3 1701 /* val[0] is op result and other value is for parse_writeback callback */ 1702 struct fips_val val[2] = {{NULL, 0},}; 1703 struct fips_val md[SHA_MD_BLOCK], msg; 1704 int ret; 1705 uint32_t i, j; 1706 1707 msg.len = SHA_MD_BLOCK * vec.cipher_auth.digest.len; 1708 msg.val = calloc(1, msg.len); 1709 if (vec.pt.val) 1710 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len); 1711 1712 for (i = 0; i < SHA_MD_BLOCK; i++) 1713 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 1714 1715 rte_free(vec.pt.val); 1716 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); 1717 1718 if (info.file_type != FIPS_TYPE_JSON) { 1719 fips_test_write_one_case(); 1720 fprintf(info.fp_wr, "\n"); 1721 } 1722 1723 for (j = 0; j < SHA_EXTERN_ITER; j++) { 1724 1725 memcpy(md[0].val, vec.cipher_auth.digest.val, 1726 vec.cipher_auth.digest.len); 1727 md[0].len = vec.cipher_auth.digest.len; 1728 memcpy(md[1].val, vec.cipher_auth.digest.val, 1729 vec.cipher_auth.digest.len); 1730 md[1].len = vec.cipher_auth.digest.len; 1731 memcpy(md[2].val, vec.cipher_auth.digest.val, 1732 vec.cipher_auth.digest.len); 1733 md[2].len = vec.cipher_auth.digest.len; 1734 1735 for (i = 0; i < SHA_MD_BLOCK; i++) 1736 memcpy(&msg.val[i * md[i].len], md[i].val, md[i].len); 1737 1738 for (i = 0; i < (SHA_INTERN_ITER); i++) { 1739 1740 memcpy(vec.pt.val, md[0].val, 1741 (size_t)md[0].len); 1742 memcpy((vec.pt.val + md[0].len), md[1].val, 1743 (size_t)md[1].len); 1744 memcpy((vec.pt.val + md[0].len + md[1].len), 1745 md[2].val, 1746 (size_t)md[2].len); 1747 vec.pt.len = md[0].len + md[1].len + md[2].len; 1748 1749 ret = fips_run_test(); 1750 if (ret < 0) { 1751 if (ret == -EPERM || ret == -ENOTSUP) { 1752 if (info.file_type == FIPS_TYPE_JSON) 1753 return ret; 1754 1755 fprintf(info.fp_wr, "Bypass\n\n"); 1756 return 0; 1757 } 1758 return ret; 1759 } 1760 1761 ret = get_writeback_data(&val[0]); 1762 if (ret < 0) 1763 return ret; 1764 1765 memcpy(md[0].val, md[1].val, md[1].len); 1766 md[0].len = md[1].len; 1767 memcpy(md[1].val, md[2].val, md[2].len); 1768 md[1].len = md[2].len; 1769 1770 memcpy(md[2].val, (val[0].val + vec.pt.len), 1771 vec.cipher_auth.digest.len); 1772 md[2].len = vec.cipher_auth.digest.len; 1773 } 1774 1775 memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len); 1776 vec.cipher_auth.digest.len = md[2].len; 1777 1778 if (info.file_type != FIPS_TYPE_JSON) 1779 fprintf(info.fp_wr, "COUNT = %u\n", j); 1780 1781 val[1].val = msg.val; 1782 val[1].len = msg.len; 1783 info.parse_writeback(val); 1784 1785 if (info.file_type != FIPS_TYPE_JSON) 1786 fprintf(info.fp_wr, "\n"); 1787 } 1788 1789 for (i = 0; i < (SHA_MD_BLOCK); i++) 1790 rte_free(md[i].val); 1791 1792 rte_free(vec.pt.val); 1793 1794 free(val[0].val); 1795 free(msg.val); 1796 1797 return 0; 1798 } 1799 1800 1801 static int 1802 init_test_ops(void) 1803 { 1804 switch (info.algo) { 1805 case FIPS_TEST_ALGO_AES_CBC: 1806 case FIPS_TEST_ALGO_AES: 1807 test_ops.prepare_op = prepare_cipher_op; 1808 test_ops.prepare_xform = prepare_aes_xform; 1809 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 1810 test_ops.test = fips_mct_aes_test; 1811 else 1812 test_ops.test = fips_generic_test; 1813 break; 1814 case FIPS_TEST_ALGO_HMAC: 1815 test_ops.prepare_op = prepare_auth_op; 1816 test_ops.prepare_xform = prepare_hmac_xform; 1817 test_ops.test = fips_generic_test; 1818 break; 1819 case FIPS_TEST_ALGO_TDES: 1820 test_ops.prepare_op = prepare_cipher_op; 1821 test_ops.prepare_xform = prepare_tdes_xform; 1822 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1823 test_ops.test = fips_mct_tdes_test; 1824 else 1825 test_ops.test = fips_generic_test; 1826 break; 1827 case FIPS_TEST_ALGO_AES_GCM: 1828 test_ops.prepare_op = prepare_aead_op; 1829 test_ops.prepare_xform = prepare_gcm_xform; 1830 test_ops.test = fips_generic_test; 1831 break; 1832 case FIPS_TEST_ALGO_AES_CMAC: 1833 test_ops.prepare_op = prepare_auth_op; 1834 test_ops.prepare_xform = prepare_cmac_xform; 1835 test_ops.test = fips_generic_test; 1836 break; 1837 case FIPS_TEST_ALGO_AES_CCM: 1838 test_ops.prepare_op = prepare_aead_op; 1839 test_ops.prepare_xform = prepare_ccm_xform; 1840 test_ops.test = fips_generic_test; 1841 break; 1842 case FIPS_TEST_ALGO_SHA: 1843 test_ops.prepare_op = prepare_auth_op; 1844 test_ops.prepare_xform = prepare_sha_xform; 1845 if (info.interim_info.sha_data.test_type == SHA_MCT) 1846 test_ops.test = fips_mct_sha_test; 1847 else 1848 test_ops.test = fips_generic_test; 1849 break; 1850 case FIPS_TEST_ALGO_AES_XTS: 1851 test_ops.prepare_op = prepare_cipher_op; 1852 test_ops.prepare_xform = prepare_xts_xform; 1853 test_ops.test = fips_generic_test; 1854 break; 1855 default: 1856 if (strstr(info.file_name, "TECB") || 1857 strstr(info.file_name, "TCBC")) { 1858 info.algo = FIPS_TEST_ALGO_TDES; 1859 test_ops.prepare_op = prepare_cipher_op; 1860 test_ops.prepare_xform = prepare_tdes_xform; 1861 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1862 test_ops.test = fips_mct_tdes_test; 1863 else 1864 test_ops.test = fips_generic_test; 1865 break; 1866 } 1867 return -1; 1868 } 1869 1870 return 0; 1871 } 1872 1873 static void 1874 print_test_block(void) 1875 { 1876 uint32_t i; 1877 1878 for (i = 0; i < info.nb_vec_lines; i++) 1879 printf("%s\n", info.vec[i]); 1880 1881 printf("\n"); 1882 } 1883 1884 static int 1885 fips_test_one_file(void) 1886 { 1887 int fetch_ret = 0, ret; 1888 1889 ret = init_test_ops(); 1890 if (ret < 0) { 1891 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 1892 return ret; 1893 } 1894 1895 while (ret >= 0 && fetch_ret == 0) { 1896 fetch_ret = fips_test_fetch_one_block(); 1897 if (fetch_ret < 0) { 1898 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 1899 fetch_ret); 1900 ret = fetch_ret; 1901 goto error_one_case; 1902 } 1903 1904 if (info.nb_vec_lines == 0) { 1905 if (fetch_ret == -EOF) 1906 break; 1907 1908 fprintf(info.fp_wr, "\n"); 1909 continue; 1910 } 1911 1912 ret = fips_test_parse_one_case(); 1913 switch (ret) { 1914 case 0: 1915 ret = test_ops.test(); 1916 if (ret == 0) 1917 break; 1918 RTE_LOG(ERR, USER1, "Error %i: test block\n", 1919 ret); 1920 goto error_one_case; 1921 case 1: 1922 break; 1923 default: 1924 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 1925 ret); 1926 goto error_one_case; 1927 } 1928 1929 continue; 1930 error_one_case: 1931 print_test_block(); 1932 } 1933 1934 fips_test_clear(); 1935 1936 if (env.digest) { 1937 rte_free(env.digest); 1938 env.digest = NULL; 1939 } 1940 rte_pktmbuf_free(env.mbuf); 1941 1942 return ret; 1943 } 1944 1945 #ifdef USE_JANSSON 1946 static int 1947 fips_test_json_init_writeback(void) 1948 { 1949 json_t *session_info, *session_write; 1950 session_info = json_array_get(json_info.json_root, 0); 1951 session_write = json_object(); 1952 json_info.json_write_root = json_array(); 1953 1954 json_object_set(session_write, "jwt", 1955 json_object_get(session_info, "jwt")); 1956 json_object_set(session_write, "url", 1957 json_object_get(session_info, "url")); 1958 json_object_set(session_write, "isSample", 1959 json_object_get(session_info, "isSample")); 1960 1961 json_info.is_sample = json_boolean_value( 1962 json_object_get(session_info, "isSample")); 1963 1964 json_array_append_new(json_info.json_write_root, session_write); 1965 return 0; 1966 } 1967 1968 static int 1969 fips_test_one_test_case(void) 1970 { 1971 int ret; 1972 1973 ret = fips_test_parse_one_json_case(); 1974 1975 switch (ret) { 1976 case 0: 1977 ret = test_ops.test(); 1978 if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP)) 1979 break; 1980 RTE_LOG(ERR, USER1, "Error %i: test block\n", 1981 ret); 1982 break; 1983 default: 1984 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 1985 ret); 1986 } 1987 return ret; 1988 } 1989 1990 static int 1991 fips_test_one_test_group(void) 1992 { 1993 int ret; 1994 json_t *tests, *write_tests; 1995 size_t test_idx, tests_size; 1996 1997 write_tests = json_array(); 1998 json_info.json_write_group = json_object(); 1999 json_object_set(json_info.json_write_group, "tgId", 2000 json_object_get(json_info.json_test_group, "tgId")); 2001 json_object_set_new(json_info.json_write_group, "tests", write_tests); 2002 2003 switch (info.algo) { 2004 case FIPS_TEST_ALGO_AES_GCM: 2005 ret = parse_test_gcm_json_init(); 2006 break; 2007 case FIPS_TEST_ALGO_HMAC: 2008 ret = parse_test_hmac_json_init(); 2009 break; 2010 case FIPS_TEST_ALGO_AES_CMAC: 2011 ret = parse_test_cmac_json_init(); 2012 break; 2013 case FIPS_TEST_ALGO_AES_XTS: 2014 ret = parse_test_xts_json_init(); 2015 break; 2016 case FIPS_TEST_ALGO_AES_CBC: 2017 case FIPS_TEST_ALGO_AES: 2018 ret = parse_test_aes_json_init(); 2019 break; 2020 case FIPS_TEST_ALGO_SHA: 2021 ret = parse_test_sha_json_init(); 2022 break; 2023 case FIPS_TEST_ALGO_TDES: 2024 ret = parse_test_tdes_json_init(); 2025 break; 2026 default: 2027 return -EINVAL; 2028 } 2029 2030 if (ret < 0) 2031 return ret; 2032 2033 ret = fips_test_parse_one_json_group(); 2034 if (ret < 0) 2035 return ret; 2036 2037 ret = init_test_ops(); 2038 if (ret < 0) 2039 return ret; 2040 2041 tests = json_object_get(json_info.json_test_group, "tests"); 2042 tests_size = json_array_size(tests); 2043 for (test_idx = 0; test_idx < tests_size; test_idx++) { 2044 json_info.json_test_case = json_array_get(tests, test_idx); 2045 if (fips_test_one_test_case() == 0) 2046 json_array_append_new(write_tests, json_info.json_write_case); 2047 } 2048 2049 return 0; 2050 } 2051 2052 static int 2053 fips_test_one_vector_set(void) 2054 { 2055 int ret; 2056 json_t *test_groups, *write_groups, *write_version, *write_set; 2057 size_t group_idx, num_groups; 2058 2059 test_groups = json_object_get(json_info.json_vector_set, "testGroups"); 2060 num_groups = json_array_size(test_groups); 2061 2062 json_info.json_write_set = json_array(); 2063 write_version = json_object(); 2064 json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION)); 2065 json_array_append_new(json_info.json_write_set, write_version); 2066 2067 write_set = json_object(); 2068 json_array_append(json_info.json_write_set, write_set); 2069 write_groups = json_array(); 2070 2071 json_object_set(write_set, "vsId", 2072 json_object_get(json_info.json_vector_set, "vsId")); 2073 json_object_set(write_set, "algorithm", 2074 json_object_get(json_info.json_vector_set, "algorithm")); 2075 json_object_set(write_set, "revision", 2076 json_object_get(json_info.json_vector_set, "revision")); 2077 json_object_set_new(write_set, "isSample", 2078 json_boolean(json_info.is_sample)); 2079 json_object_set_new(write_set, "testGroups", write_groups); 2080 2081 ret = fips_test_parse_one_json_vector_set(); 2082 if (ret < 0) { 2083 RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n", 2084 json_string_value(json_object_get(json_info.json_vector_set, "algorithm"))); 2085 return ret; 2086 } 2087 2088 for (group_idx = 0; group_idx < num_groups; group_idx++) { 2089 json_info.json_test_group = json_array_get(test_groups, group_idx); 2090 ret = fips_test_one_test_group(); 2091 json_array_append_new(write_groups, json_info.json_write_group); 2092 } 2093 2094 return 0; 2095 } 2096 2097 static int 2098 fips_test_one_json_file(void) 2099 { 2100 size_t vector_set_idx, root_size; 2101 2102 root_size = json_array_size(json_info.json_root); 2103 fips_test_json_init_writeback(); 2104 2105 for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) { 2106 /* Vector set index starts at 1, the 0th index contains test session 2107 * information. 2108 */ 2109 json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx); 2110 fips_test_one_vector_set(); 2111 json_array_append_new(json_info.json_write_root, json_info.json_write_set); 2112 json_incref(json_info.json_write_set); 2113 } 2114 2115 json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4)); 2116 json_decref(json_info.json_write_root); 2117 2118 return 0; 2119 } 2120 #endif /* USE_JANSSON */ 2121