All of lore.kernel.org
 help / color / mirror / Atom feed
From: Akhil Goyal <akhil.goyal@nxp.com>
To: Marko Kovacevic <marko.kovacevic@intel.com>,
	"dev@dpdk.org" <dev@dpdk.org>
Cc: "roy.fan.zhang@intel.com" <roy.fan.zhang@intel.com>,
	"arkadiuszx.kusztal@intel.com" <arkadiuszx.kusztal@intel.com>
Subject: Re: [PATCH v5 1/8] examples/cryptodev_fips_validate: add fips validation into examples
Date: Wed, 24 Oct 2018 12:13:13 +0000	[thread overview]
Message-ID: <64103ec5-2f25-1648-4d47-27a0f13e30e0@nxp.com> (raw)
In-Reply-To: <20181017124937.38052-2-marko.kovacevic@intel.com>



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 <marko.kovacevic@intel.com>
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> ---
>   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
> +
> +# 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 <stdio.h>
> +#include <string.h>
> +
> +#include <rte_string_fns.h>
> +#include <rte_cryptodev.h>
> +#include <rte_malloc.h>
> +
> +#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.
> +
> +	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.
> +					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
> +
> +	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
> +	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 <sys/stat.h>
> +#include <getopt.h>
> +#include <dirent.h>
> +
> +#include <rte_cryptodev.h>
> +#include <rte_cryptodev_pmd.h>
> +#include <rte_mempool.h>
> +#include <rte_mbuf.h>
> +#include <rte_string_fns.h>
> +
> +#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.
> +			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;
}
> +
> +		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'
> +)


  reply	other threads:[~2018-10-24 12:13 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-12 14:44 [PATCH v4 0/8] FIPS validation capability Marko Kovacevic
2018-10-12 14:44 ` [PATCH v4 1/8] examples: add fips validation into examples Marko Kovacevic
2018-10-12 14:44 ` [PATCH v4 2/8] examples: add aes parser and enablement for test types Marko Kovacevic
2018-10-12 14:44 ` [PATCH v4 3/8] examples: add hmac parser Marko Kovacevic
2018-10-12 14:44 ` [PATCH v4 4/8] examples: add TDES parser and enablement for test types Marko Kovacevic
2018-10-12 14:44 ` [PATCH v4 5/8] examples: add gcm parser Marko Kovacevic
2018-10-12 14:44 ` [PATCH v4 6/8] examples: add cmac parser and enablement for test types Marko Kovacevic
2018-10-12 14:45 ` [PATCH v4 7/8] examples: add ccm " Marko Kovacevic
2018-10-12 14:45 ` [PATCH v4 8/8] doc: add guides for fips validation Marko Kovacevic
2018-10-15  6:36 ` [PATCH v4 0/8] FIPS validation capability Kusztal, ArkadiuszX
2018-10-16 14:40 ` Akhil Goyal
2018-10-17 12:49 ` [PATCH v5 " Marko Kovacevic
2018-10-17 12:49   ` [PATCH v5 1/8] examples/cryptodev_fips_validate: add fips validation into examples Marko Kovacevic
2018-10-24 12:13     ` Akhil Goyal [this message]
2018-10-24 14:17       ` Marko Kovacevic
2018-10-24 14:36         ` Akhil Goyal
2018-10-24 15:13           ` Marko Kovacevic
2018-10-17 12:49   ` [PATCH v5 2/8] examples/cryptodev_fips_validate: add aes parser and enablement for test types Marko Kovacevic
2018-10-24 12:37     ` Akhil Goyal
2018-10-24 14:18       ` Marko Kovacevic
2018-10-17 12:49   ` [PATCH v5 3/8] examples/cryptodev_fips_validate: add hmac parser Marko Kovacevic
2018-10-17 12:49   ` [PATCH v5 4/8] examples/cryptodev_fips_validate: add TDES parser and enablement for test types Marko Kovacevic
2018-10-24 12:31     ` Akhil Goyal
2018-10-24 14:11       ` Marko Kovacevic
2018-10-17 12:49   ` [PATCH v5 5/8] examples/cryptodev_fips_validate: add gcm parser Marko Kovacevic
2018-10-17 12:49   ` [PATCH v5 6/8] examples/cryptodev_fips_validate: add cmac parser and enablement for test types Marko Kovacevic
2018-10-17 12:49   ` [PATCH v5 7/8] examples/cryptodev_fips_validate: add ccm " Marko Kovacevic
2018-10-17 12:49   ` [PATCH v5 8/8] doc/guides/sample_app_ug: add guides for fips validation Marko Kovacevic
2018-10-24 12:51     ` Akhil Goyal
2018-10-24 11:42   ` [PATCH v5 0/8] FIPS validation capability Akhil Goyal
2018-10-26 11:07   ` [PATCH v6 " Marko Kovacevic
2018-10-26 11:07     ` [PATCH v6 1/8] examples/fips_validation: add cryptodev fips compliant application Marko Kovacevic
2018-10-26 11:07     ` [PATCH v6 2/8] examples/fips_validation: support AES parsing Marko Kovacevic
2018-10-26 11:07     ` [PATCH v6 3/8] examples/fips_validation: support HMAC parsing Marko Kovacevic
2018-10-26 11:07     ` [PATCH v6 4/8] examples/fips_validation: support TDES parsing Marko Kovacevic
2018-10-26 11:07     ` [PATCH v6 5/8] examples/fips_validation: support GCM parsing Marko Kovacevic
2018-10-26 11:07     ` [PATCH v6 6/8] examples/fips_validation: support CMAC parsing Marko Kovacevic
2018-10-26 11:07     ` [PATCH v6 7/8] examples/fips_validation: support CCM parsing Marko Kovacevic
2018-10-26 11:07     ` [PATCH v6 8/8] doc: add fips validation application guide Marko Kovacevic
2018-11-02  9:17     ` [PATCH v6 0/8] FIPS validation capability Akhil Goyal
2018-11-02  9:34       ` Kovacevic, Marko
2018-11-02  9:55     ` [PATCH v7 " Kovacevic, Marko
2018-11-02  9:55       ` [PATCH v7 1/8] examples/fips_validation: add cryptodev fips compliant application Kovacevic, Marko
2018-11-02  9:55       ` [PATCH v7 2/8] examples/fips_validation: support AES parsing Kovacevic, Marko
2018-11-02  9:55       ` [PATCH v7 3/8] examples/fips_validation: support HMAC parsing Kovacevic, Marko
2018-11-02  9:55       ` [PATCH v7 4/8] examples/fips_validation: support TDES parsing Kovacevic, Marko
2018-11-02  9:55       ` [PATCH v7 5/8] examples/fips_validation: support GCM parsing Kovacevic, Marko
2018-11-02  9:55       ` [PATCH v7 6/8] examples/fips_validation: support CMAC parsing Kovacevic, Marko
2018-11-02  9:55       ` [PATCH v7 7/8] examples/fips_validation: support CCM parsing Kovacevic, Marko
2018-11-02  9:55       ` [PATCH v7 8/8] doc: add fips validation application guide Kovacevic, Marko
2018-11-02 11:23       ` [PATCH v7 0/8] FIPS validation capability Akhil Goyal
2018-11-02 11:34         ` Akhil Goyal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=64103ec5-2f25-1648-4d47-27a0f13e30e0@nxp.com \
    --to=akhil.goyal@nxp.com \
    --cc=arkadiuszx.kusztal@intel.com \
    --cc=dev@dpdk.org \
    --cc=marko.kovacevic@intel.com \
    --cc=roy.fan.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.