All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3]crypto/openssl: support asymmetric crypto
@ 2018-07-12 14:08 Shally Verma
  2018-07-12 14:08 ` [PATCH v4 1/3] crypto/openssl: add rsa and mod asym op Shally Verma
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Shally Verma @ 2018-07-12 14:08 UTC (permalink / raw)
  To: pablo.de.lara.guarch; +Cc: dev, pathreya, nmurthy

This patch series add asymmetric crypto support in openssl pmd
changes in v4:
- add openssl 1.1.0h support in openssl PMD for asym operations.
- A compat.h added for PMD compatibility with both 1.0.2 and 1.1.0
- update openssl document with asymmetric feature support 

For further history refer https://patches.dpdk.org/patch/40079/

Sunila Sahu (3):
  crypto/openssl: add rsa and mod asym op
  crypto/openssl: add dh and dsa asym op
  doc: add asym feature list

 doc/guides/cryptodevs/features/openssl.ini       |  11 +
 doc/guides/cryptodevs/openssl.rst                |   1 +
 drivers/crypto/openssl/compat.h                  | 108 +++++
 drivers/crypto/openssl/rte_openssl_pmd.c         | 466 +++++++++++++++++++-
 drivers/crypto/openssl/rte_openssl_pmd_ops.c     | 528 ++++++++++++++++++++++-
 drivers/crypto/openssl/rte_openssl_pmd_private.h |  28 ++
 6 files changed, 1130 insertions(+), 12 deletions(-)
 create mode 100644 drivers/crypto/openssl/compat.h

-- 
2.9.5

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

* [PATCH v4 1/3] crypto/openssl: add rsa and mod asym op
  2018-07-12 14:08 [PATCH v4 0/3]crypto/openssl: support asymmetric crypto Shally Verma
@ 2018-07-12 14:08 ` Shally Verma
  2018-07-23 12:32   ` De Lara Guarch, Pablo
  2018-07-12 14:08 ` [PATCH v4 2/3] crypto/openssl: add dh and dsa " Shally Verma
  2018-07-12 14:08 ` [PATCH v4 3/3] doc: add asym feature list Shally Verma
  2 siblings, 1 reply; 5+ messages in thread
From: Shally Verma @ 2018-07-12 14:08 UTC (permalink / raw)
  To: pablo.de.lara.guarch; +Cc: dev, pathreya, nmurthy, Sunila Sahu, Ashish Gupta

From: Sunila Sahu <sunila.sahu@caviumnetworks.com>

- Add compat.h to make pmd compatible to openssl-1.1.0 and
  backward version
- Add rsa sign/verify/encrypt/decrypt and modular operation
  support

Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
---
 drivers/crypto/openssl/compat.h                  |  40 +++
 drivers/crypto/openssl/rte_openssl_pmd.c         | 229 ++++++++++++++-
 drivers/crypto/openssl/rte_openssl_pmd_ops.c     | 336 ++++++++++++++++++++++-
 drivers/crypto/openssl/rte_openssl_pmd_private.h |  19 ++
 4 files changed, 612 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/openssl/compat.h b/drivers/crypto/openssl/compat.h
new file mode 100644
index 0000000..8ece808
--- /dev/null
+++ b/drivers/crypto/openssl/compat.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Cavium Networks
+ */
+
+#ifndef __RTA_COMPAT_H__
+#define __RTA_COMPAT_H__
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+
+#define set_rsa_params(rsa, p, q, ret) \
+	do {rsa->p = p; rsa->q = q; ret = 0; } while (0)
+
+#define set_rsa_crt_params(rsa, dmp1, dmq1, iqmp, ret) \
+	do { \
+		rsa->dmp1 = dmp1; \
+		rsa->dmq1 = dmq1; \
+		rsa->iqmp = iqmp; \
+		ret = 0; \
+	} while (0)
+
+#define set_rsa_keys(rsa, n, e, d, ret) \
+	do { \
+		rsa->n = n; rsa->e = e; rsa->d = d; ret = 0; \
+	} while (0)
+
+#else
+
+#define set_rsa_params(rsa, p, q, ret) \
+	(ret = !RSA_set0_factors(rsa, p, q))
+
+#define set_rsa_crt_params(rsa, dmp1, dmq1, iqmp, ret) \
+	(ret = !RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp))
+
+/* n, e must be non-null, d can be NULL */
+#define set_rsa_keys(rsa, n, e, d, ret) \
+	(ret = !RSA_set0_key(rsa, n, e, d))
+
+#endif /* version < 10100000 */
+
+#endif /* __RTA_COMPAT_H__ */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 5228b92..e21a6a1 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -14,6 +14,7 @@
 #include <openssl/evp.h>
 
 #include "rte_openssl_pmd_private.h"
+#include "compat.h"
 
 #define DES_BLOCK_SIZE 8
 
@@ -727,19 +728,36 @@ openssl_reset_session(struct openssl_session *sess)
 }
 
 /** Provide session for operation */
-static struct openssl_session *
+static void *
 get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
 {
 	struct openssl_session *sess = NULL;
+	struct openssl_asym_session *asym_sess = NULL;
 
 	if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
-		/* get existing session */
-		if (likely(op->sym->session != NULL))
-			sess = (struct openssl_session *)
-					get_sym_session_private_data(
-					op->sym->session,
-					cryptodev_driver_id);
+		if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
+			/* get existing session */
+			if (likely(op->sym->session != NULL))
+				sess = (struct openssl_session *)
+						get_sym_session_private_data(
+						op->sym->session,
+						cryptodev_driver_id);
+		} else {
+			if (likely(op->asym->session != NULL))
+				asym_sess = (struct openssl_asym_session *)
+						get_asym_session_private_data(
+						op->asym->session,
+						cryptodev_driver_id);
+			if (asym_sess == NULL)
+				op->status =
+					RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
+			return asym_sess;
+		}
 	} else {
+		/* sessionless asymmetric not supported */
+		if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
+			return NULL;
+
 		/* provide internal session */
 		void *_sess = NULL;
 		void *_sess_private_data = NULL;
@@ -1525,6 +1543,191 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
 }
 
+/* process modinv operation */
+static int process_openssl_modinv_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	struct rte_crypto_asym_op *op = cop->asym;
+	BIGNUM *base = BN_CTX_get(sess->u.m.ctx);
+	BIGNUM *res = BN_CTX_get(sess->u.m.ctx);
+
+	if (unlikely(base == NULL || res == NULL)) {
+		if (base)
+			BN_free(base);
+		if (res)
+			BN_free(res);
+		cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		return -1;
+	}
+
+	base = BN_bin2bn((const unsigned char *)op->modinv.base.data,
+			op->modinv.base.length, base);
+
+	if (BN_mod_inverse(res, base, sess->u.m.modulus, sess->u.m.ctx)) {
+		cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+		op->modinv.base.length = BN_bn2bin(res, op->modinv.base.data);
+	} else {
+		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+	}
+
+	return 0;
+}
+
+/* process modexp operation */
+static int process_openssl_modexp_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	struct rte_crypto_asym_op *op = cop->asym;
+	BIGNUM *base = BN_CTX_get(sess->u.e.ctx);
+	BIGNUM *res = BN_CTX_get(sess->u.e.ctx);
+
+	if (unlikely(base == NULL || res == NULL)) {
+		if (base)
+			BN_free(base);
+		if (res)
+			BN_free(res);
+		cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		return -1;
+	}
+
+	base = BN_bin2bn((const unsigned char *)op->modinv.base.data,
+			op->modinv.base.length, base);
+
+	if (BN_mod_exp(res, base, sess->u.e.exp,
+				sess->u.e.mod, sess->u.e.ctx)) {
+		op->modinv.base.length = BN_bn2bin(res, op->modinv.base.data);
+		cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+	} else {
+		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+	}
+
+	return 0;
+}
+
+/* process rsa operations */
+static int process_openssl_rsa_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	int ret = 0;
+	struct rte_crypto_asym_op *op = cop->asym;
+	RSA *rsa = sess->u.r.rsa;
+	uint32_t pad = (op->rsa.pad);
+
+	switch (pad) {
+	case RTE_CRYPTO_RSA_PKCS1_V1_5_BT0:
+	case RTE_CRYPTO_RSA_PKCS1_V1_5_BT1:
+	case RTE_CRYPTO_RSA_PKCS1_V1_5_BT2:
+		pad = RSA_PKCS1_PADDING;
+		break;
+	case RTE_CRYPTO_RSA_PADDING_NONE:
+		pad = RSA_NO_PADDING;
+		break;
+	default:
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		OPENSSL_LOG(ERR,
+				"rsa pad type not supported %d\n", pad);
+		return 0;
+	}
+
+	switch (op->rsa.op_type) {
+	case RTE_CRYPTO_ASYM_OP_ENCRYPT:
+		ret = RSA_public_encrypt(op->rsa.message.length,
+				op->rsa.message.data,
+				op->rsa.message.data,
+				rsa,
+				pad);
+
+		if (ret > 0)
+			op->rsa.message.length = ret;
+		OPENSSL_LOG(DEBUG,
+				"length of encrypted text %d\n", ret);
+		break;
+
+	case RTE_CRYPTO_ASYM_OP_DECRYPT:
+		ret = RSA_private_decrypt(op->rsa.message.length,
+				op->rsa.message.data,
+				op->rsa.message.data,
+				rsa,
+				pad);
+		if (ret > 0)
+			op->rsa.message.length = ret;
+		break;
+
+	case RTE_CRYPTO_ASYM_OP_SIGN:
+		ret = RSA_private_encrypt(op->rsa.message.length,
+				op->rsa.message.data,
+				op->rsa.sign.data,
+				rsa,
+				pad);
+		if (ret > 0)
+			op->rsa.sign.length = ret;
+		break;
+
+	case RTE_CRYPTO_ASYM_OP_VERIFY:
+		ret = RSA_public_decrypt(op->rsa.sign.length,
+				op->rsa.sign.data,
+				op->rsa.sign.data,
+				rsa,
+				pad);
+
+		OPENSSL_LOG(DEBUG,
+				"Length of public_decrypt %d "
+				"length of message %zd\n",
+				ret, op->rsa.message.length);
+
+		if (memcmp(op->rsa.sign.data, op->rsa.message.data,
+					op->rsa.message.length)) {
+			OPENSSL_LOG(ERR,
+					"RSA sign Verification failed");
+			return -1;
+		}
+	default:
+		/* allow ops with invalid args to be pushed to
+		 * completion queue
+		 */
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		break;
+	}
+
+	if (ret < 0)
+		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	return 0;
+}
+
+static int
+process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
+		struct openssl_asym_session *sess)
+{
+	int retval = 0;
+
+	op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+
+	switch (sess->xfrm_type) {
+	case RTE_CRYPTO_ASYM_XFORM_RSA:
+		retval = process_openssl_rsa_op(op, sess);
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_MODEX:
+		retval = process_openssl_modexp_op(op, sess);
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_MODINV:
+		retval = process_openssl_modinv_op(op, sess);
+		break;
+	default:
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		break;
+	}
+	if (!retval) {
+		/* op processed so push to completion queue as processed */
+		retval = rte_ring_enqueue(qp->processed_ops, (void *)op);
+		if (retval)
+			/* return error if failed to put in completion queue */
+			retval = -1;
+	}
+
+	return retval;
+}
+
 /** Process crypto operation for mbuf */
 static int
 process_op(struct openssl_qp *qp, struct rte_crypto_op *op,
@@ -1597,7 +1800,7 @@ static uint16_t
 openssl_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
 		uint16_t nb_ops)
 {
-	struct openssl_session *sess;
+	void *sess;
 	struct openssl_qp *qp = queue_pair;
 	int i, retval;
 
@@ -1606,7 +1809,12 @@ openssl_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
 		if (unlikely(sess == NULL))
 			goto enqueue_err;
 
-		retval = process_op(qp, ops[i], sess);
+		if (ops[i]->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC)
+			retval = process_op(qp, ops[i],
+					(struct openssl_session *) sess);
+		else
+			retval = process_asym_op(qp, ops[i],
+					(struct openssl_asym_session *) sess);
 		if (unlikely(retval < 0))
 			goto enqueue_err;
 	}
@@ -1661,7 +1869,8 @@ cryptodev_openssl_create(const char *name,
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
 			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
-			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT;
+			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
+			RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO;
 
 	/* Set vector instructions mode supported */
 	internals = dev->data->dev_private;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index 5335685..a23a9e2 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -9,6 +9,7 @@
 #include <rte_cryptodev_pmd.h>
 
 #include "rte_openssl_pmd_private.h"
+#include "compat.h"
 
 
 static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
@@ -469,6 +470,63 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 			}, }
 		}, }
 	},
+	{	/* RSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					(1 << RTE_CRYPTO_ASYM_OP_VERIFY) |
+					(1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) |
+					(1 << RTE_CRYPTO_ASYM_OP_DECRYPT)),
+				{
+				.modlen = {
+				/* min length is based on openssl rsa keygen */
+				.min = 30,
+				/* value 0 symbolizes no limit on max length */
+				.max = 0,
+				.increment = 1
+				}, }
+			}
+		},
+		}
+	},
+	{	/* modexp */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
+				.op_types = 0,
+				{
+				.modlen = {
+				/* value 0 symbolizes no limit on min length */
+				.min = 0,
+				/* value 0 symbolizes no limit on max length */
+				.max = 0,
+				.increment = 1
+				}, }
+			}
+		},
+		}
+	},
+	{	/* modinv */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
+				.op_types = 0,
+				{
+				.modlen = {
+				/* value 0 symbolizes no limit on min length */
+				.min = 0,
+				/* value 0 symbolizes no limit on max length */
+				.max = 0,
+				.increment = 1
+				}, }
+			}
+		},
+		}
+	},
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -655,13 +713,20 @@ openssl_pmd_qp_count(struct rte_cryptodev *dev)
 	return dev->data->nb_queue_pairs;
 }
 
-/** Returns the size of the session structure */
+/** Returns the size of the symmetric session structure */
 static unsigned
 openssl_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
 {
 	return sizeof(struct openssl_session);
 }
 
+/** Returns the size of the asymmetric session structure */
+static unsigned
+openssl_pmd_asym_session_get_size(struct rte_cryptodev *dev __rte_unused)
+{
+	return sizeof(struct openssl_asym_session);
+}
+
 /** Configure the session from a crypto xform chain */
 static int
 openssl_pmd_sym_session_configure(struct rte_cryptodev *dev __rte_unused,
@@ -698,6 +763,226 @@ openssl_pmd_sym_session_configure(struct rte_cryptodev *dev __rte_unused,
 	return 0;
 }
 
+static int openssl_set_asym_session_parameters(
+		struct openssl_asym_session *asym_session,
+		struct rte_crypto_asym_xform *xform)
+{
+	int ret = 0;
+
+	if (xform->next != NULL) {
+		OPENSSL_LOG(ERR, "chained xfrms are not supported on %s",
+			rte_crypto_asym_xform_strings[xform->xform_type]);
+		return -1;
+	}
+
+	switch (xform->xform_type) {
+	case RTE_CRYPTO_ASYM_XFORM_RSA:
+	{
+		BIGNUM *n = NULL;
+		BIGNUM *e = NULL;
+		BIGNUM *d = NULL;
+		BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL;
+		BIGNUM *iqmp = NULL, *dmq1 = NULL;
+
+		/* copy xfrm data into rsa struct */
+		n = BN_bin2bn((const unsigned char *)xform->rsa.n.data,
+				xform->rsa.n.length, n);
+		e = BN_bin2bn((const unsigned char *)xform->rsa.e.data,
+				xform->rsa.e.length, e);
+
+		if (!n || !e)
+			goto err_rsa;
+
+		RSA *rsa = RSA_new();
+		if (rsa == NULL)
+			goto err_rsa;
+
+		if (xform->rsa.key_type == RTE_RSA_KEY_TYPE_EXP) {
+			d = BN_bin2bn(
+			(const unsigned char *)xform->rsa.d.data,
+			xform->rsa.d.length,
+			d);
+			if (!d) {
+				RSA_free(rsa);
+				goto err_rsa;
+			}
+		} else {
+			p = BN_bin2bn((const unsigned char *)
+					xform->rsa.qt.p.data,
+					xform->rsa.qt.p.length,
+					p);
+			q = BN_bin2bn((const unsigned char *)
+					xform->rsa.qt.q.data,
+					xform->rsa.qt.q.length,
+					q);
+			dmp1 = BN_bin2bn((const unsigned char *)
+					xform->rsa.qt.dP.data,
+					xform->rsa.qt.dP.length,
+					dmp1);
+			dmq1 = BN_bin2bn((const unsigned char *)
+					xform->rsa.qt.dQ.data,
+					xform->rsa.qt.dQ.length,
+					dmq1);
+			iqmp = BN_bin2bn((const unsigned char *)
+					xform->rsa.qt.qInv.data,
+					xform->rsa.qt.qInv.length,
+					iqmp);
+
+			if (!p || !q || !dmp1 || !dmq1 || !iqmp) {
+				RSA_free(rsa);
+				goto err_rsa;
+			}
+			set_rsa_params(rsa, p, q, ret);
+			if (ret) {
+				OPENSSL_LOG(ERR,
+					"failed to set rsa params\n");
+				RSA_free(rsa);
+				goto err_rsa;
+			}
+			set_rsa_crt_params(rsa, dmp1, dmq1, iqmp, ret);
+			if (ret) {
+				OPENSSL_LOG(ERR,
+					"failed to set crt params\n");
+				RSA_free(rsa);
+				/*
+				 * set already populated params to NULL
+				 * as its freed by call to RSA_free
+				 */
+				p = q = NULL;
+				goto err_rsa;
+			}
+		}
+
+		set_rsa_keys(rsa, n, e, d, ret);
+		if (ret) {
+			OPENSSL_LOG(ERR, "Failed to load rsa keys\n");
+			RSA_free(rsa);
+			return -1;
+		}
+		asym_session->u.r.rsa = rsa;
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_RSA;
+		break;
+err_rsa:
+		if (n)
+			BN_free(n);
+		if (e)
+			BN_free(e);
+		if (d)
+			BN_free(d);
+		if (p)
+			BN_free(p);
+		if (q)
+			BN_free(q);
+		if (dmp1)
+			BN_free(dmp1);
+		if (dmq1)
+			BN_free(dmq1);
+		if (iqmp)
+			BN_free(iqmp);
+
+		return -1;
+	}
+	case RTE_CRYPTO_ASYM_XFORM_MODEX:
+	{
+		struct rte_crypto_modex_xform *xfrm = &(xform->modex);
+
+		BN_CTX *ctx = BN_CTX_new();
+		if (ctx == NULL) {
+			OPENSSL_LOG(ERR,
+				" failed to allocate resources\n");
+			return -1;
+		}
+		BN_CTX_start(ctx);
+		BIGNUM *mod = BN_CTX_get(ctx);
+		BIGNUM *exp = BN_CTX_get(ctx);
+		if (mod == NULL || exp == NULL) {
+			BN_CTX_end(ctx);
+			BN_CTX_free(ctx);
+			return -1;
+		}
+
+		mod = BN_bin2bn((const unsigned char *)
+				xfrm->modulus.data,
+				xfrm->modulus.length, mod);
+		exp = BN_bin2bn((const unsigned char *)
+				xfrm->exponent.data,
+				xfrm->exponent.length, exp);
+		asym_session->u.e.ctx = ctx;
+		asym_session->u.e.mod = mod;
+		asym_session->u.e.exp = exp;
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODEX;
+		break;
+	}
+	case RTE_CRYPTO_ASYM_XFORM_MODINV:
+	{
+		struct rte_crypto_modinv_xform *xfrm = &(xform->modinv);
+
+		BN_CTX *ctx = BN_CTX_new();
+		if (ctx == NULL) {
+			OPENSSL_LOG(ERR,
+				" failed to allocate resources\n");
+			return -1;
+		}
+		BN_CTX_start(ctx);
+		BIGNUM *mod = BN_CTX_get(ctx);
+		if (mod == NULL) {
+			BN_CTX_end(ctx);
+			BN_CTX_free(ctx);
+			return -1;
+		}
+
+		mod = BN_bin2bn((const unsigned char *)
+				xfrm->modulus.data,
+				xfrm->modulus.length,
+				mod);
+		asym_session->u.m.ctx = ctx;
+		asym_session->u.m.modulus = mod;
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODINV;
+		break;
+	}
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+/** Configure the session from a crypto xform chain */
+static int
+openssl_pmd_asym_session_configure(struct rte_cryptodev *dev __rte_unused,
+		struct rte_crypto_asym_xform *xform,
+		struct rte_cryptodev_asym_session *sess,
+		struct rte_mempool *mempool)
+{
+	void *asym_sess_private_data;
+	int ret;
+
+	if (unlikely(sess == NULL)) {
+		OPENSSL_LOG(ERR, "invalid asymmetric session struct");
+		return -EINVAL;
+	}
+
+	if (rte_mempool_get(mempool, &asym_sess_private_data)) {
+		CDEV_LOG_ERR(
+			"Couldn't get object from session mempool");
+		return -ENOMEM;
+	}
+
+	ret = openssl_set_asym_session_parameters(asym_sess_private_data,
+			xform);
+	if (ret != 0) {
+		OPENSSL_LOG(ERR, "failed configure session parameters");
+
+		/* Return session to mempool */
+		rte_mempool_put(mempool, asym_sess_private_data);
+		return ret;
+	}
+
+	set_asym_session_private_data(sess, dev->driver_id,
+			asym_sess_private_data);
+
+	return 0;
+}
 
 /** Clear the memory of session so it doesn't leave key material behind */
 static void
@@ -717,6 +1002,50 @@ openssl_pmd_sym_session_clear(struct rte_cryptodev *dev,
 	}
 }
 
+static void openssl_reset_asym_session(struct openssl_asym_session *sess)
+{
+	switch (sess->xfrm_type) {
+	case RTE_CRYPTO_ASYM_XFORM_RSA:
+		if (sess->u.r.rsa)
+			RSA_free(sess->u.r.rsa);
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_MODEX:
+		if (sess->u.e.ctx) {
+			BN_CTX_end(sess->u.e.ctx);
+			BN_CTX_free(sess->u.e.ctx);
+		}
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_MODINV:
+		if (sess->u.m.ctx) {
+			BN_CTX_end(sess->u.m.ctx);
+			BN_CTX_free(sess->u.m.ctx);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+/** Clear the memory of asymmetric session
+ * so it doesn't leave key material behind
+ */
+static void
+openssl_pmd_asym_session_clear(struct rte_cryptodev *dev,
+		struct rte_cryptodev_asym_session *sess)
+{
+	uint8_t index = dev->driver_id;
+	void *sess_priv = get_asym_session_private_data(sess, index);
+
+	/* Zero out the whole structure */
+	if (sess_priv) {
+		openssl_reset_asym_session(sess_priv);
+		memset(sess_priv, 0, sizeof(struct openssl_asym_session));
+		struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
+		set_asym_session_private_data(sess, index, NULL);
+		rte_mempool_put(sess_mp, sess_priv);
+	}
+}
+
 struct rte_cryptodev_ops openssl_pmd_ops = {
 		.dev_configure		= openssl_pmd_config,
 		.dev_start		= openssl_pmd_start,
@@ -733,8 +1062,11 @@ struct rte_cryptodev_ops openssl_pmd_ops = {
 		.queue_pair_count	= openssl_pmd_qp_count,
 
 		.sym_session_get_size	= openssl_pmd_sym_session_get_size,
+		.asym_session_get_size	= openssl_pmd_asym_session_get_size,
 		.sym_session_configure	= openssl_pmd_sym_session_configure,
-		.sym_session_clear	= openssl_pmd_sym_session_clear
+		.asym_session_configure	= openssl_pmd_asym_session_configure,
+		.sym_session_clear	= openssl_pmd_sym_session_clear,
+		.asym_session_clear	= openssl_pmd_asym_session_clear
 };
 
 struct rte_cryptodev_ops *rte_openssl_pmd_ops = &openssl_pmd_ops;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_private.h b/drivers/crypto/openssl/rte_openssl_pmd_private.h
index 29fcb76..0ebe596 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_private.h
+++ b/drivers/crypto/openssl/rte_openssl_pmd_private.h
@@ -8,6 +8,7 @@
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/des.h>
+#include <openssl/rsa.h>
 
 #define CRYPTODEV_NAME_OPENSSL_PMD	crypto_openssl
 /**< Open SSL Crypto PMD device name */
@@ -142,6 +143,24 @@ struct openssl_session {
 
 } __rte_cache_aligned;
 
+/** OPENSSL crypto private asymmetric session structure */
+struct openssl_asym_session {
+	enum rte_crypto_asym_xform_type xfrm_type;
+	union {
+		struct rsa {
+			RSA *rsa;
+		} r;
+		struct exp {
+			BIGNUM *exp;
+			BIGNUM *mod;
+			BN_CTX *ctx;
+		} e;
+		struct mod {
+			BIGNUM *modulus;
+			BN_CTX *ctx;
+		} m;
+	} u;
+} __rte_cache_aligned;
 /** Set and validate OPENSSL crypto session parameters */
 extern int
 openssl_set_session_parameters(struct openssl_session *sess,
-- 
2.9.5

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

* [PATCH v4 2/3] crypto/openssl: add dh and dsa asym op
  2018-07-12 14:08 [PATCH v4 0/3]crypto/openssl: support asymmetric crypto Shally Verma
  2018-07-12 14:08 ` [PATCH v4 1/3] crypto/openssl: add rsa and mod asym op Shally Verma
