summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ecdsa
diff options
context:
space:
mode:
authortb <>2018-06-14 18:51:01 +0000
committertb <>2018-06-14 18:51:01 +0000
commit419cc2003a828092974570e1c645b732b8908228 (patch)
treeb0dafa4456b38f55ede9cb825ae6050bec87d29c /src/lib/libcrypto/ecdsa
parentcc064d672d8fc76e2a66d1833709d38c5d72daaa (diff)
downloadopenbsd-419cc2003a828092974570e1c645b732b8908228.tar.gz
openbsd-419cc2003a828092974570e1c645b732b8908228.tar.bz2
openbsd-419cc2003a828092974570e1c645b732b8908228.zip
Use a blinding value when generating an ECDSA 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 jsing
Diffstat (limited to 'src/lib/libcrypto/ecdsa')
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_ossl.c79
1 files changed, 65 insertions, 14 deletions
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c
index 0f594aa86e..3939d7c8c1 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.11 2018/06/13 15:05:04 jsing Exp $ */ 1/* $OpenBSD: ecs_ossl.c,v 1.12 2018/06/14 18:51:01 tb Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project 3 * Written by Nils Larsch for the OpenSSL project
4 */ 4 */
@@ -221,14 +221,14 @@ static ECDSA_SIG *
221ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 221ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
222 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) 222 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
223{ 223{
224 int ok = 0, i; 224 BIGNUM *b = NULL, *binv = NULL, *bm = NULL, *bxr = NULL;
225 BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; 225 BIGNUM *kinv = NULL, *m = NULL, *order = NULL, *range = NULL, *s;
226 const BIGNUM *ckinv; 226 const BIGNUM *ckinv, *priv_key;
227 BN_CTX *ctx = NULL; 227 BN_CTX *ctx = NULL;
228 const EC_GROUP *group; 228 const EC_GROUP *group;
229 ECDSA_SIG *ret; 229 ECDSA_SIG *ret;
230 ECDSA_DATA *ecdsa; 230 ECDSA_DATA *ecdsa;
231 const BIGNUM *priv_key; 231 int ok = 0, i;
232 232
233 ecdsa = ecdsa_check(eckey); 233 ecdsa = ecdsa_check(eckey);
234 group = EC_KEY_get0_group(eckey); 234 group = EC_KEY_get0_group(eckey);
@@ -247,7 +247,9 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
247 s = ret->s; 247 s = ret->s;
248 248
249 if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || 249 if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
250 (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { 250 (range = BN_new()) == NULL || (b = BN_new()) == NULL ||
251 (binv = BN_new()) == NULL || (bm = BN_new()) == NULL ||
252 (bxr = BN_new()) == NULL || (m = BN_new()) == NULL) {
251 ECDSAerror(ERR_R_MALLOC_FAILURE); 253 ECDSAerror(ERR_R_MALLOC_FAILURE);
252 goto err; 254 goto err;
253 } 255 }
@@ -286,11 +288,53 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
286 } 288 }
287 } 289 }
288 290
289 if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { 291 /*
292 * Compute s = inv(k)(m + xr) mod order.
293 *
294 * In order to reduce the possibility of a side-channel attack,
295 * the following is calculated using a blinding value:
296 *
297 * s = inv(k)inv(b)(bm + bxr) mod order
298 *
299 * where b is a random value in the range [1, order-1].
300 */
301
302 /* Generate b in range [1, order-1]. */
303 if (!BN_sub(range, order, BN_value_one())) {
304 ECDSAerror(ERR_R_BN_LIB);
305 goto err;
306 }
307 if (!BN_rand_range(b, range)) {
308 ECDSAerror(ERR_R_BN_LIB);
309 goto err;
310 }
311 if (!BN_add(b, b, BN_value_one())) {
312 ECDSAerror(ERR_R_BN_LIB);
313 goto err;
314 }
315
316 if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) {
317 ECDSAerror(ERR_R_BN_LIB);
318 goto err;
319 }
320
321 if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) { /* bx */
290 ECDSAerror(ERR_R_BN_LIB); 322 ECDSAerror(ERR_R_BN_LIB);
291 goto err; 323 goto err;
292 } 324 }
293 if (!BN_mod_add(s, tmp, m, order, ctx)) { 325 if (!BN_mod_mul(bxr, bxr, ret->r, order, ctx)) { /* bxr */
326 ECDSAerror(ERR_R_BN_LIB);
327 goto err;
328 }
329 if (!BN_mod_mul(bm, b, m, order, ctx)) { /* bm */
330 ECDSAerror(ERR_R_BN_LIB);
331 goto err;
332 }
333 if (!BN_mod_add(s, bm, bxr, order, ctx)) { /* s = bm + bxr */
334 ECDSAerror(ERR_R_BN_LIB);
335 goto err;
336 }
337 if (!BN_mod_mul(s, s, binv, order, ctx)) { /* s = m + xr */
294 ECDSAerror(ERR_R_BN_LIB); 338 ECDSAerror(ERR_R_BN_LIB);
295 goto err; 339 goto err;
296 } 340 }
@@ -298,9 +342,12 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
298 ECDSAerror(ERR_R_BN_LIB); 342 ECDSAerror(ERR_R_BN_LIB);
299 goto err; 343 goto err;
300 } 344 }
345
301 if (BN_is_zero(s)) { 346 if (BN_is_zero(s)) {
302 /* if kinv and r have been supplied by the caller 347 /*
303 * don't to generate new kinv and r values */ 348 * If kinv and r have been supplied by the caller,
349 * don't generate new kinv and r values
350 */
304 if (in_kinv != NULL && in_r != NULL) { 351 if (in_kinv != NULL && in_r != NULL) {
305 ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES); 352 ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES);
306 goto err; 353 goto err;
@@ -318,10 +365,14 @@ err:
318 ret = NULL; 365 ret = NULL;
319 } 366 }
320 BN_CTX_free(ctx); 367 BN_CTX_free(ctx);
368 BN_clear_free(b);
369 BN_clear_free(binv);
370 BN_clear_free(bm);
371 BN_clear_free(bxr);
372 BN_clear_free(kinv);
321 BN_clear_free(m); 373 BN_clear_free(m);
322 BN_clear_free(tmp);
323 BN_free(order); 374 BN_free(order);
324 BN_clear_free(kinv); 375 BN_free(range);
325 return ret; 376 return ret;
326} 377}
327 378