DPDK patches and discussions
 help / color / mirror / Atom feed
* [RFC] examples/fips_validation: add fips 140-3 acvp aes-cbc test
@ 2022-05-20 16:05 Brian Dooley
  2022-05-25 10:04 ` [EXT] " Gowrishankar Muthukrishnan
  0 siblings, 1 reply; 2+ messages in thread
From: Brian Dooley @ 2022-05-20 16:05 UTC (permalink / raw)
  To: dev; +Cc: gakhil, gmuthukrishn, Brian Dooley, Fan Zhang

This RFC patch showcases an alternative approach to enable
FIPS 140-3 support in the DPDK fips_validation sample application.

The approach presented here takes advantage of an existing open source
library, libacvp,(https://github.com/cisco/libacvp) to generate the
parsed test cases instead of creating and maintaining a DPDK FIPS
test file parser. In addition call back functions are added to the
dpdk-fips_validation application to process the parsed test vectors
and write back the results.

This initial RFC patch contains the code to parse the FIPS 140-3
test files with libacvp library, and the AES-CBC test runner
callback function implementation with most test types covered
apart from MCT test.

Although a different approach has been proposed
(http://patches.dpdk.org/project/dpdk/list/?series=22738),
it has the disadvantage of having to maintain the parsing code.

For the sake of this RFC here is some information on how to
modify and run a test case.

The libacvp library can be installed by following the Building
instructions in the README of the libacvp repo as linked above.

An example test vector which we can call as our input.req:
https://github.com/cisco/libacvp/blob/main/test/json/aes/aes.json

The header acvVersion metadata at the start needs to been updated
to the following:

    {
      "acvVersion": "1.0",
      "jwt": "NA",
      "url": "NA",
      "isSample": false,
      "vectorSetUrls": ["NA"]
    }

With this RFC patch applied you can then run the dpdk-fips_validation
as follows:

    ./dpdk-fips_validation --vdev=crypto_aesni_mb -- \
        --req-file input.req --rsp-file output.rsp --acvp

Please note the MCT tests in the input.req file will generate an
incorrect result set as the IV update part has yet to be implemented.
This will be addressed in next revision.

Signed-off-by: Brian Dooley <brian.dooley@intel.com>
---
 examples/fips_validation/fips_test_acvp.c  | 183 +++++++++++++++++++++
 examples/fips_validation/fips_validation.h |  34 ++++
 examples/fips_validation/main.c            |  59 ++++---
 examples/fips_validation/meson.build       |   9 +
 4 files changed, 260 insertions(+), 25 deletions(-)
 create mode 100644 examples/fips_validation/fips_test_acvp.c

diff --git a/examples/fips_validation/fips_test_acvp.c b/examples/fips_validation/fips_test_acvp.c
new file mode 100644
index 0000000000..55f6b35a7d
--- /dev/null
+++ b/examples/fips_validation/fips_test_acvp.c
@@ -0,0 +1,183 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <acvp/acvp.h>
+#include <intel-ipsec-mb.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <rte_cryptodev.h>
+#include <rte_malloc.h>
+
+#include "fips_validation.h"
+
+#define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
+
+static ACVP_RESULT logger(char *msg)
+{
+	printf("%s", msg);
+	return ACVP_SUCCESS;
+}
+
+static int aes_cbc_handler(ACVP_TEST_CASE *test_case)
+{
+	ACVP_SYM_CIPHER_TC *tc;
+	struct rte_crypto_sym_xform xform = { 0 };
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_cipher_xform *cipher_xform = &xform.cipher;
+	struct rte_crypto_sym_op *sym = env.op->sym;
+	struct fips_val val = {NULL, 0};
+	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
+	uint16_t n_deqd;
+	int ret;
+
+	memset(&xform, 0, sizeof(xform));
+
+	tc = test_case->tc.symmetric;
+
+	xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
+	cipher_xform->op = (tc->direction == ACVP_SYM_CIPH_DIR_ENCRYPT) ?
+		RTE_CRYPTO_AEAD_OP_ENCRYPT :
+		RTE_CRYPTO_AEAD_OP_DECRYPT;
+	cipher_xform->key.data = tc->key;
+	/* Check support for 128 bit key*/
+	if (tc->key_len % 8 == 0)
+		cipher_xform->key.length = 16;
+	else
+		cipher_xform->key.length = tc->key_len;
+
+	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC) {
+		cipher_xform->iv.length = tc->iv_len;
+		cipher_xform->iv.offset = IV_OFF;
+	} else {
+		cipher_xform->iv.length = 0;
+		cipher_xform->iv.offset = 0;
+	}
+	cap_idx.algo.cipher = cipher_xform->algo;
+	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;
+	}
+
+	env.sess = rte_cryptodev_sym_session_create(env.sess_mpool);
+	if (!env.sess)
+		return -ENOMEM;
+
+	ret = rte_cryptodev_sym_session_init(env.dev_id, env.sess, &xform,
+	env.sess_priv_mpool);
+	if (ret < 0) {
+		RTE_LOG(ERR, PMD, "Error %i: Init session\n", ret);
+		return ret;
+	}
+
+	if (env.op)
+		rte_crypto_op_free(env.op);
+
+	env.op = rte_crypto_op_alloc(env.op_pool,
+			RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	if (!env.op)
+		ret = -ENOMEM;
+
+	memcpy(iv, tc->iv, tc->iv_len);
+
+	if (tc->direction == ACVP_SYM_CIPH_DIR_ENCRYPT) {
+		val.val = tc->pt;
+		val.len = tc->pt_len;
+	} else { /* Decrypt */
+		val.val = tc->ct;
+		val.len = tc->ct_len;
+	}
+
+	ret = prepare_data_mbufs(&val);
+	if (ret < 0)
+		return ret;
+
+	if (tc->direction == ACVP_SYM_CIPH_DIR_ENCRYPT) {
+		sym->cipher.data.length = tc->pt_len;
+	} else { /* Decrypt */
+		sym->cipher.data.length = tc->ct_len;
+	}
+
+	rte_crypto_op_attach_sym_session(env.op, env.sess);
+
+	sym->m_src = env.mbuf;
+	sym->cipher.data.offset = 0;
+
+	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
+		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
+		return ret = -1;
+	}
+
+	do {
+		struct rte_crypto_op *deqd_op[1];
+
+		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, deqd_op,
+				1);
+	} while (n_deqd == 0);
+
+	rte_cryptodev_sym_session_clear(env.dev_id, env.sess);
+	rte_cryptodev_sym_session_free(env.sess);
+
+	val.val = NULL;
+
+	ret = get_writeback_data(&val);
+	if (ret < 0)
+		return ret;
+
+	if (tc->direction == ACVP_SYM_CIPH_DIR_ENCRYPT) {
+		memcpy(tc->ct, val.val, val.len);
+		tc->ct_len = val.len;
+	} else { /* Decrypt */
+		memcpy(tc->pt, val.val, val.len);
+		tc->pt_len = val.len;
+	}
+
+	return ret;
+}
+
+int
+fips_test_acvp_init(void **acvp_ctx)
+{
+	*acvp_ctx = NULL;
+	ACVP_RESULT acvp_ret = ACVP_SUCCESS;
+
+	/* Create test session and enable CBC tests */
+	acvp_ret = acvp_create_test_session((ACVP_CTX **)acvp_ctx, logger,
+					ACVP_LOG_LVL_INFO);
+	if (acvp_ret != ACVP_SUCCESS)
+		return acvp_ret;
+
+	if (acvp_cap_sym_cipher_enable((ACVP_CTX *)*acvp_ctx, ACVP_AES_CBC,
+				&aes_cbc_handler) != ACVP_SUCCESS)
+		return acvp_ret;
+
+	return ACVP_SUCCESS;
+}
+
+void
+fips_test_acvp(void *acvp_ctx, const char *req_file_path,
+			const char *rsp_file_path)
+{
+	/* Parse request file, run crypto tests and write out response file */
+	acvp_run_vectors_from_file(acvp_ctx, req_file_path, rsp_file_path);
+}
diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h
index aaadf01ba8..de831fd0aa 100644
--- a/examples/fips_validation/fips_validation.h
+++ b/examples/fips_validation/fips_validation.h
@@ -193,8 +193,31 @@ struct fips_test_interim_info {
 	post_prcess_t kat_check;
 };
 
+struct cryptodev_fips_validate_env {
+	const char *req_path;
+	const char *rsp_path;
+	uint32_t is_path_folder;
+	uint8_t dev_id;
+	uint8_t dev_support_sgl;
+	uint16_t mbuf_data_room;
+	struct rte_mempool *mpool;
+	struct rte_mempool *sess_mpool;
+	struct rte_mempool *sess_priv_mpool;
+	struct rte_mempool *op_pool;
+	struct rte_mbuf *mbuf;
+	uint8_t *digest;
+	uint16_t digest_len;
+	struct rte_crypto_op *op;
+	struct rte_cryptodev_sym_session *sess;
+	uint16_t self_test;
+	struct fips_dev_broken_test_config *broken_test_config;
+	uint8_t is_acvp;
+	void *acvp_ctx;
+};
+
 extern struct fips_test_vector vec;
 extern struct fips_test_interim_info info;
+extern struct cryptodev_fips_validate_env env;
 
 int
 fips_test_init(const char *req_file_path, const char *rsp_file_path,
@@ -289,4 +312,15 @@ int prepare_gcm_xform(struct rte_crypto_sym_xform *xform);
 
 int prepare_gmac_xform(struct rte_crypto_sym_xform *xform);
 
+int prepare_data_mbufs(struct fips_val *val);
+
+int get_writeback_data(struct fips_val *val);
+
+__rte_weak void
+fips_test_acvp(void *acvp_ctx, const char *req_file_path,
+				const char *rsp_file_path);
+
+__rte_weak int
+fips_test_acvp_init(void **acvp_ctx);
+
 #endif
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index e06ae37567..54b45dcc1f 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -12,6 +12,8 @@
 #include <rte_mbuf.h>
 #include <rte_string_fns.h>
 
+#include <acvp/acvp.h>
+
 #include "fips_validation.h"
 #include "fips_dev_self_test.h"
 
@@ -34,30 +36,13 @@ enum {
 	OPT_CRYPTODEV_BK_ID_NUM,
 #define OPT_CRYPTODEV_BK_DIR_KEY    "broken-test-dir"
 	OPT_CRYPTODEV_BK_DIR_KEY_NUM,
+#define OPT_CRYPTODEV_ACVP			"acvp"
+	OPT_CRYPTODEV_ACVP_NUM,
 };
 
 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;
-	uint8_t dev_id;
-	uint8_t dev_support_sgl;
-	uint16_t mbuf_data_room;
-	struct rte_mempool *mpool;
-	struct rte_mempool *sess_mpool;
-	struct rte_mempool *sess_priv_mpool;
-	struct rte_mempool *op_pool;
-	struct rte_mbuf *mbuf;
-	uint8_t *digest;
-	uint16_t digest_len;
-	struct rte_crypto_op *op;
-	struct rte_cryptodev_sym_session *sess;
-	uint16_t self_test;
-	struct fips_dev_broken_test_config *broken_test_config;
-} env;
+struct cryptodev_fips_validate_env env;
 
 static int
 cryptodev_fips_validate_app_int(void)
@@ -79,6 +64,12 @@ cryptodev_fips_validate_app_int(void)
 		}
 	}
 
+	if (env.is_acvp) {
+		ret = fips_test_acvp_init(&env.acvp_ctx);
+		if (ret < 0)
+			return ret;
+	}
+
 	ret = rte_cryptodev_configure(env.dev_id, &conf);
 	if (ret < 0)
 		return ret;
@@ -161,6 +152,7 @@ cryptodev_fips_validate_app_uninit(void)
 	rte_mempool_free(env.sess_mpool);
 	rte_mempool_free(env.sess_priv_mpool);
 	rte_mempool_free(env.op_pool);
+	acvp_free_test_session(env.acvp_ctx);
 }
 
 static int
@@ -218,11 +210,13 @@ cryptodev_fips_validate_usage(const char *prgname)
 		"  --%s: CRYPTODEV-ID-NAME\n"
 		"  --%s: self test indicator\n"
 		"  --%s: self broken test ID\n"
-		"  --%s: self broken test direction\n",
+		"  --%s: self broken test direction\n"
+		"  --%s: acvp test indicator\n",
 		prgname, OPT_REQ_FILE_PATH, OPT_RSP_FILE_PATH,
 		OPT_FOLDER, OPT_MBUF_DATAROOM, def_mbuf_seg_size,
 		OPT_CRYPTODEV, OPT_CRYPTODEV_ID, OPT_CRYPTODEV_ST,
-		OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY);
+		OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY,
+		OPT_CRYPTODEV_ACVP);
 }
 
 static int
@@ -251,6 +245,8 @@ cryptodev_fips_validate_parse_args(int argc, char **argv)
 				NULL, OPT_CRYPTODEV_BK_ID_NUM},
 		{OPT_CRYPTODEV_BK_DIR_KEY, required_argument,
 				NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM},
+		{OPT_CRYPTODEV_ACVP, no_argument,
+				NULL, OPT_CRYPTODEV_ACVP_NUM},
 		{NULL, 0, 0, 0}
 	};
 
@@ -363,6 +359,10 @@ cryptodev_fips_validate_parse_args(int argc, char **argv)
 			}
 			break;
 
+		case OPT_CRYPTODEV_ACVP_NUM:
+			env.is_acvp = 1;
+			break;
+
 		default:
 			cryptodev_fips_validate_usage(prgname);
 			return -EINVAL;
@@ -417,6 +417,11 @@ main(int argc, char *argv[])
 	if (!env.is_path_folder) {
 		printf("Processing file %s... ", env.req_path);
 
+		if (env.is_acvp) {
+			fips_test_acvp(env.acvp_ctx, env.req_path, env.rsp_path);
+			printf("Done\n");
+			goto exit;
+		}
 		ret = fips_test_init(env.req_path, env.rsp_path,
 			rte_cryptodev_name_get(env.dev_id));
 		if (ret < 0) {
@@ -425,7 +430,6 @@ main(int argc, char *argv[])
 			goto exit;
 		}
 
-
 		ret = fips_test_one_file();
 		if (ret < 0) {
 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
@@ -473,6 +477,11 @@ main(int argc, char *argv[])
 
 			printf("Processing file %s... ", req_path);
 
+			if (env.is_acvp) {
+				fips_test_acvp(env.acvp_ctx, env.req_path, env.rsp_path);
+				continue;
+			}
+
 			ret = fips_test_init(req_path, rsp_path,
 			rte_cryptodev_name_get(env.dev_id));
 			if (ret < 0) {
@@ -511,7 +520,7 @@ main(int argc, char *argv[])
 
 struct fips_test_ops test_ops;
 
-static int
+int
 prepare_data_mbufs(struct fips_val *val)
 {
 	struct rte_mbuf *m, *head = 0;
@@ -1115,7 +1124,7 @@ prepare_xts_xform(struct rte_crypto_sym_xform *xform)
 	return 0;
 }
 
-static int
+int
 get_writeback_data(struct fips_val *val)
 {
 	struct rte_mbuf *m = env.mbuf;
diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build
index 7eef456318..03302fcc5a 100644
--- a/examples/fips_validation/meson.build
+++ b/examples/fips_validation/meson.build
@@ -19,5 +19,14 @@ sources = files(
         'fips_validation_sha.c',
         'fips_validation_xts.c',
         'fips_dev_self_test.c',
+        'fips_test_acvp.c',
         'main.c',
 )
+
+libacvp = cc.find_library('acvp', required: true)
+
+if not libacvp.found()
+    libacvp = false
+endif
+
+ext_deps += libacvp
-- 
2.25.1


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

* RE: [EXT] [RFC] examples/fips_validation: add fips 140-3 acvp aes-cbc test
  2022-05-20 16:05 [RFC] examples/fips_validation: add fips 140-3 acvp aes-cbc test Brian Dooley
@ 2022-05-25 10:04 ` Gowrishankar Muthukrishnan
  0 siblings, 0 replies; 2+ messages in thread
