Ensure that, when generating small primes, the result is actually of the
requested size. Fixes OpenSSL #2701. This change does not address the cases of generating safe primes, or where the |add| parameter is non-NULL. Conflicts: crypto/bn/bn.h crypto/bn/bn_err.c
This commit is contained in:
parent
2b0180c37f
commit
96a4c31be3
@ -826,6 +826,8 @@ void ERR_load_BN_strings(void);
|
||||
#define BN_F_BN_EXP 123
|
||||
#define BN_F_BN_EXPAND2 108
|
||||
#define BN_F_BN_EXPAND_INTERNAL 120
|
||||
#define BN_F_BN_GENERATE_DSA_NONCE 140
|
||||
#define BN_F_BN_GENERATE_PRIME_EX 141
|
||||
#define BN_F_BN_GF2M_MOD 131
|
||||
#define BN_F_BN_GF2M_MOD_EXP 132
|
||||
#define BN_F_BN_GF2M_MOD_MUL 133
|
||||
@ -854,6 +856,7 @@ void ERR_load_BN_strings(void);
|
||||
#define BN_R_ARG2_LT_ARG3 100
|
||||
#define BN_R_BAD_RECIPROCAL 101
|
||||
#define BN_R_BIGNUM_TOO_LONG 114
|
||||
#define BN_R_BITS_TOO_SMALL 118
|
||||
#define BN_R_CALLED_WITH_EVEN_MODULUS 102
|
||||
#define BN_R_DIV_BY_ZERO 103
|
||||
#define BN_R_ENCODING_ERROR 104
|
||||
|
@ -87,6 +87,8 @@ static ERR_STRING_DATA BN_str_functs[]=
|
||||
{ERR_FUNC(BN_F_BN_EXP), "BN_exp"},
|
||||
{ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"},
|
||||
{ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"},
|
||||
{ERR_FUNC(BN_F_BN_GENERATE_DSA_NONCE), "BN_generate_dsa_nonce"},
|
||||
{ERR_FUNC(BN_F_BN_GENERATE_PRIME_EX), "BN_generate_prime_ex"},
|
||||
{ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"},
|
||||
{ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"},
|
||||
{ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"},
|
||||
@ -118,6 +120,7 @@ static ERR_STRING_DATA BN_str_reasons[]=
|
||||
{ERR_REASON(BN_R_ARG2_LT_ARG3) ,"arg2 lt arg3"},
|
||||
{ERR_REASON(BN_R_BAD_RECIPROCAL) ,"bad reciprocal"},
|
||||
{ERR_REASON(BN_R_BIGNUM_TOO_LONG) ,"bignum too long"},
|
||||
{ERR_REASON(BN_R_BITS_TOO_SMALL) ,"bits too small"},
|
||||
{ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS),"called with even modulus"},
|
||||
{ERR_REASON(BN_R_DIV_BY_ZERO) ,"div by zero"},
|
||||
{ERR_REASON(BN_R_ENCODING_ERROR) ,"encoding error"},
|
||||
|
@ -165,6 +165,19 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
|
||||
BN_CTX *ctx;
|
||||
int checks = BN_prime_checks_for_size(bits);
|
||||
|
||||
if (bits < 2)
|
||||
{
|
||||
/* There are no prime numbers this small. */
|
||||
BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
else if (bits == 2 && safe)
|
||||
{
|
||||
/* The smallest safe prime (7) is three bits. */
|
||||
BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx=BN_CTX_new();
|
||||
if (ctx == NULL) goto err;
|
||||
BN_CTX_start(ctx);
|
||||
@ -378,27 +391,65 @@ static int probable_prime(BIGNUM *rnd, int bits)
|
||||
{
|
||||
int i;
|
||||
prime_t mods[NUMPRIMES];
|
||||
BN_ULONG delta,maxdelta;
|
||||
BN_ULONG delta;
|
||||
BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES-1];
|
||||
char is_single_word = bits <= BN_BITS2;
|
||||
|
||||
again:
|
||||
if (!BN_rand(rnd,bits,1,1)) return(0);
|
||||
/* we now have a random number 'rand' to test. */
|
||||
/* we now have a random number 'rnd' to test. */
|
||||
for (i=1; i<NUMPRIMES; i++)
|
||||
mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]);
|
||||
maxdelta=BN_MASK2 - primes[NUMPRIMES-1];
|
||||
delta=0;
|
||||
loop: for (i=1; i<NUMPRIMES; i++)
|
||||
/* If bits is so small that it fits into a single word then we
|
||||
* additionally don't want to exceed that many bits. */
|
||||
if (is_single_word)
|
||||
{
|
||||
/* check that rnd is not a prime and also
|
||||
* that gcd(rnd-1,primes) == 1 (except for 2) */
|
||||
if (((mods[i]+delta)%primes[i]) <= 1)
|
||||
BN_ULONG size_limit = (((BN_ULONG) 1) << bits) - BN_get_word(rnd) - 1;
|
||||
if (size_limit < maxdelta)
|
||||
maxdelta = size_limit;
|
||||
}
|
||||
delta=0;
|
||||
loop:
|
||||
if (is_single_word)
|
||||
{
|
||||
BN_ULONG rnd_word = BN_get_word(rnd);
|
||||
|
||||
/* In the case that the candidate prime is a single word then
|
||||
* we check that:
|
||||
* 1) It's greater than primes[i] because we shouldn't reject
|
||||
* 3 as being a prime number because it's a multiple of
|
||||
* three.
|
||||
* 2) That it's not a multiple of a known prime. We don't
|
||||
* check that rnd-1 is also coprime to all the known
|
||||
* primes because there aren't many small primes where
|
||||
* that's true. */
|
||||
for (i=1; i<NUMPRIMES && primes[i]<rnd_word; i++)
|
||||
{
|
||||
delta+=2;
|
||||
if (delta > maxdelta) goto again;
|
||||
goto loop;
|
||||
if ((mods[i]+delta)%primes[i] == 0)
|
||||
{
|
||||
delta+=2;
|
||||
if (delta > maxdelta) goto again;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=1; i<NUMPRIMES; i++)
|
||||
{
|
||||
/* check that rnd is not a prime and also
|
||||
* that gcd(rnd-1,primes) == 1 (except for 2) */
|
||||
if (((mods[i]+delta)%primes[i]) <= 1)
|
||||
{
|
||||
delta+=2;
|
||||
if (delta > maxdelta) goto again;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!BN_add_word(rnd,delta)) return(0);
|
||||
if (BN_num_bits(rnd) != bits)
|
||||
goto again;
|
||||
bn_check_top(rnd);
|
||||
return(1);
|
||||
}
|
||||
|
@ -120,6 +120,7 @@ int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
|
||||
int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
|
||||
int test_kron(BIO *bp,BN_CTX *ctx);
|
||||
int test_sqrt(BIO *bp,BN_CTX *ctx);
|
||||
int test_small_prime(BIO *bp,BN_CTX *ctx);
|
||||
int rand_neg(void);
|
||||
static int results=0;
|
||||
|
||||
@ -264,6 +265,11 @@ int main(int argc, char *argv[])
|
||||
message(out,"BN_mod_sqrt");
|
||||
if (!test_sqrt(out,ctx)) goto err;
|
||||
(void)BIO_flush(out);
|
||||
|
||||
message(out,"Small prime generation");
|
||||
if (!test_small_prime(out,ctx)) goto err;
|
||||
(void)BIO_flush(out);
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
message(out,"BN_GF2m_add");
|
||||
if (!test_gf2m_add(out)) goto err;
|
||||
@ -1895,6 +1901,28 @@ int test_sqrt(BIO *bp, BN_CTX *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_small_prime(BIO *bp,BN_CTX *ctx)
|
||||
{
|
||||
static const int bits = 10;
|
||||
int ret = 0;
|
||||
BIGNUM r;
|
||||
|
||||
BN_init(&r);
|
||||
if (!BN_generate_prime_ex(&r, bits, 0, NULL, NULL, NULL))
|
||||
goto err;
|
||||
if (BN_num_bits(&r) != bits)
|
||||
{
|
||||
BIO_printf(bp, "Expected %d bit prime, got %d bit number\n", bits, BN_num_bits(&r));
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_clear(&r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
|
||||
{
|
||||
BIGNUM *a,*b,*c,*d;
|
||||
|
Loading…
x
Reference in New Issue
Block a user