From patchwork Mon Nov 13 13:16:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Power, Ciara" X-Patchwork-Id: 134160 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7DFF54331B; Mon, 13 Nov 2023 14:16:31 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id ED673402F0; Mon, 13 Nov 2023 14:16:30 +0100 (CET) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id D3D5A402AE; Mon, 13 Nov 2023 14:16:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1699881389; x=1731417389; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sI+LTcbzAJUwrTlGBKYSA4XIKmCa0rGAJ6vzGEjjOzs=; b=ZgbfOlZbTemeg5fo2NHnOJqNTRduoa+yUYHYNE7s1hiVfmNKWPaVf7vV hRbTMizx6IqTYJ6jq4xToLRMSC6XgkNopfWDEPUTyK/bixDkR7lo8tJMG Bt5cSuSxviMA4HL4Y+yptMKiOyR7HrNwxjWZH4tImT1WpuG2KrwKFm2gR HhSzLXdulRwEbDp3n7Bgbfde2WJD2iKLEaH03Lrc8nw9bpBEgRnqzjhE7 x2aT2IAPRlbdluOIbCLpjEfwK5Z3aOgHuc8mosZG+p7vIqqi+KVNTLsdg 0PG52yMddHkxmDnkSUjjvklVceFDWzoNXbGgphM1umpoUG8+ru1ebDrbB A==; X-IronPort-AV: E=McAfee;i="6600,9927,10893"; a="390237885" X-IronPort-AV: E=Sophos;i="6.03,299,1694761200"; d="scan'208";a="390237885" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Nov 2023 05:16:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10893"; a="793436803" X-IronPort-AV: E=Sophos;i="6.03,299,1694761200"; d="scan'208";a="793436803" Received: from silpixa00400355.ir.intel.com (HELO silpixa00400355.ger.corp.intel.com) ([10.237.222.80]) by orsmga008.jf.intel.com with ESMTP; 13 Nov 2023 05:16:25 -0800 From: Ciara Power To: dev@dpdk.org Cc: gakhil@marvell.com, Ciara Power , kai.ji@intel.com, gmuthukrishn@marvell.com, sunila.sahu@caviumnetworks.com, stable@dpdk.org Subject: [PATCH v3] crypto/openssl: fix asym memory leaks Date: Mon, 13 Nov 2023 13:16:23 +0000 Message-Id: <20231113131623.1485483-1-ciara.power@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231103154516.3456536-1-ciara.power@intel.com> References: <20231103154516.3456536-1-ciara.power@intel.com> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org 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. Some cases need to be treated differently if OpenSSL < 3.0. It has slightly different handling of memory, as functions such as RSA_set0_key() take over memory management of values, so the caller should not free the values. 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") Fixes: ad149f93093e ("crypto/openssl: fix memory leaks in asym ops") Cc: kai.ji@intel.com Cc: gmuthukrishn@marvell.com Cc: sunila.sahu@caviumnetworks.com Cc: stable@dpdk.org Signed-off-by: Ciara Power Acked-by: Kai Ji --- v2: Added a few more fixes for OpenSSL < 3.0 cases. v3: Fixed long line. --- drivers/crypto/openssl/openssl_pmd_private.h | 6 ++ drivers/crypto/openssl/rte_openssl_pmd.c | 1 + drivers/crypto/openssl/rte_openssl_pmd_ops.c | 99 +++++++++++++------- 3 files changed, 74 insertions(+), 32 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 9d463520ff..e8cb09defc 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -1960,6 +1960,7 @@ process_openssl_dsa_sign_op_evp(struct rte_crypto_op *cop, OSSL_PARAM_free(params); EVP_PKEY_CTX_free(key_ctx); EVP_PKEY_CTX_free(dsa_ctx); + 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 db5579bdb1..b16baaa08f 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c @@ -1032,7 +1032,7 @@ static int openssl_set_asym_session_parameters( } asym_session->u.r.rsa = rsa; asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_RSA; - ret = 0; + break; #endif err_rsa: BN_clear_free(n); @@ -1106,22 +1106,22 @@ static int openssl_set_asym_session_parameters( } case RTE_CRYPTO_ASYM_XFORM_DH: { - BIGNUM *p = NULL; - BIGNUM *g = NULL; + DH *dh = NULL; +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + 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; -#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) OSSL_PARAM_BLD *param_bld = NULL; param_bld = OSSL_PARAM_BLD_new(); if (!param_bld) { @@ -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; @@ -1159,6 +1159,20 @@ static int openssl_set_asym_session_parameters( asym_session->u.dh.param_bld = param_bld; asym_session->u.dh.param_bld_peer = param_bld_peer; #else + 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_new(); if (dh == NULL) { OPENSSL_LOG(ERR, @@ -1177,40 +1191,47 @@ static int openssl_set_asym_session_parameters( err_dh: OPENSSL_LOG(ERR, " failed to set dh params\n"); +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + BN_free(*p); + BN_free(*g); +#else BN_free(p); BN_free(g); +#endif 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 +1240,11 @@ 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 +1308,24 @@ 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: +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + BN_free(*p); + BN_free(*q); + BN_free(*g); + BN_free(*priv_key); +#else BN_free(p); BN_free(q); BN_free(g); BN_free(priv_key); +#endif BN_free(pub_key); return -1; } @@ -1307,7 +1336,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; @@ -1462,11 +1491,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);