diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | crypto/dsa/dsa_ossl.c | 73 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_ossl.c | 14 |
3 files changed, 61 insertions, 30 deletions
@@ -9,8 +9,8 @@ Changes between 1.0.2o and 1.0.2p [xx XXX xxxx] - *) Add blinding to an ECDSA signature to protect against side channel attacks - discovered by Keegan Ryan (NCC Group). + *) Add blinding to ECDSA and DSA signatures to protect against side channel + attacks discovered by Keegan Ryan (NCC Group). [Matt Caswell] *) When unlocking a pass phrase protected PEM file or PKCS#8 container, we diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index aa10dd12f6..2dcfedeeee 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -133,17 +133,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; } @@ -154,6 +150,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)) @@ -173,20 +176,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. @@ -210,13 +245,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, diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c index 1d37551803..6115df7407 100644 --- a/crypto/ecdsa/ecs_ossl.c +++ b/crypto/ecdsa/ecs_ossl.c @@ -334,7 +334,7 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, * * We will blind this to protect against side channel attacks * - * s := k^-1 * blind^-1 * (blind * m + blind * r * priv_key) mod order + * s := blind^-1 * k^-1 * (blind * m + blind * r * priv_key) mod order */ /* Generate a blinding value */ @@ -368,18 +368,18 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, goto err; } - /* s:= s * blind^-1 mod order */ - if (BN_mod_inverse(blind, blind, order, ctx) == NULL) { + /* s := s * k^-1 mod order */ + if (!BN_mod_mul(s, s, ckinv, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } - if (!BN_mod_mul(s, s, blind, order, ctx)) { + + /* s:= s * blind^-1 mod order */ + if (BN_mod_inverse(blind, blind, order, ctx) == NULL) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } - - /* s := s * k^-1 mod order */ - if (!BN_mod_mul(s, s, ckinv, order, ctx)) { + if (!BN_mod_mul(s, s, blind, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } |