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