aboutsummaryrefslogtreecommitdiff
path: root/providers/implementations/exchange
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-08-29 12:54:00 +1000
committerMatt Caswell <matt@openssl.org>2020-09-18 14:20:38 +0100
commitb8237707d483719e527313cc007c09e96ef7d778 (patch)
treeb257c8153b39dc86a33351b6c09c927c1669c87e /providers/implementations/exchange
parent0645110ebdf0192d20831e00e45d308e719ff0f1 (diff)
downloadopenssl-b8237707d483719e527313cc007c09e96ef7d778.zip
openssl-b8237707d483719e527313cc007c09e96ef7d778.tar.gz
openssl-b8237707d483719e527313cc007c09e96ef7d778.tar.bz2
Add fips checks for dh key agreement
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/12745)
Diffstat (limited to 'providers/implementations/exchange')
-rw-r--r--providers/implementations/exchange/build.info5
-rw-r--r--providers/implementations/exchange/dh_exch.c47
2 files changed, 47 insertions, 5 deletions
diff --git a/providers/implementations/exchange/build.info b/providers/implementations/exchange/build.info
index 92932b9..3ae8630 100644
--- a/providers/implementations/exchange/build.info
+++ b/providers/implementations/exchange/build.info
@@ -1,13 +1,12 @@
# We make separate GOAL variables for each algorithm, to make it easy to
# switch each to the Legacy provider when needed.
-$DH_GOAL=../../libimplementations.a
$ECX_GOAL=../../libimplementations.a
-$ECDH_GOAL=../../libimplementations.a
$KDF_GOAL=../../libimplementations.a
IF[{- !$disabled{dh} -}]
- SOURCE[$DH_GOAL]=dh_exch.c
+ SOURCE[../../libfips.a]=dh_exch.c
+ SOURCE[../../libnonfips.a]=dh_exch.c
ENDIF
IF[{- !$disabled{asm} -}]
diff --git a/providers/implementations/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c
index fad38ec..a8a0d43 100644
--- a/providers/implementations/exchange/dh_exch.c
+++ b/providers/implementations/exchange/dh_exch.c
@@ -23,6 +23,7 @@
#include "prov/providercommon.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
+#include "prov/provider_util.h"
#include "crypto/dh.h"
static OSSL_FUNC_keyexch_newctx_fn dh_newctx;
@@ -91,6 +92,43 @@ static void *dh_newctx(void *provctx)
return pdhctx;
}
+/*
+ * For DH key agreement refer to SP800-56A
+ * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf
+ * "Section 5.5.1.1FFC Domain Parameter Selection/Generation" and
+ * "Appendix D" FFC Safe-prime Groups
+ */
+static int dh_check_key(const DH *dh)
+{
+#ifdef FIPS_MODULE
+ size_t L, N;
+ const BIGNUM *p, *q;
+
+ if (dh == NULL)
+ return 0;
+
+ p = DH_get0_p(dh);
+ q = DH_get0_q(dh);
+ if (p == NULL || q == NULL)
+ return 0;
+
+ L = BN_num_bits(p);
+ if (L < 2048)
+ return 0;
+
+ /* If it is a safe prime group then it is ok */
+ if (DH_get_nid(dh))
+ return 1;
+
+ /* If not then it must be FFC, which only allows certain sizes. */
+ N = BN_num_bits(q);
+
+ return (L == 2048 && (N == 224 || N == 256));
+#else
+ return 1;
+#endif
+}
+
static int dh_init(void *vpdhctx, void *vdh)
{
PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
@@ -103,7 +141,7 @@ static int dh_init(void *vpdhctx, void *vdh)
DH_free(pdhctx->dh);
pdhctx->dh = vdh;
pdhctx->kdf_type = PROV_DH_KDF_NONE;
- return 1;
+ return dh_check_key(vdh);
}
static int dh_set_peer(void *vpdhctx, void *vdh)
@@ -320,7 +358,12 @@ static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
EVP_MD_free(pdhctx->kdf_md);
pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops);
-
+#ifdef FIPS_MODULE
+ if (!ossl_prov_digest_get_approved_nid(pdhctx->kdf_md, 1)) {
+ EVP_MD_free(pdhctx->kdf_md);
+ pdhctx->kdf_md = NULL;
+ }
+#endif
if (pdhctx->kdf_md == NULL)
return 0;
}