Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fe6d707

Browse filesBrowse files
rvaggtargos
authored andcommitted
deps: float 0c27d793 from openssl (ECDSA blinding)
Pending OpenSSL 1.1.0i release. Refs: https://www.nccgroup.trust/us/our-research/technical-advisory-return-of-the-hidden-number-problem/ PR-URL: #21345 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Shigeki Ohtsu <ohtsu@ohtsu.org> Reviewed-By: James M Snell <jasnell@gmail.com> Upstream: openssl/openssl@0c27d793 Original commit message: Add blinding to an ECDSA signature Keegan Ryan (NCC Group) has demonstrated a side channel attack on an ECDSA signature operation. During signing the signer calculates: s:= k^-1 * (m + r * priv_key) mod order The addition operation above provides a sufficient signal for a flush+reload attack to derive the private key given sufficient signature operations. As a mitigation (based on a suggestion from Keegan) we add blinding to the operation so that: s := k^-1 * blind^-1 (blind * m + blind * r * priv_key) mod order Since this attack is a localhost side channel only no CVE is assigned. Reviewed-by: Rich Salz <rsalz@openssl.org>
1 parent 6cca5a8 commit fe6d707
Copy full SHA for fe6d707

File tree

Expand file treeCollapse file tree

1 file changed

+63
-7
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+63
-7
lines changed
Open diff view settings
Collapse file

‎deps/openssl/openssl/crypto/ec/ecdsa_ossl.c‎

Copy file name to clipboardExpand all lines: deps/openssl/openssl/crypto/ec/ecdsa_ossl.c
+63-7Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
210210
EC_KEY *eckey)
211211
{
212212
int ok = 0, i;
213-
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL;
213+
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *blind = NULL;
214+
BIGNUM *blindm = NULL;
214215
const BIGNUM *order, *ckinv;
215216
BN_CTX *ctx = NULL;
216217
const EC_GROUP *group;
@@ -243,8 +244,18 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
243244
}
244245
s = ret->s;
245246

246-
if ((ctx = BN_CTX_new()) == NULL ||
247-
(tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
247+
ctx = BN_CTX_secure_new();
248+
if (ctx == NULL) {
249+
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
250+
goto err;
251+
}
252+
253+
BN_CTX_start(ctx);
254+
tmp = BN_CTX_get(ctx);
255+
m = BN_CTX_get(ctx);
256+
blind = BN_CTX_get(ctx);
257+
blindm = BN_CTX_get(ctx);
258+
if (blindm == NULL) {
248259
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
249260
goto err;
250261
}
@@ -284,18 +295,64 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
284295
}
285296
}
286297

287-
if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
298+
/*
299+
* The normal signature calculation is:
300+
*
301+
* s := k^-1 * (m + r * priv_key) mod order
302+
*
303+
* We will blind this to protect against side channel attacks
304+
*
305+
* s := k^-1 * blind^-1 * (blind * m + blind * r * priv_key) mod order
306+
*/
307+
308+
/* Generate a blinding value */
309+
do {
310+
if (!BN_rand(blind, BN_num_bits(order) - 1, BN_RAND_TOP_ANY,
311+
BN_RAND_BOTTOM_ANY))
312+
goto err;
313+
} while (BN_is_zero(blind));
314+
BN_set_flags(blind, BN_FLG_CONSTTIME);
315+
BN_set_flags(blindm, BN_FLG_CONSTTIME);
316+
BN_set_flags(tmp, BN_FLG_CONSTTIME);
317+
318+
/* tmp := blind * priv_key * r mod order */
319+
if (!BN_mod_mul(tmp, blind, priv_key, order, ctx)) {
288320
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
289321
goto err;
290322
}
291-
if (!BN_mod_add_quick(s, tmp, m, order)) {
323+
if (!BN_mod_mul(tmp, tmp, ret->r, order, ctx)) {
292324
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
293325
goto err;
294326
}
327+
328+
/* blindm := blind * m mod order */
329+
if (!BN_mod_mul(blindm, blind, m, order, ctx)) {
330+
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
331+
goto err;
332+
}
333+
334+
/* s : = (blind * priv_key * r) + (blind * m) mod order */
335+
if (!BN_mod_add_quick(s, tmp, blindm, order)) {
336+
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
337+
goto err;
338+
}
339+
340+
/* s:= s * blind^-1 mod order */
341+
if (BN_mod_inverse(blind, blind, order, ctx) == NULL) {
342+
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
343+
goto err;
344+
}
345+
if (!BN_mod_mul(s, s, blind, order, ctx)) {
346+
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
347+
goto err;
348+
}
349+
350+
/* s := s * k^-1 mod order */
295351
if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
296352
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
297353
goto err;
298354
}
355+
299356
if (BN_is_zero(s)) {
300357
/*
301358
* if kinv and r have been supplied by the caller don't to
@@ -317,9 +374,8 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
317374
ECDSA_SIG_free(ret);
318375
ret = NULL;
319376
}
377+
BN_CTX_end(ctx);
320378
BN_CTX_free(ctx);
321-
BN_clear_free(m);
322-
BN_clear_free(tmp);
323379
BN_clear_free(kinv);
324380
return ret;
325381
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.