[v2,1/1] fips_validation: Add plain SHA support

Message ID 20190319094348.8756-2-damianx.nowak@intel.com (mailing list archive)
State Accepted, archived
Delegated to: akhil goyal
Headers
Series fips_validation: Add plain SHA support |

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/intel-Performance-Testing success Performance Testing PASS
ci/mellanox-Performance-Testing success Performance Testing PASS
ci/checkpatch success coding style OK

Commit Message

Damian Nowak March 19, 2019, 9:43 a.m. UTC
  This patch enables plain SHA algorithm CAVP test support
in fips_validation sample application.

Signed-off-by: Damian Nowak <damianx.nowak@intel.com>
Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Marko Kovacevic <marko.kovacevic@intel.com>
---
 examples/fips_validation/Makefile              |   1 +
 examples/fips_validation/fips_validation.c     |  17 ++++
 examples/fips_validation/fips_validation.h     |  17 +++-
 examples/fips_validation/fips_validation_sha.c | 110 +++++++++++++++++++++
 examples/fips_validation/main.c                | 127 +++++++++++++++++++++++++
 examples/fips_validation/meson.build           |   1 +
 6 files changed, 272 insertions(+), 1 deletion(-)
 create mode 100644 examples/fips_validation/fips_validation_sha.c
  

Comments

Akhil Goyal March 22, 2019, 3:06 p.m. UTC | #1
On 3/19/2019 3:13 PM, Damian Nowak wrote:
> This patch enables plain SHA algorithm CAVP test support
> in fips_validation sample application.
>
> Signed-off-by: Damian Nowak <damianx.nowak@intel.com>
> Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Marko Kovacevic <marko.kovacevic@intel.com>
> ---
>
Applied to dpdk-next-crypto

Thanks.
  

Patch

diff --git a/examples/fips_validation/Makefile b/examples/fips_validation/Makefile
index 923d0be..2120cd9 100644
--- a/examples/fips_validation/Makefile
+++ b/examples/fips_validation/Makefile
@@ -12,6 +12,7 @@  SRCS-y += fips_validation_tdes.c
 SRCS-y += fips_validation_gcm.c
 SRCS-y += fips_validation_cmac.c
 SRCS-y += fips_validation_ccm.c
+SRCS-y += fips_validation_sha.c
 SRCS-y += fips_dev_self_test.c
 SRCS-y += main.c
 
diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c
index a835cc3..2f8314f 100644
--- a/examples/fips_validation/fips_validation.c
+++ b/examples/fips_validation/fips_validation.c
@@ -136,6 +136,11 @@  fips_test_parse_header(void)
 			ret = parse_test_tdes_init();
 			if (ret < 0)
 				return 0;
+		} else if (strstr(info.vec[i], "SHA-")) {
+			info.algo = FIPS_TEST_ALGO_SHA;
+			ret = parse_test_sha_init();
+			if (ret < 0)
+				return ret;
 		}
 
 		tmp = strstr(info.vec[i], "# Config info for ");
@@ -186,6 +191,18 @@  fips_test_parse_header(void)
 			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;
+		}
+
 		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 ",
diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h
index 3e291bc..b604db9 100644
--- a/examples/fips_validation/fips_validation.h
+++ b/examples/fips_validation/fips_validation.h
@@ -14,6 +14,7 @@ 
 #define MAX_NB_TESTS		10240
 #define MAX_BUF_SIZE		2048
 #define MAX_STRING_SIZE		64
+#define MAX_DIGEST_SIZE		64
 
 #define POSITIVE_TEST		0
 #define NEGATIVE_TEST		-1