From: Gowrishankar Muthukrishnan @ 2022-05-25 10:04 UTC (permalink / raw)
  To: Brian Dooley, dev
  Cc: Akhil Goyal, Fan Zhang, Anoob Joseph, Jerin Jacob Kollanukkaran,
	Thomas Monjalon, Archana Muniganti

Hi Brian,
Thanks for the RFC and PFA inline my comments.

> -----Original Message-----
> From: Brian Dooley <brian.dooley@intel.com>
> Sent: Friday, May 20, 2022 9:36 PM
> To: dev@dpdk.org
> Cc: Akhil Goyal <gakhil@marvell.com>; Gowrishankar Muthukrishnan
> <gmuthukrishn@marvell.com>; Brian Dooley <brian.dooley@intel.com>; Fan
> Zhang <roy.fan.zhang@intel.com>
> Subject: [EXT] [RFC] examples/fips_validation: add fips 140-3 acvp aes-cbc
> test
> 
> External Email
> 
> ----------------------------------------------------------------------
> This RFC patch showcases an alternative approach to enable FIPS 140-3
> support in the DPDK fips_validation sample application.
> 
> The approach presented here takes advantage of an existing open source
> library, libacvp,(https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__github.com_cisco_libacvp&d=DwIDAg&c=nKjWec2b6R0mOyPaz7xtfQ&r
> =EAtr-g7yUFhtOio8r2Rtm13Aqe4WVp_S_gHpcu6KFVo&m=Or6tpEsPX87-
> j0caOkxdpMd9nEJRSlAb4JusQjipu1g09R4MIPOTbu_XGke63me_&s=ZnDDms
> 0KubRYj4TCliLrDQ9IO5S27LVUJunrx3vbpUA&e= ) to generate the parsed test
> cases instead of creating and maintaining a DPDK FIPS test file parser. In
> addition call back functions are added to the dpdk-fips_validation application
> to process the parsed test vectors and write back the results.
> 

