13d0fad56SMarko Kovacevic /* SPDX-License-Identifier: BSD-3-Clause 23d0fad56SMarko Kovacevic * Copyright(c) 2018 Intel Corporation 33d0fad56SMarko Kovacevic */ 43d0fad56SMarko Kovacevic 53d0fad56SMarko Kovacevic #include <sys/stat.h> 63d0fad56SMarko Kovacevic #include <getopt.h> 73d0fad56SMarko Kovacevic #include <dirent.h> 83d0fad56SMarko Kovacevic 93d0fad56SMarko Kovacevic #include <rte_cryptodev.h> 103d0fad56SMarko Kovacevic #include <rte_cryptodev_pmd.h> 113d0fad56SMarko Kovacevic #include <rte_mempool.h> 123d0fad56SMarko Kovacevic #include <rte_mbuf.h> 133d0fad56SMarko Kovacevic #include <rte_string_fns.h> 143d0fad56SMarko Kovacevic 153d0fad56SMarko Kovacevic #include "fips_validation.h" 163d0fad56SMarko Kovacevic 173d0fad56SMarko Kovacevic #define REQ_FILE_PATH_KEYWORD "req-file" 183d0fad56SMarko Kovacevic #define RSP_FILE_PATH_KEYWORD "rsp-file" 193d0fad56SMarko Kovacevic #define FOLDER_KEYWORD "path-is-folder" 203d0fad56SMarko Kovacevic #define CRYPTODEV_KEYWORD "cryptodev" 213d0fad56SMarko Kovacevic #define CRYPTODEV_ID_KEYWORD "cryptodev-id" 223d0fad56SMarko Kovacevic 233d0fad56SMarko Kovacevic struct fips_test_vector vec; 243d0fad56SMarko Kovacevic struct fips_test_interim_info info; 253d0fad56SMarko Kovacevic 263d0fad56SMarko Kovacevic struct cryptodev_fips_validate_env { 273d0fad56SMarko Kovacevic const char *req_path; 283d0fad56SMarko Kovacevic const char *rsp_path; 293d0fad56SMarko Kovacevic uint32_t is_path_folder; 303d0fad56SMarko Kovacevic uint32_t dev_id; 313d0fad56SMarko Kovacevic struct rte_mempool *mpool; 32*261bbff7SFan Zhang struct rte_mempool *sess_mpool; 33*261bbff7SFan Zhang struct rte_mempool *sess_priv_mpool; 343d0fad56SMarko Kovacevic struct rte_mempool *op_pool; 353d0fad56SMarko Kovacevic struct rte_mbuf *mbuf; 363d0fad56SMarko Kovacevic struct rte_crypto_op *op; 373d0fad56SMarko Kovacevic struct rte_cryptodev_sym_session *sess; 383d0fad56SMarko Kovacevic } env; 393d0fad56SMarko Kovacevic 403d0fad56SMarko Kovacevic static int 413d0fad56SMarko Kovacevic cryptodev_fips_validate_app_int(void) 423d0fad56SMarko Kovacevic { 433d0fad56SMarko Kovacevic struct rte_cryptodev_config conf = {rte_socket_id(), 1}; 44725d2a7fSFan Zhang struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL}; 45*261bbff7SFan Zhang uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size( 46*261bbff7SFan Zhang env.dev_id); 473d0fad56SMarko Kovacevic int ret; 483d0fad56SMarko Kovacevic 493d0fad56SMarko Kovacevic ret = rte_cryptodev_configure(env.dev_id, &conf); 503d0fad56SMarko Kovacevic if (ret < 0) 513d0fad56SMarko Kovacevic return ret; 523d0fad56SMarko Kovacevic 533d0fad56SMarko Kovacevic env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", 128, 0, 0, 543d0fad56SMarko Kovacevic UINT16_MAX, rte_socket_id()); 553d0fad56SMarko Kovacevic if (!env.mpool) 563d0fad56SMarko Kovacevic return ret; 573d0fad56SMarko Kovacevic 583d0fad56SMarko Kovacevic ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf, 59725d2a7fSFan Zhang rte_socket_id()); 603d0fad56SMarko Kovacevic if (ret < 0) 613d0fad56SMarko Kovacevic return ret; 623d0fad56SMarko Kovacevic 633d0fad56SMarko Kovacevic ret = -ENOMEM; 643d0fad56SMarko Kovacevic 65*261bbff7SFan Zhang env.sess_mpool = rte_cryptodev_sym_session_pool_create( 66*261bbff7SFan Zhang "FIPS_SESS_MEMPOOL", 16, 0, 0, 0, rte_socket_id()); 67*261bbff7SFan Zhang if (!env.sess_mpool) 68*261bbff7SFan Zhang goto error_exit; 69*261bbff7SFan Zhang 70*261bbff7SFan Zhang env.sess_priv_mpool = rte_mempool_create("FIPS_SESS_PRIV_MEMPOOL", 71*261bbff7SFan Zhang 16, sess_sz, 0, 0, NULL, NULL, NULL, 72*261bbff7SFan Zhang NULL, rte_socket_id(), 0); 73*261bbff7SFan Zhang if (!env.sess_priv_mpool) 74*261bbff7SFan Zhang goto error_exit; 75*261bbff7SFan Zhang 763d0fad56SMarko Kovacevic env.op_pool = rte_crypto_op_pool_create( 773d0fad56SMarko Kovacevic "FIPS_OP_POOL", 783d0fad56SMarko Kovacevic RTE_CRYPTO_OP_TYPE_SYMMETRIC, 793d0fad56SMarko Kovacevic 1, 0, 803d0fad56SMarko Kovacevic 16, 813d0fad56SMarko Kovacevic rte_socket_id()); 823d0fad56SMarko Kovacevic if (!env.op_pool) 833d0fad56SMarko Kovacevic goto error_exit; 843d0fad56SMarko Kovacevic 853d0fad56SMarko Kovacevic env.mbuf = rte_pktmbuf_alloc(env.mpool); 863d0fad56SMarko Kovacevic if (!env.mbuf) 873d0fad56SMarko Kovacevic goto error_exit; 883d0fad56SMarko Kovacevic 893d0fad56SMarko Kovacevic env.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 903d0fad56SMarko Kovacevic if (!env.op) 913d0fad56SMarko Kovacevic goto error_exit; 923d0fad56SMarko Kovacevic 93*261bbff7SFan Zhang qp_conf.mp_session = env.sess_mpool; 94*261bbff7SFan Zhang qp_conf.mp_session_private = env.sess_priv_mpool; 95*261bbff7SFan Zhang 96*261bbff7SFan Zhang ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf, 97*261bbff7SFan Zhang rte_socket_id()); 98*261bbff7SFan Zhang if (ret < 0) 99*261bbff7SFan Zhang goto error_exit; 100*261bbff7SFan Zhang 1013d0fad56SMarko Kovacevic return 0; 1023d0fad56SMarko Kovacevic 1033d0fad56SMarko Kovacevic error_exit: 104*261bbff7SFan Zhang 1053d0fad56SMarko Kovacevic rte_mempool_free(env.mpool); 106*261bbff7SFan Zhang if (env.sess_mpool) 107*261bbff7SFan Zhang rte_mempool_free(env.sess_mpool); 108*261bbff7SFan Zhang if (env.sess_priv_mpool) 109*261bbff7SFan Zhang rte_mempool_free(env.sess_priv_mpool); 1103d0fad56SMarko Kovacevic if (env.op_pool) 1113d0fad56SMarko Kovacevic rte_mempool_free(env.op_pool); 1123d0fad56SMarko Kovacevic 1133d0fad56SMarko Kovacevic return ret; 1143d0fad56SMarko Kovacevic } 1153d0fad56SMarko Kovacevic 1163d0fad56SMarko Kovacevic static void 1173d0fad56SMarko Kovacevic cryptodev_fips_validate_app_uninit(void) 1183d0fad56SMarko Kovacevic { 1193d0fad56SMarko Kovacevic rte_pktmbuf_free(env.mbuf); 1203d0fad56SMarko Kovacevic rte_crypto_op_free(env.op); 1213d0fad56SMarko Kovacevic rte_cryptodev_sym_session_clear(env.dev_id, env.sess); 1223d0fad56SMarko Kovacevic rte_cryptodev_sym_session_free(env.sess); 1233d0fad56SMarko Kovacevic rte_mempool_free(env.mpool); 124*261bbff7SFan Zhang rte_mempool_free(env.sess_mpool); 125*261bbff7SFan Zhang rte_mempool_free(env.sess_priv_mpool); 1263d0fad56SMarko Kovacevic rte_mempool_free(env.op_pool); 1273d0fad56SMarko Kovacevic } 1283d0fad56SMarko Kovacevic 1293d0fad56SMarko Kovacevic static int 1303d0fad56SMarko Kovacevic fips_test_one_file(void); 1313d0fad56SMarko Kovacevic 1323d0fad56SMarko Kovacevic static int 1333d0fad56SMarko Kovacevic parse_cryptodev_arg(char *arg) 1343d0fad56SMarko Kovacevic { 1353d0fad56SMarko Kovacevic int id = rte_cryptodev_get_dev_id(arg); 1363d0fad56SMarko Kovacevic 1373d0fad56SMarko Kovacevic if (id < 0) { 1383d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n", 1393d0fad56SMarko Kovacevic id, arg); 1403d0fad56SMarko Kovacevic return id; 1413d0fad56SMarko Kovacevic } 1423d0fad56SMarko Kovacevic 1433d0fad56SMarko Kovacevic env.dev_id = (uint32_t)id; 1443d0fad56SMarko Kovacevic 1453d0fad56SMarko Kovacevic return 0; 1463d0fad56SMarko Kovacevic } 1473d0fad56SMarko Kovacevic 1483d0fad56SMarko Kovacevic static int 1493d0fad56SMarko Kovacevic parse_cryptodev_id_arg(char *arg) 1503d0fad56SMarko Kovacevic { 1513d0fad56SMarko Kovacevic uint32_t cryptodev_id; 1523d0fad56SMarko Kovacevic 1533d0fad56SMarko Kovacevic if (parser_read_uint32(&cryptodev_id, arg) < 0) { 1543d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", 1553d0fad56SMarko Kovacevic -EINVAL, arg); 1563d0fad56SMarko Kovacevic return -1; 1573d0fad56SMarko Kovacevic } 1583d0fad56SMarko Kovacevic 1593d0fad56SMarko Kovacevic 1603d0fad56SMarko Kovacevic if (!rte_cryptodev_pmd_is_valid_dev(cryptodev_id)) { 1613d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", 1623d0fad56SMarko Kovacevic cryptodev_id, arg); 1633d0fad56SMarko Kovacevic return -1; 1643d0fad56SMarko Kovacevic } 1653d0fad56SMarko Kovacevic 1663d0fad56SMarko Kovacevic env.dev_id = (uint32_t)cryptodev_id; 1673d0fad56SMarko Kovacevic 1683d0fad56SMarko Kovacevic return 0; 1693d0fad56SMarko Kovacevic } 1703d0fad56SMarko Kovacevic 1713d0fad56SMarko Kovacevic static void 1723d0fad56SMarko Kovacevic cryptodev_fips_validate_usage(const char *prgname) 1733d0fad56SMarko Kovacevic { 1743d0fad56SMarko Kovacevic printf("%s [EAL options] --\n" 1753d0fad56SMarko Kovacevic " --%s: REQUEST-FILE-PATH\n" 1763d0fad56SMarko Kovacevic " --%s: RESPONSE-FILE-PATH\n" 1773d0fad56SMarko Kovacevic " --%s: indicating both paths are folders\n" 1783d0fad56SMarko Kovacevic " --%s: CRYPTODEV-NAME\n" 1793d0fad56SMarko Kovacevic " --%s: CRYPTODEV-ID-NAME\n", 1803d0fad56SMarko Kovacevic prgname, REQ_FILE_PATH_KEYWORD, RSP_FILE_PATH_KEYWORD, 1813d0fad56SMarko Kovacevic FOLDER_KEYWORD, CRYPTODEV_KEYWORD, CRYPTODEV_ID_KEYWORD); 1823d0fad56SMarko Kovacevic } 1833d0fad56SMarko Kovacevic 1843d0fad56SMarko Kovacevic static int 1853d0fad56SMarko Kovacevic cryptodev_fips_validate_parse_args(int argc, char **argv) 1863d0fad56SMarko Kovacevic { 1873d0fad56SMarko Kovacevic int opt, ret; 1883d0fad56SMarko Kovacevic char *prgname = argv[0]; 1893d0fad56SMarko Kovacevic char **argvopt; 1903d0fad56SMarko Kovacevic int option_index; 1913d0fad56SMarko Kovacevic struct option lgopts[] = { 1923d0fad56SMarko Kovacevic {REQ_FILE_PATH_KEYWORD, required_argument, 0, 0}, 1933d0fad56SMarko Kovacevic {RSP_FILE_PATH_KEYWORD, required_argument, 0, 0}, 1943d0fad56SMarko Kovacevic {FOLDER_KEYWORD, no_argument, 0, 0}, 1953d0fad56SMarko Kovacevic {CRYPTODEV_KEYWORD, required_argument, 0, 0}, 1963d0fad56SMarko Kovacevic {CRYPTODEV_ID_KEYWORD, required_argument, 0, 0}, 1973d0fad56SMarko Kovacevic {NULL, 0, 0, 0} 1983d0fad56SMarko Kovacevic }; 1993d0fad56SMarko Kovacevic 2003d0fad56SMarko Kovacevic argvopt = argv; 2013d0fad56SMarko Kovacevic 2023d0fad56SMarko Kovacevic while ((opt = getopt_long(argc, argvopt, "s:", 2033d0fad56SMarko Kovacevic lgopts, &option_index)) != EOF) { 2043d0fad56SMarko Kovacevic 2053d0fad56SMarko Kovacevic switch (opt) { 2063d0fad56SMarko Kovacevic case 0: 2073d0fad56SMarko Kovacevic if (strcmp(lgopts[option_index].name, 2083d0fad56SMarko Kovacevic REQ_FILE_PATH_KEYWORD) == 0) 2093d0fad56SMarko Kovacevic env.req_path = optarg; 2103d0fad56SMarko Kovacevic else if (strcmp(lgopts[option_index].name, 2113d0fad56SMarko Kovacevic RSP_FILE_PATH_KEYWORD) == 0) 2123d0fad56SMarko Kovacevic env.rsp_path = optarg; 2133d0fad56SMarko Kovacevic else if (strcmp(lgopts[option_index].name, 2143d0fad56SMarko Kovacevic FOLDER_KEYWORD) == 0) 2153d0fad56SMarko Kovacevic env.is_path_folder = 1; 2163d0fad56SMarko Kovacevic else if (strcmp(lgopts[option_index].name, 2173d0fad56SMarko Kovacevic CRYPTODEV_KEYWORD) == 0) { 2183d0fad56SMarko Kovacevic ret = parse_cryptodev_arg(optarg); 2193d0fad56SMarko Kovacevic if (ret < 0) { 2203d0fad56SMarko Kovacevic cryptodev_fips_validate_usage(prgname); 2213d0fad56SMarko Kovacevic return -EINVAL; 2223d0fad56SMarko Kovacevic } 2233d0fad56SMarko Kovacevic } else if (strcmp(lgopts[option_index].name, 2243d0fad56SMarko Kovacevic CRYPTODEV_ID_KEYWORD) == 0) { 2253d0fad56SMarko Kovacevic ret = parse_cryptodev_id_arg(optarg); 2263d0fad56SMarko Kovacevic if (ret < 0) { 2273d0fad56SMarko Kovacevic cryptodev_fips_validate_usage(prgname); 2283d0fad56SMarko Kovacevic return -EINVAL; 2293d0fad56SMarko Kovacevic } 2303d0fad56SMarko Kovacevic } else { 2313d0fad56SMarko Kovacevic cryptodev_fips_validate_usage(prgname); 2323d0fad56SMarko Kovacevic return -EINVAL; 2333d0fad56SMarko Kovacevic } 2343d0fad56SMarko Kovacevic break; 2353d0fad56SMarko Kovacevic default: 2363d0fad56SMarko Kovacevic return -1; 2373d0fad56SMarko Kovacevic } 2383d0fad56SMarko Kovacevic } 2393d0fad56SMarko Kovacevic 2403d0fad56SMarko Kovacevic if (env.req_path == NULL || env.rsp_path == NULL || 2413d0fad56SMarko Kovacevic env.dev_id == UINT32_MAX) { 2423d0fad56SMarko Kovacevic cryptodev_fips_validate_usage(prgname); 2433d0fad56SMarko Kovacevic return -EINVAL; 2443d0fad56SMarko Kovacevic } 2453d0fad56SMarko Kovacevic 2463d0fad56SMarko Kovacevic return 0; 2473d0fad56SMarko Kovacevic } 2483d0fad56SMarko Kovacevic 2493d0fad56SMarko Kovacevic int 2503d0fad56SMarko Kovacevic main(int argc, char *argv[]) 2513d0fad56SMarko Kovacevic { 2523d0fad56SMarko Kovacevic int ret; 2533d0fad56SMarko Kovacevic 2543d0fad56SMarko Kovacevic ret = rte_eal_init(argc, argv); 2553d0fad56SMarko Kovacevic if (ret < 0) { 2563d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); 2573d0fad56SMarko Kovacevic return -1; 2583d0fad56SMarko Kovacevic } 2593d0fad56SMarko Kovacevic 2603d0fad56SMarko Kovacevic argc -= ret; 2613d0fad56SMarko Kovacevic argv += ret; 2623d0fad56SMarko Kovacevic 2633d0fad56SMarko Kovacevic ret = cryptodev_fips_validate_parse_args(argc, argv); 2643d0fad56SMarko Kovacevic if (ret < 0) 2653d0fad56SMarko Kovacevic rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n"); 2663d0fad56SMarko Kovacevic 2673d0fad56SMarko Kovacevic ret = cryptodev_fips_validate_app_int(); 2683d0fad56SMarko Kovacevic if (ret < 0) { 2693d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); 2703d0fad56SMarko Kovacevic return -1; 2713d0fad56SMarko Kovacevic } 2723d0fad56SMarko Kovacevic 2733d0fad56SMarko Kovacevic if (!env.is_path_folder) { 2743d0fad56SMarko Kovacevic printf("Processing file %s... ", env.req_path); 2753d0fad56SMarko Kovacevic 2763d0fad56SMarko Kovacevic ret = fips_test_init(env.req_path, env.rsp_path, 2773d0fad56SMarko Kovacevic rte_cryptodev_name_get(env.dev_id)); 2783d0fad56SMarko Kovacevic if (ret < 0) { 2793d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 2803d0fad56SMarko Kovacevic ret, env.req_path); 2813d0fad56SMarko Kovacevic goto exit; 2823d0fad56SMarko Kovacevic } 2833d0fad56SMarko Kovacevic 2843d0fad56SMarko Kovacevic 2853d0fad56SMarko Kovacevic ret = fips_test_one_file(); 2863d0fad56SMarko Kovacevic if (ret < 0) { 2873d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 2883d0fad56SMarko Kovacevic ret, env.req_path); 2893d0fad56SMarko Kovacevic goto exit; 2903d0fad56SMarko Kovacevic } 2913d0fad56SMarko Kovacevic 2923d0fad56SMarko Kovacevic printf("Done\n"); 2933d0fad56SMarko Kovacevic 2943d0fad56SMarko Kovacevic } else { 2953d0fad56SMarko Kovacevic struct dirent *dir; 2963d0fad56SMarko Kovacevic DIR *d_req, *d_rsp; 2973d0fad56SMarko Kovacevic char req_path[1024]; 2983d0fad56SMarko Kovacevic char rsp_path[1024]; 2993d0fad56SMarko Kovacevic 3003d0fad56SMarko Kovacevic d_req = opendir(env.req_path); 3013d0fad56SMarko Kovacevic if (!d_req) { 3023d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n", 3033d0fad56SMarko Kovacevic -EINVAL, env.req_path); 3043d0fad56SMarko Kovacevic goto exit; 3053d0fad56SMarko Kovacevic } 3063d0fad56SMarko Kovacevic 3073d0fad56SMarko Kovacevic d_rsp = opendir(env.rsp_path); 3083d0fad56SMarko Kovacevic if (!d_rsp) { 3093d0fad56SMarko Kovacevic ret = mkdir(env.rsp_path, 0700); 3103d0fad56SMarko Kovacevic if (ret == 0) 3113d0fad56SMarko Kovacevic d_rsp = opendir(env.rsp_path); 3123d0fad56SMarko Kovacevic else { 3133d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n", 3143d0fad56SMarko Kovacevic -EINVAL, env.rsp_path); 3153d0fad56SMarko Kovacevic goto exit; 3163d0fad56SMarko Kovacevic } 3173d0fad56SMarko Kovacevic } 3183d0fad56SMarko Kovacevic closedir(d_rsp); 3193d0fad56SMarko Kovacevic 3203d0fad56SMarko Kovacevic while ((dir = readdir(d_req)) != NULL) { 3213d0fad56SMarko Kovacevic if (strstr(dir->d_name, "req") == NULL) 3223d0fad56SMarko Kovacevic continue; 3233d0fad56SMarko Kovacevic 3243d0fad56SMarko Kovacevic snprintf(req_path, 1023, "%s/%s", env.req_path, 3253d0fad56SMarko Kovacevic dir->d_name); 3263d0fad56SMarko Kovacevic snprintf(rsp_path, 1023, "%s/%s", env.rsp_path, 3273d0fad56SMarko Kovacevic dir->d_name); 3283d0fad56SMarko Kovacevic strlcpy(strstr(rsp_path, "req"), "rsp", 4); 3293d0fad56SMarko Kovacevic 3303d0fad56SMarko Kovacevic printf("Processing file %s... ", req_path); 3313d0fad56SMarko Kovacevic 3323d0fad56SMarko Kovacevic ret = fips_test_init(req_path, rsp_path, 3333d0fad56SMarko Kovacevic rte_cryptodev_name_get(env.dev_id)); 3343d0fad56SMarko Kovacevic if (ret < 0) { 3353d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 3363d0fad56SMarko Kovacevic ret, req_path); 3373d0fad56SMarko Kovacevic break; 3383d0fad56SMarko Kovacevic } 3393d0fad56SMarko Kovacevic 3403d0fad56SMarko Kovacevic ret = fips_test_one_file(); 3413d0fad56SMarko Kovacevic if (ret < 0) { 3423d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", 3433d0fad56SMarko Kovacevic ret, req_path); 3443d0fad56SMarko Kovacevic break; 3453d0fad56SMarko Kovacevic } 3463d0fad56SMarko Kovacevic 3473d0fad56SMarko Kovacevic printf("Done\n"); 3483d0fad56SMarko Kovacevic } 3493d0fad56SMarko Kovacevic 3503d0fad56SMarko Kovacevic closedir(d_req); 3513d0fad56SMarko Kovacevic } 3523d0fad56SMarko Kovacevic 3533d0fad56SMarko Kovacevic 3543d0fad56SMarko Kovacevic exit: 3553d0fad56SMarko Kovacevic fips_test_clear(); 3563d0fad56SMarko Kovacevic cryptodev_fips_validate_app_uninit(); 3573d0fad56SMarko Kovacevic 3583d0fad56SMarko Kovacevic return ret; 3593d0fad56SMarko Kovacevic 3603d0fad56SMarko Kovacevic } 3613d0fad56SMarko Kovacevic 362cd255ccfSMarko Kovacevic #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op)) 363cd255ccfSMarko Kovacevic #define CRYPTODEV_FIPS_MAX_RETRIES 16 364cd255ccfSMarko Kovacevic 365cd255ccfSMarko Kovacevic typedef int (*fips_test_one_case_t)(void); 366cd255ccfSMarko Kovacevic typedef int (*fips_prepare_op_t)(void); 367cd255ccfSMarko Kovacevic typedef int (*fips_prepare_xform_t)(struct rte_crypto_sym_xform *); 368cd255ccfSMarko Kovacevic 369cd255ccfSMarko Kovacevic struct fips_test_ops { 370cd255ccfSMarko Kovacevic fips_prepare_xform_t prepare_xform; 371cd255ccfSMarko Kovacevic fips_prepare_op_t prepare_op; 372cd255ccfSMarko Kovacevic fips_test_one_case_t test; 373cd255ccfSMarko Kovacevic } test_ops; 374cd255ccfSMarko Kovacevic 375cd255ccfSMarko Kovacevic static int 376cd255ccfSMarko Kovacevic prepare_cipher_op(void) 377cd255ccfSMarko Kovacevic { 378cd255ccfSMarko Kovacevic struct rte_crypto_sym_op *sym = env.op->sym; 379cd255ccfSMarko Kovacevic uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); 380cd255ccfSMarko Kovacevic 381cd255ccfSMarko Kovacevic __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 382cd255ccfSMarko Kovacevic rte_pktmbuf_reset(env.mbuf); 383cd255ccfSMarko Kovacevic 384cd255ccfSMarko Kovacevic sym->m_src = env.mbuf; 385cd255ccfSMarko Kovacevic sym->cipher.data.offset = 0; 386cd255ccfSMarko Kovacevic 387cd255ccfSMarko Kovacevic memcpy(iv, vec.iv.val, vec.iv.len); 388cd255ccfSMarko Kovacevic 389cd255ccfSMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 390cd255ccfSMarko Kovacevic uint8_t *pt; 391cd255ccfSMarko Kovacevic 392cd255ccfSMarko Kovacevic if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) { 393cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len); 394cd255ccfSMarko Kovacevic return -EPERM; 395cd255ccfSMarko Kovacevic } 396cd255ccfSMarko Kovacevic 397cd255ccfSMarko Kovacevic pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len); 398cd255ccfSMarko Kovacevic 399cd255ccfSMarko Kovacevic if (!pt) { 400cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", 401cd255ccfSMarko Kovacevic -ENOMEM); 402cd255ccfSMarko Kovacevic return -ENOMEM; 403cd255ccfSMarko Kovacevic } 404cd255ccfSMarko Kovacevic 405cd255ccfSMarko Kovacevic memcpy(pt, vec.pt.val, vec.pt.len); 406cd255ccfSMarko Kovacevic sym->cipher.data.length = vec.pt.len; 407cd255ccfSMarko Kovacevic 408cd255ccfSMarko Kovacevic } else { 409cd255ccfSMarko Kovacevic uint8_t *ct; 410cd255ccfSMarko Kovacevic 411cd255ccfSMarko Kovacevic if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) { 412cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len); 413cd255ccfSMarko Kovacevic return -EPERM; 414cd255ccfSMarko Kovacevic } 415cd255ccfSMarko Kovacevic 416cd255ccfSMarko Kovacevic ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len); 417cd255ccfSMarko Kovacevic 418cd255ccfSMarko Kovacevic if (!ct) { 419cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", 420cd255ccfSMarko Kovacevic -ENOMEM); 421cd255ccfSMarko Kovacevic return -ENOMEM; 422cd255ccfSMarko Kovacevic } 423cd255ccfSMarko Kovacevic 424cd255ccfSMarko Kovacevic memcpy(ct, vec.ct.val, vec.ct.len); 425cd255ccfSMarko Kovacevic sym->cipher.data.length = vec.ct.len; 426cd255ccfSMarko Kovacevic } 427cd255ccfSMarko Kovacevic 428cd255ccfSMarko Kovacevic rte_crypto_op_attach_sym_session(env.op, env.sess); 429cd255ccfSMarko Kovacevic 430cd255ccfSMarko Kovacevic return 0; 431cd255ccfSMarko Kovacevic } 432cd255ccfSMarko Kovacevic 433cd255ccfSMarko Kovacevic static int 434f64adb67SMarko Kovacevic prepare_auth_op(void) 435f64adb67SMarko Kovacevic { 436f64adb67SMarko Kovacevic struct rte_crypto_sym_op *sym = env.op->sym; 437f64adb67SMarko Kovacevic 438f64adb67SMarko Kovacevic __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 439f64adb67SMarko Kovacevic rte_pktmbuf_reset(env.mbuf); 440f64adb67SMarko Kovacevic 441f64adb67SMarko Kovacevic sym->m_src = env.mbuf; 442f64adb67SMarko Kovacevic sym->auth.data.offset = 0; 443f64adb67SMarko Kovacevic 444f64adb67SMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 445f64adb67SMarko Kovacevic uint8_t *pt; 446f64adb67SMarko Kovacevic 447f64adb67SMarko Kovacevic if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) { 448f64adb67SMarko Kovacevic RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len); 449f64adb67SMarko Kovacevic return -EPERM; 450f64adb67SMarko Kovacevic } 451f64adb67SMarko Kovacevic 452f64adb67SMarko Kovacevic pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len + 453f64adb67SMarko Kovacevic vec.cipher_auth.digest.len); 454f64adb67SMarko Kovacevic 455f64adb67SMarko Kovacevic if (!pt) { 456f64adb67SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", 457f64adb67SMarko Kovacevic -ENOMEM); 458f64adb67SMarko Kovacevic return -ENOMEM; 459f64adb67SMarko Kovacevic } 460f64adb67SMarko Kovacevic 461f64adb67SMarko Kovacevic memcpy(pt, vec.pt.val, vec.pt.len); 462f64adb67SMarko Kovacevic sym->auth.data.length = vec.pt.len; 463f64adb67SMarko Kovacevic sym->auth.digest.data = pt + vec.pt.len; 464f64adb67SMarko Kovacevic sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset( 465f64adb67SMarko Kovacevic env.mbuf, vec.pt.len); 466f64adb67SMarko Kovacevic 467f64adb67SMarko Kovacevic } else { 468f64adb67SMarko Kovacevic uint8_t *ct; 469f64adb67SMarko Kovacevic 470f64adb67SMarko Kovacevic if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) { 471f64adb67SMarko Kovacevic RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len); 472f64adb67SMarko Kovacevic return -EPERM; 473f64adb67SMarko Kovacevic } 474f64adb67SMarko Kovacevic 475f64adb67SMarko Kovacevic ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, 476f64adb67SMarko Kovacevic vec.ct.len + vec.cipher_auth.digest.len); 477f64adb67SMarko Kovacevic 478f64adb67SMarko Kovacevic if (!ct) { 479f64adb67SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", 480f64adb67SMarko Kovacevic -ENOMEM); 481f64adb67SMarko Kovacevic return -ENOMEM; 482f64adb67SMarko Kovacevic } 483f64adb67SMarko Kovacevic 484f64adb67SMarko Kovacevic memcpy(ct, vec.ct.val, vec.ct.len); 485f64adb67SMarko Kovacevic sym->auth.data.length = vec.ct.len; 486f64adb67SMarko Kovacevic sym->auth.digest.data = vec.cipher_auth.digest.val; 487f64adb67SMarko Kovacevic sym->auth.digest.phys_addr = rte_malloc_virt2iova( 488f64adb67SMarko Kovacevic sym->auth.digest.data); 489f64adb67SMarko Kovacevic } 490f64adb67SMarko Kovacevic 491f64adb67SMarko Kovacevic rte_crypto_op_attach_sym_session(env.op, env.sess); 492c05e4ab7SThomas Monjalon 493c05e4ab7SThomas Monjalon return 0; 494f64adb67SMarko Kovacevic } 495f64adb67SMarko Kovacevic 496f64adb67SMarko Kovacevic static int 4974aaad299SMarko Kovacevic prepare_aead_op(void) 4984aaad299SMarko Kovacevic { 4994aaad299SMarko Kovacevic struct rte_crypto_sym_op *sym = env.op->sym; 5004aaad299SMarko Kovacevic uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF); 5014aaad299SMarko Kovacevic 5024aaad299SMarko Kovacevic __rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC); 5034aaad299SMarko Kovacevic rte_pktmbuf_reset(env.mbuf); 5044aaad299SMarko Kovacevic 505305921f4SMarko Kovacevic if (info.algo == FIPS_TEST_ALGO_AES_CCM) 506305921f4SMarko Kovacevic memcpy(iv + 1, vec.iv.val, vec.iv.len); 507305921f4SMarko Kovacevic else 5084aaad299SMarko Kovacevic memcpy(iv, vec.iv.val, vec.iv.len); 5094aaad299SMarko Kovacevic 5104aaad299SMarko Kovacevic sym->m_src = env.mbuf; 5114aaad299SMarko Kovacevic sym->aead.data.offset = 0; 5124aaad299SMarko Kovacevic sym->aead.aad.data = vec.aead.aad.val; 5134aaad299SMarko Kovacevic sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data); 5144aaad299SMarko Kovacevic 5154aaad299SMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 5164aaad299SMarko Kovacevic uint8_t *pt; 5174aaad299SMarko Kovacevic 5184aaad299SMarko Kovacevic if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) { 5194aaad299SMarko Kovacevic RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len); 5204aaad299SMarko Kovacevic return -EPERM; 5214aaad299SMarko Kovacevic } 5224aaad299SMarko Kovacevic 5234aaad299SMarko Kovacevic pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, 5244aaad299SMarko Kovacevic vec.pt.len + vec.aead.digest.len); 5254aaad299SMarko Kovacevic 5264aaad299SMarko Kovacevic if (!pt) { 5274aaad299SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", 5284aaad299SMarko Kovacevic -ENOMEM); 5294aaad299SMarko Kovacevic return -ENOMEM; 5304aaad299SMarko Kovacevic } 5314aaad299SMarko Kovacevic 5324aaad299SMarko Kovacevic memcpy(pt, vec.pt.val, vec.pt.len); 5334aaad299SMarko Kovacevic sym->aead.data.length = vec.pt.len; 5344aaad299SMarko Kovacevic sym->aead.digest.data = pt + vec.pt.len; 5354aaad299SMarko Kovacevic sym->aead.digest.phys_addr = rte_pktmbuf_mtophys_offset( 5364aaad299SMarko Kovacevic env.mbuf, vec.pt.len); 5374aaad299SMarko Kovacevic } else { 5384aaad299SMarko Kovacevic uint8_t *ct; 5394aaad299SMarko Kovacevic 5404aaad299SMarko Kovacevic if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) { 5414aaad299SMarko Kovacevic RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len); 5424aaad299SMarko Kovacevic return -EPERM; 5434aaad299SMarko Kovacevic } 5444aaad299SMarko Kovacevic 5454aaad299SMarko Kovacevic ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len); 5464aaad299SMarko Kovacevic 5474aaad299SMarko Kovacevic if (!ct) { 5484aaad299SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n", 5494aaad299SMarko Kovacevic -ENOMEM); 5504aaad299SMarko Kovacevic return -ENOMEM; 5514aaad299SMarko Kovacevic } 5524aaad299SMarko Kovacevic 5534aaad299SMarko Kovacevic memcpy(ct, vec.ct.val, vec.ct.len); 5544aaad299SMarko Kovacevic sym->aead.data.length = vec.ct.len; 5554aaad299SMarko Kovacevic sym->aead.digest.data = vec.aead.digest.val; 5564aaad299SMarko Kovacevic sym->aead.digest.phys_addr = rte_malloc_virt2iova( 5574aaad299SMarko Kovacevic sym->aead.digest.data); 5584aaad299SMarko Kovacevic } 5594aaad299SMarko Kovacevic 5604aaad299SMarko Kovacevic rte_crypto_op_attach_sym_session(env.op, env.sess); 561c05e4ab7SThomas Monjalon 562c05e4ab7SThomas Monjalon return 0; 5634aaad299SMarko Kovacevic } 5644aaad299SMarko Kovacevic 5654aaad299SMarko Kovacevic static int 566cd255ccfSMarko Kovacevic prepare_aes_xform(struct rte_crypto_sym_xform *xform) 567cd255ccfSMarko Kovacevic { 568cd255ccfSMarko Kovacevic const struct rte_cryptodev_symmetric_capability *cap; 569cd255ccfSMarko Kovacevic struct rte_cryptodev_sym_capability_idx cap_idx; 570cd255ccfSMarko Kovacevic struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 571cd255ccfSMarko Kovacevic 572cd255ccfSMarko Kovacevic xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 573cd255ccfSMarko Kovacevic 574cd255ccfSMarko Kovacevic cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC; 575cd255ccfSMarko Kovacevic cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 576cd255ccfSMarko Kovacevic RTE_CRYPTO_CIPHER_OP_ENCRYPT : 577cd255ccfSMarko Kovacevic RTE_CRYPTO_CIPHER_OP_DECRYPT; 578cd255ccfSMarko Kovacevic cipher_xform->key.data = vec.cipher_auth.key.val; 579cd255ccfSMarko Kovacevic cipher_xform->key.length = vec.cipher_auth.key.len; 580cd255ccfSMarko Kovacevic cipher_xform->iv.length = vec.iv.len; 581cd255ccfSMarko Kovacevic cipher_xform->iv.offset = IV_OFF; 582cd255ccfSMarko Kovacevic 583cd255ccfSMarko Kovacevic cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_CBC; 584cd255ccfSMarko Kovacevic cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 585cd255ccfSMarko Kovacevic 586cd255ccfSMarko Kovacevic cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 587cd255ccfSMarko Kovacevic if (!cap) { 588cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 589cd255ccfSMarko Kovacevic env.dev_id); 590cd255ccfSMarko Kovacevic return -EINVAL; 591cd255ccfSMarko Kovacevic } 592cd255ccfSMarko Kovacevic 593cd255ccfSMarko Kovacevic if (rte_cryptodev_sym_capability_check_cipher(cap, 594cd255ccfSMarko Kovacevic cipher_xform->key.length, 595cd255ccfSMarko Kovacevic cipher_xform->iv.length) != 0) { 596cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 597cd255ccfSMarko Kovacevic info.device_name, cipher_xform->key.length, 598cd255ccfSMarko Kovacevic cipher_xform->iv.length); 599cd255ccfSMarko Kovacevic return -EPERM; 600cd255ccfSMarko Kovacevic } 601cd255ccfSMarko Kovacevic 602cd255ccfSMarko Kovacevic return 0; 603cd255ccfSMarko Kovacevic } 604cd255ccfSMarko Kovacevic 605f64adb67SMarko Kovacevic static int 606527cbf3dSMarko Kovacevic prepare_tdes_xform(struct rte_crypto_sym_xform *xform) 607527cbf3dSMarko Kovacevic { 608527cbf3dSMarko Kovacevic const struct rte_cryptodev_symmetric_capability *cap; 609527cbf3dSMarko Kovacevic struct rte_cryptodev_sym_capability_idx cap_idx; 610527cbf3dSMarko Kovacevic struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher; 611527cbf3dSMarko Kovacevic 612527cbf3dSMarko Kovacevic xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 613527cbf3dSMarko Kovacevic 614527cbf3dSMarko Kovacevic cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC; 615527cbf3dSMarko Kovacevic cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 616527cbf3dSMarko Kovacevic RTE_CRYPTO_CIPHER_OP_ENCRYPT : 617527cbf3dSMarko Kovacevic RTE_CRYPTO_CIPHER_OP_DECRYPT; 618527cbf3dSMarko Kovacevic cipher_xform->key.data = vec.cipher_auth.key.val; 619527cbf3dSMarko Kovacevic cipher_xform->key.length = vec.cipher_auth.key.len; 620527cbf3dSMarko Kovacevic cipher_xform->iv.length = vec.iv.len; 621527cbf3dSMarko Kovacevic cipher_xform->iv.offset = IV_OFF; 622527cbf3dSMarko Kovacevic 623527cbf3dSMarko Kovacevic cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_3DES_CBC; 624527cbf3dSMarko Kovacevic cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER; 625527cbf3dSMarko Kovacevic 626527cbf3dSMarko Kovacevic cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 627527cbf3dSMarko Kovacevic if (!cap) { 628527cbf3dSMarko Kovacevic RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 629527cbf3dSMarko Kovacevic env.dev_id); 630527cbf3dSMarko Kovacevic return -EINVAL; 631527cbf3dSMarko Kovacevic } 632527cbf3dSMarko Kovacevic 633527cbf3dSMarko Kovacevic if (rte_cryptodev_sym_capability_check_cipher(cap, 634527cbf3dSMarko Kovacevic cipher_xform->key.length, 635527cbf3dSMarko Kovacevic cipher_xform->iv.length) != 0) { 636527cbf3dSMarko Kovacevic RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 637527cbf3dSMarko Kovacevic info.device_name, cipher_xform->key.length, 638527cbf3dSMarko Kovacevic cipher_xform->iv.length); 639527cbf3dSMarko Kovacevic return -EPERM; 640527cbf3dSMarko Kovacevic } 641527cbf3dSMarko Kovacevic 642527cbf3dSMarko Kovacevic return 0; 643527cbf3dSMarko Kovacevic } 644527cbf3dSMarko Kovacevic 645527cbf3dSMarko Kovacevic static int 646f64adb67SMarko Kovacevic prepare_hmac_xform(struct rte_crypto_sym_xform *xform) 647f64adb67SMarko Kovacevic { 648f64adb67SMarko Kovacevic const struct rte_cryptodev_symmetric_capability *cap; 649f64adb67SMarko Kovacevic struct rte_cryptodev_sym_capability_idx cap_idx; 650f64adb67SMarko Kovacevic struct rte_crypto_auth_xform *auth_xform = &xform->auth; 651f64adb67SMarko Kovacevic 652f64adb67SMarko Kovacevic xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 653f64adb67SMarko Kovacevic 654f64adb67SMarko Kovacevic auth_xform->algo = info.interim_info.hmac_data.algo; 655f64adb67SMarko Kovacevic auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE; 656f64adb67SMarko Kovacevic auth_xform->digest_length = vec.cipher_auth.digest.len; 657f64adb67SMarko Kovacevic auth_xform->key.data = vec.cipher_auth.key.val; 658f64adb67SMarko Kovacevic auth_xform->key.length = vec.cipher_auth.key.len; 659f64adb67SMarko Kovacevic 660f64adb67SMarko Kovacevic cap_idx.algo.auth = auth_xform->algo; 661f64adb67SMarko Kovacevic cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 662f64adb67SMarko Kovacevic 663f64adb67SMarko Kovacevic cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 664f64adb67SMarko Kovacevic if (!cap) { 665f64adb67SMarko Kovacevic RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 666f64adb67SMarko Kovacevic env.dev_id); 667f64adb67SMarko Kovacevic return -EINVAL; 668f64adb67SMarko Kovacevic } 669f64adb67SMarko Kovacevic 670f64adb67SMarko Kovacevic if (rte_cryptodev_sym_capability_check_auth(cap, 671f64adb67SMarko Kovacevic auth_xform->key.length, 672f64adb67SMarko Kovacevic auth_xform->digest_length, 0) != 0) { 673f64adb67SMarko Kovacevic RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 674f64adb67SMarko Kovacevic info.device_name, auth_xform->key.length, 675f64adb67SMarko Kovacevic auth_xform->digest_length); 676f64adb67SMarko Kovacevic return -EPERM; 677f64adb67SMarko Kovacevic } 678f64adb67SMarko Kovacevic 679f64adb67SMarko Kovacevic return 0; 680f64adb67SMarko Kovacevic } 681f64adb67SMarko Kovacevic 6824aaad299SMarko Kovacevic static int 6834aaad299SMarko Kovacevic prepare_gcm_xform(struct rte_crypto_sym_xform *xform) 6844aaad299SMarko Kovacevic { 6854aaad299SMarko Kovacevic const struct rte_cryptodev_symmetric_capability *cap; 6864aaad299SMarko Kovacevic struct rte_cryptodev_sym_capability_idx cap_idx; 6874aaad299SMarko Kovacevic struct rte_crypto_aead_xform *aead_xform = &xform->aead; 6884aaad299SMarko Kovacevic 6894aaad299SMarko Kovacevic xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 6904aaad299SMarko Kovacevic 6914aaad299SMarko Kovacevic aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM; 6924aaad299SMarko Kovacevic aead_xform->aad_length = vec.aead.aad.len; 6934aaad299SMarko Kovacevic aead_xform->digest_length = vec.aead.digest.len; 6944aaad299SMarko Kovacevic aead_xform->iv.offset = IV_OFF; 6954aaad299SMarko Kovacevic aead_xform->iv.length = vec.iv.len; 6964aaad299SMarko Kovacevic aead_xform->key.data = vec.aead.key.val; 6974aaad299SMarko Kovacevic aead_xform->key.length = vec.aead.key.len; 6984aaad299SMarko Kovacevic aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 6994aaad299SMarko Kovacevic RTE_CRYPTO_AEAD_OP_ENCRYPT : 7004aaad299SMarko Kovacevic RTE_CRYPTO_AEAD_OP_DECRYPT; 7014aaad299SMarko Kovacevic 7024aaad299SMarko Kovacevic cap_idx.algo.aead = aead_xform->algo; 7034aaad299SMarko Kovacevic cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 7044aaad299SMarko Kovacevic 7054aaad299SMarko Kovacevic cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 7064aaad299SMarko Kovacevic if (!cap) { 7074aaad299SMarko Kovacevic RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 7084aaad299SMarko Kovacevic env.dev_id); 7094aaad299SMarko Kovacevic return -EINVAL; 7104aaad299SMarko Kovacevic } 7114aaad299SMarko Kovacevic 7124aaad299SMarko Kovacevic if (rte_cryptodev_sym_capability_check_aead(cap, 7134aaad299SMarko Kovacevic aead_xform->key.length, 7144aaad299SMarko Kovacevic aead_xform->digest_length, aead_xform->aad_length, 7154aaad299SMarko Kovacevic aead_xform->iv.length) != 0) { 7164aaad299SMarko Kovacevic RTE_LOG(ERR, USER1, 7174aaad299SMarko Kovacevic "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 7184aaad299SMarko Kovacevic info.device_name, aead_xform->key.length, 7194aaad299SMarko Kovacevic aead_xform->digest_length, 7204aaad299SMarko Kovacevic aead_xform->aad_length, 7214aaad299SMarko Kovacevic aead_xform->iv.length); 7224aaad299SMarko Kovacevic return -EPERM; 7234aaad299SMarko Kovacevic } 7244aaad299SMarko Kovacevic 7254aaad299SMarko Kovacevic return 0; 7264aaad299SMarko Kovacevic } 7274aaad299SMarko Kovacevic 728ac026f46SMarko Kovacevic static int 729ac026f46SMarko Kovacevic prepare_cmac_xform(struct rte_crypto_sym_xform *xform) 730ac026f46SMarko Kovacevic { 731ac026f46SMarko Kovacevic const struct rte_cryptodev_symmetric_capability *cap; 732ac026f46SMarko Kovacevic struct rte_cryptodev_sym_capability_idx cap_idx; 733ac026f46SMarko Kovacevic struct rte_crypto_auth_xform *auth_xform = &xform->auth; 734ac026f46SMarko Kovacevic 735ac026f46SMarko Kovacevic xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 736ac026f46SMarko Kovacevic 737ac026f46SMarko Kovacevic auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC; 738ac026f46SMarko Kovacevic auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 739ac026f46SMarko Kovacevic RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY; 740ac026f46SMarko Kovacevic auth_xform->digest_length = vec.cipher_auth.digest.len; 741ac026f46SMarko Kovacevic auth_xform->key.data = vec.cipher_auth.key.val; 742ac026f46SMarko Kovacevic auth_xform->key.length = vec.cipher_auth.key.len; 743ac026f46SMarko Kovacevic 744ac026f46SMarko Kovacevic cap_idx.algo.auth = auth_xform->algo; 745ac026f46SMarko Kovacevic cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH; 746ac026f46SMarko Kovacevic 747ac026f46SMarko Kovacevic cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 748ac026f46SMarko Kovacevic if (!cap) { 749ac026f46SMarko Kovacevic RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 750ac026f46SMarko Kovacevic env.dev_id); 751ac026f46SMarko Kovacevic return -EINVAL; 752ac026f46SMarko Kovacevic } 753ac026f46SMarko Kovacevic 754ac026f46SMarko Kovacevic if (rte_cryptodev_sym_capability_check_auth(cap, 755ac026f46SMarko Kovacevic auth_xform->key.length, 756ac026f46SMarko Kovacevic auth_xform->digest_length, 0) != 0) { 757ac026f46SMarko Kovacevic RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n", 758ac026f46SMarko Kovacevic info.device_name, auth_xform->key.length, 759ac026f46SMarko Kovacevic auth_xform->digest_length); 760ac026f46SMarko Kovacevic return -EPERM; 761ac026f46SMarko Kovacevic } 762ac026f46SMarko Kovacevic 763ac026f46SMarko Kovacevic return 0; 764ac026f46SMarko Kovacevic } 765ac026f46SMarko Kovacevic 766305921f4SMarko Kovacevic static int 767305921f4SMarko Kovacevic prepare_ccm_xform(struct rte_crypto_sym_xform *xform) 768305921f4SMarko Kovacevic { 769305921f4SMarko Kovacevic const struct rte_cryptodev_symmetric_capability *cap; 770305921f4SMarko Kovacevic struct rte_cryptodev_sym_capability_idx cap_idx; 771305921f4SMarko Kovacevic struct rte_crypto_aead_xform *aead_xform = &xform->aead; 772305921f4SMarko Kovacevic 773305921f4SMarko Kovacevic xform->type = RTE_CRYPTO_SYM_XFORM_AEAD; 774305921f4SMarko Kovacevic 775305921f4SMarko Kovacevic aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM; 776305921f4SMarko Kovacevic aead_xform->aad_length = vec.aead.aad.len; 777305921f4SMarko Kovacevic aead_xform->digest_length = vec.aead.digest.len; 778305921f4SMarko Kovacevic aead_xform->iv.offset = IV_OFF; 779305921f4SMarko Kovacevic aead_xform->iv.length = vec.iv.len; 780305921f4SMarko Kovacevic aead_xform->key.data = vec.aead.key.val; 781305921f4SMarko Kovacevic aead_xform->key.length = vec.aead.key.len; 782305921f4SMarko Kovacevic aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ? 783305921f4SMarko Kovacevic RTE_CRYPTO_AEAD_OP_ENCRYPT : 784305921f4SMarko Kovacevic RTE_CRYPTO_AEAD_OP_DECRYPT; 785305921f4SMarko Kovacevic 786305921f4SMarko Kovacevic cap_idx.algo.aead = aead_xform->algo; 787305921f4SMarko Kovacevic cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD; 788305921f4SMarko Kovacevic 789305921f4SMarko Kovacevic cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx); 790305921f4SMarko Kovacevic if (!cap) { 791305921f4SMarko Kovacevic RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n", 792305921f4SMarko Kovacevic env.dev_id); 793305921f4SMarko Kovacevic return -EINVAL; 794305921f4SMarko Kovacevic } 795305921f4SMarko Kovacevic 796305921f4SMarko Kovacevic if (rte_cryptodev_sym_capability_check_aead(cap, 797305921f4SMarko Kovacevic aead_xform->key.length, 798305921f4SMarko Kovacevic aead_xform->digest_length, aead_xform->aad_length, 799305921f4SMarko Kovacevic aead_xform->iv.length) != 0) { 800305921f4SMarko Kovacevic RTE_LOG(ERR, USER1, 801305921f4SMarko Kovacevic "PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n", 802305921f4SMarko Kovacevic info.device_name, aead_xform->key.length, 803305921f4SMarko Kovacevic aead_xform->digest_length, 804305921f4SMarko Kovacevic aead_xform->aad_length, 805305921f4SMarko Kovacevic aead_xform->iv.length); 806305921f4SMarko Kovacevic return -EPERM; 807305921f4SMarko Kovacevic } 808305921f4SMarko Kovacevic 809305921f4SMarko Kovacevic return 0; 810305921f4SMarko Kovacevic } 811305921f4SMarko Kovacevic 812cd255ccfSMarko Kovacevic static void 813cd255ccfSMarko Kovacevic get_writeback_data(struct fips_val *val) 814cd255ccfSMarko Kovacevic { 815cd255ccfSMarko Kovacevic val->val = rte_pktmbuf_mtod(env.mbuf, uint8_t *); 816cd255ccfSMarko Kovacevic val->len = rte_pktmbuf_pkt_len(env.mbuf); 817cd255ccfSMarko Kovacevic } 818cd255ccfSMarko Kovacevic 819cd255ccfSMarko Kovacevic static int 820cd255ccfSMarko Kovacevic fips_run_test(void) 821cd255ccfSMarko Kovacevic { 822cd255ccfSMarko Kovacevic struct rte_crypto_sym_xform xform = {0}; 823cd255ccfSMarko Kovacevic uint16_t n_deqd; 824cd255ccfSMarko Kovacevic int ret; 825cd255ccfSMarko Kovacevic 826cd255ccfSMarko Kovacevic ret = test_ops.prepare_xform(&xform); 827cd255ccfSMarko Kovacevic if (ret < 0) 828cd255ccfSMarko Kovacevic return ret; 829cd255ccfSMarko Kovacevic 830*261bbff7SFan Zhang env.sess = rte_cryptodev_sym_session_create(env.sess_mpool); 831cd255ccfSMarko Kovacevic if (!env.sess) 832cd255ccfSMarko Kovacevic return -ENOMEM; 833cd255ccfSMarko Kovacevic 834cd255ccfSMarko Kovacevic ret = rte_cryptodev_sym_session_init(env.dev_id, 835*261bbff7SFan Zhang env.sess, &xform, env.sess_priv_mpool); 836cd255ccfSMarko Kovacevic if (ret < 0) { 837cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Init session\n", 838cd255ccfSMarko Kovacevic ret); 839cd255ccfSMarko Kovacevic return ret; 840cd255ccfSMarko Kovacevic } 841cd255ccfSMarko Kovacevic 842cd255ccfSMarko Kovacevic ret = test_ops.prepare_op(); 843cd255ccfSMarko Kovacevic if (ret < 0) { 844cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", 845cd255ccfSMarko Kovacevic ret); 846cd255ccfSMarko Kovacevic return ret; 847cd255ccfSMarko Kovacevic } 848cd255ccfSMarko Kovacevic 849cd255ccfSMarko Kovacevic if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) { 850cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "Error: Failed enqueue\n"); 851cd255ccfSMarko Kovacevic return ret; 852cd255ccfSMarko Kovacevic } 853cd255ccfSMarko Kovacevic 854cd255ccfSMarko Kovacevic do { 855cd255ccfSMarko Kovacevic struct rte_crypto_op *deqd_op; 856cd255ccfSMarko Kovacevic 857cd255ccfSMarko Kovacevic n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 858cd255ccfSMarko Kovacevic 1); 859cd255ccfSMarko Kovacevic } while (n_deqd == 0); 860cd255ccfSMarko Kovacevic 861cd255ccfSMarko Kovacevic vec.status = env.op->status; 862cd255ccfSMarko Kovacevic 863cd255ccfSMarko Kovacevic rte_cryptodev_sym_session_clear(env.dev_id, env.sess); 864cd255ccfSMarko Kovacevic rte_cryptodev_sym_session_free(env.sess); 865cd255ccfSMarko Kovacevic env.sess = NULL; 866cd255ccfSMarko Kovacevic 867cd255ccfSMarko Kovacevic return ret; 868cd255ccfSMarko Kovacevic } 869cd255ccfSMarko Kovacevic 870cd255ccfSMarko Kovacevic static int 871cd255ccfSMarko Kovacevic fips_generic_test(void) 872cd255ccfSMarko Kovacevic { 873cd255ccfSMarko Kovacevic struct fips_val val; 874cd255ccfSMarko Kovacevic int ret; 875cd255ccfSMarko Kovacevic 876cd255ccfSMarko Kovacevic fips_test_write_one_case(); 877cd255ccfSMarko Kovacevic 878cd255ccfSMarko Kovacevic ret = fips_run_test(); 879cd255ccfSMarko Kovacevic if (ret < 0) { 880cd255ccfSMarko Kovacevic if (ret == -EPERM) { 881cd255ccfSMarko Kovacevic fprintf(info.fp_wr, "Bypass\n\n"); 882cd255ccfSMarko Kovacevic return 0; 883cd255ccfSMarko Kovacevic } 884cd255ccfSMarko Kovacevic 885cd255ccfSMarko Kovacevic return ret; 886cd255ccfSMarko Kovacevic } 887cd255ccfSMarko Kovacevic 888cd255ccfSMarko Kovacevic get_writeback_data(&val); 889cd255ccfSMarko Kovacevic 890cd255ccfSMarko Kovacevic switch (info.file_type) { 891cd255ccfSMarko Kovacevic case FIPS_TYPE_REQ: 892cd255ccfSMarko Kovacevic case FIPS_TYPE_RSP: 893cd255ccfSMarko Kovacevic if (info.parse_writeback == NULL) 894cd255ccfSMarko Kovacevic return -EPERM; 895cd255ccfSMarko Kovacevic ret = info.parse_writeback(&val); 896cd255ccfSMarko Kovacevic if (ret < 0) 897cd255ccfSMarko Kovacevic return ret; 898cd255ccfSMarko Kovacevic break; 899cd255ccfSMarko Kovacevic case FIPS_TYPE_FAX: 900cd255ccfSMarko Kovacevic if (info.kat_check == NULL) 901cd255ccfSMarko Kovacevic return -EPERM; 902cd255ccfSMarko Kovacevic ret = info.kat_check(&val); 903cd255ccfSMarko Kovacevic if (ret < 0) 904cd255ccfSMarko Kovacevic return ret; 905cd255ccfSMarko Kovacevic break; 906cd255ccfSMarko Kovacevic } 907cd255ccfSMarko Kovacevic 908cd255ccfSMarko Kovacevic fprintf(info.fp_wr, "\n"); 909cd255ccfSMarko Kovacevic 910cd255ccfSMarko Kovacevic return 0; 911cd255ccfSMarko Kovacevic } 912cd255ccfSMarko Kovacevic 913cd255ccfSMarko Kovacevic static int 914527cbf3dSMarko Kovacevic fips_mct_tdes_test(void) 915527cbf3dSMarko Kovacevic { 916527cbf3dSMarko Kovacevic #define TDES_BLOCK_SIZE 8 917527cbf3dSMarko Kovacevic #define TDES_EXTERN_ITER 400 918527cbf3dSMarko Kovacevic #define TDES_INTERN_ITER 10000 919527cbf3dSMarko Kovacevic struct fips_val val, val_key; 9209252e81aSMarko Kovacevic uint8_t prev_out[TDES_BLOCK_SIZE] = {0}; 9219252e81aSMarko Kovacevic uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0}; 9229252e81aSMarko Kovacevic uint8_t prev_in[TDES_BLOCK_SIZE] = {0}; 923527cbf3dSMarko Kovacevic uint32_t i, j, k; 924527cbf3dSMarko Kovacevic int ret; 925527cbf3dSMarko Kovacevic 926527cbf3dSMarko Kovacevic for (i = 0; i < TDES_EXTERN_ITER; i++) { 927527cbf3dSMarko Kovacevic if (i != 0) 928527cbf3dSMarko Kovacevic update_info_vec(i); 929527cbf3dSMarko Kovacevic 930527cbf3dSMarko Kovacevic fips_test_write_one_case(); 931527cbf3dSMarko Kovacevic 932527cbf3dSMarko Kovacevic for (j = 0; j < TDES_INTERN_ITER; j++) { 933527cbf3dSMarko Kovacevic ret = fips_run_test(); 934527cbf3dSMarko Kovacevic if (ret < 0) { 935527cbf3dSMarko Kovacevic if (ret == -EPERM) { 936527cbf3dSMarko Kovacevic fprintf(info.fp_wr, "Bypass\n"); 937527cbf3dSMarko Kovacevic return 0; 938527cbf3dSMarko Kovacevic } 939527cbf3dSMarko Kovacevic 940527cbf3dSMarko Kovacevic return ret; 941527cbf3dSMarko Kovacevic } 942527cbf3dSMarko Kovacevic 943527cbf3dSMarko Kovacevic get_writeback_data(&val); 944527cbf3dSMarko Kovacevic 945527cbf3dSMarko Kovacevic if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 946527cbf3dSMarko Kovacevic memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE); 947527cbf3dSMarko Kovacevic 948527cbf3dSMarko Kovacevic if (j == 0) { 949527cbf3dSMarko Kovacevic memcpy(prev_out, val.val, TDES_BLOCK_SIZE); 950527cbf3dSMarko Kovacevic 951527cbf3dSMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 952527cbf3dSMarko Kovacevic memcpy(vec.pt.val, vec.iv.val, 953527cbf3dSMarko Kovacevic TDES_BLOCK_SIZE); 954527cbf3dSMarko Kovacevic memcpy(vec.iv.val, val.val, 955527cbf3dSMarko Kovacevic TDES_BLOCK_SIZE); 956527cbf3dSMarko Kovacevic } else { 957527cbf3dSMarko Kovacevic memcpy(vec.iv.val, vec.ct.val, 958527cbf3dSMarko Kovacevic TDES_BLOCK_SIZE); 959527cbf3dSMarko Kovacevic memcpy(vec.ct.val, val.val, 960527cbf3dSMarko Kovacevic TDES_BLOCK_SIZE); 961527cbf3dSMarko Kovacevic } 962527cbf3dSMarko Kovacevic continue; 963527cbf3dSMarko Kovacevic } 964527cbf3dSMarko Kovacevic 965527cbf3dSMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 966527cbf3dSMarko Kovacevic memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE); 967527cbf3dSMarko Kovacevic memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 968527cbf3dSMarko Kovacevic } else { 969527cbf3dSMarko Kovacevic memcpy(vec.iv.val, vec.ct.val, TDES_BLOCK_SIZE); 970527cbf3dSMarko Kovacevic memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); 971527cbf3dSMarko Kovacevic } 972527cbf3dSMarko Kovacevic 973527cbf3dSMarko Kovacevic if (j == TDES_INTERN_ITER - 1) 974527cbf3dSMarko Kovacevic continue; 975527cbf3dSMarko Kovacevic 976527cbf3dSMarko Kovacevic memcpy(prev_out, val.val, TDES_BLOCK_SIZE); 977527cbf3dSMarko Kovacevic 978527cbf3dSMarko Kovacevic if (j == TDES_INTERN_ITER - 3) 979527cbf3dSMarko Kovacevic memcpy(prev_prev_out, val.val, TDES_BLOCK_SIZE); 980527cbf3dSMarko Kovacevic } 981527cbf3dSMarko Kovacevic 982527cbf3dSMarko Kovacevic info.parse_writeback(&val); 983527cbf3dSMarko Kovacevic fprintf(info.fp_wr, "\n"); 984527cbf3dSMarko Kovacevic 985527cbf3dSMarko Kovacevic if (i == TDES_EXTERN_ITER - 1) 986527cbf3dSMarko Kovacevic continue; 987527cbf3dSMarko Kovacevic 988527cbf3dSMarko Kovacevic /** update key */ 989527cbf3dSMarko Kovacevic memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 990527cbf3dSMarko Kovacevic 991527cbf3dSMarko Kovacevic if (info.interim_info.tdes_data.nb_keys == 0) { 992527cbf3dSMarko Kovacevic if (memcmp(val_key.val, val_key.val + 8, 8) == 0) 993527cbf3dSMarko Kovacevic info.interim_info.tdes_data.nb_keys = 1; 994527cbf3dSMarko Kovacevic else if (memcmp(val_key.val, val_key.val + 16, 8) == 0) 995527cbf3dSMarko Kovacevic info.interim_info.tdes_data.nb_keys = 2; 996527cbf3dSMarko Kovacevic else 997527cbf3dSMarko Kovacevic info.interim_info.tdes_data.nb_keys = 3; 998527cbf3dSMarko Kovacevic 999527cbf3dSMarko Kovacevic } 1000527cbf3dSMarko Kovacevic 1001527cbf3dSMarko Kovacevic for (k = 0; k < TDES_BLOCK_SIZE; k++) { 1002527cbf3dSMarko Kovacevic 1003527cbf3dSMarko Kovacevic switch (info.interim_info.tdes_data.nb_keys) { 1004527cbf3dSMarko Kovacevic case 3: 1005527cbf3dSMarko Kovacevic val_key.val[k] ^= val.val[k]; 1006527cbf3dSMarko Kovacevic val_key.val[k + 8] ^= prev_out[k]; 1007527cbf3dSMarko Kovacevic val_key.val[k + 16] ^= prev_prev_out[k]; 1008527cbf3dSMarko Kovacevic break; 1009527cbf3dSMarko Kovacevic case 2: 1010527cbf3dSMarko Kovacevic val_key.val[k] ^= val.val[k]; 1011527cbf3dSMarko Kovacevic val_key.val[k + 8] ^= prev_out[k]; 1012527cbf3dSMarko Kovacevic val_key.val[k + 16] ^= val.val[k]; 1013527cbf3dSMarko Kovacevic break; 1014527cbf3dSMarko Kovacevic default: /* case 1 */ 1015527cbf3dSMarko Kovacevic val_key.val[k] ^= val.val[k]; 1016527cbf3dSMarko Kovacevic val_key.val[k + 8] ^= val.val[k]; 1017527cbf3dSMarko Kovacevic val_key.val[k + 16] ^= val.val[k]; 1018527cbf3dSMarko Kovacevic break; 1019527cbf3dSMarko Kovacevic } 1020527cbf3dSMarko Kovacevic 1021527cbf3dSMarko Kovacevic } 1022527cbf3dSMarko Kovacevic 1023527cbf3dSMarko Kovacevic for (k = 0; k < 24; k++) 1024527cbf3dSMarko Kovacevic val_key.val[k] = (__builtin_popcount(val_key.val[k]) & 1025527cbf3dSMarko Kovacevic 0x1) ? 1026527cbf3dSMarko Kovacevic val_key.val[k] : (val_key.val[k] ^ 0x1); 1027527cbf3dSMarko Kovacevic 1028527cbf3dSMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1029527cbf3dSMarko Kovacevic memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE); 1030527cbf3dSMarko Kovacevic memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE); 1031527cbf3dSMarko Kovacevic } else { 1032527cbf3dSMarko Kovacevic memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE); 1033527cbf3dSMarko Kovacevic memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE); 1034527cbf3dSMarko Kovacevic } 1035527cbf3dSMarko Kovacevic } 1036527cbf3dSMarko Kovacevic 1037527cbf3dSMarko Kovacevic return 0; 1038527cbf3dSMarko Kovacevic } 1039527cbf3dSMarko Kovacevic 1040527cbf3dSMarko Kovacevic static int 1041cd255ccfSMarko Kovacevic fips_mct_aes_test(void) 1042cd255ccfSMarko Kovacevic { 1043cd255ccfSMarko Kovacevic #define AES_BLOCK_SIZE 16 1044cd255ccfSMarko Kovacevic #define AES_EXTERN_ITER 100 1045cd255ccfSMarko Kovacevic #define AES_INTERN_ITER 1000 1046cd255ccfSMarko Kovacevic struct fips_val val, val_key; 1047cd255ccfSMarko Kovacevic uint8_t prev_out[AES_BLOCK_SIZE] = {0}; 1048cd255ccfSMarko Kovacevic uint8_t prev_in[AES_BLOCK_SIZE] = {0}; 1049cd255ccfSMarko Kovacevic uint32_t i, j, k; 1050cd255ccfSMarko Kovacevic int ret; 1051cd255ccfSMarko Kovacevic 1052cd255ccfSMarko Kovacevic for (i = 0; i < AES_EXTERN_ITER; i++) { 1053cd255ccfSMarko Kovacevic if (i != 0) 1054cd255ccfSMarko Kovacevic update_info_vec(i); 1055cd255ccfSMarko Kovacevic 1056cd255ccfSMarko Kovacevic fips_test_write_one_case(); 1057cd255ccfSMarko Kovacevic 1058cd255ccfSMarko Kovacevic for (j = 0; j < AES_INTERN_ITER; j++) { 1059cd255ccfSMarko Kovacevic ret = fips_run_test(); 1060cd255ccfSMarko Kovacevic if (ret < 0) { 1061cd255ccfSMarko Kovacevic if (ret == -EPERM) { 1062cd255ccfSMarko Kovacevic fprintf(info.fp_wr, "Bypass\n"); 1063cd255ccfSMarko Kovacevic return 0; 1064cd255ccfSMarko Kovacevic } 1065cd255ccfSMarko Kovacevic 1066cd255ccfSMarko Kovacevic return ret; 1067cd255ccfSMarko Kovacevic } 1068cd255ccfSMarko Kovacevic 1069cd255ccfSMarko Kovacevic get_writeback_data(&val); 1070cd255ccfSMarko Kovacevic 1071cd255ccfSMarko Kovacevic if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1072cd255ccfSMarko Kovacevic memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE); 1073cd255ccfSMarko Kovacevic 1074cd255ccfSMarko Kovacevic if (j == 0) { 1075cd255ccfSMarko Kovacevic memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1076cd255ccfSMarko Kovacevic 1077cd255ccfSMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1078cd255ccfSMarko Kovacevic memcpy(vec.pt.val, vec.iv.val, 1079cd255ccfSMarko Kovacevic AES_BLOCK_SIZE); 1080cd255ccfSMarko Kovacevic memcpy(vec.iv.val, val.val, 1081cd255ccfSMarko Kovacevic AES_BLOCK_SIZE); 1082cd255ccfSMarko Kovacevic } else { 1083cd255ccfSMarko Kovacevic memcpy(vec.ct.val, vec.iv.val, 1084cd255ccfSMarko Kovacevic AES_BLOCK_SIZE); 1085cd255ccfSMarko Kovacevic memcpy(vec.iv.val, prev_in, 1086cd255ccfSMarko Kovacevic AES_BLOCK_SIZE); 1087cd255ccfSMarko Kovacevic } 1088cd255ccfSMarko Kovacevic continue; 1089cd255ccfSMarko Kovacevic } 1090cd255ccfSMarko Kovacevic 1091cd255ccfSMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 1092cd255ccfSMarko Kovacevic memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); 1093cd255ccfSMarko Kovacevic memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE); 1094cd255ccfSMarko Kovacevic } else { 1095cd255ccfSMarko Kovacevic memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE); 1096cd255ccfSMarko Kovacevic memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE); 1097cd255ccfSMarko Kovacevic } 1098cd255ccfSMarko Kovacevic 1099cd255ccfSMarko Kovacevic if (j == AES_INTERN_ITER - 1) 1100cd255ccfSMarko Kovacevic continue; 1101cd255ccfSMarko Kovacevic 1102cd255ccfSMarko Kovacevic memcpy(prev_out, val.val, AES_BLOCK_SIZE); 1103cd255ccfSMarko Kovacevic } 1104cd255ccfSMarko Kovacevic 1105cd255ccfSMarko Kovacevic info.parse_writeback(&val); 1106cd255ccfSMarko Kovacevic fprintf(info.fp_wr, "\n"); 1107cd255ccfSMarko Kovacevic 1108cd255ccfSMarko Kovacevic if (i == AES_EXTERN_ITER - 1) 1109cd255ccfSMarko Kovacevic continue; 1110cd255ccfSMarko Kovacevic 1111cd255ccfSMarko Kovacevic /** update key */ 1112cd255ccfSMarko Kovacevic memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key)); 1113cd255ccfSMarko Kovacevic for (k = 0; k < vec.cipher_auth.key.len; k++) { 1114cd255ccfSMarko Kovacevic switch (vec.cipher_auth.key.len) { 1115cd255ccfSMarko Kovacevic case 16: 1116cd255ccfSMarko Kovacevic val_key.val[k] ^= val.val[k]; 1117cd255ccfSMarko Kovacevic break; 1118cd255ccfSMarko Kovacevic case 24: 1119cd255ccfSMarko Kovacevic if (k < 8) 1120cd255ccfSMarko Kovacevic val_key.val[k] ^= prev_out[k + 8]; 1121cd255ccfSMarko Kovacevic else 1122cd255ccfSMarko Kovacevic val_key.val[k] ^= val.val[k - 8]; 1123cd255ccfSMarko Kovacevic break; 1124cd255ccfSMarko Kovacevic case 32: 1125cd255ccfSMarko Kovacevic if (k < 16) 1126cd255ccfSMarko Kovacevic val_key.val[k] ^= prev_out[k]; 1127cd255ccfSMarko Kovacevic else 1128cd255ccfSMarko Kovacevic val_key.val[k] ^= val.val[k - 16]; 1129cd255ccfSMarko Kovacevic break; 1130cd255ccfSMarko Kovacevic default: 1131cd255ccfSMarko Kovacevic return -1; 1132cd255ccfSMarko Kovacevic } 1133cd255ccfSMarko Kovacevic } 1134cd255ccfSMarko Kovacevic 1135cd255ccfSMarko Kovacevic if (info.op == FIPS_TEST_DEC_AUTH_VERIF) 1136cd255ccfSMarko Kovacevic memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE); 1137cd255ccfSMarko Kovacevic } 1138cd255ccfSMarko Kovacevic 1139cd255ccfSMarko Kovacevic return 0; 1140cd255ccfSMarko Kovacevic } 1141cd255ccfSMarko Kovacevic 1142cd255ccfSMarko Kovacevic static int 1143cd255ccfSMarko Kovacevic init_test_ops(void) 1144cd255ccfSMarko Kovacevic { 1145cd255ccfSMarko Kovacevic switch (info.algo) { 1146cd255ccfSMarko Kovacevic case FIPS_TEST_ALGO_AES: 1147cd255ccfSMarko Kovacevic test_ops.prepare_op = prepare_cipher_op; 1148cd255ccfSMarko Kovacevic test_ops.prepare_xform = prepare_aes_xform; 1149cd255ccfSMarko Kovacevic if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT) 1150cd255ccfSMarko Kovacevic test_ops.test = fips_mct_aes_test; 1151cd255ccfSMarko Kovacevic else 1152cd255ccfSMarko Kovacevic test_ops.test = fips_generic_test; 1153cd255ccfSMarko Kovacevic break; 1154f64adb67SMarko Kovacevic case FIPS_TEST_ALGO_HMAC: 1155f64adb67SMarko Kovacevic test_ops.prepare_op = prepare_auth_op; 1156f64adb67SMarko Kovacevic test_ops.prepare_xform = prepare_hmac_xform; 1157f64adb67SMarko Kovacevic test_ops.test = fips_generic_test; 1158f64adb67SMarko Kovacevic break; 1159527cbf3dSMarko Kovacevic case FIPS_TEST_ALGO_TDES: 1160527cbf3dSMarko Kovacevic test_ops.prepare_op = prepare_cipher_op; 1161527cbf3dSMarko Kovacevic test_ops.prepare_xform = prepare_tdes_xform; 1162527cbf3dSMarko Kovacevic if (info.interim_info.tdes_data.test_type == TDES_MCT) 1163527cbf3dSMarko Kovacevic test_ops.test = fips_mct_tdes_test; 1164527cbf3dSMarko Kovacevic else 1165527cbf3dSMarko Kovacevic test_ops.test = fips_generic_test; 1166527cbf3dSMarko Kovacevic break; 11674aaad299SMarko Kovacevic case FIPS_TEST_ALGO_AES_GCM: 11684aaad299SMarko Kovacevic test_ops.prepare_op = prepare_aead_op; 11694aaad299SMarko Kovacevic test_ops.prepare_xform = prepare_gcm_xform; 11704aaad299SMarko Kovacevic test_ops.test = fips_generic_test; 11714aaad299SMarko Kovacevic break; 1172ac026f46SMarko Kovacevic case FIPS_TEST_ALGO_AES_CMAC: 1173ac026f46SMarko Kovacevic test_ops.prepare_op = prepare_auth_op; 1174ac026f46SMarko Kovacevic test_ops.prepare_xform = prepare_cmac_xform; 1175ac026f46SMarko Kovacevic test_ops.test = fips_generic_test; 1176ac026f46SMarko Kovacevic break; 1177305921f4SMarko Kovacevic case FIPS_TEST_ALGO_AES_CCM: 1178305921f4SMarko Kovacevic test_ops.prepare_op = prepare_aead_op; 1179305921f4SMarko Kovacevic test_ops.prepare_xform = prepare_ccm_xform; 1180305921f4SMarko Kovacevic test_ops.test = fips_generic_test; 1181305921f4SMarko Kovacevic break; 1182cd255ccfSMarko Kovacevic default: 1183cd255ccfSMarko Kovacevic return -1; 1184cd255ccfSMarko Kovacevic } 1185cd255ccfSMarko Kovacevic 1186cd255ccfSMarko Kovacevic return 0; 1187cd255ccfSMarko Kovacevic } 1188cd255ccfSMarko Kovacevic 11893d0fad56SMarko Kovacevic static void 11903d0fad56SMarko Kovacevic print_test_block(void) 11913d0fad56SMarko Kovacevic { 11923d0fad56SMarko Kovacevic uint32_t i; 11933d0fad56SMarko Kovacevic 11943d0fad56SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) 11953d0fad56SMarko Kovacevic printf("%s\n", info.vec[i]); 11963d0fad56SMarko Kovacevic 11973d0fad56SMarko Kovacevic printf("\n"); 11983d0fad56SMarko Kovacevic } 11993d0fad56SMarko Kovacevic 12003d0fad56SMarko Kovacevic static int 12013d0fad56SMarko Kovacevic fips_test_one_file(void) 12023d0fad56SMarko Kovacevic { 12033d0fad56SMarko Kovacevic int fetch_ret = 0, ret; 12043d0fad56SMarko Kovacevic 1205cd255ccfSMarko Kovacevic 1206cd255ccfSMarko Kovacevic ret = init_test_ops(); 1207cd255ccfSMarko Kovacevic if (ret < 0) { 1208cd255ccfSMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret); 1209cd255ccfSMarko Kovacevic return ret; 1210cd255ccfSMarko Kovacevic } 1211cd255ccfSMarko Kovacevic 1212cd255ccfSMarko Kovacevic while (ret >= 0 && fetch_ret == 0) { 12133d0fad56SMarko Kovacevic fetch_ret = fips_test_fetch_one_block(); 12143d0fad56SMarko Kovacevic if (fetch_ret < 0) { 12153d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", 12163d0fad56SMarko Kovacevic fetch_ret); 12173d0fad56SMarko Kovacevic ret = fetch_ret; 12183d0fad56SMarko Kovacevic goto error_one_case; 12193d0fad56SMarko Kovacevic } 12203d0fad56SMarko Kovacevic 12213d0fad56SMarko Kovacevic if (info.nb_vec_lines == 0) { 12223d0fad56SMarko Kovacevic if (fetch_ret == -EOF) 12233d0fad56SMarko Kovacevic break; 12243d0fad56SMarko Kovacevic 12253d0fad56SMarko Kovacevic fprintf(info.fp_wr, "\n"); 12263d0fad56SMarko Kovacevic continue; 12273d0fad56SMarko Kovacevic } 12283d0fad56SMarko Kovacevic 12293d0fad56SMarko Kovacevic ret = fips_test_parse_one_case(); 12303d0fad56SMarko Kovacevic switch (ret) { 12313d0fad56SMarko Kovacevic case 0: 1232cd255ccfSMarko Kovacevic ret = test_ops.test(); 12333d0fad56SMarko Kovacevic if (ret == 0) 12343d0fad56SMarko Kovacevic break; 12353d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: test block\n", 12363d0fad56SMarko Kovacevic ret); 12373d0fad56SMarko Kovacevic goto error_one_case; 12383d0fad56SMarko Kovacevic case 1: 12393d0fad56SMarko Kovacevic break; 12403d0fad56SMarko Kovacevic default: 12413d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Error %i: Parse block\n", 12423d0fad56SMarko Kovacevic ret); 12433d0fad56SMarko Kovacevic goto error_one_case; 12443d0fad56SMarko Kovacevic } 12453d0fad56SMarko Kovacevic 12463d0fad56SMarko Kovacevic continue; 12473d0fad56SMarko Kovacevic error_one_case: 12483d0fad56SMarko Kovacevic print_test_block(); 12493d0fad56SMarko Kovacevic } 12503d0fad56SMarko Kovacevic 12513d0fad56SMarko Kovacevic fips_test_clear(); 12523d0fad56SMarko Kovacevic 1253cd255ccfSMarko Kovacevic return ret; 1254cd255ccfSMarko Kovacevic 12553d0fad56SMarko Kovacevic } 1256