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