[v2,5/5] crypto/openssl: 3.0 EVP update on DSA routine

Message ID 20220516101039.4537-6-kai.ji@intel.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series crypto/openssl: EVP api update for 3.0 lib |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/github-robot: build success github build: passed
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-x86_64-compile-testing fail Testing issues

Commit Message

Ji, Kai May 16, 2022, 10:10 a.m. UTC
  This patch updates asymmetric DSA routine in crypto openssl pmd
to adopt openssl 3.0 EVP apis. Divide the single combined dsa sign
test to two indiviual dsa sign and dsa verfiy tests.

Signed-off-by: Kai Ji <kai.ji@intel.com>
---
 app/test/test_cryptodev_asym.c               |  91 ++++++++--
 drivers/crypto/openssl/compat.h              |  12 ++
 drivers/crypto/openssl/meson.build           |   1 -
 drivers/crypto/openssl/openssl_pmd_private.h |   3 +
 drivers/crypto/openssl/rte_openssl_pmd.c     | 175 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c |  56 +++++-
 6 files changed, 323 insertions(+), 15 deletions(-)
  

Patch

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index 573af2a537..f8597df246 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -1639,7 +1639,7 @@  test_dh_keygenration(void)
 }
 
 static int
-test_dsa_sign(void)
+test_dsa_sign(struct rte_crypto_dsa_op_param *dsa_op)
 {
 	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
 	struct rte_mempool *op_mpool = ts_params->op_mpool;
@@ -1649,9 +1649,6 @@  test_dsa_sign(void)
 	struct rte_crypto_op *op = NULL, *result_op = NULL;
 	void *sess = NULL;
 	int status = TEST_SUCCESS;
-	uint8_t r[TEST_DH_MOD_LEN];
-	uint8_t s[TEST_DH_MOD_LEN];
-	uint8_t dgst[] = "35d81554afaad2cf18f3a1770d5fedc4ea5be344";
 	int ret;
 
 	ret = rte_cryptodev_asym_session_create(dev_id, &dsa_xform, sess_mpool, &sess);
@@ -1673,6 +1670,7 @@  test_dsa_sign(void)
 		goto error_exit;
 	}
 	asym_op = op->asym;
+	asym_op->dsa = *dsa_op;
 
 	debug_hexdump(stdout, "p: ", dsa_xform.dsa.p.data,
 			dsa_xform.dsa.p.length);
@@ -1686,13 +1684,6 @@  test_dsa_sign(void)
 	/* attach asymmetric crypto session to crypto operations */
 	rte_crypto_op_attach_asym_session(op, sess);
 	asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
-	asym_op->dsa.message.data = dgst;
-	asym_op->dsa.message.length = sizeof(dgst);
-	asym_op->dsa.r.length = sizeof(r);
-	asym_op->dsa.r.data = r;
-	asym_op->dsa.s.length = sizeof(s);
-	asym_op->dsa.s.data = s;
-
 	RTE_LOG(DEBUG, USER1, "Process ASYM operation");
 
 	/* Process crypto operation */
@@ -1716,12 +1707,72 @@  test_dsa_sign(void)
 	}
 
 	asym_op = result_op->asym;
+	dsa_op->r.length = asym_op->dsa.r.length;
+	dsa_op->s.length = asym_op->dsa.s.length;
+
+	debug_hexdump(stdout, "r:",
+			asym_op->dsa.r.data, asym_op->dsa.r.length);
+	debug_hexdump(stdout, "s:",
+			asym_op->dsa.s.data, asym_op->dsa.s.length);
+error_exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	if (op != NULL)
+		rte_crypto_op_free(op);
+	return status;
+}
+
+
+static int
+test_dsa_verify(struct rte_crypto_dsa_op_param *dsa_op)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_asym_op *asym_op = NULL;
+	struct rte_crypto_op *op = NULL, *result_op = NULL;
+	void *sess = NULL;
+	int status = TEST_SUCCESS;
+	int ret;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &dsa_xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				 "line %u FAILED: %s", __LINE__,
+				"Session creation failed");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto error_exit;
+	}
+	/* set up crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (!op) {
+		RTE_LOG(ERR, USER1,
+			"line %u FAILED: %s",
+			__LINE__, "Failed to allocate asymmetric crypto "
+			"operation struct");
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+	asym_op = op->asym;
+	asym_op->dsa = *dsa_op;
+
+	debug_hexdump(stdout, "p: ", dsa_xform.dsa.p.data,
+			dsa_xform.dsa.p.length);
+	debug_hexdump(stdout, "q: ", dsa_xform.dsa.q.data,
+			dsa_xform.dsa.q.length);
+	debug_hexdump(stdout, "g: ", dsa_xform.dsa.g.data,
+			dsa_xform.dsa.g.length);
+
+	/* attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
 
 	debug_hexdump(stdout, "r:",
 			asym_op->dsa.r.data, asym_op->dsa.r.length);
 	debug_hexdump(stdout, "s:",
 			asym_op->dsa.s.data, asym_op->dsa.s.length);
 
+	RTE_LOG(DEBUG, USER1, "Process ASYM verify operation");
 	/* Test PMD DSA sign verification using signer public key */
 	asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
 
