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 (info.interim_info.gcm_data.gen_iv == 1) { 664 uint32_t i; 665 666 if (!vec.iv.val) { 667 vec.iv.val = rte_malloc(0, vec.iv.len, 0); 668 if (!vec.iv.val) 669 return -ENOMEM; 670 } 671 672 for (i = 0; i < vec.iv.len; i++) { 673 int random = rand(); 674 vec.iv.val[i] = (uint8_t)random; 675 } 676 } 677 678 if (vec.iv.len) { 679 uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, 680 IV_OFF); 681 memset(iv, 0, vec.iv.len); 682 if (vec.iv.val) 683 memcpy(iv, vec.iv.val, vec.iv.len); 684 } 685 686 ret = prepare_data_mbufs(&vec.pt); 687 if (ret < 0) 688 return ret; 689 690 rte_free(env.digest); 691 692 env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len, 693 RTE_CACHE_LINE_SIZE); 694 if (!env.digest) { 695 RTE_LOG(ERR, USER1, "Not enough memory\n"); 696 return -ENOMEM; 697 } 698 env.digest_len = vec.cipher_auth.digest.len; 699 700 sym->m_src = env.mbuf; 701 sym->auth.data.offset = 0; 702 sym->auth.data.length = vec.pt.len; 703 sym->auth.digest.data = env.digest; 704 sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest); 705 706 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 707 memcpy(env.digest, vec.cipher_auth.digest.val, 708 vec.cipher_auth.digest.len); 709 710 rte_crypto_op_attach_sym_session(env.op, env.sess); 711 712 return 0; 713 } 714 715 int 716 prepare_aead_op(void) 717 { 718 struct rte_crypto_sym_op *sym = env.op->sym; 719 uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); 720 int ret; 721 722 __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 723 724 if (info.algo == FIPS_TEST_ALGO_AES_CCM) 725 iv++; 726 727 if (vec.iv.val) 728 memcpy(iv, vec.iv.val, vec.iv.len); 729 else 730 /* if REQ file has iv length but not data, default as all 0 */ 731 memset(iv, 0, vec.iv.len); 732 733 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 734 ret = prepare_data_mbufs(&vec.pt); 735 if (ret < 0) 736 return ret; 737 738 rte_free(env.digest); 739 env.digest = rte_zmalloc(NULL, vec.aead.digest.len, 740 RTE_CACHE_LINE_SIZE); 741 if (!env.digest) { 742 RTE_LOG(ERR, USER1, "Not enough memory\n"); 743 return -ENOMEM; 744 } 745 env.digest_len = vec.cipher_auth.digest.len; 746 747 sym->aead.data.length = vec.pt.len; 748 sym->aead.digest.data = env.digest; 749 sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest); 750 } else { 751 ret = prepare_data_mbufs(&vec.ct); 752 if (ret < 0) 753 return ret; 754 755 sym->aead.data.length = vec.ct.len; 756 sym->aead.digest.data = vec.aead.digest.val; 757 sym->aead.digest.phys_addr = rte_malloc_virt2iova( 758 sym->aead.digest.data); 759 } 760 761 sym->m_src = env.mbuf; 762 sym->aead.data.offset = 0; 763 sym->aead.aad.data = vec.aead.aad.val; 764 sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data); 765 766 rte_crypto_op_attach_sym_session(env.op, env.sess); 767 768 return 0; 769 } 770 771 static int 772 prepare_aes_xform(struct rte_crypto_sym_xform *xform) 773 { 774 const struct rte_cryptodev_symmetric_capability *cap; 775 struct rte_cryptodev_sym_capability_idx cap_idx; 776 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 777 778 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 779 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) 780 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC; 781 else if (info.interim_info.aes_data.cipher_algo == 782 RTE_CRYPTO_CIPHER_AES_CTR) 783 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR; 784 else 785 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB; 786 787 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 788 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 789 RTE_CRYPTO_CIPHER_OP_DECRYPT; 790 cipher_xform->key.data = vec.cipher_auth.key.val; 791 cipher_xform->key.length = vec.cipher_auth.key.len; 792 if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC || 793 cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) { 794 cipher_xform->iv.length = vec.iv.len; 795 cipher_xform->iv.offset = IV_OFF; 796 } else { 797 cipher_xform->iv.length = 0; 798 cipher_xform->iv.offset = 0; 799 } 800 cap_idx.algo.cipher = cipher_xform->algo; 801 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 802 803 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 804 if (!cap) { 805 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 806 env.dev_id); 807 return -EINVAL; 808 } 809 810 if (rte_cryptodev_sym_capability_check_cipher(cap, 811 cipher_xform->key.length, 812 cipher_xform->iv.length) != 0) { 813 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 814 info.device_name, cipher_xform->key.length, 815 cipher_xform->iv.length); 816 return -EPERM; 817 } 818 819 return 0; 820 } 821 822 static int 823 prepare_tdes_xform(struct rte_crypto_sym_xform *xform) 824 { 825 const struct rte_cryptodev_symmetric_capability *cap; 826 struct rte_cryptodev_sym_capability_idx cap_idx; 827 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 828 829 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 830 831 if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC) 832 cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC; 833 else 834 cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB; 835 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 836 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 837 RTE_CRYPTO_CIPHER_OP_DECRYPT; 838 cipher_xform->key.data = vec.cipher_auth.key.val; 839 cipher_xform->key.length = vec.cipher_auth.key.len; 840 841 if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) { 842 cipher_xform->iv.length = vec.iv.len; 843 cipher_xform->iv.offset = IV_OFF; 844 } else { 845 cipher_xform->iv.length = 0; 846 cipher_xform->iv.offset = 0; 847 } 848 cap_idx.algo.cipher = cipher_xform->algo; 849 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 850 851 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 852 if (!cap) { 853 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 854 env.dev_id); 855 return -EINVAL; 856 } 857 858 if (rte_cryptodev_sym_capability_check_cipher(cap, 859 cipher_xform->key.length, 860 cipher_xform->iv.length) != 0) { 861 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 862 info.device_name, cipher_xform->key.length, 863 cipher_xform->iv.length); 864 return -EPERM; 865 } 866 867 return 0; 868 } 869 870 static int 871 prepare_hmac_xform(struct rte_crypto_sym_xform *xform) 872 { 873 const struct rte_cryptodev_symmetric_capability *cap; 874 struct rte_cryptodev_sym_capability_idx cap_idx; 875 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 876 877 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 878 879 auth_xform->algo = info.interim_info.hmac_data.algo; 880 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 881 auth_xform->digest_length = vec.cipher_auth.digest.len; 882 auth_xform->key.data = vec.cipher_auth.key.val; 883 auth_xform->key.length = vec.cipher_auth.key.len; 884 885 cap_idx.algo.auth = auth_xform->algo; 886 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 887 888 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 889 if (!cap) { 890 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 891 env.dev_id); 892 return -EINVAL; 893 } 894 895 if (rte_cryptodev_sym_capability_check_auth(cap, 896 auth_xform->key.length, 897 auth_xform->digest_length, 0) != 0) { 898 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 899 info.device_name, auth_xform->key.length, 900 auth_xform->digest_length); 901 return -EPERM; 902 } 903 904 return 0; 905 } 906 907 int 908 prepare_gcm_xform(struct rte_crypto_sym_xform *xform) 909 { 910 const struct rte_cryptodev_symmetric_capability *cap; 911 struct rte_cryptodev_sym_capability_idx cap_idx; 912 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 913 914 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 915 916 aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM; 917 aead_xform->aad_length = vec.aead.aad.len; 918 aead_xform->digest_length = vec.aead.digest.len; 919 aead_xform->iv.offset = IV_OFF; 920 aead_xform->iv.length = vec.iv.len; 921 aead_xform->key.data = vec.aead.key.val; 922 aead_xform->key.length = vec.aead.key.len; 923 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 924 RTE_CRYPTO_AEAD_OP_ENCRYPT : 925 RTE_CRYPTO_AEAD_OP_DECRYPT; 926 927 cap_idx.algo.aead = aead_xform->algo; 928 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 929 930 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 931 if (!cap) { 932 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 933 env.dev_id); 934 return -EINVAL; 935 } 936 937 if (rte_cryptodev_sym_capability_check_aead(cap, 938 aead_xform->key.length, 939 aead_xform->digest_length, aead_xform->aad_length, 940 aead_xform->iv.length) != 0) { 941 RTE_LOG(ERR, USER1, 942 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 943 info.device_name, aead_xform->key.length, 944 aead_xform->digest_length, 945 aead_xform->aad_length, 946 aead_xform->iv.length); 947 return -EPERM; 948 } 949 950 return 0; 951 } 952 953 int 954 prepare_gmac_xform(struct rte_crypto_sym_xform *xform) 955 { 956 const struct rte_cryptodev_symmetric_capability *cap; 957 struct rte_cryptodev_sym_capability_idx cap_idx; 958 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 959 960 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 961 962 auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC; 963 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 964 RTE_CRYPTO_AUTH_OP_GENERATE : 965 RTE_CRYPTO_AUTH_OP_VERIFY; 966 auth_xform->iv.offset = IV_OFF; 967 auth_xform->iv.length = vec.iv.len; 968 auth_xform->digest_length = vec.aead.digest.len; 969 auth_xform->key.data = vec.aead.key.val; 970 auth_xform->key.length = vec.aead.key.len; 971 972 cap_idx.algo.auth = auth_xform->algo; 973 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 974 975 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 976 if (!cap) { 977 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 978 env.dev_id); 979 return -EINVAL; 980 } 981 982 if (rte_cryptodev_sym_capability_check_auth(cap, 983 auth_xform->key.length, 984 auth_xform->digest_length, 985 auth_xform->iv.length) != 0) { 986 987 RTE_LOG(ERR, USER1, 988 "PMD %s key length %u Digest length %u IV length %u\n", 989 info.device_name, auth_xform->key.length, 990 auth_xform->digest_length, 991 auth_xform->iv.length); 992 return -EPERM; 993 } 994 995 return 0; 996 } 997 998 static int 999 prepare_cmac_xform(struct rte_crypto_sym_xform *xform) 1000 { 1001 const struct rte_cryptodev_symmetric_capability *cap; 1002 struct rte_cryptodev_sym_capability_idx cap_idx; 1003 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1004 1005 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1006 1007 auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC; 1008 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1009 RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY; 1010 auth_xform->digest_length = vec.cipher_auth.digest.len; 1011 auth_xform->key.data = vec.cipher_auth.key.val; 1012 auth_xform->key.length = vec.cipher_auth.key.len; 1013 1014 cap_idx.algo.auth = auth_xform->algo; 1015 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1016 1017 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1018 if (!cap) { 1019 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1020 env.dev_id); 1021 return -EINVAL; 1022 } 1023 1024 if (rte_cryptodev_sym_capability_check_auth(cap, 1025 auth_xform->key.length, 1026 auth_xform->digest_length, 0) != 0) { 1027 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1028 info.device_name, auth_xform->key.length, 1029 auth_xform->digest_length); 1030 return -EPERM; 1031 } 1032 1033 return 0; 1034 } 1035 1036 static int 1037 prepare_ccm_xform(struct rte_crypto_sym_xform *xform) 1038 { 1039 const struct rte_cryptodev_symmetric_capability *cap; 1040 struct rte_cryptodev_sym_capability_idx cap_idx; 1041 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 1042 1043 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 1044 1045 aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM; 1046 aead_xform->aad_length = vec.aead.aad.len; 1047 aead_xform->digest_length = vec.aead.digest.len; 1048 aead_xform->iv.offset = IV_OFF; 1049 aead_xform->iv.length = vec.iv.len; 1050 aead_xform->key.data = vec.aead.key.val; 1051 aead_xform->key.length = vec.aead.key.len; 1052 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1053 RTE_CRYPTO_AEAD_OP_ENCRYPT : 1054 RTE_CRYPTO_AEAD_OP_DECRYPT; 1055 1056 cap_idx.algo.aead = aead_xform->algo; 1057 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 1058 1059 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1060 if (!cap) { 1061 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1062 env.dev_id); 1063 return -EINVAL; 1064 } 1065 1066 if (rte_cryptodev_sym_capability_check_aead(cap, 1067 aead_xform->key.length, 1068 aead_xform->digest_length, aead_xform->aad_length, 1069 aead_xform->iv.length) != 0) { 1070 RTE_LOG(ERR, USER1, 1071 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 1072 info.device_name, aead_xform->key.length, 1073 aead_xform->digest_length, 1074 aead_xform->aad_length, 1075 aead_xform->iv.length); 1076 return -EPERM; 1077 } 1078 1079 return 0; 1080 } 1081 1082 static int 1083 prepare_sha_xform(struct rte_crypto_sym_xform *xform) 1084 { 1085 const struct rte_cryptodev_symmetric_capability *cap; 1086 struct rte_cryptodev_sym_capability_idx cap_idx; 1087 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1088 1089 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1090 1091 auth_xform->algo = info.interim_info.sha_data.algo; 1092 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 1093 auth_xform->digest_length = vec.cipher_auth.digest.len; 1094 1095 cap_idx.algo.auth = auth_xform->algo; 1096 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1097 1098 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1099 if (!cap) { 1100 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1101 env.dev_id); 1102 return -EINVAL; 1103 } 1104 1105 if (rte_cryptodev_sym_capability_check_auth(cap, 1106 auth_xform->key.length, 1107 auth_xform->digest_length, 0) != 0) { 1108 RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n", 1109 info.device_name, auth_xform->key.length, 1110 auth_xform->digest_length); 1111 return -EPERM; 1112 } 1113 1114 return 0; 1115 } 1116 1117 static int 1118 prepare_xts_xform(struct rte_crypto_sym_xform *xform) 1119 { 1120 const struct rte_cryptodev_symmetric_capability *cap; 1121 struct rte_cryptodev_sym_capability_idx cap_idx; 1122 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1123 1124 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1125 1126 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS; 1127 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1128 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1129 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1130 cipher_xform->key.data = vec.cipher_auth.key.val; 1131 cipher_xform->key.length = vec.cipher_auth.key.len; 1132 cipher_xform->iv.length = vec.iv.len; 1133 cipher_xform->iv.offset = IV_OFF; 1134 1135 cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS; 1136 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1137 1138 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1139 if (!cap) { 1140 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1141 env.dev_id); 1142 return -EINVAL; 1143 } 1144 1145 if (rte_cryptodev_sym_capability_check_cipher(cap, 1146 cipher_xform->key.length, 1147 cipher_xform->iv.length) != 0) { 1148 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1149 info.device_name, cipher_xform->key.length, 1150 cipher_xform->iv.length); 1151 return -EPERM; 1152 } 1153 1154 return 0; 1155 } 1156 1157 static int 1158 get_writeback_data(struct fips_val *val) 1159 { 1160 struct rte_mbuf *m = env.mbuf; 1161 uint16_t data_len = rte_pktmbuf_pkt_len(m); 1162 uint16_t total_len = data_len + env.digest_len; 1163 uint8_t *src, *dst, *wb_data; 1164 1165 /* in case val is reused for MCT test, try to free the buffer first */ 1166 if (val->val) { 1167 free(val->val); 1168 val->val = NULL; 1169 } 1170 1171 wb_data = dst = calloc(1, total_len); 1172 if (!dst) { 1173 RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM); 1174 return -ENOMEM; 1175 } 1176 1177 while (m && data_len) { 1178 uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len); 1179 1180 src = rte_pktmbuf_mtod(m, uint8_t *); 1181 memcpy(dst, src, seg_len); 1182 m = m->next; 1183 data_len -= seg_len; 1184 dst += seg_len; 1185 } 1186 1187 if (data_len) { 1188 RTE_LOG(ERR, USER1, "Error -1: write back data\n"); 1189 free(wb_data); 1190 return -1; 1191 } 1192 1193 if (env.digest) 1194 memcpy(dst, env.digest, env.digest_len); 1195 1196 val->val = wb_data; 1197 val->len = total_len; 1198 1199 return 0; 1200 } 1201 1202 static int 1203 fips_run_test(void) 1204 { 1205 struct rte_crypto_sym_xform xform = {0}; 1206 uint16_t n_deqd; 1207 int ret; 1208 1209 ret = test_ops.prepare_xform(&xform); 1210 if (ret < 0) 1211 return ret; 1212 1213 env.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform, 1214 env.sess_mpool); 1215 if (!env.sess) { 1216 RTE_LOG(ERR, USER1, "Error %i: Init session\n", 1217 ret); 1218 goto exit; 1219 } 1220 1221 ret = test_ops.prepare_op(); 1222 if (ret < 0) { 1223 RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", 1224 ret); 1225 goto exit; 1226 } 1227 1228 if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 1229 RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 1230 ret = -1; 1231 goto exit; 1232 } 1233 1234 do { 1235 struct rte_crypto_op *deqd_op; 1236 1237 n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1238 1); 1239 } while (n_deqd == 0); 1240 1241 vec.status = env.op->status; 1242 1243 exit: 1244 if (env.sess) { 1245 rte_cryptodev_sym_session_free(env.dev_id, env.sess); 1246 env.sess = NULL; 1247 } 1248 1249 return ret; 1250 } 1251 1252 static int 1253 fips_generic_test(void) 1254 { 1255 struct fips_val val = {NULL, 0}; 1256 int ret; 1257 1258 if (info.file_type != FIPS_TYPE_JSON) 1259 fips_test_write_one_case(); 1260 1261 ret = fips_run_test(); 1262 if (ret < 0) { 1263 if (ret == -EPERM || ret == -ENOTSUP) { 1264 if (info.file_type == FIPS_TYPE_JSON) 1265 return ret; 1266 1267 fprintf(info.fp_wr, "Bypass\n\n"); 1268 return 0; 1269 } 1270 1271 return ret; 1272 } 1273 1274 ret = get_writeback_data(&val); 1275 if (ret < 0) 1276 return ret; 1277 1278 switch (info.file_type) { 1279 case FIPS_TYPE_REQ: 1280 case FIPS_TYPE_RSP: 1281 case FIPS_TYPE_JSON: 1282 if (info.parse_writeback == NULL) 1283 return -EPERM; 1284 ret = info.parse_writeback(&val); 1285 if (ret < 0) 1286 return ret; 1287 break; 1288 case FIPS_TYPE_FAX: 1289 if (info.kat_check == NULL) 1290 return -EPERM; 1291 ret = info.kat_check(&val); 1292 if (ret < 0) 1293 return ret; 1294 break; 1295 default: 1296 break; 1297 } 1298 1299 if (info.file_type != FIPS_TYPE_JSON) 1300 fprintf(info.fp_wr, "\n"); 1301 free(val.val); 1302 1303 return 0; 1304 } 1305 1306 static int 1307 fips_mct_tdes_test(void) 1308 { 1309 #define TDES_BLOCK_SIZE 8 1310 #define TDES_EXTERN_ITER 400 1311 #define TDES_INTERN_ITER 10000 1312 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 1313 uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; 1314 uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; 1315 uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; 1316 uint32_t i, j, k; 1317 int ret; 1318 int test_mode = info.interim_info.tdes_data.test_mode; 1319 1320 pt.len = vec.pt.len; 1321 pt.val = calloc(1, pt.len); 1322 ct.len = vec.ct.len; 1323 ct.val = calloc(1, ct.len); 1324 iv.len = vec.iv.len; 1325 iv.val = calloc(1, iv.len); 1326 1327 for (i = 0; i < TDES_EXTERN_ITER; i++) { 1328 if (info.file_type != FIPS_TYPE_JSON) { 1329 if ((i == 0) && (info.version == 21.4f)) { 1330 if (!(strstr(info.vec[0], "COUNT"))) 1331 fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0); 1332 } 1333 1334 if (i != 0) 1335 update_info_vec(i); 1336 1337 fips_test_write_one_case(); 1338 } 1339 1340 for (j = 0; j < TDES_INTERN_ITER; j++) { 1341 ret = fips_run_test(); 1342 if (ret < 0) { 1343 if (ret == -EPERM) { 1344 if (info.file_type == FIPS_TYPE_JSON) 1345 return ret; 1346 1347 fprintf(info.fp_wr, "Bypass\n"); 1348 return 0; 1349 } 1350 return ret; 1351 } 1352 1353 ret = get_writeback_data(&val[0]); 1354 if (ret < 0) 1355 return ret; 1356 1357 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1358 memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 1359 1360 if (j == 0) { 1361 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 1362 memcpy(pt.val, vec.pt.val, pt.len); 1363 memcpy(ct.val, vec.ct.val, ct.len); 1364 memcpy(iv.val, vec.iv.val, iv.len); 1365 1366 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1367 if (test_mode == TDES_MODE_ECB) { 1368 memcpy(vec.pt.val, val[0].val, 1369 TDES_BLOCK_SIZE); 1370 } else { 1371 memcpy(vec.pt.val, vec.iv.val, 1372 TDES_BLOCK_SIZE); 1373 memcpy(vec.iv.val, val[0].val, 1374 TDES_BLOCK_SIZE); 1375 } 1376 val[1].val = pt.val; 1377 val[1].len = pt.len; 1378 val[2].val = iv.val; 1379 val[2].len = iv.len; 1380 } else { 1381 if (test_mode == TDES_MODE_ECB) { 1382 memcpy(vec.ct.val, val[0].val, 1383 TDES_BLOCK_SIZE); 1384 } else { 1385 memcpy(vec.iv.val, vec.ct.val, 1386 TDES_BLOCK_SIZE); 1387 memcpy(vec.ct.val, val[0].val, 1388 TDES_BLOCK_SIZE); 1389 } 1390 val[1].val = ct.val; 1391 val[1].len = ct.len; 1392 val[2].val = iv.val; 1393 val[2].len = iv.len; 1394 } 1395 continue; 1396 } 1397 1398 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1399 if (test_mode == TDES_MODE_ECB) { 1400 memcpy(vec.pt.val, val[0].val, 1401 TDES_BLOCK_SIZE); 1402 } else { 1403 memcpy(vec.iv.val, val[0].val, 1404 TDES_BLOCK_SIZE); 1405 memcpy(vec.pt.val, prev_out, 1406 TDES_BLOCK_SIZE); 1407 } 1408 } else { 1409 if (test_mode == TDES_MODE_ECB) { 1410 memcpy(vec.ct.val, val[0].val, 1411 TDES_BLOCK_SIZE); 1412 } else { 1413 memcpy(vec.iv.val, vec.ct.val, 1414 TDES_BLOCK_SIZE); 1415 memcpy(vec.ct.val, val[0].val, 1416 TDES_BLOCK_SIZE); 1417 } 1418 } 1419 1420 if (j == TDES_INTERN_ITER - 1) 1421 continue; 1422 1423 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 1424 1425 if (j == TDES_INTERN_ITER - 3) 1426 memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE); 1427 } 1428 1429 info.parse_writeback(val); 1430 if (info.file_type != FIPS_TYPE_JSON) 1431 fprintf(info.fp_wr, "\n"); 1432 1433 if (i == TDES_EXTERN_ITER - 1) 1434 continue; 1435 1436 /** update key */ 1437 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1438 1439 if (info.interim_info.tdes_data.nb_keys == 0) { 1440 if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 1441 info.interim_info.tdes_data.nb_keys = 1; 1442 else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 1443 info.interim_info.tdes_data.nb_keys = 2; 1444 else 1445 info.interim_info.tdes_data.nb_keys = 3; 1446 1447 } 1448 1449 for (k = 0; k < TDES_BLOCK_SIZE; k++) { 1450 1451 switch (info.interim_info.tdes_data.nb_keys) { 1452 case 3: 1453 val_key.val[k] ^= val[0].val[k]; 1454 val_key.val[k + 8] ^= prev_out[k]; 1455 val_key.val[k + 16] ^= prev_prev_out[k]; 1456 break; 1457 case 2: 1458 val_key.val[k] ^= val[0].val[k]; 1459 val_key.val[k + 8] ^= prev_out[k]; 1460 val_key.val[k + 16] ^= val[0].val[k]; 1461 break; 1462 default: /* case 1 */ 1463 val_key.val[k] ^= val[0].val[k]; 1464 val_key.val[k + 8] ^= val[0].val[k]; 1465 val_key.val[k + 16] ^= val[0].val[k]; 1466 break; 1467 } 1468 1469 } 1470 1471 for (k = 0; k < 24; k++) 1472 val_key.val[k] = (__builtin_popcount(val_key.val[k]) & 1473 0x1) ? 1474 val_key.val[k] : (val_key.val[k] ^ 0x1); 1475 1476 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1477 if (test_mode == TDES_MODE_ECB) { 1478 memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE); 1479 } else { 1480 memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE); 1481 memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 1482 } 1483 } else { 1484 if (test_mode == TDES_MODE_ECB) { 1485 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 1486 } else { 1487 memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 1488 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 1489 } 1490 } 1491 } 1492 1493 free(val[0].val); 1494 free(pt.val); 1495 free(ct.val); 1496 free(iv.val); 1497 1498 return 0; 1499 } 1500 1501 static int 1502 fips_mct_aes_ecb_test(void) 1503 { 1504 #define AES_BLOCK_SIZE 16 1505 #define AES_EXTERN_ITER 100 1506 #define AES_INTERN_ITER 1000 1507 struct fips_val val = {NULL, 0}, val_key; 1508 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1509 uint32_t i, j, k; 1510 int ret; 1511 1512 for (i = 0; i < AES_EXTERN_ITER; i++) { 1513 if (i != 0) 1514 update_info_vec(i); 1515 1516 fips_test_write_one_case(); 1517 1518 for (j = 0; j < AES_INTERN_ITER; j++) { 1519 ret = fips_run_test(); 1520 if (ret < 0) { 1521 if (ret == -EPERM) { 1522 if (info.file_type == FIPS_TYPE_JSON) 1523 return ret; 1524 1525 fprintf(info.fp_wr, "Bypass\n"); 1526 return 0; 1527 } 1528 1529 return ret; 1530 } 1531 1532 ret = get_writeback_data(&val); 1533 if (ret < 0) 1534 return ret; 1535 1536 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 1537 memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); 1538 else 1539 memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); 1540 1541 if (j == AES_INTERN_ITER - 1) 1542 continue; 1543 1544 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1545 } 1546 1547 info.parse_writeback(&val); 1548 fprintf(info.fp_wr, "\n"); 1549 1550 if (i == AES_EXTERN_ITER - 1) 1551 continue; 1552 1553 /** update key */ 1554 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1555 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1556 switch (vec.cipher_auth.key.len) { 1557 case 16: 1558 val_key.val[k] ^= val.val[k]; 1559 break; 1560 case 24: 1561 if (k < 8) 1562 val_key.val[k] ^= prev_out[k + 8]; 1563 else 1564 val_key.val[k] ^= val.val[k - 8]; 1565 break; 1566 case 32: 1567 if (k < 16) 1568 val_key.val[k] ^= prev_out[k]; 1569 else 1570 val_key.val[k] ^= val.val[k - 16]; 1571 break; 1572 default: 1573 return -1; 1574 } 1575 } 1576 } 1577 1578 free(val.val); 1579 1580 return 0; 1581 } 1582 static int 1583 fips_mct_aes_test(void) 1584 { 1585 #define AES_BLOCK_SIZE 16 1586 #define AES_EXTERN_ITER 100 1587 #define AES_INTERN_ITER 1000 1588 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 1589 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1590 uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 1591 uint32_t i, j, k; 1592 int ret; 1593 1594 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) 1595 return fips_mct_aes_ecb_test(); 1596 1597 pt.len = vec.pt.len; 1598 pt.val = calloc(1, pt.len); 1599 ct.len = vec.ct.len; 1600 ct.val = calloc(1, ct.len); 1601 iv.len = vec.iv.len; 1602 iv.val = calloc(1, iv.len); 1603 for (i = 0; i < AES_EXTERN_ITER; i++) { 1604 if (info.file_type != FIPS_TYPE_JSON) { 1605 if (i != 0) 1606 update_info_vec(i); 1607 1608 fips_test_write_one_case(); 1609 } 1610 1611 for (j = 0; j < AES_INTERN_ITER; j++) { 1612 ret = fips_run_test(); 1613 if (ret < 0) { 1614 if (ret == -EPERM) { 1615 if (info.file_type == FIPS_TYPE_JSON) 1616 return ret; 1617 1618 fprintf(info.fp_wr, "Bypass\n"); 1619 return 0; 1620 } 1621 1622 return ret; 1623 } 1624 1625 ret = get_writeback_data(&val[0]); 1626 if (ret < 0) 1627 return ret; 1628 1629 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1630 memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 1631 1632 if (j == 0) { 1633 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 1634 memcpy(pt.val, vec.pt.val, pt.len); 1635 memcpy(ct.val, vec.ct.val, ct.len); 1636 memcpy(iv.val, vec.iv.val, iv.len); 1637 1638 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1639 memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE); 1640 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1641 val[1].val = pt.val; 1642 val[1].len = pt.len; 1643 val[2].val = iv.val; 1644 val[2].len = iv.len; 1645 } else { 1646 memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE); 1647 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1648 val[1].val = ct.val; 1649 val[1].len = ct.len; 1650 val[2].val = iv.val; 1651 val[2].len = iv.len; 1652 } 1653 continue; 1654 } 1655 1656 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1657 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1658 memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 1659 } else { 1660 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1661 memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 1662 } 1663 1664 if (j == AES_INTERN_ITER - 1) 1665 continue; 1666 1667 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 1668 } 1669 1670 info.parse_writeback(val); 1671 if (info.file_type != FIPS_TYPE_JSON) 1672 fprintf(info.fp_wr, "\n"); 1673 1674 if (i == AES_EXTERN_ITER - 1) 1675 continue; 1676 1677 /** update key */ 1678 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1679 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1680 switch (vec.cipher_auth.key.len) { 1681 case 16: 1682 val_key.val[k] ^= val[0].val[k]; 1683 break; 1684 case 24: 1685 if (k < 8) 1686 val_key.val[k] ^= prev_out[k + 8]; 1687 else 1688 val_key.val[k] ^= val[0].val[k - 8]; 1689 break; 1690 case 32: 1691 if (k < 16) 1692 val_key.val[k] ^= prev_out[k]; 1693 else 1694 val_key.val[k] ^= val[0].val[k - 16]; 1695 break; 1696 default: 1697 return -1; 1698 } 1699 } 1700 1701 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1702 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 1703 } 1704 1705 free(val[0].val); 1706 free(pt.val); 1707 free(ct.val); 1708 free(iv.val); 1709 1710 return 0; 1711 } 1712 1713 static int 1714 fips_mct_sha_test(void) 1715 { 1716 #define SHA_EXTERN_ITER 100 1717 #define SHA_INTERN_ITER 1000 1718 #define SHA_MD_BLOCK 3 1719 /* val[0] is op result and other value is for parse_writeback callback */ 1720 struct fips_val val[2] = {{NULL, 0},}; 1721 struct fips_val md[SHA_MD_BLOCK], msg; 1722 int ret; 1723 uint32_t i, j; 1724 1725 msg.len = SHA_MD_BLOCK * vec.cipher_auth.digest.len; 1726 msg.val = calloc(1, msg.len); 1727 if (vec.pt.val) 1728 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len); 1729 1730 for (i = 0; i < SHA_MD_BLOCK; i++) 1731 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 1732 1733 rte_free(vec.pt.val); 1734 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); 1735 1736 if (info.file_type != FIPS_TYPE_JSON) { 1737 fips_test_write_one_case(); 1738 fprintf(info.fp_wr, "\n"); 1739 } 1740 1741 for (j = 0; j < SHA_EXTERN_ITER; j++) { 1742 1743 memcpy(md[0].val, vec.cipher_auth.digest.val, 1744 vec.cipher_auth.digest.len); 1745 md[0].len = vec.cipher_auth.digest.len; 1746 memcpy(md[1].val, vec.cipher_auth.digest.val, 1747 vec.cipher_auth.digest.len); 1748 md[1].len = vec.cipher_auth.digest.len; 1749 memcpy(md[2].val, vec.cipher_auth.digest.val, 1750 vec.cipher_auth.digest.len); 1751 md[2].len = vec.cipher_auth.digest.len; 1752 1753 for (i = 0; i < SHA_MD_BLOCK; i++) 1754 memcpy(&msg.val[i * md[i].len], md[i].val, md[i].len); 1755 1756 for (i = 0; i < (SHA_INTERN_ITER); i++) { 1757 1758 memcpy(vec.pt.val, md[0].val, 1759 (size_t)md[0].len); 1760 memcpy((vec.pt.val + md[0].len), md[1].val, 1761 (size_t)md[1].len); 1762 memcpy((vec.pt.val + md[0].len + md[1].len), 1763 md[2].val, 1764 (size_t)md[2].len); 1765 vec.pt.len = md[0].len + md[1].len + md[2].len; 1766 1767 ret = fips_run_test(); 1768 if (ret < 0) { 1769 if (ret == -EPERM || ret == -ENOTSUP) { 1770 if (info.file_type == FIPS_TYPE_JSON) 1771 return ret; 1772 1773 fprintf(info.fp_wr, "Bypass\n\n"); 1774 return 0; 1775 } 1776 return ret; 1777 } 1778 1779 ret = get_writeback_data(&val[0]); 1780 if (ret < 0) 1781 return ret; 1782 1783 memcpy(md[0].val, md[1].val, md[1].len); 1784 md[0].len = md[1].len; 1785 memcpy(md[1].val, md[2].val, md[2].len); 1786 md[1].len = md[2].len; 1787 1788 memcpy(md[2].val, (val[0].val + vec.pt.len), 1789 vec.cipher_auth.digest.len); 1790 md[2].len = vec.cipher_auth.digest.len; 1791 } 1792 1793 memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len); 1794 vec.cipher_auth.digest.len = md[2].len; 1795 1796 if (info.file_type != FIPS_TYPE_JSON) 1797 fprintf(info.fp_wr, "COUNT = %u\n", j); 1798 1799 val[1].val = msg.val; 1800 val[1].len = msg.len; 1801 info.parse_writeback(val); 1802 1803 if (info.file_type != FIPS_TYPE_JSON) 1804 fprintf(info.fp_wr, "\n"); 1805 } 1806 1807 for (i = 0; i < (SHA_MD_BLOCK); i++) 1808 rte_free(md[i].val); 1809 1810 rte_free(vec.pt.val); 1811 1812 free(val[0].val); 1813 free(msg.val); 1814 1815 return 0; 1816 } 1817 1818 1819 static int 1820 init_test_ops(void) 1821 { 1822 switch (info.algo) { 1823 case FIPS_TEST_ALGO_AES_CBC: 1824 case FIPS_TEST_ALGO_AES_CTR: 1825 case FIPS_TEST_ALGO_AES: 1826 test_ops.prepare_op = prepare_cipher_op; 1827 test_ops.prepare_xform = prepare_aes_xform; 1828 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 1829 test_ops.test = fips_mct_aes_test; 1830 else 1831 test_ops.test = fips_generic_test; 1832 break; 1833 case FIPS_TEST_ALGO_HMAC: 1834 test_ops.prepare_op = prepare_auth_op; 1835 test_ops.prepare_xform = prepare_hmac_xform; 1836 test_ops.test = fips_generic_test; 1837 break; 1838 case FIPS_TEST_ALGO_TDES: 1839 test_ops.prepare_op = prepare_cipher_op; 1840 test_ops.prepare_xform = prepare_tdes_xform; 1841 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1842 test_ops.test = fips_mct_tdes_test; 1843 else 1844 test_ops.test = fips_generic_test; 1845 break; 1846 case FIPS_TEST_ALGO_AES_GMAC: 1847 test_ops.prepare_op = prepare_auth_op; 1848 test_ops.prepare_xform = prepare_gmac_xform; 1849 test_ops.test = fips_generic_test; 1850 break; 1851 case FIPS_TEST_ALGO_AES_GCM: 1852 test_ops.prepare_op = prepare_aead_op; 1853 test_ops.prepare_xform = prepare_gcm_xform; 1854 test_ops.test = fips_generic_test; 1855 break; 1856 case FIPS_TEST_ALGO_AES_CMAC: 1857 test_ops.prepare_op = prepare_auth_op; 1858 test_ops.prepare_xform = prepare_cmac_xform; 1859 test_ops.test = fips_generic_test; 1860 break; 1861 case FIPS_TEST_ALGO_AES_CCM: 1862 test_ops.prepare_op = prepare_aead_op; 1863 test_ops.prepare_xform = prepare_ccm_xform; 1864 test_ops.test = fips_generic_test; 1865 break; 1866 case FIPS_TEST_ALGO_SHA: 1867 test_ops.prepare_op = prepare_auth_op; 1868 test_ops.prepare_xform = prepare_sha_xform; 1869 if (info.interim_info.sha_data.test_type == SHA_MCT) 1870 test_ops.test = fips_mct_sha_test; 1871 else 1872 test_ops.test = fips_generic_test; 1873 break; 1874 case FIPS_TEST_ALGO_AES_XTS: 1875 test_ops.prepare_op = prepare_cipher_op; 1876 test_ops.prepare_xform = prepare_xts_xform; 1877 test_ops.test = fips_generic_test; 1878 break; 1879 default: 1880 if (strstr(info.file_name, "TECB") || 1881 strstr(info.file_name, "TCBC")) { 1882 info.algo = FIPS_TEST_ALGO_TDES; 1883 test_ops.prepare_op = prepare_cipher_op; 1884 test_ops.prepare_xform = prepare_tdes_xform; 1885 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1886 test_ops.test = fips_mct_tdes_test; 1887 else 1888 test_ops.test = fips_generic_test; 1889 break; 1890 } 1891 return -1; 1892 } 1893 1894 return 0; 1895 } 1896 1897 static void 1898 print_test_block(void) 1899 { 1900 uint32_t i; 1901 1902 for (i = 0; i < info.nb_vec_lines; i++) 1903 printf("%s\n", info.vec[i]); 1904 1905 printf("\n"); 1906 } 1907 1908 static int 1909 fips_test_one_file(void) 1910 { 1911 int fetch_ret = 0, ret; 1912 1913 ret = init_test_ops(); 1914 if (ret < 0) { 1915 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 1916 return ret; 1917 } 1918 1919 while (ret >= 0 && fetch_ret == 0) { 1920 fetch_ret = fips_test_fetch_one_block(); 1921 if (fetch_ret < 0) { 1922 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 1923 fetch_ret); 1924 ret = fetch_ret; 1925 goto error_one_case; 1926 } 1927 1928 if (info.nb_vec_lines == 0) { 1929 if (fetch_ret == -EOF) 1930 break; 1931 1932 fprintf(info.fp_wr, "\n"); 1933 continue; 1934 } 1935 1936 ret = fips_test_parse_one_case(); 1937 switch (ret) { 1938 case 0: 1939 ret = test_ops.test(); 1940 if (ret == 0) 1941 break; 1942 RTE_LOG(ERR, USER1, "Error %i: test block\n", 1943 ret); 1944 goto error_one_case; 1945 case 1: 1946 break; 1947 default: 1948 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 1949 ret); 1950 goto error_one_case; 1951 } 1952 1953 continue; 1954 error_one_case: 1955 print_test_block(); 1956 } 1957 1958 fips_test_clear(); 1959 1960 if (env.digest) { 1961 rte_free(env.digest); 1962 env.digest = NULL; 1963 } 1964 rte_pktmbuf_free(env.mbuf); 1965 1966 return ret; 1967 } 1968 1969 #ifdef USE_JANSSON 1970 static int 1971 fips_test_json_init_writeback(void) 1972 { 1973 json_t *session_info, *session_write; 1974 session_info = json_array_get(json_info.json_root, 0); 1975 session_write = json_object(); 1976 json_info.json_write_root = json_array(); 1977 1978 json_object_set(session_write, "jwt", 1979 json_object_get(session_info, "jwt")); 1980 json_object_set(session_write, "url", 1981 json_object_get(session_info, "url")); 1982 json_object_set(session_write, "isSample", 1983 json_object_get(session_info, "isSample")); 1984 1985 json_info.is_sample = json_boolean_value( 1986 json_object_get(session_info, "isSample")); 1987 1988 json_array_append_new(json_info.json_write_root, session_write); 1989 return 0; 1990 } 1991 1992 static int 1993 fips_test_one_test_case(void) 1994 { 1995 int ret; 1996 1997 ret = fips_test_parse_one_json_case(); 1998 1999 switch (ret) { 2000 case 0: 2001 ret = test_ops.test(); 2002 if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP)) 2003 break; 2004 RTE_LOG(ERR, USER1, "Error %i: test block\n", 2005 ret); 2006 break; 2007 default: 2008 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 2009 ret); 2010 } 2011 return ret; 2012 } 2013 2014 static int 2015 fips_test_one_test_group(void) 2016 { 2017 int ret; 2018 json_t *tests, *write_tests; 2019 size_t test_idx, tests_size; 2020 2021 write_tests = json_array(); 2022 json_info.json_write_group = json_object(); 2023 json_object_set(json_info.json_write_group, "tgId", 2024 json_object_get(json_info.json_test_group, "tgId")); 2025 json_object_set_new(json_info.json_write_group, "tests", write_tests); 2026 2027 switch (info.algo) { 2028 case FIPS_TEST_ALGO_AES_GMAC: 2029 case FIPS_TEST_ALGO_AES_GCM: 2030 ret = parse_test_gcm_json_init(); 2031 break; 2032 case FIPS_TEST_ALGO_HMAC: 2033 ret = parse_test_hmac_json_init(); 2034 break; 2035 case FIPS_TEST_ALGO_AES_CMAC: 2036 ret = parse_test_cmac_json_init(); 2037 break; 2038 case FIPS_TEST_ALGO_AES_XTS: 2039 ret = parse_test_xts_json_init(); 2040 break; 2041 case FIPS_TEST_ALGO_AES_CBC: 2042 case FIPS_TEST_ALGO_AES_CTR: 2043 case FIPS_TEST_ALGO_AES: 2044 ret = parse_test_aes_json_init(); 2045 break; 2046 case FIPS_TEST_ALGO_SHA: 2047 ret = parse_test_sha_json_init(); 2048 break; 2049 case FIPS_TEST_ALGO_TDES: 2050 ret = parse_test_tdes_json_init(); 2051 break; 2052 default: 2053 return -EINVAL; 2054 } 2055 2056 if (ret < 0) 2057 return ret; 2058 2059 ret = fips_test_parse_one_json_group(); 2060 if (ret < 0) 2061 return ret; 2062 2063 ret = init_test_ops(); 2064 if (ret < 0) 2065 return ret; 2066 2067 tests = json_object_get(json_info.json_test_group, "tests"); 2068 tests_size = json_array_size(tests); 2069 for (test_idx = 0; test_idx < tests_size; test_idx++) { 2070 json_info.json_test_case = json_array_get(tests, test_idx); 2071 if (fips_test_one_test_case() == 0) 2072 json_array_append_new(write_tests, json_info.json_write_case); 2073 } 2074 2075 return 0; 2076 } 2077 2078 static int 2079 fips_test_one_vector_set(void) 2080 { 2081 int ret; 2082 json_t *test_groups, *write_groups, *write_version, *write_set; 2083 size_t group_idx, num_groups; 2084 2085 test_groups = json_object_get(json_info.json_vector_set, "testGroups"); 2086 num_groups = json_array_size(test_groups); 2087 2088 json_info.json_write_set = json_array(); 2089 write_version = json_object(); 2090 json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION)); 2091 json_array_append_new(json_info.json_write_set, write_version); 2092 2093 write_set = json_object(); 2094 json_array_append(json_info.json_write_set, write_set); 2095 write_groups = json_array(); 2096 2097 json_object_set(write_set, "vsId", 2098 json_object_get(json_info.json_vector_set, "vsId")); 2099 json_object_set(write_set, "algorithm", 2100 json_object_get(json_info.json_vector_set, "algorithm")); 2101 json_object_set(write_set, "revision", 2102 json_object_get(json_info.json_vector_set, "revision")); 2103 json_object_set_new(write_set, "isSample", 2104 json_boolean(json_info.is_sample)); 2105 json_object_set_new(write_set, "testGroups", write_groups); 2106 2107 ret = fips_test_parse_one_json_vector_set(); 2108 if (ret < 0) { 2109 RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n", 2110 json_string_value(json_object_get(json_info.json_vector_set, "algorithm"))); 2111 return ret; 2112 } 2113 2114 for (group_idx = 0; group_idx < num_groups; group_idx++) { 2115 json_info.json_test_group = json_array_get(test_groups, group_idx); 2116 ret = fips_test_one_test_group(); 2117 json_array_append_new(write_groups, json_info.json_write_group); 2118 } 2119 2120 return 0; 2121 } 2122 2123 static int 2124 fips_test_one_json_file(void) 2125 { 2126 size_t vector_set_idx, root_size; 2127 2128 root_size = json_array_size(json_info.json_root); 2129 fips_test_json_init_writeback(); 2130 2131 for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) { 2132 /* Vector set index starts at 1, the 0th index contains test session 2133 * information. 2134 */ 2135 json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx); 2136 fips_test_one_vector_set(); 2137 json_array_append_new(json_info.json_write_root, json_info.json_write_set); 2138 json_incref(json_info.json_write_set); 2139 } 2140 2141 json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4)); 2142 json_decref(json_info.json_write_root); 2143 2144 return 0; 2145 } 2146 #endif /* USE_JANSSON */ 2147