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, 0) != 0) { 931 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 932 info.device_name, auth_xform->key.length, 933 auth_xform->digest_length); 934 return -EPERM; 935 } 936 937 return 0; 938 } 939 940 static int 941 prepare_cmac_xform(struct rte_crypto_sym_xform *xform) 942 { 943 const struct rte_cryptodev_symmetric_capability *cap; 944 struct rte_cryptodev_sym_capability_idx cap_idx; 945 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 946 947 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 948 949 auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC; 950 auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 951 RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY; 952 auth_xform->digest_length = vec.cipher_auth.digest.len; 953 auth_xform->key.data = vec.cipher_auth.key.val; 954 auth_xform->key.length = vec.cipher_auth.key.len; 955 956 cap_idx.algo.auth = auth_xform->algo; 957 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 958 959 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 960 if (!cap) { 961 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 962 env.dev_id); 963 return -EINVAL; 964 } 965 966 if (rte_cryptodev_sym_capability_check_auth(cap, 967 auth_xform->key.length, 968 auth_xform->digest_length, 0) != 0) { 969 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 970 info.device_name, auth_xform->key.length, 971 auth_xform->digest_length); 972 return -EPERM; 973 } 974 975 return 0; 976 } 977 978 static int 979 prepare_ccm_xform(struct rte_crypto_sym_xform *xform) 980 { 981 const struct rte_cryptodev_symmetric_capability *cap; 982 struct rte_cryptodev_sym_capability_idx cap_idx; 983 struct rte_crypto_aead_xform *aead_xform = &xform->aead; 984 985 xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 986 987 aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM; 988 aead_xform->aad_length = vec.aead.aad.len; 989 aead_xform->digest_length = vec.aead.digest.len; 990 aead_xform->iv.offset = IV_OFF; 991 aead_xform->iv.length = vec.iv.len; 992 aead_xform->key.data = vec.aead.key.val; 993 aead_xform->key.length = vec.aead.key.len; 994 aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 995 RTE_CRYPTO_AEAD_OP_ENCRYPT : 996 RTE_CRYPTO_AEAD_OP_DECRYPT; 997 998 cap_idx.algo.aead = aead_xform->algo; 999 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 1000 1001 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1002 if (!cap) { 1003 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1004 env.dev_id); 1005 return -EINVAL; 1006 } 1007 1008 if (rte_cryptodev_sym_capability_check_aead(cap, 1009 aead_xform->key.length, 1010 aead_xform->digest_length, aead_xform->aad_length, 1011 aead_xform->iv.length) != 0) { 1012 RTE_LOG(ERR, USER1, 1013 "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 1014 info.device_name, aead_xform->key.length, 1015 aead_xform->digest_length, 1016 aead_xform->aad_length, 1017 aead_xform->iv.length); 1018 return -EPERM; 1019 } 1020 1021 return 0; 1022 } 1023 1024 static int 1025 prepare_sha_xform(struct rte_crypto_sym_xform *xform) 1026 { 1027 const struct rte_cryptodev_symmetric_capability *cap; 1028 struct rte_cryptodev_sym_capability_idx cap_idx; 1029 struct rte_crypto_auth_xform *auth_xform = &xform->auth; 1030 1031 xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1032 1033 auth_xform->algo = info.interim_info.sha_data.algo; 1034 auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 1035 auth_xform->digest_length = vec.cipher_auth.digest.len; 1036 1037 cap_idx.algo.auth = auth_xform->algo; 1038 cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 1039 1040 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1041 if (!cap) { 1042 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1043 env.dev_id); 1044 return -EINVAL; 1045 } 1046 1047 if (rte_cryptodev_sym_capability_check_auth(cap, 1048 auth_xform->key.length, 1049 auth_xform->digest_length, 0) != 0) { 1050 RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n", 1051 info.device_name, auth_xform->key.length, 1052 auth_xform->digest_length); 1053 return -EPERM; 1054 } 1055 1056 return 0; 1057 } 1058 1059 static int 1060 prepare_xts_xform(struct rte_crypto_sym_xform *xform) 1061 { 1062 const struct rte_cryptodev_symmetric_capability *cap; 1063 struct rte_cryptodev_sym_capability_idx cap_idx; 1064 struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 1065 1066 xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1067 1068 cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS; 1069 cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 1070 RTE_CRYPTO_CIPHER_OP_ENCRYPT : 1071 RTE_CRYPTO_CIPHER_OP_DECRYPT; 1072 cipher_xform->key.data = vec.cipher_auth.key.val; 1073 cipher_xform->key.length = vec.cipher_auth.key.len; 1074 cipher_xform->iv.length = vec.iv.len; 1075 cipher_xform->iv.offset = IV_OFF; 1076 1077 cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS; 1078 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1079 1080 cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 1081 if (!cap) { 1082 RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 1083 env.dev_id); 1084 return -EINVAL; 1085 } 1086 1087 if (rte_cryptodev_sym_capability_check_cipher(cap, 1088 cipher_xform->key.length, 1089 cipher_xform->iv.length) != 0) { 1090 RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 1091 info.device_name, cipher_xform->key.length, 1092 cipher_xform->iv.length); 1093 return -EPERM; 1094 } 1095 1096 return 0; 1097 } 1098 1099 static int 1100 get_writeback_data(struct fips_val *val) 1101 { 1102 struct rte_mbuf *m = env.mbuf; 1103 uint16_t data_len = rte_pktmbuf_pkt_len(m); 1104 uint16_t total_len = data_len + env.digest_len; 1105 uint8_t *src, *dst, *wb_data; 1106 1107 /* in case val is reused for MCT test, try to free the buffer first */ 1108 if (val->val) { 1109 free(val->val); 1110 val->val = NULL; 1111 } 1112 1113 wb_data = dst = calloc(1, total_len); 1114 if (!dst) { 1115 RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM); 1116 return -ENOMEM; 1117 } 1118 1119 while (m && data_len) { 1120 uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len); 1121 1122 src = rte_pktmbuf_mtod(m, uint8_t *); 1123 memcpy(dst, src, seg_len); 1124 m = m->next; 1125 data_len -= seg_len; 1126 dst += seg_len; 1127 } 1128 1129 if (data_len) { 1130 RTE_LOG(ERR, USER1, "Error -1: write back data\n"); 1131 return -1; 1132 } 1133 1134 if (env.digest) 1135 memcpy(dst, env.digest, env.digest_len); 1136 1137 val->val = wb_data; 1138 val->len = total_len; 1139 1140 return 0; 1141 } 1142 1143 static int 1144 fips_run_test(void) 1145 { 1146 struct rte_crypto_sym_xform xform = {0}; 1147 uint16_t n_deqd; 1148 int ret; 1149 1150 ret = test_ops.prepare_xform(&xform); 1151 if (ret < 0) 1152 return ret; 1153 1154 env.sess = rte_cryptodev_sym_session_create(env.sess_mpool); 1155 if (!env.sess) 1156 return -ENOMEM; 1157 1158 ret = rte_cryptodev_sym_session_init(env.dev_id, 1159 env.sess, &xform, env.sess_priv_mpool); 1160 if (ret < 0) { 1161 RTE_LOG(ERR, USER1, "Error %i: Init session\n", 1162 ret); 1163 goto exit; 1164 } 1165 1166 ret = test_ops.prepare_op(); 1167 if (ret < 0) { 1168 RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", 1169 ret); 1170 goto exit; 1171 } 1172 1173 if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 1174 RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 1175 ret = -1; 1176 goto exit; 1177 } 1178 1179 do { 1180 struct rte_crypto_op *deqd_op; 1181 1182 n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1183 1); 1184 } while (n_deqd == 0); 1185 1186 vec.status = env.op->status; 1187 1188 exit: 1189 rte_cryptodev_sym_session_clear(env.dev_id, env.sess); 1190 rte_cryptodev_sym_session_free(env.sess); 1191 env.sess = NULL; 1192 1193 return ret; 1194 } 1195 1196 static int 1197 fips_generic_test(void) 1198 { 1199 struct fips_val val = {NULL, 0}; 1200 int ret; 1201 1202 fips_test_write_one_case(); 1203 1204 ret = fips_run_test(); 1205 if (ret < 0) { 1206 if (ret == -EPERM || ret == -ENOTSUP) { 1207 fprintf(info.fp_wr, "Bypass\n\n"); 1208 return 0; 1209 } 1210 1211 return ret; 1212 } 1213 1214 ret = get_writeback_data(&val); 1215 if (ret < 0) 1216 return ret; 1217 1218 switch (info.file_type) { 1219 case FIPS_TYPE_REQ: 1220 case FIPS_TYPE_RSP: 1221 if (info.parse_writeback == NULL) 1222 return -EPERM; 1223 ret = info.parse_writeback(&val); 1224 if (ret < 0) 1225 return ret; 1226 break; 1227 case FIPS_TYPE_FAX: 1228 if (info.kat_check == NULL) 1229 return -EPERM; 1230 ret = info.kat_check(&val); 1231 if (ret < 0) 1232 return ret; 1233 break; 1234 } 1235 1236 fprintf(info.fp_wr, "\n"); 1237 free(val.val); 1238 1239 return 0; 1240 } 1241 1242 static int 1243 fips_mct_tdes_test(void) 1244 { 1245 #define TDES_BLOCK_SIZE 8 1246 #define TDES_EXTERN_ITER 400 1247 #define TDES_INTERN_ITER 10000 1248 struct fips_val val = {NULL, 0}, val_key; 1249 uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; 1250 uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; 1251 uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; 1252 uint32_t i, j, k; 1253 int ret; 1254 int test_mode = info.interim_info.tdes_data.test_mode; 1255 1256 for (i = 0; i < TDES_EXTERN_ITER; i++) { 1257 if ((i == 0) && (info.version == 21.4f)) { 1258 if (!(strstr(info.vec[0], "COUNT"))) 1259 fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0); 1260 } 1261 1262 if (i != 0) 1263 update_info_vec(i); 1264 1265 fips_test_write_one_case(); 1266 1267 for (j = 0; j < TDES_INTERN_ITER; j++) { 1268 ret = fips_run_test(); 1269 if (ret < 0) { 1270 if (ret == -EPERM) { 1271 fprintf(info.fp_wr, "Bypass\n"); 1272 return 0; 1273 } 1274 return ret; 1275 } 1276 1277 ret = get_writeback_data(&val); 1278 if (ret < 0) 1279 return ret; 1280 1281 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1282 memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 1283 1284 if (j == 0) { 1285 memcpy(prev_out, val.val, TDES_BLOCK_SIZE); 1286 1287 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1288 if (test_mode == TDES_MODE_ECB) { 1289 memcpy(vec.pt.val, val.val, 1290 TDES_BLOCK_SIZE); 1291 } else { 1292 memcpy(vec.pt.val, vec.iv.val, 1293 TDES_BLOCK_SIZE); 1294 memcpy(vec.iv.val, val.val, 1295 TDES_BLOCK_SIZE); 1296 } 1297 1298 } else { 1299 if (test_mode == TDES_MODE_ECB) { 1300 memcpy(vec.ct.val, val.val, 1301 TDES_BLOCK_SIZE); 1302 } else { 1303 memcpy(vec.iv.val, vec.ct.val, 1304 TDES_BLOCK_SIZE); 1305 memcpy(vec.ct.val, val.val, 1306 TDES_BLOCK_SIZE); 1307 } 1308 } 1309 continue; 1310 } 1311 1312 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1313 if (test_mode == TDES_MODE_ECB) { 1314 memcpy(vec.pt.val, val.val, 1315 TDES_BLOCK_SIZE); 1316 } else { 1317 memcpy(vec.iv.val, val.val, 1318 TDES_BLOCK_SIZE); 1319 memcpy(vec.pt.val, prev_out, 1320 TDES_BLOCK_SIZE); 1321 } 1322 } else { 1323 if (test_mode == TDES_MODE_ECB) { 1324 memcpy(vec.ct.val, val.val, 1325 TDES_BLOCK_SIZE); 1326 } else { 1327 memcpy(vec.iv.val, vec.ct.val, 1328 TDES_BLOCK_SIZE); 1329 memcpy(vec.ct.val, val.val, 1330 TDES_BLOCK_SIZE); 1331 } 1332 } 1333 1334 if (j == TDES_INTERN_ITER - 1) 1335 continue; 1336 1337 memcpy(prev_out, val.val, TDES_BLOCK_SIZE); 1338 1339 if (j == TDES_INTERN_ITER - 3) 1340 memcpy(prev_prev_out, val.val, TDES_BLOCK_SIZE); 1341 } 1342 1343 info.parse_writeback(&val); 1344 fprintf(info.fp_wr, "\n"); 1345 1346 if (i == TDES_EXTERN_ITER - 1) 1347 continue; 1348 1349 /** update key */ 1350 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1351 1352 if (info.interim_info.tdes_data.nb_keys == 0) { 1353 if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 1354 info.interim_info.tdes_data.nb_keys = 1; 1355 else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 1356 info.interim_info.tdes_data.nb_keys = 2; 1357 else 1358 info.interim_info.tdes_data.nb_keys = 3; 1359 1360 } 1361 1362 for (k = 0; k < TDES_BLOCK_SIZE; k++) { 1363 1364 switch (info.interim_info.tdes_data.nb_keys) { 1365 case 3: 1366 val_key.val[k] ^= val.val[k]; 1367 val_key.val[k + 8] ^= prev_out[k]; 1368 val_key.val[k + 16] ^= prev_prev_out[k]; 1369 break; 1370 case 2: 1371 val_key.val[k] ^= val.val[k]; 1372 val_key.val[k + 8] ^= prev_out[k]; 1373 val_key.val[k + 16] ^= val.val[k]; 1374 break; 1375 default: /* case 1 */ 1376 val_key.val[k] ^= val.val[k]; 1377 val_key.val[k + 8] ^= val.val[k]; 1378 val_key.val[k + 16] ^= val.val[k]; 1379 break; 1380 } 1381 1382 } 1383 1384 for (k = 0; k < 24; k++) 1385 val_key.val[k] = (__builtin_popcount(val_key.val[k]) & 1386 0x1) ? 1387 val_key.val[k] : (val_key.val[k] ^ 0x1); 1388 1389 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1390 if (test_mode == TDES_MODE_ECB) { 1391 memcpy(vec.pt.val, val.val, TDES_BLOCK_SIZE); 1392 } else { 1393 memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE); 1394 memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 1395 } 1396 } else { 1397 if (test_mode == TDES_MODE_ECB) { 1398 memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); 1399 } else { 1400 memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 1401 memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); 1402 } 1403 } 1404 } 1405 1406 if (val.val) 1407 free(val.val); 1408 1409 return 0; 1410 } 1411 1412 static int 1413 fips_mct_aes_ecb_test(void) 1414 { 1415 #define AES_BLOCK_SIZE 16 1416 #define AES_EXTERN_ITER 100 1417 #define AES_INTERN_ITER 1000 1418 struct fips_val val = {NULL, 0}, val_key; 1419 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1420 uint32_t i, j, k; 1421 int ret; 1422 1423 for (i = 0; i < AES_EXTERN_ITER; i++) { 1424 if (i != 0) 1425 update_info_vec(i); 1426 1427 fips_test_write_one_case(); 1428 1429 for (j = 0; j < AES_INTERN_ITER; j++) { 1430 ret = fips_run_test(); 1431 if (ret < 0) { 1432 if (ret == -EPERM) { 1433 fprintf(info.fp_wr, "Bypass\n"); 1434 return 0; 1435 } 1436 1437 return ret; 1438 } 1439 1440 ret = get_writeback_data(&val); 1441 if (ret < 0) 1442 return ret; 1443 1444 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 1445 memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); 1446 else 1447 memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); 1448 1449 if (j == AES_INTERN_ITER - 1) 1450 continue; 1451 1452 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1453 } 1454 1455 info.parse_writeback(&val); 1456 fprintf(info.fp_wr, "\n"); 1457 1458 if (i == AES_EXTERN_ITER - 1) 1459 continue; 1460 1461 /** update key */ 1462 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1463 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1464 switch (vec.cipher_auth.key.len) { 1465 case 16: 1466 val_key.val[k] ^= val.val[k]; 1467 break; 1468 case 24: 1469 if (k < 8) 1470 val_key.val[k] ^= prev_out[k + 8]; 1471 else 1472 val_key.val[k] ^= val.val[k - 8]; 1473 break; 1474 case 32: 1475 if (k < 16) 1476 val_key.val[k] ^= prev_out[k]; 1477 else 1478 val_key.val[k] ^= val.val[k - 16]; 1479 break; 1480 default: 1481 return -1; 1482 } 1483 } 1484 } 1485 1486 if (val.val) 1487 free(val.val); 1488 1489 return 0; 1490 } 1491 static int 1492 fips_mct_aes_test(void) 1493 { 1494 #define AES_BLOCK_SIZE 16 1495 #define AES_EXTERN_ITER 100 1496 #define AES_INTERN_ITER 1000 1497 struct fips_val val = {NULL, 0}, val_key; 1498 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1499 uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 1500 uint32_t i, j, k; 1501 int ret; 1502 1503 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) 1504 return fips_mct_aes_ecb_test(); 1505 1506 for (i = 0; i < AES_EXTERN_ITER; i++) { 1507 if (i != 0) 1508 update_info_vec(i); 1509 1510 fips_test_write_one_case(); 1511 1512 for (j = 0; j < AES_INTERN_ITER; j++) { 1513 ret = fips_run_test(); 1514 if (ret < 0) { 1515 if (ret == -EPERM) { 1516 fprintf(info.fp_wr, "Bypass\n"); 1517 return 0; 1518 } 1519 1520 return ret; 1521 } 1522 1523 get_writeback_data(&val); 1524 1525 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1526 memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 1527 1528 if (j == 0) { 1529 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1530 1531 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1532 memcpy(vec.pt.val, vec.iv.val, 1533 AES_BLOCK_SIZE); 1534 memcpy(vec.iv.val, val.val, 1535 AES_BLOCK_SIZE); 1536 } else { 1537 memcpy(vec.ct.val, vec.iv.val, 1538 AES_BLOCK_SIZE); 1539 memcpy(vec.iv.val, prev_in, 1540 AES_BLOCK_SIZE); 1541 } 1542 continue; 1543 } 1544 1545 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1546 memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); 1547 memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 1548 } else { 1549 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1550 memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 1551 } 1552 1553 if (j == AES_INTERN_ITER - 1) 1554 continue; 1555 1556 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1557 } 1558 1559 info.parse_writeback(&val); 1560 fprintf(info.fp_wr, "\n"); 1561 1562 if (i == AES_EXTERN_ITER - 1) 1563 continue; 1564 1565 /** update key */ 1566 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1567 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1568 switch (vec.cipher_auth.key.len) { 1569 case 16: 1570 val_key.val[k] ^= val.val[k]; 1571 break; 1572 case 24: 1573 if (k < 8) 1574 val_key.val[k] ^= prev_out[k + 8]; 1575 else 1576 val_key.val[k] ^= val.val[k - 8]; 1577 break; 1578 case 32: 1579 if (k < 16) 1580 val_key.val[k] ^= prev_out[k]; 1581 else 1582 val_key.val[k] ^= val.val[k - 16]; 1583 break; 1584 default: 1585 return -1; 1586 } 1587 } 1588 1589 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1590 memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); 1591 } 1592 1593 if (val.val) 1594 free(val.val); 1595 1596 return 0; 1597 } 1598 1599 static int 1600 fips_mct_sha_test(void) 1601 { 1602 #define SHA_EXTERN_ITER 100 1603 #define SHA_INTERN_ITER 1000 1604 #define SHA_MD_BLOCK 3 1605 struct fips_val val = {NULL, 0}, md[SHA_MD_BLOCK]; 1606 char temp[MAX_DIGEST_SIZE*2]; 1607 int ret; 1608 uint32_t i, j; 1609 1610 val.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); 1611 for (i = 0; i < SHA_MD_BLOCK; i++) 1612 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 1613 1614 rte_free(vec.pt.val); 1615 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); 1616 1617 fips_test_write_one_case(); 1618 fprintf(info.fp_wr, "\n"); 1619 1620 for (j = 0; j < SHA_EXTERN_ITER; j++) { 1621 1622 memcpy(md[0].val, vec.cipher_auth.digest.val, 1623 vec.cipher_auth.digest.len); 1624 md[0].len = vec.cipher_auth.digest.len; 1625 memcpy(md[1].val, vec.cipher_auth.digest.val, 1626 vec.cipher_auth.digest.len); 1627 md[1].len = vec.cipher_auth.digest.len; 1628 memcpy(md[2].val, vec.cipher_auth.digest.val, 1629 vec.cipher_auth.digest.len); 1630 md[2].len = vec.cipher_auth.digest.len; 1631 1632 for (i = 0; i < (SHA_INTERN_ITER); i++) { 1633 1634 memcpy(vec.pt.val, md[0].val, 1635 (size_t)md[0].len); 1636 memcpy((vec.pt.val + md[0].len), md[1].val, 1637 (size_t)md[1].len); 1638 memcpy((vec.pt.val + md[0].len + md[1].len), 1639 md[2].val, 1640 (size_t)md[2].len); 1641 vec.pt.len = md[0].len + md[1].len + md[2].len; 1642 1643 ret = fips_run_test(); 1644 if (ret < 0) { 1645 if (ret == -EPERM || ret == -ENOTSUP) { 1646 fprintf(info.fp_wr, "Bypass\n\n"); 1647 return 0; 1648 } 1649 return ret; 1650 } 1651 1652 get_writeback_data(&val); 1653 1654 memcpy(md[0].val, md[1].val, md[1].len); 1655 md[0].len = md[1].len; 1656 memcpy(md[1].val, md[2].val, md[2].len); 1657 md[1].len = md[2].len; 1658 1659 memcpy(md[2].val, (val.val + vec.pt.len), 1660 vec.cipher_auth.digest.len); 1661 md[2].len = vec.cipher_auth.digest.len; 1662 } 1663 1664 memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len); 1665 vec.cipher_auth.digest.len = md[2].len; 1666 1667 fprintf(info.fp_wr, "COUNT = %u\n", j); 1668 1669 writeback_hex_str("", temp, &vec.cipher_auth.digest); 1670 1671 fprintf(info.fp_wr, "MD = %s\n\n", temp); 1672 } 1673 1674 for (i = 0; i < (SHA_MD_BLOCK); i++) 1675 rte_free(md[i].val); 1676 1677 rte_free(vec.pt.val); 1678 1679 if (val.val) 1680 free(val.val); 1681 1682 return 0; 1683 } 1684 1685 1686 static int 1687 init_test_ops(void) 1688 { 1689 switch (info.algo) { 1690 case FIPS_TEST_ALGO_AES: 1691 test_ops.prepare_op = prepare_cipher_op; 1692 test_ops.prepare_xform = prepare_aes_xform; 1693 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 1694 test_ops.test = fips_mct_aes_test; 1695 else 1696 test_ops.test = fips_generic_test; 1697 break; 1698 case FIPS_TEST_ALGO_HMAC: 1699 test_ops.prepare_op = prepare_auth_op; 1700 test_ops.prepare_xform = prepare_hmac_xform; 1701 test_ops.test = fips_generic_test; 1702 break; 1703 case FIPS_TEST_ALGO_TDES: 1704 test_ops.prepare_op = prepare_cipher_op; 1705 test_ops.prepare_xform = prepare_tdes_xform; 1706 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1707 test_ops.test = fips_mct_tdes_test; 1708 else 1709 test_ops.test = fips_generic_test; 1710 break; 1711 case FIPS_TEST_ALGO_AES_GCM: 1712 test_ops.prepare_op = prepare_aead_op; 1713 test_ops.prepare_xform = prepare_gcm_xform; 1714 test_ops.test = fips_generic_test; 1715 break; 1716 case FIPS_TEST_ALGO_AES_CMAC: 1717 test_ops.prepare_op = prepare_auth_op; 1718 test_ops.prepare_xform = prepare_cmac_xform; 1719 test_ops.test = fips_generic_test; 1720 break; 1721 case FIPS_TEST_ALGO_AES_CCM: 1722 test_ops.prepare_op = prepare_aead_op; 1723 test_ops.prepare_xform = prepare_ccm_xform; 1724 test_ops.test = fips_generic_test; 1725 break; 1726 case FIPS_TEST_ALGO_SHA: 1727 test_ops.prepare_op = prepare_auth_op; 1728 test_ops.prepare_xform = prepare_sha_xform; 1729 if (info.interim_info.sha_data.test_type == SHA_MCT) 1730 test_ops.test = fips_mct_sha_test; 1731 else 1732 test_ops.test = fips_generic_test; 1733 break; 1734 case FIPS_TEST_ALGO_AES_XTS: 1735 test_ops.prepare_op = prepare_cipher_op; 1736 test_ops.prepare_xform = prepare_xts_xform; 1737 test_ops.test = fips_generic_test; 1738 break; 1739 default: 1740 if (strstr(info.file_name, "TECB") || 1741 strstr(info.file_name, "TCBC")) { 1742 info.algo = FIPS_TEST_ALGO_TDES; 1743 test_ops.prepare_op = prepare_cipher_op; 1744 test_ops.prepare_xform = prepare_tdes_xform; 1745 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1746 test_ops.test = fips_mct_tdes_test; 1747 else 1748 test_ops.test = fips_generic_test; 1749 break; 1750 } 1751 return -1; 1752 } 1753 1754 return 0; 1755 } 1756 1757 static void 1758 print_test_block(void) 1759 { 1760 uint32_t i; 1761 1762 for (i = 0; i < info.nb_vec_lines; i++) 1763 printf("%s\n", info.vec[i]); 1764 1765 printf("\n"); 1766 } 1767 1768 static int 1769 fips_test_one_file(void) 1770 { 1771 int fetch_ret = 0, ret; 1772 1773 ret = init_test_ops(); 1774 if (ret < 0) { 1775 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 1776 return ret; 1777 } 1778 1779 while (ret >= 0 && fetch_ret == 0) { 1780 fetch_ret = fips_test_fetch_one_block(); 1781 if (fetch_ret < 0) { 1782 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 1783 fetch_ret); 1784 ret = fetch_ret; 1785 goto error_one_case; 1786 } 1787 1788 if (info.nb_vec_lines == 0) { 1789 if (fetch_ret == -EOF) 1790 break; 1791 1792 fprintf(info.fp_wr, "\n"); 1793 continue; 1794 } 1795 1796 ret = fips_test_parse_one_case(); 1797 switch (ret) { 1798 case 0: 1799 ret = test_ops.test(); 1800 if (ret == 0) 1801 break; 1802 RTE_LOG(ERR, USER1, "Error %i: test block\n", 1803 ret); 1804 goto error_one_case; 1805 case 1: 1806 break; 1807 default: 1808 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 1809 ret); 1810 goto error_one_case; 1811 } 1812 1813 continue; 1814 error_one_case: 1815 print_test_block(); 1816 } 1817 1818 fips_test_clear(); 1819 1820 if (env.digest) 1821 rte_free(env.digest); 1822 if (env.mbuf) 1823 rte_pktmbuf_free(env.mbuf); 1824 1825 return ret; 1826 } 1827