Browse Source

Merge pull request #408 from libtom/pr/fix-cve-2018-12437

ecc_sign_hash blinding CVE-2018-12437
karel-m 7 years ago
parent
commit
6aef5e3765
1 changed files with 10 additions and 7 deletions
  1. 10 7
      src/pk/ecc/ecc_sign_hash.c

+ 10 - 7
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, const ecc_key *key, int sigformat)
                                 prng_state *prng, int wprng, const ecc_key *key, int sigformat)
 {
 {
    ecc_key       pubkey;
    ecc_key       pubkey;
-   void          *r, *s, *e, *p;
+   void          *r, *s, *e, *p, *b;
    int           err, max_iterations = LTC_PK_MAX_RETRIES;
    int           err, max_iterations = LTC_PK_MAX_RETRIES;
    unsigned long pbits, pbytes, i, shift_right;
    unsigned long pbits, pbytes, i, shift_right;
    unsigned char ch, buf[MAXBLOCKSIZE];
    unsigned char ch, buf[MAXBLOCKSIZE];
@@ -37,7 +37,7 @@ static int _ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
    }
    }
 
 
    /* init the bignums */
    /* init the bignums */
-   if ((err = mp_init_multi(&r, &s, &e, NULL)) != CRYPT_OK) {
+   if ((err = mp_init_multi(&r, &s, &e, &b, NULL)) != CRYPT_OK) {
       return err;
       return err;
    }
    }
 
 
@@ -72,12 +72,15 @@ static int _ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
       if (mp_iszero(r) == LTC_MP_YES) {
       if (mp_iszero(r) == LTC_MP_YES) {
          ecc_free(&pubkey);
          ecc_free(&pubkey);
       } else {
       } else {
+         if ((err = rand_bn_upto(b, p, prng, wprng)) != CRYPT_OK)          { goto error; } /* b = blinding value */
          /* find s = (e + xr)/k */
          /* 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_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);
          ecc_free(&pubkey);
          if (mp_iszero(s) == LTC_MP_NO) {
          if (mp_iszero(s) == LTC_MP_NO) {
             break;
             break;
@@ -111,7 +114,7 @@ static int _ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
 error:
 error:
    ecc_free(&pubkey);
    ecc_free(&pubkey);
 errnokey:
 errnokey:
-   mp_clear_multi(r, s, e, NULL);
+   mp_clear_multi(r, s, e, b, NULL);
    return err;
    return err;
 }
 }