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