@@ -1767,8 +1818,22 @@  static int
 test_dsa(void)
 {
 	int status;
-	status = test_dsa_sign();
-	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+	uint8_t r[TEST_DH_MOD_LEN];
+	uint8_t s[TEST_DH_MOD_LEN];
+	struct rte_crypto_dsa_op_param dsa_op;
+	uint8_t dgst[] = "35d81554afaad2cf18f3a1770d5fedc4ea5be344";
+
+	dsa_op.message.data = dgst;
+	dsa_op.message.length = sizeof(dgst);
+	dsa_op.r.data = r;
+	dsa_op.s.data = s;
+	dsa_op.r.length = sizeof(r);
+	dsa_op.s.length = sizeof(s);
+
+	status = test_dsa_sign(&dsa_op);
+	TEST_ASSERT_EQUAL(status, 0, "DSA sign test failed");
+	status = test_dsa_verify(&dsa_op);
+	TEST_ASSERT_EQUAL(status, 0, "DSA verify test failed");
 	return status;
 }
 
diff --git a/drivers/crypto/openssl/compat.h b/drivers/crypto/openssl/compat.h
index eecb7d3698..9f9167c4f1 100644
--- a/drivers/crypto/openssl/compat.h
+++ b/drivers/crypto/openssl/compat.h
@@ -104,6 +104,18 @@  get_dsa_priv_key(DSA *dsa, BIGNUM **priv_key)
 	*priv_key = dsa->priv_key;
 }
 
+#elif (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+static __rte_always_inline void
+set_dsa_sign(DSA_SIG *sign, BIGNUM *r, BIGNUM *s)
+{
+	DSA_SIG_set0(sign, r, s);
+}
+
+static __rte_always_inline void
+get_dsa_sign(DSA_SIG *sign, const BIGNUM **r, const BIGNUM **s)
+{
+	DSA_SIG_get0(sign, r, s);
+}
 #else
 
 static __rte_always_inline int
diff --git a/drivers/crypto/openssl/meson.build b/drivers/crypto/openssl/meson.build
index 9a3dea2c04..cd962da1d6 100644
--- a/drivers/crypto/openssl/meson.build
+++ b/drivers/crypto/openssl/meson.build
@@ -15,4 +15,3 @@  endif
 deps += 'bus_vdev'
 sources = files('rte_openssl_pmd.c', 'rte_openssl_pmd_ops.c')
 ext_deps += dep
