summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2020-06-26 10:21:26 +0200
committerDaiki Ueno <ueno@gnu.org>2020-06-27 12:57:09 +0200
commit3f4532862bf9140976d970ab14e102cede61d1c7 (patch)
treee7f66327cb9a9dd1463b24a3446cb673b14a6a1f /lib
parent481e48f3236be42ff1fcb96f96c4efcbb2b69242 (diff)
downloadgnutls-tmp-sp800-56ar3.tar.gz
dhe: check if DH params in SKE match the FIPS approved algorithmstmp-sp800-56ar3
SP800-56A rev. 3 restricts the FIPS compliant clients to use only approved DH parameters, defined in RFC 7919 and RFC 3526. This adds a check in the handling of ServerKeyExchange if DHE is negotiated. Signed-off-by: Daiki Ueno <ueno@gnu.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/auth/dh_common.c8
-rw-r--r--lib/dh-primes.c34
-rw-r--r--lib/dh.h6
3 files changed, 48 insertions, 0 deletions
diff --git a/lib/auth/dh_common.c b/lib/auth/dh_common.c
index 19c205bbe8..252eea0cb4 100644
--- a/lib/auth/dh_common.c
+++ b/lib/auth/dh_common.c
@@ -257,6 +257,14 @@ _gnutls_proc_dh_common_server_kx(gnutls_session_t session,
}
}
+#ifdef ENABLE_FIPS140
+ if (gnutls_fips140_mode_enabled() &&
+ !_gnutls_dh_prime_is_fips_approved(data_p, n_p, data_g, n_g)) {
+ gnutls_assert();
+ return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
+ }
+#endif
+
if (_gnutls_mpi_init_scan_nz(&session->key.proto.tls12.dh.params.params[DH_G], data_g, _n_g) != 0) {
gnutls_assert();
return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
diff --git a/lib/dh-primes.c b/lib/dh-primes.c
index 5d2dce0fb6..a43a8e5dea 100644
--- a/lib/dh-primes.c
+++ b/lib/dh-primes.c
@@ -1893,4 +1893,38 @@ const gnutls_datum_t gnutls_modp_8192_group_generator = {
};
const unsigned int gnutls_modp_8192_key_bits = 512;
+unsigned
+_gnutls_dh_prime_is_fips_approved(const uint8_t *prime,
+ size_t prime_size,
+ const uint8_t *generator,
+ size_t generator_size)
+{
+ static const struct {
+ const gnutls_datum_t *prime;
+ const gnutls_datum_t *generator;
+ } primes[] = {
+ { &gnutls_ffdhe_8192_group_prime, &gnutls_ffdhe_8192_group_generator },
+ { &gnutls_ffdhe_6144_group_prime, &gnutls_ffdhe_6144_group_generator },
+ { &gnutls_ffdhe_4096_group_prime, &gnutls_ffdhe_4096_group_generator },
+ { &gnutls_ffdhe_3072_group_prime, &gnutls_ffdhe_3072_group_generator },
+ { &gnutls_ffdhe_2048_group_prime, &gnutls_ffdhe_2048_group_generator },
+ { &gnutls_modp_8192_group_prime, &gnutls_modp_8192_group_generator },
+ { &gnutls_modp_6144_group_prime, &gnutls_modp_6144_group_generator },
+ { &gnutls_modp_4096_group_prime, &gnutls_modp_4096_group_generator },
+ { &gnutls_modp_3072_group_prime, &gnutls_modp_3072_group_generator },
+ { &gnutls_modp_2048_group_prime, &gnutls_modp_2048_group_generator },
+ };
+ size_t i;
+
+ for (i = 0; i < sizeof(primes) / sizeof(primes[0]); i++) {
+ if (primes[i].prime->size == prime_size &&
+ memcmp(primes[i].prime->data, prime, primes[i].prime->size) == 0 &&
+ primes[i].generator->size == generator_size &&
+ memcmp(primes[i].generator->data, generator, primes[i].generator->size) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
#endif
diff --git a/lib/dh.h b/lib/dh.h
index a64a4eb5e8..6724519479 100644
--- a/lib/dh.h
+++ b/lib/dh.h
@@ -60,4 +60,10 @@ extern const gnutls_datum_t gnutls_modp_2048_group_q;
extern const gnutls_datum_t gnutls_modp_2048_group_generator;
extern const unsigned int gnutls_modp_2048_key_bits;
+unsigned
+_gnutls_dh_prime_is_fips_approved(const uint8_t *prime,
+ size_t prime_size,
+ const uint8_t *generator,
+ size_t generator_size);
+
#endif /* GNUTLS_LIB_DH_H */