@ 2018-07-12 14:08 ` Shally Verma
  2018-07-12 14:08 ` [PATCH v4 3/3] doc: add asym feature list Shally Verma
  2 siblings, 0 replies; 5+ messages in thread
From: Shally Verma @ 2018-07-12 14:08 UTC (permalink / raw)
  To: pablo.de.lara.guarch; +Cc: dev, pathreya, nmurthy, Sunila Sahu, Ashish Gupta

From: Sunila Sahu <sunila.sahu@caviumnetworks.com>

- Add dh key generation and shared compute
- Add dsa sign and verify operation

Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
---
 drivers/crypto/openssl/compat.h                  |  68 +++++++
 drivers/crypto/openssl/rte_openssl_pmd.c         | 237 +++++++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c     | 194 ++++++++++++++++++-
 drivers/crypto/openssl/rte_openssl_pmd_private.h |   9 +
 4 files changed, 507 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/openssl/compat.h b/drivers/crypto/openssl/compat.h
index 8ece808..45f9a33 100644
--- a/drivers/crypto/openssl/compat.h
+++ b/drivers/crypto/openssl/compat.h
@@ -23,6 +23,41 @@
 		rsa->n = n; rsa->e = e; rsa->d = d; ret = 0; \
 	} while (0)
 
+#define set_dh_params(dh, p, g, ret) \
+	do { \
+		dh->p = p; \
+		dh->q = NULL; \
+		dh->g = g; \
+		ret = 0; \
+	} while (0)
+
+#define set_dh_priv_key(dh, priv_key, ret) \
+	do { dh->priv_key = priv_key; ret = 0; } while (0)
+
+#define set_dsa_params(dsa, p, q, g, ret) \
+	do { dsa->p = p; dsa->q = q; dsa->g = g; ret = 0; } while (0)
+
+#define get_dh_pub_key(dh, pub_key) \
+	(pub_key = dh->pub_key)
+
+#define get_dh_priv_key(dh, priv_key) \
+	(priv_key = dh->priv_key)
+
+#define set_dsa_sign(sign, r, s) \
+	do { sign->r = r; sign->s = s; } while (0)
+
+#define get_dsa_sign(sign, r, s) \
+	do { r = sign->r; s = sign->s; } while (0)
+
+#define set_dsa_keys(dsa, pub, priv, ret) \
+	do { dsa->pub_key = pub; dsa->priv_key = priv; ret = 0; } while (0)
+
+#define set_dsa_pub_key(dsa, pub_key) \
+	(dsa->pub_key = pub_key)
+
+#define get_dsa_priv_key(dsa, priv_key) \
+	(priv_key = dsa->priv_key)
+
 #else
 
 #define set_rsa_params(rsa, p, q, ret) \