libacvp carries its source code under Apache License v2. Would there be
any license conflict to consume it as parser for fips_validation in DPDK ?
https://github.com/cisco/libacvp/blob/main/LICENSE

> This initial RFC patch contains the code to parse the FIPS 140-3 test files with
> libacvp library, and the AES-CBC test runner callback function implementation
> with most test types covered apart from MCT test.
> 
> Although a different approach has been proposed
> (https://urldefense.proofpoint.com/v2/url?u=http-
> 3A__patches.dpdk.org_project_dpdk_list_-3Fseries-
> 3D22738&d=DwIDAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=EAtr-
> g7yUFhtOio8r2Rtm13Aqe4WVp_S_gHpcu6KFVo&m=Or6tpEsPX87-
> j0caOkxdpMd9nEJRSlAb4JusQjipu1g09R4MIPOTbu_XGke63me_&s=OlrgMzf
> QefOQwOunfPxgtFcKOid-8-mw1yQVv0_Ncv8&e= ), it has the disadvantage
> of having to maintain the parsing code.
> 

We already have stabilized code and good number of parsers from Brandon series 
(plus the one I am also topping up - AES_CBC, SHA etc), we can always extend the parsers 
availability as and when needed. Extension also would not be too difficult IMHO as its 
base functions are ready for all sort of extensions (where the real work could only be to
manipulate with key words for test vectors).

