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