summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2018-11-17 18:46:43 +0000
committertb <>2018-11-17 18:46:43 +0000
commite62c65b7027fd19c83f1f0a8228cea389f0f329d (patch)
tree7e438079e24bfc85d16d7115569b7e6ddd73433a
parentb4a1f1ba7fd6ed7aa2bd88d8973d2c7c031fd911 (diff)
downloadopenbsd-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
-rw-r--r--src/lib/libcrypto/dsa/dsa_ossl.c48
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_ossl.c79
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)
94static DSA_SIG * 94static DSA_SIG *
95dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 95dsa_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 *
204ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 204ecdsa_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