Enforce a minimum DH modulus size of 512 bits
[extended tests] Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9437)
This commit is contained in:
parent
8b84b075ff
commit
6de1fe9086
9 changed files with 36 additions and 20 deletions
3
CHANGES
3
CHANGES
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
||||||
|
|
||||||
|
*) Enforce a minimum DH modulus size of 512 bits.
|
||||||
|
[Bernd Edlinger]
|
||||||
|
|
||||||
*) Changed DH parameters to generate the order q subgroup instead of 2q.
|
*) Changed DH parameters to generate the order q subgroup instead of 2q.
|
||||||
Previously generated DH parameters are still accepted by DH_check
|
Previously generated DH parameters are still accepted by DH_check
|
||||||
but DH_generate_key works around that by clearing bit 0 of the
|
but DH_generate_key works around that by clearing bit 0 of the
|
||||||
|
|
|
@ -41,6 +41,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = {
|
||||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_KEYS_NOT_SET), "keys not set"},
|
{ERR_PACK(ERR_LIB_DH, 0, DH_R_KEYS_NOT_SET), "keys not set"},
|
||||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"},
|
{ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"},
|
||||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large"},
|
{ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large"},
|
||||||
|
{ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_SMALL), "modulus too small"},
|
||||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR),
|
{ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR),
|
||||||
"not suitable generator"},
|
"not suitable generator"},
|
||||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set"},
|
{ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set"},
|
||||||
|
|
|
@ -61,6 +61,16 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
|
||||||
int g, ok = -1;
|
int g, ok = -1;
|
||||||
BN_CTX *ctx = NULL;
|
BN_CTX *ctx = NULL;
|
||||||
|
|
||||||
|
if (prime_len > OPENSSL_DH_MAX_MODULUS_BITS) {
|
||||||
|
DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_MODULUS_TOO_LARGE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prime_len < DH_MIN_MODULUS_BITS) {
|
||||||
|
DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_MODULUS_TOO_SMALL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = BN_CTX_new();
|
ctx = BN_CTX_new();
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -87,6 +87,11 @@ static int generate_key(DH *dh)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) {
|
||||||
|
DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_SMALL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = BN_CTX_new();
|
ctx = BN_CTX_new();
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -181,6 +186,11 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) {
|
||||||
|
DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_SMALL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = BN_CTX_new();
|
ctx = BN_CTX_new();
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
#include "internal/refcount.h"
|
#include "internal/refcount.h"
|
||||||
|
|
||||||
|
#define DH_MIN_MODULUS_BITS 512
|
||||||
|
|
||||||
struct dh_st {
|
struct dh_st {
|
||||||
/*
|
/*
|
||||||
* This first argument is used to pick up errors when a DH is passed
|
* This first argument is used to pick up errors when a DH is passed
|
||||||
|
|
|
@ -2276,6 +2276,7 @@ DH_R_KDF_PARAMETER_ERROR:112:kdf parameter error
|
||||||
DH_R_KEYS_NOT_SET:108:keys not set
|
DH_R_KEYS_NOT_SET:108:keys not set
|
||||||
DH_R_MISSING_PUBKEY:125:missing pubkey
|
DH_R_MISSING_PUBKEY:125:missing pubkey
|
||||||
DH_R_MODULUS_TOO_LARGE:103:modulus too large
|
DH_R_MODULUS_TOO_LARGE:103:modulus too large
|
||||||
|
DH_R_MODULUS_TOO_SMALL:126:modulus too small
|
||||||
DH_R_NOT_SUITABLE_GENERATOR:120:not suitable generator
|
DH_R_NOT_SUITABLE_GENERATOR:120:not suitable generator
|
||||||
DH_R_NO_PARAMETERS_SET:107:no parameters set
|
DH_R_NO_PARAMETERS_SET:107:no parameters set
|
||||||
DH_R_NO_PRIVATE_VALUE:100:no private value
|
DH_R_NO_PRIVATE_VALUE:100:no private value
|
||||||
|
|
|
@ -103,8 +103,9 @@ This can be used with a subsequent B<-rand> flag.
|
||||||
This option specifies that a parameter set should be generated of size
|
This option specifies that a parameter set should be generated of size
|
||||||
I<numbits>. It must be the last option. If this option is present then
|
I<numbits>. It must be the last option. If this option is present then
|
||||||
the input file is ignored and parameters are generated instead. If
|
the input file is ignored and parameters are generated instead. If
|
||||||
this option is not present but a generator (B<-2> or B<-5>) is
|
this option is not present but a generator (B<-2>, B<-3> or B<-5>) is
|
||||||
present, parameters are generated with a default length of 2048 bits.
|
present, parameters are generated with a default length of 2048 bits.
|
||||||
|
The minimim length is 512 bits. The maximum length is 10000 bits.
|
||||||
|
|
||||||
=item B<-noout>
|
=item B<-noout>
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ int ERR_load_DH_strings(void);
|
||||||
# define DH_R_KEYS_NOT_SET 108
|
# define DH_R_KEYS_NOT_SET 108
|
||||||
# define DH_R_MISSING_PUBKEY 125
|
# define DH_R_MISSING_PUBKEY 125
|
||||||
# define DH_R_MODULUS_TOO_LARGE 103
|
# define DH_R_MODULUS_TOO_LARGE 103
|
||||||
|
# define DH_R_MODULUS_TOO_SMALL 126
|
||||||
# define DH_R_NOT_SUITABLE_GENERATOR 120
|
# define DH_R_NOT_SUITABLE_GENERATOR 120
|
||||||
# define DH_R_NO_PARAMETERS_SET 107
|
# define DH_R_NO_PARAMETERS_SET 107
|
||||||
# define DH_R_NO_PRIVATE_VALUE 100
|
# define DH_R_NO_PRIVATE_VALUE 100
|
||||||
|
|
|
@ -103,25 +103,12 @@ static int dh_test(void)
|
||||||
|| !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
|
|| !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
|
||||||
goto err3;
|
goto err3;
|
||||||
|
|
||||||
/* now generate a key pair ... */
|
/* now generate a key pair (expect failure since modulus is too small) */
|
||||||
if (!DH_generate_key(dh))
|
if (!TEST_false(DH_generate_key(dh)))
|
||||||
goto err3;
|
goto err3;
|
||||||
|
|
||||||
/* ... and check whether the private key was reused: */
|
/* We'll have a stale error on the queue from the above test so clear it */
|
||||||
|
ERR_clear_error();
|
||||||
/* test it with the combined getter for pub_key and priv_key */
|
|
||||||
DH_get0_key(dh, &pub_key2, &priv_key2);
|
|
||||||
if (!TEST_ptr(pub_key2)
|
|
||||||
|| !TEST_ptr_eq(priv_key2, priv_key))
|
|
||||||
goto err3;
|
|
||||||
|
|
||||||
/* test it the simple getters for pub_key and priv_key */
|
|
||||||
if (!TEST_ptr_eq(DH_get0_pub_key(dh), pub_key2)
|
|
||||||
|| !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
|
|
||||||
goto err3;
|
|
||||||
|
|
||||||
/* check whether the public key was calculated correctly */
|
|
||||||
TEST_uint_eq(BN_get_word(pub_key2), 3331L);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* II) key generation
|
* II) key generation
|
||||||
|
@ -132,7 +119,7 @@ static int dh_test(void)
|
||||||
goto err3;
|
goto err3;
|
||||||
BN_GENCB_set(_cb, &cb, NULL);
|
BN_GENCB_set(_cb, &cb, NULL);
|
||||||
if (!TEST_ptr(a = DH_new())
|
if (!TEST_ptr(a = DH_new())
|
||||||
|| !TEST_true(DH_generate_parameters_ex(a, 64,
|
|| !TEST_true(DH_generate_parameters_ex(a, 512,
|
||||||
DH_GENERATOR_5, _cb)))
|
DH_GENERATOR_5, _cb)))
|
||||||
goto err3;
|
goto err3;
|
||||||
|
|
||||||
|
@ -192,7 +179,7 @@ static int dh_test(void)
|
||||||
|| !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1))
|
|| !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1))
|
||||||
goto err3;
|
goto err3;
|
||||||
|
|
||||||
if (!TEST_true(aout >= 4)
|
if (!TEST_true(aout >= 20)
|
||||||
|| !TEST_mem_eq(abuf, aout, bbuf, bout)
|
|| !TEST_mem_eq(abuf, aout, bbuf, bout)
|
||||||
|| !TEST_mem_eq(abuf, aout, cbuf, cout))
|
|| !TEST_mem_eq(abuf, aout, cbuf, cout))
|
||||||
goto err3;
|
goto err3;
|
||||||
|
|
Loading…
Reference in a new issue