I am also thinking that, NIST will only make changes in a pace that its eco system can also
follow. So, we can certainly catch up in our releases.

> For the sake of this RFC here is some information on how to modify and run a
> test case.
> 
> The libacvp library can be installed by following the Building instructions in the
> README of the libacvp repo as linked above.
> 

Also libacvp is not available in any of OS distributions (https://pkgs.org/search/?q=acvp).
Though README is absolutely helping, proper documentation in the context of
consuming it for fips_validation can help better. For eg,

      (a) What configure options required (at bare minimum) to support fips app.
      (b) Versions of libcurl and openssl that is supported by libacvp compilation (for fips app.)
      (c) cross compilation notes
      (d) source code url to download from etc.

Cross compiling with dependent libs is difficult at times when the integrity is not tested 
properly. Hence, DPDK fips_validation would require special instructions apart from 
README IMHO.

> An example test vector which we can call as our input.req:
> https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__github.com_cisco_libacvp_blob_main_test_json_aes_aes.json&d=DwI
> DAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=EAtr-
> g7yUFhtOio8r2Rtm13Aqe4WVp_S_gHpcu6KFVo&m=Or6tpEsPX87-
> j0caOkxdpMd9nEJRSlAb4JusQjipu1g09R4MIPOTbu_XGke63me_&s=JR1nXo6
> 9fg3FQ64fRyNYYYTs1-YU8ziuU5epo0VdRcg&e=
> 
> The header acvVersion metadata at the start needs to been updated to the
> following:
> 
>     {
>       "acvVersion": "1.0",
>       "jwt": "NA",
>       "url": "NA",
>       "isSample": false,
>       "vectorSetUrls": ["NA"]
>     }

Can we manipulate these fields within the app itself instead ?
For eg, url should be NA anyway for the scope of using this library here.

> 
> With this RFC patch applied you can then run the dpdk-fips_validation as
> follows:
> 
>     ./dpdk-fips_validation --vdev=crypto_aesni_mb -- \
>         --req-file input.req --rsp-file output.rsp --acvp
> 
> Please note the MCT tests in the input.req file will generate an incorrect
> result set as the IV update part has yet to be implemented.
> This will be addressed in next revision.
> 

Please give a check on entire results including AFT as well. I did json diff and learnt 
atleast 1500 out of 2156 tests failed for AES_CBC while using this patch
(i.e post tcId 285, many of tests failed including AFT). If it is not the case for you,
I can cross check once again if anything else going wrong, as none of tests fail
in same env and with same req file, while using native parser from Brandon.

> Signed-off-by: Brian Dooley <brian.dooley@intel.com>
> ---
>  examples/fips_validation/fips_test_acvp.c  | 183
> +++++++++++++++++++++  examples/fips_validation/fips_validation.h |  34
> ++++
>  examples/fips_validation/main.c            |  59 ++++---
>  examples/fips_validation/meson.build       |   9 +
>  4 files changed, 260 insertions(+), 25 deletions(-)  create mode 100644
> examples/fips_validation/fips_test_acvp.c
> 
> diff --git a/examples/fips_validation/fips_test_acvp.c
> b/examples/fips_validation/fips_test_acvp.c
> new file mode 100644
> index 0000000000..55f6b35a7d
> --- /dev/null
> +++ b/examples/fips_validation/fips_test_acvp.c
> @@ -0,0 +1,183 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2022 Intel Corporation
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <acvp/acvp.h>
> +#include <intel-ipsec-mb.h>

I find it not required for this patch, do we need this header for any other purpose ?

> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <ctype.h>
> +
> +#include <rte_cryptodev.h>
> +#include <rte_malloc.h>
> +
> +#include "fips_validation.h"
> +
> +#define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct
> +rte_crypto_sym_op))
> +
> +static ACVP_RESULT logger(char *msg)
> +{
> +	printf("%s", msg);
> +	return ACVP_SUCCESS;
> +}
> +
> +static int aes_cbc_handler(ACVP_TEST_CASE *test_case) {
> +	ACVP_SYM_CIPHER_TC *tc;
> +	struct rte_crypto_sym_xform xform = { 0 };
> +	const struct rte_cryptodev_symmetric_capability *cap;
> +	struct rte_cryptodev_sym_capability_idx cap_idx;
> +	struct rte_crypto_cipher_xform *cipher_xform = &xform.cipher;
> +	struct rte_crypto_sym_op *sym = env.op->sym;
> +	struct fips_val val = {NULL, 0};
> +	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
> +	uint16_t n_deqd;
> +	int ret;
> +
> +	memset(&xform, 0, sizeof(xform));
> +
> +	tc = test_case->tc.symmetric;
> +
> +	xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
> +
> +	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
> +	cipher_xform->op = (tc->direction ==
> ACVP_SYM_CIPH_DIR_ENCRYPT) ?
> +		RTE_CRYPTO_AEAD_OP_ENCRYPT :
> +		RTE_CRYPTO_AEAD_OP_DECRYPT;
> +	cipher_xform->key.data = tc->key;
> +	/* Check support for 128 bit key*/
> +	if (tc->key_len % 8 == 0)
> +		cipher_xform->key.length = 16;
> +	else
> +		cipher_xform->key.length = tc->key_len;
> +
> +	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC) {
> +		cipher_xform->iv.length = tc->iv_len;
> +		cipher_xform->iv.offset = IV_OFF;
> +	} else {
> +		cipher_xform->iv.length = 0;
> +		cipher_xform->iv.offset = 0;
> +	}
> +	cap_idx.algo.cipher = cipher_xform->algo;
> +	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
> +
> +	cap = 	(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;
> +	}
> +
> +	env.sess = rte_cryptodev_sym_session_create(env.sess_mpool);
> +	if (!env.sess)
> +		return -ENOMEM;
> +
> +	ret = rte_cryptodev_sym_session_init(env.dev_id, env.sess,
> &xform,
> +	env.sess_priv_mpool);
> +	if (ret < 0) {
> +		RTE_LOG(ERR, PMD, "Error %i: Init session\n", ret);
> +		return ret;
> +	}
> +
> +	if (env.op)
> +		rte_crypto_op_free(env.op);
> +
> +	env.op = rte_crypto_op_alloc(env.op_pool,
> +			RTE_CRYPTO_OP_TYPE_SYMMETRIC);
> +	if (!env.op)
> +		ret = -ENOMEM;
> +
> +	memcpy(iv, tc->iv, tc->iv_len);
> +
> +	if (tc->direction == ACVP_SYM_CIPH_DIR_ENCRYPT) {
> +		val.val = tc->pt;
> +		val.len = tc->pt_len;
> +	} else { /* Decrypt */
> +		val.val = tc->ct;
> +		val.len = tc->ct_len;
> +	}
> +
> +	ret = prepare_data_mbufs(&val);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (tc->direction == ACVP_SYM_CIPH_DIR_ENCRYPT) {
> +		sym->cipher.data.length = tc->pt_len;
> +	} else { /* Decrypt */
> +		sym->cipher.data.length = tc->ct_len;
> +	}
> +
> +	rte_crypto_op_attach_sym_session(env.op, env.sess);
> +
> +	sym->m_src = env.mbuf;
> +	sym->cipher.data.offset = 0;
> +
> +	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
> +		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
> +		return ret = -1;
> +	}
> +
> +	do {
> +		struct rte_crypto_op *deqd_op[1];
> +
> +		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0,
> deqd_op,
> +				1);
> +	} while (n_deqd == 0);
> +
> +	rte_cryptodev_sym_session_clear(env.dev_id, env.sess);
> +	rte_cryptodev_sym_session_free(env.sess);
> +
> +	val.val = NULL;
> +
> +	ret = get_writeback_data(&val);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (tc->direction == ACVP_SYM_CIPH_DIR_ENCRYPT) {
> +		memcpy(tc->ct, val.val, val.len);
> +		tc->ct_len = val.len;
> +	} else { /* Decrypt */
> +		memcpy(tc->pt, val.val, val.len);
> +		tc->pt_len = val.len;
> +	}
> +
> +	return ret;
> +}
> +

Can we have common aes_cbc handler common for above prepare xform, session creation and run test,
writeback_data etc so that, these can be shared between native and library parsers.

Finally, If an end user of fips_validation app is reluctant to proceed with libacvp for any reason,
we will not have any parser to help him for FIPS 140-3, instead we can keep Brandon approach as a 
native fallback option and this patch can add support using external libacvp library (as an option).

Thanks,
Gowrishankar

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

end of thread, other threads:[~2022-05-25 10:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-20 16:05 [RFC] examples/fips_validation: add fips 140-3 acvp aes-cbc test Brian Dooley
2022-05-25 10:04 ` [EXT] " Gowrishankar Muthukrishnan

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).