@@ -35,6 +70,39 @@
 #define set_rsa_keys(rsa, n, e, d, ret) \
 	(ret = !RSA_set0_key(rsa, n, e, d))
 
+#define set_dh_params(dh, p, g, ret) \
+	(ret = !DH_set0_pqg(dh, p, NULL, g))
+
+#define set_dh_priv_key(dh, priv_key, ret) \
+	(ret = !DH_set0_key(dh, NULL, priv_key))
+
+#define get_dh_pub_key(dh, pub_key) \
+	(DH_get0_key(dh_key, &pub_key, NULL))
+
+#define get_dh_priv_key(dh, priv_key) \
+	(DH_get0_key(dh_key, NULL, &priv_key))
+
+#define set_dsa_params(dsa, p, q, g, ret) \
+	(ret = !DSA_set0_pqg(dsa, p, q, g))
+
+#define set_dsa_priv_key(dsa, priv_key) \
+	(DSA_set0_key(dsa, NULL, priv_key))
+
+#define set_dsa_sign(sign, r, s) \
+	(DSA_SIG_set0(sign, r, s))
+
+#define get_dsa_sign(sign, r, s) \
+	(DSA_SIG_get0(sign, &r, &s))
+
+#define set_dsa_keys(dsa, pub, priv, ret) \
+	(ret = !DSA_set0_key(dsa, pub, priv))
+
+#define set_dsa_pub_key(dsa, pub_key) \
+	(DSA_set0_key(dsa, pub_key, NULL))
+
+#define get_dsa_priv_key(dsa, priv_key) \
+	(DSA_get0_key(dsa, NULL, &priv_key))
+
 #endif /* version < 10100000 */
 
 #endif /* __RTA_COMPAT_H__ */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index e21a6a1..3314802 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -1543,6 +1543,230 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
 }
 
