From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id B3E852B94 for ; Wed, 24 Oct 2018 16:17:49 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 24 Oct 2018 07:17:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,420,1534834800"; d="scan'208";a="268415802" Received: from mkovacev-mobl.ger.corp.intel.com (HELO [10.237.221.98]) ([10.237.221.98]) by orsmga005.jf.intel.com with ESMTP; 24 Oct 2018 07:17:46 -0700 To: Akhil Goyal , "dev@dpdk.org" Cc: "roy.fan.zhang@intel.com" , "arkadiuszx.kusztal@intel.com" References: <20181012144501.19562-1-marko.kovacevic@intel.com> <20181017124937.38052-1-marko.kovacevic@intel.com> <20181017124937.38052-2-marko.kovacevic@intel.com> <64103ec5-2f25-1648-4d47-27a0f13e30e0@nxp.com> From: Marko Kovacevic Message-ID: Date: Wed, 24 Oct 2018 15:17:46 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: <64103ec5-2f25-1648-4d47-27a0f13e30e0@nxp.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Subject: Re: [dpdk-dev] [PATCH v5 1/8] examples/cryptodev_fips_validate: add fips validation into examples X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Oct 2018 14:17:50 -0000 On 24/10/2018 13:13, Akhil Goyal wrote: > > On 10/17/2018 6:19 PM, Marko Kovacevic wrote: >> Added FIPS application into the examples to allow >> users to use a simple sample app to validate >> their systems and be able to get FIPS certification. >> >> Signed-off-by: Marko Kovacevic >> Signed-off-by: Fan Zhang >> Acked-by: Arek Kusztal >> --- >> examples/cryptodev_fips_validate/Makefile | 69 +++ >> .../cryptodev_fips_parse_validate.c | 562 +++++++++++++++++++++ >> .../cryptodev_fips_validate.h | 150 ++++++ >> examples/cryptodev_fips_validate/main.c | 388 ++++++++++++++ >> examples/cryptodev_fips_validate/meson.build | 14 + >> 5 files changed, 1183 insertions(+) >> create mode 100644 examples/cryptodev_fips_validate/Makefile >> create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c >> create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_validate.h >> create mode 100644 examples/cryptodev_fips_validate/main.c >> create mode 100644 examples/cryptodev_fips_validate/meson.build >> >> diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile >> new file mode 100644 >> index 0000000..7f0e603 >> --- /dev/null >> +++ b/examples/cryptodev_fips_validate/Makefile >> @@ -0,0 +1,69 @@ >> +# SPDX-License-Identifier: BSD-3-Clause >> +# Copyright(c) 2010-2014 Intel Corporation > I believe this is a copy paste error, it should be 2018 Yeah your right will make the change. >> + >> +# binary name >> +APP = fips_validation >> + >> +# all source are stored in SRCS-y >> +SRCS-y += cryptodev_fips_parse_validate.c >> +SRCS-y += main.c >> + >> +# Build using pkg-config variables if possible >> +$(shell pkg-config --exists libdpdk) >> +ifeq ($(.SHELLSTATUS),0) >> + >> +all: shared >> +.PHONY: shared static >> +shared: build/$(APP)-shared >> + ln -sf $(APP)-shared build/$(APP) >> +static: build/$(APP)-static >> + ln -sf $(APP)-static build/$(APP) >> + >> +PC_FILE := $(shell pkg-config --path libdpdk) >> +CFLAGS += -O3 $(shell pkg-config --cflags libdpdk) >> +LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk) >> +LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk) >> + >> +build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build >> + $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) >> + >> +build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build >> + $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) >> + >> +build: >> + @mkdir -p $@ >> + >> +.PHONY: clean >> +clean: >> + rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared >> + rmdir --ignore-fail-on-non-empty build >> + >> +else >> + >> +ifeq ($(RTE_SDK),) >> +$(error "Please define RTE_SDK environment variable") >> +endif >> + >> +# Default target, can be overridden by command line or environment >> +RTE_TARGET ?= x86_64-native-linuxapp-gcc >> + >> +INC += $(sort $(wildcard *.h)) >> + >> +include $(RTE_SDK)/mk/rte.vars.mk >> + >> +CFLAGS += $(WERROR_FLAGS) >> + >> +# workaround for a gcc bug with noreturn attribute >> +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603 >> +ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) >> +CFLAGS_main.o += -Wno-return-type >> +endif >> + >> +CFLAGS += -DALLOW_EXPERIMENTAL_API >> +CFLAGS += -I$(SRCDIR) >> +CFLAGS += -O3 >> +CFLAGS += $(WERROR_FLAGS) >> + >> +include $(RTE_SDK)/mk/rte.extapp.mk >> + >> +endif >> diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c >> new file mode 100644 >> index 0000000..aec5bb9 >> --- /dev/null >> +++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c >> @@ -0,0 +1,562 @@ >> +/* SPDX-License-Identifier: BSD-3-Clause >> + * Copyright(c) 2018 Intel Corporation >> + */ >> + >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> + >> +#include "cryptodev_fips_validate.h" >> + >> +#define skip_white_spaces(pos) \ >> +({ \ >> + __typeof__(pos) _p = (pos); \ >> + for ( ; isspace(*_p); _p++) \ >> + ; \ >> + _p; \ >> +}) >> + >> +static int >> +get_file_line(void) >> +{ >> + FILE *fp = info.fp_rd; >> + char *line = info.one_line_text; >> + char c; >> + uint32_t loc = 0; >> + >> + memset(line, 0, MAX_LINE_CHAR); >> + while ((c = fgetc(fp)) != EOF) { >> + if (loc >= MAX_LINE_CHAR - 1) >> + return -ENOMEM; >> + if (c == '\n') >> + return 0; >> + line[loc++] = c; >> + } >> + >> + if (c == EOF) >> + return -EOF; >> + >> + return 0; >> +} >> + >> +int >> +fips_test_fetch_one_block(void) >> +{ >> + size_t size; >> + int ret = 0; >> + uint32_t i; >> + >> + for (i = 0; i < info.nb_vec_lines; i++) { >> + free(info.vec[i]); >> + info.vec[i] = NULL; >> + } >> + >> + i = 0; >> + do { >> + if (i >= MAX_LINE_PER_VECTOR) { >> + ret = -ENOMEM; >> + goto error_exit; >> + } >> + >> + ret = get_file_line(); >> + size = strlen(info.one_line_text); >> + if (size == 0) >> + break; >> + >> + info.vec[i] = calloc(1, size + 5); >> + if (info.vec[i] == NULL) >> + goto error_exit; >> + >> + strlcpy(info.vec[i], info.one_line_text, size + 1); >> + i++; >> + } while (ret == 0); >> + >> + info.nb_vec_lines = i; >> + >> + return ret; >> + >> +error_exit: >> + for (i = 0; i < MAX_LINE_PER_VECTOR; i++) >> + if (info.vec[i] != NULL) { >> + free(info.vec[i]); >> + info.vec[i] = NULL; >> + } >> + >> + info.nb_vec_lines = 0; >> + >> + return -ENOMEM; >> +} >> + >> +static int >> +fips_test_parse_header(void) >> +{ >> + uint32_t i; >> + char *tmp; >> + int ret; >> + time_t t = time(NULL); >> + struct tm *tm_now = localtime(&t); >> + >> + ret = fips_test_fetch_one_block(); >> + if (ret < 0) >> + return ret; >> + >> + for (i = 0; i < info.nb_vec_lines; i++) { >> + >> + tmp = strstr(info.vec[i], "# Config info for "); >> + if (tmp != NULL) { >> + fprintf(info.fp_wr, "%s%s\n", "# Config info for DPDK Cryptodev ", >> + info.device_name); >> + continue; >> + } >> + >> + tmp = strstr(info.vec[i], "# HMAC information for "); >> + if (tmp != NULL) { >> + fprintf(info.fp_wr, "%s%s\n", "# HMAC information for " >> + "DPDK Cryptodev ", >> + info.device_name); >> + continue; >> + } >> + >> + tmp = strstr(info.vec[i], "# Config Info for : "); >> + if (tmp != NULL) { >> + >> + fprintf(info.fp_wr, "%s%s\n", "# Config Info for DPDK Cryptodev : ", >> + info.device_name); >> + continue; >> + } >> + >> + tmp = strstr(info.vec[i], "# information for "); >> + if (tmp != NULL) { >> + >> + char tmp_output[128] = {0}; >> + >> + strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1); >> + >> + fprintf(info.fp_wr, "%s%s%s\n", tmp_output, >> + "information for DPDK Cryptodev ", >> + info.device_name); >> + continue; >> + } >> + >> + tmp = strstr(info.vec[i], " test information for "); >> + if (tmp != NULL) { >> + char tmp_output[128] = {0}; >> + >> + strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1); >> + >> + fprintf(info.fp_wr, "%s%s%s\n", tmp_output, >> + "test information for DPDK Cryptodev ", >> + info.device_name); >> + continue; >> + } >> + >> + if (i == info.nb_vec_lines - 1) { >> + /** update the time as current time, write to file */ >> + fprintf(info.fp_wr, "%s%s\n", "# Generated on ", >> + asctime(tm_now)); >> + continue; >> + } >> + >> + /* to this point, no field need to update, >> + * only copy to rsp file >> + */ >> + fprintf(info.fp_wr, "%s\n", info.vec[i]); >> + } >> + >> + return 0; >> +} >> + >> +static int >> +parse_file_type(const char *path) >> +{ >> + const char *tmp = path + strlen(path) - 3; >> + >> + if (strstr(tmp, REQ_FILE_PERFIX)) >> + info.file_type = FIPS_TYPE_REQ; >> + else if (strstr(tmp, RSP_FILE_PERFIX)) >> + info.file_type = FIPS_TYPE_RSP; >> + else if (strstr(path, FAX_FILE_PERFIX)) >> + info.file_type = FIPS_TYPE_FAX; >> + else >> + return -EINVAL; >> + >> + return 0; >> +} >> + >> +int >> +fips_test_init(const char *req_file_path, const char *rsp_file_path, >> + const char *device_name) >> +{ >> + if (strcmp(req_file_path, rsp_file_path) == 0) { >> + RTE_LOG(ERR, USER1, "File paths cannot be the same\n"); >> + return -EINVAL; >> + } >> + >> + fips_test_clear(); >> + >> + info.algo = FIPS_TEST_ALGO_MAX; >> + if (parse_file_type(req_file_path) < 0) { >> + RTE_LOG(ERR, USER1, "File %s type not supported\n", >> + req_file_path); >> + return -EINVAL; >> + } >> + >> + info.fp_rd = fopen(req_file_path, "r"); >> + if (!info.fp_rd) { >> + RTE_LOG(ERR, USER1, "Cannot open file %s\n", req_file_path); >> + return -EINVAL; >> + } >> + >> + info.fp_wr = fopen(rsp_file_path, "w"); >> + if (!info.fp_wr) { >> + RTE_LOG(ERR, USER1, "Cannot open file %s\n", rsp_file_path); >> + return -EINVAL; >> + } >> + >> + info.one_line_text = calloc(1, MAX_LINE_CHAR); >> + if (!info.one_line_text) { >> + RTE_LOG(ERR, USER1, "Insufficient memory\n"); >> + return -ENOMEM; >> + } >> + >> + strlcpy(info.device_name, device_name, sizeof(info.device_name)); >> + >> + if (fips_test_parse_header() < 0) { >> + RTE_LOG(ERR, USER1, "Failed parsing header\n"); >> + return -1; >> + } > memory leak for calloc done above in case of error. > Also there is no fclose in case of errors. All memory allocated will be freed and the files are closed in the fips_test_clear function and is called in the end of the main function. >> + >> + return 0; >> +} >> + >> +void >> +fips_test_clear(void) >> +{ >> + if (info.fp_rd) >> + fclose(info.fp_rd); >> + if (info.fp_wr) >> + fclose(info.fp_wr); >> + if (info.one_line_text) >> + free(info.one_line_text); >> + if (info.nb_vec_lines) { >> + uint32_t i; >> + >> + for (i = 0; i < info.nb_vec_lines; i++) >> + free(info.vec[i]); >> + } >> + >> + memset(&info, 0, sizeof(info)); >> +} >> + >> +int >> +fips_test_parse_one_case(void) >> +{ >> + uint32_t i, j = 0; >> + uint32_t is_interim = 0; >> + int ret; >> + >> + if (info.interim_callbacks) { >> + for (i = 0; i < info.nb_vec_lines; i++) { >> + for (j = 0; info.interim_callbacks[j].key != NULL; j++) >> + if (strstr(info.vec[i], >> + info.interim_callbacks[j].key)) { > it looks interim_callback is a single structure and there is no need for > treating as an array. For some tests interim data could be multiple lines. >> + is_interim = 1; >> + >> + ret = info.interim_callbacks[j].cb( >> + info.interim_callbacks[j].key, >> + info.vec[i], >> + info.interim_callbacks[j].val); >> + if (ret < 0) >> + return ret; >> + } >> + } >> + } >> + >> + if (is_interim) { >> + for (i = 0; i < info.nb_vec_lines; i++) >> + fprintf(info.fp_wr, "%s\n", info.vec[i]); >> + fprintf(info.fp_wr, "\n"); >> + return 1; >> + } >> + >> + for (i = 0; i < info.nb_vec_lines; i++) { >> + for (j = 0; info.callbacks[j].key != NULL; j++) >> + if (strstr(info.vec[i], info.callbacks[j].key)) { >> + ret = info.callbacks[j].cb( >> + info.callbacks[j].key, >> + info.vec[i], info.callbacks[j].val); >> + if (ret < 0) >> + return ret; >> + break; >> + } >> + } >> + >> + return 0; >> +} >> + >> +void >> +fips_test_write_one_case(void) >> +{ >> + uint32_t i; >> + >> + for (i = 0; i < info.nb_vec_lines; i++) >> + fprintf(info.fp_wr, "%s\n", info.vec[i]); >> +} >> + >> +static int >> +parser_read_uint64_hex(uint64_t *value, const char *p) >> +{ >> + char *next; >> + uint64_t val; >> + >> + p = skip_white_spaces(p); >> + >> + val = strtoul(p, &next, 16); >> + if (p == next) >> + return -EINVAL; >> + >> + p = skip_white_spaces(next); >> + if (*p != '\0') >> + return -EINVAL; >> + >> + *value = val; >> + return 0; >> +} >> + >> +int >> +parser_read_uint8_hex(uint8_t *value, const char *p) >> +{ >> + uint64_t val = 0; >> + int ret = parser_read_uint64_hex(&val, p); >> + >> + if (ret < 0) >> + return ret; >> + >> + if (val > UINT8_MAX) >> + return -ERANGE; >> + >> + *value = val; >> + return 0; >> +} >> + >> +int >> +parse_uint8_known_len_hex_str(const char *key, char *src, struct fips_val *val) >> +{ >> + struct fips_val tmp_val = {0}; >> + uint32_t len = val->len; >> + int ret; >> + >> + if (len == 0) { >> + if (val->val != NULL) { >> + rte_free(val->val); >> + val->val = NULL; >> + } >> + >> + return 0; >> + } >> + >> + ret = parse_uint8_hex_str(key, src, &tmp_val); >> + if (ret < 0) >> + return ret; >> + >> + if (tmp_val.len == val->len) { >> + val->val = tmp_val.val; >> + return 0; >> + } >> + >> + if (tmp_val.len < val->len) { >> + rte_free(tmp_val.val); >> + return -EINVAL; >> + } >> + >> + val->val = rte_zmalloc(NULL, val->len, 0); >> + if (!val->val) { >> + rte_free(tmp_val.val); >> + memset(val, 0, sizeof(*val)); >> + return -ENOMEM; >> + } >> + >> + memcpy(val->val, tmp_val.val, val->len); >> + rte_free(tmp_val.val); >> + >> + return 0; >> +} >> + >> +int >> +parse_uint8_hex_str(const char *key, char *src, struct fips_val *val) >> +{ >> + uint32_t len, j; >> + >> + src += strlen(key); >> + >> + len = strlen(src) / 2; >> + >> + if (val->val) { >> + rte_free(val->val); >> + val->val = NULL; >> + } >> + >> + val->val = rte_zmalloc(NULL, len, 0); >> + if (!val->val) >> + return -1; > should be -ENOMEM will change it. >> + >> + for (j = 0; j < len; j++) { >> + char byte[3] = {src[j * 2], src[j * 2 + 1], '\0'}; >> + >> + if (parser_read_uint8_hex(&val->val[j], byte) < 0) { >> + rte_free(val->val); >> + memset(val, 0, sizeof(*val)); >> + return -EINVAL; >> + } >> + } >> + >> + val->len = len; >> + >> + return 0; >> +} >> + >> +int >> +parser_read_uint32_val(const char *key, char *src, struct fips_val *val) >> +{ >> + char *data = src + strlen(key); >> + size_t data_len = strlen(data); >> + int ret; >> + >> + if (data[data_len - 1] == ']') { >> + char *tmp_data = calloc(1, data_len + 1); >> + >> + if (tmp_data == NULL) >> + return -ENOMEM; >> + >> + strlcpy(tmp_data, data, data_len); >> + >> + ret = parser_read_uint32(&val->len, tmp_data); >> + >> + free(tmp_data); >> + } else >> + ret = parser_read_uint32(&val->len, data); >> + >> + return ret; >> +} >> + >> +int >> +parser_read_uint32_bit_val(const char *key, char *src, struct fips_val *val) >> +{ >> + int ret; >> + >> + ret = parser_read_uint32_val(key, src, val); >> + >> + if (ret < 0) >> + return ret; >> + >> + val->len /= 8; >> + >> + return 0; >> +} >> + >> +int >> +writeback_hex_str(const char *key, char *dst, struct fips_val *val) >> +{ >> + char *str = dst; >> + uint32_t len; >> + >> + str += strlen(key); >> + >> + for (len = 0; len < val->len; len++) >> + snprintf(str + len * 2, 255, "%02x", val->val[len]); >> + >> + return 0; >> +} >> + >> +static int >> +parser_read_uint64(uint64_t *value, const char *p) >> +{ >> + char *next; >> + uint64_t val; >> + >> + p = skip_white_spaces(p); >> + if (!isdigit(*p)) >> + return -EINVAL; >> + >> + val = strtoul(p, &next, 10); >> + if (p == next) >> + return -EINVAL; >> + >> + p = next; >> + switch (*p) { >> + case 'T': >> + val *= 1024ULL; >> + /* fall through */ >> + case 'G': >> + val *= 1024ULL; >> + /* fall through */ >> + case 'M': >> + val *= 1024ULL; >> + /* fall through */ >> + case 'k': >> + case 'K': >> + val *= 1024ULL; >> + p++; >> + break; >> + } >> + >> + p = skip_white_spaces(p); >> + if (*p != '\0') >> + return -EINVAL; >> + >> + *value = val; >> + return 0; >> +} >> + >> +int >> +parser_read_uint32(uint32_t *value, char *p) >> +{ >> + uint64_t val = 0; >> + int ret = parser_read_uint64(&val, p); >> + >> + if (ret < 0) >> + return ret; >> + >> + if (val > UINT32_MAX) >> + return -EINVAL; >> + >> + *value = val; >> + return 0; >> +} >> + >> +void >> +parse_write_hex_str(struct fips_val *src) >> +{ >> + writeback_hex_str("", info.one_line_text, src); >> + >> + fprintf(info.fp_wr, "%s\n", info.one_line_text); >> +} >> + >> +int >> +update_info_vec(uint32_t count) >> +{ >> + const struct fips_test_callback *cb; >> + uint32_t i, j; >> + >> + if (!info.writeback_callbacks) >> + return -1; >> + >> + cb = &info.writeback_callbacks[0]; >> + >> + snprintf(info.vec[0], strlen(info.vec[0]) + 4, "%s%u", cb->key, count); >> + >> + for (i = 1; i < info.nb_vec_lines; i++) { >> + for (j = 1; info.writeback_callbacks[j].key != NULL; j++) { >> + cb = &info.writeback_callbacks[j]; >> + if (strstr(info.vec[i], cb->key)) { >> + cb->cb(cb->key, info.vec[i], cb->val); >> + break; >> + } >> + } >> + } >> + >> + return 0; >> +} >> diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h >> new file mode 100644 >> index 0000000..beb6bed >> --- /dev/null >> +++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h >> @@ -0,0 +1,150 @@ >> +/* SPDX-License-Identifier: BSD-3-Clause >> + * Copyright(c) 2018 Intel Corporation >> + */ >> + >> +#ifndef _CRYPTODEV_NIST_FIPS_PARSER_H_ >> +#define _CRYPTODEV_NIST_FIPS_PARSER_H_ >> + >> +#define FIPS_PARSE_ERR(fmt, args) \ >> + RTE_LOG(ERR, USER1, "FIPS parse error" ## fmt ## "\n", ## args) >> + >> +#define ERR_MSG_SIZE 128 >> +#define MAX_CASE_LINE 15 >> +#define MAX_LINE_CHAR 204800 /*< max number of characters per line */ >> +#define MAX_NB_TESTS 10240 >> +#define MAX_BUF_SIZE 2048 >> +#define MAX_STRING_SIZE 64 >> + >> +#define POSITIVE_TEST 0 >> +#define NEGATIVE_TEST -1 >> + >> +#define REQ_FILE_PERFIX "req" >> +#define RSP_FILE_PERFIX "rsp" >> +#define FAX_FILE_PERFIX "fax" >> + >> +enum fips_test_algorithms { >> + FIPS_TEST_ALGO_MAX >> +}; >> + >> +enum file_types { >> + FIPS_TYPE_REQ = 1, >> + FIPS_TYPE_FAX, >> + FIPS_TYPE_RSP >> +}; >> + >> +enum fips_test_op { >> + FIPS_TEST_ENC_AUTH_GEN = 1, >> + FIPS_TEST_DEC_AUTH_VERIF, >> +}; >> + >> +#define MAX_LINE_PER_VECTOR 16 >> + >> +struct fips_val { >> + uint8_t *val; >> + uint32_t len; >> +}; >> + >> +struct fips_test_vector { >> + union { >> + struct { >> + struct fips_val key; >> + struct fips_val digest; >> + struct fips_val auth_aad; >> + struct fips_val aad; >> + } cipher_auth; >> + struct { >> + struct fips_val key; >> + struct fips_val digest; >> + struct fips_val aad; >> + } aead; >> + }; >> + >> + struct fips_val pt; >> + struct fips_val ct; >> + struct fips_val iv; >> + >> + enum rte_crypto_op_status status; >> +}; >> + >> +typedef int (*post_prcess_t)(struct fips_val *val); >> + >> +typedef int (*parse_callback_t)(const char *key, char *text, >> + struct fips_val *val); >> + >> +struct fips_test_callback { >> + const char *key; >> + parse_callback_t cb; >> + struct fips_val *val; >> +}; >> + >> +struct fips_test_interim_info { >> + FILE *fp_rd; >> + FILE *fp_wr; >> + enum file_types file_type; >> + enum fips_test_algorithms algo; >> + char *one_line_text; >> + char *vec[MAX_LINE_PER_VECTOR]; >> + uint32_t nb_vec_lines; >> + //uint8_t cryptodev_id; > remove if not needed will do missed it. >> + char device_name[MAX_STRING_SIZE]; >> + >> + enum fips_test_op op; >> + >> + const struct fips_test_callback *callbacks; >> + const struct fips_test_callback *interim_callbacks; >> + const struct fips_test_callback *writeback_callbacks; >> + >> + post_prcess_t parse_writeback; >> + post_prcess_t kat_check; >> +}; >> + >> +extern struct fips_test_vector vec; >> +extern struct fips_test_interim_info info; >> + >> +int >> +fips_test_init(const char *req_file_path, const char *rsp_file_path, >> + const char *device_name); >> + >> +void >> +fips_test_clear(void); >> + >> +int >> +fips_test_fetch_one_block(void); >> + >> +int >> +fips_test_parse_one_case(void); >> + >> +void >> +fips_test_write_one_case(void); >> + >> +int >> +parser_read_uint8_hex(uint8_t *value, const char *p); >> + >> +int >> +parse_uint8_hex_str(const char *key, char *src, struct fips_val *val); >> + >> +int >> +parse_uint8_known_len_hex_str(const char *key, char *src, struct fips_val *val); >> + >> +int >> +parser_read_uint32_val(const char *key, char *src, struct fips_val *val); >> + >> +int >> +parser_read_uint32_bit_val(const char *key, char *src, struct fips_val *val); >> + >> +int >> +parser_read_uint32(uint32_t *value, char *p); >> + >> +int >> +parser_read_uint32_val(const char *key, char *src, struct fips_val *val); >> + >> +int >> +writeback_hex_str(const char *key, char *dst, struct fips_val *val); >> + >> +void >> +parse_write_hex_str(struct fips_val *src); >> + >> +int >> +update_info_vec(uint32_t count); >> + >> +#endif >> diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c >> new file mode 100644 >> index 0000000..4f14b04 >> --- /dev/null >> +++ b/examples/cryptodev_fips_validate/main.c >> @@ -0,0 +1,388 @@ >> +/* SPDX-License-Identifier: BSD-3-Clause >> + * Copyright(c) 2018 Intel Corporation >> + */ >> + >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "cryptodev_fips_validate.h" >> + >> +#define REQ_FILE_PATH_KEYWORD "req-file" >> +#define RSP_FILE_PATH_KEYWORD "rsp-file" >> +#define FOLDER_KEYWORD "path-is-folder" >> +#define CRYPTODEV_KEYWORD "cryptodev" >> +#define CRYPTODEV_ID_KEYWORD "cryptodev-id" >> + >> +struct fips_test_vector vec; >> +struct fips_test_interim_info info; >> + >> +struct cryptodev_fips_validate_env { >> + const char *req_path; >> + const char *rsp_path; >> + uint32_t is_path_folder; >> + uint32_t dev_id; >> + struct rte_mempool *mpool; >> + struct rte_mempool *op_pool; >> + struct rte_mbuf *mbuf; >> + struct rte_crypto_op *op; >> + struct rte_cryptodev_sym_session *sess; >> +} env; >> + >> +static int >> +cryptodev_fips_validate_app_int(void) >> +{ >> + struct rte_cryptodev_config conf = {rte_socket_id(), 1}; >> + struct rte_cryptodev_qp_conf qp_conf = {128}; >> + int ret; >> + >> + ret = rte_cryptodev_configure(env.dev_id, &conf); >> + if (ret < 0) >> + return ret; >> + >> + env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", 128, 0, 0, >> + UINT16_MAX, rte_socket_id()); >> + if (!env.mpool) >> + return ret; >> + >> + ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf, >> + rte_socket_id(), env.mpool); >> + if (ret < 0) >> + return ret; >> + >> + ret = -ENOMEM; >> + >> + env.op_pool = rte_crypto_op_pool_create( >> + "FIPS_OP_POOL", >> + RTE_CRYPTO_OP_TYPE_SYMMETRIC, >> + 1, 0, >> + 16, >> + rte_socket_id()); >> + if (!env.op_pool) >> + goto error_exit; >> + >> + env.mbuf = rte_pktmbuf_alloc(env.mpool); >> + if (!env.mbuf) >> + goto error_exit; >> + >> + env.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); >> + if (!env.op) >> + goto error_exit; >> + >> + return 0; >> + >> +error_exit: >> + rte_mempool_free(env.mpool); >> + if (env.op_pool) >> + rte_mempool_free(env.op_pool); >> + >> + return ret; >> +} >> + >> +static void >> +cryptodev_fips_validate_app_uninit(void) >> +{ >> + rte_pktmbuf_free(env.mbuf); >> + rte_crypto_op_free(env.op); >> + rte_cryptodev_sym_session_clear(env.dev_id, env.sess); >> + rte_cryptodev_sym_session_free(env.sess); >> + rte_mempool_free(env.mpool); >> + rte_mempool_free(env.op_pool); >> +} >> + >> +static int >> +fips_test_one_file(void); >> + >> +static int >> +parse_cryptodev_arg(char *arg) >> +{ >> + int id = rte_cryptodev_get_dev_id(arg); >> + >> + if (id < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n", >> + id, arg); >> + return id; >> + } >> + >> + env.dev_id = (uint32_t)id; >> + >> + return 0; >> +} >> + >> +static int >> +parse_cryptodev_id_arg(char *arg) >> +{ >> + uint32_t cryptodev_id; >> + >> + if (parser_read_uint32(&cryptodev_id, arg) < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", >> + -EINVAL, arg); >> + return -1; >> + } >> + >> + >> + if (!rte_cryptodev_pmd_is_valid_dev(cryptodev_id)) { >> + RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n", >> + cryptodev_id, arg); >> + return -1; >> + } >> + >> + env.dev_id = (uint32_t)cryptodev_id; >> + >> + return 0; >> +} >> + >> +static void >> +cryptodev_fips_validate_usage(const char *prgname) >> +{ >> + printf("%s [EAL options] --\n" >> + " --%s: REQUEST-FILE-PATH\n" >> + " --%s: RESPONSE-FILE-PATH\n" >> + " --%s: indicating both paths are folders\n" >> + " --%s: CRYPTODEV-NAME\n" >> + " --%s: CRYPTODEV-ID-NAME\n", >> + prgname, REQ_FILE_PATH_KEYWORD, RSP_FILE_PATH_KEYWORD, >> + FOLDER_KEYWORD, CRYPTODEV_KEYWORD, CRYPTODEV_ID_KEYWORD); >> +} >> + >> +static int >> +cryptodev_fips_validate_parse_args(int argc, char **argv) >> +{ >> + int opt, ret; >> + char *prgname = argv[0]; >> + char **argvopt; >> + int option_index; >> + struct option lgopts[] = { >> + {REQ_FILE_PATH_KEYWORD, required_argument, 0, 0}, >> + {RSP_FILE_PATH_KEYWORD, required_argument, 0, 0}, >> + {FOLDER_KEYWORD, no_argument, 0, 0}, >> + {CRYPTODEV_KEYWORD, required_argument, 0, 0}, >> + {CRYPTODEV_ID_KEYWORD, required_argument, 0, 0}, >> + {NULL, 0, 0, 0} >> + }; >> + >> + argvopt = argv; >> + >> + while ((opt = getopt_long(argc, argvopt, "s:", >> + lgopts, &option_index)) != EOF) { >> + >> + switch (opt) { >> + case 0: >> + if (strcmp(lgopts[option_index].name, >> + REQ_FILE_PATH_KEYWORD) == 0) >> + env.req_path = optarg; >> + else if (strcmp(lgopts[option_index].name, >> + RSP_FILE_PATH_KEYWORD) == 0) >> + env.rsp_path = optarg; >> + else if (strcmp(lgopts[option_index].name, >> + FOLDER_KEYWORD) == 0) >> + env.is_path_folder = 1; >> + else if (strcmp(lgopts[option_index].name, >> + CRYPTODEV_KEYWORD) == 0) { >> + ret = parse_cryptodev_arg(optarg); >> + if (ret < 0) { >> + cryptodev_fips_validate_usage(prgname); >> + return -EINVAL; >> + } >> + } else if (strcmp(lgopts[option_index].name, >> + CRYPTODEV_ID_KEYWORD) == 0) { >> + ret = parse_cryptodev_id_arg(optarg); >> + if (ret < 0) { >> + cryptodev_fips_validate_usage(prgname); >> + return -EINVAL; >> + } >> + } else { >> + cryptodev_fips_validate_usage(prgname); >> + return -EINVAL; >> + } >> + break; >> + default: >> + return -1; >> + } >> + } >> + >> + if (env.req_path == NULL || env.rsp_path == NULL || >> + env.dev_id == UINT32_MAX) { >> + cryptodev_fips_validate_usage(prgname); >> + return -EINVAL; >> + } >> + >> + return 0; >> +} >> + >> +int >> +main(int argc, char *argv[]) >> +{ >> + int ret; >> + >> + ret = rte_eal_init(argc, argv); >> + if (ret < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); >> + return -1; >> + } >> + >> + argc -= ret; >> + argv += ret; >> + >> + ret = cryptodev_fips_validate_parse_args(argc, argv); >> + if (ret < 0) >> + rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n"); >> + >> + ret = cryptodev_fips_validate_app_int(); >> + if (ret < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret); >> + return -1; >> + } >> + >> + if (!env.is_path_folder) { >> + printf("Processing file %s... ", env.req_path); >> + >> + ret = fips_test_init(env.req_path, env.rsp_path, >> + rte_cryptodev_name_get(env.dev_id)); >> + if (ret < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", >> + ret, env.req_path); >> + goto exit; >> + } >> + >> + >> + ret = fips_test_one_file(); >> + if (ret < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", >> + ret, env.req_path); >> + goto exit; >> + } >> + >> + printf("Done\n"); >> + >> + } else { >> + struct dirent *dir; >> + DIR *d_req, *d_rsp; >> + char req_path[1024]; >> + char rsp_path[1024]; >> + >> + d_req = opendir(env.req_path); >> + if (!d_req) { >> + RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n", >> + -EINVAL, env.req_path); >> + goto exit; >> + } >> + >> + d_rsp = opendir(env.rsp_path); >> + if (!d_rsp) { >> + ret = mkdir(env.rsp_path, 0700); >> + if (ret == 0) >> + d_rsp = opendir(env.rsp_path); >> + else { >> + RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n", >> + -EINVAL, env.rsp_path); >> + goto exit; >> + } >> + } >> + closedir(d_rsp); >> + >> + while ((dir = readdir(d_req)) != NULL) { >> + if (strstr(dir->d_name, "req") == NULL) >> + continue; >> + >> + snprintf(req_path, 1023, "%s/%s", env.req_path, >> + dir->d_name); >> + snprintf(rsp_path, 1023, "%s/%s", env.rsp_path, >> + dir->d_name); >> + strlcpy(strstr(rsp_path, "req"), "rsp", 4); >> + >> + printf("Processing file %s... ", req_path); >> + >> + ret = fips_test_init(req_path, rsp_path, >> + rte_cryptodev_name_get(env.dev_id)); >> + if (ret < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", >> + ret, req_path); >> + break; >> + } >> + >> + ret = fips_test_one_file(); >> + if (ret < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n", >> + ret, req_path); >> + break; >> + } >> + >> + printf("Done\n"); >> + } >> + >> + closedir(d_req); >> + } >> + >> + >> +exit: >> + fips_test_clear(); >> + cryptodev_fips_validate_app_uninit(); >> + >> + return ret; >> + >> +} >> + >> +static void >> +print_test_block(void) >> +{ >> + uint32_t i; >> + >> + for (i = 0; i < info.nb_vec_lines; i++) >> + printf("%s\n", info.vec[i]); >> + >> + printf("\n"); >> +} >> + >> +static int >> +fips_test_one_file(void) >> +{ >> + int fetch_ret = 0, ret; >> + >> + while (fetch_ret == 0) { >> + fetch_ret = fips_test_fetch_one_block(); >> + if (fetch_ret < 0) { >> + RTE_LOG(ERR, USER1, "Error %i: Fetch block\n", >> + fetch_ret); >> + ret = fetch_ret; >> + goto error_one_case; >> + } >> + >> + if (info.nb_vec_lines == 0) { >> + if (fetch_ret == -EOF) >> + break; >> + >> + fprintf(info.fp_wr, "\n"); >> + continue; >> + } >> + >> + ret = fips_test_parse_one_case(); >> + switch (ret) { >> + case 0: >> + if (ret == 0) >> + break; >> + RTE_LOG(ERR, USER1, "Error %i: test block\n", >> + ret); > this log is unreachable code. The bit that is missing is being added in v2 when i was splitting the patch i forgot to remove this check until this was added ret = test_ops.test();             if (ret == 0)                 break;             RTE_LOG(ERR, USER1, "Error %i: test block\n",                     ret);             goto error_one_case; >> + goto error_one_case; >> + case 1: >> + break; >> + default: >> + RTE_LOG(ERR, USER1, "Error %i: Parse block\n", >> + ret); >> + goto error_one_case; >> + } > do you really need this switch case here. In both the cases you are > breaking without doing anything. > it should be something like > if (ret <= 0) { >     RTE_LOG(ERR, USER1, "Error %i: Parse block\n", ret); >     goto error_one_case; > } 1 = test-interim data and 0 = test-data will add  a comment with more info inside the files of what the return cases mean >> + >> + continue; >> +error_one_case: >> + print_test_block(); >> + } >> + >> + fips_test_clear(); >> + >> +} >> diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build >> new file mode 100644 >> index 0000000..f44043c >> --- /dev/null >> +++ b/examples/cryptodev_fips_validate/meson.build >> @@ -0,0 +1,14 @@ >> +# SPDX-License-Identifier: BSD-3-Clause >> +# Copyright(c) 2018 Intel Corporation >> + >> +# meson file, for building this example as part of a main DPDK build. >> +# >> +# To build this example as a standalone application with an already-installed >> +# DPDK instance, use 'make' >> + >> +deps += ['cryptodev'] >> +allow_experimental_apis = true >> +sources = files( >> + 'cryptodev_fips_parse_validate.c', >> + 'main.c' >> +)