DPDK patches and discussions
 help / color / mirror / Atom feed
From: Ciara Power <ciara.power@intel.com>
To: dev@dpdk.org
Cc: Ciara Power <ciara.power@intel.com>,
	kai.ji@intel.com, gmuthukrishn@marvell.com,
	sunila.sahu@caviumnetworks.com, stable@dpdk.org
Subject: [PATCH] crypto/openssl: fix asym memory leaks
Date: Fri,  3 Nov 2023 15:45:16 +0000	[thread overview]
Message-ID: <20231103154516.3456536-1-ciara.power@intel.com> (raw)

Numerous memory leaks were detected by ASAN
in the OpenSSL PMD asymmetric code path.

These are now fixed to free all variables allocated
by OpenSSL functions such as BN_bin2bn and
OSSL_PARAM_BLD_new.

Some need to exist until the op is processed,
for example the BIGNUMs associated with DSA.
The pointers for these are added to the private
asym session so they can be accessed later when calling free.

Fixes: 4c7ae22f1f83 ("crypto/openssl: update DSA routine with 3.0 EVP API")
Fixes: c794b40c9258 ("crypto/openssl: update DH routine with 3.0 EVP API")
Fixes: 3b7d638fb11f ("crypto/openssl: support asymmetric SM2")
Fixes: ac42813a0a7c ("crypto/openssl: add DH and DSA asym operations")
Fixes: d7bd42f6db19 ("crypto/openssl: update RSA routine with 3.0 EVP API")
Cc: kai.ji@intel.com
Cc: gmuthukrishn@marvell.com
Cc: sunila.sahu@caviumnetworks.com
Cc: stable@dpdk.org

Signed-off-by: Ciara Power <ciara.power@intel.com>
---
Depends-on: patch-133837 ("crypto/openssl: fix memory leaks in asym ops")
---
 drivers/crypto/openssl/openssl_pmd_private.h |  6 ++
 drivers/crypto/openssl/rte_openssl_pmd.c     | 42 +++-------
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 81 +++++++++++---------
 3 files changed, 62 insertions(+), 67 deletions(-)

diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index 1edb669dfd..334912d335 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -190,6 +190,8 @@ struct openssl_asym_session {
 		struct dh {
 			DH *dh_key;
 			uint32_t key_op;
+			BIGNUM *p;
+			BIGNUM *g;
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 			OSSL_PARAM_BLD * param_bld;
 			OSSL_PARAM_BLD *param_bld_peer;
@@ -199,6 +201,10 @@ struct openssl_asym_session {
 			DSA *dsa;
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 			OSSL_PARAM_BLD * param_bld;
+			BIGNUM *p;
+			BIGNUM *g;
+			BIGNUM *q;
+			BIGNUM *priv_key;
 #endif
 		} s;
 		struct {
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 6fb827b600..89ef63eb66 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -1958,11 +1958,8 @@ process_openssl_dsa_sign_op_evp(struct rte_crypto_op *cop,
 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);
-
+	EVP_PKEY_CTX_free(key_ctx);
+	EVP_PKEY_CTX_free(dsa_ctx);
 	EVP_PKEY_free(pkey);
 	return ret;
 }
@@ -2043,10 +2040,8 @@ process_openssl_dsa_verify_op_evp(struct rte_crypto_op *cop,
 		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);
+	EVP_PKEY_CTX_free(key_ctx);
+	EVP_PKEY_CTX_free(dsa_ctx);
 
 	BN_free(pub_key);
 	EVP_PKEY_free(pkey);
@@ -2301,17 +2296,12 @@ process_openssl_dh_op_evp(struct rte_crypto_op *cop,
 	ret = 0;
 
  err_dh:
-	if (pub_key)
-		BN_free(pub_key);
-	if (priv_key)
-		BN_free(priv_key);
+	BN_free(pub_key);
+	BN_free(priv_key);
 	if (params)
 		OSSL_PARAM_free(params);
-	if (dhpkey)
-		EVP_PKEY_free(dhpkey);
-	if (peerkey)
-		EVP_PKEY_free(peerkey);
-
+	EVP_PKEY_free(dhpkey);
+	EVP_PKEY_free(peerkey);
 	EVP_PKEY_CTX_free(dh_ctx);
 
 	return ret;
@@ -2887,18 +2877,10 @@ process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 err_sm2:
 	EVP_MD_free(check_md);
 	EVP_MD_CTX_free(md_ctx);
-
-	if (kctx)
-		EVP_PKEY_CTX_free(kctx);
-
-	if (sctx)
-		EVP_PKEY_CTX_free(sctx);
-
-	if (cctx)
-		EVP_PKEY_CTX_free(cctx);
-
-	if (pkey)
-		EVP_PKEY_free(pkey);
+	EVP_PKEY_CTX_free(kctx);
+	EVP_PKEY_CTX_free(sctx);
+	EVP_PKEY_CTX_free(cctx);
+	EVP_PKEY_free(pkey);
 
 	return ret;
 }
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index bef7671424..dedfd464c8 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -1106,18 +1106,18 @@ static int openssl_set_asym_session_parameters(
 	}
 	case RTE_CRYPTO_ASYM_XFORM_DH:
 	{
-		BIGNUM *p = NULL;
-		BIGNUM *g = NULL;
+		BIGNUM **p = &asym_session->u.dh.p;
+		BIGNUM **g = &asym_session->u.dh.g;
 
-		p = BN_bin2bn((const unsigned char *)
+		*p = BN_bin2bn((const unsigned char *)
 				xform->dh.p.data,
 				xform->dh.p.length,
-				p);
-		g = BN_bin2bn((const unsigned char *)
+				*p);
+		*g = BN_bin2bn((const unsigned char *)
 				xform->dh.g.data,
 				xform->dh.g.length,
-				g);
-		if (!p || !g)
+				*g);
+		if (!*p || !*g)
 			goto err_dh;
 
 		DH *dh = NULL;
@@ -1131,9 +1131,9 @@ static int openssl_set_asym_session_parameters(
 		if ((!OSSL_PARAM_BLD_push_utf8_string(param_bld,
 					"group", "ffdhe2048", 0))
 			|| (!OSSL_PARAM_BLD_push_BN(param_bld,
-					OSSL_PKEY_PARAM_FFC_P, p))
+					OSSL_PKEY_PARAM_FFC_P, *p))
 			|| (!OSSL_PARAM_BLD_push_BN(param_bld,
-					OSSL_PKEY_PARAM_FFC_G, g))) {
+					OSSL_PKEY_PARAM_FFC_G, *g))) {
 			OSSL_PARAM_BLD_free(param_bld);
 			goto err_dh;
 		}
