diff options
| author | jsing <> | 2018-06-14 18:34:50 +0000 |
|---|---|---|
| committer | jsing <> | 2018-06-14 18:34:50 +0000 |
| commit | c24fe07c8a7f1dbb21f1b6ad11364215f3cf4827 (patch) | |
| tree | f861ef32af25ae21d1033f86dd2014b3664313a5 /src/lib/libcrypto/dsa/dsa_ossl.c | |
| parent | 4dee824e86c9654e9dbc65146920eb67b52beb36 (diff) | |
| download | openbsd-c24fe07c8a7f1dbb21f1b6ad11364215f3cf4827.tar.gz openbsd-c24fe07c8a7f1dbb21f1b6ad11364215f3cf4827.tar.bz2 openbsd-c24fe07c8a7f1dbb21f1b6ad11364215f3cf4827.zip | |
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@
Diffstat (limited to 'src/lib/libcrypto/dsa/dsa_ossl.c')
| -rw-r--r-- | src/lib/libcrypto/dsa/dsa_ossl.c | 48 |
1 files changed, 39 insertions, 9 deletions
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 @@ | |||
| 1 | /* $OpenBSD: dsa_ossl.c,v 1.36 2018/06/14 18:03:59 jsing Exp $ */ | 1 | /* $OpenBSD: dsa_ossl.c,v 1.37 2018/06/14 18:34:50 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -94,16 +94,17 @@ DSA_OpenSSL(void) | |||
| 94 | static DSA_SIG * | 94 | static DSA_SIG * |
| 95 | dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | 95 | dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) |
| 96 | { | 96 | { |
| 97 | BIGNUM *kinv = NULL, *r = NULL, *s = NULL; | 97 | BIGNUM b, bm, bxr, binv, m, *kinv = NULL, *r = NULL, *s = NULL; |
| 98 | BIGNUM m; | ||
| 99 | BIGNUM xr; | ||
| 100 | BN_CTX *ctx = NULL; | 98 | BN_CTX *ctx = NULL; |
| 101 | int reason = ERR_R_BN_LIB; | 99 | int reason = ERR_R_BN_LIB; |
| 102 | DSA_SIG *ret = NULL; | 100 | DSA_SIG *ret = NULL; |
| 103 | int noredo = 0; | 101 | int noredo = 0; |
| 104 | 102 | ||
| 103 | BN_init(&b); | ||
| 104 | BN_init(&binv); | ||
| 105 | BN_init(&bm); | ||
| 106 | BN_init(&bxr); | ||
| 105 | BN_init(&m); | 107 | BN_init(&m); |
| 106 | BN_init(&xr); | ||
| 107 | 108 | ||
| 108 | if (!dsa->p || !dsa->q || !dsa->g) { | 109 | if (!dsa->p || !dsa->q || !dsa->g) { |
| 109 | reason = DSA_R_MISSING_PARAMETERS; | 110 | reason = DSA_R_MISSING_PARAMETERS; |
| @@ -139,10 +140,36 @@ dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |||
| 139 | noredo = 1; | 140 | noredo = 1; |
| 140 | } | 141 | } |
| 141 | 142 | ||
| 142 | /* Compute s = inv(k) (m + xr) mod q */ | 143 | /* |
| 143 | if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) /* s = xr */ | 144 | * Compute: |
| 145 | * | ||
| 146 | * s = inv(k)(m + xr) mod q | ||
| 147 | * | ||
| 148 | * In order to reduce the possibility of a side-channel attack, the | ||
| 149 | * following is calculated using a blinding value: | ||
| 150 | * | ||
| 151 | * s = inv(k)inv(b)(bm + bxr) mod q | ||
| 152 | * | ||
| 153 | * Where b is a random value in the range [1, q-1]. | ||
| 154 | */ | ||
| 155 | if (!BN_sub(&bm, dsa->q, BN_value_one())) | ||
| 156 | goto err; | ||
| 157 | if (!BN_rand_range(&b, &bm)) | ||
| 158 | goto err; | ||
| 159 | if (!BN_add(&b, &b, BN_value_one())) | ||
| 160 | goto err; | ||
| 161 | if (BN_mod_inverse_ct(&binv, &b, dsa->q, ctx) == NULL) | ||
| 162 | goto err; | ||
| 163 | |||
| 164 | if (!BN_mod_mul(&bxr, &b, dsa->priv_key, dsa->q, ctx)) /* bx */ | ||
| 165 | goto err; | ||
| 166 | if (!BN_mod_mul(&bxr, &bxr, r, dsa->q, ctx)) /* bxr */ | ||
| 167 | goto err; | ||
| 168 | if (!BN_mod_mul(&bm, &b, &m, dsa->q, ctx)) /* bm */ | ||
| 169 | goto err; | ||
| 170 | if (!BN_mod_add(s, &bxr, &bm, dsa->q, ctx)) /* s = bm + bxr */ | ||
| 144 | goto err; | 171 | goto err; |
| 145 | if (!BN_mod_add(s, &xr, &m, dsa->q, ctx)) /* s = m + xr */ | 172 | if (!BN_mod_mul(s, s, &binv, dsa->q, ctx)) /* s = m + xr */ |
| 146 | goto err; | 173 | goto err; |
| 147 | if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) | 174 | if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) |
| 148 | goto err; | 175 | goto err; |
| @@ -173,8 +200,11 @@ dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |||
| 173 | BN_free(s); | 200 | BN_free(s); |
| 174 | } | 201 | } |
| 175 | BN_CTX_free(ctx); | 202 | BN_CTX_free(ctx); |
| 203 | BN_clear_free(&b); | ||
| 204 | BN_clear_free(&bm); | ||
| 205 | BN_clear_free(&bxr); | ||
| 206 | BN_clear_free(&binv); | ||
| 176 | BN_clear_free(&m); | 207 | BN_clear_free(&m); |
| 177 | BN_clear_free(&xr); | ||
| 178 | BN_clear_free(kinv); | 208 | BN_clear_free(kinv); |
| 179 | 209 | ||
| 180 | return ret; | 210 | return ret; |
