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