DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2 0/8] FIPS validation capability
@ 2018-10-04  9:40 Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 1/8] examples: add fips validation into examples Fan Zhang
                   ` (8 more replies)
  0 siblings, 9 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal

This sample application is made for the purpose so that users of DPDK
who wish to get FIPS certification for their platforms, this sample app enables
users to parse test vectors that is gotten from NIST and be able to get
a generated response file which they can then verify and be sure their
system will pass FIPS certification.

Marko Kovacevic (8):
  examples: add fips validation into examples
  examples: add aes parser and enablement for test types
  examples: add hmac parser
  examples: add TDES parser and enablement for test types
  examples: add gcm parser
  examples: add cmac parser and enablement for test types
  examples: add ccm parser and enablement for test types
  doc: add guides for fips validation

 doc/guides/rel_notes/release_18_11.rst             |    6 +
 doc/guides/sample_app_ug/fips_validation.rst       |   97 ++
 doc/guides/sample_app_ug/index.rst                 |    5 +
 examples/cryptodev_fips_validate/Makefile          |   75 ++
 .../cryptodev_fips_parse_3des.c                    |  259 +++++
 .../cryptodev_fips_parse_aes.c                     |  188 +++
 .../cryptodev_fips_parse_ccm.c                     |  272 +++++
 .../cryptodev_fips_parse_cmac.c                    |  116 ++
 .../cryptodev_fips_parse_gcm.c                     |  125 ++
 .../cryptodev_fips_parse_hmac.c                    |  105 ++
 .../cryptodev_fips_parse_validate.c                |  593 ++++++++++
 .../cryptodev_fips_validate.h                      |  234 ++++
 examples/cryptodev_fips_validate/main.c            | 1219 ++++++++++++++++++++
 examples/cryptodev_fips_validate/meson.build       |   20 +
 14 files changed, 3314 insertions(+)
 create mode 100644 doc/guides/sample_app_ug/fips_validation.rst
 create mode 100644 examples/cryptodev_fips_validate/Makefile
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c
 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

-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v2 1/8] examples: add fips validation into examples
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
@ 2018-10-04  9:40 ` Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 2/8] examples: add aes parser and enablement for test types Fan Zhang
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

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>
---
 examples/cryptodev_fips_validate/Makefile          |  69 +++
 .../cryptodev_fips_parse_validate.c                | 562 +++++++++++++++++++++
 .../cryptodev_fips_validate.h                      | 150 ++++++
 examples/cryptodev_fips_validate/main.c            | 387 ++++++++++++++
 examples/cryptodev_fips_validate/meson.build       |  14 +
 5 files changed, 1182 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 000000000..5515aa6d9