+/* process dsa sign operation */
+static int
+process_openssl_dsa_sign_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	struct rte_crypto_dsa_op_param *op = &cop->asym->dsa;
+	DSA *dsa = sess->u.s.dsa;
+	DSA_SIG *sign = NULL;
+
+	sign = DSA_do_sign(op->message.data,
+			op->message.length,
+			dsa);
+
+	if (sign == NULL) {
+		OPENSSL_LOG(ERR, "%s:%d\n", __func__, __LINE__);
+		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+	} 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);
+
+	return 0;
+}
+
+/* process dsa verify operation */
+static int
+process_openssl_dsa_verify_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	struct rte_crypto_dsa_op_param *op = &cop->asym->dsa;
+	DSA *dsa = sess->u.s.dsa;
+	int ret;
+	DSA_SIG *sign = DSA_SIG_new();
+	BIGNUM *r = NULL, *s = NULL;
+	BIGNUM *pub_key = NULL;
+
+	if (sign == NULL) {
+		OPENSSL_LOG(ERR, " %s:%d\n", __func__, __LINE__);
+		cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		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) {
+		if (r)
+			BN_free(r);
+		if (s)
+			BN_free(s);
+		if (pub_key)
+			BN_free(pub_key);
+
+		cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		return -1;
+	}
+	set_dsa_sign(sign, r, s);
+	set_dsa_pub_key(dsa, pub_key);
+
+	ret = DSA_do_verify(op->message.data,
+			op->message.length,
+			sign,
+			dsa);
+
+	if (ret != 1)
+		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+	else
+		cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+
+	DSA_SIG_free(sign);
+
+	return 0;
+}
+
+/* process dh operation */
+static int
+process_openssl_dh_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	struct rte_crypto_dh_op_param *op = &cop->asym->dh;
+	DH *dh_key = sess->u.dh.dh_key;
+	BIGNUM *priv_key = NULL;
+	int ret = 0;
+
+	if (sess->u.dh.key_op &
+			(1 << RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE)) {
+		/* compute shared secret using peer public key
+		 * and current private key
+		 * shared secret = peer_key ^ priv_key mod p
+		 */
+		BIGNUM *peer_key = NULL;
+
+		/* copy private key and peer key and compute shared secret */
+		peer_key = BN_bin2bn(op->pub_key.data,
+				op->pub_key.length,
+				peer_key);
+		if (peer_key == NULL) {
+			cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+			return -1;
+		}
+		priv_key = BN_bin2bn(op->priv_key.data,
+				op->priv_key.length,
+				priv_key);
+		if (priv_key == NULL) {
+			BN_free(peer_key);
+			cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+			return -1;
+		}
+		set_dh_priv_key(dh_key, priv_key, ret);
+		if (ret) {
+			OPENSSL_LOG(ERR, "Failed to set private key\n");
+			cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+			BN_free(peer_key);
+			BN_free(priv_key);
+			return 0;
+		}
+
+		ret = DH_compute_key(
+				op->shared_secret.data,
+				peer_key, dh_key);
+		if (ret < 0) {
+			cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+			BN_free(peer_key);
+			/* priv key is already loaded into dh,
+			 * let's not free that directly here.
+			 * DH_free() will auto free it later.
+			 */
+			return 0;
+		}
+		cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+		op->shared_secret.length = ret;
+		BN_free(peer_key);
+		return 0;
+	}
+
+	/*
+	 * other options are public and private key generations.
+	 *
+	 * if user provides private key,
+	 * then first set DH with user provided private key
+	 */
+	if ((sess->u.dh.key_op &
+			(1 << RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE)) &&
+			!(sess->u.dh.key_op &
+			(1 << RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE))) {
+		/* generate public key using user-provided private key
+		 * pub_key = g ^ priv_key mod p
+		 */
+
+		/* load private key into DH */
+		priv_key = BN_bin2bn(op->priv_key.data,
+				op->priv_key.length,
+				priv_key);
+		if (priv_key == NULL) {
+			cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+			return -1;
+		}
+		set_dh_priv_key(dh_key, priv_key, ret);
+		if (ret) {
+			OPENSSL_LOG(ERR, "Failed to set private key\n");
+			cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+			BN_free(priv_key);
+			return 0;
+		}
+	}
+
+	/* generate public and private key pair.
+	 *
+	 * if private key already set, generates only public key.
+	 *
+	 * if private key is not already set, then set it to random value
+	 * and update internal private key.
+	 */
+	if (!DH_generate_key(dh_key)) {
+		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+		return 0;
+	}
+
+	if (sess->u.dh.key_op & (1 << RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE)) {
+		const BIGNUM *pub_key = NULL;
+
+		OPENSSL_LOG(DEBUG, "%s:%d update public key\n",
+				__func__, __LINE__);
+
+		/* get the generated keys */
+		get_dh_pub_key(dh_key, pub_key);
+
+		/* output public key */
+		op->pub_key.length = BN_bn2bin(pub_key,
+				op->pub_key.data);
+	}
+
+	if (sess->u.dh.key_op &
+			(1 << RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE)) {
+		const BIGNUM *priv_key = NULL;
+
+		OPENSSL_LOG(DEBUG, "%s:%d updated priv key\n",
+				__func__, __LINE__);
+
+		/* get the generated keys */
+		get_dh_priv_key(dh_key, priv_key);
+
+		/* provide generated private key back to user */
+		op->priv_key.length = BN_bn2bin(priv_key,
+				op->priv_key.data);
+	}
+
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+
+	return 0;
+}
+
 /* process modinv operation */
 static int process_openssl_modinv_op(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -1713,6 +1937,19 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 	case RTE_CRYPTO_ASYM_XFORM_MODINV:
 		retval = process_openssl_modinv_op(op, sess);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_DH:
+		retval = process_openssl_dh_op(op, sess);
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_DSA:
+		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);
+		else
+			op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		break;
 	default:
 		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 a23a9e2..ee31e1b 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -527,6 +527,48 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		},
 		}
 	},
