summaryrefslogtreecommitdiffstats
path: root/crypto/bn
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@google.com>2016-06-24 17:07:52 +0200
committerKurt Roeckx <kurt@roeckx.be>2016-06-25 11:01:34 +0200
commitd70a562714199c9a4eb835efe7b22c9a7017e7e5 (patch)
treed1db68f2d94d79db0f212fb7bcd2896be542fa8e /crypto/bn
parentFix BN_is_prime* calls. (diff)
downloadopenssl-d70a562714199c9a4eb835efe7b22c9a7017e7e5.tar.xz
openssl-d70a562714199c9a4eb835efe7b22c9a7017e7e5.zip
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 <kurt@roeckx.be> Reviewed-by: Rich Salz <rsalz@openssl.org> GH: #1251
Diffstat (limited to 'crypto/bn')
-rw-r--r--crypto/bn/bn_prime.c41
1 files changed, 30 insertions, 11 deletions
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))