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