+	{	/* dh */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_DH,
+				.op_types =
+				((1<<RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE) |
+				(1 << RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE |
+				(1 <<
+				RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE))),
+				{
+				.modlen = {
+				/* value 0 symbolizes no limit on min length */
+				.min = 0,
+				/* value 0 symbolizes no limit on max length */
+				.max = 0,
+				.increment = 1
+				}, }
+			}
+		},
+		}
+	},
+	{	/* dsa */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_DSA,
+				.op_types =
+				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
+				(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+				{
+				.modlen = {
+				/* value 0 symbolizes no limit on min length */
+				.min = 0,
+				/* value 0 symbolizes no limit on max length */
+				.max = 0,
+				.increment = 1
+				}, }
+			}
+		},
+		}
+	},
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -769,7 +811,8 @@ static int openssl_set_asym_session_parameters(
 {
 	int ret = 0;
 
-	if (xform->next != NULL) {
+	if ((xform->xform_type != RTE_CRYPTO_ASYM_XFORM_DH) &&
+		(xform->next != NULL)) {
 		OPENSSL_LOG(ERR, "chained xfrms are not supported on %s",
 			rte_crypto_asym_xform_strings[xform->xform_type]);
 		return -1;
@@ -940,6 +983,147 @@ static int openssl_set_asym_session_parameters(
 		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODINV;
 		break;
 	}
+	case RTE_CRYPTO_ASYM_XFORM_DH:
+	{
+		BIGNUM *p = NULL;
+		BIGNUM *g = NULL;
+
+		p = BN_bin2bn((const unsigned char *)
+				xform->dh.p.data,
+				xform->dh.p.length,
+				p);
+		g = BN_bin2bn((const unsigned char *)
+				xform->dh.g.data,
+				xform->dh.g.length,
+				g);
+		if (!p || !g)
+			goto err_dh;
+
+		DH *dh = DH_new();
+		if (dh == NULL) {
+			OPENSSL_LOG(ERR,
+				"failed to allocate resources\n");
+			goto err_dh;
+		}
+		set_dh_params(dh, p, g, ret);
+		if (ret) {
+			DH_free(dh);
+			goto err_dh;
+		}
+
+		/*
+		 * setup xfrom for
+		 * public key generate, or
+		 * DH Priv key generate, or both
+		 * public and private key generate
+		 */
+		asym_session->u.dh.key_op = (1 << xform->dh.type);
+
+		if (xform->dh.type ==
+			RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE) {
+			/* check if next is pubkey */
+			if ((xform->next != NULL) &&
+				(xform->next->xform_type ==
+				RTE_CRYPTO_ASYM_XFORM_DH) &&
+				(xform->next->dh.type ==
+				RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE)
+				) {
+				/*
+				 * setup op as pub/priv key
+				 * pair generationi
+				 */
+				asym_session->u.dh.key_op |=
+				(1 <<
+				RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE);
+			}
+		}
+		asym_session->u.dh.dh_key = dh;
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DH;
+		break;
+
+err_dh:
+		OPENSSL_LOG(ERR, " failed to set dh params\n");
+		if (p)
+			BN_free(p);
+		if (g)
+			BN_free(g);
+		return -1;
+	}
+	case RTE_CRYPTO_ASYM_XFORM_DSA:
+	{
+		BIGNUM *p = NULL, *g = NULL;
+		BIGNUM *q = NULL, *priv_key = NULL;
+		BIGNUM *pub_key = BN_new();
+		BN_zero(pub_key);
+
+		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;
+
+		DSA *dsa = DSA_new();
+		if (dsa == NULL) {
+			OPENSSL_LOG(ERR,
+				" failed to allocate resources\n");
+			goto err_dsa;
+		}
+
+		set_dsa_params(dsa, p, q, g, ret);
+		if (ret) {
+			DSA_free(dsa);
+			OPENSSL_LOG(ERR, "Failed to dsa params\n");
+			goto err_dsa;
+		}
+
+		/*
+		 * openssl 1.1.0 mandate that public key can't be
+		 * NULL in very first call. so set a dummy pub key.
+		 * to keep consistency, lets follow same approach for
+		 * both versions
+		 */
+		/* just set dummy public for very 1st call */
+		set_dsa_keys(dsa, pub_key, priv_key, ret);
+		if (ret) {
+			DSA_free(dsa);
+			OPENSSL_LOG(ERR, "Failed to set keys\n");
+			return -1;
+		}
+		asym_session->u.s.dsa = dsa;
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA;
+		break;
+
+err_dsa:
+		if (p)
+			BN_free(p);
+		if (q)
+			BN_free(q);
+		if (g)
+			BN_free(g);
+		if (priv_key)
+			BN_free(priv_key);
+		if (pub_key)
+			BN_free(pub_key);
+		return -1;
+	}
 	default:
 		return -1;
 	}
@@ -1021,6 +1205,14 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 			BN_CTX_free(sess->u.m.ctx);
 		}
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_DH:
+		if (sess->u.dh.dh_key)
+			DH_free(sess->u.dh.dh_key);
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_DSA:
+		if (sess->u.s.dsa)
+			DSA_free(sess->u.s.dsa);
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_private.h b/drivers/crypto/openssl/rte_openssl_pmd_private.h
index 0ebe596..a8f2c84 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_private.h
+++ b/drivers/crypto/openssl/rte_openssl_pmd_private.h
@@ -9,6 +9,8 @@
 #include <openssl/hmac.h>
 #include <openssl/des.h>
 #include <openssl/rsa.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
 
 #define CRYPTODEV_NAME_OPENSSL_PMD	crypto_openssl
 /**< Open SSL Crypto PMD device name */
@@ -159,6 +161,13 @@ struct openssl_asym_session {
 			BIGNUM *modulus;
 			BN_CTX *ctx;
 		} m;
+		struct dh {
+			DH *dh_key;
+			uint32_t key_op;
+		} dh;
+		struct {
+			DSA *dsa;
+		} s;
 	} u;
 } __rte_cache_aligned;
 /** Set and validate OPENSSL crypto session parameters */
