From 250eced90497121e75b0edc4827c1cba7a9c75c2 Mon Sep 17 00:00:00 2001 From: karel-m <1918753+karel-m@users.noreply.github.com> Date: Tue, 19 Jun 2018 09:30:51 +0200 Subject: [PATCH] Merge pull request #408 from libtom/pr/fix-cve-2018-12437 ecc_sign_hash blinding CVE-2018-12437 (cherry picked from commit 6aef5e3765cb84dd610883932c170975cf254167) --- src/pk/ecc/ecc_sign_hash.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/pk/ecc/ecc_sign_hash.c b/src/pk/ecc/ecc_sign_hash.c index 46cdfa36..5d435699 100644 --- a/src/pk/ecc/ecc_sign_hash.c +++ b/src/pk/ecc/ecc_sign_hash.c @@ -21,7 +21,7 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, prng_state *prng, int wprng, ecc_key *key, int sigformat) { ecc_key pubkey; - void *r, *s, *e, *p; + void *r, *s, *e, *p, *b; int err, max_iterations = LTC_PK_MAX_RETRIES; unsigned long pbits, pbytes, i, shift_right; unsigned char ch, buf[MAXBLOCKSIZE]; @@ -46,7 +46,7 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, } /* init the bignums */ - if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { + if ((err = mp_init_multi(&r, &s, &p, &e, &b, NULL)) != CRYPT_OK) { return err; } if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; } @@ -82,12 +82,15 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, if (mp_iszero(r) == LTC_MP_YES) { ecc_free(&pubkey); } else { + if ((err = rand_bn_upto(b, p, prng, wprng)) != CRYPT_OK) { goto error; } /* b = blinding value */ /* find s = (e + xr)/k */ - if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */ + if ((err = mp_mulmod(pubkey.k, b, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = kb */ + if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/kb */ if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */ - if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ - if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ - if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */ + if ((err = mp_mulmod(pubkey.k, s, p, s)) != CRYPT_OK) { goto error; } /* s = xr/kb */ + if ((err = mp_mulmod(pubkey.k, e, p, e)) != CRYPT_OK) { goto error; } /* e = e/kb */ + if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e/kb + xr/kb */ + if ((err = mp_mulmod(s, b, p, s)) != CRYPT_OK) { goto error; } /* s = b(e/kb + xr/kb) = (e + xr)/k */ ecc_free(&pubkey); if (mp_iszero(s) == LTC_MP_NO) { break; @@ -121,7 +124,7 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, error: ecc_free(&pubkey); errnokey: - mp_clear_multi(r, s, p, e, NULL); + mp_clear_multi(r, s, p, e, b, NULL); return err; }