summaryrefslogtreecommitdiffstats
path: root/providers/implementations/exchange
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2021-04-12 09:06:24 +1000
committerShane Lontis <shane.lontis@oracle.com>2021-04-14 16:01:13 +1000
commit46eee7104d77f9d303e06a398febdc60fd014d33 (patch)
treed826be79497504683f836f4c6a9d7c0b6a91f3d0 /providers/implementations/exchange
parent0d5bbaaae2c65ddf7a30596b61617304e0950d9c (diff)
Add domain parameter match check for DH and ECDH key exchange.
Fixes #14808 Validation checks were moved into EVP_PKEY_derive_set_peer() which broke an external negative test. Originally the old code was semi working by checking the peers public key was in the range of other parties p. It was not actually ever checking that the domain parameters were consistent between the 2 parties. It now checks the parameters match as well as validating the peers public key. Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14823)
Diffstat (limited to 'providers/implementations/exchange')
-rw-r--r--providers/implementations/exchange/dh_exch.c16
-rw-r--r--providers/implementations/exchange/ecdh_exch.c27
2 files changed, 42 insertions, 1 deletions
diff --git a/providers/implementations/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c
index 87eb17dd60..0ecc6c7a4c 100644
--- a/providers/implementations/exchange/dh_exch.c
+++ b/providers/implementations/exchange/dh_exch.c
@@ -108,6 +108,21 @@ static int dh_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[])
return dh_set_ctx_params(pdhctx, params) && ossl_dh_check_key(vdh);
}
+/* The 2 parties must share the same domain parameters */
+static int dh_match_params(DH *priv, DH *peer)
+{
+ int ret;
+ FFC_PARAMS *dhparams_priv = ossl_dh_get0_params(priv);
+ FFC_PARAMS *dhparams_peer = ossl_dh_get0_params(peer);
+
+ ret = dhparams_priv != NULL
+ && dhparams_peer != NULL
+ && ossl_ffc_params_cmp(dhparams_priv, dhparams_peer, 1);
+ if (!ret)
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS);
+ return ret;
+}
+
static int dh_set_peer(void *vpdhctx, void *vdh)
{
PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
@@ -115,6 +130,7 @@ static int dh_set_peer(void *vpdhctx, void *vdh)
if (!ossl_prov_is_running()
|| pdhctx == NULL
|| vdh == NULL
+ || !dh_match_params(vdh, pdhctx->dh)
|| !DH_up_ref(vdh))
return 0;
DH_free(pdhctx->dhpeer);
diff --git a/providers/implementations/exchange/ecdh_exch.c b/providers/implementations/exchange/ecdh_exch.c
index 63bcf4e50c..ba2b493a76 100644
--- a/providers/implementations/exchange/ecdh_exch.c
+++ b/providers/implementations/exchange/ecdh_exch.c
@@ -117,6 +117,28 @@ int ecdh_init(void *vpecdhctx, void *vecdh, const OSSL_PARAM params[])
}
static
+int ecdh_match_params(const EC_KEY *priv, const EC_KEY *peer)
+{
+ int ret;
+ BN_CTX *ctx = NULL;
+ const EC_GROUP *group_priv = EC_KEY_get0_group(priv);
+ const EC_GROUP *group_peer = EC_KEY_get0_group(peer);
+
+ ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(priv));
+ if (ctx == NULL) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ret = group_priv != NULL
+ && group_peer != NULL
+ && EC_GROUP_cmp(group_priv, group_peer, ctx) == 0;
+ if (!ret)
+ ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
+static
int ecdh_set_peer(void *vpecdhctx, void *vecdh)
{
PROV_ECDH_CTX *pecdhctx = (PROV_ECDH_CTX *)vpecdhctx;
@@ -124,11 +146,14 @@ int ecdh_set_peer(void *vpecdhctx, void *vecdh)
if (!ossl_prov_is_running()
|| pecdhctx == NULL
|| vecdh == NULL
+ || !ecdh_match_params(pecdhctx->k, vecdh)
+ || !ossl_ec_check_key(vecdh, 1)
|| !EC_KEY_up_ref(vecdh))
return 0;
+
EC_KEY_free(pecdhctx->peerk);
pecdhctx->peerk = vecdh;
- return ossl_ec_check_key(vecdh, 1);
+ return 1;
}
static