Commit d70a5627 authored by David Benjamin's avatar David Benjamin Committed by Kurt Roeckx
Browse files

Handle BN_mod_word failures.



As of 37258dad 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: default avatarKurt Roeckx <kurt@roeckx.be>
Reviewed-by: default avatarRich Salz <rsalz@openssl.org>

GH: #1251
parent 748e8530
Loading
Loading
Loading
Loading
+30 −11
Original line number Diff line number Diff line
@@ -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,10 +366,12 @@ 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;

 err:
@@ -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))
+4 −0
Original line number Diff line number Diff line
@@ -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