diff options
Diffstat (limited to 'freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c')
-rw-r--r-- | freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c | 73 |
1 files changed, 52 insertions, 21 deletions
diff --git a/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c b/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c index 715511c2..dc6c2c94 100644 --- a/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c +++ b/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c @@ -135,17 +135,13 @@ const DSA_METHOD *DSA_OpenSSL(void) static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { BIGNUM *kinv = NULL, *r = NULL, *s = NULL; - BIGNUM m; - BIGNUM xr; + BIGNUM *m, *blind, *blindm, *tmp; BN_CTX *ctx = NULL; int reason = ERR_R_BN_LIB; DSA_SIG *ret = NULL; int noredo = 0; - BN_init(&m); - BN_init(&xr); - - if (!dsa->p || !dsa->q || !dsa->g) { + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { reason = DSA_R_MISSING_PARAMETERS; goto err; } @@ -156,6 +152,13 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) ctx = BN_CTX_new(); if (ctx == NULL) goto err; + m = BN_CTX_get(ctx); + blind = BN_CTX_get(ctx); + blindm = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + redo: if ((dsa->kinv == NULL) || (dsa->r == NULL)) { if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) @@ -175,20 +178,52 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) * 4.2 */ dlen = BN_num_bytes(dsa->q); - if (BN_bin2bn(dgst, dlen, &m) == NULL) + if (BN_bin2bn(dgst, dlen, m) == NULL) goto err; - /* Compute s = inv(k) (m + xr) mod q */ - if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) - goto err; /* s = xr */ - if (!BN_add(s, &xr, &m)) - goto err; /* s = m + xr */ - if (BN_cmp(s, dsa->q) > 0) - if (!BN_sub(s, s, dsa->q)) + /* + * The normal signature calculation is: + * + * s := k^-1 * (m + r * priv_key) mod q + * + * We will blind this to protect against side channel attacks + * + * s := blind^-1 * k^-1 * (blind * m + blind * r * priv_key) mod q + */ + + /* Generate a blinding value */ + do { + if (!BN_rand(blind, BN_num_bits(dsa->q) - 1, -1, 0)) goto err; + } while (BN_is_zero(blind)); + BN_set_flags(blind, BN_FLG_CONSTTIME); + BN_set_flags(blindm, BN_FLG_CONSTTIME); + BN_set_flags(tmp, BN_FLG_CONSTTIME); + + /* tmp := blind * priv_key * r mod q */ + if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->q, ctx)) + goto err; + if (!BN_mod_mul(tmp, tmp, r, dsa->q, ctx)) + goto err; + + /* blindm := blind * m mod q */ + if (!BN_mod_mul(blindm, blind, m, dsa->q, ctx)) + goto err; + + /* s : = (blind * priv_key * r) + (blind * m) mod q */ + if (!BN_mod_add_quick(s, tmp, blindm, dsa->q)) + goto err; + + /* s := s * k^-1 mod q */ if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) goto err; + /* s:= s * blind^-1 mod q */ + if (BN_mod_inverse(blind, blind, dsa->q, ctx) == NULL) + goto err; + if (!BN_mod_mul(s, s, blind, dsa->q, ctx)) + goto err; + /* * Redo if r or s is zero as required by FIPS 186-3: this is very * unlikely. @@ -212,13 +247,9 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) BN_free(r); BN_free(s); } - if (ctx != NULL) - BN_CTX_free(ctx); - BN_clear_free(&m); - BN_clear_free(&xr); - if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ - BN_clear_free(kinv); - return (ret); + BN_CTX_free(ctx); + BN_clear_free(kinv); + return ret; } static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, |