X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdsa%2Fdsa_ossl.c;h=d78c5f00cbabf325a3428823a1ae52bb774862c6;hp=3c734ec26ed434a4745865d0eb43aab69bd64d70;hb=c0caa945f6ef30363e0d01d75155f20248403df4;hpb=823146d65fe145eb6024d84ab50ed63ba9f8705c diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 3c734ec26e..d78c5f00cb 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -7,8 +7,6 @@ * https://www.openssl.org/source/license.html */ -/* Original version from Steven Schoch */ - #include #include "internal/cryptlib.h" #include @@ -41,6 +39,18 @@ static DSA_METHOD openssl_dsa_meth = { NULL }; +static const DSA_METHOD *default_DSA_method = &openssl_dsa_meth; + +void DSA_set_default_method(const DSA_METHOD *meth) +{ + default_DSA_method = meth; +} + +const DSA_METHOD *DSA_get_default_method(void) +{ + return default_DSA_method; +} + const DSA_METHOD *DSA_OpenSSL(void) { return &openssl_dsa_meth; @@ -51,7 +61,6 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) BIGNUM *kinv = NULL; BIGNUM *m; BIGNUM *xr; - BIGNUM *r, *s; BN_CTX *ctx = NULL; int reason = ERR_R_BN_LIB; DSA_SIG *ret = NULL; @@ -70,14 +79,16 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) ret = DSA_SIG_new(); if (ret == NULL) goto err; - - DSA_SIG_get0(&r, &s, ret); + ret->r = BN_new(); + ret->s = BN_new(); + if (ret->r == NULL || ret->s == NULL) + goto err; ctx = BN_CTX_new(); if (ctx == NULL) goto err; redo: - if (!dsa_sign_setup(dsa, ctx, &kinv, &r, dgst, dlen)) + if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen)) goto err; if (dlen > BN_num_bytes(dsa->q)) @@ -91,21 +102,21 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) goto err; /* Compute s = inv(k) (m + xr) mod q */ - if (!BN_mod_mul(xr, dsa->priv_key, r, dsa->q, ctx)) + if (!BN_mod_mul(xr, dsa->priv_key, ret->r, dsa->q, ctx)) goto err; /* s = xr */ - if (!BN_add(s, xr, m)) + if (!BN_add(ret->s, xr, m)) goto err; /* s = m + xr */ - if (BN_cmp(s, dsa->q) > 0) - if (!BN_sub(s, s, dsa->q)) + if (BN_cmp(ret->s, dsa->q) > 0) + if (!BN_sub(ret->s, ret->s, dsa->q)) goto err; - if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) + if (!BN_mod_mul(ret->s, ret->s, kinv, dsa->q, ctx)) goto err; /* * Redo if r or s is zero as required by FIPS 186-3: this is very * unlikely. */ - if (BN_is_zero(r) || BN_is_zero(s)) + if (BN_is_zero(ret->r) || BN_is_zero(ret->s)) goto redo; rv = 1; @@ -135,7 +146,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, { BN_CTX *ctx = NULL; BIGNUM *k, *kinv = NULL, *r = *rp; + BIGNUM *l, *m; int ret = 0; + int q_bits; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); @@ -143,7 +156,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, } k = BN_new(); - if (k == NULL) + l = BN_new(); + m = BN_new(); + if (k == NULL || l == NULL || m == NULL) goto err; if (ctx_in == NULL) { @@ -152,6 +167,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, } else ctx = ctx_in; + /* Preallocate space */ + q_bits = BN_num_bits(dsa->q); + if (!BN_set_bit(k, q_bits) + || !BN_set_bit(l, q_bits) + || !BN_set_bit(m, q_bits)) + goto err; + /* Get random k */ do { if (dgst != NULL) { @@ -162,7 +184,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst, dlen, ctx)) goto err; - } else if (!BN_rand_range(k, dsa->q)) + } else if (!BN_priv_rand_range(k, dsa->q)) goto err; } while (BN_is_zero(k)); @@ -178,17 +200,19 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, /* * We do not want timing information to leak the length of k, so we - * compute g^k using an equivalent exponent of fixed length. (This - * is a kludge that we need because the BN_mod_exp_mont() does not - * let us specify the desired timing behaviour.) + * compute G^k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the modulus. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. */ - - if (!BN_add(k, k, dsa->q)) + if (!BN_add(l, k, dsa->q) + || !BN_add(m, l, dsa->q) + || !BN_copy(k, BN_num_bits(l) > q_bits ? l : m)) goto err; - if (BN_num_bits(k) <= BN_num_bits(dsa->q)) { - if (!BN_add(k, k, dsa->q)) - goto err; - } if ((dsa)->meth->bn_mod_exp != NULL) { if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx, @@ -216,6 +240,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, if (ctx != ctx_in) BN_CTX_free(ctx); BN_clear_free(k); + BN_clear_free(l); + BN_clear_free(m); return ret; } @@ -225,7 +251,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, BN_CTX *ctx; BIGNUM *u1, *u2, *t1; BN_MONT_CTX *mont = NULL; - BIGNUM *r, *s; + const BIGNUM *r, *s; int ret = -1, i; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS); @@ -250,7 +276,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, if (u1 == NULL || u2 == NULL || t1 == NULL || ctx == NULL) goto err; - DSA_SIG_get0(&r, &s, sig); + DSA_SIG_get0(sig, &r, &s); if (BN_is_zero(r) || BN_is_negative(r) || BN_ucmp(r, dsa->q) >= 0) { @@ -321,17 +347,17 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, BN_free(u1); BN_free(u2); BN_free(t1); - return (ret); + return ret; } static int dsa_init(DSA *dsa) { dsa->flags |= DSA_FLAG_CACHE_MONT_P; - return (1); + return 1; } static int dsa_finish(DSA *dsa) { BN_MONT_CTX_free(dsa->method_mont_p); - return (1); + return 1; }