--- /dev/null
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2014 Intel Corporation
+
+# binary name
+APP = cryptodev_fips_validate_app
+
+# 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 000000000..aec5bb9c6
--- /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;
+	}
+
+	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)) {
+					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;
+
+	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 000000000..beb6bedda
--- /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;
+	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 000000000..1cf043fc8
--- /dev/null
+++ b/examples/cryptodev_fips_validate/main.c
@@ -0,0 +1,387 @@
+/* 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);
+			goto error_one_case;
+		case 1:
+			break;
+		default:
+			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 000000000..e41773305
--- /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', 'bus_pci']
+allow_experimental_apis = true
+sources = files(
+	'cryptodev_fips_parse_validate.c',
+	'main.c'
+)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v2 2/8] examples: add aes parser and enablement for test types
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 1/8] examples: add fips validation into examples Fan Zhang
@ 2018-10-04  9:40 ` Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 3/8] examples: add hmac parser Fan Zhang
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for AES-CBC parser, to allow the
application to parser the aes request file and to validate all
test types supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_aes.c                     | 186 +++++++++++
 .../cryptodev_fips_parse_validate.c                |   6 +
 .../cryptodev_fips_validate.h                      |  24 ++
 examples/cryptodev_fips_validate/main.c            | 345 ++++++++++++++++++++-
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 562 insertions(+), 1 deletion(-)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index 5515aa6d9..f058081ff 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -5,6 +5,7 @@
 APP = cryptodev_fips_validate_app
 
 # all source are stored in SRCS-y
+SRCS-y := cryptodev_fips_parse_aes.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
new file mode 100644
index 000000000..39dbd6ff9
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define MODE_STR	"AESVS"
+#define ALGO_STR	"test data for "
+#define OP_STR		"State"
+#define KEY_SIZE_STR	"Key Length : "
+
+
+#define COUNT_STR	"COUNT = "
+#define KEY_STR		"KEY = "
+#define IV_STR		"IV = "
+#define PT_STR		"PLAINTEXT = "
+#define CT_STR		"CIPHERTEXT = "
+
+#define OP_ENC_STR	"ENCRYPT"
+#define OP_DEC_STR	"DECRYPT"
+
+struct {
+	uint32_t type;
+	const char *desc;
+} aes_test_types[] = {
+		{AESAVS_TYPE_GFXBOX, "GFSbox"},
+		{AESAVS_TYPE_KEYSBOX, "KeySbox"},
+		{AESAVS_TYPE_VARKEY, "VarKey"},
+		{AESAVS_TYPE_VARTXT, "VarTxt"},
+		{AESAVS_TYPE_MMT, "MMT"},
+		{AESAVS_TYPE_MCT, "MCT"},
+};
+
+struct aes_test_algo {
+	const char *name;
+	enum rte_crypto_cipher_algorithm algo;
+} const algo_con[] = {
+		{"CBC", RTE_CRYPTO_CIPHER_AES_CBC},
+};
+
+static int
+parse_interim_enc_dec(const char *key,
+		__attribute__((__unused__)) char *text,
+		__attribute__((__unused__)) struct fips_val *val)
+{
+	if (strcmp(key, OP_ENC_STR) == 0)
+		info.op = FIPS_TEST_ENC_AUTH_GEN;
+	else if (strcmp(key, OP_DEC_STR) == 0)
+		info.op = FIPS_TEST_DEC_AUTH_VERIF;
+	else
+		return -1;
+
+	return 0;
+}
+
+struct fips_test_callback aes_tests_interim[] = {
+		{OP_ENC_STR, parse_interim_enc_dec, NULL},
+		{OP_DEC_STR, parse_interim_enc_dec, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback aes_tests_vectors[] = {
+		{KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key},
+		{IV_STR, parse_uint8_hex_str, &vec.iv},
+		{PT_STR, parse_uint8_hex_str, &vec.pt},
+		{CT_STR, parse_uint8_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback aes_tests_interim_vectors[] = {
+		{OP_ENC_STR, parse_interim_enc_dec, NULL},
+		{OP_DEC_STR, parse_interim_enc_dec, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback aes_writeback_callbacks[] = {
+		/** First element is used to pass COUNT string */
+		{COUNT_STR, NULL, NULL},
+		{IV_STR, writeback_hex_str, &vec.iv},
+		{KEY_STR, writeback_hex_str, &vec.cipher_auth.key},
+		{PT_STR, writeback_hex_str, &vec.pt},
+		{CT_STR, writeback_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_test_aes_writeback(struct fips_val *val)
+{
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+		fprintf(info.fp_wr, "%s", CT_STR);
+	else
+		fprintf(info.fp_wr, "%s", PT_STR);
+
+	parse_write_hex_str(val);
+
+	return 0;
+}
+
+static int
+rsp_test_aes_check(struct fips_val *val)
+{
+	struct fips_val *data;
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+		data = &vec.ct;
+	else
+		data = &vec.pt;
+
+	if (memcmp(val->val, data->val, val->len) == 0)
+		fprintf(info.fp_wr, "Success\n");
+	else
+		fprintf(info.fp_wr, "Failed\n");
+
+	return 0;
+}
+
+int
+parse_test_aes_init(void)
+{
+	char *tmp;
+	uint32_t i, j;
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+
+		tmp = strstr(line, MODE_STR);
+		if (tmp) {
+			for (j = 0; j < RTE_DIM(aes_test_types); j++)
+				if (strstr(line, aes_test_types[j].desc)) {
+					info.interim_info.aes_data.test_type =
+							aes_test_types[j].type;
+					break;
+				}
+
+			if (j >= RTE_DIM(aes_test_types))
+				return -EINVAL;
+
+			tmp = strstr(line, ALGO_STR);
+			if (!tmp)
+				return -EINVAL;
+
+			tmp += strlen(ALGO_STR);
+			for (j = 0; j < RTE_DIM(algo_con); j++)
+				if (strcmp(algo_con[j].name, tmp) == 0) {
+					info.interim_info.aes_data.cipher_algo =
+						(uint32_t)algo_con[j].algo;
+					break;
+				}
+			if (j >= RTE_DIM(algo_con))
+				return -EINVAL;
+
+			continue;
+		}
+
+		tmp = strstr(line, OP_STR);
+		if (tmp)
+			continue;
+
+		tmp = strstr(line, KEY_SIZE_STR);
+		if (tmp) {
+			tmp += strlen(KEY_SIZE_STR);
+			if (parser_read_uint32
+					(&info.interim_info.aes_data.key_len,
+							tmp) < 0)
+				return -EINVAL;
+
+			info.interim_info.aes_data.key_len /= 8;
+
+			continue;
+		}
+	}
+
+	info.parse_writeback = parse_test_aes_writeback;
+	info.callbacks = aes_tests_vectors;
+	info.interim_callbacks = aes_tests_interim_vectors;
+	info.writeback_callbacks = aes_writeback_callbacks;
+	info.kat_check = rsp_test_aes_check;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index aec5bb9c6..32af47b1c 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -104,6 +104,12 @@ fips_test_parse_header(void)
 		return ret;
 
 	for (i = 0; i < info.nb_vec_lines; i++) {
+		if (strstr(info.vec[i], "AESVS")) {
+			info.algo = FIPS_TEST_ALGO_AES;
+			ret = parse_test_aes_init();
+			if (ret < 0)
+				return ret;
+		}
 
 		tmp = strstr(info.vec[i], "# Config info for ");
 		if (tmp != NULL) {
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index beb6bedda..5ac858d02 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -23,6 +23,7 @@
 #define FAX_FILE_PERFIX		"fax"
 
 enum fips_test_algorithms {
+		FIPS_TEST_ALGO_AES = 0,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -77,6 +78,21 @@ struct fips_test_callback {
 	struct fips_val *val;
 };
 
+enum fips_aesavs_test_types {
+	AESAVS_TYPE_GFXBOX = 0,
+	AESAVS_TYPE_KEYSBOX,
+	AESAVS_TYPE_VARKEY,
+	AESAVS_TYPE_VARTXT,
+	AESAVS_TYPE_MMT,
+	AESAVS_TYPE_MCT,
+};
+
+struct aesavs_interim_data {
+	enum fips_aesavs_test_types test_type;
+	uint32_t cipher_algo;
+	uint32_t key_len;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -88,6 +104,11 @@ struct fips_test_interim_info {
 	//uint8_t cryptodev_id;
 	char device_name[MAX_STRING_SIZE];
 
+	union {
+		struct aesavs_interim_data aes_data;
+
+	} interim_info;
+
 	enum fips_test_op op;
 
 	const struct fips_test_callback *callbacks;
@@ -118,6 +139,9 @@ void
 fips_test_write_one_case(void);
 
 int
+parse_test_aes_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 1cf043fc8..2e719e073 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -328,6 +328,340 @@ main(int argc, char *argv[])
 
 }
 
+#define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
+#define CRYPTODEV_FIPS_MAX_RETRIES	16
+
+typedef int (*fips_test_one_case_t)(void);
+typedef int (*fips_prepare_op_t)(void);
+typedef int (*fips_prepare_xform_t)(struct rte_crypto_sym_xform *);
+
+struct fips_test_ops {
+	fips_prepare_xform_t prepare_xform;
+	fips_prepare_op_t prepare_op;
+	fips_test_one_case_t test;
+} test_ops;
+
+static int
+prepare_cipher_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	rte_pktmbuf_reset(env.mbuf);
+
+	sym->m_src = env.mbuf;
+	sym->cipher.data.offset = 0;
+
+	memcpy(iv, vec.iv.val, vec.iv.len);
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		uint8_t *pt;
+
+		if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len);
+			return -EPERM;
+		}
+
+		pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len);
+
+		if (!pt) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(pt, vec.pt.val, vec.pt.len);
+		sym->cipher.data.length = vec.pt.len;
+
+	} else {
+		uint8_t *ct;
+
+		if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len);
+			return -EPERM;
+		}
+
+		ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len);
+
+		if (!ct) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(ct, vec.ct.val, vec.ct.len);
+		sym->cipher.data.length = vec.ct.len;
+	}
+
+	rte_crypto_op_attach_sym_session(env.op, env.sess);
+
+	return 0;
+}
+
+static int
+prepare_aes_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
+	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+			RTE_CRYPTO_CIPHER_OP_DECRYPT;
+	cipher_xform->key.data = vec.cipher_auth.key.val;
+	cipher_xform->key.length = vec.cipher_auth.key.len;
+	cipher_xform->iv.length = vec.iv.len;
+	cipher_xform->iv.offset = IV_OFF;
+
+	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_CBC;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_cipher(cap,
+			cipher_xform->key.length,
+			cipher_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, cipher_xform->key.length,
+				cipher_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static void
+get_writeback_data(struct fips_val *val)
+{
+	val->val = rte_pktmbuf_mtod(env.mbuf, uint8_t *);
+	val->len = rte_pktmbuf_pkt_len(env.mbuf);
+}
+
+static int
+fips_run_test(void)
+{
+	struct rte_crypto_sym_xform xform = {0};
+	uint16_t n_deqd;
+	int ret;
+
+	ret = test_ops.prepare_xform(&xform);
+	if (ret < 0)
+		return ret;
+
+	env.sess = rte_cryptodev_sym_session_create(env.mpool);
+	if (!env.sess)
+		return -ENOMEM;
+
+	ret = rte_cryptodev_sym_session_init(env.dev_id,
+			env.sess, &xform, env.mpool);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Init session\n",
+				ret);
+		return ret;
+	}
+
+	ret = test_ops.prepare_op();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
+				ret);
+		return ret;
+	}
+
+	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
+		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
+		return ret;
+	}
+
+	do {
+		struct rte_crypto_op *deqd_op;
+
+		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op,
+				1);
+	} while (n_deqd == 0);
+
+	vec.status = env.op->status;
+
+	rte_cryptodev_sym_session_clear(env.dev_id, env.sess);
+	rte_cryptodev_sym_session_free(env.sess);
+	env.sess = NULL;
+
+	return ret;
+}
+
+static int
+fips_generic_test(void)
+{
+	struct fips_val val;
+	int ret;
+
+	fips_test_write_one_case();
+
+	ret = fips_run_test();
+	if (ret < 0) {
+		if (ret == -EPERM) {
+			fprintf(info.fp_wr, "Bypass\n\n");
+			return 0;
+		}
+
+		return ret;
+	}
+
+	get_writeback_data(&val);
+
+	switch (info.file_type) {
+	case FIPS_TYPE_REQ:
+	case FIPS_TYPE_RSP:
+		if (info.parse_writeback == NULL)
+			return -EPERM;
+		ret = info.parse_writeback(&val);
+		if (ret < 0)
+			return ret;
+		break;
+	case FIPS_TYPE_FAX:
+		if (info.kat_check == NULL)
+			return -EPERM;
+		ret = info.kat_check(&val);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+
+	fprintf(info.fp_wr, "\n");
+
+	return 0;
+}
+
+static int
+fips_mct_aes_test(void)
+{
+#define AES_BLOCK_SIZE	16
+#define AES_EXTERN_ITER	100
+#define AES_INTERN_ITER	1000
+	struct fips_val val, val_key;
+	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
+	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
+	uint32_t i, j, k;
+	int ret;
+
+	for (i = 0; i < AES_EXTERN_ITER; i++) {
+		if (i != 0)
+			update_info_vec(i);
+
+		fips_test_write_one_case();
+
+		for (j = 0; j < AES_INTERN_ITER; j++) {
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM) {
+					fprintf(info.fp_wr, "Bypass\n");
+					return 0;
+				}
+
+				return ret;
+			}
+
+			get_writeback_data(&val);
+
+			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
+
+			if (j == 0) {
+				memcpy(prev_out, val.val, AES_BLOCK_SIZE);
+
+				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+					memcpy(vec.pt.val, vec.iv.val,
+							AES_BLOCK_SIZE);
+					memcpy(vec.iv.val, val.val,
+							AES_BLOCK_SIZE);
+				} else {
+					memcpy(vec.ct.val, vec.iv.val,
+							AES_BLOCK_SIZE);
+					memcpy(vec.iv.val, prev_in,
+							AES_BLOCK_SIZE);
+				}
+				continue;
+			}
+
+			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+				memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE);
+				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
+			} else {
+				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
+				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
+			}
+
+			if (j == AES_INTERN_ITER - 1)
+				continue;
+
+			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
+		}
+
+		info.parse_writeback(&val);
+		fprintf(info.fp_wr, "\n");
+
+		if (i == AES_EXTERN_ITER - 1)
+			continue;
+
+		/** update key */
+		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
+		for (k = 0; k < vec.cipher_auth.key.len; k++) {
+			switch (vec.cipher_auth.key.len) {
+			case 16:
+				val_key.val[k] ^= val.val[k];
+				break;
+			case 24:
+				if (k < 8)
+					val_key.val[k] ^= prev_out[k + 8];
+				else
+					val_key.val[k] ^= val.val[k - 8];
+				break;
+			case 32:
+				if (k < 16)
+					val_key.val[k] ^= prev_out[k];
+				else
+					val_key.val[k] ^= val.val[k - 16];
+				break;
+			default:
+				return -1;
+			}
+		}
+
+		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+			memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE);
+	}
+
+	return 0;
+}
+
+static int
+init_test_ops(void)
+{
+	switch (info.algo) {
+	case FIPS_TEST_ALGO_AES:
+		test_ops.prepare_op = prepare_cipher_op;
+		test_ops.prepare_xform  = prepare_aes_xform;
+		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
+			test_ops.test = fips_mct_aes_test;
+		else
+			test_ops.test = fips_generic_test;
+		break;
+
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
 static void
 print_test_block(void)
 {
@@ -344,7 +678,14 @@ fips_test_one_file(void)
 {
 	int fetch_ret = 0, ret;
 
-	while (fetch_ret == 0) {
+
+	ret = init_test_ops();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
+		return ret;
+	}
+
+	while (ret >= 0 && fetch_ret == 0) {
 		fetch_ret = fips_test_fetch_one_block();
 		if (fetch_ret < 0) {
 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
@@ -384,4 +725,6 @@ fips_test_one_file(void)
 
 	fips_test_clear();
 
+	return ret;
+
 }
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index e41773305..d04e9bbeb 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -9,6 +9,7 @@
 deps += ['cryptodev', 'bus_pci']
 allow_experimental_apis = true
 sources = files(
+	'cryptodev_fips_parse_aes.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v2 3/8] examples: add hmac parser
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 1/8] examples: add fips validation into examples Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 2/8] examples: add aes parser and enablement for test types Fan Zhang
@ 2018-10-04  9:40 ` Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 4/8] examples: add TDES parser and enablement for test types Fan Zhang
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for HMAC parser, to allow the
application to parser the hmac request files and to validate all
tests supported

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_hmac.c                    | 105 +++++++++++++++++++++
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |   9 ++
 examples/cryptodev_fips_validate/main.c            | 103 ++++++++++++++++++++
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 224 insertions(+)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index f058081ff..50be23cf5 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -6,6 +6,7 @@ APP = cryptodev_fips_validate_app
 
 # all source are stored in SRCS-y
 SRCS-y := cryptodev_fips_parse_aes.c
+SRCS-y += cryptodev_fips_parse_hmac.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c
new file mode 100644
index 000000000..2fbc2469c
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define ALGO_PREFIX	"[L="
+#define KEYLEN_STR	"Klen = "
+#define TAGLEN_STR	"Tlen = "
+
+#define COUNT_STR	"Count = "
+#define KEY_STR		"Key = "
+#define PT_STR		"Msg = "
+#define TAG_STR		"Mac = "
+
+struct hash_size_conversion {
+	const char *str;
+	enum rte_crypto_auth_algorithm algo;
+} hsc[] = {
+		{"20", RTE_CRYPTO_AUTH_SHA1_HMAC},
+		{"28", RTE_CRYPTO_AUTH_SHA224_HMAC},
+		{"32", RTE_CRYPTO_AUTH_SHA256_HMAC},
+		{"48", RTE_CRYPTO_AUTH_SHA384_HMAC},
+		{"64", RTE_CRYPTO_AUTH_SHA512_HMAC},
+};
+
+static int
+parse_interim_algo(__attribute__((__unused__)) const char *key,
+		char *text,
+		__attribute__((__unused__)) struct fips_val *val)
+{
+
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(hsc); i++) {
+		if (strstr(text, hsc[i].str)) {
+			info.interim_info.hmac_data.algo = hsc[i].algo;
+			break;
+		}
+	}
+
+	if (i == RTE_DIM(hsc))
+		return -1;
+
+	return 0;
+}
+
+struct fips_test_callback hmac_tests_vectors[] = {
+		{KEYLEN_STR, parser_read_uint32_val, &vec.cipher_auth.key},
+		{TAGLEN_STR, parser_read_uint32_val, &vec.cipher_auth.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key},
+		{PT_STR, parse_uint8_hex_str, &vec.pt},
+		{TAG_STR, parse_uint8_hex_str, &vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback hmac_tests_interim_vectors[] = {
+		{ALGO_PREFIX, parse_interim_algo, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_test_hmac_writeback(struct fips_val *val)
+{
+	struct fips_val val_local;
+
+	fprintf(info.fp_wr, "%s", TAG_STR);
+
+	val_local.val = val->val + vec.pt.len;
+	val_local.len = vec.cipher_auth.digest.len;
+
+	parse_write_hex_str(&val_local);
+	return 0;
+}
+
+static int
+rsp_test_hmac_check(struct fips_val *val)
+{
+	if (memcmp(val->val + vec.pt.len, vec.cipher_auth.digest.val,
+			vec.cipher_auth.digest.len) == 0)
+		fprintf(info.fp_wr, "Success\n");
+	else
+		fprintf(info.fp_wr, "Failed\n");
+
+	return 0;
+}
+
+int
+parse_test_hmac_init(void)
+{
+	info.op = FIPS_TEST_ENC_AUTH_GEN;
+	info.parse_writeback = parse_test_hmac_writeback;
+	info.callbacks = hmac_tests_vectors;
+	info.interim_callbacks = hmac_tests_interim_vectors;
+	info.writeback_callbacks = NULL;
+	info.kat_check = rsp_test_hmac_check;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index 32af47b1c..f1cd80253 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -109,6 +109,11 @@ fips_test_parse_header(void)
 			ret = parse_test_aes_init();
 			if (ret < 0)
 				return ret;
+		} else if (strstr(info.vec[i], "HMAC")) {
+			info.algo = FIPS_TEST_ALGO_HMAC;
+			ret = parse_test_hmac_init();
+			if (ret < 0)
+				return ret;
 		}
 
 		tmp = strstr(info.vec[i], "# Config info for ");
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index 5ac858d02..3cda9fe87 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -24,6 +24,7 @@
 
 enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
+		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -93,6 +94,10 @@ struct aesavs_interim_data {
 	uint32_t key_len;
 };
 
+struct hmac_interim_data {
+	enum rte_crypto_auth_algorithm algo;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -106,6 +111,7 @@ struct fips_test_interim_info {
 
 	union {
 		struct aesavs_interim_data aes_data;
+		struct hmac_interim_data hmac_data;
 
 	} interim_info;
 
@@ -142,6 +148,9 @@ int
 parse_test_aes_init(void);
 
 int
+parse_test_hmac_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 2e719e073..cb102a920 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -400,6 +400,67 @@ prepare_cipher_op(void)
 }
 
 static int
+prepare_auth_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	rte_pktmbuf_reset(env.mbuf);
+
+	sym->m_src = env.mbuf;
+	sym->auth.data.offset = 0;
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		uint8_t *pt;
+
+		if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len);
+			return -EPERM;
+		}
+
+		pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len +
+				vec.cipher_auth.digest.len);
+
+		if (!pt) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(pt, vec.pt.val, vec.pt.len);
+		sym->auth.data.length = vec.pt.len;
+		sym->auth.digest.data = pt + vec.pt.len;
+		sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+				env.mbuf, vec.pt.len);
+
+	} else {
+		uint8_t *ct;
+
+		if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len);
+			return -EPERM;
+		}
+
+		ct = (uint8_t *)rte_pktmbuf_append(env.mbuf,
+				vec.ct.len + vec.cipher_auth.digest.len);
+
+		if (!ct) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(ct, vec.ct.val, vec.ct.len);
+		sym->auth.data.length = vec.ct.len;
+		sym->auth.digest.data = vec.cipher_auth.digest.val;
+		sym->auth.digest.phys_addr = rte_malloc_virt2iova(
+				sym->auth.digest.data);
+	}
+
+	rte_crypto_op_attach_sym_session(env.op, env.sess);
+}
+
+static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
 	const struct rte_cryptodev_symmetric_capability *cap;
@@ -439,6 +500,43 @@ prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = info.interim_info.hmac_data.algo;
+	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
+	auth_xform->digest_length = vec.cipher_auth.digest.len;
+	auth_xform->key.data = vec.cipher_auth.key.val;
+	auth_xform->key.length = vec.cipher_auth.key.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length, 0) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static void
 get_writeback_data(struct fips_val *val)
 {
@@ -654,6 +752,11 @@ init_test_ops(void)
 		else
 			test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_HMAC:
+		test_ops.prepare_op = prepare_auth_op;
+		test_ops.prepare_xform = prepare_hmac_xform;
+		test_ops.test = fips_generic_test;
+		break;
 
 	default:
 		return -1;
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index d04e9bbeb..dcf90bbbb 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -10,6 +10,7 @@ deps += ['cryptodev', 'bus_pci']
 allow_experimental_apis = true
 sources = files(
 	'cryptodev_fips_parse_aes.c',
+	'cryptodev_fips_parse_hmac.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v2 4/8] examples: add TDES parser and enablement for test types
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
                   ` (2 preceding siblings ...)
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 3/8] examples: add hmac parser Fan Zhang
@ 2018-10-04  9:40 ` Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 5/8] examples: add gcm parser Fan Zhang
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for TDES parser, to allow the
application to parser the TDES request files and to validate all
test types supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_3des.c                    | 259 +++++++++++++++++++++
 .../cryptodev_fips_parse_aes.c                     |   2 +
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |  21 ++
 examples/cryptodev_fips_validate/main.c            | 175 ++++++++++++++
 examples/cryptodev_fips_validate/meson.build       |   1 +
 7 files changed, 464 insertions(+)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index 50be23cf5..54ea43ffd 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -7,6 +7,7 @@ APP = cryptodev_fips_validate_app
 # all source are stored in SRCS-y
 SRCS-y := cryptodev_fips_parse_aes.c
 SRCS-y += cryptodev_fips_parse_hmac.c
+SRCS-y += cryptodev_fips_parse_3des.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c
new file mode 100644
index 000000000..82e9132a7
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c
@@ -0,0 +1,259 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include <rte_malloc.h>
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define NEW_LINE_STR	"#"
+#define TEST_TYPE_KEY	" for CBC"
+#define TEST_CBCI_KEY	" for CBCI"
+
+#define ENC_STR		"[ENCRYPT]"
+#define DEC_STR		"[DECRYPT]"
+
+#define COUNT_STR	"COUNT = "
+#define KEY1_STR	"KEY1 = "
+#define KEY2_STR	"KEY2 = "
+#define KEY3_STR	"KEY3 = "
+
+#define KEYS_STR	"KEYs = "
+#define IV_STR		"IV = "
+#define PT_STR		"PLAINTEXT = "
+#define CT_STR		"CIPHERTEXT = "
+#define NK_STR		"NumKeys = "
+
+#define SET_STR		" = "
+
+#define PLAIN_TEXT	0
+#define CIPHER_TEXT	1
+#define KEY_TEXT	2
+#define IV_TEXT		3
+
+#define DEVICE_STR	"# Config Info for : "
+
+struct {
+	uint32_t type;
+	const char *desc;
+} test_types[] = {
+		{TDES_INVERSE_PERMUTATION, "INVERSE PERMUTATION"},
+		{TDES_PERMUTATION, "PERMUTATION OPERATION"},
+		{TDES_SUBSTITUTION_TABLE, "SUBSTITUTION TABLE"},
+		{TDES_VARIABLE_KEY, "VARIABLE KEY"},
+		{TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"},
+		{TDES_VARIABLE_TEXT, "KAT"},
+		{TDES_MCT, "Monte Carlo (Modes) Test"},
+		{TDES_MMT, "Multi block Message Test"},
+};
+
+static int
+writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val);
+
+static int
+parse_3des_uint8_hex_str(const char *key, char *src, struct fips_val *val);
+
+static int
+parse_tdes_interim(const char *key,
+		__attribute__((__unused__)) char *text,
+		struct fips_val *val);
+
+struct fips_test_callback tdes_tests_vectors[] = {
+		{KEYS_STR, parse_3des_uint8_hex_str, &vec.cipher_auth.key},
+		{KEY1_STR, parse_3des_uint8_hex_str, &vec.cipher_auth.key},
+		{KEY2_STR, parse_3des_uint8_hex_str, &vec.cipher_auth.key},
+		{KEY3_STR, parse_3des_uint8_hex_str, &vec.cipher_auth.key},
+		{IV_STR, parse_uint8_hex_str, &vec.iv},
+		{PT_STR, parse_uint8_hex_str, &vec.pt},
+		{CT_STR, parse_uint8_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback tdes_tests_interim_vectors[] = {
+		{ENC_STR, parse_tdes_interim, NULL},
+		{DEC_STR, parse_tdes_interim, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback tdes_writeback_callbacks[] = {
+		/** First element is used to pass COUNT string */
+		{COUNT_STR, NULL, NULL},
+		{IV_STR, writeback_hex_str, &vec.iv},
+		{KEY1_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
+		{KEY2_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
+		{KEY3_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
+		{KEYS_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
+		{PT_STR, writeback_hex_str, &vec.pt},
+		{CT_STR, writeback_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_tdes_interim(const char *key,
+		__attribute__((__unused__)) char *text,
+		__attribute__((__unused__)) struct fips_val *val)
+{
+	if (strstr(key, ENC_STR))
+		info.op = FIPS_TEST_ENC_AUTH_GEN;
+	else if (strstr(key, DEC_STR))
+		info.op = FIPS_TEST_DEC_AUTH_VERIF;
+	else if (strstr(NK_STR, "NumKeys = 1"))
+		info.interim_info.tdes_data.nb_keys = 1;
+	else if (strstr(NK_STR, "NumKeys = 2"))
+		info.interim_info.tdes_data.nb_keys = 2;
+	else if (strstr(NK_STR, "NumKeys = 3"))
+		info.interim_info.tdes_data.nb_keys = 3;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+parse_3des_uint8_hex_str(const char *key, char *src, struct fips_val *val)
+{
+	uint8_t tmp_key[24] = {0};
+	uint32_t len, i;
+
+	src += strlen(key);
+
+	len = strlen(src) / 2;
+
+	if (val->val) {
+		memcpy(tmp_key, val->val, val->len);
+		rte_free(val->val);
+	}
+
+	val->val = rte_zmalloc(NULL, 24, 0);
+	if (!val->val)
+		return -1;
+
+	memcpy(val->val, tmp_key, 24);
+
+	if (strstr(key, KEYS_STR)) {
+		for (i = 0; i < len; i++) {
+			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
+
+			if (parser_read_uint8_hex(&val->val[i], byte) < 0)
+				return -EINVAL;
+		}
+
+		memcpy(val->val + 8, val->val, 8);
+		memcpy(val->val + 16, val->val, 8);
+
+	} else if (strstr(key, KEY1_STR)) {
+		for (i = 0; i < len; i++) {
+			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
+
+			if (parser_read_uint8_hex(&val->val[i], byte) < 0)
+				return -EINVAL;
+		}
+
+		if (info.interim_info.tdes_data.nb_keys == 2)
+			memcpy(val->val + 16, val->val, 8);
+
+	} else if (strstr(key, KEY2_STR)) {
+		for (i = 0; i < len; i++) {
+			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
+
+			if (parser_read_uint8_hex(&val->val[i + 8], byte) < 0)
+				return -EINVAL;
+		}
+
+	} else if (strstr(key, KEY3_STR)) {
+		for (i = 0; i < len; i++) {
+			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
+
+			if (parser_read_uint8_hex(&val->val[i + 16], byte) < 0)
+				return -EINVAL;
+		}
+	} else
+		return -EINVAL;
+
+	val->len = 24;
+
+	return 0;
+}
+
+static int
+parse_test_tdes_writeback(struct fips_val *val)
+{
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+		fprintf(info.fp_wr, "%s", CT_STR);
+	else
+		fprintf(info.fp_wr, "%s", PT_STR);
+
+	parse_write_hex_str(val);
+
+	return 0;
+
+}
+
+static int
+writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val)
+{
+	struct fips_val tmp_val;
+
+	tmp_val.len = 8;
+
+	if (strstr(key, KEY1_STR))
+		tmp_val.val = val->val;
+	else if (strstr(key, KEY2_STR))
+		tmp_val.val = val->val + 8;
+	else if (strstr(key, KEY3_STR))
+		tmp_val.val = val->val + 16;
+
+	return writeback_hex_str(key, dst, &tmp_val);
+}
+
+static int
+rsp_test_tdes_check(struct fips_val *val)
+{
+	struct fips_val *data;
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+		data = &vec.ct;
+	else
+		data = &vec.pt;
+
+	if (memcmp(val->val, data->val, val->len) == 0)
+		fprintf(info.fp_wr, "Success\n");
+	else
+		fprintf(info.fp_wr, "Failed\n");
+
+	return 0;
+}
+
+int
+parse_test_tdes_init(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+		uint32_t j;
+
+		if (strstr(line, TEST_CBCI_KEY))
+			return -EPERM;
+
+		for (j = 0; j < RTE_DIM(test_types); j++)
+			if (strstr(line, test_types[j].desc)) {
+				info.interim_info.tdes_data.test_type =
+						test_types[j].type;
+				break;
+			}
+	}
+
+	info.parse_writeback = parse_test_tdes_writeback;
+	info.callbacks = tdes_tests_vectors;
+	info.interim_callbacks = tdes_tests_interim_vectors;
+	info.writeback_callbacks = tdes_writeback_callbacks;
+	info.kat_check = rsp_test_tdes_check;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
index 39dbd6ff9..cc2775428 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
@@ -33,6 +33,8 @@ struct {
 		{AESAVS_TYPE_KEYSBOX, "KeySbox"},
 		{AESAVS_TYPE_VARKEY, "VarKey"},
 		{AESAVS_TYPE_VARTXT, "VarTxt"},
+		{TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"},
+		{TDES_VARIABLE_TEXT, "KAT"},
 		{AESAVS_TYPE_MMT, "MMT"},
 		{AESAVS_TYPE_MCT, "MCT"},
 };
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index f1cd80253..bb396e54d 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -114,6 +114,11 @@ fips_test_parse_header(void)
 			ret = parse_test_hmac_init();
 			if (ret < 0)
 				return ret;
+		} else if (strstr(info.vec[i], "TDES")) {
+			info.algo = FIPS_TEST_ALGO_TDES;
+			ret = parse_test_tdes_init();
+			if (ret < 0)
+				return 0;
 		}
 
 		tmp = strstr(info.vec[i], "# Config info for ");
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index 3cda9fe87..c9b11dda2 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -25,6 +25,7 @@
 enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
 		FIPS_TEST_ALGO_HMAC,
+		FIPS_TEST_ALGO_TDES,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -88,6 +89,17 @@ enum fips_aesavs_test_types {
 	AESAVS_TYPE_MCT,
 };
 
+enum fips_tdes_test_types {
+	TDES_INVERSE_PERMUTATION = 0,
+	TDES_PERMUTATION,
+	TDES_SUBSTITUTION_TABLE,
+	TDES_VARIABLE_KEY,
+	TDES_VARIABLE_TEXT,
+	TDES_KAT,
+	TDES_MCT, /* Monte Carlo (Modes) Test */
+	TDES_MMT /* Multi block Message Test */
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -98,6 +110,11 @@ struct hmac_interim_data {
 	enum rte_crypto_auth_algorithm algo;
 };
 
+struct tdes_interim_data {
+	enum fips_tdes_test_types test_type;
+	uint32_t nb_keys;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -112,6 +129,7 @@ struct fips_test_interim_info {
 	union {
 		struct aesavs_interim_data aes_data;
 		struct hmac_interim_data hmac_data;
+		struct tdes_interim_data tdes_data;
 
 	} interim_info;
 
@@ -148,6 +166,9 @@ int
 parse_test_aes_init(void);
 
 int
+parse_test_tdes_init(void);
+
+int
 parse_test_hmac_init(void);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index cb102a920..8a9622f02 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -501,6 +501,46 @@ prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 }
 
 static int
+prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
+	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+			RTE_CRYPTO_CIPHER_OP_DECRYPT;
+	cipher_xform->key.data = vec.cipher_auth.key.val;
+	cipher_xform->key.length = vec.cipher_auth.key.len;
+	cipher_xform->iv.length = vec.iv.len;
+	cipher_xform->iv.offset = IV_OFF;
+
+	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_3DES_CBC;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_cipher(cap,
+			cipher_xform->key.length,
+			cipher_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, cipher_xform->key.length,
+				cipher_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
 prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
 {
 	const struct rte_cryptodev_symmetric_capability *cap;
@@ -639,6 +679,133 @@ fips_generic_test(void)
 }
 
 static int
+fips_mct_tdes_test(void)
+{
+#define TDES_BLOCK_SIZE		16
+#define TDES_EXTERN_ITER	400
+#define TDES_INTERN_ITER	10000
+	struct fips_val val, val_key;
+	uint8_t prev_out[TDES_BLOCK_SIZE];
+	uint8_t prev_prev_out[TDES_BLOCK_SIZE];
+	uint8_t prev_in[TDES_BLOCK_SIZE];
+	uint32_t i, j, k;
+	int ret;
+
+	for (i = 0; i < TDES_EXTERN_ITER; i++) {
+		if (i != 0)
+			update_info_vec(i);
+
+		fips_test_write_one_case();
+
+		for (j = 0; j < TDES_INTERN_ITER; j++) {
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM) {
+					fprintf(info.fp_wr, "Bypass\n");
+					return 0;
+				}
+
+				return ret;
+			}
+
+			get_writeback_data(&val);
+
+			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
+
+			if (j == 0) {
+				memcpy(prev_out, val.val, TDES_BLOCK_SIZE);
+
+				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+					memcpy(vec.pt.val, vec.iv.val,
+							TDES_BLOCK_SIZE);
+					memcpy(vec.iv.val, val.val,
+							TDES_BLOCK_SIZE);
+				} else {
+					memcpy(vec.iv.val, vec.ct.val,
+							TDES_BLOCK_SIZE);
+					memcpy(vec.ct.val, val.val,
+							TDES_BLOCK_SIZE);
+				}
+				continue;
+			}
+
+			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+				memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE);
+				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
+			} else {
+				memcpy(vec.iv.val, vec.ct.val, TDES_BLOCK_SIZE);
+				memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE);
+			}
+
+			if (j == TDES_INTERN_ITER - 1)
+				continue;
+
+			memcpy(prev_out, val.val, TDES_BLOCK_SIZE);
+
+			if (j == TDES_INTERN_ITER - 3)
+				memcpy(prev_prev_out, val.val, TDES_BLOCK_SIZE);
+		}
+
+		info.parse_writeback(&val);
+		fprintf(info.fp_wr, "\n");
+
+		if (i == TDES_EXTERN_ITER - 1)
+			continue;
+
+		/** update key */
+		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
+
+		if (info.interim_info.tdes_data.nb_keys == 0) {
+			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
+				info.interim_info.tdes_data.nb_keys = 1;
+			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
+				info.interim_info.tdes_data.nb_keys = 2;
+			else
+				info.interim_info.tdes_data.nb_keys = 3;
+
+		}
+
+		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
+
+			switch (info.interim_info.tdes_data.nb_keys) {
+			case 3:
+				val_key.val[k] ^= val.val[k];
+				val_key.val[k + 8] ^= prev_out[k];
+				val_key.val[k + 16] ^= prev_prev_out[k];
+				break;
+			case 2:
+				val_key.val[k] ^= val.val[k];
+				val_key.val[k + 8] ^= prev_out[k];
+				val_key.val[k + 16] ^= val.val[k];
+				break;
+			default: /* case 1 */
+				val_key.val[k] ^= val.val[k];
+				val_key.val[k + 8] ^= val.val[k];
+				val_key.val[k + 16] ^= val.val[k];
+				break;
+			}
+
+		}
+
+		for (k = 0; k < 24; k++)
+			val_key.val[k] = (__builtin_popcount(val_key.val[k]) &
+					0x1) ?
+					val_key.val[k] : (val_key.val[k] ^ 0x1);
+
+		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+			memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE);
+			memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
+		} else {
+			memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
+			memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE);
+		}
+	}
+
+	return 0;
+}
+
+static int
 fips_mct_aes_test(void)
 {
 #define AES_BLOCK_SIZE	16
@@ -757,6 +924,14 @@ init_test_ops(void)
 		test_ops.prepare_xform = prepare_hmac_xform;
 		test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_TDES:
+		test_ops.prepare_op = prepare_cipher_op;
+		test_ops.prepare_xform  = prepare_tdes_xform;
+		if (info.interim_info.tdes_data.test_type == TDES_MCT)
+			test_ops.test = fips_mct_tdes_test;
+		else
+			test_ops.test = fips_generic_test;
+		break;
 
 	default:
 		return -1;
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index dcf90bbbb..a18e76d4b 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -11,6 +11,7 @@ allow_experimental_apis = true
 sources = files(
 	'cryptodev_fips_parse_aes.c',
 	'cryptodev_fips_parse_hmac.c',
+	'cryptodev_fips_parse_3des.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v2 5/8] examples: add gcm parser
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
                   ` (3 preceding siblings ...)
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 4/8] examples: add TDES parser and enablement for test types Fan Zhang
@ 2018-10-04  9:40 ` Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 6/8] examples: add cmac parser and enablement for test types Fan Zhang
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for GCM parser, to allow the
application to parser the GCM request file and to validate all
tests supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_gcm.c                     | 125 +++++++++++++++++++++
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |   4 +
 examples/cryptodev_fips_validate/main.c            | 116 ++++++++++++++++++-
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 251 insertions(+), 1 deletion(-)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index 54ea43ffd..1eb0108bd 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -8,6 +8,7 @@ APP = cryptodev_fips_validate_app
 SRCS-y := cryptodev_fips_parse_aes.c
 SRCS-y += cryptodev_fips_parse_hmac.c
 SRCS-y += cryptodev_fips_parse_3des.c
+SRCS-y += cryptodev_fips_parse_gcm.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c
new file mode 100644
index 000000000..6999dad7f
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define NEW_LINE_STR	"#"
+#define OP_STR		"GCM "
+
+#define PARAM_PREFIX	"["
+#define KEYLEN_STR	"Keylen = "
+#define IVLEN_STR	"IVlen = "
+#define PTLEN_STR	"PTlen = "
+#define AADLEN_STR	"AADlen = "
+#define TAGLEN_STR	"Taglen = "
+
+#define COUNT_STR	"Count = "
+#define KEY_STR		"Key = "
+#define IV_STR		"IV = "
+#define PT_STR		"PT = "
+#define CT_STR		"CT = "
+#define TAG_STR		"Tag = "
+#define AAD_STR		"AAD = "
+
+#define OP_ENC_STR	"Encrypt"
+#define OP_DEC_STR	"Decrypt"
+
+#define NEG_TEST_STR	"FAIL"
+
+struct fips_test_callback gcm_dec_vectors[] = {
+		{KEY_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{CT_STR, parse_uint8_known_len_hex_str, &vec.ct},
+		{AAD_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.aad},
+		{TAG_STR, parse_uint8_known_len_hex_str,
+				&vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+struct fips_test_callback gcm_interim_vectors[] = {
+		{KEYLEN_STR, parser_read_uint32_bit_val, &vec.cipher_auth.key},
+		{IVLEN_STR, parser_read_uint32_bit_val, &vec.iv},
+		{PTLEN_STR, parser_read_uint32_bit_val, &vec.pt},
+		{AADLEN_STR, parser_read_uint32_bit_val, &vec.cipher_auth.aad},
+		{TAGLEN_STR, parser_read_uint32_bit_val,
+				&vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback gcm_enc_vectors[] = {
+		{KEY_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{AAD_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.aad},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_test_gcm_writeback(struct fips_val *val)
+{
+	struct fips_val tmp_val;
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		fprintf(info.fp_wr, "%s", CT_STR);
+
+		tmp_val.val = val->val;
+		tmp_val.len = vec.pt.len;
+
+		parse_write_hex_str(&tmp_val);
+
+		fprintf(info.fp_wr, "%s", TAG_STR);
+
+		tmp_val.val = val->val + vec.pt.len;
+		tmp_val.len = val->len - vec.pt.len;
+
+		parse_write_hex_str(&tmp_val);
+	} else {
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
+			fprintf(info.fp_wr, "%s", PT_STR);
+
+			tmp_val.val = val->val;
+			tmp_val.len = vec.pt.len;
+
+			parse_write_hex_str(&tmp_val);
+		} else
+			fprintf(info.fp_wr, "%s\n", NEG_TEST_STR);
+	}
+
+	return 0;
+}
+
+int
+parse_test_gcm_init(void)
+{
+	char *tmp;
+	uint32_t i;
+
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+
+
+		tmp = strstr(line, OP_STR);
+		if (tmp) {
+			if (strstr(line, OP_ENC_STR)) {
+				info.op = FIPS_TEST_ENC_AUTH_GEN;
+				info.callbacks = gcm_enc_vectors;
+			} else if (strstr(line, OP_DEC_STR)) {
+				info.op = FIPS_TEST_DEC_AUTH_VERIF;
+				info.callbacks = gcm_dec_vectors;
+			} else
+				return -EINVAL;
+		}
+	}
+
+	info.interim_callbacks = gcm_interim_vectors;
+	info.parse_writeback = parse_test_gcm_writeback;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index bb396e54d..d45c88de6 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -109,6 +109,11 @@ fips_test_parse_header(void)
 			ret = parse_test_aes_init();
 			if (ret < 0)
 				return ret;
+		} else if (strstr(info.vec[i], "GCM")) {
+			info.algo = FIPS_TEST_ALGO_AES_GCM;
+			ret = parse_test_gcm_init();
+			if (ret < 0)
+				return ret;
 		} else if (strstr(info.vec[i], "HMAC")) {
 			info.algo = FIPS_TEST_ALGO_HMAC;
 			ret = parse_test_hmac_init();
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index c9b11dda2..685bc0bf8 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -24,6 +24,7 @@
 
 enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
+		FIPS_TEST_ALGO_AES_GCM,
 		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_TDES,
 		FIPS_TEST_ALGO_MAX
@@ -172,6 +173,9 @@ int
 parse_test_hmac_init(void);
 
 int
+parse_test_gcm_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 8a9622f02..426baf002 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -461,6 +461,70 @@ prepare_auth_op(void)
 }
 
 static int
+prepare_aead_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	rte_pktmbuf_reset(env.mbuf);
+
+	memcpy(iv, vec.iv.val, vec.iv.len);
+
+	sym->m_src = env.mbuf;
+	sym->aead.data.offset = 0;
+	sym->aead.aad.data = vec.aead.aad.val;
+	sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		uint8_t *pt;
+
+		if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len);
+			return -EPERM;
+		}
+
+		pt = (uint8_t *)rte_pktmbuf_append(env.mbuf,
+				vec.pt.len + vec.aead.digest.len);
+
+		if (!pt) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(pt, vec.pt.val, vec.pt.len);
+		sym->aead.data.length = vec.pt.len;
+		sym->aead.digest.data = pt + vec.pt.len;
+		sym->aead.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+				env.mbuf, vec.pt.len);
+	} else {
+		uint8_t *ct;
+
+		if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len);
+			return -EPERM;
+		}
+
+		ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len);
+
+		if (!ct) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(ct, vec.ct.val, vec.ct.len);
+		sym->aead.data.length = vec.ct.len;
+		sym->aead.digest.data = vec.aead.digest.val;
+		sym->aead.digest.phys_addr = rte_malloc_virt2iova(
+				sym->aead.digest.data);
+	}
+
+	rte_crypto_op_attach_sym_session(env.op, env.sess);
+}
+
+static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
 	const struct rte_cryptodev_symmetric_capability *cap;
@@ -577,6 +641,52 @@ prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
+	aead_xform->aad_length = vec.aead.aad.len;
+	aead_xform->digest_length = vec.aead.digest.len;
+	aead_xform->iv.offset = IV_OFF;
+	aead_xform->iv.length = vec.iv.len;
+	aead_xform->key.data = vec.aead.key.val;
+	aead_xform->key.length = vec.aead.key.len;
+	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AEAD_OP_ENCRYPT :
+			RTE_CRYPTO_AEAD_OP_DECRYPT;
+
+	cap_idx.algo.aead = aead_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_aead(cap,
+			aead_xform->key.length,
+			aead_xform->digest_length, aead_xform->aad_length,
+			aead_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1,
+			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
+				info.device_name, aead_xform->key.length,
+				aead_xform->digest_length,
+				aead_xform->aad_length,
+				aead_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static void
 get_writeback_data(struct fips_val *val)
 {
@@ -932,7 +1042,11 @@ init_test_ops(void)
 		else
 			test_ops.test = fips_generic_test;
 		break;
-
+	case FIPS_TEST_ALGO_AES_GCM:
+		test_ops.prepare_op = prepare_aead_op;
+		test_ops.prepare_xform = prepare_gcm_xform;
+		test_ops.test = fips_generic_test;
+		break;
 	default:
 		return -1;
 	}
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index a18e76d4b..510d2a79e 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -12,6 +12,7 @@ sources = files(
 	'cryptodev_fips_parse_aes.c',
 	'cryptodev_fips_parse_hmac.c',
 	'cryptodev_fips_parse_3des.c',
+	'cryptodev_fips_parse_gcm.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v2 6/8] examples: add cmac parser and enablement for test types
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
                   ` (4 preceding siblings ...)
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 5/8] examples: add gcm parser Fan Zhang
@ 2018-10-04  9:40 ` Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 7/8] examples: add ccm " Fan Zhang
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for CMAC parser, to allow the
application to parser the cmac request files and to validate all
test types supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_cmac.c                    | 116 +++++++++++++++++++++
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |   4 +
 examples/cryptodev_fips_validate/main.c            |  43 ++++++++
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 170 insertions(+)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index 1eb0108bd..f5c2705d5 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -9,6 +9,7 @@ SRCS-y := cryptodev_fips_parse_aes.c
 SRCS-y += cryptodev_fips_parse_hmac.c
 SRCS-y += cryptodev_fips_parse_3des.c
 SRCS-y += cryptodev_fips_parse_gcm.c
+SRCS-y += cryptodev_fips_parse_cmac.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c
new file mode 100644
index 000000000..37c6317ae
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <rte_string_fns.h>
+
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define NEW_LINE_STR	"#"
+#define OP_STR		"CMAC"
+
+#define ALGO_STR	"Alg = "
+#define MODE_STR	"Mode = "
+
+#define COUNT_STR	"Count = "
+#define KLEN_STR	"Klen = "
+#define PTLEN_STR	"Mlen = "
+#define TAGLEN_STR	"Tlen = "
+#define KEY_STR		"Key = "
+#define PT_STR		"Msg = "
+#define TAG_STR		"Mac = "
+
+#define GEN_STR		"Generate"
+#define VERIF_STR	"Verify"
+
+#define POS_NEG_STR	"Result = "
+#define PASS_STR	"P"
+#define FAIL_STR	"F"
+
+struct hash_algo_conversion {
+	const char *str;
+	enum fips_test_algorithms algo;
+} cmac_algo[] = {
+		{"AES", FIPS_TEST_ALGO_AES_CMAC},
+};
+
+static int
+parse_test_cmac_writeback(struct fips_val *val)
+{
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		struct fips_val tmp_val = {val->val + vec.pt.len,
+				vec.cipher_auth.digest.len};
+
+		fprintf(info.fp_wr, "%s", TAG_STR);
+		parse_write_hex_str(&tmp_val);
+	} else {
+		fprintf(info.fp_wr, "%s", POS_NEG_STR);
+
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)
+			fprintf(info.fp_wr, "%s\n", PASS_STR);
+		else if (vec.status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED)
+			fprintf(info.fp_wr, "%s\n", FAIL_STR);
+		else
+			fprintf(info.fp_wr, "Error\n");
+	}
+
+	return 0;
+}
+
+struct fips_test_callback cmac_tests_vectors[] = {
+		{KLEN_STR, parser_read_uint32_val, &vec.cipher_auth.key},
+		{PTLEN_STR, parser_read_uint32_val, &vec.pt},
+		{TAGLEN_STR, parser_read_uint32_val, &vec.cipher_auth.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{TAG_STR, parse_uint8_known_len_hex_str,
+				&vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+int
+parse_test_cmac_init(void)
+{
+	char *tmp;
+	uint32_t i, j;
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+
+		tmp = strstr(line, ALGO_STR);
+		if (!tmp)
+			continue;
+
+		for (j = 0; j < RTE_DIM(cmac_algo); j++) {
+			if (!strstr(line, cmac_algo[j].str))
+				continue;
+
+			info.algo = cmac_algo[j].algo;
+			break;
+		}
+
+		if (j == RTE_DIM(cmac_algo))
+			return -EINVAL;
+
+		tmp = strstr(line, MODE_STR);
+		if (!tmp)
+			return -1;
+
+		if (strstr(tmp, GEN_STR))
+			info.op = FIPS_TEST_ENC_AUTH_GEN;
+		else if (strstr(tmp, VERIF_STR))
+			info.op = FIPS_TEST_DEC_AUTH_VERIF;
+		else
+			return -EINVAL;
+	}
+
+	info.parse_writeback = parse_test_cmac_writeback;
+	info.callbacks = cmac_tests_vectors;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index d45c88de6..4617c67e2 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -114,6 +114,11 @@ fips_test_parse_header(void)
 			ret = parse_test_gcm_init();
 			if (ret < 0)
 				return ret;
+		} else if (strstr(info.vec[i], "CMAC")) {
+			info.algo = FIPS_TEST_ALGO_AES_CMAC;
+			ret = parse_test_cmac_init();
+			if (ret < 0)
+				return 0;
 		} else if (strstr(info.vec[i], "HMAC")) {
 			info.algo = FIPS_TEST_ALGO_HMAC;
 			ret = parse_test_hmac_init();
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index 685bc0bf8..7bd1e9a6f 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -25,6 +25,7 @@
 enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
 		FIPS_TEST_ALGO_AES_GCM,
+		FIPS_TEST_ALGO_AES_CMAC,
 		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_TDES,
 		FIPS_TEST_ALGO_MAX
@@ -176,6 +177,9 @@ int
 parse_test_gcm_init(void);
 
 int
+parse_test_cmac_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 426baf002..a983a66f5 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -687,6 +687,44 @@ prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
+	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
+	auth_xform->digest_length = vec.cipher_auth.digest.len;
+	auth_xform->key.data = vec.cipher_auth.key.val;
+	auth_xform->key.length = vec.cipher_auth.key.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length, 0) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static void
 get_writeback_data(struct fips_val *val)
 {
@@ -1047,6 +1085,11 @@ init_test_ops(void)
 		test_ops.prepare_xform = prepare_gcm_xform;
 		test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_AES_CMAC:
+		test_ops.prepare_op = prepare_auth_op;
+		test_ops.prepare_xform = prepare_cmac_xform;
+		test_ops.test = fips_generic_test;
+		break;
 	default:
 		return -1;
 	}
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index 510d2a79e..4889d7095 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -13,6 +13,7 @@ sources = files(
 	'cryptodev_fips_parse_hmac.c',
 	'cryptodev_fips_parse_3des.c',
 	'cryptodev_fips_parse_gcm.c',
+	'cryptodev_fips_parse_cmac.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v2 7/8] examples: add ccm parser and enablement for test types
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
                   ` (5 preceding siblings ...)
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 6/8] examples: add cmac parser and enablement for test types Fan Zhang
@ 2018-10-04  9:40 ` Fan Zhang
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 8/8] doc: add guides for fips validation Fan Zhang
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
  8 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for CCM parser, to allow the
application to parser the ccm request files and to validate all
test types supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_ccm.c                     | 272 +++++++++++++++++++++
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |  22 ++
 examples/cryptodev_fips_validate/main.c            |  56 ++++-
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 356 insertions(+), 1 deletion(-)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index f5c2705d5..4f1dc6b5d 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -10,6 +10,7 @@ SRCS-y += cryptodev_fips_parse_hmac.c
 SRCS-y += cryptodev_fips_parse_3des.c
 SRCS-y += cryptodev_fips_parse_gcm.c
 SRCS-y += cryptodev_fips_parse_cmac.c
+SRCS-y += cryptodev_fips_parse_ccm.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c
new file mode 100644
index 000000000..0fdb75ad4
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c
@@ -0,0 +1,272 @@
+/* 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 DVPT_STR	"CCM-DVPT"
+#define VADT_STR	"CCM-VADT"
+#define VPT_STR		"CCM-VPT"
+#define VNT_STR		"CCM-VNT"
+#define VTT_STR		"CCM-VTT"
+
+#define PARAM_PREFIX	"["
+#define ALEN_PREFIX	"Alen = "
+#define PLEN_PREFIX	"Plen = "
+#define IVLEN_PREFIX	"Nlen = "
+#define DIGESTL_PREFIX	"Tlen = "
+
+#define COUNT_STR	"Count = "
+#define KEY_STR		"Key = "
+#define IV_STR		"Nonce = "
+#define PT_STR		"Payload = "
+#define CT_STR		"CT = "
+#define AAD_STR		"Adata = "
+#define POS_NEG_STR	"Result = "
+
+#define POS_KEYWORD	"Pass"
+#define NEG_KEYWORD	"Fail"
+
+static int
+parser_dvpt_interim(const char *key, char *src, struct fips_val *val)
+{
+	char *tmp, c, value[10];
+	char num_pattern[] = "0123456789";
+	int i = 0;
+
+	memset(value, 0, 10);
+
+	tmp = strstr(src, key);
+	if (!tmp)
+		return -1;
+
+	tmp += strlen(key);
+
+	c = tmp[0];
+
+	while (strchr(num_pattern, c) && i < 10) {
+		value[i++] = c;
+		c = tmp[i];
+	}
+
+	return parser_read_uint32_val("", value, val);
+}
+
+static int
+parse_dvpt_ct_hex_str(const char *key, char *src, struct fips_val *val)
+{
+	int ret;
+
+	val->len = vec.pt.len;
+
+	ret = parse_uint8_known_len_hex_str(key, src, val);
+	if (ret < 0)
+		return ret;
+
+	src += strlen(key) + val->len * 2;
+
+	ret = parse_uint8_known_len_hex_str("", src, &vec.aead.digest);
+	if (ret < 0) {
+		rte_free(val->val);
+		memset(val, 0, sizeof(*val));
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+parse_uint8_ccm_aad_str(const char *key, char *src, struct fips_val *val)
+{
+	uint32_t len = val->len, j;
+
+	src += strlen(key);
+
+	/* CCM aad requires 18 bytes padding before the real content */
+	val->val = rte_zmalloc(NULL, len + 18, 0);
+	if (!val->val)
+		return -1;
+
+	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 + 18], byte) < 0) {
+			rte_free(val->val);
+			memset(val, 0, sizeof(*val));
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+struct fips_test_callback ccm_vnt_vec[] = {
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vnt_interim_vec[] = {
+		{ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad},
+		{PLEN_PREFIX, parser_read_uint32_val, &vec.pt},
+		{DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest},
+		{IVLEN_PREFIX, parser_read_uint32_val, &vec.iv},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vtt_vec[] = {
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vtt_interim_vec[] = {
+		{ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad},
+		{PLEN_PREFIX, parser_read_uint32_val, &vec.pt},
+		{IVLEN_PREFIX, parser_read_uint32_val, &vec.iv},
+		{DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vadt_vec[] = {
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vadt_interim_vec[] = {
+		{PLEN_PREFIX, parser_read_uint32_val, &vec.pt},
+		{IVLEN_PREFIX, parser_read_uint32_val, &vec.iv},
+		{ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad},
+		{DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vpt_vec[] = {
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vpt_interim_vec[] = {
+		{ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad},
+		{IVLEN_PREFIX, parser_read_uint32_val, &vec.iv},
+		{DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest},
+		{PLEN_PREFIX, parser_read_uint32_val, &vec.pt},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_dvpt_vec[] = {
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{CT_STR, parse_dvpt_ct_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_dvpt_interim_vec[] = {
+		{ALEN_PREFIX, parser_dvpt_interim, &vec.aead.aad},
+		{PLEN_PREFIX, parser_dvpt_interim, &vec.pt},
+		{IVLEN_PREFIX, parser_dvpt_interim, &vec.iv},
+		{DIGESTL_PREFIX, parser_dvpt_interim, &vec.aead.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct ccm_test_types {
+	const char *str;
+	uint32_t type;
+	const struct fips_test_callback *cb;
+	const struct fips_test_callback *cb_interim;
+	enum fips_test_op op;
+} ctt[] = {
+		{DVPT_STR, CCM_DVPT, ccm_dvpt_vec, ccm_dvpt_interim_vec,
+			FIPS_TEST_DEC_AUTH_VERIF},
+		{VPT_STR, CCM_VPT, ccm_vpt_vec, ccm_vpt_interim_vec,
+			FIPS_TEST_ENC_AUTH_GEN},
+		{VADT_STR, CCM_VADT, ccm_vadt_vec, ccm_vadt_interim_vec,
+			FIPS_TEST_ENC_AUTH_GEN},
+		{VNT_STR, CCM_VNT, ccm_vnt_vec, ccm_vnt_interim_vec,
+			FIPS_TEST_ENC_AUTH_GEN},
+		{VTT_STR, CCM_VTT, ccm_vtt_vec, ccm_vtt_interim_vec,
+			FIPS_TEST_ENC_AUTH_GEN},
+};
+
+static int
+parse_test_ccm_writeback(struct fips_val *val)
+{
+	struct fips_val tmp_val;
+
+	switch (info.interim_info.ccm_data.test_type) {
+	case CCM_DVPT:
+		fprintf(info.fp_wr, "%s", POS_NEG_STR);
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
+			fprintf(info.fp_wr, "%s\n", POS_KEYWORD);
+			fprintf(info.fp_wr, "%s", PT_STR);
+
+			tmp_val.val = val->val;
+			tmp_val.len = vec.pt.len;
+
+			if (tmp_val.len == 0)
+				fprintf(info.fp_wr, "00\n");
+			else
+				parse_write_hex_str(&tmp_val);
+		} else
+			fprintf(info.fp_wr, "%s\n", NEG_KEYWORD);
+
+		break;
+
+	case CCM_VADT:
+	case CCM_VNT:
+	case CCM_VPT:
+	case CCM_VTT:
+		fprintf(info.fp_wr, "%s", CT_STR);
+
+		parse_write_hex_str(val);
+
+		break;
+
+	}
+
+	return 0;
+}
+
+int
+parse_test_ccm_init(void)
+{
+
+	uint32_t i;
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+		uint32_t j;
+
+		for (j = 0; j < RTE_DIM(ctt); j++)
+			if (strstr(line, ctt[j].str)) {
+				info.interim_info.ccm_data.test_type =
+						ctt[j].type;
+				info.callbacks = ctt[j].cb;
+				info.interim_callbacks = ctt[j].cb_interim;
+				info.op = ctt[j].op;
+				break;
+		}
+	}
+
+	info.parse_writeback = parse_test_ccm_writeback;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index 4617c67e2..47e3732b2 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -119,6 +119,11 @@ fips_test_parse_header(void)
 			ret = parse_test_cmac_init();
 			if (ret < 0)
 				return 0;
+		} else if (strstr(info.vec[i], "CCM")) {
+			info.algo = FIPS_TEST_ALGO_AES_CCM;
+			ret = parse_test_ccm_init();
+			if (ret < 0)
+				return 0;
 		} else if (strstr(info.vec[i], "HMAC")) {
 			info.algo = FIPS_TEST_ALGO_HMAC;
 			ret = parse_test_hmac_init();
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index 7bd1e9a6f..afa0c0a80 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -26,6 +26,7 @@ enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
 		FIPS_TEST_ALGO_AES_GCM,
 		FIPS_TEST_ALGO_AES_CMAC,
+		FIPS_TEST_ALGO_AES_CCM,
 		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_TDES,
 		FIPS_TEST_ALGO_MAX
@@ -102,6 +103,14 @@ enum fips_tdes_test_types {
 	TDES_MMT /* Multi block Message Test */
 };
 
+enum fips_ccm_test_types {
+	CCM_VADT	= 1, /* Variable Associated Data Test */
+	CCM_VPT,		 /* Variable Payload Test */
+	CCM_VNT,		 /* Variable Nonce Test */
+	CCM_VTT,		 /* Variable Tag Test */
+	CCM_DVPT,	 /*  Decryption-Verification Process Test */
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -117,6 +126,15 @@ struct tdes_interim_data {
 	uint32_t nb_keys;
 };
 
+struct ccm_interim_data {
+	enum fips_ccm_test_types test_type;
+	uint32_t aad_len;
+	uint32_t pt_len;
+	uint32_t digest_len;
+	uint32_t key_len;
+	uint32_t iv_len;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -132,6 +150,7 @@ struct fips_test_interim_info {
 		struct aesavs_interim_data aes_data;
 		struct hmac_interim_data hmac_data;
 		struct tdes_interim_data tdes_data;
+		struct ccm_interim_data ccm_data;
 
 	} interim_info;
 
@@ -180,6 +199,9 @@ int
 parse_test_cmac_init(void);
 
 int
+parse_test_ccm_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index a983a66f5..80ead3809 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -469,7 +469,10 @@ prepare_aead_op(void)
 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
 	rte_pktmbuf_reset(env.mbuf);
 
-	memcpy(iv, vec.iv.val, vec.iv.len);
+	if (info.algo == FIPS_TEST_ALGO_AES_CCM)
+		memcpy(iv + 1, vec.iv.val, vec.iv.len);
+	else
+		memcpy(iv, vec.iv.val, vec.iv.len);
 
 	sym->m_src = env.mbuf;
 	sym->aead.data.offset = 0;
@@ -725,6 +728,52 @@ prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
+	aead_xform->aad_length = vec.aead.aad.len;
+	aead_xform->digest_length = vec.aead.digest.len;
+	aead_xform->iv.offset = IV_OFF;
+	aead_xform->iv.length = vec.iv.len;
+	aead_xform->key.data = vec.aead.key.val;
+	aead_xform->key.length = vec.aead.key.len;
+	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AEAD_OP_ENCRYPT :
+			RTE_CRYPTO_AEAD_OP_DECRYPT;
+
+	cap_idx.algo.aead = aead_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_aead(cap,
+			aead_xform->key.length,
+			aead_xform->digest_length, aead_xform->aad_length,
+			aead_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1,
+			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
+				info.device_name, aead_xform->key.length,
+				aead_xform->digest_length,
+				aead_xform->aad_length,
+				aead_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static void
 get_writeback_data(struct fips_val *val)
 {
@@ -1090,6 +1139,11 @@ init_test_ops(void)
 		test_ops.prepare_xform = prepare_cmac_xform;
 		test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_AES_CCM:
+		test_ops.prepare_op = prepare_aead_op;
+		test_ops.prepare_xform = prepare_ccm_xform;
+		test_ops.test = fips_generic_test;
+		break;
 	default:
 		return -1;
 	}
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index 4889d7095..e3bf7ac88 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -14,6 +14,7 @@ sources = files(
 	'cryptodev_fips_parse_3des.c',
 	'cryptodev_fips_parse_gcm.c',
 	'cryptodev_fips_parse_cmac.c',
+	'cryptodev_fips_parse_ccm.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v2 8/8] doc: add guides for fips validation
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
                   ` (6 preceding siblings ...)
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 7/8] examples: add ccm " Fan Zhang
@ 2018-10-04  9:40 ` Fan Zhang
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
  8 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04  9:40 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Document explains how to run the fips sample app
and instructions users need to parser all the request
files and generate the response files.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 doc/guides/rel_notes/release_18_11.rst       |  6 ++
 doc/guides/sample_app_ug/fips_validation.rst | 97 ++++++++++++++++++++++++++++
 doc/guides/sample_app_ug/index.rst           |  5 ++
 3 files changed, 108 insertions(+)
 create mode 100644 doc/guides/sample_app_ug/fips_validation.rst

diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 2133a5b9b..db1579b6e 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -104,6 +104,12 @@ New Features
   the specified port. The port must be stopped before the command call in order
   to reconfigure queues.
 
+* **Added Cryptodev Fips Validation Example Application.**
+
+  Added an example application to parse and perform symmetric cryptography
+  computation to the NIST Cryptographic Algorithm Validation Program (CAVP)
+  test vectors.
+
 
 API Changes
 -----------
diff --git a/doc/guides/sample_app_ug/fips_validation.rst b/doc/guides/sample_app_ug/fips_validation.rst
new file mode 100644
index 000000000..e56741a9a
--- /dev/null
+++ b/doc/guides/sample_app_ug/fips_validation.rst
@@ -0,0 +1,97 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2018 Intel Corporation.
+
+Federal Information Processing Standards (FIPS) CryptoDev Validation
+====================================================================
+
+Overview
+--------
+
+Federal Information Processing Standards (FIPS) are publicly announced standards
+developed by the United States federal government for use in computer systems by
+non-military government agencies and government contractors.
+
+This application is used to parse and perform symmetric cryptography
+computation to the NIST Cryptographic Algorithm Validation Program (CAVP) test
+vectors.
+
+Limitations
+-----------
+
+* Only NIST CAVP request files are parsed by this application.
+* The version of request file supported is ``CAVS 21.0``
+* The application does not supply the test vectors. The user is expected to
+  obtain the test vector files from `NIST
+  <https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/block-ciphers>`_
+* Supported test vectors
+    * AES-CBC (128,192,256) - GFSbox, KeySbox, MCT, MMT
+    * AES-GCM (128,192,256) - EncryptExtIV, Decrypt
+    * AES-CCM (128) - VADT, VNT, VPT, VTT, DVPT
+    * AES-CMAC (128) - Generate, Verify
+    * HMAC (SHA1, SHA224, SHA256, SHA384, SHA512)
+    * TDES (1 Key, 2 Keys, 3 Keys) - MMT, Monte, Permop, Subkey, Varkey, VarText
+
+Compiling the Application
+-------------------------
+
+* Compile Application
+
+    .. code-block:: console
+
+         make -C examples/cryptodev_fips_validate
+
+*  Run ``dos2unix`` on the request files
+
+    .. code-block:: console
+
+         dos2unix AES/req/*
+         dos2unix AES_GCM/req/*
+         dos2unix CCM/req/*
+         dos2unix CMAC/req/*
+         dos2unix HMAC/req/*
+         dos2unix TDES/req/*
+
+Running the Application
+-----------------------
+
+The application requires a number of command line options:
+
+    .. code-block:: console
+
+         ./cryptodev_fips_validate_app [EAL options]
+         -- --req-file FILE_PATH/FOLDER_PATH
+         --rsp-file FILE_PATH/FOLDER_PATH
+         [--cryptodev DEVICE_NAME] [--cryptodev-id ID] [--path-is-folder]
+
+where,
+  * req-file: The path of the request file or folder, separated by
+    ``path-is-folder`` option.
+
+  * rsp-file: The path that the response file or folder is stored. separated by
+    ``path-is-folder`` option.
+
+  * cryptodev: The name of the target DPDK Crypto device to be validated.
+
+  * cryptodev-id: The id of the target DPDK Crypto device to be validated.
+
+  * path-is-folder: If presented the application expects req-file and rsp-file
+    are folder paths.
+
+To run the application in linuxapp environment to test one AES FIPS test data
+file for crypto_aesni_mb PMD, issue the command:
+
+.. code-block:: console
+
+    $ ./cryptodev_fips_validate_app --vdev crypto_aesni_mb -- 
+    --req-file /PATH/TO/REQUEST/FILE.req --rsp-file ./PATH/TO/RESPONSE/FILE.rsp
+    --cryptodev crypto_aesni_mb
+
+To run the application in linuxapp environment to test all AES-GCM FIPS test
+data files in one folder for crypto_aesni_gcm PMD, issue the command:
+
+.. code-block:: console
+
+    $ ./cryptodev_fips_validate_app --vdev crypto_aesni_gcm0 -- 
+    --req-file /PATH/TO/REQUEST/FILE/FOLDER/
+    --rsp-file ./PATH/TO/RESPONSE/FILE/FOLDER/
+    --cryptodev-id 0 --path-is-folder
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 5bedf4f6f..146296b7a 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -56,6 +56,7 @@ Sample Applications User Guides
     performance_thread
     ipsec_secgw
     bbdev_app
+    fips_validation
 
 **Figures**
 
@@ -83,6 +84,10 @@ Sample Applications User Guides
 
 :numref:`figure_client_svr_sym_multi_proc_app` :ref:`figure_client_svr_sym_multi_proc_app`
 
+:numref:`figure_master_slave_proc` :ref:`figure_master_slave_proc`
+
+:numref:`figure_slave_proc_recov` :ref:`figure_slave_proc_recov`
+
 :numref:`figure_qos_sched_app_arch` :ref:`figure_qos_sched_app_arch`
 
 :numref:`figure_pipeline_overview` :ref:`figure_pipeline_overview`
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 0/8] FIPS validation capability
  2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
                   ` (7 preceding siblings ...)
  2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 8/8] doc: add guides for fips validation Fan Zhang
