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