From: David Benjamin Date: Fri, 24 Jun 2016 15:07:52 +0000 (-0400) Subject: Handle BN_mod_word failures. X-Git-Tag: OpenSSL_1_1_0-pre6~340 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=d70a562714199c9a4eb835efe7b22c9a7017e7e5;p=oweals%2Fopenssl.git Handle BN_mod_word failures. As of 37258dadaa9e36db4b96a3aa54aa6c67136160cc and the corresponding upstream change, BN_mod_word may fail, like BN_div_word. Handle this properly. Thanks to Brian Smith for pointing this out. See BoringSSL's 44bedc348d9491e63c7ed1438db100a4b8a830be. Signed-off-by: Kurt Roeckx Reviewed-by: Rich Salz GH: #1251 --- diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c index df4f058d8c..1c41938fed 100644 --- a/crypto/bn/bn_prime.c +++ b/crypto/bn/bn_prime.c @@ -143,7 +143,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, goto err; } } - /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ + if (!BN_GENCB_call(cb, 0, c1++)) /* aborted */ goto err; @@ -218,9 +218,13 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, /* a is even => a is prime if and only if a == 2 */ return BN_is_word(a, 2); if (do_trial_division) { - for (i = 1; i < NUMPRIMES; i++) - if (BN_mod_word(a, primes[i]) == 0) + for (i = 1; i < NUMPRIMES; i++) { + BN_ULONG mod = BN_mod_word(a, primes[i]); + if (mod == (BN_ULONG)-1) + goto err; + if (mod == 0) return 0; + } if (!BN_GENCB_call(cb, 1, -1)) goto err; } @@ -313,7 +317,10 @@ int bn_probable_prime_dh_retry(BIGNUM *rnd, int bits, BN_CTX *ctx) for (i = 1; i < NUMPRIMES; i++) { /* check that rnd is a prime */ - if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { + BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); + if (mod == (BN_ULONG)-1) + goto err; + if (mod <= 1) { goto loop; } } @@ -359,9 +366,11 @@ int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits, BN_CTX *ctx) /* skip coprimes */ for (i = first_prime_index; i < NUMPRIMES; i++) { /* check that rnd is a prime */ - if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { + BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); + if (mod == (BN_ULONG)-1) + goto err; + if (mod <= 1) goto loop; - } } ret = 1; @@ -409,8 +418,12 @@ static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods) if (!BN_rand(rnd, bits, 1, 1)) return (0); /* 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]); + for (i = 1; i < NUMPRIMES; i++) { + BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); + if (mod == (BN_ULONG)-1) + return 0; + mods[i] = (prime_t) mod; + } /* * If bits is so small that it fits into a single word then we * additionally don't want to exceed that many bits. @@ -508,7 +521,10 @@ int bn_probable_prime_dh(BIGNUM *rnd, int bits, loop: for (i = 1; i < NUMPRIMES; i++) { /* check that rnd is a prime */ - if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { + BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); + if (mod == (BN_ULONG)-1) + goto err; + if (mod <= 1) { if (!BN_add(rnd, rnd, add)) goto err; goto loop; @@ -569,8 +585,11 @@ static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, /* * check that for p and q gcd(p-1,primes) == 1 (except for 2) */ - if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) || - (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) { + BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]); + BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]); + if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1) + goto err; + if (pmod == 0 || qmod == 0) { if (!BN_add(p, p, padd)) goto err; if (!BN_add(q, q, qadd)) diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index 8d2e096c08..fcc1d99ad7 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -68,10 +68,14 @@ int DH_check(const DH *dh, int *ret) } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { l = BN_mod_word(dh->p, 24); + if (l == (BN_ULONG)-1) + goto err; if (l != 11) *ret |= DH_NOT_SUITABLE_GENERATOR; } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { l = BN_mod_word(dh->p, 10); + if (l == (BN_ULONG)-1) + goto err; if ((l != 3) && (l != 7)) *ret |= DH_NOT_SUITABLE_GENERATOR; } else