@ 2018-10-04 13:12 ` Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 1/8] examples: add fips validation into examples Fan Zhang
                     ` (7 more replies)
  8 siblings, 8 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal

This sample application is made for the purpose so that users of DPDK
who wish to get FIPS certification for their platforms, this sample app enables
users to parse test vectors that is gotten from NIST and be able to get
a generated response file which they can then verify and be sure their
system will pass FIPS certification.

Marko Kovacevic (8):
v3:
- Fixed a no-testing bug
- Fixed some code style issue

v2:
- Refactor the code.
- Move the code from test to sample applcation

  examples: add fips validation into examples
  examples: add aes parser and enablement for test types
  examples: add hmac parser
  examples: add TDES parser and enablement for test types
  examples: add gcm parser
  examples: add cmac parser and enablement for test types
  examples: add ccm parser and enablement for test types
  doc: add guides for fips validation

 doc/guides/rel_notes/release_18_11.rst             |    6 +
 doc/guides/sample_app_ug/fips_validation.rst       |   97 ++
 doc/guides/sample_app_ug/index.rst                 |    5 +
 examples/cryptodev_fips_validate/Makefile          |   75 ++
 .../cryptodev_fips_parse_3des.c                    |  259 +++++
 .../cryptodev_fips_parse_aes.c                     |  188 +++
 .../cryptodev_fips_parse_ccm.c                     |  272 +++++
 .../cryptodev_fips_parse_cmac.c                    |  116 ++
 .../cryptodev_fips_parse_gcm.c                     |  125 ++
 .../cryptodev_fips_parse_hmac.c                    |  105 ++
 .../cryptodev_fips_parse_validate.c                |  593 ++++++++++
 .../cryptodev_fips_validate.h                      |  234 ++++
 examples/cryptodev_fips_validate/main.c            | 1221 ++++++++++++++++++++
 examples/cryptodev_fips_validate/meson.build       |   20 +
 14 files changed, 3316 insertions(+)
 create mode 100644 doc/guides/sample_app_ug/fips_validation.rst
 create mode 100644 examples/cryptodev_fips_validate/Makefile
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c
 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

