From 2a0c037f98c8d6c02f47fec2df1375338f7f17fe Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 4 Dec 2019 11:08:28 +1000 Subject: [PATCH] Improve wc_ecc_mulmod_ex cache attack resistance --- wolfcrypt/src/ecc.c | 117 ++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 63 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 90c2d3f2e..d910446d4 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -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 */ }