1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
8 #include <rte_string_fns.h>
9 #include <rte_cryptodev.h>
10 #include <rte_malloc.h>
12 #include "fips_validation.h"
14 #define skip_white_spaces(pos) \
16 __typeof__(pos) _p = (pos); \
17 for ( ; isspace(*_p); _p++) \
25 FILE *fp = info.fp_rd;
26 char *line = info.one_line_text;
30 memset(line, 0, MAX_LINE_CHAR);
31 while ((ret = fgetc(fp)) != EOF) {
34 if (loc >= MAX_LINE_CHAR - 1)
50 fips_test_fetch_one_block(void)
56 for (i = 0; i < info.nb_vec_lines; i++) {
63 if (i >= MAX_LINE_PER_VECTOR) {
68 ret = get_file_line();
69 size = strlen(info.one_line_text);
73 info.vec[i] = calloc(1, size + 5);
74 if (info.vec[i] == NULL)
77 strlcpy(info.vec[i], info.one_line_text, size + 1);
81 info.nb_vec_lines = i;
86 for (i = 0; i < MAX_LINE_PER_VECTOR; i++)
87 if (info.vec[i] != NULL) {
92 info.nb_vec_lines = 0;
98 fips_test_parse_header(void)
104 time_t t = time(NULL);
105 struct tm *tm_now = localtime(&t);
107 ret = fips_test_fetch_one_block();
111 for (i = 0; i < info.nb_vec_lines; i++) {
113 if (strstr(info.vec[i], "AESVS")) {
115 info.algo = FIPS_TEST_ALGO_AES;
116 ret = parse_test_aes_init();
119 } else if (strstr(info.vec[i], "GCM")) {
121 info.algo = FIPS_TEST_ALGO_AES_GCM;
122 ret = parse_test_gcm_init();
125 } else if (strstr(info.vec[i], "CMAC")) {
127 info.algo = FIPS_TEST_ALGO_AES_CMAC;
128 ret = parse_test_cmac_init();
131 } else if (strstr(info.vec[i], "CCM")) {
133 info.algo = FIPS_TEST_ALGO_AES_CCM;
134 ret = parse_test_ccm_init();
137 } else if (strstr(info.vec[i], "HMAC")) {
139 info.algo = FIPS_TEST_ALGO_HMAC;
140 ret = parse_test_hmac_init();
143 } else if (strstr(info.vec[i], "TDES")) {
145 info.algo = FIPS_TEST_ALGO_TDES;
146 ret = parse_test_tdes_init();
149 } else if (strstr(info.vec[i], "PERMUTATION")) {
151 info.algo = FIPS_TEST_ALGO_TDES;
152 ret = parse_test_tdes_init();
155 } else if (strstr(info.vec[i], "VARIABLE")) {
157 info.algo = FIPS_TEST_ALGO_TDES;
158 ret = parse_test_tdes_init();
161 } else if (strstr(info.vec[i], "SUBSTITUTION")) {
163 info.algo = FIPS_TEST_ALGO_TDES;
164 ret = parse_test_tdes_init();
167 } else if (strstr(info.vec[i], "SHA-")) {
169 info.algo = FIPS_TEST_ALGO_SHA;
170 ret = parse_test_sha_init();
173 } else if (strstr(info.vec[i], "XTS")) {
175 info.algo = FIPS_TEST_ALGO_AES_XTS;
176 ret = parse_test_xts_init();
182 tmp = strstr(info.vec[i], "# Config info for ");
184 fprintf(info.fp_wr, "%s%s\n", "# Config info for DPDK Cryptodev ",
189 tmp = strstr(info.vec[i], "# HMAC information for ");
191 fprintf(info.fp_wr, "%s%s\n", "# HMAC information for "
197 tmp = strstr(info.vec[i], "# Config Info for : ");
200 fprintf(info.fp_wr, "%s%s\n", "# Config Info for DPDK Cryptodev : ",
205 tmp = strstr(info.vec[i], "# information for ");
208 char tmp_output[128] = {0};
210 strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1);
212 fprintf(info.fp_wr, "%s%s%s\n", tmp_output,
213 "information for DPDK Cryptodev ",
218 tmp = strstr(info.vec[i], " test information for ");
220 char tmp_output[128] = {0};
222 strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1);
224 fprintf(info.fp_wr, "%s%s%s\n", tmp_output,
225 "test information for DPDK Cryptodev ",
230 tmp = strstr(info.vec[i], "\" information for \"");
232 char tmp_output[128] = {0};
234 strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1);
236 fprintf(info.fp_wr, "%s%s%s\n", tmp_output,
237 "\" information for DPDK Cryptodev ",
242 if (i == info.nb_vec_lines - 1) {
243 /** update the time as current time, write to file */
244 fprintf(info.fp_wr, "%s%s\n", "# Generated on ",
249 /* to this point, no field need to update,
250 * only copy to rsp file
252 fprintf(info.fp_wr, "%s\n", info.vec[i]);
259 parse_file_type(const char *path)
261 const char *tmp = path + strlen(path) - 3;
263 if (strstr(tmp, REQ_FILE_PERFIX))
264 info.file_type = FIPS_TYPE_REQ;
265 else if (strstr(tmp, RSP_FILE_PERFIX))
266 info.file_type = FIPS_TYPE_RSP;
267 else if (strstr(path, FAX_FILE_PERFIX))
268 info.file_type = FIPS_TYPE_FAX;
276 fips_test_init(const char *req_file_path, const char *rsp_file_path,
277 const char *device_name)
279 if (strcmp(req_file_path, rsp_file_path) == 0) {
280 RTE_LOG(ERR, USER1, "File paths cannot be the same\n");
286 if (rte_strscpy(info.file_name, req_file_path,
287 sizeof(info.file_name)) < 0) {
288 RTE_LOG(ERR, USER1, "Path %s too long\n", req_file_path);
291 info.algo = FIPS_TEST_ALGO_MAX;
292 if (parse_file_type(req_file_path) < 0) {
293 RTE_LOG(ERR, USER1, "File %s type not supported\n",
298 info.fp_rd = fopen(req_file_path, "r");
300 RTE_LOG(ERR, USER1, "Cannot open file %s\n", req_file_path);
304 info.fp_wr = fopen(rsp_file_path, "w");
306 RTE_LOG(ERR, USER1, "Cannot open file %s\n", rsp_file_path);
310 info.one_line_text = calloc(1, MAX_LINE_CHAR);
311 if (!info.one_line_text) {
312 RTE_LOG(ERR, USER1, "Insufficient memory\n");
316 if (rte_strscpy(info.device_name, device_name,
317 sizeof(info.device_name)) < 0) {
318 RTE_LOG(ERR, USER1, "Device name %s too long\n", device_name);
322 if (fips_test_parse_header() < 0) {
323 RTE_LOG(ERR, USER1, "Failed parsing header\n");
331 fips_test_clear(void)
337 if (info.one_line_text)
338 free(info.one_line_text);
339 if (info.nb_vec_lines) {
342 for (i = 0; i < info.nb_vec_lines; i++)
346 memset(&info, 0, sizeof(info));
350 fips_test_parse_one_case(void)
354 uint32_t interim_cnt = 0;
357 if (info.interim_callbacks) {
358 for (i = 0; i < info.nb_vec_lines; i++) {
360 for (j = 0; info.interim_callbacks[j].key != NULL; j++)
361 if (strstr(info.vec[i],
362 info.interim_callbacks[j].key)) {
365 ret = info.interim_callbacks[j].cb(
366 info.interim_callbacks[j].key,
368 info.interim_callbacks[j].val);
378 info.vec_start_off = interim_cnt;
381 for (i = 0; i < interim_cnt; i++)
382 fprintf(info.fp_wr, "%s\n", info.vec[i]);
383 fprintf(info.fp_wr, "\n");
385 if (info.nb_vec_lines == interim_cnt)
389 for (i = info.vec_start_off; i < info.nb_vec_lines; i++) {
390 for (j = 0; info.callbacks[j].key != NULL; j++)
391 if (strstr(info.vec[i], info.callbacks[j].key)) {
392 ret = info.callbacks[j].cb(
393 info.callbacks[j].key,
394 info.vec[i], info.callbacks[j].val);
405 fips_test_write_one_case(void)
409 for (i = info.vec_start_off; i < info.nb_vec_lines; i++)
410 fprintf(info.fp_wr, "%s\n", info.vec[i]);
414 parser_read_uint64_hex(uint64_t *value, const char *p)
419 p = skip_white_spaces(p);
421 val = strtoul(p, &next, 16);
425 p = skip_white_spaces(next);
434 parser_read_uint8_hex(uint8_t *value, const char *p)
437 int ret = parser_read_uint64_hex(&val, p);
450 parse_uint8_known_len_hex_str(const char *key, char *src, struct fips_val *val)
452 struct fips_val tmp_val = {0};
453 uint32_t len = val->len;
457 if (val->val != NULL) {
465 ret = parse_uint8_hex_str(key, src, &tmp_val);
469 if (tmp_val.len == val->len) {
470 val->val = tmp_val.val;
474 if (tmp_val.len < val->len) {
475 rte_free(tmp_val.val);
479 val->val = rte_zmalloc(NULL, val->len, 0);
481 rte_free(tmp_val.val);
482 memset(val, 0, sizeof(*val));
486 memcpy(val->val, tmp_val.val, val->len);
487 rte_free(tmp_val.val);
493 parse_uint8_hex_str(const char *key, char *src, struct fips_val *val)
499 len = strlen(src) / 2;
506 val->val = rte_zmalloc(NULL, len, 0);
510 for (j = 0; j < len; j++) {
511 char byte[3] = {src[j * 2], src[j * 2 + 1], '\0'};
513 if (parser_read_uint8_hex(&val->val[j], byte) < 0) {
515 memset(val, 0, sizeof(*val));
526 parser_read_uint32_val(const char *key, char *src, struct fips_val *val)
528 char *data = src + strlen(key);
529 size_t data_len = strlen(data);
532 if (data[data_len - 1] == ']') {
533 char *tmp_data = calloc(1, data_len + 1);
535 if (tmp_data == NULL)
538 strlcpy(tmp_data, data, data_len);
540 ret = parser_read_uint32(&val->len, tmp_data);
544 ret = parser_read_uint32(&val->len, data);
550 parser_read_uint32_bit_val(const char *key, char *src, struct fips_val *val)
554 ret = parser_read_uint32_val(key, src, val);
565 writeback_hex_str(const char *key, char *dst, struct fips_val *val)
572 for (len = 0; len < val->len; len++)
573 snprintf(str + len * 2, 255, "%02x", val->val[len]);
579 parser_read_uint64(uint64_t *value, const char *p)
584 p = skip_white_spaces(p);
588 val = strtoul(p, &next, 10);
610 p = skip_white_spaces(p);
619 parser_read_uint32(uint32_t *value, char *p)
622 int ret = parser_read_uint64(&val, p);
627 if (val > UINT32_MAX)
635 parse_write_hex_str(struct fips_val *src)
637 writeback_hex_str("", info.one_line_text, src);
639 fprintf(info.fp_wr, "%s\n", info.one_line_text);
643 update_info_vec(uint32_t count)
645 const struct fips_test_callback *cb;
648 if (!info.writeback_callbacks)
651 cb = &info.writeback_callbacks[0];
653 if (!(strstr(info.vec[0], cb->key))) {
654 fprintf(info.fp_wr, "%s%u\n", cb->key, count);
657 snprintf(info.vec[0], strlen(info.vec[0]) + 4, "%s%u", cb->key,
661 snprintf(info.vec[0], strlen(info.vec[0]) + 4, "%s%u", cb->key, count);
663 for (i = 1; i < info.nb_vec_lines; i++) {
664 for (j = 1; info.writeback_callbacks[j].key != NULL; j++) {
665 cb = &info.writeback_callbacks[j];
666 if (strstr(info.vec[i], cb->key)) {
667 cb->cb(cb->key, info.vec[i], cb->val);