-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 1/8] examples: add fips validation into examples
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
@ 2018-10-04 13:12   ` Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 2/8] examples: add aes parser and enablement for test types Fan Zhang
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

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>
---
 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 000000000..5515aa6d9
--- /dev/null
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2014 Intel Corporation
+
+# binary name
+APP = cryptodev_fips_validate_app
+
+# 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 000000000..aec5bb9c6
--- /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;
+	}
+
+	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)) {
+					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;
+
+	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 000000000..beb6bedda
--- /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;
+	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 000000000..4f14b0429
--- /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);
+			goto error_one_case;
+		case 1:
+			break;
+		default:
+			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 000000000..e41773305
--- /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', 'bus_pci']
+allow_experimental_apis = true
+sources = files(
+	'cryptodev_fips_parse_validate.c',
+	'main.c'
+)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 2/8] examples: add aes parser and enablement for test types
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 1/8] examples: add fips validation into examples Fan Zhang
@ 2018-10-04 13:12   ` Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 3/8] examples: add hmac parser Fan Zhang
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for AES-CBC parser, to allow the
application to parser the aes request file and to validate all
test types supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_aes.c                     | 186 +++++++++++
 .../cryptodev_fips_parse_validate.c                |   6 +
 .../cryptodev_fips_validate.h                      |  24 ++
 examples/cryptodev_fips_validate/main.c            | 346 ++++++++++++++++++++-
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 563 insertions(+), 1 deletion(-)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index 5515aa6d9..f058081ff 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -5,6 +5,7 @@
 APP = cryptodev_fips_validate_app
 
 # all source are stored in SRCS-y
