1*3d0fad56SMarko Kovacevic /* SPDX-License-Identifier: BSD-3-Clause 2*3d0fad56SMarko Kovacevic * Copyright(c) 2018 Intel Corporation 3*3d0fad56SMarko Kovacevic */ 4*3d0fad56SMarko Kovacevic 5*3d0fad56SMarko Kovacevic #include <stdio.h> 6*3d0fad56SMarko Kovacevic #include <string.h> 7*3d0fad56SMarko Kovacevic 8*3d0fad56SMarko Kovacevic #include <rte_string_fns.h> 9*3d0fad56SMarko Kovacevic #include <rte_cryptodev.h> 10*3d0fad56SMarko Kovacevic #include <rte_malloc.h> 11*3d0fad56SMarko Kovacevic 12*3d0fad56SMarko Kovacevic #include "fips_validation.h" 13*3d0fad56SMarko Kovacevic 14*3d0fad56SMarko Kovacevic #define skip_white_spaces(pos) \ 15*3d0fad56SMarko Kovacevic ({ \ 16*3d0fad56SMarko Kovacevic __typeof__(pos) _p = (pos); \ 17*3d0fad56SMarko Kovacevic for ( ; isspace(*_p); _p++) \ 18*3d0fad56SMarko Kovacevic ; \ 19*3d0fad56SMarko Kovacevic _p; \ 20*3d0fad56SMarko Kovacevic }) 21*3d0fad56SMarko Kovacevic 22*3d0fad56SMarko Kovacevic static int 23*3d0fad56SMarko Kovacevic get_file_line(void) 24*3d0fad56SMarko Kovacevic { 25*3d0fad56SMarko Kovacevic FILE *fp = info.fp_rd; 26*3d0fad56SMarko Kovacevic char *line = info.one_line_text; 27*3d0fad56SMarko Kovacevic int ret; 28*3d0fad56SMarko Kovacevic uint32_t loc = 0; 29*3d0fad56SMarko Kovacevic 30*3d0fad56SMarko Kovacevic memset(line, 0, MAX_LINE_CHAR); 31*3d0fad56SMarko Kovacevic while ((ret = fgetc(fp)) != EOF) { 32*3d0fad56SMarko Kovacevic char c = (char)ret; 33*3d0fad56SMarko Kovacevic 34*3d0fad56SMarko Kovacevic if (loc >= MAX_LINE_CHAR - 1) 35*3d0fad56SMarko Kovacevic return -ENOMEM; 36*3d0fad56SMarko Kovacevic if (c == '\n') 37*3d0fad56SMarko Kovacevic break; 38*3d0fad56SMarko Kovacevic line[loc++] = c; 39*3d0fad56SMarko Kovacevic } 40*3d0fad56SMarko Kovacevic 41*3d0fad56SMarko Kovacevic if (ret == EOF) 42*3d0fad56SMarko Kovacevic return -EOF; 43*3d0fad56SMarko Kovacevic 44*3d0fad56SMarko Kovacevic return 0; 45*3d0fad56SMarko Kovacevic } 46*3d0fad56SMarko Kovacevic 47*3d0fad56SMarko Kovacevic int 48*3d0fad56SMarko Kovacevic fips_test_fetch_one_block(void) 49*3d0fad56SMarko Kovacevic { 50*3d0fad56SMarko Kovacevic size_t size; 51*3d0fad56SMarko Kovacevic int ret = 0; 52*3d0fad56SMarko Kovacevic uint32_t i; 53*3d0fad56SMarko Kovacevic 54*3d0fad56SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) { 55*3d0fad56SMarko Kovacevic free(info.vec[i]); 56*3d0fad56SMarko Kovacevic info.vec[i] = NULL; 57*3d0fad56SMarko Kovacevic } 58*3d0fad56SMarko Kovacevic 59*3d0fad56SMarko Kovacevic i = 0; 60*3d0fad56SMarko Kovacevic do { 61*3d0fad56SMarko Kovacevic if (i >= MAX_LINE_PER_VECTOR) { 62*3d0fad56SMarko Kovacevic ret = -ENOMEM; 63*3d0fad56SMarko Kovacevic goto error_exit; 64*3d0fad56SMarko Kovacevic } 65*3d0fad56SMarko Kovacevic 66*3d0fad56SMarko Kovacevic ret = get_file_line(); 67*3d0fad56SMarko Kovacevic size = strlen(info.one_line_text); 68*3d0fad56SMarko Kovacevic if (size == 0) 69*3d0fad56SMarko Kovacevic break; 70*3d0fad56SMarko Kovacevic 71*3d0fad56SMarko Kovacevic info.vec[i] = calloc(1, size + 5); 72*3d0fad56SMarko Kovacevic if (info.vec[i] == NULL) 73*3d0fad56SMarko Kovacevic goto error_exit; 74*3d0fad56SMarko Kovacevic 75*3d0fad56SMarko Kovacevic strlcpy(info.vec[i], info.one_line_text, size + 1); 76*3d0fad56SMarko Kovacevic i++; 77*3d0fad56SMarko Kovacevic } while (ret == 0); 78*3d0fad56SMarko Kovacevic 79*3d0fad56SMarko Kovacevic info.nb_vec_lines = i; 80*3d0fad56SMarko Kovacevic 81*3d0fad56SMarko Kovacevic return ret; 82*3d0fad56SMarko Kovacevic 83*3d0fad56SMarko Kovacevic error_exit: 84*3d0fad56SMarko Kovacevic for (i = 0; i < MAX_LINE_PER_VECTOR; i++) 85*3d0fad56SMarko Kovacevic if (info.vec[i] != NULL) { 86*3d0fad56SMarko Kovacevic free(info.vec[i]); 87*3d0fad56SMarko Kovacevic info.vec[i] = NULL; 88*3d0fad56SMarko Kovacevic } 89*3d0fad56SMarko Kovacevic 90*3d0fad56SMarko Kovacevic info.nb_vec_lines = 0; 91*3d0fad56SMarko Kovacevic 92*3d0fad56SMarko Kovacevic return -ENOMEM; 93*3d0fad56SMarko Kovacevic } 94*3d0fad56SMarko Kovacevic 95*3d0fad56SMarko Kovacevic static int 96*3d0fad56SMarko Kovacevic fips_test_parse_header(void) 97*3d0fad56SMarko Kovacevic { 98*3d0fad56SMarko Kovacevic uint32_t i; 99*3d0fad56SMarko Kovacevic char *tmp; 100*3d0fad56SMarko Kovacevic int ret; 101*3d0fad56SMarko Kovacevic time_t t = time(NULL); 102*3d0fad56SMarko Kovacevic struct tm *tm_now = localtime(&t); 103*3d0fad56SMarko Kovacevic 104*3d0fad56SMarko Kovacevic ret = fips_test_fetch_one_block(); 105*3d0fad56SMarko Kovacevic if (ret < 0) 106*3d0fad56SMarko Kovacevic return ret; 107*3d0fad56SMarko Kovacevic 108*3d0fad56SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) { 109*3d0fad56SMarko Kovacevic 110*3d0fad56SMarko Kovacevic tmp = strstr(info.vec[i], "# Config info for "); 111*3d0fad56SMarko Kovacevic if (tmp != NULL) { 112*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s%s\n", "# Config info for DPDK Cryptodev ", 113*3d0fad56SMarko Kovacevic info.device_name); 114*3d0fad56SMarko Kovacevic continue; 115*3d0fad56SMarko Kovacevic } 116*3d0fad56SMarko Kovacevic 117*3d0fad56SMarko Kovacevic tmp = strstr(info.vec[i], "# HMAC information for "); 118*3d0fad56SMarko Kovacevic if (tmp != NULL) { 119*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s%s\n", "# HMAC information for " 120*3d0fad56SMarko Kovacevic "DPDK Cryptodev ", 121*3d0fad56SMarko Kovacevic info.device_name); 122*3d0fad56SMarko Kovacevic continue; 123*3d0fad56SMarko Kovacevic } 124*3d0fad56SMarko Kovacevic 125*3d0fad56SMarko Kovacevic tmp = strstr(info.vec[i], "# Config Info for : "); 126*3d0fad56SMarko Kovacevic if (tmp != NULL) { 127*3d0fad56SMarko Kovacevic 128*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s%s\n", "# Config Info for DPDK Cryptodev : ", 129*3d0fad56SMarko Kovacevic info.device_name); 130*3d0fad56SMarko Kovacevic continue; 131*3d0fad56SMarko Kovacevic } 132*3d0fad56SMarko Kovacevic 133*3d0fad56SMarko Kovacevic tmp = strstr(info.vec[i], "# information for "); 134*3d0fad56SMarko Kovacevic if (tmp != NULL) { 135*3d0fad56SMarko Kovacevic 136*3d0fad56SMarko Kovacevic char tmp_output[128] = {0}; 137*3d0fad56SMarko Kovacevic 138*3d0fad56SMarko Kovacevic strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1); 139*3d0fad56SMarko Kovacevic 140*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s%s%s\n", tmp_output, 141*3d0fad56SMarko Kovacevic "information for DPDK Cryptodev ", 142*3d0fad56SMarko Kovacevic info.device_name); 143*3d0fad56SMarko Kovacevic continue; 144*3d0fad56SMarko Kovacevic } 145*3d0fad56SMarko Kovacevic 146*3d0fad56SMarko Kovacevic tmp = strstr(info.vec[i], " test information for "); 147*3d0fad56SMarko Kovacevic if (tmp != NULL) { 148*3d0fad56SMarko Kovacevic char tmp_output[128] = {0}; 149*3d0fad56SMarko Kovacevic 150*3d0fad56SMarko Kovacevic strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1); 151*3d0fad56SMarko Kovacevic 152*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s%s%s\n", tmp_output, 153*3d0fad56SMarko Kovacevic "test information for DPDK Cryptodev ", 154*3d0fad56SMarko Kovacevic info.device_name); 155*3d0fad56SMarko Kovacevic continue; 156*3d0fad56SMarko Kovacevic } 157*3d0fad56SMarko Kovacevic 158*3d0fad56SMarko Kovacevic if (i == info.nb_vec_lines - 1) { 159*3d0fad56SMarko Kovacevic /** update the time as current time, write to file */ 160*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s%s\n", "# Generated on ", 161*3d0fad56SMarko Kovacevic asctime(tm_now)); 162*3d0fad56SMarko Kovacevic continue; 163*3d0fad56SMarko Kovacevic } 164*3d0fad56SMarko Kovacevic 165*3d0fad56SMarko Kovacevic /* to this point, no field need to update, 166*3d0fad56SMarko Kovacevic * only copy to rsp file 167*3d0fad56SMarko Kovacevic */ 168*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s\n", info.vec[i]); 169*3d0fad56SMarko Kovacevic } 170*3d0fad56SMarko Kovacevic 171*3d0fad56SMarko Kovacevic return 0; 172*3d0fad56SMarko Kovacevic } 173*3d0fad56SMarko Kovacevic 174*3d0fad56SMarko Kovacevic static int 175*3d0fad56SMarko Kovacevic parse_file_type(const char *path) 176*3d0fad56SMarko Kovacevic { 177*3d0fad56SMarko Kovacevic const char *tmp = path + strlen(path) - 3; 178*3d0fad56SMarko Kovacevic 179*3d0fad56SMarko Kovacevic if (strstr(tmp, REQ_FILE_PERFIX)) 180*3d0fad56SMarko Kovacevic info.file_type = FIPS_TYPE_REQ; 181*3d0fad56SMarko Kovacevic else if (strstr(tmp, RSP_FILE_PERFIX)) 182*3d0fad56SMarko Kovacevic info.file_type = FIPS_TYPE_RSP; 183*3d0fad56SMarko Kovacevic else if (strstr(path, FAX_FILE_PERFIX)) 184*3d0fad56SMarko Kovacevic info.file_type = FIPS_TYPE_FAX; 185*3d0fad56SMarko Kovacevic else 186*3d0fad56SMarko Kovacevic return -EINVAL; 187*3d0fad56SMarko Kovacevic 188*3d0fad56SMarko Kovacevic return 0; 189*3d0fad56SMarko Kovacevic } 190*3d0fad56SMarko Kovacevic 191*3d0fad56SMarko Kovacevic int 192*3d0fad56SMarko Kovacevic fips_test_init(const char *req_file_path, const char *rsp_file_path, 193*3d0fad56SMarko Kovacevic const char *device_name) 194*3d0fad56SMarko Kovacevic { 195*3d0fad56SMarko Kovacevic if (strcmp(req_file_path, rsp_file_path) == 0) { 196*3d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "File paths cannot be the same\n"); 197*3d0fad56SMarko Kovacevic return -EINVAL; 198*3d0fad56SMarko Kovacevic } 199*3d0fad56SMarko Kovacevic 200*3d0fad56SMarko Kovacevic fips_test_clear(); 201*3d0fad56SMarko Kovacevic 202*3d0fad56SMarko Kovacevic info.algo = FIPS_TEST_ALGO_MAX; 203*3d0fad56SMarko Kovacevic if (parse_file_type(req_file_path) < 0) { 204*3d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "File %s type not supported\n", 205*3d0fad56SMarko Kovacevic req_file_path); 206*3d0fad56SMarko Kovacevic return -EINVAL; 207*3d0fad56SMarko Kovacevic } 208*3d0fad56SMarko Kovacevic 209*3d0fad56SMarko Kovacevic info.fp_rd = fopen(req_file_path, "r"); 210*3d0fad56SMarko Kovacevic if (!info.fp_rd) { 211*3d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Cannot open file %s\n", req_file_path); 212*3d0fad56SMarko Kovacevic return -EINVAL; 213*3d0fad56SMarko Kovacevic } 214*3d0fad56SMarko Kovacevic 215*3d0fad56SMarko Kovacevic info.fp_wr = fopen(rsp_file_path, "w"); 216*3d0fad56SMarko Kovacevic if (!info.fp_wr) { 217*3d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Cannot open file %s\n", rsp_file_path); 218*3d0fad56SMarko Kovacevic return -EINVAL; 219*3d0fad56SMarko Kovacevic } 220*3d0fad56SMarko Kovacevic 221*3d0fad56SMarko Kovacevic info.one_line_text = calloc(1, MAX_LINE_CHAR); 222*3d0fad56SMarko Kovacevic if (!info.one_line_text) { 223*3d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Insufficient memory\n"); 224*3d0fad56SMarko Kovacevic return -ENOMEM; 225*3d0fad56SMarko Kovacevic } 226*3d0fad56SMarko Kovacevic 227*3d0fad56SMarko Kovacevic strlcpy(info.device_name, device_name, sizeof(info.device_name)); 228*3d0fad56SMarko Kovacevic 229*3d0fad56SMarko Kovacevic if (fips_test_parse_header() < 0) { 230*3d0fad56SMarko Kovacevic RTE_LOG(ERR, USER1, "Failed parsing header\n"); 231*3d0fad56SMarko Kovacevic return -1; 232*3d0fad56SMarko Kovacevic } 233*3d0fad56SMarko Kovacevic 234*3d0fad56SMarko Kovacevic return 0; 235*3d0fad56SMarko Kovacevic } 236*3d0fad56SMarko Kovacevic 237*3d0fad56SMarko Kovacevic void 238*3d0fad56SMarko Kovacevic fips_test_clear(void) 239*3d0fad56SMarko Kovacevic { 240*3d0fad56SMarko Kovacevic if (info.fp_rd) 241*3d0fad56SMarko Kovacevic fclose(info.fp_rd); 242*3d0fad56SMarko Kovacevic if (info.fp_wr) 243*3d0fad56SMarko Kovacevic fclose(info.fp_wr); 244*3d0fad56SMarko Kovacevic if (info.one_line_text) 245*3d0fad56SMarko Kovacevic free(info.one_line_text); 246*3d0fad56SMarko Kovacevic if (info.nb_vec_lines) { 247*3d0fad56SMarko Kovacevic uint32_t i; 248*3d0fad56SMarko Kovacevic 249*3d0fad56SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) 250*3d0fad56SMarko Kovacevic free(info.vec[i]); 251*3d0fad56SMarko Kovacevic } 252*3d0fad56SMarko Kovacevic 253*3d0fad56SMarko Kovacevic memset(&info, 0, sizeof(info)); 254*3d0fad56SMarko Kovacevic } 255*3d0fad56SMarko Kovacevic 256*3d0fad56SMarko Kovacevic int 257*3d0fad56SMarko Kovacevic fips_test_parse_one_case(void) 258*3d0fad56SMarko Kovacevic { 259*3d0fad56SMarko Kovacevic uint32_t i, j = 0; 260*3d0fad56SMarko Kovacevic uint32_t is_interim = 0; 261*3d0fad56SMarko Kovacevic int ret; 262*3d0fad56SMarko Kovacevic 263*3d0fad56SMarko Kovacevic if (info.interim_callbacks) { 264*3d0fad56SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) { 265*3d0fad56SMarko Kovacevic for (j = 0; info.interim_callbacks[j].key != NULL; j++) 266*3d0fad56SMarko Kovacevic if (strstr(info.vec[i], 267*3d0fad56SMarko Kovacevic info.interim_callbacks[j].key)) { 268*3d0fad56SMarko Kovacevic is_interim = 1; 269*3d0fad56SMarko Kovacevic 270*3d0fad56SMarko Kovacevic ret = info.interim_callbacks[j].cb( 271*3d0fad56SMarko Kovacevic info.interim_callbacks[j].key, 272*3d0fad56SMarko Kovacevic info.vec[i], 273*3d0fad56SMarko Kovacevic info.interim_callbacks[j].val); 274*3d0fad56SMarko Kovacevic if (ret < 0) 275*3d0fad56SMarko Kovacevic return ret; 276*3d0fad56SMarko Kovacevic } 277*3d0fad56SMarko Kovacevic } 278*3d0fad56SMarko Kovacevic } 279*3d0fad56SMarko Kovacevic 280*3d0fad56SMarko Kovacevic if (is_interim) { 281*3d0fad56SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) 282*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s\n", info.vec[i]); 283*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "\n"); 284*3d0fad56SMarko Kovacevic return 1; 285*3d0fad56SMarko Kovacevic } 286*3d0fad56SMarko Kovacevic 287*3d0fad56SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) { 288*3d0fad56SMarko Kovacevic for (j = 0; info.callbacks[j].key != NULL; j++) 289*3d0fad56SMarko Kovacevic if (strstr(info.vec[i], info.callbacks[j].key)) { 290*3d0fad56SMarko Kovacevic ret = info.callbacks[j].cb( 291*3d0fad56SMarko Kovacevic info.callbacks[j].key, 292*3d0fad56SMarko Kovacevic info.vec[i], info.callbacks[j].val); 293*3d0fad56SMarko Kovacevic if (ret < 0) 294*3d0fad56SMarko Kovacevic return ret; 295*3d0fad56SMarko Kovacevic break; 296*3d0fad56SMarko Kovacevic } 297*3d0fad56SMarko Kovacevic } 298*3d0fad56SMarko Kovacevic 299*3d0fad56SMarko Kovacevic return 0; 300*3d0fad56SMarko Kovacevic } 301*3d0fad56SMarko Kovacevic 302*3d0fad56SMarko Kovacevic void 303*3d0fad56SMarko Kovacevic fips_test_write_one_case(void) 304*3d0fad56SMarko Kovacevic { 305*3d0fad56SMarko Kovacevic uint32_t i; 306*3d0fad56SMarko Kovacevic 307*3d0fad56SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) 308*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s\n", info.vec[i]); 309*3d0fad56SMarko Kovacevic } 310*3d0fad56SMarko Kovacevic 311*3d0fad56SMarko Kovacevic static int 312*3d0fad56SMarko Kovacevic parser_read_uint64_hex(uint64_t *value, const char *p) 313*3d0fad56SMarko Kovacevic { 314*3d0fad56SMarko Kovacevic char *next; 315*3d0fad56SMarko Kovacevic uint64_t val; 316*3d0fad56SMarko Kovacevic 317*3d0fad56SMarko Kovacevic p = skip_white_spaces(p); 318*3d0fad56SMarko Kovacevic 319*3d0fad56SMarko Kovacevic val = strtoul(p, &next, 16); 320*3d0fad56SMarko Kovacevic if (p == next) 321*3d0fad56SMarko Kovacevic return -EINVAL; 322*3d0fad56SMarko Kovacevic 323*3d0fad56SMarko Kovacevic p = skip_white_spaces(next); 324*3d0fad56SMarko Kovacevic if (*p != '\0') 325*3d0fad56SMarko Kovacevic return -EINVAL; 326*3d0fad56SMarko Kovacevic 327*3d0fad56SMarko Kovacevic *value = val; 328*3d0fad56SMarko Kovacevic return 0; 329*3d0fad56SMarko Kovacevic } 330*3d0fad56SMarko Kovacevic 331*3d0fad56SMarko Kovacevic int 332*3d0fad56SMarko Kovacevic parser_read_uint8_hex(uint8_t *value, const char *p) 333*3d0fad56SMarko Kovacevic { 334*3d0fad56SMarko Kovacevic uint64_t val = 0; 335*3d0fad56SMarko Kovacevic int ret = parser_read_uint64_hex(&val, p); 336*3d0fad56SMarko Kovacevic 337*3d0fad56SMarko Kovacevic if (ret < 0) 338*3d0fad56SMarko Kovacevic return ret; 339*3d0fad56SMarko Kovacevic 340*3d0fad56SMarko Kovacevic if (val > UINT8_MAX) 341*3d0fad56SMarko Kovacevic return -ERANGE; 342*3d0fad56SMarko Kovacevic 343*3d0fad56SMarko Kovacevic *value = val; 344*3d0fad56SMarko Kovacevic return 0; 345*3d0fad56SMarko Kovacevic } 346*3d0fad56SMarko Kovacevic 347*3d0fad56SMarko Kovacevic int 348*3d0fad56SMarko Kovacevic parse_uint8_known_len_hex_str(const char *key, char *src, struct fips_val *val) 349*3d0fad56SMarko Kovacevic { 350*3d0fad56SMarko Kovacevic struct fips_val tmp_val = {0}; 351*3d0fad56SMarko Kovacevic uint32_t len = val->len; 352*3d0fad56SMarko Kovacevic int ret; 353*3d0fad56SMarko Kovacevic 354*3d0fad56SMarko Kovacevic if (len == 0) { 355*3d0fad56SMarko Kovacevic if (val->val != NULL) { 356*3d0fad56SMarko Kovacevic rte_free(val->val); 357*3d0fad56SMarko Kovacevic val->val = NULL; 358*3d0fad56SMarko Kovacevic } 359*3d0fad56SMarko Kovacevic 360*3d0fad56SMarko Kovacevic return 0; 361*3d0fad56SMarko Kovacevic } 362*3d0fad56SMarko Kovacevic 363*3d0fad56SMarko Kovacevic ret = parse_uint8_hex_str(key, src, &tmp_val); 364*3d0fad56SMarko Kovacevic if (ret < 0) 365*3d0fad56SMarko Kovacevic return ret; 366*3d0fad56SMarko Kovacevic 367*3d0fad56SMarko Kovacevic if (tmp_val.len == val->len) { 368*3d0fad56SMarko Kovacevic val->val = tmp_val.val; 369*3d0fad56SMarko Kovacevic return 0; 370*3d0fad56SMarko Kovacevic } 371*3d0fad56SMarko Kovacevic 372*3d0fad56SMarko Kovacevic if (tmp_val.len < val->len) { 373*3d0fad56SMarko Kovacevic rte_free(tmp_val.val); 374*3d0fad56SMarko Kovacevic return -EINVAL; 375*3d0fad56SMarko Kovacevic } 376*3d0fad56SMarko Kovacevic 377*3d0fad56SMarko Kovacevic val->val = rte_zmalloc(NULL, val->len, 0); 378*3d0fad56SMarko Kovacevic if (!val->val) { 379*3d0fad56SMarko Kovacevic rte_free(tmp_val.val); 380*3d0fad56SMarko Kovacevic memset(val, 0, sizeof(*val)); 381*3d0fad56SMarko Kovacevic return -ENOMEM; 382*3d0fad56SMarko Kovacevic } 383*3d0fad56SMarko Kovacevic 384*3d0fad56SMarko Kovacevic memcpy(val->val, tmp_val.val, val->len); 385*3d0fad56SMarko Kovacevic rte_free(tmp_val.val); 386*3d0fad56SMarko Kovacevic 387*3d0fad56SMarko Kovacevic return 0; 388*3d0fad56SMarko Kovacevic } 389*3d0fad56SMarko Kovacevic 390*3d0fad56SMarko Kovacevic int 391*3d0fad56SMarko Kovacevic parse_uint8_hex_str(const char *key, char *src, struct fips_val *val) 392*3d0fad56SMarko Kovacevic { 393*3d0fad56SMarko Kovacevic uint32_t len, j; 394*3d0fad56SMarko Kovacevic 395*3d0fad56SMarko Kovacevic src += strlen(key); 396*3d0fad56SMarko Kovacevic 397*3d0fad56SMarko Kovacevic len = strlen(src) / 2; 398*3d0fad56SMarko Kovacevic 399*3d0fad56SMarko Kovacevic if (val->val) { 400*3d0fad56SMarko Kovacevic rte_free(val->val); 401*3d0fad56SMarko Kovacevic val->val = NULL; 402*3d0fad56SMarko Kovacevic } 403*3d0fad56SMarko Kovacevic 404*3d0fad56SMarko Kovacevic val->val = rte_zmalloc(NULL, len, 0); 405*3d0fad56SMarko Kovacevic if (!val->val) 406*3d0fad56SMarko Kovacevic return -ENOMEM; 407*3d0fad56SMarko Kovacevic 408*3d0fad56SMarko Kovacevic for (j = 0; j < len; j++) { 409*3d0fad56SMarko Kovacevic char byte[3] = {src[j * 2], src[j * 2 + 1], '\0'}; 410*3d0fad56SMarko Kovacevic 411*3d0fad56SMarko Kovacevic if (parser_read_uint8_hex(&val->val[j], byte) < 0) { 412*3d0fad56SMarko Kovacevic rte_free(val->val); 413*3d0fad56SMarko Kovacevic memset(val, 0, sizeof(*val)); 414*3d0fad56SMarko Kovacevic return -EINVAL; 415*3d0fad56SMarko Kovacevic } 416*3d0fad56SMarko Kovacevic } 417*3d0fad56SMarko Kovacevic 418*3d0fad56SMarko Kovacevic val->len = len; 419*3d0fad56SMarko Kovacevic 420*3d0fad56SMarko Kovacevic return 0; 421*3d0fad56SMarko Kovacevic } 422*3d0fad56SMarko Kovacevic 423*3d0fad56SMarko Kovacevic int 424*3d0fad56SMarko Kovacevic parser_read_uint32_val(const char *key, char *src, struct fips_val *val) 425*3d0fad56SMarko Kovacevic { 426*3d0fad56SMarko Kovacevic char *data = src + strlen(key); 427*3d0fad56SMarko Kovacevic size_t data_len = strlen(data); 428*3d0fad56SMarko Kovacevic int ret; 429*3d0fad56SMarko Kovacevic 430*3d0fad56SMarko Kovacevic if (data[data_len - 1] == ']') { 431*3d0fad56SMarko Kovacevic char *tmp_data = calloc(1, data_len + 1); 432*3d0fad56SMarko Kovacevic 433*3d0fad56SMarko Kovacevic if (tmp_data == NULL) 434*3d0fad56SMarko Kovacevic return -ENOMEM; 435*3d0fad56SMarko Kovacevic 436*3d0fad56SMarko Kovacevic strlcpy(tmp_data, data, data_len); 437*3d0fad56SMarko Kovacevic 438*3d0fad56SMarko Kovacevic ret = parser_read_uint32(&val->len, tmp_data); 439*3d0fad56SMarko Kovacevic 440*3d0fad56SMarko Kovacevic free(tmp_data); 441*3d0fad56SMarko Kovacevic } else 442*3d0fad56SMarko Kovacevic ret = parser_read_uint32(&val->len, data); 443*3d0fad56SMarko Kovacevic 444*3d0fad56SMarko Kovacevic return ret; 445*3d0fad56SMarko Kovacevic } 446*3d0fad56SMarko Kovacevic 447*3d0fad56SMarko Kovacevic int 448*3d0fad56SMarko Kovacevic parser_read_uint32_bit_val(const char *key, char *src, struct fips_val *val) 449*3d0fad56SMarko Kovacevic { 450*3d0fad56SMarko Kovacevic int ret; 451*3d0fad56SMarko Kovacevic 452*3d0fad56SMarko Kovacevic ret = parser_read_uint32_val(key, src, val); 453*3d0fad56SMarko Kovacevic 454*3d0fad56SMarko Kovacevic if (ret < 0) 455*3d0fad56SMarko Kovacevic return ret; 456*3d0fad56SMarko Kovacevic 457*3d0fad56SMarko Kovacevic val->len /= 8; 458*3d0fad56SMarko Kovacevic 459*3d0fad56SMarko Kovacevic return 0; 460*3d0fad56SMarko Kovacevic } 461*3d0fad56SMarko Kovacevic 462*3d0fad56SMarko Kovacevic int 463*3d0fad56SMarko Kovacevic writeback_hex_str(const char *key, char *dst, struct fips_val *val) 464*3d0fad56SMarko Kovacevic { 465*3d0fad56SMarko Kovacevic char *str = dst; 466*3d0fad56SMarko Kovacevic uint32_t len; 467*3d0fad56SMarko Kovacevic 468*3d0fad56SMarko Kovacevic str += strlen(key); 469*3d0fad56SMarko Kovacevic 470*3d0fad56SMarko Kovacevic for (len = 0; len < val->len; len++) 471*3d0fad56SMarko Kovacevic snprintf(str + len * 2, 255, "%02x", val->val[len]); 472*3d0fad56SMarko Kovacevic 473*3d0fad56SMarko Kovacevic return 0; 474*3d0fad56SMarko Kovacevic } 475*3d0fad56SMarko Kovacevic 476*3d0fad56SMarko Kovacevic static int 477*3d0fad56SMarko Kovacevic parser_read_uint64(uint64_t *value, const char *p) 478*3d0fad56SMarko Kovacevic { 479*3d0fad56SMarko Kovacevic char *next; 480*3d0fad56SMarko Kovacevic uint64_t val; 481*3d0fad56SMarko Kovacevic 482*3d0fad56SMarko Kovacevic p = skip_white_spaces(p); 483*3d0fad56SMarko Kovacevic if (!isdigit(*p)) 484*3d0fad56SMarko Kovacevic return -EINVAL; 485*3d0fad56SMarko Kovacevic 486*3d0fad56SMarko Kovacevic val = strtoul(p, &next, 10); 487*3d0fad56SMarko Kovacevic if (p == next) 488*3d0fad56SMarko Kovacevic return -EINVAL; 489*3d0fad56SMarko Kovacevic 490*3d0fad56SMarko Kovacevic p = next; 491*3d0fad56SMarko Kovacevic switch (*p) { 492*3d0fad56SMarko Kovacevic case 'T': 493*3d0fad56SMarko Kovacevic val *= 1024ULL; 494*3d0fad56SMarko Kovacevic /* fall through */ 495*3d0fad56SMarko Kovacevic case 'G': 496*3d0fad56SMarko Kovacevic val *= 1024ULL; 497*3d0fad56SMarko Kovacevic /* fall through */ 498*3d0fad56SMarko Kovacevic case 'M': 499*3d0fad56SMarko Kovacevic val *= 1024ULL; 500*3d0fad56SMarko Kovacevic /* fall through */ 501*3d0fad56SMarko Kovacevic case 'k': 502*3d0fad56SMarko Kovacevic case 'K': 503*3d0fad56SMarko Kovacevic val *= 1024ULL; 504*3d0fad56SMarko Kovacevic p++; 505*3d0fad56SMarko Kovacevic break; 506*3d0fad56SMarko Kovacevic } 507*3d0fad56SMarko Kovacevic 508*3d0fad56SMarko Kovacevic p = skip_white_spaces(p); 509*3d0fad56SMarko Kovacevic if (*p != '\0') 510*3d0fad56SMarko Kovacevic return -EINVAL; 511*3d0fad56SMarko Kovacevic 512*3d0fad56SMarko Kovacevic *value = val; 513*3d0fad56SMarko Kovacevic return 0; 514*3d0fad56SMarko Kovacevic } 515*3d0fad56SMarko Kovacevic 516*3d0fad56SMarko Kovacevic int 517*3d0fad56SMarko Kovacevic parser_read_uint32(uint32_t *value, char *p) 518*3d0fad56SMarko Kovacevic { 519*3d0fad56SMarko Kovacevic uint64_t val = 0; 520*3d0fad56SMarko Kovacevic int ret = parser_read_uint64(&val, p); 521*3d0fad56SMarko Kovacevic 522*3d0fad56SMarko Kovacevic if (ret < 0) 523*3d0fad56SMarko Kovacevic return ret; 524*3d0fad56SMarko Kovacevic 525*3d0fad56SMarko Kovacevic if (val > UINT32_MAX) 526*3d0fad56SMarko Kovacevic return -EINVAL; 527*3d0fad56SMarko Kovacevic 528*3d0fad56SMarko Kovacevic *value = val; 529*3d0fad56SMarko Kovacevic return 0; 530*3d0fad56SMarko Kovacevic } 531*3d0fad56SMarko Kovacevic 532*3d0fad56SMarko Kovacevic void 533*3d0fad56SMarko Kovacevic parse_write_hex_str(struct fips_val *src) 534*3d0fad56SMarko Kovacevic { 535*3d0fad56SMarko Kovacevic writeback_hex_str("", info.one_line_text, src); 536*3d0fad56SMarko Kovacevic 537*3d0fad56SMarko Kovacevic fprintf(info.fp_wr, "%s\n", info.one_line_text); 538*3d0fad56SMarko Kovacevic } 539*3d0fad56SMarko Kovacevic 540*3d0fad56SMarko Kovacevic int 541*3d0fad56SMarko Kovacevic update_info_vec(uint32_t count) 542*3d0fad56SMarko Kovacevic { 543*3d0fad56SMarko Kovacevic const struct fips_test_callback *cb; 544*3d0fad56SMarko Kovacevic uint32_t i, j; 545*3d0fad56SMarko Kovacevic 546*3d0fad56SMarko Kovacevic if (!info.writeback_callbacks) 547*3d0fad56SMarko Kovacevic return -1; 548*3d0fad56SMarko Kovacevic 549*3d0fad56SMarko Kovacevic cb = &info.writeback_callbacks[0]; 550*3d0fad56SMarko Kovacevic 551*3d0fad56SMarko Kovacevic snprintf(info.vec[0], strlen(info.vec[0]) + 4, "%s%u", cb->key, count); 552*3d0fad56SMarko Kovacevic 553*3d0fad56SMarko Kovacevic for (i = 1; i < info.nb_vec_lines; i++) { 554*3d0fad56SMarko Kovacevic for (j = 1; info.writeback_callbacks[j].key != NULL; j++) { 555*3d0fad56SMarko Kovacevic cb = &info.writeback_callbacks[j]; 556*3d0fad56SMarko Kovacevic if (strstr(info.vec[i], cb->key)) { 557*3d0fad56SMarko Kovacevic cb->cb(cb->key, info.vec[i], cb->val); 558*3d0fad56SMarko Kovacevic break; 559*3d0fad56SMarko Kovacevic } 560*3d0fad56SMarko Kovacevic } 561*3d0fad56SMarko Kovacevic } 562*3d0fad56SMarko Kovacevic 563*3d0fad56SMarko Kovacevic return 0; 564*3d0fad56SMarko Kovacevic } 565