-cflags += ['-DOPENSSL_API_COMPAT=0x10100000L']
diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index 8fdbc75511..b0e5cd109b 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -184,6 +184,9 @@  struct openssl_asym_session {
 		} dh;
 		struct {
 			DSA *dsa;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			OSSL_PARAM_BLD * param_bld;
+#endif
 		} s;
 	} u;
 } __rte_cache_aligned;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 691b000191..45cc6a76b3 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -1761,6 +1761,171 @@  process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 }
 
 /* process dsa sign operation */
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+static int
+process_openssl_dsa_sign_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	struct rte_crypto_dsa_op_param *op = &cop->asym->dsa;
+	EVP_PKEY_CTX *dsa_ctx;
+	EVP_PKEY_CTX *key_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
+	EVP_PKEY *pkey = NULL;
+	OSSL_PARAM_BLD *param_bld = sess->u.s.param_bld;
+	OSSL_PARAM *params = NULL;
+
+	size_t outlen;
+	unsigned char *dsa_sign_data;
+	const unsigned char *dsa_sign_data_p;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+	params = OSSL_PARAM_BLD_to_param(param_bld);
+	if (!params) {
+		OSSL_PARAM_BLD_free(param_bld);
+		return -1;
+	}
+
+	if (key_ctx == NULL
+		|| EVP_PKEY_fromdata_init(key_ctx) <= 0
+		|| EVP_PKEY_fromdata(key_ctx, &pkey,
+						EVP_PKEY_PUBLIC_KEY, params) <= 0)
+		goto err_dsa_sign;
+
+	dsa_ctx = EVP_PKEY_CTX_new(pkey, NULL);
+	if (!dsa_ctx)
+		goto err_dsa_sign;
+
+	if (EVP_PKEY_sign_init(dsa_ctx) <= 0)
+		goto err_dsa_sign;
+
+	if (EVP_PKEY_sign(dsa_ctx, NULL, &outlen, op->message.data,
+						op->message.length) <= 0)
+		goto err_dsa_sign;
+
+	if (outlen <= 0)
+		goto err_dsa_sign;
+
+	dsa_sign_data = OPENSSL_malloc(outlen);
+	if (!dsa_sign_data)
+		goto err_dsa_sign;
+
+	if (EVP_PKEY_sign(dsa_ctx, dsa_sign_data, &outlen, op->message.data,
+						op->message.length) <= 0) {
+		free(dsa_sign_data);
+		goto err_dsa_sign;
+	}
+
+	dsa_sign_data_p = (const unsigned char *)dsa_sign_data;
+	DSA_SIG *sign = d2i_DSA_SIG(NULL, &dsa_sign_data_p, outlen);
+	if (!sign) {
+		OPENSSL_LOG(ERR, "%s:%d\n", __func__, __LINE__);
+		free(dsa_sign_data);
+		goto err_dsa_sign;
+	} else {
+		const BIGNUM *r = NULL, *s = NULL;
+		get_dsa_sign(sign, &r, &s);
+
+		op->r.length = BN_bn2bin(r, op->r.data);
+		op->s.length = BN_bn2bin(s, op->s.data);
+		cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+	}
+
+	DSA_SIG_free(sign);
+	free(dsa_sign_data);
+	return 0;
+
+err_dsa_sign:
+	if (params)
+		OSSL_PARAM_free(params);
+	if (key_ctx)
+		EVP_PKEY_CTX_free(key_ctx);
+	if (dsa_ctx)
+		EVP_PKEY_CTX_free(dsa_ctx);
+	return -1;
+}
+
+/* process dsa verify operation */
+static int
+process_openssl_dsa_verify_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	struct rte_crypto_dsa_op_param *op = &cop->asym->dsa;
+	DSA_SIG *sign = DSA_SIG_new();
+	BIGNUM *r = NULL, *s = NULL;
+	BIGNUM *pub_key = NULL;
+	OSSL_PARAM_BLD *param_bld = sess->u.s.param_bld;
+	OSSL_PARAM *params = NULL;
+	EVP_PKEY *pkey = NULL;
+	EVP_PKEY_CTX *dsa_ctx = NULL;
+	EVP_PKEY_CTX *key_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
+	unsigned char *dsa_sig = NULL;
+	size_t sig_len;
+	int ret = -1;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+	if (!param_bld) {
+		OPENSSL_LOG(ERR, " %s:%d\n", __func__, __LINE__);
+		return -1;
+	}
+
+	r = BN_bin2bn(op->r.data, op->r.length, r);
+	s = BN_bin2bn(op->s.data, op->s.length,	s);
+	pub_key = BN_bin2bn(op->y.data, op->y.length, pub_key);
+	if (!r || !s || !pub_key) {
+		BN_free(r);
+		BN_free(s);
+		BN_free(pub_key);
+		OSSL_PARAM_BLD_free(param_bld);
+		goto err_dsa_verify;
+	}
+
+	set_dsa_sign(sign, r, s);
+	if (!OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, pub_key)) {
+		OSSL_PARAM_BLD_free(param_bld);
+		goto err_dsa_verify;
+	}
+
+	params = OSSL_PARAM_BLD_to_param(param_bld);
+	if (!params) {
+		OSSL_PARAM_BLD_free(param_bld);
+		goto err_dsa_verify;
+	}
+
+	if (key_ctx == NULL
+		|| EVP_PKEY_fromdata_init(key_ctx) <= 0
+		|| EVP_PKEY_fromdata(key_ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+		goto err_dsa_verify;
+
+	dsa_ctx = EVP_PKEY_CTX_new(pkey, NULL);
+	if (!dsa_ctx)
+		goto err_dsa_verify;
+
+	if (!sign)
+		goto err_dsa_verify;
+
+	sig_len = i2d_DSA_SIG(sign, &dsa_sig);
+	if (EVP_PKEY_verify_init(dsa_ctx) <= 0)
+		goto err_dsa_verify;
+
+	ret = EVP_PKEY_verify(dsa_ctx, dsa_sig, sig_len,
+					op->message.data, op->message.length);
+	if (ret == 1) {
+		cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+		ret = 0;
+	}
+
+err_dsa_verify:
+	if (sign)
+		DSA_SIG_free(sign);
+	if (params)
+		OSSL_PARAM_free(params);
+	if (key_ctx)
+		EVP_PKEY_CTX_free(key_ctx);
+	if (dsa_ctx)
+		EVP_PKEY_CTX_free(dsa_ctx);
+
+	return ret;
+}
+#else
 static int
 process_openssl_dsa_sign_op(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -1842,6 +2007,7 @@  process_openssl_dsa_verify_op(struct rte_crypto_op *cop,
 
 	return 0;
 }
+#endif
 
 /* process dh operation */
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
@@ -2501,12 +2667,21 @@  process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 #endif
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_DSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		if (op->asym->dsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+			retval = process_openssl_dsa_sign_op_evp(op, sess);
+		else if (op->asym->dsa.op_type ==
+				RTE_CRYPTO_ASYM_OP_VERIFY)
+			retval =
+				process_openssl_dsa_verify_op_evp(op, sess);
+#else
 		if (op->asym->dsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN)
 			retval = process_openssl_dsa_sign_op(op, sess);
 		else if (op->asym->dsa.op_type ==
 				RTE_CRYPTO_ASYM_OP_VERIFY)
 			retval =
 				process_openssl_dsa_verify_op(op, sess);
+#endif
 		else
 			op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
 		break;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index f77e9a9842..a465574d48 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -1183,6 +1183,56 @@  static int openssl_set_asym_session_parameters(
 	}
 	case RTE_CRYPTO_ASYM_XFORM_DSA:
 	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		BIGNUM *p = NULL, *g = NULL;
+		BIGNUM *q = NULL, *priv_key = NULL;
+		BIGNUM *pub_key = BN_new();
+		BN_zero(pub_key);
+		OSSL_PARAM_BLD *param_bld = NULL;
+
+		p = BN_bin2bn((const unsigned char *)
+				xform->dsa.p.data,
+				xform->dsa.p.length,
+				p);
+
+		g = BN_bin2bn((const unsigned char *)
+				xform->dsa.g.data,
+				xform->dsa.g.length,
+				g);
+
+		q = BN_bin2bn((const unsigned char *)
+				xform->dsa.q.data,
+				xform->dsa.q.length,
+				q);
+		if (!p || !q || !g)
+			goto err_dsa;
+
+		priv_key = BN_bin2bn((const unsigned char *)
+				xform->dsa.x.data,
+				xform->dsa.x.length,
+				priv_key);
+		if (priv_key == NULL)
+			goto err_dsa;
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate resources\n");
+			goto err_dsa;
+		}
+
+		if (!OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p)
+			|| !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g)
+			|| !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q)
+			|| !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, priv_key)) {
+			OSSL_PARAM_BLD_free(param_bld);
+			OPENSSL_LOG(ERR, "failed to allocate resources\n");
+			goto err_dsa;
+		}
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA;
+		asym_session->u.s.param_bld = param_bld;
+
+		break;
+#else
 		BIGNUM *p = NULL, *g = NULL;
 		BIGNUM *q = NULL, *priv_key = NULL;
 		BIGNUM *pub_key = BN_new();
@@ -1242,7 +1292,7 @@  static int openssl_set_asym_session_parameters(
 		asym_session->u.s.dsa = dsa;
 		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA;
 		break;
-
+#endif
 err_dsa:
 		BN_free(p);
 		BN_free(q);
@@ -1335,8 +1385,12 @@  static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #endif
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_DSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		sess->u.s.param_bld = NULL;
+#else
 		if (sess->u.s.dsa)
 			DSA_free(sess->u.s.dsa);
+#endif
 		break;
 	default:
 		break;