File openssl-fips-DH-Pair-wise-Consistency.patch of Package openssl-1_1.32465
---
crypto/dh/dh_check.c | 35 +++++++++++++++++++++++++++++++++++
crypto/dh/dh_key.c | 7 +++++++
crypto/dh/dh_local.h | 3 +++
3 files changed, 45 insertions(+)
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -263,3 +263,38 @@ int dh_check_pub_key_full(const DH *dh,
return dh_check_pub_key_int(dh, q, pub_key, ret);
}
+/*
+ * See SP800-56Ar3 Section 5.6.2.1.4 : Owner Assurance of Pair-wise Consistency.
+ */
+int dh_check_pairwise(const DH *dh)
+{
+ int ret = 0;
+ BN_CTX *ctx = NULL;
+ BN_MONT_CTX *mont = NULL;
+ BIGNUM *pub_key = NULL;
+
+ if (dh->p == NULL
+ || dh->g == NULL
+ || dh->priv_key == NULL
+ || dh->pub_key == NULL)
+ return 0;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+
+ pub_key = BN_new();
+ if (pub_key == NULL)
+ goto err;
+
+ /* recalculate the public key = (g ^ priv) mod p */
+ if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, dh->priv_key, dh->p, ctx, mont))
+ goto err;
+ /* check it matches the existing pubic_key */
+ ret = BN_cmp(pub_key, dh->pub_key) == 0;
+err:
+ BN_free(pub_key);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -224,6 +224,13 @@ static int generate_key(DH *dh)
dh->pub_key = pub_key;
dh->priv_key = priv_key;
+ if (FIPS_mode()) {
+ if (!dh_check_pairwise(dh)) {
+ dh->pub_key = dh->priv_key = NULL;
+ DHerr(DH_F_GENERATE_KEY, DH_R_INVALID_PUBKEY);
+ goto err;
+ }
+ }
ok = 1;
err:
if (ok != 1)
--- a/crypto/dh/dh_local.h
+++ b/crypto/dh/dh_local.h
@@ -65,3 +65,6 @@ int dh_get_known_q(const DH *dh, BIGNUM
/* FIPS mode only check which requires nid set and looks up q based on it. */
int dh_check_pub_key_full(const DH *dh, const BIGNUM *pub_key, int *ret);
+/* FIPS mode only check pairwise consistency of DH public key. */
+int dh_check_pairwise(const DH *dh);
+