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 vec.cipher_auth.digest.len = 1945 parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth); 1946 test_ops.prepare_sym_xform = prepare_sha_xform; 1947 test_ops.prepare_sym_op = prepare_auth_op; 1948 1949 env.op = env.sym.op; 1950 ret = fips_run_sym_test(); 1951 if (ret < 0) 1952 return ret; 1953 } 1954 1955 env.op = env.asym.op; 1956 if (info.op == FIPS_TEST_ASYM_SIGGEN) { 1957 fips_prepare_asym_xform_t old_xform; 1958 fips_prepare_op_t old_op; 1959 1960 old_xform = test_ops.prepare_asym_xform; 1961 old_op = test_ops.prepare_asym_op; 1962 1963 if (info.algo == FIPS_TEST_ALGO_ECDSA && 1964 info.interim_info.ecdsa_data.pubkey_gen == 1) { 1965 info.op = FIPS_TEST_ASYM_KEYGEN; 1966 test_ops.prepare_asym_xform = prepare_ecfpm_xform; 1967 test_ops.prepare_asym_op = prepare_ecfpm_op; 1968 1969 ret = fips_run_asym_test(); 1970 if (ret < 0) 1971 return ret; 1972 1973 info.post_interim_writeback(NULL); 1974 info.interim_info.ecdsa_data.pubkey_gen = 0; 1975 1976 } else if (info.algo == FIPS_TEST_ALGO_EDDSA && 1977 info.interim_info.eddsa_data.pubkey_gen == 1) { 1978 info.op = FIPS_TEST_ASYM_KEYGEN; 1979 test_ops.prepare_asym_xform = prepare_edfpm_xform; 1980 test_ops.prepare_asym_op = prepare_edfpm_op; 1981 1982 const struct rte_cryptodev_asymmetric_xform_capability *cap; 1983 struct rte_cryptodev_asym_capability_idx cap_idx; 1984 1985 cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA; 1986 cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx); 1987 if (!cap) { 1988 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1989 env.dev_id); 1990 return -EINVAL; 1991 } 1992 1993 if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) { 1994 ret = fips_run_asym_test(); 1995 if (ret < 0) 1996 return ret; 1997 } else { 1998 /* Below is only a workaround by using known keys. */ 1999 struct rte_crypto_asym_xform xform = {0}; 2000 2001 prepare_edfpm_xform(&xform); 2002 prepare_edfpm_op(); 2003 uint8_t pkey25519[] = { 2004 0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d, 2005 0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e, 2006 0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b, 2007 0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42 2008 }; 2009 uint8_t q25519[] = { 2010 0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b, 2011 0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34, 2012 0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64, 2013 0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf 2014 }; 2015 uint8_t pkey448[] = { 2016 0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08, 2017 0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d, 2018 0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5, 2019 0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf, 2020 0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f, 2021 0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa, 2022 0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f, 2023 0x01 2024 }; 2025 uint8_t q448[] = { 2026 0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80, 2027 0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a, 2028 0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd, 2029 0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a, 2030 0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd, 2031 0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5, 2032 0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f, 2033 0x00 2034 }; 2035 if (info.interim_info.eddsa_data.curve_id == 2036 RTE_CRYPTO_EC_GROUP_ED25519) { 2037 memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519)); 2038 vec.eddsa.pkey.len = 32; 2039 memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519)); 2040 vec.eddsa.q.len = 32; 2041 } else { 2042 memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448)); 2043 vec.eddsa.pkey.len = 32; 2044 memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448)); 2045 vec.eddsa.q.len = 32; 2046 } 2047 } 2048 info.post_interim_writeback(NULL); 2049 info.interim_info.eddsa_data.pubkey_gen = 0; 2050 2051 } 2052 2053 test_ops.prepare_asym_xform = old_xform; 2054 test_ops.prepare_asym_op = old_op; 2055 info.op = FIPS_TEST_ASYM_SIGGEN; 2056 ret = fips_run_asym_test(); 2057 } else { 2058 ret = fips_run_asym_test(); 2059 } 2060 2061 return ret; 2062 } 2063 2064 static int 2065 fips_generic_test(void) 2066 { 2067 struct fips_val val = {NULL, 0}; 2068 int ret; 2069 2070 if (info.file_type != FIPS_TYPE_JSON) 2071 fips_test_write_one_case(); 2072 2073 ret = fips_run_test(); 2074 if (ret < 0) { 2075 if (ret == -EPERM || ret == -ENOTSUP) { 2076 if (info.file_type == FIPS_TYPE_JSON) 2077 return ret; 2078 2079 fprintf(info.fp_wr, "Bypass\n\n"); 2080 return 0; 2081 } 2082 2083 return ret; 2084 } 2085 2086 if (!env.is_asym_test) { 2087 ret = get_writeback_data(&val); 2088 if (ret < 0) 2089 return ret; 2090 } 2091 2092 switch (info.file_type) { 2093 case FIPS_TYPE_REQ: 2094 case FIPS_TYPE_RSP: 2095 case FIPS_TYPE_JSON: 2096 if (info.parse_writeback == NULL) 2097 return -EPERM; 2098 ret = info.parse_writeback(&val); 2099 if (ret < 0) 2100 return ret; 2101 break; 2102 case FIPS_TYPE_FAX: 2103 if (info.kat_check == NULL) 2104 return -EPERM; 2105 ret = info.kat_check(&val); 2106 if (ret < 0) 2107 return ret; 2108 break; 2109 default: 2110 break; 2111 } 2112 2113 if (info.file_type != FIPS_TYPE_JSON) 2114 fprintf(info.fp_wr, "\n"); 2115 rte_free(val.val); 2116 2117 return 0; 2118 } 2119 2120 static int 2121 fips_mct_tdes_test(void) 2122 { 2123 #define TDES_BLOCK_SIZE 8 2124 #define TDES_EXTERN_ITER 400 2125 #define TDES_INTERN_ITER 10000 2126 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 2127 uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; 2128 uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; 2129 uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; 2130 uint32_t i, j, k; 2131 int ret; 2132 int test_mode = info.interim_info.tdes_data.test_mode; 2133 2134 pt.len = vec.pt.len; 2135 pt.val = rte_malloc(NULL, pt.len, 0); 2136 ct.len = vec.ct.len; 2137 ct.val = rte_malloc(NULL, ct.len, 0); 2138 iv.len = vec.iv.len; 2139 iv.val = rte_malloc(NULL, iv.len, 0); 2140 2141 for (i = 0; i < TDES_EXTERN_ITER; i++) { 2142 if (info.file_type != FIPS_TYPE_JSON) { 2143 if ((i == 0) && (info.version == 21.4f)) { 2144 if (!(strstr(info.vec[0], "COUNT"))) 2145 fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0); 2146 } 2147 2148 if (i != 0) 2149 update_info_vec(i); 2150 2151 fips_test_write_one_case(); 2152 } 2153 2154 for (j = 0; j < TDES_INTERN_ITER; j++) { 2155 ret = fips_run_test(); 2156 if (ret < 0) { 2157 if (ret == -EPERM) { 2158 if (info.file_type == FIPS_TYPE_JSON) 2159 return ret; 2160 2161 fprintf(info.fp_wr, "Bypass\n"); 2162 return 0; 2163 } 2164 return ret; 2165 } 2166 2167 ret = get_writeback_data(&val[0]); 2168 if (ret < 0) 2169 return ret; 2170 2171 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 2172 memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 2173 2174 if (j == 0) { 2175 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 2176 memcpy(pt.val, vec.pt.val, pt.len); 2177 memcpy(ct.val, vec.ct.val, ct.len); 2178 memcpy(iv.val, vec.iv.val, iv.len); 2179 2180 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2181 if (test_mode == TDES_MODE_ECB) { 2182 memcpy(vec.pt.val, val[0].val, 2183 TDES_BLOCK_SIZE); 2184 } else { 2185 memcpy(vec.pt.val, vec.iv.val, 2186 TDES_BLOCK_SIZE); 2187 memcpy(vec.iv.val, val[0].val, 2188 TDES_BLOCK_SIZE); 2189 } 2190 val[1].val = pt.val; 2191 val[1].len = pt.len; 2192 val[2].val = iv.val; 2193 val[2].len = iv.len; 2194 } else { 2195 if (test_mode == TDES_MODE_ECB) { 2196 memcpy(vec.ct.val, val[0].val, 2197 TDES_BLOCK_SIZE); 2198 } else { 2199 memcpy(vec.iv.val, vec.ct.val, 2200 TDES_BLOCK_SIZE); 2201 memcpy(vec.ct.val, val[0].val, 2202 TDES_BLOCK_SIZE); 2203 } 2204 val[1].val = ct.val; 2205 val[1].len = ct.len; 2206 val[2].val = iv.val; 2207 val[2].len = iv.len; 2208 } 2209 continue; 2210 } 2211 2212 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2213 if (test_mode == TDES_MODE_ECB) { 2214 memcpy(vec.pt.val, val[0].val, 2215 TDES_BLOCK_SIZE); 2216 } else { 2217 memcpy(vec.iv.val, val[0].val, 2218 TDES_BLOCK_SIZE); 2219 memcpy(vec.pt.val, prev_out, 2220 TDES_BLOCK_SIZE); 2221 } 2222 } else { 2223 if (test_mode == TDES_MODE_ECB) { 2224 memcpy(vec.ct.val, val[0].val, 2225 TDES_BLOCK_SIZE); 2226 } else { 2227 memcpy(vec.iv.val, vec.ct.val, 2228 TDES_BLOCK_SIZE); 2229 memcpy(vec.ct.val, val[0].val, 2230 TDES_BLOCK_SIZE); 2231 } 2232 } 2233 2234 if (j == TDES_INTERN_ITER - 1) 2235 continue; 2236 2237 memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE); 2238 2239 if (j == TDES_INTERN_ITER - 3) 2240 memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE); 2241 } 2242 2243 info.parse_writeback(val); 2244 if (info.file_type != FIPS_TYPE_JSON) 2245 fprintf(info.fp_wr, "\n"); 2246 2247 if (i == TDES_EXTERN_ITER - 1) 2248 continue; 2249 2250 /** update key */ 2251 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2252 2253 if (info.interim_info.tdes_data.nb_keys == 0) { 2254 if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 2255 info.interim_info.tdes_data.nb_keys = 1; 2256 else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 2257 info.interim_info.tdes_data.nb_keys = 2; 2258 else 2259 info.interim_info.tdes_data.nb_keys = 3; 2260 2261 } 2262 2263 for (k = 0; k < TDES_BLOCK_SIZE; k++) { 2264 2265 switch (info.interim_info.tdes_data.nb_keys) { 2266 case 3: 2267 val_key.val[k] ^= val[0].val[k]; 2268 val_key.val[k + 8] ^= prev_out[k]; 2269 val_key.val[k + 16] ^= prev_prev_out[k]; 2270 break; 2271 case 2: 2272 val_key.val[k] ^= val[0].val[k]; 2273 val_key.val[k + 8] ^= prev_out[k]; 2274 val_key.val[k + 16] ^= val[0].val[k]; 2275 break; 2276 default: /* case 1 */ 2277 val_key.val[k] ^= val[0].val[k]; 2278 val_key.val[k + 8] ^= val[0].val[k]; 2279 val_key.val[k + 16] ^= val[0].val[k]; 2280 break; 2281 } 2282 2283 } 2284 2285 for (k = 0; k < 24; k++) 2286 val_key.val[k] = (rte_popcount32(val_key.val[k]) & 2287 0x1) ? 2288 val_key.val[k] : (val_key.val[k] ^ 0x1); 2289 2290 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2291 if (test_mode == TDES_MODE_ECB) { 2292 memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE); 2293 } else { 2294 memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE); 2295 memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 2296 } 2297 } else { 2298 if (test_mode == TDES_MODE_ECB) { 2299 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 2300 } else { 2301 memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 2302 memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE); 2303 } 2304 } 2305 } 2306 2307 rte_free(val[0].val); 2308 rte_free(pt.val); 2309 rte_free(ct.val); 2310 rte_free(iv.val); 2311 2312 return 0; 2313 } 2314 2315 static int 2316 fips_mct_aes_ecb_test(void) 2317 { 2318 #define AES_BLOCK_SIZE 16 2319 #define AES_EXTERN_ITER 100 2320 #define AES_INTERN_ITER 1000 2321 struct fips_val val = {NULL, 0}, val_key; 2322 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 2323 uint32_t i, j, k; 2324 int ret; 2325 2326 for (i = 0; i < AES_EXTERN_ITER; i++) { 2327 if (i != 0) 2328 update_info_vec(i); 2329 2330 fips_test_write_one_case(); 2331 2332 for (j = 0; j < AES_INTERN_ITER; j++) { 2333 ret = fips_run_test(); 2334 if (ret < 0) { 2335 if (ret == -EPERM) { 2336 if (info.file_type == FIPS_TYPE_JSON) 2337 return ret; 2338 2339 fprintf(info.fp_wr, "Bypass\n"); 2340 return 0; 2341 } 2342 2343 return ret; 2344 } 2345 2346 ret = get_writeback_data(&val); 2347 if (ret < 0) 2348 return ret; 2349 2350 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 2351 memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); 2352 else 2353 memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); 2354 2355 if (j == AES_INTERN_ITER - 1) 2356 continue; 2357 2358 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 2359 } 2360 2361 info.parse_writeback(&val); 2362 fprintf(info.fp_wr, "\n"); 2363 2364 if (i == AES_EXTERN_ITER - 1) 2365 continue; 2366 2367 /** update key */ 2368 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2369 for (k = 0; k < vec.cipher_auth.key.len; k++) { 2370 switch (vec.cipher_auth.key.len) { 2371 case 16: 2372 val_key.val[k] ^= val.val[k]; 2373 break; 2374 case 24: 2375 if (k < 8) 2376 val_key.val[k] ^= prev_out[k + 8]; 2377 else 2378 val_key.val[k] ^= val.val[k - 8]; 2379 break; 2380 case 32: 2381 if (k < 16) 2382 val_key.val[k] ^= prev_out[k]; 2383 else 2384 val_key.val[k] ^= val.val[k - 16]; 2385 break; 2386 default: 2387 return -1; 2388 } 2389 } 2390 } 2391 2392 rte_free(val.val); 2393 2394 return 0; 2395 } 2396 static int 2397 fips_mct_aes_test(void) 2398 { 2399 #define AES_BLOCK_SIZE 16 2400 #define AES_EXTERN_ITER 100 2401 #define AES_INTERN_ITER 1000 2402 struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv; 2403 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 2404 uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 2405 uint32_t i, j, k; 2406 int ret; 2407 2408 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) 2409 return fips_mct_aes_ecb_test(); 2410 2411 pt.len = vec.pt.len; 2412 pt.val = rte_malloc(NULL, pt.len, 0); 2413 ct.len = vec.ct.len; 2414 ct.val = rte_malloc(NULL, ct.len, 0); 2415 iv.len = vec.iv.len; 2416 iv.val = rte_malloc(NULL, iv.len, 0); 2417 for (i = 0; i < AES_EXTERN_ITER; i++) { 2418 if (info.file_type != FIPS_TYPE_JSON) { 2419 if (i != 0) 2420 update_info_vec(i); 2421 2422 fips_test_write_one_case(); 2423 } 2424 2425 for (j = 0; j < AES_INTERN_ITER; j++) { 2426 ret = fips_run_test(); 2427 if (ret < 0) { 2428 if (ret == -EPERM) { 2429 if (info.file_type == FIPS_TYPE_JSON) 2430 return ret; 2431 2432 fprintf(info.fp_wr, "Bypass\n"); 2433 return 0; 2434 } 2435 2436 return ret; 2437 } 2438 2439 ret = get_writeback_data(&val[0]); 2440 if (ret < 0) 2441 return ret; 2442 2443 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 2444 memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 2445 2446 if (j == 0) { 2447 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 2448 memcpy(pt.val, vec.pt.val, pt.len); 2449 memcpy(ct.val, vec.ct.val, ct.len); 2450 memcpy(iv.val, vec.iv.val, iv.len); 2451 2452 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2453 memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE); 2454 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2455 val[1].val = pt.val; 2456 val[1].len = pt.len; 2457 val[2].val = iv.val; 2458 val[2].len = iv.len; 2459 } else { 2460 memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE); 2461 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 2462 val[1].val = ct.val; 2463 val[1].len = ct.len; 2464 val[2].val = iv.val; 2465 val[2].len = iv.len; 2466 } 2467 continue; 2468 } 2469 2470 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 2471 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2472 memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 2473 } else { 2474 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 2475 memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 2476 } 2477 2478 if (j == AES_INTERN_ITER - 1) 2479 continue; 2480 2481 memcpy(prev_out, val[0].val, AES_BLOCK_SIZE); 2482 } 2483 2484 info.parse_writeback(val); 2485 if (info.file_type != FIPS_TYPE_JSON) 2486 fprintf(info.fp_wr, "\n"); 2487 2488 if (i == AES_EXTERN_ITER - 1) 2489 continue; 2490 2491 /** update key */ 2492 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 2493 for (k = 0; k < vec.cipher_auth.key.len; k++) { 2494 switch (vec.cipher_auth.key.len) { 2495 case 16: 2496 val_key.val[k] ^= val[0].val[k]; 2497 break; 2498 case 24: 2499 if (k < 8) 2500 val_key.val[k] ^= prev_out[k + 8]; 2501 else 2502 val_key.val[k] ^= val[0].val[k - 8]; 2503 break; 2504 case 32: 2505 if (k < 16) 2506 val_key.val[k] ^= prev_out[k]; 2507 else 2508 val_key.val[k] ^= val[0].val[k - 16]; 2509 break; 2510 default: 2511 return -1; 2512 } 2513 } 2514 2515 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 2516 memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE); 2517 } 2518 2519 rte_free(val[0].val); 2520 rte_free(pt.val); 2521 rte_free(ct.val); 2522 rte_free(iv.val); 2523 2524 return 0; 2525 } 2526 2527 static int 2528 fips_mct_sha_test(void) 2529 { 2530 #define SHA_EXTERN_ITER 100 2531 #define SHA_INTERN_ITER 1000 2532 uint8_t md_blocks = info.interim_info.sha_data.md_blocks; 2533 struct fips_val val = {NULL, 0}; 2534 struct fips_val md[md_blocks]; 2535 int ret; 2536 uint32_t i, j, k, offset, max_outlen; 2537 2538 max_outlen = md_blocks * vec.cipher_auth.digest.len; 2539 2540 rte_free(vec.cipher_auth.digest.val); 2541 vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0); 2542 2543 if (vec.pt.val) 2544 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len); 2545 2546 rte_free(vec.pt.val); 2547 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*md_blocks), 0); 2548 2549 for (i = 0; i < md_blocks; i++) 2550 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 2551 2552 if (info.file_type != FIPS_TYPE_JSON) { 2553 fips_test_write_one_case(); 2554 fprintf(info.fp_wr, "\n"); 2555 } 2556 2557 for (j = 0; j < SHA_EXTERN_ITER; j++) { 2558 for (i = 0; i < md_blocks; i++) { 2559 memcpy(md[i].val, vec.cipher_auth.digest.val, 2560 vec.cipher_auth.digest.len); 2561 md[i].len = vec.cipher_auth.digest.len; 2562 } 2563 2564 for (i = 0; i < (SHA_INTERN_ITER); i++) { 2565 offset = 0; 2566 for (k = 0; k < md_blocks; k++) { 2567 memcpy(vec.pt.val + offset, md[k].val, (size_t)md[k].len); 2568 offset += md[k].len; 2569 } 2570 vec.pt.len = offset; 2571 2572 ret = fips_run_test(); 2573 if (ret < 0) { 2574 if (ret == -EPERM || ret == -ENOTSUP) { 2575 if (info.file_type == FIPS_TYPE_JSON) 2576 return ret; 2577 2578 fprintf(info.fp_wr, "Bypass\n\n"); 2579 return 0; 2580 } 2581 return ret; 2582 } 2583 2584 ret = get_writeback_data(&val); 2585 if (ret < 0) 2586 return ret; 2587 2588 for (k = 1; k < md_blocks; k++) { 2589 memcpy(md[k-1].val, md[k].val, md[k].len); 2590 md[k-1].len = md[k].len; 2591 } 2592 2593 memcpy(md[md_blocks-1].val, (val.val + vec.pt.len), 2594 vec.cipher_auth.digest.len); 2595 md[md_blocks-1].len = vec.cipher_auth.digest.len; 2596 } 2597 2598 memcpy(vec.cipher_auth.digest.val, md[md_blocks-1].val, md[md_blocks-1].len); 2599 vec.cipher_auth.digest.len = md[md_blocks-1].len; 2600 2601 if (info.file_type != FIPS_TYPE_JSON) 2602 fprintf(info.fp_wr, "COUNT = %u\n", j); 2603 2604 info.parse_writeback(&val); 2605 2606 if (info.file_type != FIPS_TYPE_JSON) 2607 fprintf(info.fp_wr, "\n"); 2608 } 2609 2610 for (i = 0; i < (md_blocks); i++) 2611 rte_free(md[i].val); 2612 2613 rte_free(vec.pt.val); 2614 2615 rte_free(val.val); 2616 return 0; 2617 } 2618 2619 static int 2620 fips_mct_shake_test(void) 2621 { 2622 #define SHAKE_EXTERN_ITER 100 2623 #define SHAKE_INTERN_ITER 1000 2624 uint32_t i, j, range, outlen, max_outlen; 2625 struct fips_val val = {NULL, 0}, md; 2626 uint8_t rightmost[2]; 2627 uint16_t *rightptr; 2628 int ret; 2629 2630 max_outlen = vec.cipher_auth.digest.len; 2631 2632 rte_free(vec.cipher_auth.digest.val); 2633 vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0); 2634 2635 if (vec.pt.val) 2636 memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.pt.len); 2637 2638 rte_free(vec.pt.val); 2639 vec.pt.val = rte_malloc(NULL, 16, 0); 2640 vec.pt.len = 16; 2641 2642 md.val = rte_malloc(NULL, max_outlen, 0); 2643 md.len = max_outlen; 2644 2645 if (info.file_type != FIPS_TYPE_JSON) { 2646 fips_test_write_one_case(); 2647 fprintf(info.fp_wr, "\n"); 2648 } 2649 2650 range = max_outlen - info.interim_info.sha_data.min_outlen + 1; 2651 outlen = max_outlen; 2652 for (j = 0; j < SHAKE_EXTERN_ITER; j++) { 2653 memset(md.val, 0, max_outlen); 2654 memcpy(md.val, vec.cipher_auth.digest.val, 2655 vec.cipher_auth.digest.len); 2656 2657 for (i = 0; i < (SHAKE_INTERN_ITER); i++) { 2658 memset(vec.pt.val, 0, vec.pt.len); 2659 memcpy(vec.pt.val, md.val, vec.pt.len); 2660 vec.cipher_auth.digest.len = outlen; 2661 ret = fips_run_test(); 2662 if (ret < 0) { 2663 if (ret == -EPERM || ret == -ENOTSUP) { 2664 if (info.file_type == FIPS_TYPE_JSON) 2665 return ret; 2666 2667 fprintf(info.fp_wr, "Bypass\n\n"); 2668 return 0; 2669 } 2670 return ret; 2671 } 2672 2673 ret = get_writeback_data(&val); 2674 if (ret < 0) 2675 return ret; 2676 2677 memset(md.val, 0, max_outlen); 2678 memcpy(md.val, (val.val + vec.pt.len), 2679 vec.cipher_auth.digest.len); 2680 md.len = outlen; 2681 rightmost[0] = md.val[md.len-1]; 2682 rightmost[1] = md.val[md.len-2]; 2683 rightptr = (uint16_t *)rightmost; 2684 outlen = info.interim_info.sha_data.min_outlen + 2685 (*rightptr % range); 2686 } 2687 2688 memcpy(vec.cipher_auth.digest.val, md.val, md.len); 2689 vec.cipher_auth.digest.len = md.len; 2690 2691 if (info.file_type != FIPS_TYPE_JSON) 2692 fprintf(info.fp_wr, "COUNT = %u\n", j); 2693 2694 info.parse_writeback(&val); 2695 2696 if (info.file_type != FIPS_TYPE_JSON) 2697 fprintf(info.fp_wr, "\n"); 2698 } 2699 2700 rte_free(md.val); 2701 rte_free(vec.pt.val); 2702 rte_free(val.val); 2703 return 0; 2704 } 2705 2706 static int 2707 init_test_ops(void) 2708 { 2709 switch (info.algo) { 2710 case FIPS_TEST_ALGO_AES_CBC: 2711 case FIPS_TEST_ALGO_AES_CTR: 2712 case FIPS_TEST_ALGO_AES: 2713 test_ops.prepare_sym_op = prepare_cipher_op; 2714 test_ops.prepare_sym_xform = prepare_aes_xform; 2715 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 2716 test_ops.test = fips_mct_aes_test; 2717 else 2718 test_ops.test = fips_generic_test; 2719 break; 2720 case FIPS_TEST_ALGO_HMAC: 2721 test_ops.prepare_sym_op = prepare_auth_op; 2722 test_ops.prepare_sym_xform = prepare_hmac_xform; 2723 test_ops.test = fips_generic_test; 2724 break; 2725 case FIPS_TEST_ALGO_TDES: 2726 test_ops.prepare_sym_op = prepare_cipher_op; 2727 test_ops.prepare_sym_xform = prepare_tdes_xform; 2728 if (info.interim_info.tdes_data.test_type == TDES_MCT) 2729 test_ops.test = fips_mct_tdes_test; 2730 else 2731 test_ops.test = fips_generic_test; 2732 break; 2733 case FIPS_TEST_ALGO_AES_GMAC: 2734 test_ops.prepare_sym_op = prepare_auth_op; 2735 test_ops.prepare_sym_xform = prepare_gmac_xform; 2736 test_ops.test = fips_generic_test; 2737 break; 2738 case FIPS_TEST_ALGO_AES_GCM: 2739 test_ops.prepare_sym_op = prepare_aead_op; 2740 test_ops.prepare_sym_xform = prepare_gcm_xform; 2741 test_ops.test = fips_generic_test; 2742 break; 2743 case FIPS_TEST_ALGO_AES_CMAC: 2744 test_ops.prepare_sym_op = prepare_auth_op; 2745 test_ops.prepare_sym_xform = prepare_cmac_xform; 2746 test_ops.test = fips_generic_test; 2747 break; 2748 case FIPS_TEST_ALGO_AES_CCM: 2749 test_ops.prepare_sym_op = prepare_aead_op; 2750 test_ops.prepare_sym_xform = prepare_ccm_xform; 2751 test_ops.test = fips_generic_test; 2752 break; 2753 case FIPS_TEST_ALGO_SHA: 2754 test_ops.prepare_sym_op = prepare_auth_op; 2755 test_ops.prepare_sym_xform = prepare_sha_xform; 2756 if (info.interim_info.sha_data.test_type == SHA_MCT) 2757 if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 || 2758 info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256) 2759 test_ops.test = fips_mct_shake_test; 2760 else 2761 test_ops.test = fips_mct_sha_test; 2762 else 2763 test_ops.test = fips_generic_test; 2764 break; 2765 case FIPS_TEST_ALGO_AES_XTS: 2766 test_ops.prepare_sym_op = prepare_cipher_op; 2767 test_ops.prepare_sym_xform = prepare_xts_xform; 2768 test_ops.test = fips_generic_test; 2769 break; 2770 case FIPS_TEST_ALGO_RSA: 2771 test_ops.prepare_asym_op = prepare_rsa_op; 2772 test_ops.prepare_asym_xform = prepare_rsa_xform; 2773 test_ops.test = fips_generic_test; 2774 break; 2775 case FIPS_TEST_ALGO_ECDSA: 2776 if (info.op == FIPS_TEST_ASYM_KEYGEN) { 2777 test_ops.prepare_asym_op = prepare_ecfpm_op; 2778 test_ops.prepare_asym_xform = prepare_ecfpm_xform; 2779 test_ops.test = fips_generic_test; 2780 } else { 2781 test_ops.prepare_asym_op = prepare_ecdsa_op; 2782 test_ops.prepare_asym_xform = prepare_ecdsa_xform; 2783 test_ops.test = fips_generic_test; 2784 } 2785 break; 2786 case FIPS_TEST_ALGO_EDDSA: 2787 if (info.op == FIPS_TEST_ASYM_KEYGEN) { 2788 test_ops.prepare_asym_op = prepare_edfpm_op; 2789 test_ops.prepare_asym_xform = prepare_edfpm_xform; 2790 test_ops.test = fips_generic_test; 2791 } else { 2792 test_ops.prepare_asym_op = prepare_eddsa_op; 2793 test_ops.prepare_asym_xform = prepare_eddsa_xform; 2794 test_ops.test = fips_generic_test; 2795 } 2796 break; 2797 default: 2798 if (strstr(info.file_name, "TECB") || 2799 strstr(info.file_name, "TCBC")) { 2800 info.algo = FIPS_TEST_ALGO_TDES; 2801 test_ops.prepare_sym_op = prepare_cipher_op; 2802 test_ops.prepare_sym_xform = prepare_tdes_xform; 2803 if (info.interim_info.tdes_data.test_type == TDES_MCT) 2804 test_ops.test = fips_mct_tdes_test; 2805 else 2806 test_ops.test = fips_generic_test; 2807 break; 2808 } 2809 return -1; 2810 } 2811 2812 return 0; 2813 } 2814 2815 static void 2816 print_test_block(void) 2817 { 2818 uint32_t i; 2819 2820 for (i = 0; i < info.nb_vec_lines; i++) 2821 printf("%s\n", info.vec[i]); 2822 2823 printf("\n"); 2824 } 2825 2826 static int 2827 fips_test_one_file(void) 2828 { 2829 int fetch_ret = 0, ret; 2830 2831 ret = init_test_ops(); 2832 if (ret < 0) { 2833 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 2834 return ret; 2835 } 2836 2837 while (ret >= 0 && fetch_ret == 0) { 2838 fetch_ret = fips_test_fetch_one_block(); 2839 if (fetch_ret < 0) { 2840 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 2841 fetch_ret); 2842 ret = fetch_ret; 2843 goto error_one_case; 2844 } 2845 2846 if (info.nb_vec_lines == 0) { 2847 if (fetch_ret == -EOF) 2848 break; 2849 2850 fprintf(info.fp_wr, "\n"); 2851 continue; 2852 } 2853 2854 ret = fips_test_parse_one_case(); 2855 switch (ret) { 2856 case 0: 2857 ret = test_ops.test(); 2858 if (ret == 0) 2859 break; 2860 RTE_LOG(ERR, USER1, "Error %i: test block\n", 2861 ret); 2862 goto error_one_case; 2863 case 1: 2864 break; 2865 default: 2866 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 2867 ret); 2868 goto error_one_case; 2869 } 2870 2871 continue; 2872 error_one_case: 2873 print_test_block(); 2874 } 2875 2876 fips_test_clear(); 2877 2878 if (env.digest) { 2879 rte_free(env.digest); 2880 env.digest = NULL; 2881 env.digest_len = 0; 2882 } 2883 rte_pktmbuf_free(env.mbuf); 2884 2885 return ret; 2886 } 2887 2888 #ifdef USE_JANSSON 2889 static int 2890 fips_test_json_init_writeback(void) 2891 { 2892 json_t *session_info, *session_write; 2893 session_info = json_array_get(json_info.json_root, 0); 2894 session_write = json_object(); 2895 json_info.json_write_root = json_array(); 2896 2897 json_object_set(session_write, "jwt", 2898 json_object_get(session_info, "jwt")); 2899 json_object_set(session_write, "url", 2900 json_object_get(session_info, "url")); 2901 json_object_set(session_write, "isSample", 2902 json_object_get(session_info, "isSample")); 2903 2904 json_info.is_sample = json_boolean_value( 2905 json_object_get(session_info, "isSample")); 2906 2907 json_array_append_new(json_info.json_write_root, session_write); 2908 return 0; 2909 } 2910 2911 static int 2912 fips_test_one_test_case(void) 2913 { 2914 int ret; 2915 2916 ret = fips_test_parse_one_json_case(); 2917 2918 switch (ret) { 2919 case 0: 2920 ret = test_ops.test(); 2921 if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP)) 2922 break; 2923 RTE_LOG(ERR, USER1, "Error %i: test block\n", 2924 ret); 2925 break; 2926 default: 2927 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 2928 ret); 2929 } 2930 return ret; 2931 } 2932 2933 static int 2934 fips_test_one_test_group(void) 2935 { 2936 int ret; 2937 json_t *tests, *write_tests; 2938 size_t test_idx, tests_size; 2939 2940 write_tests = json_array(); 2941 json_info.json_write_group = json_object(); 2942 json_object_set(json_info.json_write_group, "tgId", 2943 json_object_get(json_info.json_test_group, "tgId")); 2944 json_object_set_new(json_info.json_write_group, "tests", write_tests); 2945 2946 switch (info.algo) { 2947 case FIPS_TEST_ALGO_AES_GMAC: 2948 case FIPS_TEST_ALGO_AES_GCM: 2949 ret = parse_test_gcm_json_init(); 2950 break; 2951 case FIPS_TEST_ALGO_AES_CCM: 2952 ret = parse_test_ccm_json_init(); 2953 break; 2954 case FIPS_TEST_ALGO_HMAC: 2955 ret = parse_test_hmac_json_init(); 2956 break; 2957 case FIPS_TEST_ALGO_AES_CMAC: 2958 ret = parse_test_cmac_json_init(); 2959 break; 2960 case FIPS_TEST_ALGO_AES_XTS: 2961 ret = parse_test_xts_json_init(); 2962 break; 2963 case FIPS_TEST_ALGO_AES_CBC: 2964 case FIPS_TEST_ALGO_AES_CTR: 2965 case FIPS_TEST_ALGO_AES: 2966 ret = parse_test_aes_json_init(); 2967 break; 2968 case FIPS_TEST_ALGO_SHA: 2969 ret = parse_test_sha_json_init(); 2970 break; 2971 case FIPS_TEST_ALGO_TDES: 2972 ret = parse_test_tdes_json_init(); 2973 break; 2974 case FIPS_TEST_ALGO_RSA: 2975 ret = parse_test_rsa_json_init(); 2976 break; 2977 case FIPS_TEST_ALGO_ECDSA: 2978 ret = parse_test_ecdsa_json_init(); 2979 break; 2980 case FIPS_TEST_ALGO_EDDSA: 2981 ret = parse_test_eddsa_json_init(); 2982 break; 2983 default: 2984 return -EINVAL; 2985 } 2986 2987 if (ret < 0) 2988 return ret; 2989 2990 ret = fips_test_parse_one_json_group(); 2991 if (ret < 0) 2992 return ret; 2993 2994 ret = init_test_ops(); 2995 if (ret < 0) 2996 return ret; 2997 2998 tests = json_object_get(json_info.json_test_group, "tests"); 2999 tests_size = json_array_size(tests); 3000 for (test_idx = 0; test_idx < tests_size; test_idx++) { 3001 json_info.json_test_case = json_array_get(tests, test_idx); 3002 if (fips_test_one_test_case() == 0) 3003 json_array_append_new(write_tests, json_info.json_write_case); 3004 } 3005 3006 return 0; 3007 } 3008 3009 static int 3010 fips_test_one_vector_set(void) 3011 { 3012 int ret; 3013 json_t *test_groups, *write_groups, *write_version, *write_set, *mode; 3014 size_t group_idx, num_groups; 3015 3016 test_groups = json_object_get(json_info.json_vector_set, "testGroups"); 3017 num_groups = json_array_size(test_groups); 3018 3019 json_info.json_write_set = json_array(); 3020 write_version = json_object(); 3021 json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION)); 3022 json_array_append_new(json_info.json_write_set, write_version); 3023 3024 write_set = json_object(); 3025 json_array_append(json_info.json_write_set, write_set); 3026 write_groups = json_array(); 3027 3028 json_object_set(write_set, "vsId", 3029 json_object_get(json_info.json_vector_set, "vsId")); 3030 json_object_set(write_set, "algorithm", 3031 json_object_get(json_info.json_vector_set, "algorithm")); 3032 mode = json_object_get(json_info.json_vector_set, "mode"); 3033 if (mode != NULL) 3034 json_object_set_new(write_set, "mode", mode); 3035 3036 json_object_set(write_set, "revision", 3037 json_object_get(json_info.json_vector_set, "revision")); 3038 json_object_set_new(write_set, "isSample", 3039 json_boolean(json_info.is_sample)); 3040 json_object_set_new(write_set, "testGroups", write_groups); 3041 3042 ret = fips_test_parse_one_json_vector_set(); 3043 if (ret < 0) { 3044 RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n", 3045 json_string_value(json_object_get(json_info.json_vector_set, "algorithm"))); 3046 return ret; 3047 } 3048 3049 for (group_idx = 0; group_idx < num_groups; group_idx++) { 3050 json_info.json_test_group = json_array_get(test_groups, group_idx); 3051 ret = fips_test_one_test_group(); 3052 json_array_append_new(write_groups, json_info.json_write_group); 3053 } 3054 3055 return 0; 3056 } 3057 3058 static int 3059 fips_test_one_json_file(void) 3060 { 3061 size_t vector_set_idx, root_size; 3062 3063 root_size = json_array_size(json_info.json_root); 3064 fips_test_json_init_writeback(); 3065 3066 for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) { 3067 /* Vector set index starts at 1, the 0th index contains test session 3068 * information. 3069 */ 3070 json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx); 3071 fips_test_one_vector_set(); 3072 json_array_append_new(json_info.json_write_root, json_info.json_write_set); 3073 json_incref(json_info.json_write_set); 3074 } 3075 3076 json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4)); 3077 json_decref(json_info.json_write_root); 3078 3079 return 0; 3080 } 3081 #endif /* USE_JANSSON */ 3082