@@ -1148,9 +1148,9 @@ static int openssl_set_asym_session_parameters(
 		if ((!OSSL_PARAM_BLD_push_utf8_string(param_bld_peer,
 					"group", "ffdhe2048", 0))
 			|| (!OSSL_PARAM_BLD_push_BN(param_bld_peer,
-					OSSL_PKEY_PARAM_FFC_P, p))
+					OSSL_PKEY_PARAM_FFC_P, *p))
 			|| (!OSSL_PARAM_BLD_push_BN(param_bld_peer,
-					OSSL_PKEY_PARAM_FFC_G, g))) {
+					OSSL_PKEY_PARAM_FFC_G, *g))) {
 			OSSL_PARAM_BLD_free(param_bld);
 			OSSL_PARAM_BLD_free(param_bld_peer);
 			goto err_dh;
@@ -1177,40 +1177,42 @@ static int openssl_set_asym_session_parameters(
 
 err_dh:
 		OPENSSL_LOG(ERR, " failed to set dh params\n");
-		BN_free(p);
-		BN_free(g);
+		BN_free(*p);
+		BN_free(*g);
 		return -1;
 	}
 	case RTE_CRYPTO_ASYM_XFORM_DSA:
 	{
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
-		BIGNUM *p = NULL, *g = NULL;
-		BIGNUM *q = NULL, *priv_key = NULL;
+		BIGNUM **p = &asym_session->u.s.p;
+		BIGNUM **g = &asym_session->u.s.g;
+		BIGNUM **q = &asym_session->u.s.q;
+		BIGNUM **priv_key = &asym_session->u.s.priv_key;
 		BIGNUM *pub_key = NULL;
 		OSSL_PARAM_BLD *param_bld = NULL;
 
-		p = BN_bin2bn((const unsigned char *)
+		*p = BN_bin2bn((const unsigned char *)
 				xform->dsa.p.data,
 				xform->dsa.p.length,
-				p);
+				*p);
 
-		g = BN_bin2bn((const unsigned char *)
+		*g = BN_bin2bn((const unsigned char *)
 				xform->dsa.g.data,
 				xform->dsa.g.length,
-				g);
+				*g);
 
-		q = BN_bin2bn((const unsigned char *)
+		*q = BN_bin2bn((const unsigned char *)
 				xform->dsa.q.data,
 				xform->dsa.q.length,
-				q);
-		if (!p || !q || !g)
+				*q);
+		if (!*p || !*q || !*g)
 			goto err_dsa;
 
-		priv_key = BN_bin2bn((const unsigned char *)
+		*priv_key = BN_bin2bn((const unsigned char *)
 				xform->dsa.x.data,
 				xform->dsa.x.length,
-				priv_key);
-		if (priv_key == NULL)
+				*priv_key);
+		if (*priv_key == NULL)
 			goto err_dsa;
 
 		param_bld = OSSL_PARAM_BLD_new();
@@ -1219,10 +1221,10 @@ static int openssl_set_asym_session_parameters(
 			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)) {
+		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;
@@ -1286,17 +1288,17 @@ static int openssl_set_asym_session_parameters(
 		if (ret) {
 			DSA_free(dsa);
 			OPENSSL_LOG(ERR, "Failed to set keys\n");
-			return -1;
+			goto err_dsa;
 		}
 		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);
-		BN_free(g);
-		BN_free(priv_key);
+		BN_free(*p);
+		BN_free(*q);
+		BN_free(*g);
+		BN_free(*priv_key);
 		BN_free(pub_key);
 		return -1;
 	}
@@ -1307,7 +1309,7 @@ static int openssl_set_asym_session_parameters(
 		OSSL_PARAM_BLD *param_bld = NULL;
 		OSSL_PARAM *params = NULL;
 		BIGNUM *pkey_bn = NULL;
-		uint8_t pubkey[64];
+		uint8_t pubkey[65];
 		size_t len = 0;
 		int ret = -1;
 
@@ -1434,8 +1436,7 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 	switch (sess->xfrm_type) {
 	case RTE_CRYPTO_ASYM_XFORM_RSA:
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
-		if (sess->u.r.ctx)
-			EVP_PKEY_CTX_free(sess->u.r.ctx);
+		EVP_PKEY_CTX_free(sess->u.r.ctx);
 #else
 		if (sess->u.r.rsa)
 			RSA_free(sess->u.r.rsa);
@@ -1463,11 +1464,17 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 		if (sess->u.dh.dh_key)
 			DH_free(sess->u.dh.dh_key);
 #endif
+		BN_clear_free(sess->u.dh.p);
+		BN_clear_free(sess->u.dh.g);
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_DSA:
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 		OSSL_PARAM_BLD_free(sess->u.s.param_bld);
 		sess->u.s.param_bld = NULL;
+		BN_clear_free(sess->u.s.p);
+		BN_clear_free(sess->u.s.q);
+		BN_clear_free(sess->u.s.g);
+		BN_clear_free(sess->u.s.priv_key);
 #else
 		if (sess->u.s.dsa)
 			DSA_free(sess->u.s.dsa);
-- 
2.34.1


             reply	other threads:[~2023-11-03 15:45 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-03 15:45 Ciara Power [this message]
2023-11-06 23:14 ` Ji, Kai
2023-11-13  6:24 ` [EXT] " Akhil Goyal
2023-11-13 13:07 ` [PATCH v2] " Ciara Power
2023-11-13 13:16 ` [PATCH v3] " Ciara Power

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231103154516.3456536-1-ciara.power@intel.com \
    --to=ciara.power@intel.com \
    --cc=dev@dpdk.org \
    --cc=gmuthukrishn@marvell.com \
    --cc=kai.ji@intel.com \
    --cc=stable@dpdk.org \
    --cc=sunila.sahu@caviumnetworks.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).