Check the DH modulus bit length
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Fri, 6 Sep 2019 21:38:49 +0000 (23:38 +0200)
committerBernd Edlinger <bernd.edlinger@hotmail.de>
Mon, 9 Sep 2019 12:43:57 +0000 (14:43 +0200)
The check was missing in DH_check and DH_check_params.

[extended tests]

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9796)

crypto/dh/dh_check.c
doc/man3/DH_generate_parameters.pod
include/openssl/dh.h
test/dhtest.c

index aff7e3718138efbb31680cfb1fe7881cd8e56c6d..373110d263b0cd6a2c3d00f9591517cb724b9a56 100644 (file)
@@ -31,6 +31,10 @@ int DH_check_params_ex(const DH *dh)
         DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_CHECK_P_NOT_PRIME);
     if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0)
         DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_NOT_SUITABLE_GENERATOR);
+    if ((errflags & DH_MODULUS_TOO_SMALL) != 0)
+        DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_MODULUS_TOO_SMALL);
+    if ((errflags & DH_MODULUS_TOO_LARGE) != 0)
+        DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_MODULUS_TOO_LARGE);
 
     return errflags == 0;
 }
@@ -58,6 +62,10 @@ int DH_check_params(const DH *dh, int *ret)
         goto err;
     if (BN_cmp(dh->g, tmp) >= 0)
         *ret |= DH_NOT_SUITABLE_GENERATOR;
+    if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS)
+        *ret |= DH_MODULUS_TOO_SMALL;
+    if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS)
+        *ret |= DH_MODULUS_TOO_LARGE;
 
     ok = 1;
  err:
@@ -91,6 +99,10 @@ int DH_check_ex(const DH *dh)
         DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_PRIME);
     if ((errflags & DH_CHECK_P_NOT_SAFE_PRIME) != 0)
         DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_SAFE_PRIME);
+    if ((errflags & DH_MODULUS_TOO_SMALL) != 0)
+        DHerr(DH_F_DH_CHECK_EX, DH_R_MODULUS_TOO_SMALL);
+    if ((errflags & DH_MODULUS_TOO_LARGE) != 0)
+        DHerr(DH_F_DH_CHECK_EX, DH_R_MODULUS_TOO_LARGE);
 
     return errflags == 0;
 }
index a1541caf686998278d6099aa86222b475b929eeb..4908dcf515b2bb34cdde663a982fb8f9f15d88f1 100644 (file)
@@ -73,6 +73,14 @@ The generator B<g> is not suitable.
 Note that the lack of this bit doesn't guarantee that B<g> is
 suitable, unless B<p> is known to be a strong prime.
 
+=item DH_MODULUS_TOO_SMALL
+
+The modulus is too small.
+
+=item DH_MODULUS_TOO_LARGE
+
+The modulus is too large.
+
 =back
 
 DH_check() confirms that the Diffie-Hellman parameters B<dh> are valid. The
@@ -141,7 +149,7 @@ DH_generate_parameters_ex() instead.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 7c509b4c0f5489b1908a76cc29ddf751f7d0fbb1..4e117a0d038b6dce3fb3f47de1aa1635020c99e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -76,6 +76,8 @@ DECLARE_ASN1_ITEM(DHparams)
 # define DH_CHECK_Q_NOT_PRIME            0x10
 # define DH_CHECK_INVALID_Q_VALUE        0x20
 # define DH_CHECK_INVALID_J_VALUE        0x40
+# define DH_MODULUS_TOO_SMALL            0x80
+# define DH_MODULUS_TOO_LARGE            0x100
 
 /* DH_check_pub_key error codes */
 # define DH_CHECK_PUBKEY_TOO_SMALL       0x01
index 662a4f32eb4841a7db8306f0f525c1157a39f0c1..e8a91f17f88e0088cfde2eed735234de49c4f74e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -63,14 +63,19 @@ static int dh_test(void)
         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
         goto err1;
 
+    /* check fails, because p is way too small */
     if (!DH_check(dh, &i))
         goto err2;
+    i ^= DH_MODULUS_TOO_SMALL;
     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
-            || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
-            || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
+            || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
+            || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
+            || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
+            || !TEST_false(i & DH_MODULUS_TOO_SMALL)
+            || !TEST_false(i & DH_MODULUS_TOO_LARGE)
             || !TEST_false(i))
         goto err2;
 
@@ -130,6 +135,11 @@ static int dh_test(void)
             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
+            || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
+            || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
+            || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
+            || !TEST_false(i & DH_MODULUS_TOO_SMALL)
+            || !TEST_false(i & DH_MODULUS_TOO_LARGE)
             || !TEST_false(i))
         goto err3;