The branch master has been updated via 7f9822a48213dd2feca845dbbb6bcb8beb9550de (commit) from 95aec8641fb6f596f170f97852e1e2839f4ec2fc (commit)
- Log ----------------------------------------------------------------- commit 7f9822a48213dd2feca845dbbb6bcb8beb9550de Author: Matt Caswell <m...@openssl.org> Date: Tue Jun 19 15:07:02 2018 +0100 Add blinding to a DSA signature This extends the recently added ECDSA signature blinding to blind DSA too. This is based on side channel attacks demonstrated by Keegan Ryan (NCC Group) for ECDSA which are likely to be able to be applied to DSA. Normally, as in ECDSA, during signing the signer calculates: s:= k^-1 * (m + r * priv_key) mod order In ECDSA, the addition operation above provides a sufficient signal for a flush+reload attack to derive the private key given sufficient signature operations. As a mitigation (based on a suggestion from Keegan) we add blinding to the operation so that: s := k^-1 * blind^-1 (blind * m + blind * r * priv_key) mod order Since this attack is a localhost side channel only no CVE is assigned. This commit also tweaks the previous ECDSA blinding so that blinding is only removed at the last possible step. Reviewed-by: Rich Salz <rs...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6522) ----------------------------------------------------------------------- Summary of changes: CHANGES | 4 +-- crypto/dsa/dsa_ossl.c | 66 +++++++++++++++++++++++++++++++++++++------------- crypto/ec/ecdsa_ossl.c | 14 +++++------ 3 files changed, 58 insertions(+), 26 deletions(-) diff --git a/CHANGES b/CHANGES index a4beda6..4dc0659 100644 --- a/CHANGES +++ b/CHANGES @@ -13,8 +13,8 @@ chosen point SCA attacks. [Sohaib ul Hassan, Nicola Tuveri, Billy Bob Brumley] - *) 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] *) Enforce checking in the pkeyutl command line app to ensure that the input diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index d78c5f0..5237794 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -59,19 +59,13 @@ const DSA_METHOD *DSA_OpenSSL(void) static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { BIGNUM *kinv = 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 rv = 0; - m = BN_new(); - xr = BN_new(); - if (m == NULL || xr == NULL) - goto err; - - if (!dsa->p || !dsa->q || !dsa->g) { + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { reason = DSA_R_MISSING_PARAMETERS; goto err; } @@ -87,6 +81,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_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen)) goto err; @@ -101,17 +102,50 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 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, ret->r, dsa->q, ctx)) - goto err; /* s = xr */ - if (!BN_add(ret->s, xr, m)) - goto err; /* s = m + xr */ - if (BN_cmp(ret->s, dsa->q) > 0) - if (!BN_sub(ret->s, ret->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_priv_rand(blind, BN_num_bits(dsa->q) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) 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, ret->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(ret->s, tmp, blindm, dsa->q)) + goto err; + + /* s := s * k^-1 mod q */ if (!BN_mod_mul(ret->s, ret->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(ret->s, ret->s, blind, dsa->q, ctx)) + goto err; + /* * Redo if r or s is zero as required by FIPS 186-3: this is very * unlikely. @@ -128,8 +162,6 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) ret = NULL; } BN_CTX_free(ctx); - BN_clear_free(m); - BN_clear_free(xr); BN_clear_free(kinv); return ret; } diff --git a/crypto/ec/ecdsa_ossl.c b/crypto/ec/ecdsa_ossl.c index 640593b..cdd0cf0 100644 --- a/crypto/ec/ecdsa_ossl.c +++ b/crypto/ec/ecdsa_ossl.c @@ -288,7 +288,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(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 */ @@ -323,18 +323,18 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(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)) { ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, 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) { ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, 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)) { ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); goto err; } _____ openssl-commits mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-commits