-- 
2.9.5

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

* [PATCH v4 3/3] doc: add asym feature list
  2018-07-12 14:08 [PATCH v4 0/3]crypto/openssl: support asymmetric crypto Shally Verma
  2018-07-12 14:08 ` [PATCH v4 1/3] crypto/openssl: add rsa and mod asym op Shally Verma
  2018-07-12 14:08 ` [PATCH v4 2/3] crypto/openssl: add dh and dsa " Shally Verma
@ 2018-07-12 14:08 ` Shally Verma
  2 siblings, 0 replies; 5+ messages in thread
From: Shally Verma @ 2018-07-12 14:08 UTC (permalink / raw)
  To: pablo.de.lara.guarch; +Cc: dev, pathreya, nmurthy, Ashish Gupta, Sunila Sahu

From: Ashish Gupta <ashish.gupta@caviumnetworks.com>

Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
---
 doc/guides/cryptodevs/features/openssl.ini | 11 +++++++++++
 doc/guides/cryptodevs/openssl.rst          |  1 +
 2 files changed, 12 insertions(+)

diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index 626ec1b..b9c0bdc 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -8,6 +8,7 @@ Symmetric crypto       = Y
 Sym operation chaining = Y
 OOP SGL In LB  Out     = Y
 OOP LB  In LB  Out     = Y
+Asymmetric crypto      = Y
 
 ;
 ; Supported crypto algorithms of the 'openssl' crypto driver.
@@ -50,3 +51,13 @@ AES GCM (256) = Y
 AES CCM (128) = Y
 AES CCM (192) = Y
 AES CCM (256) = Y
+
+;
+; Supported Asymmetric algorithms of the 'openssl' crypto driver.
+;
+[Asymmetric]
+RSA = Y
+DSA = Y
+Modular Exponentiation = Y
+Modular Inversion = Y
+Diffie-hellman = Y
diff --git a/doc/guides/cryptodevs/openssl.rst b/doc/guides/cryptodevs/openssl.rst
index 427fc80..bdc30f6 100644
--- a/doc/guides/cryptodevs/openssl.rst
+++ b/doc/guides/cryptodevs/openssl.rst
@@ -80,6 +80,7 @@ crypto processing.
 
 Test name is cryptodev_openssl_autotest.
 For performance test cryptodev_openssl_perftest can be used.
+For asymmetric crypto operations testing, run cryptodev_openssl_asym_autotest.
 
 To verify real traffic l2fwd-crypto example can be used with this command:
 
-- 
2.9.5

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

* Re: [PATCH v4 1/3] crypto/openssl: add rsa and mod asym op
  2018-07-12 14:08 ` [PATCH v4 1/3] crypto/openssl: add rsa and mod asym op Shally Verma
