diff options
author | Simo Sorce <simo@redhat.com> | 2019-05-03 12:32:56 -0400 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2019-05-23 11:35:12 +0200 |
commit | 2555412f8982ec0a1bbbf6b3c10a0330fe848820 (patch) | |
tree | b59ab064e03f347b168c2e5c1e374f68df51f048 /lib/nettle | |
parent | 431307e1b3da3c782961623c7b19cb7c7fbf84b8 (diff) | |
download | gnutls-2555412f8982ec0a1bbbf6b3c10a0330fe848820.tar.gz |
Add Full Public Key Check for DH
This is for NIST SP800-56A requirements and FIPS CAVS testing.
GnuTLS never passes in a non-empty Q for normal operations, but tests will
and if Q is passed in it needs to be checked.
Signed-off-by: Simo Sorce <simo@redhat.com>
Diffstat (limited to 'lib/nettle')
-rw-r--r-- | lib/nettle/pk.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 9aa51660d8..1874bca54f 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -240,15 +240,16 @@ static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, switch (algo) { case GNUTLS_PK_DH: { - bigint_t f, x, prime; - bigint_t k = NULL, ff = NULL; + bigint_t f, x, q, prime; + bigint_t k = NULL, ff = NULL, r = NULL; unsigned int bits; f = pub->params[DH_Y]; x = priv->params[DH_X]; + q = priv->params[DH_Q]; prime = priv->params[DH_P]; - ret = _gnutls_mpi_init_multi(&k, &ff, NULL); + ret = _gnutls_mpi_init_multi(&k, &ff, &r, NULL); if (ret < 0) return gnutls_assert_val(ret); @@ -268,6 +269,21 @@ static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, goto dh_cleanup; } + /* if we have Q check that y ^ q mod p == 1 */ + if (q != NULL) { + ret = _gnutls_mpi_powm(r, f, q, prime); + if (ret < 0) { + gnutls_assert(); + goto dh_cleanup; + } + ret = _gnutls_mpi_cmp_ui(r, 1); + if (ret != 0) { + gnutls_assert(); + ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; + goto dh_cleanup; + } + } + /* prevent denial of service */ bits = _gnutls_mpi_get_nbits(prime); if (bits == 0 || bits > MAX_DH_BITS) { @@ -298,6 +314,7 @@ static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, ret = 0; dh_cleanup: + _gnutls_mpi_release(&r); _gnutls_mpi_release(&ff); zrelease_temp_mpi_key(&k); if (ret < 0) |