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