@ 2018-07-23 12:32   ` De Lara Guarch, Pablo
  0 siblings, 0 replies; 5+ messages in thread
From: De Lara Guarch, Pablo @ 2018-07-23 12:32 UTC (permalink / raw)
  To: Shally Verma; +Cc: dev, pathreya, nmurthy, Sunila Sahu, Ashish Gupta

Hi Shally,

> -----Original Message-----
> From: Shally Verma [mailto:shally.verma@caviumnetworks.com]
> Sent: Thursday, July 12, 2018 3:09 PM
> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Cc: dev@dpdk.org; pathreya@caviumnetworks.com;
> nmurthy@caviumnetworks.com; Sunila Sahu
> <sunila.sahu@caviumnetworks.com>; Ashish Gupta
> <ashish.gupta@caviumnetworks.com>
> Subject: [PATCH v4 1/3] crypto/openssl: add rsa and mod asym op
> 
> From: Sunila Sahu <sunila.sahu@caviumnetworks.com>
> 
> - Add compat.h to make pmd compatible to openssl-1.1.0 and
>   backward version
> - Add rsa sign/verify/encrypt/decrypt and modular operation
>   support
> 
> Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
> Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
> Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>

...

> --- a/drivers/crypto/openssl/rte_openssl_pmd.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd.c

...

> +	case RTE_CRYPTO_ASYM_OP_VERIFY:
> +		ret = RSA_public_decrypt(op->rsa.sign.length,
> +				op->rsa.sign.data,
> +				op->rsa.sign.data,
> +				rsa,
> +				pad);
> +
> +		OPENSSL_LOG(DEBUG,
> +				"Length of public_decrypt %d "
> +				"length of message %zd\n",
> +				ret, op->rsa.message.length);
> +
> +		if (memcmp(op->rsa.sign.data, op->rsa.message.data,
> +					op->rsa.message.length)) {
> +			OPENSSL_LOG(ERR,
> +					"RSA sign Verification failed");
> +			return -1;
> +		}

There is a compilation issue here (missing "break"?):

drivers/crypto/openssl/rte_openssl_pmd.c:1905:6: error:
this statement may fall through [-Werror=implicit-fallthrough=]
   if (memcmp(op->rsa.sign.data, op->rsa.message.data,
      ^


> +	default:
> +		/* allow ops with invalid args to be pushed to
> +		 * completion queue
> +		 */
> +		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> +		break;
> +	}

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

end of thread, other threads:[~2018-07-23 12:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-12 14:08 [PATCH v4 0/3]crypto/openssl: support asymmetric crypto Shally Verma
2018-07-12 14:08 ` [PATCH v4 1/3] crypto/openssl: add rsa and mod asym op Shally Verma
2018-07-23 12:32   ` De Lara Guarch, Pablo
2018-07-12 14:08 ` [PATCH v4 2/3] crypto/openssl: add dh and dsa " Shally Verma
2018-07-12 14:08 ` [PATCH v4 3/3] doc: add asym feature list Shally Verma

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.