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 return 0; 138 139 error_exit: 140 141 rte_mempool_free(env.mpool); 142 if (env.sess_mpool) 143 rte_mempool_free(env.sess_mpool); 144 if (env.sess_priv_mpool) 145 rte_mempool_free(env.sess_priv_mpool); 146 if (env.op_pool) 147 rte_mempool_free(env.op_pool); 148 149 return ret; 150 } 151 152 static void 153 cryptodev_fips_validate_app_uninit(void) 154 { 155 rte_pktmbuf_free(env.mbuf); 156 rte_crypto_op_free(env.op); 157 rte_cryptodev_sym_session_clear(env.dev_id, env.sess); 158 rte_cryptodev_sym_session_free(env.sess); 159 rte_mempool_free(env.mpool); 160 rte_mempool_free(env.sess_mpool); 161 rte_mempool_free(env.sess_priv_mpool); 162 rte_mempool_free(env.op_pool); 163 } 164 165 static int 166 fips_test_one_file(void); 167 168 static int 169 parse_cryptodev_arg(char *arg) 170 { 171 int id = rte_cryptodev_get_dev_id(arg); 172 173 if (id < 0) { 174 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n", 175 id, arg); 176 return id; 177 } 178 179 env.dev_id = (uint8_t)id; 180 181 return 0; 182 } 183 184 static int 185 parse_cryptodev_id_arg(char *arg) 186 { 187 uint32_t cryptodev_id; 188 189 if (parser_read_uint32(&cryptodev_id, arg) < 0) { 190 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", 191 -EINVAL, arg); 192 return -1; 193 } 194 195 196 if (!rte_cryptodev_is_valid_dev(cryptodev_id)) { 197 RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", 198 cryptodev_id, arg); 199 return -1; 200 } 201 202 env.dev_id = (uint8_t)cryptodev_id; 203 204 return 0; 205 } 206 207 static void 208 cryptodev_fips_validate_usage(const char *prgname) 209 { 210 uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE; 211 printf("%s [EAL options] --\n" 212 " --%s: REQUEST-FILE-PATH\n" 213 " --%s: RESPONSE-FILE-PATH\n" 214 " --%s: indicating both paths are folders\n" 215 " --%s: mbuf dataroom size (default %u bytes)\n" 216 " --%s: CRYPTODEV-NAME\n" 217 " --%s: CRYPTODEV-ID-NAME\n" 218 " --%s: self test indicator\n" 219 " --%s: self broken test ID\n" 220 " --%s: self broken test direction\n", 221 prgname, OPT_REQ_FILE_PATH, OPT_RSP_FILE_PATH, 222 OPT_FOLDER, OPT_MBUF_DATAROOM, def_mbuf_seg_size, 223 OPT_CRYPTODEV, OPT_CRYPTODEV_ID, OPT_CRYPTODEV_ST, 224 OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY); 225 } 226 227 static int 228 cryptodev_fips_validate_parse_args(int argc, char **argv) 229 { 230 int opt, ret; 231 char *prgname = argv[0]; 232 char **argvopt; 233 int option_index; 234 struct option lgopts[] = { 235 {OPT_REQ_FILE_PATH, required_argument, 236 NULL, OPT_REQ_FILE_PATH_NUM}, 237 {OPT_RSP_FILE_PATH, required_argument, 238 NULL, OPT_RSP_FILE_PATH_NUM}, 239 {OPT_FOLDER, no_argument, 240 NULL, OPT_FOLDER_NUM}, 241 {OPT_MBUF_DATAROOM, required_argument, 242 NULL, OPT_MBUF_DATAROOM_NUM}, 243 {OPT_CRYPTODEV, required_argument, 244 NULL, OPT_CRYPTODEV_NUM}, 245 {OPT_CRYPTODEV_ID, required_argument, 246 NULL, OPT_CRYPTODEV_ID_NUM}, 247 {OPT_CRYPTODEV_ST, no_argument, 248 NULL, OPT_CRYPTODEV_ST_NUM}, 249 {OPT_CRYPTODEV_BK_ID, required_argument, 250 NULL, OPT_CRYPTODEV_BK_ID_NUM}, 251 {OPT_CRYPTODEV_BK_DIR_KEY, required_argument, 252 NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM}, 253 {NULL, 0, 0, 0} 254 }; 255 256 argvopt = argv; 257 258 env.mbuf_data_room = DEF_MBUF_SEG_SIZE; 259 if (rte_cryptodev_count()) 260 env.dev_id = 0; 261 else { 262 cryptodev_fips_validate_usage(prgname); 263 return -EINVAL; 264 } 265 266 while ((opt = getopt_long(argc, argvopt, "s:", 267 lgopts, &option_index)) != EOF) { 268 269 switch (opt) { 270 case OPT_REQ_FILE_PATH_NUM: 271 env.req_path = optarg; 272 break; 273 274 case OPT_RSP_FILE_PATH_NUM: 275 env.rsp_path = optarg; 276 break; 277 278 case OPT_FOLDER_NUM: 279 env.is_path_folder = 1; 280 break; 281 282 case OPT_CRYPTODEV_NUM: 283 ret = parse_cryptodev_arg(optarg); 284 if (ret < 0) { 285 cryptodev_fips_validate_usage(prgname); 286 return -EINVAL; 287 } 288 break; 289 290 case OPT_CRYPTODEV_ID_NUM: 291 ret = parse_cryptodev_id_arg(optarg); 292 if (ret < 0) { 293 cryptodev_fips_validate_usage(prgname); 294 return -EINVAL; 295 } 296 break; 297 298 case OPT_CRYPTODEV_ST_NUM: 299 env.self_test = 1; 300 break; 301 302 case OPT_CRYPTODEV_BK_ID_NUM: 303 if (!env.broken_test_config) { 304 env.broken_test_config = rte_malloc( 305 NULL, 306 sizeof(*env.broken_test_config), 307 0); 308 if (!env.broken_test_config) 309 return -ENOMEM; 310 311 env.broken_test_config->expect_fail_dir = 312 self_test_dir_enc_auth_gen; 313 } 314 315 if (parser_read_uint32( 316 &env.broken_test_config->expect_fail_test_idx, 317 optarg) < 0) { 318 rte_free(env.broken_test_config); 319 cryptodev_fips_validate_usage(prgname); 320 return -EINVAL; 321 } 322 break; 323 324 case OPT_CRYPTODEV_BK_DIR_KEY_NUM: 325 if (!env.broken_test_config) { 326 env.broken_test_config = rte_malloc( 327 NULL, 328 sizeof(*env.broken_test_config), 329 0); 330 if (!env.broken_test_config) 331 return -ENOMEM; 332 333 env.broken_test_config->expect_fail_test_idx = 334 0; 335 } 336 337 if (strcmp(optarg, "enc") == 0) 338 env.broken_test_config->expect_fail_dir = 339 self_test_dir_enc_auth_gen; 340 else if (strcmp(optarg, "dec") 341 == 0) 342 env.broken_test_config->expect_fail_dir = 343 self_test_dir_dec_auth_verify; 344 else { 345 rte_free(env.broken_test_config); 346 cryptodev_fips_validate_usage(prgname); 347 return -EINVAL; 348 } 349 break; 350 351 352 case OPT_MBUF_DATAROOM_NUM: 353 if (parser_read_uint16(&env.mbuf_data_room, 354 optarg) < 0) { 355 cryptodev_fips_validate_usage(prgname); 356 return -EINVAL; 357 } 358 359 if (env.mbuf_data_room == 0) { 360 cryptodev_fips_validate_usage(prgname); 361 return -EINVAL; 362 } 363 break; 364 365 default: 366 cryptodev_fips_validate_usage(prgname); 367 return -EINVAL; 368 } 369 } 370 371 if ((env.req_path == NULL && env.rsp_path != NULL) || 372 (env.req_path != NULL && env.rsp_path == NULL)) { 373 RTE_LOG(ERR, USER1, "Missing req path or rsp path\n"); 374 cryptodev_fips_validate_usage(prgname); 375 return -EINVAL; 376 } 377 378 if (env.req_path == NULL && env.self_test == 0) { 379 RTE_LOG(ERR, USER1, "--self-test must be set if req path is missing\n"); 380 cryptodev_fips_validate_usage(prgname); 381 return -EINVAL; 382 } 383 384 return 0; 385 } 386 387 int 388 main(int argc, char *argv[]) 389 { 390 int ret; 391 392 ret = rte_eal_init(argc, argv); 393 if (ret < 0) { 394 RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); 395 return -1; 396 } 397 398 argc -= ret; 399 argv += ret; 400 401 ret = cryptodev_fips_validate_parse_args(argc, argv); 402 if (ret < 0) 403 rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n"); 404 405 ret = cryptodev_fips_validate_app_int(); 406 if (ret < 0) { 407 RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); 408 return -1; 409 } 410 411 if (env.req_path == NULL || env.rsp_path == NULL) { 412 printf("No request, exit.\n"); 413 goto exit; 414 } 415 416 if (!env.is_path_folder) { 417 printf("Processing file %s... ", env.req_path); 418 419 ret = fips_test_init(env.req_path, env.rsp_path, 420 rte_cryptodev_name_get(env.dev_id)); 421 if (ret < 0) { 422 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 423 ret, env.req_path); 424 goto exit; 425 } 426 427 428 ret = fips_test_one_file(); 429 if (ret < 0) { 430 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 431 ret, env.req_path); 432 goto exit; 433 } 434 435 printf("Done\n"); 436 437 } else { 438 struct dirent *dir; 439 DIR *d_req, *d_rsp; 440 char req_path[1024]; 441 char rsp_path[1024]; 442 443 d_req = opendir(env.req_path); 444 if (!d_req) { 445 RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n", 446 -EINVAL, env.req_path); 447 goto exit; 448 } 449 450 d_rsp = opendir(env.rsp_path); 451 if (!d_rsp) { 452 ret = mkdir(env.rsp_path, 0700); 453 if (ret == 0) 454 d_rsp = opendir(env.rsp_path); 455 else { 456 RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n", 457 -EINVAL, env.rsp_path); 458 goto exit; 459 } 460 } 461 closedir(d_rsp); 462 463 while ((dir = readdir(d_req)) != NULL) { 464 if (strstr(dir->d_name, "req") == NULL) 465 continue; 466 467 snprintf(req_path, 1023, "%s/%s", env.req_path, 468 dir->d_name); 469 snprintf(rsp_path, 1023, "%s/%s", env.rsp_path, 470 dir->d_name); 471 strlcpy(strstr(rsp_path, "req"), "rsp", 4); 472 473 printf("Processing file %s... ", req_path); 474 475 ret = fips_test_init(req_path, rsp_path, 476 rte_cryptodev_name_get(env.dev_id)); 477 if (ret < 0) { 478 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 479 ret, req_path); 480 break; 481 } 482 483 ret = fips_test_one_file(); 484 if (ret < 0) { 485 RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 486 ret, req_path); 487 break; 488 } 489 490 printf("Done\n"); 491 } 492 493 closedir(d_req); 494 } 495 496 497 exit: 498 fips_test_clear(); 499 cryptodev_fips_validate_app_uninit(); 500 501 /* clean up the EAL */ 502 rte_eal_cleanup(); 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 for (i = 0; i < SHA_MD_BLOCK; i++) 1636 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 1637 1638 rte_free(vec.pt.val); 1639 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); 1640 1641 fips_test_write_one_case(); 1642 fprintf(info.fp_wr, "\n"); 1643 1644 for (j = 0; j < SHA_EXTERN_ITER; j++) { 1645 1646 memcpy(md[0].val, vec.cipher_auth.digest.val, 1647 vec.cipher_auth.digest.len); 1648 md[0].len = vec.cipher_auth.digest.len; 1649 memcpy(md[1].val, vec.cipher_auth.digest.val, 1650 vec.cipher_auth.digest.len); 1651 md[1].len = vec.cipher_auth.digest.len; 1652 memcpy(md[2].val, vec.cipher_auth.digest.val, 1653 vec.cipher_auth.digest.len); 1654 md[2].len = vec.cipher_auth.digest.len; 1655 1656 for (i = 0; i < (SHA_INTERN_ITER); i++) { 1657 1658 memcpy(vec.pt.val, md[0].val, 1659 (size_t)md[0].len); 1660 memcpy((vec.pt.val + md[0].len), md[1].val, 1661 (size_t)md[1].len); 1662 memcpy((vec.pt.val + md[0].len + md[1].len), 1663 md[2].val, 1664 (size_t)md[2].len); 1665 vec.pt.len = md[0].len + md[1].len + md[2].len; 1666 1667 ret = fips_run_test(); 1668 if (ret < 0) { 1669 if (ret == -EPERM || ret == -ENOTSUP) { 1670 fprintf(info.fp_wr, "Bypass\n\n"); 1671 return 0; 1672 } 1673 return ret; 1674 } 1675 1676 ret = get_writeback_data(&val); 1677 if (ret < 0) 1678 return ret; 1679 1680 memcpy(md[0].val, md[1].val, md[1].len); 1681 md[0].len = md[1].len; 1682 memcpy(md[1].val, md[2].val, md[2].len); 1683 md[1].len = md[2].len; 1684 1685 memcpy(md[2].val, (val.val + vec.pt.len), 1686 vec.cipher_auth.digest.len); 1687 md[2].len = vec.cipher_auth.digest.len; 1688 } 1689 1690 memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len); 1691 vec.cipher_auth.digest.len = md[2].len; 1692 1693 fprintf(info.fp_wr, "COUNT = %u\n", j); 1694 1695 writeback_hex_str("", temp, &vec.cipher_auth.digest); 1696 1697 fprintf(info.fp_wr, "MD = %s\n\n", temp); 1698 } 1699 1700 for (i = 0; i < (SHA_MD_BLOCK); i++) 1701 rte_free(md[i].val); 1702 1703 rte_free(vec.pt.val); 1704 1705 if (val.val) 1706 free(val.val); 1707 1708 return 0; 1709 } 1710 1711 1712 static int 1713 init_test_ops(void) 1714 { 1715 switch (info.algo) { 1716 case FIPS_TEST_ALGO_AES: 1717 test_ops.prepare_op = prepare_cipher_op; 1718 test_ops.prepare_xform = prepare_aes_xform; 1719 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 1720 test_ops.test = fips_mct_aes_test; 1721 else 1722 test_ops.test = fips_generic_test; 1723 break; 1724 case FIPS_TEST_ALGO_HMAC: 1725 test_ops.prepare_op = prepare_auth_op; 1726 test_ops.prepare_xform = prepare_hmac_xform; 1727 test_ops.test = fips_generic_test; 1728 break; 1729 case FIPS_TEST_ALGO_TDES: 1730 test_ops.prepare_op = prepare_cipher_op; 1731 test_ops.prepare_xform = prepare_tdes_xform; 1732 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1733 test_ops.test = fips_mct_tdes_test; 1734 else 1735 test_ops.test = fips_generic_test; 1736 break; 1737 case FIPS_TEST_ALGO_AES_GCM: 1738 test_ops.prepare_op = prepare_aead_op; 1739 test_ops.prepare_xform = prepare_gcm_xform; 1740 test_ops.test = fips_generic_test; 1741 break; 1742 case FIPS_TEST_ALGO_AES_CMAC: 1743 test_ops.prepare_op = prepare_auth_op; 1744 test_ops.prepare_xform = prepare_cmac_xform; 1745 test_ops.test = fips_generic_test; 1746 break; 1747 case FIPS_TEST_ALGO_AES_CCM: 1748 test_ops.prepare_op = prepare_aead_op; 1749 test_ops.prepare_xform = prepare_ccm_xform; 1750 test_ops.test = fips_generic_test; 1751 break; 1752 case FIPS_TEST_ALGO_SHA: 1753 test_ops.prepare_op = prepare_auth_op; 1754 test_ops.prepare_xform = prepare_sha_xform; 1755 if (info.interim_info.sha_data.test_type == SHA_MCT) 1756 test_ops.test = fips_mct_sha_test; 1757 else 1758 test_ops.test = fips_generic_test; 1759 break; 1760 case FIPS_TEST_ALGO_AES_XTS: 1761 test_ops.prepare_op = prepare_cipher_op; 1762 test_ops.prepare_xform = prepare_xts_xform; 1763 test_ops.test = fips_generic_test; 1764 break; 1765 default: 1766 if (strstr(info.file_name, "TECB") || 1767 strstr(info.file_name, "TCBC")) { 1768 info.algo = FIPS_TEST_ALGO_TDES; 1769 test_ops.prepare_op = prepare_cipher_op; 1770 test_ops.prepare_xform = prepare_tdes_xform; 1771 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1772 test_ops.test = fips_mct_tdes_test; 1773 else 1774 test_ops.test = fips_generic_test; 1775 break; 1776 } 1777 return -1; 1778 } 1779 1780 return 0; 1781 } 1782 1783 static void 1784 print_test_block(void) 1785 { 1786 uint32_t i; 1787 1788 for (i = 0; i < info.nb_vec_lines; i++) 1789 printf("%s\n", info.vec[i]); 1790 1791 printf("\n"); 1792 } 1793 1794 static int 1795 fips_test_one_file(void) 1796 { 1797 int fetch_ret = 0, ret; 1798 1799 ret = init_test_ops(); 1800 if (ret < 0) { 1801 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 1802 return ret; 1803 } 1804 1805 while (ret >= 0 && fetch_ret == 0) { 1806 fetch_ret = fips_test_fetch_one_block(); 1807 if (fetch_ret < 0) { 1808 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 1809 fetch_ret); 1810 ret = fetch_ret; 1811 goto error_one_case; 1812 } 1813 1814 if (info.nb_vec_lines == 0) { 1815 if (fetch_ret == -EOF) 1816 break; 1817 1818 fprintf(info.fp_wr, "\n"); 1819 continue; 1820 } 1821 1822 ret = fips_test_parse_one_case(); 1823 switch (ret) { 1824 case 0: 1825 ret = test_ops.test(); 1826 if (ret == 0) 1827 break; 1828 RTE_LOG(ERR, USER1, "Error %i: test block\n", 1829 ret); 1830 goto error_one_case; 1831 case 1: 1832 break; 1833 default: 1834 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 1835 ret); 1836 goto error_one_case; 1837 } 1838 1839 continue; 1840 error_one_case: 1841 print_test_block(); 1842 } 1843 1844 fips_test_clear(); 1845 1846 if (env.digest) { 1847 rte_free(env.digest); 1848 env.digest = NULL; 1849 } 1850 if (env.mbuf) 1851 rte_pktmbuf_free(env.mbuf); 1852 1853 return ret; 1854 } 1855