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 free(wb_data); 1132 return -1; 1133 } 1134 1135 if (env.digest) 1136 memcpy(dst, env.digest, env.digest_len); 1137 1138 val->val = wb_data; 1139 val->len = total_len; 1140 1141 return 0; 1142 } 1143 1144 static int 1145 fips_run_test(void) 1146 { 1147 struct rte_crypto_sym_xform xform = {0}; 1148 uint16_t n_deqd; 1149 int ret; 1150 1151 ret = test_ops.prepare_xform(&xform); 1152 if (ret < 0) 1153 return ret; 1154 1155 env.sess = rte_cryptodev_sym_session_create(env.sess_mpool); 1156 if (!env.sess) 1157 return -ENOMEM; 1158 1159 ret = rte_cryptodev_sym_session_init(env.dev_id, 1160 env.sess, &xform, env.sess_priv_mpool); 1161 if (ret < 0) { 1162 RTE_LOG(ERR, USER1, "Error %i: Init session\n", 1163 ret); 1164 goto exit; 1165 } 1166 1167 ret = test_ops.prepare_op(); 1168 if (ret < 0) { 1169 RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", 1170 ret); 1171 goto exit; 1172 } 1173 1174 if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 1175 RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 1176 ret = -1; 1177 goto exit; 1178 } 1179 1180 do { 1181 struct rte_crypto_op *deqd_op; 1182 1183 n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1184 1); 1185 } while (n_deqd == 0); 1186 1187 vec.status = env.op->status; 1188 1189 exit: 1190 rte_cryptodev_sym_session_clear(env.dev_id, env.sess); 1191 rte_cryptodev_sym_session_free(env.sess); 1192 env.sess = NULL; 1193 1194 return ret; 1195 } 1196 1197 static int 1198 fips_generic_test(void) 1199 { 1200 struct fips_val val = {NULL, 0}; 1201 int ret; 1202 1203 fips_test_write_one_case(); 1204 1205 ret = fips_run_test(); 1206 if (ret < 0) { 1207 if (ret == -EPERM || ret == -ENOTSUP) { 1208 fprintf(info.fp_wr, "Bypass\n\n"); 1209 return 0; 1210 } 1211 1212 return ret; 1213 } 1214 1215 ret = get_writeback_data(&val); 1216 if (ret < 0) 1217 return ret; 1218 1219 switch (info.file_type) { 1220 case FIPS_TYPE_REQ: 1221 case FIPS_TYPE_RSP: 1222 if (info.parse_writeback == NULL) 1223 return -EPERM; 1224 ret = info.parse_writeback(&val); 1225 if (ret < 0) 1226 return ret; 1227 break; 1228 case FIPS_TYPE_FAX: 1229 if (info.kat_check == NULL) 1230 return -EPERM; 1231 ret = info.kat_check(&val); 1232 if (ret < 0) 1233 return ret; 1234 break; 1235 } 1236 1237 fprintf(info.fp_wr, "\n"); 1238 free(val.val); 1239 1240 return 0; 1241 } 1242 1243 static int 1244 fips_mct_tdes_test(void) 1245 { 1246 #define TDES_BLOCK_SIZE 8 1247 #define TDES_EXTERN_ITER 400 1248 #define TDES_INTERN_ITER 10000 1249 struct fips_val val = {NULL, 0}, val_key; 1250 uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; 1251 uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; 1252 uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; 1253 uint32_t i, j, k; 1254 int ret; 1255 int test_mode = info.interim_info.tdes_data.test_mode; 1256 1257 for (i = 0; i < TDES_EXTERN_ITER; i++) { 1258 if ((i == 0) && (info.version == 21.4f)) { 1259 if (!(strstr(info.vec[0], "COUNT"))) 1260 fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0); 1261 } 1262 1263 if (i != 0) 1264 update_info_vec(i); 1265 1266 fips_test_write_one_case(); 1267 1268 for (j = 0; j < TDES_INTERN_ITER; j++) { 1269 ret = fips_run_test(); 1270 if (ret < 0) { 1271 if (ret == -EPERM) { 1272 fprintf(info.fp_wr, "Bypass\n"); 1273 return 0; 1274 } 1275 return ret; 1276 } 1277 1278 ret = get_writeback_data(&val); 1279 if (ret < 0) 1280 return ret; 1281 1282 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1283 memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 1284 1285 if (j == 0) { 1286 memcpy(prev_out, val.val, TDES_BLOCK_SIZE); 1287 1288 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1289 if (test_mode == TDES_MODE_ECB) { 1290 memcpy(vec.pt.val, val.val, 1291 TDES_BLOCK_SIZE); 1292 } else { 1293 memcpy(vec.pt.val, vec.iv.val, 1294 TDES_BLOCK_SIZE); 1295 memcpy(vec.iv.val, val.val, 1296 TDES_BLOCK_SIZE); 1297 } 1298 1299 } else { 1300 if (test_mode == TDES_MODE_ECB) { 1301 memcpy(vec.ct.val, val.val, 1302 TDES_BLOCK_SIZE); 1303 } else { 1304 memcpy(vec.iv.val, vec.ct.val, 1305 TDES_BLOCK_SIZE); 1306 memcpy(vec.ct.val, val.val, 1307 TDES_BLOCK_SIZE); 1308 } 1309 } 1310 continue; 1311 } 1312 1313 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1314 if (test_mode == TDES_MODE_ECB) { 1315 memcpy(vec.pt.val, val.val, 1316 TDES_BLOCK_SIZE); 1317 } else { 1318 memcpy(vec.iv.val, val.val, 1319 TDES_BLOCK_SIZE); 1320 memcpy(vec.pt.val, prev_out, 1321 TDES_BLOCK_SIZE); 1322 } 1323 } else { 1324 if (test_mode == TDES_MODE_ECB) { 1325 memcpy(vec.ct.val, val.val, 1326 TDES_BLOCK_SIZE); 1327 } else { 1328 memcpy(vec.iv.val, vec.ct.val, 1329 TDES_BLOCK_SIZE); 1330 memcpy(vec.ct.val, val.val, 1331 TDES_BLOCK_SIZE); 1332 } 1333 } 1334 1335 if (j == TDES_INTERN_ITER - 1) 1336 continue; 1337 1338 memcpy(prev_out, val.val, TDES_BLOCK_SIZE); 1339 1340 if (j == TDES_INTERN_ITER - 3) 1341 memcpy(prev_prev_out, val.val, TDES_BLOCK_SIZE); 1342 } 1343 1344 info.parse_writeback(&val); 1345 fprintf(info.fp_wr, "\n"); 1346 1347 if (i == TDES_EXTERN_ITER - 1) 1348 continue; 1349 1350 /** update key */ 1351 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1352 1353 if (info.interim_info.tdes_data.nb_keys == 0) { 1354 if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 1355 info.interim_info.tdes_data.nb_keys = 1; 1356 else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 1357 info.interim_info.tdes_data.nb_keys = 2; 1358 else 1359 info.interim_info.tdes_data.nb_keys = 3; 1360 1361 } 1362 1363 for (k = 0; k < TDES_BLOCK_SIZE; k++) { 1364 1365 switch (info.interim_info.tdes_data.nb_keys) { 1366 case 3: 1367 val_key.val[k] ^= val.val[k]; 1368 val_key.val[k + 8] ^= prev_out[k]; 1369 val_key.val[k + 16] ^= prev_prev_out[k]; 1370 break; 1371 case 2: 1372 val_key.val[k] ^= val.val[k]; 1373 val_key.val[k + 8] ^= prev_out[k]; 1374 val_key.val[k + 16] ^= val.val[k]; 1375 break; 1376 default: /* case 1 */ 1377 val_key.val[k] ^= val.val[k]; 1378 val_key.val[k + 8] ^= val.val[k]; 1379 val_key.val[k + 16] ^= val.val[k]; 1380 break; 1381 } 1382 1383 } 1384 1385 for (k = 0; k < 24; k++) 1386 val_key.val[k] = (__builtin_popcount(val_key.val[k]) & 1387 0x1) ? 1388 val_key.val[k] : (val_key.val[k] ^ 0x1); 1389 1390 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1391 if (test_mode == TDES_MODE_ECB) { 1392 memcpy(vec.pt.val, val.val, TDES_BLOCK_SIZE); 1393 } else { 1394 memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE); 1395 memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 1396 } 1397 } else { 1398 if (test_mode == TDES_MODE_ECB) { 1399 memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); 1400 } else { 1401 memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 1402 memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); 1403 } 1404 } 1405 } 1406 1407 if (val.val) 1408 free(val.val); 1409 1410 return 0; 1411 } 1412 1413 static int 1414 fips_mct_aes_ecb_test(void) 1415 { 1416 #define AES_BLOCK_SIZE 16 1417 #define AES_EXTERN_ITER 100 1418 #define AES_INTERN_ITER 1000 1419 struct fips_val val = {NULL, 0}, val_key; 1420 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1421 uint32_t i, j, k; 1422 int ret; 1423 1424 for (i = 0; i < AES_EXTERN_ITER; i++) { 1425 if (i != 0) 1426 update_info_vec(i); 1427 1428 fips_test_write_one_case(); 1429 1430 for (j = 0; j < AES_INTERN_ITER; j++) { 1431 ret = fips_run_test(); 1432 if (ret < 0) { 1433 if (ret == -EPERM) { 1434 fprintf(info.fp_wr, "Bypass\n"); 1435 return 0; 1436 } 1437 1438 return ret; 1439 } 1440 1441 ret = get_writeback_data(&val); 1442 if (ret < 0) 1443 return ret; 1444 1445 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 1446 memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE); 1447 else 1448 memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE); 1449 1450 if (j == AES_INTERN_ITER - 1) 1451 continue; 1452 1453 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1454 } 1455 1456 info.parse_writeback(&val); 1457 fprintf(info.fp_wr, "\n"); 1458 1459 if (i == AES_EXTERN_ITER - 1) 1460 continue; 1461 1462 /** update key */ 1463 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1464 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1465 switch (vec.cipher_auth.key.len) { 1466 case 16: 1467 val_key.val[k] ^= val.val[k]; 1468 break; 1469 case 24: 1470 if (k < 8) 1471 val_key.val[k] ^= prev_out[k + 8]; 1472 else 1473 val_key.val[k] ^= val.val[k - 8]; 1474 break; 1475 case 32: 1476 if (k < 16) 1477 val_key.val[k] ^= prev_out[k]; 1478 else 1479 val_key.val[k] ^= val.val[k - 16]; 1480 break; 1481 default: 1482 return -1; 1483 } 1484 } 1485 } 1486 1487 if (val.val) 1488 free(val.val); 1489 1490 return 0; 1491 } 1492 static int 1493 fips_mct_aes_test(void) 1494 { 1495 #define AES_BLOCK_SIZE 16 1496 #define AES_EXTERN_ITER 100 1497 #define AES_INTERN_ITER 1000 1498 struct fips_val val = {NULL, 0}, val_key; 1499 uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1500 uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 1501 uint32_t i, j, k; 1502 int ret; 1503 1504 if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB) 1505 return fips_mct_aes_ecb_test(); 1506 1507 for (i = 0; i < AES_EXTERN_ITER; i++) { 1508 if (i != 0) 1509 update_info_vec(i); 1510 1511 fips_test_write_one_case(); 1512 1513 for (j = 0; j < AES_INTERN_ITER; j++) { 1514 ret = fips_run_test(); 1515 if (ret < 0) { 1516 if (ret == -EPERM) { 1517 fprintf(info.fp_wr, "Bypass\n"); 1518 return 0; 1519 } 1520 1521 return ret; 1522 } 1523 1524 ret = get_writeback_data(&val); 1525 if (ret < 0) 1526 return ret; 1527 1528 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1529 memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 1530 1531 if (j == 0) { 1532 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1533 1534 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1535 memcpy(vec.pt.val, vec.iv.val, 1536 AES_BLOCK_SIZE); 1537 memcpy(vec.iv.val, val.val, 1538 AES_BLOCK_SIZE); 1539 } else { 1540 memcpy(vec.ct.val, vec.iv.val, 1541 AES_BLOCK_SIZE); 1542 memcpy(vec.iv.val, prev_in, 1543 AES_BLOCK_SIZE); 1544 } 1545 continue; 1546 } 1547 1548 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1549 memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); 1550 memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 1551 } else { 1552 memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1553 memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 1554 } 1555 1556 if (j == AES_INTERN_ITER - 1) 1557 continue; 1558 1559 memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1560 } 1561 1562 info.parse_writeback(&val); 1563 fprintf(info.fp_wr, "\n"); 1564 1565 if (i == AES_EXTERN_ITER - 1) 1566 continue; 1567 1568 /** update key */ 1569 memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1570 for (k = 0; k < vec.cipher_auth.key.len; k++) { 1571 switch (vec.cipher_auth.key.len) { 1572 case 16: 1573 val_key.val[k] ^= val.val[k]; 1574 break; 1575 case 24: 1576 if (k < 8) 1577 val_key.val[k] ^= prev_out[k + 8]; 1578 else 1579 val_key.val[k] ^= val.val[k - 8]; 1580 break; 1581 case 32: 1582 if (k < 16) 1583 val_key.val[k] ^= prev_out[k]; 1584 else 1585 val_key.val[k] ^= val.val[k - 16]; 1586 break; 1587 default: 1588 return -1; 1589 } 1590 } 1591 1592 if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1593 memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); 1594 } 1595 1596 if (val.val) 1597 free(val.val); 1598 1599 return 0; 1600 } 1601 1602 static int 1603 fips_mct_sha_test(void) 1604 { 1605 #define SHA_EXTERN_ITER 100 1606 #define SHA_INTERN_ITER 1000 1607 #define SHA_MD_BLOCK 3 1608 struct fips_val val = {NULL, 0}, md[SHA_MD_BLOCK]; 1609 char temp[MAX_DIGEST_SIZE*2]; 1610 int ret; 1611 uint32_t i, j; 1612 1613 val.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); 1614 for (i = 0; i < SHA_MD_BLOCK; i++) 1615 md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); 1616 1617 rte_free(vec.pt.val); 1618 vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); 1619 1620 fips_test_write_one_case(); 1621 fprintf(info.fp_wr, "\n"); 1622 1623 for (j = 0; j < SHA_EXTERN_ITER; j++) { 1624 1625 memcpy(md[0].val, vec.cipher_auth.digest.val, 1626 vec.cipher_auth.digest.len); 1627 md[0].len = vec.cipher_auth.digest.len; 1628 memcpy(md[1].val, vec.cipher_auth.digest.val, 1629 vec.cipher_auth.digest.len); 1630 md[1].len = vec.cipher_auth.digest.len; 1631 memcpy(md[2].val, vec.cipher_auth.digest.val, 1632 vec.cipher_auth.digest.len); 1633 md[2].len = vec.cipher_auth.digest.len; 1634 1635 for (i = 0; i < (SHA_INTERN_ITER); i++) { 1636 1637 memcpy(vec.pt.val, md[0].val, 1638 (size_t)md[0].len); 1639 memcpy((vec.pt.val + md[0].len), md[1].val, 1640 (size_t)md[1].len); 1641 memcpy((vec.pt.val + md[0].len + md[1].len), 1642 md[2].val, 1643 (size_t)md[2].len); 1644 vec.pt.len = md[0].len + md[1].len + md[2].len; 1645 1646 ret = fips_run_test(); 1647 if (ret < 0) { 1648 if (ret == -EPERM || ret == -ENOTSUP) { 1649 fprintf(info.fp_wr, "Bypass\n\n"); 1650 return 0; 1651 } 1652 return ret; 1653 } 1654 1655 ret = get_writeback_data(&val); 1656 if (ret < 0) 1657 return ret; 1658 1659 memcpy(md[0].val, md[1].val, md[1].len); 1660 md[0].len = md[1].len; 1661 memcpy(md[1].val, md[2].val, md[2].len); 1662 md[1].len = md[2].len; 1663 1664 memcpy(md[2].val, (val.val + vec.pt.len), 1665 vec.cipher_auth.digest.len); 1666 md[2].len = vec.cipher_auth.digest.len; 1667 } 1668 1669 memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len); 1670 vec.cipher_auth.digest.len = md[2].len; 1671 1672 fprintf(info.fp_wr, "COUNT = %u\n", j); 1673 1674 writeback_hex_str("", temp, &vec.cipher_auth.digest); 1675 1676 fprintf(info.fp_wr, "MD = %s\n\n", temp); 1677 } 1678 1679 for (i = 0; i < (SHA_MD_BLOCK); i++) 1680 rte_free(md[i].val); 1681 1682 rte_free(vec.pt.val); 1683 1684 if (val.val) 1685 free(val.val); 1686 1687 return 0; 1688 } 1689 1690 1691 static int 1692 init_test_ops(void) 1693 { 1694 switch (info.algo) { 1695 case FIPS_TEST_ALGO_AES: 1696 test_ops.prepare_op = prepare_cipher_op; 1697 test_ops.prepare_xform = prepare_aes_xform; 1698 if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 1699 test_ops.test = fips_mct_aes_test; 1700 else 1701 test_ops.test = fips_generic_test; 1702 break; 1703 case FIPS_TEST_ALGO_HMAC: 1704 test_ops.prepare_op = prepare_auth_op; 1705 test_ops.prepare_xform = prepare_hmac_xform; 1706 test_ops.test = fips_generic_test; 1707 break; 1708 case FIPS_TEST_ALGO_TDES: 1709 test_ops.prepare_op = prepare_cipher_op; 1710 test_ops.prepare_xform = prepare_tdes_xform; 1711 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1712 test_ops.test = fips_mct_tdes_test; 1713 else 1714 test_ops.test = fips_generic_test; 1715 break; 1716 case FIPS_TEST_ALGO_AES_GCM: 1717 test_ops.prepare_op = prepare_aead_op; 1718 test_ops.prepare_xform = prepare_gcm_xform; 1719 test_ops.test = fips_generic_test; 1720 break; 1721 case FIPS_TEST_ALGO_AES_CMAC: 1722 test_ops.prepare_op = prepare_auth_op; 1723 test_ops.prepare_xform = prepare_cmac_xform; 1724 test_ops.test = fips_generic_test; 1725 break; 1726 case FIPS_TEST_ALGO_AES_CCM: 1727 test_ops.prepare_op = prepare_aead_op; 1728 test_ops.prepare_xform = prepare_ccm_xform; 1729 test_ops.test = fips_generic_test; 1730 break; 1731 case FIPS_TEST_ALGO_SHA: 1732 test_ops.prepare_op = prepare_auth_op; 1733 test_ops.prepare_xform = prepare_sha_xform; 1734 if (info.interim_info.sha_data.test_type == SHA_MCT) 1735 test_ops.test = fips_mct_sha_test; 1736 else 1737 test_ops.test = fips_generic_test; 1738 break; 1739 case FIPS_TEST_ALGO_AES_XTS: 1740 test_ops.prepare_op = prepare_cipher_op; 1741 test_ops.prepare_xform = prepare_xts_xform; 1742 test_ops.test = fips_generic_test; 1743 break; 1744 default: 1745 if (strstr(info.file_name, "TECB") || 1746 strstr(info.file_name, "TCBC")) { 1747 info.algo = FIPS_TEST_ALGO_TDES; 1748 test_ops.prepare_op = prepare_cipher_op; 1749 test_ops.prepare_xform = prepare_tdes_xform; 1750 if (info.interim_info.tdes_data.test_type == TDES_MCT) 1751 test_ops.test = fips_mct_tdes_test; 1752 else 1753 test_ops.test = fips_generic_test; 1754 break; 1755 } 1756 return -1; 1757 } 1758 1759 return 0; 1760 } 1761 1762 static void 1763 print_test_block(void) 1764 { 1765 uint32_t i; 1766 1767 for (i = 0; i < info.nb_vec_lines; i++) 1768 printf("%s\n", info.vec[i]); 1769 1770 printf("\n"); 1771 } 1772 1773 static int 1774 fips_test_one_file(void) 1775 { 1776 int fetch_ret = 0, ret; 1777 1778 ret = init_test_ops(); 1779 if (ret < 0) { 1780 RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 1781 return ret; 1782 } 1783 1784 while (ret >= 0 && fetch_ret == 0) { 1785 fetch_ret = fips_test_fetch_one_block(); 1786 if (fetch_ret < 0) { 1787 RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 1788 fetch_ret); 1789 ret = fetch_ret; 1790 goto error_one_case; 1791 } 1792 1793 if (info.nb_vec_lines == 0) { 1794 if (fetch_ret == -EOF) 1795 break; 1796 1797 fprintf(info.fp_wr, "\n"); 1798 continue; 1799 } 1800 1801 ret = fips_test_parse_one_case(); 1802 switch (ret) { 1803 case 0: 1804 ret = test_ops.test(); 1805 if (ret == 0) 1806 break; 1807 RTE_LOG(ERR, USER1, "Error %i: test block\n", 1808 ret); 1809 goto error_one_case; 1810 case 1: 1811 break; 1812 default: 1813 RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 1814 ret); 1815 goto error_one_case; 1816 } 1817 1818 continue; 1819 error_one_case: 1820 print_test_block(); 1821 } 1822 1823 fips_test_clear(); 1824 1825 if (env.digest) 1826 rte_free(env.digest); 1827 if (env.mbuf) 1828 rte_pktmbuf_free(env.mbuf); 1829 1830 return ret; 1831 } 1832