CVE-2018-12436 (C, published 2018-06-15T02:29Z)
Description: value: wolfcrypt/src/ecc.c in wolfSSL before 3.15.1.patch allows a memory-cache side-channel attack on ECDSA signatures, aka the Return Of the Hidden Number Problem or ROHNP. To discover an ECDSA key, the attacker needs access to either the local machine or a different virtual machine on the same physical host.
Severity: LOW (CVSS v3 base score: 4.7)
Weakness: CWE-200 \u2014 Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Repository: https://github.com/wolfSSL/wolfssl
Files changed:
wolfcrypt/src/ecc.c
Commit message: Change ECDSA signing to use blinding.


Vulnerable code:
    /* quick sanity check to make sure we're not dealing with a 0 key */
    if (err == MP_OKAY) {
        if (mp_iszero(k) == MP_YES)
          err = MP_ZERO_E;
    }

           if (key->idx == ECC_CUSTOM_IDX) {
                                                              key->dp->id);
                   /* find s = (e + xr)/k */
                   /* s = xr */
                   /* s = e +  xr */
                   /* s = e +  xr */
                   err = mp_mod(s, curve->order, s);
                   err = mp_mulmod(s, &pubkey.k, curve->order, s);

Fixed code:
    /* quick sanity check to make sure we're not dealing with a 0 key */
    if (err == MP_OKAY) {
        if (mp_iszero(k) == MP_YES)
          err = MP_ZERO_E;
    }

           mp_int b;

           if (err == MP_OKAY) {
               err = mp_init(&b);
           }

           if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
           if (err == MP_OKAY) {
               /* Generate blinding value - non-zero value. */
               do {
                   if (++loop_check > 64) {
                        err = RNG_FAILURE_E;
                        break;
                   }

                   err = wc_ecc_gen_k(rng, key->dp->size, &b, curve->order);
               }
               while (err == MP_ZERO_E);
               loop_check = 0;
           }

                                                                   key->dp->id);
                   /* find s = (e + xr)/k
                             = b.(e/k.b + x.r/k.b) */

                   /* k = k.b */
                   err = mp_mulmod(&pubkey.k, &b, curve->order, &pubkey.k);
                   if (err != MP_OKAY) break;

                   /* k = 1/k.b */
                   /* s = x.r */
                   /* s = x.r/k.b */
                   err = mp_mulmod(&pubkey.k, s, curve->order, s);
                   if (err != MP_OKAY) break;

                   /* e = e/k.b */
                   err = mp_mulmod(&pubkey.k, e, curve->order, e);
                   if (err != MP_OKAY) break;

                   /* s = e/k.b + x.r/k.b
                        = (e + x.r)/k.b */
                   /* s = b.(e + x.r)/k.b
                        = (e + x.r)/k */
                   err = mp_mulmod(s, &b, curve->order, s);
                   err = mp_mod(s, curve->order, s);
                   if (err != MP_OKAY) break;
           mp_clear(&b);
           mp_free(&b);