@@ -29,6 +30,7 @@  enum fips_test_algorithms {
 		FIPS_TEST_ALGO_AES_CCM,
 		FIPS_TEST_ALGO_HMAC,
 		FIPS_TEST_ALGO_TDES,
+		FIPS_TEST_ALGO_SHA,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -111,6 +113,11 @@  enum fips_ccm_test_types {
 	CCM_DVPT,	 /*  Decryption-Verification Process Test */
 };
 
+enum fips_sha_test_types {
+	SHA_KAT = 0,
+	SHA_MCT
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -135,6 +142,11 @@  struct ccm_interim_data {
 	uint32_t iv_len;
 };
 
+struct sha_interim_data {
+	enum fips_sha_test_types test_type;
+	enum rte_crypto_auth_algorithm algo;
+};
+
 struct fips_test_interim_info {
 	FILE *fp_rd;
 	FILE *fp_wr;
@@ -150,7 +162,7 @@  struct fips_test_interim_info {
 		struct hmac_interim_data hmac_data;
 		struct tdes_interim_data tdes_data;
 		struct ccm_interim_data ccm_data;
-
+		struct sha_interim_data sha_data;
 	} interim_info;
 
 	enum fips_test_op op;
@@ -201,6 +213,9 @@  int
 parse_test_ccm_init(void);
 
 int
+parse_test_sha_init(void);
+
+int
 parser_read_uint8_hex(uint8_t *value, const char *p);
 
 int
diff --git a/examples/fips_validation/fips_validation_sha.c b/examples/fips_validation/fips_validation_sha.c
new file mode 100644
index 0000000..2cca9ce
--- /dev/null
+++ b/examples/fips_validation/fips_validation_sha.c
@@ -0,0 +1,110 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#include "fips_validation.h"
+
+#define ALGO_PREFIX	"[L = "
+#define MSGLEN_STR	"Len = "
+#define MSG_STR		"Msg = "
+#define MD_STR		"MD = "
+#define SEED_STR	"Seed = "
+#define MCT_STR		"Monte"
+
+struct plain_hash_size_conversion {
+	const char *str;
+	enum rte_crypto_auth_algorithm algo;
+} phsc[] = {
+		{"20", RTE_CRYPTO_AUTH_SHA1},
+		{"28", RTE_CRYPTO_AUTH_SHA224},
+		{"32", RTE_CRYPTO_AUTH_SHA256},
+		{"48", RTE_CRYPTO_AUTH_SHA384},
+		{"64", RTE_CRYPTO_AUTH_SHA512},
+};
+
+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(phsc); i++) {
+		if (strstr(text, phsc[i].str)) {
+			info.interim_info.sha_data.algo = phsc[i].algo;
+			parser_read_uint32_val(ALGO_PREFIX,
+				text, &vec.cipher_auth.digest);
+			break;
+		}
+	}
+
+	if (i == RTE_DIM(phsc))
+		return -1;
+
+	return 0;
+}
+
+struct fips_test_callback sha_tests_vectors[] = {
+		{MSGLEN_STR, parser_read_uint32_bit_val, &vec.pt},
+		{MSG_STR, parse_uint8_known_len_hex_str, &vec.pt},
+		{SEED_STR, parse_uint8_hex_str, &vec.cipher_auth.digest},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback sha_tests_interim_vectors[] = {
+		{ALGO_PREFIX, parse_interim_algo, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+static int
+parse_test_sha_writeback(struct fips_val *val) // !
+{
+	struct fips_val val_local;
+
+	fprintf(info.fp_wr, "%s", MD_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_sha_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_sha_init(void)
+{
+	uint32_t i;
+
+	info.interim_info.sha_data.test_type = SHA_KAT;
+	for (i = 0; i < info.nb_vec_lines; i++) {
+		char *line = info.vec[i];
+		if (strstr(line, MCT_STR))
+			info.interim_info.sha_data.test_type = SHA_MCT;
+	}
+
+	info.op = FIPS_TEST_ENC_AUTH_GEN;
+	info.parse_writeback = parse_test_sha_writeback;
+	info.callbacks = sha_tests_vectors;
+	info.interim_callbacks = sha_tests_interim_vectors;
+	info.writeback_callbacks = NULL;
+	info.kat_check = rsp_test_sha_check;
+	return 0;
+}
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index 32d06dd..5e3d5ba 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -887,6 +887,41 @@  prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_sha_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.sha_data.algo;
+	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
+	auth_xform->digest_length = vec.cipher_auth.digest.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 digest 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)
 {
@@ -1218,6 +1253,90 @@  fips_mct_aes_test(void)
 }
 
 static int
+fips_mct_sha_test(void)
+{
+#define SHA_EXTERN_ITER	100
+#define SHA_INTERN_ITER	1000
+#define SHA_MD_BLOCK	3
+	struct fips_val val, md[SHA_MD_BLOCK];
+	char temp[MAX_DIGEST_SIZE*2];
+	int ret;
+	uint32_t i, j;
+
+	val.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0);
+	for (i = 0; i < SHA_MD_BLOCK; i++)
+		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
+
+	rte_free(vec.pt.val);
+	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0);
+
+	fips_test_write_one_case();
+	fprintf(info.fp_wr, "\n");
+
+	for (j = 0; j < SHA_EXTERN_ITER; j++) {
+
+		memcpy(md[0].val, vec.cipher_auth.digest.val,
+			vec.cipher_auth.digest.len);
+		md[0].len = vec.cipher_auth.digest.len;
+		memcpy(md[1].val, vec.cipher_auth.digest.val,
+			vec.cipher_auth.digest.len);
+		md[1].len = vec.cipher_auth.digest.len;
+		memcpy(md[2].val, vec.cipher_auth.digest.val,
+			vec.cipher_auth.digest.len);
+		md[2].len = vec.cipher_auth.digest.len;
+
+		for (i = 0; i < (SHA_INTERN_ITER); i++) {
+
+			memcpy(vec.pt.val, md[0].val,
+				(size_t)md[0].len);
+			memcpy((vec.pt.val + md[0].len), md[1].val,
+				(size_t)md[1].len);
+			memcpy((vec.pt.val + md[0].len + md[1].len),
+				md[2].val,
+				(size_t)md[2].len);
+			vec.pt.len = md[0].len + md[1].len + md[2].len;
+
+			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);
+
+			memcpy(md[0].val, md[1].val, md[1].len);
+			md[0].len = md[1].len;
+			memcpy(md[1].val, md[2].val, md[2].len);
+			md[1].len = md[2].len;
+
+			memcpy(md[2].val, (val.val + vec.pt.len),
+				vec.cipher_auth.digest.len);
+			md[2].len = vec.cipher_auth.digest.len;
+		}
+
+		memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len);
+		vec.cipher_auth.digest.len = md[2].len;
+
+		fprintf(info.fp_wr, "COUNT = %u\n", j);
+
+		writeback_hex_str("", temp, &vec.cipher_auth.digest);
+
+		fprintf(info.fp_wr, "MD = %s\n\n", temp);
+	}
+
+	for (i = 0; i < (SHA_MD_BLOCK); i++)
+		rte_free(md[i].val);
+
+	rte_free(vec.pt.val);
+
+	return 0;
+}
+
+
+static int
 init_test_ops(void)
 {
 	switch (info.algo) {
@@ -1257,6 +1376,14 @@  init_test_ops(void)
 		test_ops.prepare_xform = prepare_ccm_xform;
 		test_ops.test = fips_generic_test;
 		break;
+	case FIPS_TEST_ALGO_SHA:
+		test_ops.prepare_op = prepare_auth_op;
+		test_ops.prepare_xform = prepare_sha_xform;
+		if (info.interim_info.sha_data.test_type == SHA_MCT)
+			test_ops.test = fips_mct_sha_test;
+		else
+			test_ops.test = fips_generic_test;
+		break;
 	default:
 		return -1;
 	}
diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build
index 20f33f4..6dd6308 100644
--- a/examples/fips_validation/meson.build
+++ b/examples/fips_validation/meson.build
@@ -16,6 +16,7 @@  sources = files(
 	'fips_validation_gcm.c',
 	'fips_validation_cmac.c',
 	'fips_validation_ccm.c',
+	'fips_validation_sha.c',
 	'fips_dev_self_test.c',
 	'main.c'
 )