Merge pull request #2637 from SparkiDev/ecc_cache_resist

Improve wc_ecc_mulmod_ex cache attack resistance
pull/2687/head
toddouska 2019-12-17 15:16:16 -08:00 committed by GitHub
commit 5ee9f9c7a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 54 additions and 63 deletions

View File

@ -2795,102 +2795,93 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
i = (buf >> (DIGIT_BIT - 1)) & 1;
buf <<= 1;
#ifdef WC_NO_CACHE_RESISTANT
if (mode == 0) {
mode = i;
/* timing resistant - dummy operations */
if (err == MP_OKAY)
err = ecc_projective_add_point(M[1], M[2], M[2], a, modulus,
mp);
#ifdef WC_NO_CACHE_RESISTANT
if (err == MP_OKAY)
err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
#else
/* instead of using M[i] for double, which leaks key bit to cache
* monitor, use M[2] as temp, make sure address calc is constant,
* keep M[0] and M[1] in cache */
if (err == MP_OKAY)
err = mp_copy((mp_int*)
( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->x & wc_off_on_addr[i])),
M[2]->x);
if (err == MP_OKAY)
err = mp_copy((mp_int*)
( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->y & wc_off_on_addr[i])),
M[2]->y);
if (err == MP_OKAY)
err = mp_copy((mp_int*)
( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->z & wc_off_on_addr[i])),
M[2]->z);
if (err == MP_OKAY)
err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
/* copy M[2] back to M[i] */
if (err == MP_OKAY)
err = mp_copy(M[2]->x,
(mp_int*)
( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->x & wc_off_on_addr[i])) );
if (err == MP_OKAY)
err = mp_copy(M[2]->y,
(mp_int*)
( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->y & wc_off_on_addr[i])) );
if (err == MP_OKAY)
err = mp_copy(M[2]->z,
(mp_int*)
( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->z & wc_off_on_addr[i])) );
#endif
}
else {
if (err == MP_OKAY)
continue;
err = ecc_projective_add_point(M[0], M[1], M[i^1], a,
modulus, mp);
if (err == MP_OKAY)
err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp);
}
if (err == MP_OKAY)
err = ecc_projective_add_point(M[0], M[1], M[i^1], a, modulus,
mp);
#ifdef WC_NO_CACHE_RESISTANT
if (err == MP_OKAY)
err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp);
mode |= i;
#else
if (err == MP_OKAY)
err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
mp);
if (err == MP_OKAY)
err = mp_copy(M[2]->x,
(mp_int*)
( ((size_t)M[0]->x & wc_off_on_addr[mode&(i )]) +
((size_t)M[1]->x & wc_off_on_addr[mode&(i^1)]) +
((size_t)M[2]->x & wc_off_on_addr[mode^1])) );
if (err == MP_OKAY)
err = mp_copy(M[2]->y,
(mp_int*)
( ((size_t)M[0]->y & wc_off_on_addr[mode&(i )]) +
((size_t)M[1]->y & wc_off_on_addr[mode&(i^1)]) +
((size_t)M[2]->y & wc_off_on_addr[mode^1])) );
if (err == MP_OKAY)
err = mp_copy(M[2]->z,
(mp_int*)
( ((size_t)M[0]->z & wc_off_on_addr[mode&(i )]) +
((size_t)M[1]->z & wc_off_on_addr[mode&(i^1)]) +
((size_t)M[2]->z & wc_off_on_addr[mode^1])) );
/* instead of using M[i] for double, which leaks key bit to cache
* monitor, use M[2] as temp, make sure address calc is constant,
* keep M[0] and M[1] in cache */
if (err == MP_OKAY)
err = mp_copy((mp_int*)
( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->x & wc_off_on_addr[i])),
( ((size_t)M[0]->x & wc_off_on_addr[i^1]) +
((size_t)M[1]->x & wc_off_on_addr[i])),
M[2]->x);
if (err == MP_OKAY)
err = mp_copy((mp_int*)
( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->y & wc_off_on_addr[i])),
( ((size_t)M[0]->y & wc_off_on_addr[i^1]) +
((size_t)M[1]->y & wc_off_on_addr[i])),
M[2]->y);
if (err == MP_OKAY)
err = mp_copy((mp_int*)
( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->z & wc_off_on_addr[i])),
( ((size_t)M[0]->z & wc_off_on_addr[i^1]) +
((size_t)M[1]->z & wc_off_on_addr[i])),
M[2]->z);
if (err == MP_OKAY)
err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp);
err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
/* copy M[2] back to M[i] */
if (err == MP_OKAY)
err = mp_copy(M[2]->x,
err = mp_copy((mp_int*)
(((size_t)M[2]->x & wc_off_on_addr[mode^1]) +
((size_t)M[3]->x & wc_off_on_addr[mode])),
(mp_int*)
( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->x & wc_off_on_addr[i])) );
( ((size_t)M[0]->x & wc_off_on_addr[i^1]) +
((size_t)M[1]->x & wc_off_on_addr[i])) );
if (err == MP_OKAY)
err = mp_copy(M[2]->y,
err = mp_copy((mp_int*)
(((size_t)M[2]->y & wc_off_on_addr[mode^1]) +
((size_t)M[3]->y & wc_off_on_addr[mode])),
(mp_int*)
( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->y & wc_off_on_addr[i])) );
( ((size_t)M[0]->y & wc_off_on_addr[i^1]) +
((size_t)M[1]->y & wc_off_on_addr[i])) );
if (err == MP_OKAY)
err = mp_copy(M[2]->z,
err = mp_copy((mp_int*)
(((size_t)M[2]->z & wc_off_on_addr[mode^1]) +
((size_t)M[3]->z & wc_off_on_addr[mode])),
(mp_int*)
( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
((wolfssl_word)M[1]->z & wc_off_on_addr[i])) );
( ((size_t)M[0]->z & wc_off_on_addr[i^1]) +
((size_t)M[1]->z & wc_off_on_addr[i])) );
if (err != MP_OKAY)
break;
mode |= i;
#endif /* WC_NO_CACHE_RESISTANT */
} /* end for */
}