diff options
| author | tb <> | 2018-11-17 18:46:43 +0000 |
|---|---|---|
| committer | tb <> | 2018-11-17 18:46:43 +0000 |
| commit | e62c65b7027fd19c83f1f0a8228cea389f0f329d (patch) | |
| tree | 7e438079e24bfc85d16d7115569b7e6ddd73433a /src | |
| parent | b4a1f1ba7fd6ed7aa2bd88d8973d2c7c031fd911 (diff) | |
| download | openbsd-e62c65b7027fd19c83f1f0a8228cea389f0f329d.tar.gz openbsd-e62c65b7027fd19c83f1f0a8228cea389f0f329d.tar.bz2 openbsd-e62c65b7027fd19c83f1f0a8228cea389f0f329d.zip | |
Use a blinding value when generating DSA and ECDSA signatures, in order to
reduce the possibility of a side-channel attack leaking the private key.
OpenBSD 6.3 errata 022
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/dsa/dsa_ossl.c | 48 | ||||
| -rw-r--r-- | src/lib/libcrypto/ecdsa/ecs_ossl.c | 79 |
2 files changed, 104 insertions, 23 deletions
diff --git a/src/lib/libcrypto/dsa/dsa_ossl.c b/src/lib/libcrypto/dsa/dsa_ossl.c index 4e75512df8..f29821059f 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.30.2.1 2018/06/13 15:08:08 jsing Exp $ */ | 1 | /* $OpenBSD: dsa_ossl.c,v 1.30.2.2 2018/11/17 18:46:43 tb 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 @@ redo: | |||
| 139 | if (BN_bin2bn(dgst,dlen,&m) == NULL) | 140 | if (BN_bin2bn(dgst,dlen,&m) == NULL) |
| 140 | goto err; | 141 | goto err; |
| 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; |
| @@ -171,8 +198,11 @@ err: | |||
| 171 | BN_free(s); | 198 | BN_free(s); |
| 172 | } | 199 | } |
| 173 | BN_CTX_free(ctx); | 200 | BN_CTX_free(ctx); |
| 201 | BN_clear_free(&b); | ||
| 202 | BN_clear_free(&bm); | ||
| 203 | BN_clear_free(&bxr); | ||
| 204 | BN_clear_free(&binv); | ||
| 174 | BN_clear_free(&m); | 205 | BN_clear_free(&m); |
| 175 | BN_clear_free(&xr); | ||
| 176 | BN_clear_free(kinv); | 206 | BN_clear_free(kinv); |
| 177 | return ret; | 207 | return ret; |
| 178 | } | 208 | } |
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c index 09f3bf8416..75ecb19557 100644 --- a/src/lib/libcrypto/ecdsa/ecs_ossl.c +++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ecs_ossl.c,v 1.9.2.1 2018/06/13 15:08:08 jsing Exp $ */ | 1 | /* $OpenBSD: ecs_ossl.c,v 1.9.2.2 2018/11/17 18:46:43 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Written by Nils Larsch for the OpenSSL project | 3 | * Written by Nils Larsch for the OpenSSL project |
| 4 | */ | 4 | */ |
| @@ -204,14 +204,14 @@ static ECDSA_SIG * | |||
| 204 | ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | 204 | ecdsa_do_sign(const unsigned char *dgst, int dgst_len, |
| 205 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) | 205 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) |
| 206 | { | 206 | { |
| 207 | int ok = 0, i; | 207 | BIGNUM *b = NULL, *binv = NULL, *bm = NULL, *bxr = NULL; |
| 208 | BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; | 208 | BIGNUM *kinv = NULL, *m = NULL, *order = NULL, *range = NULL, *s; |
| 209 | const BIGNUM *ckinv; | 209 | const BIGNUM *ckinv, *priv_key; |
| 210 | BN_CTX *ctx = NULL; | 210 | BN_CTX *ctx = NULL; |
| 211 | const EC_GROUP *group; | 211 | const EC_GROUP *group; |
| 212 | ECDSA_SIG *ret; | 212 | ECDSA_SIG *ret; |
| 213 | ECDSA_DATA *ecdsa; | 213 | ECDSA_DATA *ecdsa; |
| 214 | const BIGNUM *priv_key; | 214 | int ok = 0, i; |
| 215 | 215 | ||
| 216 | ecdsa = ecdsa_check(eckey); | 216 | ecdsa = ecdsa_check(eckey); |
| 217 | group = EC_KEY_get0_group(eckey); | 217 | group = EC_KEY_get0_group(eckey); |
| @@ -230,7 +230,9 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
| 230 | s = ret->s; | 230 | s = ret->s; |
| 231 | 231 | ||
| 232 | if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || | 232 | if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || |
| 233 | (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { | 233 | (range = BN_new()) == NULL || (b = BN_new()) == NULL || |
| 234 | (binv = BN_new()) == NULL || (bm = BN_new()) == NULL || | ||
| 235 | (bxr = BN_new()) == NULL || (m = BN_new()) == NULL) { | ||
| 234 | ECDSAerror(ERR_R_MALLOC_FAILURE); | 236 | ECDSAerror(ERR_R_MALLOC_FAILURE); |
| 235 | goto err; | 237 | goto err; |
| 236 | } | 238 | } |
| @@ -269,11 +271,53 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
| 269 | } | 271 | } |
| 270 | } | 272 | } |
| 271 | 273 | ||
| 272 | if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { | 274 | /* |
| 275 | * Compute s = inv(k)(m + xr) mod order. | ||
| 276 | * | ||
| 277 | * In order to reduce the possibility of a side-channel attack, | ||
| 278 | * the following is calculated using a blinding value: | ||
| 279 | * | ||
| 280 | * s = inv(k)inv(b)(bm + bxr) mod order | ||
| 281 | * | ||
| 282 | * where b is a random value in the range [1, order-1]. | ||
| 283 | */ | ||
| 284 | |||
| 285 | /* Generate b in range [1, order-1]. */ | ||
| 286 | if (!BN_sub(range, order, BN_value_one())) { | ||
| 287 | ECDSAerror(ERR_R_BN_LIB); | ||
| 288 | goto err; | ||
| 289 | } | ||
| 290 | if (!BN_rand_range(b, range)) { | ||
| 273 | ECDSAerror(ERR_R_BN_LIB); | 291 | ECDSAerror(ERR_R_BN_LIB); |
| 274 | goto err; | 292 | goto err; |
| 275 | } | 293 | } |
| 276 | if (!BN_mod_add(s, tmp, m, order, ctx)) { | 294 | if (!BN_add(b, b, BN_value_one())) { |
| 295 | ECDSAerror(ERR_R_BN_LIB); | ||
| 296 | goto err; | ||
| 297 | } | ||
| 298 | |||
| 299 | if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) { | ||
| 300 | ECDSAerror(ERR_R_BN_LIB); | ||
| 301 | goto err; | ||
| 302 | } | ||
| 303 | |||
| 304 | if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) { /* bx */ | ||
| 305 | ECDSAerror(ERR_R_BN_LIB); | ||
| 306 | goto err; | ||
| 307 | } | ||
| 308 | if (!BN_mod_mul(bxr, bxr, ret->r, order, ctx)) { /* bxr */ | ||
| 309 | ECDSAerror(ERR_R_BN_LIB); | ||
| 310 | goto err; | ||
| 311 | } | ||
| 312 | if (!BN_mod_mul(bm, b, m, order, ctx)) { /* bm */ | ||
| 313 | ECDSAerror(ERR_R_BN_LIB); | ||
| 314 | goto err; | ||
| 315 | } | ||
| 316 | if (!BN_mod_add(s, bm, bxr, order, ctx)) { /* s = bm + bxr */ | ||
| 317 | ECDSAerror(ERR_R_BN_LIB); | ||
| 318 | goto err; | ||
| 319 | } | ||
| 320 | if (!BN_mod_mul(s, s, binv, order, ctx)) { /* s = m + xr */ | ||
| 277 | ECDSAerror(ERR_R_BN_LIB); | 321 | ECDSAerror(ERR_R_BN_LIB); |
| 278 | goto err; | 322 | goto err; |
| 279 | } | 323 | } |
| @@ -281,9 +325,12 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
| 281 | ECDSAerror(ERR_R_BN_LIB); | 325 | ECDSAerror(ERR_R_BN_LIB); |
| 282 | goto err; | 326 | goto err; |
| 283 | } | 327 | } |
| 328 | |||
| 284 | if (BN_is_zero(s)) { | 329 | if (BN_is_zero(s)) { |
| 285 | /* if kinv and r have been supplied by the caller | 330 | /* |
| 286 | * don't to generate new kinv and r values */ | 331 | * If kinv and r have been supplied by the caller, |
| 332 | * don't generate new kinv and r values | ||
| 333 | */ | ||
| 287 | if (in_kinv != NULL && in_r != NULL) { | 334 | if (in_kinv != NULL && in_r != NULL) { |
| 288 | ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES); | 335 | ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES); |
| 289 | goto err; | 336 | goto err; |
| @@ -301,10 +348,14 @@ err: | |||
| 301 | ret = NULL; | 348 | ret = NULL; |
| 302 | } | 349 | } |
| 303 | BN_CTX_free(ctx); | 350 | BN_CTX_free(ctx); |
| 351 | BN_clear_free(b); | ||
| 352 | BN_clear_free(binv); | ||
| 353 | BN_clear_free(bm); | ||
| 354 | BN_clear_free(bxr); | ||
| 355 | BN_clear_free(kinv); | ||
| 304 | BN_clear_free(m); | 356 | BN_clear_free(m); |
| 305 | BN_clear_free(tmp); | ||
| 306 | BN_free(order); | 357 | BN_free(order); |
| 307 | BN_clear_free(kinv); | 358 | BN_free(range); |
| 308 | return ret; | 359 | return ret; |
| 309 | } | 360 | } |
| 310 | 361 | ||