+SRCS-y := cryptodev_fips_parse_aes.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
new file mode 100644
index 000000000..39dbd6ff9
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define MODE_STR	"AESVS"
+#define ALGO_STR	"test data for "
+#define OP_STR		"State"
+#define KEY_SIZE_STR	"Key Length : "
+
+
+#define COUNT_STR	"COUNT = "
+#define KEY_STR		"KEY = "
+#define IV_STR		"IV = "
+#define PT_STR		"PLAINTEXT = "
+#define CT_STR		"CIPHERTEXT = "
+
+#define OP_ENC_STR	"ENCRYPT"
+#define OP_DEC_STR	"DECRYPT"
+
+struct {
+	uint32_t type;
+	const char *desc;
+} aes_test_types[] = {
+		{AESAVS_TYPE_GFXBOX, "GFSbox"},
+		{AESAVS_TYPE_KEYSBOX, "KeySbox"},
+		{AESAVS_TYPE_VARKEY, "VarKey"},
+		{AESAVS_TYPE_VARTXT, "VarTxt"},
+		{AESAVS_TYPE_MMT, "MMT"},
+		{AESAVS_TYPE_MCT, "MCT"},
+};
+
+struct aes_test_algo {
+	const char *name;
+	enum rte_crypto_cipher_algorithm algo;
+} const algo_con[] = {
+		{"CBC", RTE_CRYPTO_CIPHER_AES_CBC},
+};
+
+static int
+parse_interim_enc_dec(const char *key,
+		__attribute__((__unused__)) char *text,
+		__attribute__((__unused__)) struct fips_val *val)
+{
+	if (strcmp(key, OP_ENC_STR) == 0)
+		info.op = FIPS_TEST_ENC_AUTH_GEN;
+	else if (strcmp(key, OP_DEC_STR) == 0)
+		info.op = FIPS_TEST_DEC_AUTH_VERIF;
+	else
+		return -1;
+
+	return 0;
+}
+
+struct fips_test_callback aes_tests_interim[] = {
+		{OP_ENC_STR, parse_interim_enc_dec, NULL},
+		{OP_DEC_STR, parse_interim_enc_dec, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback aes_tests_vectors[] = {
+		{KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key},
+		{IV_STR, parse_uint8_hex_str, &vec.iv},
+		{PT_STR, parse_uint8_hex_str, &vec.pt},
+		{CT_STR, parse_uint8_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback aes_tests_interim_vectors[] = {
+		{OP_ENC_STR, parse_interim_enc_dec, NULL},
+		{OP_DEC_STR, parse_interim_enc_dec, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback aes_writeback_callbacks[] = {
+		/** First element is used to pass COUNT string */
+		{COUNT_STR, NULL, NULL},
+		{IV_STR, writeback_hex_str, &vec.iv},
+		{KEY_STR, writeback_hex_str, &vec.cipher_auth.key},
+		{PT_STR, writeback_hex_str, &vec.pt},
+		{CT_STR, writeback_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_test_aes_writeback(struct fips_val *val)
+{
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+		fprintf(info.fp_wr, "%s", CT_STR);
+	else
+		fprintf(info.fp_wr, "%s", PT_STR);
+
+	parse_write_hex_str(val);
+
+	return 0;
+}
+
+static int
+rsp_test_aes_check(struct fips_val *val)
+{
+	struct fips_val *data;
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+		data = &vec.ct;
+	else
+		data = &vec.pt;
+
+	if (memcmp(val->val, data->val, val->len) == 0)
+		fprintf(info.fp_wr, "Success\n");
+	else
+		fprintf(info.fp_wr, "Failed\n");
+
+	return 0;
+}
+
+int
+parse_test_aes_init(void)
+{
+	char *tmp;
+	uint32_t i, j;
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+
+		tmp = strstr(line, MODE_STR);
+		if (tmp) {
+			for (j = 0; j < RTE_DIM(aes_test_types); j++)
+				if (strstr(line, aes_test_types[j].desc)) {
+					info.interim_info.aes_data.test_type =
+							aes_test_types[j].type;
+					break;
+				}
+
+			if (j >= RTE_DIM(aes_test_types))
+				return -EINVAL;
+
+			tmp = strstr(line, ALGO_STR);
+			if (!tmp)
+				return -EINVAL;
+
+			tmp += strlen(ALGO_STR);
+			for (j = 0; j < RTE_DIM(algo_con); j++)
+				if (strcmp(algo_con[j].name, tmp) == 0) {
+					info.interim_info.aes_data.cipher_algo =
+						(uint32_t)algo_con[j].algo;
+					break;
+				}
+			if (j >= RTE_DIM(algo_con))
+				return -EINVAL;
+
+			continue;
+		}
+
+		tmp = strstr(line, OP_STR);
+		if (tmp)
+			continue;
+
+		tmp = strstr(line, KEY_SIZE_STR);
+		if (tmp) {
+			tmp += strlen(KEY_SIZE_STR);
+			if (parser_read_uint32
+					(&info.interim_info.aes_data.key_len,
+							tmp) < 0)
+				return -EINVAL;
+
+			info.interim_info.aes_data.key_len /= 8;
+
+			continue;
+		}
+	}
+
+	info.parse_writeback = parse_test_aes_writeback;
+	info.callbacks = aes_tests_vectors;
+	info.interim_callbacks = aes_tests_interim_vectors;
+	info.writeback_callbacks = aes_writeback_callbacks;
+	info.kat_check = rsp_test_aes_check;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index aec5bb9c6..32af47b1c 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -104,6 +104,12 @@ fips_test_parse_header(void)
 		return ret;
 
 	for (i = 0; i < info.nb_vec_lines; i++) {
+		if (strstr(info.vec[i], "AESVS")) {
+			info.algo = FIPS_TEST_ALGO_AES;
+			ret = parse_test_aes_init();
+			if (ret < 0)
+				return ret;
+		}
 
 		tmp = strstr(info.vec[i], "# Config info for ");
 		if (tmp != NULL) {
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index beb6bedda..5ac858d02 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -23,6 +23,7 @@
 #define FAX_FILE_PERFIX		"fax"
 
 enum fips_test_algorithms {
+		FIPS_TEST_ALGO_AES = 0,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -77,6 +78,21 @@ struct fips_test_callback {
 	struct fips_val *val;
 };
 
+enum fips_aesavs_test_types {
+	AESAVS_TYPE_GFXBOX = 0,
+	AESAVS_TYPE_KEYSBOX,
+	AESAVS_TYPE_VARKEY,
+	AESAVS_TYPE_VARTXT,
+	AESAVS_TYPE_MMT,
+	AESAVS_TYPE_MCT,
+};
+
+struct aesavs_interim_data {
+	enum fips_aesavs_test_types test_type;
+	uint32_t cipher_algo;
+	uint32_t key_len;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -88,6 +104,11 @@ struct fips_test_interim_info {
 	//uint8_t cryptodev_id;
 	char device_name[MAX_STRING_SIZE];
 
+	union {
+		struct aesavs_interim_data aes_data;
+
+	} interim_info;
+
 	enum fips_test_op op;
 
 	const struct fips_test_callback *callbacks;
@@ -118,6 +139,9 @@ void
 fips_test_write_one_case(void);
 
 int
+parse_test_aes_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 4f14b0429..98d70b4c0 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -329,6 +329,340 @@ main(int argc, char *argv[])
 
 }
 
+#define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
+#define CRYPTODEV_FIPS_MAX_RETRIES	16
+
+typedef int (*fips_test_one_case_t)(void);
+typedef int (*fips_prepare_op_t)(void);
+typedef int (*fips_prepare_xform_t)(struct rte_crypto_sym_xform *);
+
+struct fips_test_ops {
+	fips_prepare_xform_t prepare_xform;
+	fips_prepare_op_t prepare_op;
+	fips_test_one_case_t test;
+} test_ops;
+
+static int
+prepare_cipher_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	rte_pktmbuf_reset(env.mbuf);
+
+	sym->m_src = env.mbuf;
+	sym->cipher.data.offset = 0;
+
+	memcpy(iv, vec.iv.val, vec.iv.len);
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		uint8_t *pt;
+
+		if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len);
+			return -EPERM;
+		}
+
+		pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len);
+
+		if (!pt) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(pt, vec.pt.val, vec.pt.len);
+		sym->cipher.data.length = vec.pt.len;
+
+	} else {
+		uint8_t *ct;
+
+		if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len);
+			return -EPERM;
+		}
+
+		ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len);
+
+		if (!ct) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(ct, vec.ct.val, vec.ct.len);
+		sym->cipher.data.length = vec.ct.len;
+	}
+
+	rte_crypto_op_attach_sym_session(env.op, env.sess);
+
+	return 0;
+}
+
+static int
+prepare_aes_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
+	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+			RTE_CRYPTO_CIPHER_OP_DECRYPT;
+	cipher_xform->key.data = vec.cipher_auth.key.val;
+	cipher_xform->key.length = vec.cipher_auth.key.len;
+	cipher_xform->iv.length = vec.iv.len;
+	cipher_xform->iv.offset = IV_OFF;
+
+	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_CBC;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_cipher(cap,
+			cipher_xform->key.length,
+			cipher_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, cipher_xform->key.length,
+				cipher_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static void
+get_writeback_data(struct fips_val *val)
+{
+	val->val = rte_pktmbuf_mtod(env.mbuf, uint8_t *);
+	val->len = rte_pktmbuf_pkt_len(env.mbuf);
+}
+
+static int
+fips_run_test(void)
+{
+	struct rte_crypto_sym_xform xform = {0};
+	uint16_t n_deqd;
+	int ret;
+
+	ret = test_ops.prepare_xform(&xform);
+	if (ret < 0)
+		return ret;
+
+	env.sess = rte_cryptodev_sym_session_create(env.mpool);
+	if (!env.sess)
+		return -ENOMEM;
+
+	ret = rte_cryptodev_sym_session_init(env.dev_id,
+			env.sess, &xform, env.mpool);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Init session\n",
+				ret);
+		return ret;
+	}
+
+	ret = test_ops.prepare_op();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
+				ret);
+		return ret;
+	}
+
+	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
+		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
+		return ret;
+	}
+
+	do {
+		struct rte_crypto_op *deqd_op;
+
+		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op,
+				1);
+	} while (n_deqd == 0);
+
+	vec.status = env.op->status;
+
+	rte_cryptodev_sym_session_clear(env.dev_id, env.sess);
+	rte_cryptodev_sym_session_free(env.sess);
+	env.sess = NULL;
+
+	return ret;
+}
+
+static int
+fips_generic_test(void)
+{
+	struct fips_val val;
+	int ret;
+
+	fips_test_write_one_case();
+
+	ret = fips_run_test();
+	if (ret < 0) {
+		if (ret == -EPERM) {
+			fprintf(info.fp_wr, "Bypass\n\n");
+			return 0;
+		}
+
+		return ret;
+	}
+
+	get_writeback_data(&val);
+
+	switch (info.file_type) {
+	case FIPS_TYPE_REQ:
+	case FIPS_TYPE_RSP:
+		if (info.parse_writeback == NULL)
+			return -EPERM;
+		ret = info.parse_writeback(&val);
+		if (ret < 0)
+			return ret;
+		break;
+	case FIPS_TYPE_FAX:
+		if (info.kat_check == NULL)
+			return -EPERM;
+		ret = info.kat_check(&val);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+
+	fprintf(info.fp_wr, "\n");
+
+	return 0;
+}
+
+static int
+fips_mct_aes_test(void)
+{
+#define AES_BLOCK_SIZE	16
+#define AES_EXTERN_ITER	100
+#define AES_INTERN_ITER	1000
+	struct fips_val val, val_key;
+	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
+	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
+	uint32_t i, j, k;
+	int ret;
+
+	for (i = 0; i < AES_EXTERN_ITER; i++) {
+		if (i != 0)
+			update_info_vec(i);
+
+		fips_test_write_one_case();
+
+		for (j = 0; j < AES_INTERN_ITER; j++) {
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM) {
+					fprintf(info.fp_wr, "Bypass\n");
+					return 0;
+				}
+
+				return ret;
+			}
+
+			get_writeback_data(&val);
+
+			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
+
+			if (j == 0) {
+				memcpy(prev_out, val.val, AES_BLOCK_SIZE);
+
+				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+					memcpy(vec.pt.val, vec.iv.val,
+							AES_BLOCK_SIZE);
+					memcpy(vec.iv.val, val.val,
+							AES_BLOCK_SIZE);
+				} else {
+					memcpy(vec.ct.val, vec.iv.val,
+							AES_BLOCK_SIZE);
+					memcpy(vec.iv.val, prev_in,
+							AES_BLOCK_SIZE);
+				}
+				continue;
+			}
+
+			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+				memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE);
+				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
+			} else {
+				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
+				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
+			}
+
+			if (j == AES_INTERN_ITER - 1)
+				continue;
+
+			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
+		}
+
+		info.parse_writeback(&val);
+		fprintf(info.fp_wr, "\n");
+
+		if (i == AES_EXTERN_ITER - 1)
+			continue;
+
+		/** update key */
+		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
+		for (k = 0; k < vec.cipher_auth.key.len; k++) {
+			switch (vec.cipher_auth.key.len) {
+			case 16:
+				val_key.val[k] ^= val.val[k];
+				break;
+			case 24:
+				if (k < 8)
+					val_key.val[k] ^= prev_out[k + 8];
+				else
+					val_key.val[k] ^= val.val[k - 8];
+				break;
+			case 32:
+				if (k < 16)
+					val_key.val[k] ^= prev_out[k];
+				else
+					val_key.val[k] ^= val.val[k - 16];
+				break;
+			default:
+				return -1;
+			}
+		}
+
+		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+			memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE);
+	}
+
+	return 0;
+}
+
+static int
+init_test_ops(void)
+{
+	switch (info.algo) {
+	case FIPS_TEST_ALGO_AES:
+		test_ops.prepare_op = prepare_cipher_op;
+		test_ops.prepare_xform  = prepare_aes_xform;
+		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
+			test_ops.test = fips_mct_aes_test;
+		else
+			test_ops.test = fips_generic_test;
+		break;
+
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
 static void
 print_test_block(void)
 {
@@ -345,7 +679,14 @@ fips_test_one_file(void)
 {
 	int fetch_ret = 0, ret;
 
-	while (fetch_ret == 0) {
+
+	ret = init_test_ops();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
+		return ret;
+	}
+
+	while (ret >= 0 && fetch_ret == 0) {
 		fetch_ret = fips_test_fetch_one_block();
 		if (fetch_ret < 0) {
 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
@@ -365,6 +706,7 @@ fips_test_one_file(void)
 		ret = fips_test_parse_one_case();
 		switch (ret) {
 		case 0:
+			ret = test_ops.test();
 			if (ret == 0)
 				break;
 			RTE_LOG(ERR, USER1, "Error %i: test block\n",
@@ -385,4 +727,6 @@ fips_test_one_file(void)
 
 	fips_test_clear();
 
+	return ret;
+
 }
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index e41773305..d04e9bbeb 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -9,6 +9,7 @@
 deps += ['cryptodev', 'bus_pci']
 allow_experimental_apis = true
 sources = files(
+	'cryptodev_fips_parse_aes.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 3/8] examples: add hmac parser
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 1/8] examples: add fips validation into examples Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 2/8] examples: add aes parser and enablement for test types Fan Zhang
@ 2018-10-04 13:12   ` Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 4/8] examples: add TDES parser and enablement for test types Fan Zhang
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for HMAC parser, to allow the
application to parser the hmac request files and to validate all
tests supported

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_hmac.c                    | 105 +++++++++++++++++++++
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |   9 ++
 examples/cryptodev_fips_validate/main.c            | 103 ++++++++++++++++++++
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 224 insertions(+)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index f058081ff..50be23cf5 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -6,6 +6,7 @@ APP = cryptodev_fips_validate_app
 
 # all source are stored in SRCS-y
 SRCS-y := cryptodev_fips_parse_aes.c
+SRCS-y += cryptodev_fips_parse_hmac.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c
new file mode 100644
index 000000000..2fbc2469c
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_hmac.c
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define ALGO_PREFIX	"[L="
+#define KEYLEN_STR	"Klen = "
+#define TAGLEN_STR	"Tlen = "
+
+#define COUNT_STR	"Count = "
+#define KEY_STR		"Key = "
+#define PT_STR		"Msg = "
+#define TAG_STR		"Mac = "
+
+struct hash_size_conversion {
+	const char *str;
+	enum rte_crypto_auth_algorithm algo;
+} hsc[] = {
+		{"20", RTE_CRYPTO_AUTH_SHA1_HMAC},
+		{"28", RTE_CRYPTO_AUTH_SHA224_HMAC},
+		{"32", RTE_CRYPTO_AUTH_SHA256_HMAC},
+		{"48", RTE_CRYPTO_AUTH_SHA384_HMAC},
+		{"64", RTE_CRYPTO_AUTH_SHA512_HMAC},
+};
+
+static int
+parse_interim_algo(__attribute__((__unused__)) const char *key,
+		char *text,
+		__attribute__((__unused__)) struct fips_val *val)
+{
+
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(hsc); i++) {
+		if (strstr(text, hsc[i].str)) {
+			info.interim_info.hmac_data.algo = hsc[i].algo;
+			break;
+		}
+	}
+
+	if (i == RTE_DIM(hsc))
+		return -1;
+
+	return 0;
+}
+
+struct fips_test_callback hmac_tests_vectors[] = {
+		{KEYLEN_STR, parser_read_uint32_val, &vec.cipher_auth.key},
+		{TAGLEN_STR, parser_read_uint32_val, &vec.cipher_auth.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key},
+		{PT_STR, parse_uint8_hex_str, &vec.pt},
+		{TAG_STR, parse_uint8_hex_str, &vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback hmac_tests_interim_vectors[] = {
+		{ALGO_PREFIX, parse_interim_algo, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_test_hmac_writeback(struct fips_val *val)
+{
+	struct fips_val val_local;
+
+	fprintf(info.fp_wr, "%s", TAG_STR);
+
+	val_local.val = val->val + vec.pt.len;
+	val_local.len = vec.cipher_auth.digest.len;
+
+	parse_write_hex_str(&val_local);
+	return 0;
+}
+
+static int
+rsp_test_hmac_check(struct fips_val *val)
+{
+	if (memcmp(val->val + vec.pt.len, vec.cipher_auth.digest.val,
+			vec.cipher_auth.digest.len) == 0)
+		fprintf(info.fp_wr, "Success\n");
+	else
+		fprintf(info.fp_wr, "Failed\n");
+
+	return 0;
+}
+
+int
+parse_test_hmac_init(void)
+{
+	info.op = FIPS_TEST_ENC_AUTH_GEN;
+	info.parse_writeback = parse_test_hmac_writeback;
+	info.callbacks = hmac_tests_vectors;
+	info.interim_callbacks = hmac_tests_interim_vectors;
+	info.writeback_callbacks = NULL;
+	info.kat_check = rsp_test_hmac_check;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index 32af47b1c..f1cd80253 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -109,6 +109,11 @@ fips_test_parse_header(void)
 			ret = parse_test_aes_init();
 			if (ret < 0)
 				return ret;
+		} else if (strstr(info.vec[i], "HMAC")) {
+			info.algo = FIPS_TEST_ALGO_HMAC;
+			ret = parse_test_hmac_init();
+			if (ret < 0)
+				return ret;
 		}
 
 		tmp = strstr(info.vec[i], "# Config info for ");
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index 5ac858d02..3cda9fe87 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -24,6 +24,7 @@
 
 enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
+		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -93,6 +94,10 @@ struct aesavs_interim_data {
 	uint32_t key_len;
 };
 
+struct hmac_interim_data {
+	enum rte_crypto_auth_algorithm algo;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -106,6 +111,7 @@ struct fips_test_interim_info {
 
 	union {
 		struct aesavs_interim_data aes_data;
+		struct hmac_interim_data hmac_data;
 
 	} interim_info;
 
@@ -142,6 +148,9 @@ int
 parse_test_aes_init(void);
 
 int
+parse_test_hmac_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 98d70b4c0..a16557655 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -401,6 +401,67 @@ prepare_cipher_op(void)
 }
 
 static int
+prepare_auth_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	rte_pktmbuf_reset(env.mbuf);
+
+	sym->m_src = env.mbuf;
+	sym->auth.data.offset = 0;
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		uint8_t *pt;
+
+		if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len);
+			return -EPERM;
+		}
+
+		pt = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.pt.len +
+				vec.cipher_auth.digest.len);
+
+		if (!pt) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(pt, vec.pt.val, vec.pt.len);
+		sym->auth.data.length = vec.pt.len;
+		sym->auth.digest.data = pt + vec.pt.len;
+		sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+				env.mbuf, vec.pt.len);
+
+	} else {
+		uint8_t *ct;
+
+		if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len);
+			return -EPERM;
+		}
+
+		ct = (uint8_t *)rte_pktmbuf_append(env.mbuf,
+				vec.ct.len + vec.cipher_auth.digest.len);
+
+		if (!ct) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(ct, vec.ct.val, vec.ct.len);
+		sym->auth.data.length = vec.ct.len;
+		sym->auth.digest.data = vec.cipher_auth.digest.val;
+		sym->auth.digest.phys_addr = rte_malloc_virt2iova(
+				sym->auth.digest.data);
+	}
+
+	rte_crypto_op_attach_sym_session(env.op, env.sess);
+}
+
+static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
 	const struct rte_cryptodev_symmetric_capability *cap;
@@ -440,6 +501,43 @@ prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = info.interim_info.hmac_data.algo;
+	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
+	auth_xform->digest_length = vec.cipher_auth.digest.len;
+	auth_xform->key.data = vec.cipher_auth.key.val;
+	auth_xform->key.length = vec.cipher_auth.key.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length, 0) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static void
 get_writeback_data(struct fips_val *val)
 {
@@ -655,6 +753,11 @@ init_test_ops(void)
 		else
 			test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_HMAC:
+		test_ops.prepare_op = prepare_auth_op;
+		test_ops.prepare_xform = prepare_hmac_xform;
+		test_ops.test = fips_generic_test;
+		break;
 
 	default:
 		return -1;
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index d04e9bbeb..dcf90bbbb 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -10,6 +10,7 @@ deps += ['cryptodev', 'bus_pci']
 allow_experimental_apis = true
 sources = files(
 	'cryptodev_fips_parse_aes.c',
+	'cryptodev_fips_parse_hmac.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 4/8] examples: add TDES parser and enablement for test types
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
                     ` (2 preceding siblings ...)
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 3/8] examples: add hmac parser Fan Zhang
@ 2018-10-04 13:12   ` Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 5/8] examples: add gcm parser Fan Zhang
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for TDES parser, to allow the
application to parser the TDES request files and to validate all
test types supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_3des.c                    | 259 +++++++++++++++++++++
 .../cryptodev_fips_parse_aes.c                     |   2 +
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |  21 ++
 examples/cryptodev_fips_validate/main.c            | 175 ++++++++++++++
 examples/cryptodev_fips_validate/meson.build       |   1 +
 7 files changed, 464 insertions(+)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index 50be23cf5..54ea43ffd 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -7,6 +7,7 @@ APP = cryptodev_fips_validate_app
 # all source are stored in SRCS-y
 SRCS-y := cryptodev_fips_parse_aes.c
 SRCS-y += cryptodev_fips_parse_hmac.c
+SRCS-y += cryptodev_fips_parse_3des.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c
new file mode 100644
index 000000000..82e9132a7
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_3des.c
@@ -0,0 +1,259 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include <rte_malloc.h>
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define NEW_LINE_STR	"#"
+#define TEST_TYPE_KEY	" for CBC"
+#define TEST_CBCI_KEY	" for CBCI"
+
+#define ENC_STR		"[ENCRYPT]"
+#define DEC_STR		"[DECRYPT]"
+
+#define COUNT_STR	"COUNT = "
+#define KEY1_STR	"KEY1 = "
+#define KEY2_STR	"KEY2 = "
+#define KEY3_STR	"KEY3 = "
+
+#define KEYS_STR	"KEYs = "
+#define IV_STR		"IV = "
+#define PT_STR		"PLAINTEXT = "
+#define CT_STR		"CIPHERTEXT = "
+#define NK_STR		"NumKeys = "
+
+#define SET_STR		" = "
+
+#define PLAIN_TEXT	0
+#define CIPHER_TEXT	1
+#define KEY_TEXT	2
+#define IV_TEXT		3
+
+#define DEVICE_STR	"# Config Info for : "
+
+struct {
+	uint32_t type;
+	const char *desc;
+} test_types[] = {
+		{TDES_INVERSE_PERMUTATION, "INVERSE PERMUTATION"},
+		{TDES_PERMUTATION, "PERMUTATION OPERATION"},
+		{TDES_SUBSTITUTION_TABLE, "SUBSTITUTION TABLE"},
+		{TDES_VARIABLE_KEY, "VARIABLE KEY"},
+		{TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"},
+		{TDES_VARIABLE_TEXT, "KAT"},
+		{TDES_MCT, "Monte Carlo (Modes) Test"},
+		{TDES_MMT, "Multi block Message Test"},
+};
+
+static int
+writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val);
+
+static int
+parse_3des_uint8_hex_str(const char *key, char *src, struct fips_val *val);
+
+static int
+parse_tdes_interim(const char *key,
+		__attribute__((__unused__)) char *text,
+		struct fips_val *val);
+
+struct fips_test_callback tdes_tests_vectors[] = {
+		{KEYS_STR, parse_3des_uint8_hex_str, &vec.cipher_auth.key},
+		{KEY1_STR, parse_3des_uint8_hex_str, &vec.cipher_auth.key},
+		{KEY2_STR, parse_3des_uint8_hex_str, &vec.cipher_auth.key},
+		{KEY3_STR, parse_3des_uint8_hex_str, &vec.cipher_auth.key},
+		{IV_STR, parse_uint8_hex_str, &vec.iv},
+		{PT_STR, parse_uint8_hex_str, &vec.pt},
+		{CT_STR, parse_uint8_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback tdes_tests_interim_vectors[] = {
+		{ENC_STR, parse_tdes_interim, NULL},
+		{DEC_STR, parse_tdes_interim, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback tdes_writeback_callbacks[] = {
+		/** First element is used to pass COUNT string */
+		{COUNT_STR, NULL, NULL},
+		{IV_STR, writeback_hex_str, &vec.iv},
+		{KEY1_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
+		{KEY2_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
+		{KEY3_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
+		{KEYS_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
+		{PT_STR, writeback_hex_str, &vec.pt},
+		{CT_STR, writeback_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_tdes_interim(const char *key,
+		__attribute__((__unused__)) char *text,
+		__attribute__((__unused__)) struct fips_val *val)
+{
+	if (strstr(key, ENC_STR))
+		info.op = FIPS_TEST_ENC_AUTH_GEN;
+	else if (strstr(key, DEC_STR))
+		info.op = FIPS_TEST_DEC_AUTH_VERIF;
+	else if (strstr(NK_STR, "NumKeys = 1"))
+		info.interim_info.tdes_data.nb_keys = 1;
+	else if (strstr(NK_STR, "NumKeys = 2"))
+		info.interim_info.tdes_data.nb_keys = 2;
+	else if (strstr(NK_STR, "NumKeys = 3"))
+		info.interim_info.tdes_data.nb_keys = 3;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+parse_3des_uint8_hex_str(const char *key, char *src, struct fips_val *val)
+{
+	uint8_t tmp_key[24] = {0};
+	uint32_t len, i;
+
+	src += strlen(key);
+
+	len = strlen(src) / 2;
+
+	if (val->val) {
+		memcpy(tmp_key, val->val, val->len);
+		rte_free(val->val);
+	}
+
+	val->val = rte_zmalloc(NULL, 24, 0);
+	if (!val->val)
+		return -1;
+
+	memcpy(val->val, tmp_key, 24);
+
+	if (strstr(key, KEYS_STR)) {
+		for (i = 0; i < len; i++) {
+			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
+
+			if (parser_read_uint8_hex(&val->val[i], byte) < 0)
+				return -EINVAL;
+		}
+
+		memcpy(val->val + 8, val->val, 8);
+		memcpy(val->val + 16, val->val, 8);
+
+	} else if (strstr(key, KEY1_STR)) {
+		for (i = 0; i < len; i++) {
+			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
+
+			if (parser_read_uint8_hex(&val->val[i], byte) < 0)
+				return -EINVAL;
+		}
+
+		if (info.interim_info.tdes_data.nb_keys == 2)
+			memcpy(val->val + 16, val->val, 8);
+
+	} else if (strstr(key, KEY2_STR)) {
+		for (i = 0; i < len; i++) {
+			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
+
+			if (parser_read_uint8_hex(&val->val[i + 8], byte) < 0)
+				return -EINVAL;
+		}
+
+	} else if (strstr(key, KEY3_STR)) {
+		for (i = 0; i < len; i++) {
+			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
+
+			if (parser_read_uint8_hex(&val->val[i + 16], byte) < 0)
+				return -EINVAL;
+		}
+	} else
+		return -EINVAL;
+
+	val->len = 24;
+
+	return 0;
+}
+
+static int
+parse_test_tdes_writeback(struct fips_val *val)
+{
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+		fprintf(info.fp_wr, "%s", CT_STR);
+	else
+		fprintf(info.fp_wr, "%s", PT_STR);
+
+	parse_write_hex_str(val);
+
+	return 0;
+
+}
+
+static int
+writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val)
+{
+	struct fips_val tmp_val;
+
+	tmp_val.len = 8;
+
+	if (strstr(key, KEY1_STR))
+		tmp_val.val = val->val;
+	else if (strstr(key, KEY2_STR))
+		tmp_val.val = val->val + 8;
+	else if (strstr(key, KEY3_STR))
+		tmp_val.val = val->val + 16;
+
+	return writeback_hex_str(key, dst, &tmp_val);
+}
+
+static int
+rsp_test_tdes_check(struct fips_val *val)
+{
+	struct fips_val *data;
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+		data = &vec.ct;
+	else
+		data = &vec.pt;
+
+	if (memcmp(val->val, data->val, val->len) == 0)
+		fprintf(info.fp_wr, "Success\n");
+	else
+		fprintf(info.fp_wr, "Failed\n");
+
+	return 0;
+}
+
+int
+parse_test_tdes_init(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+		uint32_t j;
+
+		if (strstr(line, TEST_CBCI_KEY))
+			return -EPERM;
+
+		for (j = 0; j < RTE_DIM(test_types); j++)
+			if (strstr(line, test_types[j].desc)) {
+				info.interim_info.tdes_data.test_type =
+						test_types[j].type;
+				break;
+			}
+	}
+
+	info.parse_writeback = parse_test_tdes_writeback;
+	info.callbacks = tdes_tests_vectors;
+	info.interim_callbacks = tdes_tests_interim_vectors;
+	info.writeback_callbacks = tdes_writeback_callbacks;
+	info.kat_check = rsp_test_tdes_check;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
index 39dbd6ff9..cc2775428 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_aes.c
@@ -33,6 +33,8 @@ struct {
 		{AESAVS_TYPE_KEYSBOX, "KeySbox"},
 		{AESAVS_TYPE_VARKEY, "VarKey"},
 		{AESAVS_TYPE_VARTXT, "VarTxt"},
+		{TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"},
+		{TDES_VARIABLE_TEXT, "KAT"},
 		{AESAVS_TYPE_MMT, "MMT"},
 		{AESAVS_TYPE_MCT, "MCT"},
 };
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index f1cd80253..bb396e54d 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -114,6 +114,11 @@ fips_test_parse_header(void)
 			ret = parse_test_hmac_init();
 			if (ret < 0)
 				return ret;
+		} else if (strstr(info.vec[i], "TDES")) {
+			info.algo = FIPS_TEST_ALGO_TDES;
+			ret = parse_test_tdes_init();
+			if (ret < 0)
+				return 0;
 		}
 
 		tmp = strstr(info.vec[i], "# Config info for ");
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index 3cda9fe87..c9b11dda2 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -25,6 +25,7 @@
 enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
 		FIPS_TEST_ALGO_HMAC,
+		FIPS_TEST_ALGO_TDES,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -88,6 +89,17 @@ enum fips_aesavs_test_types {
 	AESAVS_TYPE_MCT,
 };
 
+enum fips_tdes_test_types {
+	TDES_INVERSE_PERMUTATION = 0,
+	TDES_PERMUTATION,
+	TDES_SUBSTITUTION_TABLE,
+	TDES_VARIABLE_KEY,
+	TDES_VARIABLE_TEXT,
+	TDES_KAT,
+	TDES_MCT, /* Monte Carlo (Modes) Test */
+	TDES_MMT /* Multi block Message Test */
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -98,6 +110,11 @@ struct hmac_interim_data {
 	enum rte_crypto_auth_algorithm algo;
 };
 
+struct tdes_interim_data {
+	enum fips_tdes_test_types test_type;
+	uint32_t nb_keys;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -112,6 +129,7 @@ struct fips_test_interim_info {
 	union {
 		struct aesavs_interim_data aes_data;
 		struct hmac_interim_data hmac_data;
+		struct tdes_interim_data tdes_data;
 
 	} interim_info;
 
@@ -148,6 +166,9 @@ int
 parse_test_aes_init(void);
 
 int
+parse_test_tdes_init(void);
+
+int
 parse_test_hmac_init(void);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index a16557655..9696fa895 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -502,6 +502,46 @@ prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 }
 
 static int
+prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
+	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+			RTE_CRYPTO_CIPHER_OP_DECRYPT;
+	cipher_xform->key.data = vec.cipher_auth.key.val;
+	cipher_xform->key.length = vec.cipher_auth.key.len;
+	cipher_xform->iv.length = vec.iv.len;
+	cipher_xform->iv.offset = IV_OFF;
+
+	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_3DES_CBC;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_cipher(cap,
+			cipher_xform->key.length,
+			cipher_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, cipher_xform->key.length,
+				cipher_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
 prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
 {
 	const struct rte_cryptodev_symmetric_capability *cap;
@@ -640,6 +680,133 @@ fips_generic_test(void)
 }
 
 static int
+fips_mct_tdes_test(void)
+{
+#define TDES_BLOCK_SIZE		16
+#define TDES_EXTERN_ITER	400
+#define TDES_INTERN_ITER	10000
+	struct fips_val val, val_key;
+	uint8_t prev_out[TDES_BLOCK_SIZE];
+	uint8_t prev_prev_out[TDES_BLOCK_SIZE];
+	uint8_t prev_in[TDES_BLOCK_SIZE];
+	uint32_t i, j, k;
+	int ret;
+
+	for (i = 0; i < TDES_EXTERN_ITER; i++) {
+		if (i != 0)
+			update_info_vec(i);
+
+		fips_test_write_one_case();
+
+		for (j = 0; j < TDES_INTERN_ITER; j++) {
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM) {
+					fprintf(info.fp_wr, "Bypass\n");
+					return 0;
+				}
+
+				return ret;
+			}
+
+			get_writeback_data(&val);
+
+			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
+
+			if (j == 0) {
+				memcpy(prev_out, val.val, TDES_BLOCK_SIZE);
+
+				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+					memcpy(vec.pt.val, vec.iv.val,
+							TDES_BLOCK_SIZE);
+					memcpy(vec.iv.val, val.val,
+							TDES_BLOCK_SIZE);
+				} else {
+					memcpy(vec.iv.val, vec.ct.val,
+							TDES_BLOCK_SIZE);
+					memcpy(vec.ct.val, val.val,
+							TDES_BLOCK_SIZE);
+				}
+				continue;
+			}
+
+			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+				memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE);
+				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
+			} else {
+				memcpy(vec.iv.val, vec.ct.val, TDES_BLOCK_SIZE);
+				memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE);
+			}
+
+			if (j == TDES_INTERN_ITER - 1)
+				continue;
+
+			memcpy(prev_out, val.val, TDES_BLOCK_SIZE);
+
+			if (j == TDES_INTERN_ITER - 3)
+				memcpy(prev_prev_out, val.val, TDES_BLOCK_SIZE);
+		}
+
+		info.parse_writeback(&val);
+		fprintf(info.fp_wr, "\n");
+
+		if (i == TDES_EXTERN_ITER - 1)
+			continue;
+
+		/** update key */
+		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
+
+		if (info.interim_info.tdes_data.nb_keys == 0) {
+			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
+				info.interim_info.tdes_data.nb_keys = 1;
+			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
+				info.interim_info.tdes_data.nb_keys = 2;
+			else
+				info.interim_info.tdes_data.nb_keys = 3;
+
+		}
+
+		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
+
+			switch (info.interim_info.tdes_data.nb_keys) {
+			case 3:
+				val_key.val[k] ^= val.val[k];
+				val_key.val[k + 8] ^= prev_out[k];
+				val_key.val[k + 16] ^= prev_prev_out[k];
+				break;
+			case 2:
+				val_key.val[k] ^= val.val[k];
+				val_key.val[k + 8] ^= prev_out[k];
+				val_key.val[k + 16] ^= val.val[k];
+				break;
+			default: /* case 1 */
+				val_key.val[k] ^= val.val[k];
+				val_key.val[k + 8] ^= val.val[k];
+				val_key.val[k + 16] ^= val.val[k];
+				break;
+			}
+
+		}
+
+		for (k = 0; k < 24; k++)
+			val_key.val[k] = (__builtin_popcount(val_key.val[k]) &
+					0x1) ?
+					val_key.val[k] : (val_key.val[k] ^ 0x1);
+
+		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+			memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE);
+			memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
+		} else {
+			memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
+			memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE);
+		}
+	}
+
+	return 0;
+}
+
+static int
 fips_mct_aes_test(void)
 {
 #define AES_BLOCK_SIZE	16
@@ -758,6 +925,14 @@ init_test_ops(void)
 		test_ops.prepare_xform = prepare_hmac_xform;
 		test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_TDES:
+		test_ops.prepare_op = prepare_cipher_op;
+		test_ops.prepare_xform  = prepare_tdes_xform;
+		if (info.interim_info.tdes_data.test_type == TDES_MCT)
+			test_ops.test = fips_mct_tdes_test;
+		else
+			test_ops.test = fips_generic_test;
+		break;
 
 	default:
 		return -1;
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index dcf90bbbb..a18e76d4b 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -11,6 +11,7 @@ allow_experimental_apis = true
 sources = files(
 	'cryptodev_fips_parse_aes.c',
 	'cryptodev_fips_parse_hmac.c',
+	'cryptodev_fips_parse_3des.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 5/8] examples: add gcm parser
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
                     ` (3 preceding siblings ...)
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 4/8] examples: add TDES parser and enablement for test types Fan Zhang
@ 2018-10-04 13:12   ` Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 6/8] examples: add cmac parser and enablement for test types Fan Zhang
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for GCM parser, to allow the
application to parser the GCM request file and to validate all
tests supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_gcm.c                     | 125 +++++++++++++++++++++
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |   4 +
 examples/cryptodev_fips_validate/main.c            | 116 ++++++++++++++++++-
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 251 insertions(+), 1 deletion(-)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index 54ea43ffd..1eb0108bd 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -8,6 +8,7 @@ APP = cryptodev_fips_validate_app
 SRCS-y := cryptodev_fips_parse_aes.c
 SRCS-y += cryptodev_fips_parse_hmac.c
 SRCS-y += cryptodev_fips_parse_3des.c
+SRCS-y += cryptodev_fips_parse_gcm.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c
new file mode 100644
index 000000000..6999dad7f
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_gcm.c
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define NEW_LINE_STR	"#"
+#define OP_STR		"GCM "
+
+#define PARAM_PREFIX	"["
+#define KEYLEN_STR	"Keylen = "
+#define IVLEN_STR	"IVlen = "
+#define PTLEN_STR	"PTlen = "
+#define AADLEN_STR	"AADlen = "
+#define TAGLEN_STR	"Taglen = "
+
+#define COUNT_STR	"Count = "
+#define KEY_STR		"Key = "
+#define IV_STR		"IV = "
+#define PT_STR		"PT = "
+#define CT_STR		"CT = "
+#define TAG_STR		"Tag = "
+#define AAD_STR		"AAD = "
+
+#define OP_ENC_STR	"Encrypt"
+#define OP_DEC_STR	"Decrypt"
+
+#define NEG_TEST_STR	"FAIL"
+
+struct fips_test_callback gcm_dec_vectors[] = {
+		{KEY_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{CT_STR, parse_uint8_known_len_hex_str, &vec.ct},
+		{AAD_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.aad},
+		{TAG_STR, parse_uint8_known_len_hex_str,
+				&vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+struct fips_test_callback gcm_interim_vectors[] = {
+		{KEYLEN_STR, parser_read_uint32_bit_val, &vec.cipher_auth.key},
+		{IVLEN_STR, parser_read_uint32_bit_val, &vec.iv},
+		{PTLEN_STR, parser_read_uint32_bit_val, &vec.pt},
+		{AADLEN_STR, parser_read_uint32_bit_val, &vec.cipher_auth.aad},
+		{TAGLEN_STR, parser_read_uint32_bit_val,
+				&vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback gcm_enc_vectors[] = {
+		{KEY_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{AAD_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.aad},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_test_gcm_writeback(struct fips_val *val)
+{
+	struct fips_val tmp_val;
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		fprintf(info.fp_wr, "%s", CT_STR);
+
+		tmp_val.val = val->val;
+		tmp_val.len = vec.pt.len;
+
+		parse_write_hex_str(&tmp_val);
+
+		fprintf(info.fp_wr, "%s", TAG_STR);
+
+		tmp_val.val = val->val + vec.pt.len;
+		tmp_val.len = val->len - vec.pt.len;
+
+		parse_write_hex_str(&tmp_val);
+	} else {
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
+			fprintf(info.fp_wr, "%s", PT_STR);
+
+			tmp_val.val = val->val;
+			tmp_val.len = vec.pt.len;
+
+			parse_write_hex_str(&tmp_val);
+		} else
+			fprintf(info.fp_wr, "%s\n", NEG_TEST_STR);
+	}
+
+	return 0;
+}
+
+int
+parse_test_gcm_init(void)
+{
+	char *tmp;
+	uint32_t i;
+
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+
+
+		tmp = strstr(line, OP_STR);
+		if (tmp) {
+			if (strstr(line, OP_ENC_STR)) {
+				info.op = FIPS_TEST_ENC_AUTH_GEN;
+				info.callbacks = gcm_enc_vectors;
+			} else if (strstr(line, OP_DEC_STR)) {
+				info.op = FIPS_TEST_DEC_AUTH_VERIF;
+				info.callbacks = gcm_dec_vectors;
+			} else
+				return -EINVAL;
+		}
+	}
+
+	info.interim_callbacks = gcm_interim_vectors;
+	info.parse_writeback = parse_test_gcm_writeback;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index bb396e54d..d45c88de6 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -109,6 +109,11 @@ fips_test_parse_header(void)
 			ret = parse_test_aes_init();
 			if (ret < 0)
 				return ret;
+		} else if (strstr(info.vec[i], "GCM")) {
+			info.algo = FIPS_TEST_ALGO_AES_GCM;
+			ret = parse_test_gcm_init();
+			if (ret < 0)
+				return ret;
 		} else if (strstr(info.vec[i], "HMAC")) {
 			info.algo = FIPS_TEST_ALGO_HMAC;
 			ret = parse_test_hmac_init();
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index c9b11dda2..685bc0bf8 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -24,6 +24,7 @@
 
 enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
+		FIPS_TEST_ALGO_AES_GCM,
 		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_TDES,
 		FIPS_TEST_ALGO_MAX
@@ -172,6 +173,9 @@ int
 parse_test_hmac_init(void);
 
 int
+parse_test_gcm_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 9696fa895..32f2a99ee 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -462,6 +462,70 @@ prepare_auth_op(void)
 }
 
 static int
+prepare_aead_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	rte_pktmbuf_reset(env.mbuf);
+
+	memcpy(iv, vec.iv.val, vec.iv.len);
+
+	sym->m_src = env.mbuf;
+	sym->aead.data.offset = 0;
+	sym->aead.aad.data = vec.aead.aad.val;
+	sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		uint8_t *pt;
+
+		if (vec.pt.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "PT len %u\n", vec.pt.len);
+			return -EPERM;
+		}
+
+		pt = (uint8_t *)rte_pktmbuf_append(env.mbuf,
+				vec.pt.len + vec.aead.digest.len);
+
+		if (!pt) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(pt, vec.pt.val, vec.pt.len);
+		sym->aead.data.length = vec.pt.len;
+		sym->aead.digest.data = pt + vec.pt.len;
+		sym->aead.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+				env.mbuf, vec.pt.len);
+	} else {
+		uint8_t *ct;
+
+		if (vec.ct.len > RTE_MBUF_MAX_NB_SEGS) {
+			RTE_LOG(ERR, USER1, "CT len %u\n", vec.ct.len);
+			return -EPERM;
+		}
+
+		ct = (uint8_t *)rte_pktmbuf_append(env.mbuf, vec.ct.len);
+
+		if (!ct) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			return -ENOMEM;
+		}
+
+		memcpy(ct, vec.ct.val, vec.ct.len);
+		sym->aead.data.length = vec.ct.len;
+		sym->aead.digest.data = vec.aead.digest.val;
+		sym->aead.digest.phys_addr = rte_malloc_virt2iova(
+				sym->aead.digest.data);
+	}
+
+	rte_crypto_op_attach_sym_session(env.op, env.sess);
+}
+
+static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
 	const struct rte_cryptodev_symmetric_capability *cap;
@@ -578,6 +642,52 @@ prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
+	aead_xform->aad_length = vec.aead.aad.len;
+	aead_xform->digest_length = vec.aead.digest.len;
+	aead_xform->iv.offset = IV_OFF;
+	aead_xform->iv.length = vec.iv.len;
+	aead_xform->key.data = vec.aead.key.val;
+	aead_xform->key.length = vec.aead.key.len;
+	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AEAD_OP_ENCRYPT :
+			RTE_CRYPTO_AEAD_OP_DECRYPT;
+
+	cap_idx.algo.aead = aead_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_aead(cap,
+			aead_xform->key.length,
+			aead_xform->digest_length, aead_xform->aad_length,
+			aead_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1,
+			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
+				info.device_name, aead_xform->key.length,
+				aead_xform->digest_length,
+				aead_xform->aad_length,
+				aead_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static void
 get_writeback_data(struct fips_val *val)
 {
@@ -933,7 +1043,11 @@ init_test_ops(void)
 		else
 			test_ops.test = fips_generic_test;
 		break;
-
+	case FIPS_TEST_ALGO_AES_GCM:
+		test_ops.prepare_op = prepare_aead_op;
+		test_ops.prepare_xform = prepare_gcm_xform;
+		test_ops.test = fips_generic_test;
+		break;
 	default:
 		return -1;
 	}
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index a18e76d4b..510d2a79e 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -12,6 +12,7 @@ sources = files(
 	'cryptodev_fips_parse_aes.c',
 	'cryptodev_fips_parse_hmac.c',
 	'cryptodev_fips_parse_3des.c',
+	'cryptodev_fips_parse_gcm.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 6/8] examples: add cmac parser and enablement for test types
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
                     ` (4 preceding siblings ...)
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 5/8] examples: add gcm parser Fan Zhang
@ 2018-10-04 13:12   ` Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 7/8] examples: add ccm " Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 8/8] doc: add guides for fips validation Fan Zhang
  7 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for CMAC parser, to allow the
application to parser the cmac request files and to validate all
test types supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_cmac.c                    | 116 +++++++++++++++++++++
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |   4 +
 examples/cryptodev_fips_validate/main.c            |  43 ++++++++
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 170 insertions(+)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index 1eb0108bd..f5c2705d5 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -9,6 +9,7 @@ SRCS-y := cryptodev_fips_parse_aes.c
 SRCS-y += cryptodev_fips_parse_hmac.c
 SRCS-y += cryptodev_fips_parse_3des.c
 SRCS-y += cryptodev_fips_parse_gcm.c
+SRCS-y += cryptodev_fips_parse_cmac.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c
new file mode 100644
index 000000000..37c6317ae
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_cmac.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <rte_string_fns.h>
+
+#include <rte_cryptodev.h>
+
+#include "cryptodev_fips_validate.h"
+
+#define NEW_LINE_STR	"#"
+#define OP_STR		"CMAC"
+
+#define ALGO_STR	"Alg = "
+#define MODE_STR	"Mode = "
+
+#define COUNT_STR	"Count = "
+#define KLEN_STR	"Klen = "
+#define PTLEN_STR	"Mlen = "
+#define TAGLEN_STR	"Tlen = "
+#define KEY_STR		"Key = "
+#define PT_STR		"Msg = "
+#define TAG_STR		"Mac = "
+
+#define GEN_STR		"Generate"
+#define VERIF_STR	"Verify"
+
+#define POS_NEG_STR	"Result = "
+#define PASS_STR	"P"
+#define FAIL_STR	"F"
+
+struct hash_algo_conversion {
+	const char *str;
+	enum fips_test_algorithms algo;
+} cmac_algo[] = {
+		{"AES", FIPS_TEST_ALGO_AES_CMAC},
+};
+
+static int
+parse_test_cmac_writeback(struct fips_val *val)
+{
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		struct fips_val tmp_val = {val->val + vec.pt.len,
+				vec.cipher_auth.digest.len};
+
+		fprintf(info.fp_wr, "%s", TAG_STR);
+		parse_write_hex_str(&tmp_val);
+	} else {
+		fprintf(info.fp_wr, "%s", POS_NEG_STR);
+
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)
+			fprintf(info.fp_wr, "%s\n", PASS_STR);
+		else if (vec.status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED)
+			fprintf(info.fp_wr, "%s\n", FAIL_STR);
+		else
+			fprintf(info.fp_wr, "Error\n");
+	}
+
+	return 0;
+}
+
+struct fips_test_callback cmac_tests_vectors[] = {
+		{KLEN_STR, parser_read_uint32_val, &vec.cipher_auth.key},
+		{PTLEN_STR, parser_read_uint32_val, &vec.pt},
+		{TAGLEN_STR, parser_read_uint32_val, &vec.cipher_auth.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{TAG_STR, parse_uint8_known_len_hex_str,
+				&vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+int
+parse_test_cmac_init(void)
+{
+	char *tmp;
+	uint32_t i, j;
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+
+		tmp = strstr(line, ALGO_STR);
+		if (!tmp)
+			continue;
+
+		for (j = 0; j < RTE_DIM(cmac_algo); j++) {
+			if (!strstr(line, cmac_algo[j].str))
+				continue;
+
+			info.algo = cmac_algo[j].algo;
+			break;
+		}
+
+		if (j == RTE_DIM(cmac_algo))
+			return -EINVAL;
+
+		tmp = strstr(line, MODE_STR);
+		if (!tmp)
+			return -1;
+
+		if (strstr(tmp, GEN_STR))
+			info.op = FIPS_TEST_ENC_AUTH_GEN;
+		else if (strstr(tmp, VERIF_STR))
+			info.op = FIPS_TEST_DEC_AUTH_VERIF;
+		else
+			return -EINVAL;
+	}
+
+	info.parse_writeback = parse_test_cmac_writeback;
+	info.callbacks = cmac_tests_vectors;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index d45c88de6..4617c67e2 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -114,6 +114,11 @@ fips_test_parse_header(void)
 			ret = parse_test_gcm_init();
 			if (ret < 0)
 				return ret;
+		} else if (strstr(info.vec[i], "CMAC")) {
+			info.algo = FIPS_TEST_ALGO_AES_CMAC;
+			ret = parse_test_cmac_init();
+			if (ret < 0)
+				return 0;
 		} else if (strstr(info.vec[i], "HMAC")) {
 			info.algo = FIPS_TEST_ALGO_HMAC;
 			ret = parse_test_hmac_init();
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index 685bc0bf8..7bd1e9a6f 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -25,6 +25,7 @@
 enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
 		FIPS_TEST_ALGO_AES_GCM,
+		FIPS_TEST_ALGO_AES_CMAC,
 		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_TDES,
 		FIPS_TEST_ALGO_MAX
@@ -176,6 +177,9 @@ int
 parse_test_gcm_init(void);
 
 int
+parse_test_cmac_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 32f2a99ee..864b55d04 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -688,6 +688,44 @@ prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
+	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
+	auth_xform->digest_length = vec.cipher_auth.digest.len;
+	auth_xform->key.data = vec.cipher_auth.key.val;
+	auth_xform->key.length = vec.cipher_auth.key.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length, 0) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static void
 get_writeback_data(struct fips_val *val)
 {
@@ -1048,6 +1086,11 @@ init_test_ops(void)
 		test_ops.prepare_xform = prepare_gcm_xform;
 		test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_AES_CMAC:
+		test_ops.prepare_op = prepare_auth_op;
+		test_ops.prepare_xform = prepare_cmac_xform;
+		test_ops.test = fips_generic_test;
+		break;
 	default:
 		return -1;
 	}
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index 510d2a79e..4889d7095 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -13,6 +13,7 @@ sources = files(
 	'cryptodev_fips_parse_hmac.c',
 	'cryptodev_fips_parse_3des.c',
 	'cryptodev_fips_parse_gcm.c',
+	'cryptodev_fips_parse_cmac.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 7/8] examples: add ccm parser and enablement for test types
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
                     ` (5 preceding siblings ...)
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 6/8] examples: add cmac parser and enablement for test types Fan Zhang
@ 2018-10-04 13:12   ` Fan Zhang
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 8/8] doc: add guides for fips validation Fan Zhang
  7 siblings, 0 replies; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Added enablement for CCM parser, to allow the
application to parser the ccm request files and to validate all
test types supported.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/cryptodev_fips_validate/Makefile          |   1 +
 .../cryptodev_fips_parse_ccm.c                     | 272 +++++++++++++++++++++
 .../cryptodev_fips_parse_validate.c                |   5 +
 .../cryptodev_fips_validate.h                      |  22 ++
 examples/cryptodev_fips_validate/main.c            |  56 ++++-
 examples/cryptodev_fips_validate/meson.build       |   1 +
 6 files changed, 356 insertions(+), 1 deletion(-)
 create mode 100644 examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c

diff --git a/examples/cryptodev_fips_validate/Makefile b/examples/cryptodev_fips_validate/Makefile
index f5c2705d5..4f1dc6b5d 100644
--- a/examples/cryptodev_fips_validate/Makefile
+++ b/examples/cryptodev_fips_validate/Makefile
@@ -10,6 +10,7 @@ SRCS-y += cryptodev_fips_parse_hmac.c
 SRCS-y += cryptodev_fips_parse_3des.c
 SRCS-y += cryptodev_fips_parse_gcm.c
 SRCS-y += cryptodev_fips_parse_cmac.c
+SRCS-y += cryptodev_fips_parse_ccm.c
 SRCS-y += cryptodev_fips_parse_validate.c
 SRCS-y += main.c
 
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c
new file mode 100644
index 000000000..0fdb75ad4
--- /dev/null
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_ccm.c
@@ -0,0 +1,272 @@
+/* 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 DVPT_STR	"CCM-DVPT"
+#define VADT_STR	"CCM-VADT"
+#define VPT_STR		"CCM-VPT"
+#define VNT_STR		"CCM-VNT"
+#define VTT_STR		"CCM-VTT"
+
+#define PARAM_PREFIX	"["
+#define ALEN_PREFIX	"Alen = "
+#define PLEN_PREFIX	"Plen = "
+#define IVLEN_PREFIX	"Nlen = "
+#define DIGESTL_PREFIX	"Tlen = "
+
+#define COUNT_STR	"Count = "
+#define KEY_STR		"Key = "
+#define IV_STR		"Nonce = "
+#define PT_STR		"Payload = "
+#define CT_STR		"CT = "
+#define AAD_STR		"Adata = "
+#define POS_NEG_STR	"Result = "
+
+#define POS_KEYWORD	"Pass"
+#define NEG_KEYWORD	"Fail"
+
+static int
+parser_dvpt_interim(const char *key, char *src, struct fips_val *val)
+{
+	char *tmp, c, value[10];
+	char num_pattern[] = "0123456789";
+	int i = 0;
+
+	memset(value, 0, 10);
+
+	tmp = strstr(src, key);
+	if (!tmp)
+		return -1;
+
+	tmp += strlen(key);
+
+	c = tmp[0];
+
+	while (strchr(num_pattern, c) && i < 10) {
+		value[i++] = c;
+		c = tmp[i];
+	}
+
+	return parser_read_uint32_val("", value, val);
+}
+
+static int
+parse_dvpt_ct_hex_str(const char *key, char *src, struct fips_val *val)
+{
+	int ret;
+
+	val->len = vec.pt.len;
+
+	ret = parse_uint8_known_len_hex_str(key, src, val);
+	if (ret < 0)
+		return ret;
+
+	src += strlen(key) + val->len * 2;
+
+	ret = parse_uint8_known_len_hex_str("", src, &vec.aead.digest);
+	if (ret < 0) {
+		rte_free(val->val);
+		memset(val, 0, sizeof(*val));
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+parse_uint8_ccm_aad_str(const char *key, char *src, struct fips_val *val)
+{
+	uint32_t len = val->len, j;
+
+	src += strlen(key);
+
+	/* CCM aad requires 18 bytes padding before the real content */
+	val->val = rte_zmalloc(NULL, len + 18, 0);
+	if (!val->val)
+		return -1;
+
+	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 + 18], byte) < 0) {
+			rte_free(val->val);
+			memset(val, 0, sizeof(*val));
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+struct fips_test_callback ccm_vnt_vec[] = {
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vnt_interim_vec[] = {
+		{ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad},
+		{PLEN_PREFIX, parser_read_uint32_val, &vec.pt},
+		{DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest},
+		{IVLEN_PREFIX, parser_read_uint32_val, &vec.iv},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vtt_vec[] = {
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vtt_interim_vec[] = {
+		{ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad},
+		{PLEN_PREFIX, parser_read_uint32_val, &vec.pt},
+		{IVLEN_PREFIX, parser_read_uint32_val, &vec.iv},
+		{DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vadt_vec[] = {
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vadt_interim_vec[] = {
+		{PLEN_PREFIX, parser_read_uint32_val, &vec.pt},
+		{IVLEN_PREFIX, parser_read_uint32_val, &vec.iv},
+		{ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad},
+		{DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vpt_vec[] = {
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{PT_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_vpt_interim_vec[] = {
+		{ALEN_PREFIX, parser_read_uint32_val, &vec.aead.aad},
+		{IVLEN_PREFIX, parser_read_uint32_val, &vec.iv},
+		{DIGESTL_PREFIX, parser_read_uint32_val, &vec.aead.digest},
+		{PLEN_PREFIX, parser_read_uint32_val, &vec.pt},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_dvpt_vec[] = {
+		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
+		{AAD_STR, parse_uint8_ccm_aad_str, &vec.aead.aad},
+		{CT_STR, parse_dvpt_ct_hex_str, &vec.ct},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback ccm_dvpt_interim_vec[] = {
+		{ALEN_PREFIX, parser_dvpt_interim, &vec.aead.aad},
+		{PLEN_PREFIX, parser_dvpt_interim, &vec.pt},
+		{IVLEN_PREFIX, parser_dvpt_interim, &vec.iv},
+		{DIGESTL_PREFIX, parser_dvpt_interim, &vec.aead.digest},
+		{KEY_STR, parse_uint8_hex_str, &vec.aead.key},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct ccm_test_types {
+	const char *str;
+	uint32_t type;
+	const struct fips_test_callback *cb;
+	const struct fips_test_callback *cb_interim;
+	enum fips_test_op op;
+} ctt[] = {
+		{DVPT_STR, CCM_DVPT, ccm_dvpt_vec, ccm_dvpt_interim_vec,
+			FIPS_TEST_DEC_AUTH_VERIF},
+		{VPT_STR, CCM_VPT, ccm_vpt_vec, ccm_vpt_interim_vec,
+			FIPS_TEST_ENC_AUTH_GEN},
+		{VADT_STR, CCM_VADT, ccm_vadt_vec, ccm_vadt_interim_vec,
+			FIPS_TEST_ENC_AUTH_GEN},
+		{VNT_STR, CCM_VNT, ccm_vnt_vec, ccm_vnt_interim_vec,
+			FIPS_TEST_ENC_AUTH_GEN},
+		{VTT_STR, CCM_VTT, ccm_vtt_vec, ccm_vtt_interim_vec,
+			FIPS_TEST_ENC_AUTH_GEN},
+};
+
+static int
+parse_test_ccm_writeback(struct fips_val *val)
+{
+	struct fips_val tmp_val;
+
+	switch (info.interim_info.ccm_data.test_type) {
+	case CCM_DVPT:
+		fprintf(info.fp_wr, "%s", POS_NEG_STR);
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
+			fprintf(info.fp_wr, "%s\n", POS_KEYWORD);
+			fprintf(info.fp_wr, "%s", PT_STR);
+
+			tmp_val.val = val->val;
+			tmp_val.len = vec.pt.len;
+
+			if (tmp_val.len == 0)
+				fprintf(info.fp_wr, "00\n");
+			else
+				parse_write_hex_str(&tmp_val);
+		} else
+			fprintf(info.fp_wr, "%s\n", NEG_KEYWORD);
+
+		break;
+
+	case CCM_VADT:
+	case CCM_VNT:
+	case CCM_VPT:
+	case CCM_VTT:
+		fprintf(info.fp_wr, "%s", CT_STR);
+
+		parse_write_hex_str(val);
+
+		break;
+
+	}
+
+	return 0;
+}
+
+int
+parse_test_ccm_init(void)
+{
+
+	uint32_t i;
+
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+		uint32_t j;
+
+		for (j = 0; j < RTE_DIM(ctt); j++)
+			if (strstr(line, ctt[j].str)) {
+				info.interim_info.ccm_data.test_type =
+						ctt[j].type;
+				info.callbacks = ctt[j].cb;
+				info.interim_callbacks = ctt[j].cb_interim;
+				info.op = ctt[j].op;
+				break;
+		}
+	}
+
+	info.parse_writeback = parse_test_ccm_writeback;
+
+	return 0;
+}
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
index 4617c67e2..47e3732b2 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_parse_validate.c
@@ -119,6 +119,11 @@ fips_test_parse_header(void)
 			ret = parse_test_cmac_init();
 			if (ret < 0)
 				return 0;
+		} else if (strstr(info.vec[i], "CCM")) {
+			info.algo = FIPS_TEST_ALGO_AES_CCM;
+			ret = parse_test_ccm_init();
+			if (ret < 0)
+				return 0;
 		} else if (strstr(info.vec[i], "HMAC")) {
 			info.algo = FIPS_TEST_ALGO_HMAC;
 			ret = parse_test_hmac_init();
diff --git a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
index 7bd1e9a6f..afa0c0a80 100644
--- a/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
+++ b/examples/cryptodev_fips_validate/cryptodev_fips_validate.h
@@ -26,6 +26,7 @@ enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES = 0,
 		FIPS_TEST_ALGO_AES_GCM,
 		FIPS_TEST_ALGO_AES_CMAC,
+		FIPS_TEST_ALGO_AES_CCM,
 		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_TDES,
 		FIPS_TEST_ALGO_MAX
@@ -102,6 +103,14 @@ enum fips_tdes_test_types {
 	TDES_MMT /* Multi block Message Test */
 };
 
+enum fips_ccm_test_types {
+	CCM_VADT	= 1, /* Variable Associated Data Test */
+	CCM_VPT,		 /* Variable Payload Test */
+	CCM_VNT,		 /* Variable Nonce Test */
+	CCM_VTT,		 /* Variable Tag Test */
+	CCM_DVPT,	 /*  Decryption-Verification Process Test */
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -117,6 +126,15 @@ struct tdes_interim_data {
 	uint32_t nb_keys;
 };
 
+struct ccm_interim_data {
+	enum fips_ccm_test_types test_type;
+	uint32_t aad_len;
+	uint32_t pt_len;
+	uint32_t digest_len;
+	uint32_t key_len;
+	uint32_t iv_len;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -132,6 +150,7 @@ struct fips_test_interim_info {
 		struct aesavs_interim_data aes_data;
 		struct hmac_interim_data hmac_data;
 		struct tdes_interim_data tdes_data;
+		struct ccm_interim_data ccm_data;
 
 	} interim_info;
 
@@ -180,6 +199,9 @@ int
 parse_test_cmac_init(void);
 
 int
+parse_test_ccm_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/cryptodev_fips_validate/main.c b/examples/cryptodev_fips_validate/main.c
index 864b55d04..1d6afbf74 100644
--- a/examples/cryptodev_fips_validate/main.c
+++ b/examples/cryptodev_fips_validate/main.c
@@ -470,7 +470,10 @@ prepare_aead_op(void)
 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
 	rte_pktmbuf_reset(env.mbuf);
 
-	memcpy(iv, vec.iv.val, vec.iv.len);
+	if (info.algo == FIPS_TEST_ALGO_AES_CCM)
+		memcpy(iv + 1, vec.iv.val, vec.iv.len);
+	else
+		memcpy(iv, vec.iv.val, vec.iv.len);
 
 	sym->m_src = env.mbuf;
 	sym->aead.data.offset = 0;
@@ -726,6 +729,52 @@ prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
+	aead_xform->aad_length = vec.aead.aad.len;
+	aead_xform->digest_length = vec.aead.digest.len;
+	aead_xform->iv.offset = IV_OFF;
+	aead_xform->iv.length = vec.iv.len;
+	aead_xform->key.data = vec.aead.key.val;
+	aead_xform->key.length = vec.aead.key.len;
+	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AEAD_OP_ENCRYPT :
+			RTE_CRYPTO_AEAD_OP_DECRYPT;
+
+	cap_idx.algo.aead = aead_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_aead(cap,
+			aead_xform->key.length,
+			aead_xform->digest_length, aead_xform->aad_length,
+			aead_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1,
+			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
+				info.device_name, aead_xform->key.length,
+				aead_xform->digest_length,
+				aead_xform->aad_length,
+				aead_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
 static void
 get_writeback_data(struct fips_val *val)
 {
@@ -1091,6 +1140,11 @@ init_test_ops(void)
 		test_ops.prepare_xform = prepare_cmac_xform;
 		test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_AES_CCM:
+		test_ops.prepare_op = prepare_aead_op;
+		test_ops.prepare_xform = prepare_ccm_xform;
+		test_ops.test = fips_generic_test;
+		break;
 	default:
 		return -1;
 	}
diff --git a/examples/cryptodev_fips_validate/meson.build b/examples/cryptodev_fips_validate/meson.build
index 4889d7095..e3bf7ac88 100644
--- a/examples/cryptodev_fips_validate/meson.build
+++ b/examples/cryptodev_fips_validate/meson.build
@@ -14,6 +14,7 @@ sources = files(
 	'cryptodev_fips_parse_3des.c',
 	'cryptodev_fips_parse_gcm.c',
 	'cryptodev_fips_parse_cmac.c',
+	'cryptodev_fips_parse_ccm.c',
 	'cryptodev_fips_parse_validate.c',
 	'main.c'
 )
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [dpdk-dev] [PATCH v3 8/8] doc: add guides for fips validation
  2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
                     ` (6 preceding siblings ...)
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 7/8] examples: add ccm " Fan Zhang
@ 2018-10-04 13:12   ` Fan Zhang
  2018-10-09  7:01     ` Akhil Goyal
  7 siblings, 1 reply; 20+ messages in thread
From: Fan Zhang @ 2018-10-04 13:12 UTC (permalink / raw)
  To: dev; +Cc: akhil.goyal, Marko Kovacevic

From: Marko Kovacevic <marko.kovacevic@intel.com>

Document explains how to run the fips sample app
and instructions users need to parser all the request
files and generate the response files.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 doc/guides/rel_notes/release_18_11.rst       |  6 ++
 doc/guides/sample_app_ug/fips_validation.rst | 97 ++++++++++++++++++++++++++++
 doc/guides/sample_app_ug/index.rst           |  5 ++
 3 files changed, 108 insertions(+)
 create mode 100644 doc/guides/sample_app_ug/fips_validation.rst

diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 2133a5b9b..db1579b6e 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -104,6 +104,12 @@ New Features
   the specified port. The port must be stopped before the command call in order
   to reconfigure queues.
 
+* **Added Cryptodev Fips Validation Example Application.**
+
+  Added an example application to parse and perform symmetric cryptography
+  computation to the NIST Cryptographic Algorithm Validation Program (CAVP)
+  test vectors.
+
 
 API Changes
 -----------
diff --git a/doc/guides/sample_app_ug/fips_validation.rst b/doc/guides/sample_app_ug/fips_validation.rst
new file mode 100644
index 000000000..0e06aab99
--- /dev/null
+++ b/doc/guides/sample_app_ug/fips_validation.rst
@@ -0,0 +1,97 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2018 Intel Corporation.
+
+Federal Information Processing Standards (FIPS) CryptoDev Validation
+====================================================================
+
+Overview
+--------
+
+Federal Information Processing Standards (FIPS) are publicly announced standards
+developed by the United States federal government for use in computer systems by
+non-military government agencies and government contractors.
+
+This application is used to parse and perform symmetric cryptography
+computation to the NIST Cryptographic Algorithm Validation Program (CAVP) test
+vectors.
+
+Limitations
+-----------
+
+* Only NIST CAVP request files are parsed by this application.
+* The version of request file supported is ``CAVS 21.0``
+* The application does not supply the test vectors. The user is expected to
+  obtain the test vector files from `NIST
+  <https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/block-ciphers>`_
+* Supported test vectors
+    * AES-CBC (128,192,256) - GFSbox, KeySbox, MCT, MMT
+    * AES-GCM (128,192,256) - EncryptExtIV, Decrypt
+    * AES-CCM (128) - VADT, VNT, VPT, VTT, DVPT
+    * AES-CMAC (128) - Generate, Verify
+    * HMAC (SHA1, SHA224, SHA256, SHA384, SHA512)
+    * TDES (1 Key, 2 Keys, 3 Keys) - MMT, Monte, Permop, Subkey, Varkey, VarText
+
+Compiling the Application
+-------------------------
+
+* Compile Application
+
+    .. code-block:: console
+
+         make -C examples/cryptodev_fips_validate
+
+*  Run ``dos2unix`` on the request files
+
+    .. code-block:: console
+
+         dos2unix AES/req/*
+         dos2unix AES_GCM/req/*
+         dos2unix CCM/req/*
+         dos2unix CMAC/req/*
+         dos2unix HMAC/req/*
+         dos2unix TDES/req/*
+
+Running the Application
+-----------------------
+
+The application requires a number of command line options:
+
+    .. code-block:: console
+
+         ./cryptodev_fips_validate_app [EAL options]
+         -- --req-file FILE_PATH/FOLDER_PATH
+         --rsp-file FILE_PATH/FOLDER_PATH
+         [--cryptodev DEVICE_NAME] [--cryptodev-id ID] [--path-is-folder]
+
+where,
+  * req-file: The path of the request file or folder, separated by
+    ``path-is-folder`` option.
+
+  * rsp-file: The path that the response file or folder is stored. separated by
+    ``path-is-folder`` option.
+
+  * cryptodev: The name of the target DPDK Crypto device to be validated.
+
+  * cryptodev-id: The id of the target DPDK Crypto device to be validated.
+
+  * path-is-folder: If presented the application expects req-file and rsp-file
+    are folder paths.
+
+To run the application in linuxapp environment to test one AES FIPS test data
+file for crypto_aesni_mb PMD, issue the command:
+
+.. code-block:: console
+
+    $ ./cryptodev_fips_validate_app --vdev crypto_aesni_mb --
+    --req-file /PATH/TO/REQUEST/FILE.req --rsp-file ./PATH/TO/RESPONSE/FILE.rsp
+    --cryptodev crypto_aesni_mb
+
+To run the application in linuxapp environment to test all AES-GCM FIPS test
+data files in one folder for crypto_aesni_gcm PMD, issue the command:
+
+.. code-block:: console
+
+    $ ./cryptodev_fips_validate_app --vdev crypto_aesni_gcm0 --
+    --req-file /PATH/TO/REQUEST/FILE/FOLDER/
+    --rsp-file ./PATH/TO/RESPONSE/FILE/FOLDER/
+    --cryptodev-id 0 --path-is-folder
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 5bedf4f6f..146296b7a 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -56,6 +56,7 @@ Sample Applications User Guides
     performance_thread
     ipsec_secgw
     bbdev_app
+    fips_validation
 
 **Figures**
 
@@ -83,6 +84,10 @@ Sample Applications User Guides
 
 :numref:`figure_client_svr_sym_multi_proc_app` :ref:`figure_client_svr_sym_multi_proc_app`
 
+:numref:`figure_master_slave_proc` :ref:`figure_master_slave_proc`
+
+:numref:`figure_slave_proc_recov` :ref:`figure_slave_proc_recov`
+
 :numref:`figure_qos_sched_app_arch` :ref:`figure_qos_sched_app_arch`
 
 :numref:`figure_pipeline_overview` :ref:`figure_pipeline_overview`
-- 
2.13.6

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [dpdk-dev] [PATCH v3 8/8] doc: add guides for fips validation
  2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 8/8] doc: add guides for fips validation Fan Zhang
@ 2018-10-09  7:01     ` Akhil Goyal
  2018-10-09 20:14       ` Zhang, Roy Fan
  0 siblings, 1 reply; 20+ messages in thread
From: Akhil Goyal @ 2018-10-09  7:01 UTC (permalink / raw)
  To: Fan Zhang, dev; +Cc: Marko Kovacevic



On 10/4/2018 6:42 PM, Fan Zhang wrote:
> From: Marko Kovacevic <marko.kovacevic@intel.com>
>
> Document explains how to run the fips sample app
> and instructions users need to parser all the request
> files and generate the response files.
>
> Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> ---
>   doc/guides/rel_notes/release_18_11.rst       |  6 ++
>   doc/guides/sample_app_ug/fips_validation.rst | 97 ++++++++++++++++++++++++++++
>   doc/guides/sample_app_ug/index.rst           |  5 ++
>   3 files changed, 108 insertions(+)
>   create mode 100644 doc/guides/sample_app_ug/fips_validation.rst
>
> diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
> index 2133a5b9b..db1579b6e 100644
> --- a/doc/guides/rel_notes/release_18_11.rst
> +++ b/doc/guides/rel_notes/release_18_11.rst
> @@ -104,6 +104,12 @@ New Features
>     the specified port. The port must be stopped before the command call in order
>     to reconfigure queues.
>   
> +* **Added Cryptodev Fips Validation Example Application.**
> +
> +  Added an example application to parse and perform symmetric cryptography
> +  computation to the NIST Cryptographic Algorithm Validation Program (CAVP)
> +  test vectors.
> +
>   
>   API Changes
>   -----------
> diff --git a/doc/guides/sample_app_ug/fips_validation.rst b/doc/guides/sample_app_ug/fips_validation.rst
> new file mode 100644
> index 000000000..0e06aab99
> --- /dev/null
> +++ b/doc/guides/sample_app_ug/fips_validation.rst
> @@ -0,0 +1,97 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +    Copyright(c) 2018 Intel Corporation.
> +
> +Federal Information Processing Standards (FIPS) CryptoDev Validation
> +====================================================================
> +
> +Overview
> +--------
> +
> +Federal Information Processing Standards (FIPS) are publicly announced standards
> +developed by the United States federal government for use in computer systems by
> +non-military government agencies and government contractors.
> +
> +This application is used to parse and perform symmetric cryptography
> +computation to the NIST Cryptographic Algorithm Validation Program (CAVP) test
> +vectors.
> +
> +Limitations
> +-----------
> +
> +* Only NIST CAVP request files are parsed by this application.
> +* The version of request file supported is ``CAVS 21.0``
> +* The application does not supply the test vectors. The user is expected to
> +  obtain the test vector files from `NIST
> +  <https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/block-ciphers>`_
I cannot find the .req files in the above link. It only has .rsp files 
which has both cipher text as well as plain text.

> +* Supported test vectors
> +    * AES-CBC (128,192,256) - GFSbox, KeySbox, MCT, MMT
> +    * AES-GCM (128,192,256) - EncryptExtIV, Decrypt
> +    * AES-CCM (128) - VADT, VNT, VPT, VTT, DVPT
> +    * AES-CMAC (128) - Generate, Verify
> +    * HMAC (SHA1, SHA224, SHA256, SHA384, SHA512)
> +    * TDES (1 Key, 2 Keys, 3 Keys) - MMT, Monte, Permop, Subkey, Varkey, VarText
> +
> +Compiling the Application
> +-------------------------
> +
> +* Compile Application
> +
> +    .. code-block:: console
> +
> +         make -C examples/cryptodev_fips_validate
> +
> +*  Run ``dos2unix`` on the request files
> +
> +    .. code-block:: console
> +
> +         dos2unix AES/req/*
> +         dos2unix AES_GCM/req/*
> +         dos2unix CCM/req/*
> +         dos2unix CMAC/req/*
> +         dos2unix HMAC/req/*
> +         dos2unix TDES/req/*
> +
> +Running the Application
> +-----------------------
> +
> +The application requires a number of command line options:
> +
> +    .. code-block:: console
> +
> +         ./cryptodev_fips_validate_app [EAL options]
> +         -- --req-file FILE_PATH/FOLDER_PATH
> +         --rsp-file FILE_PATH/FOLDER_PATH
> +         [--cryptodev DEVICE_NAME] [--cryptodev-id ID] [--path-is-folder]
> +
> +where,
> +  * req-file: The path of the request file or folder, separated by
> +    ``path-is-folder`` option.
> +
> +  * rsp-file: The path that the response file or folder is stored. separated by
> +    ``path-is-folder`` option.
> +
> +  * cryptodev: The name of the target DPDK Crypto device to be validated.
> +
> +  * cryptodev-id: The id of the target DPDK Crypto device to be validated.
> +
> +  * path-is-folder: If presented the application expects req-file and rsp-file
> +    are folder paths.
> +
> +To run the application in linuxapp environment to test one AES FIPS test data
> +file for crypto_aesni_mb PMD, issue the command:
> +
> +.. code-block:: console
> +
> +    $ ./cryptodev_fips_validate_app --vdev crypto_aesni_mb --
> +    --req-file /PATH/TO/REQUEST/FILE.req --rsp-file ./PATH/TO/RESPONSE/FILE.rsp
> +    --cryptodev crypto_aesni_mb
> +
> +To run the application in linuxapp environment to test all AES-GCM FIPS test
> +data files in one folder for crypto_aesni_gcm PMD, issue the command:
> +
> +.. code-block:: console
> +
> +    $ ./cryptodev_fips_validate_app --vdev crypto_aesni_gcm0 --
> +    --req-file /PATH/TO/REQUEST/FILE/FOLDER/
> +    --rsp-file ./PATH/TO/RESPONSE/FILE/FOLDER/
> +    --cryptodev-id 0 --path-is-folder
> diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
> index 5bedf4f6f..146296b7a 100644
> --- a/doc/guides/sample_app_ug/index.rst
> +++ b/doc/guides/sample_app_ug/index.rst
> @@ -56,6 +56,7 @@ Sample Applications User Guides
>       performance_thread
>       ipsec_secgw
>       bbdev_app
> +    fips_validation
>   
>   **Figures**
>   
> @@ -83,6 +84,10 @@ Sample Applications User Guides
>   
>   :numref:`figure_client_svr_sym_multi_proc_app` :ref:`figure_client_svr_sym_multi_proc_app`
>   
> +:numref:`figure_master_slave_proc` :ref:`figure_master_slave_proc`
> +
> +:numref:`figure_slave_proc_recov` :ref:`figure_slave_proc_recov`
> +
>   :numref:`figure_qos_sched_app_arch` :ref:`figure_qos_sched_app_arch`
>   
>   :numref:`figure_pipeline_overview` :ref:`figure_pipeline_overview`

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [dpdk-dev] [PATCH v3 8/8] doc: add guides for fips validation
  2018-10-09  7:01     ` Akhil Goyal
@ 2018-10-09 20:14       ` Zhang, Roy Fan
  0 siblings, 0 replies; 20+ messages in thread
From: Zhang, Roy Fan @ 2018-10-09 20:14 UTC (permalink / raw)
  To: Akhil Goyal, dev; +Cc: Kovacevic, Marko

Hi Akhil,

To obtain request files the applicant has to fill the validation request to FIPS lab.
However to test the application the response files can be used. 
The application will attach an extra line with computed results of the test cases and it will be fairly easy to check :-).
Please be sure to use dos2unix to convert the formatting of the files first.

Regards,
Fan

> -----Original Message-----
> From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> Sent: Tuesday, October 9, 2018 8:02 AM
> To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> Cc: Kovacevic, Marko <marko.kovacevic@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v3 8/8] doc: add guides for fips validation
> 
> 
> 
> On 10/4/2018 6:42 PM, Fan Zhang wrote:
> > From: Marko Kovacevic <marko.kovacevic@intel.com>
> >
> > Document explains how to run the fips sample app and instructions
> > users need to parser all the request files and generate the response
> > files.
> >
> > Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> > ---
> >   doc/guides/rel_notes/release_18_11.rst       |  6 ++
> >   doc/guides/sample_app_ug/fips_validation.rst | 97
> ++++++++++++++++++++++++++++
> >   doc/guides/sample_app_ug/index.rst           |  5 ++
> >   3 files changed, 108 insertions(+)
> >   create mode 100644 doc/guides/sample_app_ug/fips_validation.rst
> >
> > diff --git a/doc/guides/rel_notes/release_18_11.rst
> > b/doc/guides/rel_notes/release_18_11.rst
> > index 2133a5b9b..db1579b6e 100644
> > --- a/doc/guides/rel_notes/release_18_11.rst
> > +++ b/doc/guides/rel_notes/release_18_11.rst
> > @@ -104,6 +104,12 @@ New Features
> >     the specified port. The port must be stopped before the command call in
> order
> >     to reconfigure queues.
> >
> > +* **Added Cryptodev Fips Validation Example Application.**
> > +
> > +  Added an example application to parse and perform symmetric
> > + cryptography  computation to the NIST Cryptographic Algorithm
> > + Validation Program (CAVP)  test vectors.
> > +
> >
> >   API Changes
> >   -----------
> > diff --git a/doc/guides/sample_app_ug/fips_validation.rst
> > b/doc/guides/sample_app_ug/fips_validation.rst
> > new file mode 100644
> > index 000000000..0e06aab99
> > --- /dev/null
> > +++ b/doc/guides/sample_app_ug/fips_validation.rst
> > @@ -0,0 +1,97 @@
> > +..  SPDX-License-Identifier: BSD-3-Clause
> > +    Copyright(c) 2018 Intel Corporation.
> > +
> > +Federal Information Processing Standards (FIPS) CryptoDev Validation
> >
> +=========================================================
> ===========
> > +
> > +Overview
> > +--------
> > +
> > +Federal Information Processing Standards (FIPS) are publicly
> > +announced standards developed by the United States federal
> government
> > +for use in computer systems by non-military government agencies and
> government contractors.
> > +
> > +This application is used to parse and perform symmetric cryptography
> > +computation to the NIST Cryptographic Algorithm Validation Program
> > +(CAVP) test vectors.
> > +
> > +Limitations
> > +-----------
> > +
> > +* Only NIST CAVP request files are parsed by this application.
> > +* The version of request file supported is ``CAVS 21.0``
> > +* The application does not supply the test vectors. The user is
> > +expected to
> > +  obtain the test vector files from `NIST
> > +
> > +<https://csrc.nist.gov/projects/cryptographic-algorithm-validation-pr
> > +ogram/block-ciphers>`_
> I cannot find the .req files in the above link. It only has .rsp files which has
> both cipher text as well as plain text.
> 
> > +* Supported test vectors
> > +    * AES-CBC (128,192,256) - GFSbox, KeySbox, MCT, MMT
> > +    * AES-GCM (128,192,256) - EncryptExtIV, Decrypt
> > +    * AES-CCM (128) - VADT, VNT, VPT, VTT, DVPT
> > +    * AES-CMAC (128) - Generate, Verify
> > +    * HMAC (SHA1, SHA224, SHA256, SHA384, SHA512)
> > +    * TDES (1 Key, 2 Keys, 3 Keys) - MMT, Monte, Permop, Subkey,
> > +Varkey, VarText
> > +
> > +Compiling the Application
> > +-------------------------
> > +
> > +* Compile Application
> > +
> > +    .. code-block:: console
> > +
> > +         make -C examples/cryptodev_fips_validate
> > +
> > +*  Run ``dos2unix`` on the request files
> > +
> > +    .. code-block:: console
> > +
> > +         dos2unix AES/req/*
> > +         dos2unix AES_GCM/req/*
> > +         dos2unix CCM/req/*
> > +         dos2unix CMAC/req/*
> > +         dos2unix HMAC/req/*
> > +         dos2unix TDES/req/*
> > +
> > +Running the Application
> > +-----------------------
> > +
> > +The application requires a number of command line options:
> > +
> > +    .. code-block:: console
> > +
> > +         ./cryptodev_fips_validate_app [EAL options]
> > +         -- --req-file FILE_PATH/FOLDER_PATH
> > +         --rsp-file FILE_PATH/FOLDER_PATH
> > +         [--cryptodev DEVICE_NAME] [--cryptodev-id ID]
> > + [--path-is-folder]
> > +
> > +where,
> > +  * req-file: The path of the request file or folder, separated by
> > +    ``path-is-folder`` option.
> > +
> > +  * rsp-file: The path that the response file or folder is stored. separated
> by
> > +    ``path-is-folder`` option.
> > +
> > +  * cryptodev: The name of the target DPDK Crypto device to be validated.
> > +
> > +  * cryptodev-id: The id of the target DPDK Crypto device to be validated.
> > +
> > +  * path-is-folder: If presented the application expects req-file and rsp-file
> > +    are folder paths.
> > +
> > +To run the application in linuxapp environment to test one AES FIPS
> > +test data file for crypto_aesni_mb PMD, issue the command:
> > +
> > +.. code-block:: console
> > +
> > +    $ ./cryptodev_fips_validate_app --vdev crypto_aesni_mb --
> > +    --req-file /PATH/TO/REQUEST/FILE.req --rsp-
> file ./PATH/TO/RESPONSE/FILE.rsp
> > +    --cryptodev crypto_aesni_mb
> > +
> > +To run the application in linuxapp environment to test all AES-GCM
> > +FIPS test data files in one folder for crypto_aesni_gcm PMD, issue the
> command:
> > +
> > +.. code-block:: console
> > +
> > +    $ ./cryptodev_fips_validate_app --vdev crypto_aesni_gcm0 --
> > +    --req-file /PATH/TO/REQUEST/FILE/FOLDER/
> > +    --rsp-file ./PATH/TO/RESPONSE/FILE/FOLDER/
> > +    --cryptodev-id 0 --path-is-folder
> > diff --git a/doc/guides/sample_app_ug/index.rst
> > b/doc/guides/sample_app_ug/index.rst
> > index 5bedf4f6f..146296b7a 100644
> > --- a/doc/guides/sample_app_ug/index.rst
> > +++ b/doc/guides/sample_app_ug/index.rst
> > @@ -56,6 +56,7 @@ Sample Applications User Guides
> >       performance_thread
> >       ipsec_secgw
> >       bbdev_app
> > +    fips_validation
> >
> >   **Figures**
> >
> > @@ -83,6 +84,10 @@ Sample Applications User Guides
> >
> >   :numref:`figure_client_svr_sym_multi_proc_app`
> > :ref:`figure_client_svr_sym_multi_proc_app`
> >
> > +:numref:`figure_master_slave_proc` :ref:`figure_master_slave_proc`
> > +
> > +:numref:`figure_slave_proc_recov` :ref:`figure_slave_proc_recov`
> > +
> >   :numref:`figure_qos_sched_app_arch` :ref:`figure_qos_sched_app_arch`
> >
> >   :numref:`figure_pipeline_overview` :ref:`figure_pipeline_overview`


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2018-10-09 20:18 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-04  9:40 [dpdk-dev] [PATCH v2 0/8] FIPS validation capability Fan Zhang
2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 1/8] examples: add fips validation into examples Fan Zhang
2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 2/8] examples: add aes parser and enablement for test types Fan Zhang
2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 3/8] examples: add hmac parser Fan Zhang
2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 4/8] examples: add TDES parser and enablement for test types Fan Zhang
2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 5/8] examples: add gcm parser Fan Zhang
2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 6/8] examples: add cmac parser and enablement for test types Fan Zhang
2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 7/8] examples: add ccm " Fan Zhang
2018-10-04  9:40 ` [dpdk-dev] [PATCH v2 8/8] doc: add guides for fips validation Fan Zhang
2018-10-04 13:12 ` [dpdk-dev] [PATCH v3 0/8] FIPS validation capability Fan Zhang
2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 1/8] examples: add fips validation into examples Fan Zhang
2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 2/8] examples: add aes parser and enablement for test types Fan Zhang
2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 3/8] examples: add hmac parser Fan Zhang
2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 4/8] examples: add TDES parser and enablement for test types Fan Zhang
2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 5/8] examples: add gcm parser Fan Zhang
2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 6/8] examples: add cmac parser and enablement for test types Fan Zhang
2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 7/8] examples: add ccm " Fan Zhang
2018-10-04 13:12   ` [dpdk-dev] [PATCH v3 8/8] doc: add guides for fips validation Fan Zhang
2018-10-09  7:01     ` Akhil Goyal
2018-10-09 20:14       ` Zhang, Roy Fan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).