From cc064d672d8fc76e2a66d1833709d38c5d72daaa Mon Sep 17 00:00:00 2001 From: jsing <> Date: Thu, 14 Jun 2018 18:34:50 +0000 Subject: Use a blinding value when generating a DSA signature, in order to reduce the possibility of a side-channel attack leaking the private key. Suggested by Keegan Ryan at NCC Group. With input from and ok tb@ --- src/lib/libcrypto/dsa/dsa_ossl.c | 48 ++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 9 deletions(-) (limited to 'src/lib/libcrypto') diff --git a/src/lib/libcrypto/dsa/dsa_ossl.c b/src/lib/libcrypto/dsa/dsa_ossl.c index 2f7268839e..c9399573ab 100644 --- a/src/lib/libcrypto/dsa/dsa_ossl.c +++ b/src/lib/libcrypto/dsa/dsa_ossl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsa_ossl.c,v 1.36 2018/06/14 18:03:59 jsing Exp $ */ +/* $OpenBSD: dsa_ossl.c,v 1.37 2018/06/14 18:34:50 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -94,16 +94,17 @@ 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 b, bm, bxr, binv, m, *kinv = NULL, *r = NULL, *s = NULL; BN_CTX *ctx = NULL; int reason = ERR_R_BN_LIB; DSA_SIG *ret = NULL; int noredo = 0; + BN_init(&b); + BN_init(&binv); + BN_init(&bm); + BN_init(&bxr); BN_init(&m); - BN_init(&xr); if (!dsa->p || !dsa->q || !dsa->g) { reason = DSA_R_MISSING_PARAMETERS; @@ -139,10 +140,36 @@ dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) noredo = 1; } - /* Compute s = inv(k) (m + xr) mod q */ - if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) /* s = xr */ + /* + * Compute: + * + * s = inv(k)(m + xr) mod q + * + * In order to reduce the possibility of a side-channel attack, the + * following is calculated using a blinding value: + * + * s = inv(k)inv(b)(bm + bxr) mod q + * + * Where b is a random value in the range [1, q-1]. + */ + if (!BN_sub(&bm, dsa->q, BN_value_one())) + goto err; + if (!BN_rand_range(&b, &bm)) + goto err; + if (!BN_add(&b, &b, BN_value_one())) + goto err; + if (BN_mod_inverse_ct(&binv, &b, dsa->q, ctx) == NULL) + goto err; + + if (!BN_mod_mul(&bxr, &b, dsa->priv_key, dsa->q, ctx)) /* bx */ + goto err; + if (!BN_mod_mul(&bxr, &bxr, r, dsa->q, ctx)) /* bxr */ + goto err; + if (!BN_mod_mul(&bm, &b, &m, dsa->q, ctx)) /* bm */ + goto err; + if (!BN_mod_add(s, &bxr, &bm, dsa->q, ctx)) /* s = bm + bxr */ goto err; - if (!BN_mod_add(s, &xr, &m, dsa->q, ctx)) /* s = m + xr */ + if (!BN_mod_mul(s, s, &binv, dsa->q, ctx)) /* s = m + xr */ goto err; if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) goto err; @@ -173,8 +200,11 @@ dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) BN_free(s); } BN_CTX_free(ctx); + BN_clear_free(&b); + BN_clear_free(&bm); + BN_clear_free(&bxr); + BN_clear_free(&binv); BN_clear_free(&m); - BN_clear_free(&xr); BN_clear_free(kinv); return ret; -- cgit v1.2.3-55-g6feb