Commit 9db724cf authored by Samuel Weiser's avatar Samuel Weiser Committed by Matt Caswell
Browse files

Replaced variable-time GCD with consttime inversion to avoid side-channel...


Replaced variable-time GCD with consttime inversion to avoid side-channel attacks on RSA key generation

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
Reviewed-by: default avatarKurt Roeckx <kurt@roeckx.be>
Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5170)
parent 178a2a6f
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
    int bitsp, bitsq, ok = -1, n = 0;
    BN_CTX *ctx = NULL;
    unsigned long error = 0;

    /*
     * When generating ridiculously small keys, we can get stuck
@@ -88,16 +89,25 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
    if (BN_copy(rsa->e, e_value) == NULL)
        goto err;

    BN_set_flags(rsa->e, BN_FLG_CONSTTIME);
    /* generate p and q */
    for (;;) {
        if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
            goto err;
        if (!BN_sub(r2, rsa->p, BN_value_one()))
            goto err;
        if (!BN_gcd(r1, r2, rsa->e, ctx))
            goto err;
        if (BN_is_one(r1))
        if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
            /* GCD == 1 since inverse exists */
            break;
        }
        error = ERR_peek_last_error();
        if (ERR_GET_LIB(error) == ERR_LIB_BN
            && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
            /* GCD != 1 */
            ERR_clear_error();
        } else {
            goto err;
        }
        if (!BN_GENCB_call(cb, 2, n++))
            goto err;
    }
@@ -110,10 +120,18 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
        } while (BN_cmp(rsa->p, rsa->q) == 0);
        if (!BN_sub(r2, rsa->q, BN_value_one()))
            goto err;
        if (!BN_gcd(r1, r2, rsa->e, ctx))
            goto err;
        if (BN_is_one(r1))
        if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
            /* GCD == 1 since inverse exists */
            break;
        }
        error = ERR_peek_last_error();
        if (ERR_GET_LIB(error) == ERR_LIB_BN
            && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
            /* GCD != 1 */
            ERR_clear_error();
        } else {
            goto err;
        }
        if (!BN_GENCB_call(cb, 2, n++))
            goto err;
    }