diff --git a/.github/configs/os-check-linux.json b/.github/configs/os-check-linux.json index 08f78b993bd..3343331fab6 100644 --- a/.github/configs/os-check-linux.json +++ b/.github/configs/os-check-linux.json @@ -98,6 +98,28 @@ "comment": "Non-blocking ECC on the portable C implementation without the small math; RSA/DH non-block are left off because their mod_exp only exists in the small variant.", "configure": ["--enable-ecc=nonblock", "--enable-sp=yes,nonblocklarge", "--disable-sp-asm", "CPPFLAGS=-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK"]}, +{"name": "modexp-copy-default-sakke", "minutes": 2.6, + "comment": "Default (address-oblivious) cache-resistant modexp copy on a normal target: _sp_exptmod_mont_ex (sp_int.c) via _sp_cond_copy and the SAKKE ladder (sakke.c) via mp_cond_copy, which touch both t[0] and t[1] so the accessed address is secret-independent. Nothing else in this matrix builds SAKKE, and on a non-capability target the sp_int.c default is only otherwise reached incidentally. Pairs with modexp-copy-fast-sakke, which flips both to the pointer-copy opt-in.", + "configure": ["--enable-sakke", "--enable-sp-math-all"]}, +{"name": "modexp-copy-fast-sakke", "minutes": 2.6, + "comment": "WOLFSSL_SP_FAST_MODEXP_COPY opt-in: the faster secret-dependent-pointer copy in _sp_exptmod_mont_ex (sp_int.c) and the SAKKE ladder (sakke.c). That branch is the #else of the oblivious default and is compiled by no other entry, and the macro is forced off on the capability (WC_NO_PTR_INT_CAST) legs in fil-c.yml, so a normal target is the only place it is built.", + "configure": ["--enable-sakke", "--enable-sp-math-all", + "CPPFLAGS=-DWOLFSSL_SP_FAST_MODEXP_COPY"]}, +{"name": "sp-ladder-modexp", "minutes": 2.0, + "comment": "Specialized SP in portable C (sp_c64.c on x86_64) with WOLFSSL_SP_LADDER_MODEXP, which replaces the windowed exptmod with the cache-resistant ladder. Default (oblivious) copy via sp_cond_select/sp_cond_memcpy. --disable-sp-asm keeps RSA/DH/ECC on the generated C files; nothing else here builds the non-small ladder on a normal target.", + "configure": ["--enable-sp", "--disable-sp-asm", + "CPPFLAGS=-DWOLFSSL_SP_LADDER_MODEXP"]}, +{"name": "sp-ladder-modexp-fast-copy", "minutes": 2.0, + "comment": "Same sp_c64.c ladder as sp-ladder-modexp but with WOLFSSL_SP_FAST_MODEXP_COPY opting the copy onto addr_mask pointer selection (the #else branch) instead of sp_cond_select/sp_cond_memcpy.", + "configure": ["--enable-sp", "--disable-sp-asm", + "CPPFLAGS=-DWOLFSSL_SP_LADDER_MODEXP -DWOLFSSL_SP_FAST_MODEXP_COPY"]}, +{"name": "fastmath-modexp-copy-default", "minutes": 2.4, + "comment": "TomsFastMath (tfm.c) on a normal target: fp_exptmod_ct selects the working value with the address-oblivious fp_cond_copy default. os-check otherwise builds no fastmath leg (only fil-c.yml does, where WC_NO_PTR_INT_CAST already forces this branch); this covers it under plain gcc. Pairs with fastmath-modexp-copy-fast.", + "configure": ["--enable-fastmath"]}, +{"name": "fastmath-modexp-copy-fast", "minutes": 2.4, + "comment": "tfm.c fp_exptmod_ct with WOLFSSL_SP_FAST_MODEXP_COPY opting onto the wc_off_on_addr pointer copy (the #else branch). Forced off on the fil-c.yml capability legs, so a normal target is the only place this branch is built.", + "configure": ["--enable-fastmath", + "CPPFLAGS=-DWOLFSSL_SP_FAST_MODEXP_COPY"]}, {"name": "all-asn-template", "minutes": 3.5, "configure": ["--enable-all", "--enable-asn=template"]}, {"name": "chain-verify-cb-async", "minutes": 3.5, diff --git a/doc/ASM_AND_MATH_DEFINES.md b/doc/ASM_AND_MATH_DEFINES.md index ad996babbac..b52e0cca263 100644 --- a/doc/ASM_AND_MATH_DEFINES.md +++ b/doc/ASM_AND_MATH_DEFINES.md @@ -281,6 +281,7 @@ so choose according to what your target has: | `WC_PROTECT_ENCRYPTED_MEM` | Extra protection for operations on encrypted memory. | | `WC_NO_CACHE_RESISTANT` | Disable cache-resistant (constant-address) table access. Faster, weaker. | | `WC_NO_HARDEN` | Disable timing-attack resistance. Faster, weaker. | +| `WOLFSSL_SP_FAST_MODEXP_COPY` | Select the cache-resistant `mod_exp` working value with a single secret-dependent pointer copy instead of touching both candidates. Faster, but leaks the exponent at cache-line granularity. Off by default; forced off on capability targets. | | `WOLFSSL_NO_CT_OPS` | Disable constant-time operations. | | `WOLFSSL_CHECK_MEM_ZERO` | Check that sensitive memory is zeroed on free (debug). | @@ -289,6 +290,26 @@ wolfSSL recommends against defining `WC_NO_HARDEN`, `WC_NO_CACHE_RESISTANT` or your threat model genuinely excludes an attacker able to observe local timing or cache behaviour. The performance gain is small relative to the protection lost. +The cache-resistant modular exponentiation (and the ECC/SAKKE scalar-mult +ladders) select the working value from one of two objects on each secret +exponent bit. By default that selection is **address-oblivious**: both objects +are accessed every iteration through a masked constant-time copy +(`_sp_cond_copy` in `sp_int.c`, `sp_cond_select`/`sp_cond_memcpy` in the +specialised `sp_.c`, `fp_cond_copy` in `tfm.c`, `mp_cond_copy` in +`sakke.c`), so the touched memory address does not depend on the secret. This +resists a co-resident attacker that can observe cache-line accesses, for example +`Prime+Probe` from a sibling SMT thread sharing the L1 data cache. Defining +`WOLFSSL_SP_FAST_MODEXP_COPY` switches to the older, faster variant that computes +a single secret-dependent pointer by address masking and copies only the +selected object; it is a few percent faster on private-key operations but +discloses the exponent bits at cache-line granularity, so enable it only where a +co-resident cache observer is outside your threat model. It requires rebuilding a +pointer from integer arithmetic on two addresses, which capability targets (those +that define `WC_NO_PTR_INT_CAST`, such as CHERI and Fil-C) cannot do, so the +option is ignored and the oblivious copy is always used there. It is also a no-op +for the default windowed `mod_exp` used by the specialised SP assembly back ends, +which select from a table scanned in full rather than from two objects. + ### Non-blocking `WOLFSSL_SP_NONBLOCK` makes long operations return `FP_WOULDBLOCK` and expect diff --git a/wolfcrypt/src/sakke.c b/wolfcrypt/src/sakke.c index 0b74ee52ec5..213d75641a5 100644 --- a/wolfcrypt/src/sakke.c +++ b/wolfcrypt/src/sakke.c @@ -2617,6 +2617,24 @@ static int sakke_modexp_loop(SakkeKey* key, mp_int* b, mp_int* e, mp_proj* c, #elif defined(WOLFSSL_SAKKE_SMALL_MODEXP) || !defined(USE_FAST_MATH) +/* The cache-resistant SAKKE modexp ladder selects the working point from c[0] + * or c[1] on each exponent bit. By default this is done with mp_cond_copy(), + * which accesses both objects every iteration so the touched address does not + * depend on the secret bit (resists co-resident L1D cache attacks such as + * Prime+Probe between SMT siblings). + * + * Defining WOLFSSL_SP_FAST_MODEXP_COPY (the same opt-in used by the SP math + * backends) selects the faster variant that instead computes a single + * secret-dependent pointer with wc_off_on_addr masking and copies only the + * selected point. It is faster but leaks the exponent at cache-line + * granularity, so only enable it where a co-resident cache observer is outside + * the threat model. The fast variant rebuilds a pointer from integer arithmetic + * on two addresses, which capability targets cannot do, so it is forced off + * when WC_NO_PTR_INT_CAST is defined. */ +#if defined(WOLFSSL_SP_FAST_MODEXP_COPY) && !defined(WC_NO_PTR_INT_CAST) + #define WC_SAKKE_MODEXP_PTR_COPY +#endif + /* * Modular exponentiate the value in F_p*. * @@ -2643,7 +2661,10 @@ static int sakke_modexp_loop(SakkeKey* key, mp_int* b, mp_int* e, mp_proj* r, mp_int* by = key->tmp.p1->z; mp_int* prime = &key->params.prime; int i; -#ifdef WC_NO_GLOBAL_OBJECT_POINTERS + /* Local address mask only when the pointer-copy opt-in is active and global + * object pointers are unavailable; the default oblivious copy never uses + * it, so declaring it unconditionally is an unused variable. */ +#if defined(WC_NO_GLOBAL_OBJECT_POINTERS) && defined(WC_SAKKE_MODEXP_PTR_COPY) static const wc_ptr_t wc_off_on_addr[2] = { #if defined(WC_64BIT_CPU) @@ -2686,11 +2707,19 @@ static int sakke_modexp_loop(SakkeKey* key, mp_int* b, mp_int* e, mp_proj* r, err = sakke_proj_mul_qx1(c[0], by, prime, mp, c[j^1], t1, t2); #else err = sakke_proj_mul_qx1(c[0], by, prime, mp, c[2], t1, t2); -#ifdef WC_NO_PTR_INT_CAST - err = mp_cond_copy(c[2]->x, j, c[0]->x); - err = mp_cond_copy(c[2]->x, j^1, c[1]->x); - err = mp_cond_copy(c[2]->y, j, c[0]->y); - err = mp_cond_copy(c[2]->y, j^1, c[1]->y); +#ifndef WC_SAKKE_MODEXP_PTR_COPY + /* Guard each copy on err so a failure in the multiply above or in + * an earlier copy is preserved rather than overwritten. err does + * not depend on the secret bit, so all four copies still run (and + * touch both c[0] and c[1]) on the success path. */ + if (err == 0) + err = mp_cond_copy(c[2]->x, j, c[0]->x); + if (err == 0) + err = mp_cond_copy(c[2]->x, j^1, c[1]->x); + if (err == 0) + err = mp_cond_copy(c[2]->y, j, c[0]->y); + if (err == 0) + err = mp_cond_copy(c[2]->y, j^1, c[1]->y); #else mp_copy(c[2]->x, (mp_int*) ( ((wc_ptr_t)c[0]->x & wc_off_on_addr[j]) + diff --git a/wolfcrypt/src/sp_c32.c b/wolfcrypt/src/sp_c32.c index 3edd0cd1dd8..301e79e16d5 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -19,6 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +/* Generated by wolfSSL/scripts: + * ruby sp/sp.rb 32 \ + * ../wolfssl/wolfcrypt/src/sp_c32 + */ + /* Implementation by Sean Parkinson. */ #define WC_FIPS_LL_CRYPTO @@ -266,9 +271,26 @@ sp_uint64 __muldi3(sp_uint64 a, sp_uint64 b) #endif #ifdef NEED_ADDR_MASK -#ifdef WC_NO_PTR_INT_CAST -/* Pointers cannot be rebuilt from integer arithmetic on two addresses, such as - * on capability based targets. */ + +/* Cache-resistant modular exponentiation and ECC scalar multiplication select + * the working value from one of two objects on each secret bit. By default the + * selection is address-oblivious: both objects are accessed every iteration + * with sp_cond_select()/sp_cond_memcpy() so the touched address does not depend + * on the secret bit (resists co-resident L1D cache attacks such as Prime+Probe + * between SMT siblings). + * + * Defining WOLFSSL_SP_FAST_MODEXP_COPY opts in to the faster variant that + * computes a single secret-dependent pointer by address masking and copies only + * the selected object. It is faster but leaks the secret bit at cache-line + * granularity, so only enable it where a co-resident cache observer is outside + * the threat model. It rebuilds a pointer from integer arithmetic on two + * addresses, which capability targets cannot do, so it is forced off when + * WC_NO_PTR_INT_CAST is defined. */ +#if defined(WOLFSSL_SP_FAST_MODEXP_COPY) && !defined(WC_NO_PTR_INT_CAST) + #define WOLFSSL_SP_PTR_COPY +#endif + +#ifndef WOLFSSL_SP_PTR_COPY /* Conditionally copy len bytes from a to r when copy is 1, in constant time. * Reads r, so r must be initialized. Both candidates are always touched, so @@ -302,7 +324,9 @@ WC_MAYBE_UNUSED static void sp_cond_select(void* r, const void* a, } } #else -/* Mask for address to obfuscate which of the two address will be used. */ +/* Address-selection mask for the WOLFSSL_SP_FAST_MODEXP_COPY pointer copy: + * index 0 -> all-zero, index 1 -> all-ones, so a masked sum resolves to one of + * two addresses without a branch. */ static const size_t addr_mask[2] = { 0, (size_t)-1 }; #endif #endif @@ -2498,7 +2522,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 36 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -2506,7 +2530,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 36 * 2); #endif sp_2048_mont_sqr_36(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 36 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 36 * 2); #else @@ -2670,7 +2694,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 36 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -2678,7 +2702,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 36 * 2); #endif sp_2048_mont_sqr_36(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 36 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 36 * 2); #else @@ -3801,7 +3825,7 @@ static int sp_2048_mod_exp_72(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_72(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 72 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -3809,7 +3833,7 @@ static int sp_2048_mod_exp_72(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 72 * 2); #endif sp_2048_mont_sqr_72(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 72 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 72 * 2); #else @@ -3973,7 +3997,7 @@ static int sp_2048_mod_exp_72(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_72(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 72 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -3981,7 +4005,7 @@ static int sp_2048_mod_exp_72(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 72 * 2); #endif sp_2048_mont_sqr_72(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 72 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 72 * 2); #else @@ -4352,7 +4376,7 @@ static int sp_2048_mod_exp_72_nb(sp_2048_mod_exp_72_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 72 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -4366,7 +4390,7 @@ static int sp_2048_mod_exp_72_nb(sp_2048_mod_exp_72_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 72 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 72 * 2); #else @@ -7042,7 +7066,7 @@ static int sp_3072_mod_exp_53(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_53(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 53 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -7050,7 +7074,7 @@ static int sp_3072_mod_exp_53(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 53 * 2); #endif sp_3072_mont_sqr_53(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 53 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 53 * 2); #else @@ -7214,7 +7238,7 @@ static int sp_3072_mod_exp_53(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_53(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 53 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -7222,7 +7246,7 @@ static int sp_3072_mod_exp_53(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 53 * 2); #endif sp_3072_mont_sqr_53(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 53 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 53 * 2); #else @@ -8119,7 +8143,7 @@ static int sp_3072_mod_exp_106(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_106(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 106 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -8127,7 +8151,7 @@ static int sp_3072_mod_exp_106(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 106 * 2); #endif sp_3072_mont_sqr_106(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 106 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 106 * 2); #else @@ -8291,7 +8315,7 @@ static int sp_3072_mod_exp_106(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_106(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 106 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -8299,7 +8323,7 @@ static int sp_3072_mod_exp_106(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 106 * 2); #endif sp_3072_mont_sqr_106(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 106 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 106 * 2); #else @@ -8670,7 +8694,7 @@ static int sp_3072_mod_exp_106_nb(sp_3072_mod_exp_106_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 106 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -8684,7 +8708,7 @@ static int sp_3072_mod_exp_106_nb(sp_3072_mod_exp_106_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 106 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 106 * 2); #else @@ -11934,7 +11958,7 @@ static int sp_3072_mod_exp_56(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_56(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 56 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -11942,7 +11966,7 @@ static int sp_3072_mod_exp_56(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 56 * 2); #endif sp_3072_mont_sqr_56(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 56 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 56 * 2); #else @@ -12106,7 +12130,7 @@ static int sp_3072_mod_exp_56(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_56(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 56 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -12114,7 +12138,7 @@ static int sp_3072_mod_exp_56(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 56 * 2); #endif sp_3072_mont_sqr_56(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 56 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 56 * 2); #else @@ -13093,7 +13117,7 @@ static int sp_3072_mod_exp_112(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_112(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 112 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -13101,7 +13125,7 @@ static int sp_3072_mod_exp_112(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 112 * 2); #endif sp_3072_mont_sqr_112(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 112 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 112 * 2); #else @@ -13265,7 +13289,7 @@ static int sp_3072_mod_exp_112(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_112(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 112 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -13273,7 +13297,7 @@ static int sp_3072_mod_exp_112(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 112 * 2); #endif sp_3072_mont_sqr_112(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 112 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 112 * 2); #else @@ -13644,7 +13668,7 @@ static int sp_3072_mod_exp_112_nb(sp_3072_mod_exp_112_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 112 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -13658,7 +13682,7 @@ static int sp_3072_mod_exp_112_nb(sp_3072_mod_exp_112_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 112 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 112 * 2); #else @@ -16006,7 +16030,7 @@ static int sp_4096_mod_exp_71(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_71(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 71 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -16014,7 +16038,7 @@ static int sp_4096_mod_exp_71(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 71 * 2); #endif sp_4096_mont_sqr_71(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 71 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 71 * 2); #else @@ -16178,7 +16202,7 @@ static int sp_4096_mod_exp_71(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_71(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 71 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -16186,7 +16210,7 @@ static int sp_4096_mod_exp_71(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 71 * 2); #endif sp_4096_mont_sqr_71(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 71 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 71 * 2); #else @@ -17084,7 +17108,7 @@ static int sp_4096_mod_exp_142(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_142(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 142 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -17092,7 +17116,7 @@ static int sp_4096_mod_exp_142(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 142 * 2); #endif sp_4096_mont_sqr_142(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 142 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 142 * 2); #else @@ -17256,7 +17280,7 @@ static int sp_4096_mod_exp_142(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_142(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 142 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -17264,7 +17288,7 @@ static int sp_4096_mod_exp_142(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 142 * 2); #endif sp_4096_mont_sqr_142(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 142 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 142 * 2); #else @@ -17635,7 +17659,7 @@ static int sp_4096_mod_exp_142_nb(sp_4096_mod_exp_142_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 142 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -17649,7 +17673,7 @@ static int sp_4096_mod_exp_142_nb(sp_4096_mod_exp_142_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 142 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 142 * 2); #else @@ -20842,7 +20866,7 @@ static int sp_4096_mod_exp_81(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_81(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 81 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -20850,7 +20874,7 @@ static int sp_4096_mod_exp_81(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 81 * 2); #endif sp_4096_mont_sqr_81(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 81 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 81 * 2); #else @@ -21014,7 +21038,7 @@ static int sp_4096_mod_exp_81(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_81(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 81 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -21022,7 +21046,7 @@ static int sp_4096_mod_exp_81(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 81 * 2); #endif sp_4096_mont_sqr_81(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 81 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 81 * 2); #else @@ -21988,7 +22012,7 @@ static int sp_4096_mod_exp_162(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_162(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 162 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -21996,7 +22020,7 @@ static int sp_4096_mod_exp_162(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 162 * 2); #endif sp_4096_mont_sqr_162(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 162 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 162 * 2); #else @@ -22160,7 +22184,7 @@ static int sp_4096_mod_exp_162(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_162(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 162 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -22168,7 +22192,7 @@ static int sp_4096_mod_exp_162(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 162 * 2); #endif sp_4096_mont_sqr_162(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 162 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 162 * 2); #else @@ -22539,7 +22563,7 @@ static int sp_4096_mod_exp_162_nb(sp_4096_mod_exp_162_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 162 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -22553,7 +22577,7 @@ static int sp_4096_mod_exp_162_nb(sp_4096_mod_exp_162_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 162 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 162 * 2); #else @@ -25806,7 +25830,7 @@ static int sp_256_ecc_mulmod_9(sp_point_256* r, const sp_point_256* g, sp_256_proj_point_add_9(&t[y^1], &t[0], &t[1], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&t[2], &t[0], &t[1], (y), sizeof(sp_point_256)); #else XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + @@ -25814,7 +25838,7 @@ static int sp_256_ecc_mulmod_9(sp_point_256* r, const sp_point_256* g, sizeof(sp_point_256)); #endif sp_256_proj_point_dbl_9(&t[2], &t[2], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&t[0], &t[2], (y)^1, sizeof(sp_point_256)); sp_cond_memcpy(&t[1], &t[2], (y), sizeof(sp_point_256)); #else @@ -27007,7 +27031,7 @@ static int sp_256_ecc_mulmod_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, err = sp_256_proj_point_add_9_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&ctx->t[2], &ctx->t[0], &ctx->t[1], (ctx->y), sizeof(sp_point_256)); #else XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + @@ -27022,7 +27046,7 @@ static int sp_256_ecc_mulmod_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, err = sp_256_proj_point_dbl_9_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2], &ctx->t[2], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&ctx->t[0], &ctx->t[2], (ctx->y)^1, sizeof(sp_point_256)); sp_cond_memcpy(&ctx->t[1], &ctx->t[2], (ctx->y), sizeof(sp_point_256)); #else @@ -33432,7 +33456,7 @@ static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, sp_384_proj_point_add_15(&t[y^1], &t[0], &t[1], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&t[2], &t[0], &t[1], (y), sizeof(sp_point_384)); #else XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + @@ -33440,7 +33464,7 @@ static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, sizeof(sp_point_384)); #endif sp_384_proj_point_dbl_15(&t[2], &t[2], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&t[0], &t[2], (y)^1, sizeof(sp_point_384)); sp_cond_memcpy(&t[1], &t[2], (y), sizeof(sp_point_384)); #else @@ -34705,7 +34729,7 @@ static int sp_384_ecc_mulmod_15_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, err = sp_384_proj_point_add_15_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&ctx->t[2], &ctx->t[0], &ctx->t[1], (ctx->y), sizeof(sp_point_384)); #else XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + @@ -34720,7 +34744,7 @@ static int sp_384_ecc_mulmod_15_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, err = sp_384_proj_point_dbl_15_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2], &ctx->t[2], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&ctx->t[0], &ctx->t[2], (ctx->y)^1, sizeof(sp_point_384)); sp_cond_memcpy(&ctx->t[1], &ctx->t[2], (ctx->y), sizeof(sp_point_384)); #else @@ -41123,7 +41147,7 @@ static int sp_521_ecc_mulmod_21(sp_point_521* r, const sp_point_521* g, sp_521_proj_point_add_21(&t[y^1], &t[0], &t[1], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&t[2], &t[0], &t[1], (y), sizeof(sp_point_521)); #else XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + @@ -41131,7 +41155,7 @@ static int sp_521_ecc_mulmod_21(sp_point_521* r, const sp_point_521* g, sizeof(sp_point_521)); #endif sp_521_proj_point_dbl_21(&t[2], &t[2], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&t[0], &t[2], (y)^1, sizeof(sp_point_521)); sp_cond_memcpy(&t[1], &t[2], (y), sizeof(sp_point_521)); #else @@ -42468,7 +42492,7 @@ static int sp_521_ecc_mulmod_21_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r, err = sp_521_proj_point_add_21_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&ctx->t[2], &ctx->t[0], &ctx->t[1], (ctx->y), sizeof(sp_point_521)); #else XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + @@ -42483,7 +42507,7 @@ static int sp_521_ecc_mulmod_21_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r, err = sp_521_proj_point_dbl_21_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2], &ctx->t[2], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&ctx->t[0], &ctx->t[2], (ctx->y)^1, sizeof(sp_point_521)); sp_cond_memcpy(&ctx->t[1], &ctx->t[2], (ctx->y), sizeof(sp_point_521)); #else @@ -49747,7 +49771,7 @@ static int sp_1024_ecc_mulmod_42(sp_point_1024* r, const sp_point_1024* g, sp_1024_proj_point_add_42(&t[y^1], &t[0], &t[1], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&t[2], &t[0], &t[1], (y), sizeof(sp_point_1024)); #else XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + @@ -49755,7 +49779,7 @@ static int sp_1024_ecc_mulmod_42(sp_point_1024* r, const sp_point_1024* g, sizeof(sp_point_1024)); #endif sp_1024_proj_point_dbl_42(&t[2], &t[2], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&t[0], &t[2], (y)^1, sizeof(sp_point_1024)); sp_cond_memcpy(&t[1], &t[2], (y), sizeof(sp_point_1024)); #else diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index 93da67e2df6..dcaf011e9ce 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -19,6 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +/* Generated by wolfSSL/scripts: + * ruby sp/sp.rb 64 \ + * ../wolfssl/wolfcrypt/src/sp_c64 + */ + /* Implementation by Sean Parkinson. */ #define WC_FIPS_LL_CRYPTO @@ -192,9 +197,26 @@ #endif #ifdef NEED_ADDR_MASK -#ifdef WC_NO_PTR_INT_CAST -/* Pointers cannot be rebuilt from integer arithmetic on two addresses, such as - * on capability based targets. */ + +/* Cache-resistant modular exponentiation and ECC scalar multiplication select + * the working value from one of two objects on each secret bit. By default the + * selection is address-oblivious: both objects are accessed every iteration + * with sp_cond_select()/sp_cond_memcpy() so the touched address does not depend + * on the secret bit (resists co-resident L1D cache attacks such as Prime+Probe + * between SMT siblings). + * + * Defining WOLFSSL_SP_FAST_MODEXP_COPY opts in to the faster variant that + * computes a single secret-dependent pointer by address masking and copies only + * the selected object. It is faster but leaks the secret bit at cache-line + * granularity, so only enable it where a co-resident cache observer is outside + * the threat model. It rebuilds a pointer from integer arithmetic on two + * addresses, which capability targets cannot do, so it is forced off when + * WC_NO_PTR_INT_CAST is defined. */ +#if defined(WOLFSSL_SP_FAST_MODEXP_COPY) && !defined(WC_NO_PTR_INT_CAST) + #define WOLFSSL_SP_PTR_COPY +#endif + +#ifndef WOLFSSL_SP_PTR_COPY /* Conditionally copy len bytes from a to r when copy is 1, in constant time. * Reads r, so r must be initialized. Both candidates are always touched, so @@ -228,7 +250,9 @@ WC_MAYBE_UNUSED static void sp_cond_select(void* r, const void* a, } } #else -/* Mask for address to obfuscate which of the two address will be used. */ +/* Address-selection mask for the WOLFSSL_SP_FAST_MODEXP_COPY pointer copy: + * index 0 -> all-zero, index 1 -> all-ones, so a masked sum resolves to one of + * two addresses without a branch. */ static const size_t addr_mask[2] = { 0, (size_t)-1 }; #endif #endif @@ -1323,7 +1347,7 @@ static int sp_2048_mod_exp_17(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_17(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 17 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -1331,7 +1355,7 @@ static int sp_2048_mod_exp_17(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 17 * 2); #endif sp_2048_mont_sqr_17(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 17 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 17 * 2); #else @@ -1495,7 +1519,7 @@ static int sp_2048_mod_exp_17(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_17(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 17 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -1503,7 +1527,7 @@ static int sp_2048_mod_exp_17(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 17 * 2); #endif sp_2048_mont_sqr_17(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 17 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 17 * 2); #else @@ -2386,7 +2410,7 @@ static int sp_2048_mod_exp_34(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_34(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 34 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -2394,7 +2418,7 @@ static int sp_2048_mod_exp_34(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 34 * 2); #endif sp_2048_mont_sqr_34(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 34 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 34 * 2); #else @@ -2558,7 +2582,7 @@ static int sp_2048_mod_exp_34(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_34(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 34 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -2566,7 +2590,7 @@ static int sp_2048_mod_exp_34(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 34 * 2); #endif sp_2048_mont_sqr_34(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 34 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 34 * 2); #else @@ -2937,7 +2961,7 @@ static int sp_2048_mod_exp_34_nb(sp_2048_mod_exp_34_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 34 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -2951,7 +2975,7 @@ static int sp_2048_mod_exp_34_nb(sp_2048_mod_exp_34_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 34 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 34 * 2); #else @@ -5716,7 +5740,7 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 18 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -5724,7 +5748,7 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 18 * 2); #endif sp_2048_mont_sqr_18(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 18 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 18 * 2); #else @@ -5888,7 +5912,7 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 18 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -5896,7 +5920,7 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 18 * 2); #endif sp_2048_mont_sqr_18(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 18 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 18 * 2); #else @@ -6842,7 +6866,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 36 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -6850,7 +6874,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 36 * 2); #endif sp_2048_mont_sqr_36(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 36 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 36 * 2); #else @@ -7014,7 +7038,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 36 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -7022,7 +7046,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 36 * 2); #endif sp_2048_mont_sqr_36(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 36 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 36 * 2); #else @@ -7393,7 +7417,7 @@ static int sp_2048_mod_exp_36_nb(sp_2048_mod_exp_36_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 36 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -7407,7 +7431,7 @@ static int sp_2048_mod_exp_36_nb(sp_2048_mod_exp_36_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 36 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 36 * 2); #else @@ -9507,7 +9531,7 @@ static int sp_3072_mod_exp_26(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_26(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 26 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -9515,7 +9539,7 @@ static int sp_3072_mod_exp_26(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 26 * 2); #endif sp_3072_mont_sqr_26(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 26 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 26 * 2); #else @@ -9679,7 +9703,7 @@ static int sp_3072_mod_exp_26(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_26(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 26 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -9687,7 +9711,7 @@ static int sp_3072_mod_exp_26(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 26 * 2); #endif sp_3072_mont_sqr_26(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 26 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 26 * 2); #else @@ -10576,7 +10600,7 @@ static int sp_3072_mod_exp_52(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_52(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 52 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -10584,7 +10608,7 @@ static int sp_3072_mod_exp_52(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 52 * 2); #endif sp_3072_mont_sqr_52(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 52 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 52 * 2); #else @@ -10748,7 +10772,7 @@ static int sp_3072_mod_exp_52(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_52(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 52 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -10756,7 +10780,7 @@ static int sp_3072_mod_exp_52(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 52 * 2); #endif sp_3072_mont_sqr_52(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 52 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 52 * 2); #else @@ -11127,7 +11151,7 @@ static int sp_3072_mod_exp_52_nb(sp_3072_mod_exp_52_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 52 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -11141,7 +11165,7 @@ static int sp_3072_mod_exp_52_nb(sp_3072_mod_exp_52_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 52 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 52 * 2); #else @@ -14056,7 +14080,7 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 27 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -14064,7 +14088,7 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 27 * 2); #endif sp_3072_mont_sqr_27(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 27 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 27 * 2); #else @@ -14228,7 +14252,7 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 27 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -14236,7 +14260,7 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 27 * 2); #endif sp_3072_mont_sqr_27(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 27 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 27 * 2); #else @@ -15193,7 +15217,7 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 54 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -15201,7 +15225,7 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 54 * 2); #endif sp_3072_mont_sqr_54(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 54 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 54 * 2); #else @@ -15365,7 +15389,7 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 54 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -15373,7 +15397,7 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 54 * 2); #endif sp_3072_mont_sqr_54(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 54 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 54 * 2); #else @@ -15744,7 +15768,7 @@ static int sp_3072_mod_exp_54_nb(sp_3072_mod_exp_54_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 54 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -15758,7 +15782,7 @@ static int sp_3072_mod_exp_54_nb(sp_3072_mod_exp_54_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 54 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 54 * 2); #else @@ -17900,7 +17924,7 @@ static int sp_4096_mod_exp_35(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_35(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 35 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -17908,7 +17932,7 @@ static int sp_4096_mod_exp_35(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 35 * 2); #endif sp_4096_mont_sqr_35(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 35 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 35 * 2); #else @@ -18072,7 +18096,7 @@ static int sp_4096_mod_exp_35(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_35(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 35 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -18080,7 +18104,7 @@ static int sp_4096_mod_exp_35(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 35 * 2); #endif sp_4096_mont_sqr_35(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 35 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 35 * 2); #else @@ -18964,7 +18988,7 @@ static int sp_4096_mod_exp_70(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_70(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 70 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -18972,7 +18996,7 @@ static int sp_4096_mod_exp_70(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 70 * 2); #endif sp_4096_mont_sqr_70(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 70 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 70 * 2); #else @@ -19136,7 +19160,7 @@ static int sp_4096_mod_exp_70(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_70(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 70 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -19144,7 +19168,7 @@ static int sp_4096_mod_exp_70(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 70 * 2); #endif sp_4096_mont_sqr_70(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 70 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 70 * 2); #else @@ -19515,7 +19539,7 @@ static int sp_4096_mod_exp_70_nb(sp_4096_mod_exp_70_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 70 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -19529,7 +19553,7 @@ static int sp_4096_mod_exp_70_nb(sp_4096_mod_exp_70_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 70 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 70 * 2); #else @@ -22542,7 +22566,7 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_39(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 39 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -22550,7 +22574,7 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 39 * 2); #endif sp_4096_mont_sqr_39(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 39 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 39 * 2); #else @@ -22714,7 +22738,7 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_39(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 39 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -22722,7 +22746,7 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 39 * 2); #endif sp_4096_mont_sqr_39(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 39 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 39 * 2); #else @@ -23680,7 +23704,7 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_78(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 78 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -23688,7 +23712,7 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 78 * 2); #endif sp_4096_mont_sqr_78(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 78 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 78 * 2); #else @@ -23852,7 +23876,7 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, sp_4096_mont_mul_78(t[y^1], t[0], t[1], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(t[2], t[0], t[1], (y), sizeof(*t[2]) * 78 * 2); #else XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + @@ -23860,7 +23884,7 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, sizeof(*t[2]) * 78 * 2); #endif sp_4096_mont_sqr_78(t[2], t[2], m, mp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(t[0], t[2], (y)^1, sizeof(*t[2]) * 78 * 2); sp_cond_memcpy(t[1], t[2], (y), sizeof(*t[2]) * 78 * 2); #else @@ -24231,7 +24255,7 @@ static int sp_4096_mod_exp_78_nb(sp_4096_mod_exp_78_ctx* ctx, ctx->state = 7; break; case 7: /* COPY_OUT: constant-time copy &t[y] -> t[2] */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(ctx->t[2], ctx->t[0], ctx->t[1], (ctx->y), sizeof(sp_digit) * 78 * 2); #else XMEMCPY(ctx->t[2], (void*)(((size_t)ctx->t[0] & addr_mask[ctx->y ^ 1]) + @@ -24245,7 +24269,7 @@ static int sp_4096_mod_exp_78_nb(sp_4096_mod_exp_78_ctx* ctx, ctx->state = 9; break; case 9: /* COPY_BACK: constant-time copy t[2] -> &t[y]; advance bit */ - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(ctx->t[0], ctx->t[2], (ctx->y)^1, sizeof(sp_digit) * 78 * 2); sp_cond_memcpy(ctx->t[1], ctx->t[2], (ctx->y), sizeof(sp_digit) * 78 * 2); #else @@ -27126,7 +27150,7 @@ static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, sp_256_proj_point_add_5(&t[y^1], &t[0], &t[1], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&t[2], &t[0], &t[1], (y), sizeof(sp_point_256)); #else XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + @@ -27134,7 +27158,7 @@ static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, sizeof(sp_point_256)); #endif sp_256_proj_point_dbl_5(&t[2], &t[2], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&t[0], &t[2], (y)^1, sizeof(sp_point_256)); sp_cond_memcpy(&t[1], &t[2], (y), sizeof(sp_point_256)); #else @@ -28279,7 +28303,7 @@ static int sp_256_ecc_mulmod_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, err = sp_256_proj_point_add_5_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&ctx->t[2], &ctx->t[0], &ctx->t[1], (ctx->y), sizeof(sp_point_256)); #else XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + @@ -28294,7 +28318,7 @@ static int sp_256_ecc_mulmod_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r, err = sp_256_proj_point_dbl_5_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2], &ctx->t[2], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&ctx->t[0], &ctx->t[2], (ctx->y)^1, sizeof(sp_point_256)); sp_cond_memcpy(&ctx->t[1], &ctx->t[2], (ctx->y), sizeof(sp_point_256)); #else @@ -34225,7 +34249,7 @@ static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, sp_384_proj_point_add_7(&t[y^1], &t[0], &t[1], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&t[2], &t[0], &t[1], (y), sizeof(sp_point_384)); #else XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + @@ -34233,7 +34257,7 @@ static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, sizeof(sp_point_384)); #endif sp_384_proj_point_dbl_7(&t[2], &t[2], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&t[0], &t[2], (y)^1, sizeof(sp_point_384)); sp_cond_memcpy(&t[1], &t[2], (y), sizeof(sp_point_384)); #else @@ -35402,7 +35426,7 @@ static int sp_384_ecc_mulmod_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, err = sp_384_proj_point_add_7_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&ctx->t[2], &ctx->t[0], &ctx->t[1], (ctx->y), sizeof(sp_point_384)); #else XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + @@ -35417,7 +35441,7 @@ static int sp_384_ecc_mulmod_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r, err = sp_384_proj_point_dbl_7_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2], &ctx->t[2], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&ctx->t[0], &ctx->t[2], (ctx->y)^1, sizeof(sp_point_384)); sp_cond_memcpy(&ctx->t[1], &ctx->t[2], (ctx->y), sizeof(sp_point_384)); #else @@ -41802,7 +41826,7 @@ static int sp_521_ecc_mulmod_9(sp_point_521* r, const sp_point_521* g, sp_521_proj_point_add_9(&t[y^1], &t[0], &t[1], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&t[2], &t[0], &t[1], (y), sizeof(sp_point_521)); #else XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + @@ -41810,7 +41834,7 @@ static int sp_521_ecc_mulmod_9(sp_point_521* r, const sp_point_521* g, sizeof(sp_point_521)); #endif sp_521_proj_point_dbl_9(&t[2], &t[2], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&t[0], &t[2], (y)^1, sizeof(sp_point_521)); sp_cond_memcpy(&t[1], &t[2], (y), sizeof(sp_point_521)); #else @@ -43003,7 +43027,7 @@ static int sp_521_ecc_mulmod_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r, err = sp_521_proj_point_add_9_nb((sp_ecc_ctx_t*)&ctx->add_ctx, &ctx->t[ctx->y^1], &ctx->t[0], &ctx->t[1], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&ctx->t[2], &ctx->t[0], &ctx->t[1], (ctx->y), sizeof(sp_point_521)); #else XMEMCPY(&ctx->t[2], (void*)(((size_t)&ctx->t[0] & addr_mask[ctx->y^1]) + @@ -43018,7 +43042,7 @@ static int sp_521_ecc_mulmod_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r, err = sp_521_proj_point_dbl_9_nb((sp_ecc_ctx_t*)&ctx->dbl_ctx, &ctx->t[2], &ctx->t[2], ctx->tmp); if (err == MP_OKAY) { - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&ctx->t[0], &ctx->t[2], (ctx->y)^1, sizeof(sp_point_521)); sp_cond_memcpy(&ctx->t[1], &ctx->t[2], (ctx->y), sizeof(sp_point_521)); #else @@ -49500,7 +49524,7 @@ static int sp_1024_ecc_mulmod_18(sp_point_1024* r, const sp_point_1024* g, sp_1024_proj_point_add_18(&t[y^1], &t[0], &t[1], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_select(&t[2], &t[0], &t[1], (y), sizeof(sp_point_1024)); #else XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) + @@ -49508,7 +49532,7 @@ static int sp_1024_ecc_mulmod_18(sp_point_1024* r, const sp_point_1024* g, sizeof(sp_point_1024)); #endif sp_1024_proj_point_dbl_18(&t[2], &t[2], tmp); - #ifdef WC_NO_PTR_INT_CAST + #ifndef WOLFSSL_SP_PTR_COPY sp_cond_memcpy(&t[0], &t[2], (y)^1, sizeof(sp_point_1024)); sp_cond_memcpy(&t[1], &t[2], (y), sizeof(sp_point_1024)); #else diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index ab1c4d72042..9aff4b8703a 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -187,6 +187,24 @@ This library provides single precision (SP) integer math functions. #include +/* Cache-resistant modular exponentiation selects the working value from t[0] or + * t[1] on each exponent bit. By default this is done with _sp_cond_copy(), which + * accesses both objects every iteration so the touched memory address does not + * depend on the secret bit (resists co-resident L1D cache attacks such as + * Prime+Probe between SMT siblings). + * + * Defining WOLFSSL_SP_FAST_MODEXP_COPY opts in to the faster variant that + * instead computes a single secret-dependent pointer with address masking and + * copies only the selected object. This is measurably faster but leaks the + * exponent at cache-line granularity, so only enable it where a co-resident + * cache observer is outside the threat model (e.g. no untrusted tenants sharing + * the physical core). The fast variant rebuilds a pointer from integer + * arithmetic on two addresses, which capability targets cannot do, so it is + * forced off when WC_NO_PTR_INT_CAST is defined. */ +#if defined(WOLFSSL_SP_FAST_MODEXP_COPY) && !defined(WC_NO_PTR_INT_CAST) + #define WOLFSSL_SP_INT_MODEXP_PTR_COPY +#endif + #ifdef WOLFSSL_SP_DYN_STACK /* We are statically declaring a variable smaller than sp_int. * We track available memory in the 'size' field. @@ -5132,18 +5150,29 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || defined(OPENSSL_EXTRA) || \ (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) #ifndef WC_NO_CACHE_RESISTANT -#ifdef WC_NO_PTR_INT_CAST -static void _sp_cond_copy(const sp_int* a, int copy, sp_int* r, sp_size_t used) +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY +/* WC_MAYBE_UNUSED: the definition guard is broader than the exptmod ladders + * that call this (e.g. ECC-with-comp-key or RSA-verify-only builds define it + * but compile no private-key exponentiation). */ +WC_MAYBE_UNUSED static void _sp_cond_copy(const sp_int* a, int copy, sp_int* r, + sp_size_t used) { sp_int_digit mask = (sp_int_digit)0 - (sp_int_digit)copy; + /* Masks for the narrower fields are derived at their own width: a + * digit-wide mask zero-extended to sp_size_t would drop the high bits of + * 'used' when SP_WORD_SIZE is 8 and the operand has 256 or more digits. */ + sp_size_t umask = (sp_size_t)(0U - (unsigned int)copy); unsigned int i; for (i = 0; i < (unsigned int)used; i++) { r->dp[i] ^= (r->dp[i] ^ a->dp[i]) & mask; } - r->used ^= (r->used ^ a->used) & (sp_size_t)mask; + r->used ^= (sp_size_t)((r->used ^ a->used) & umask); #ifdef WOLFSSL_SP_INT_NEGATIVE - r->sign ^= (r->sign ^ a->sign) & (sp_sign_t)mask; + { + sp_sign_t smask = (sp_sign_t)(0 - copy); + r->sign ^= (sp_sign_t)((r->sign ^ a->sign) & smask); + } #endif } #else @@ -5229,6 +5258,24 @@ static void _sp_init_size(sp_int* a, unsigned int size) am->size = (sp_size_t)size; } +/* Initialize an SP integer and clear its full digit span. + * + * _sp_init_size() only zeroes dp[0]. The address-oblivious copies used by the + * cache-resistant exptmod ladders (_sp_cond_copy()) scan a fixed number of + * digits regardless of an operand's 'used' count, so every digit they may read + * must be initialized; otherwise a working value with fewer significant digits + * leaves indeterminate padding that the copy reads (reported by valgrind, and + * undefined behaviour in general). Used only by those ladders. + * + * @param [out] a SP integer to initialize. + * @param [in] size Number of digits the integer can hold. + */ +WC_MAYBE_UNUSED static void _sp_init_size_ct(sp_int* a, sp_size_t size) +{ + _sp_init_size(a, size); + XMEMSET(a->dp, 0, (size_t)size * sizeof(sp_int_digit)); +} + /* Initialize the multi-precision number to be zero with a given max size. * * @param [out] a SP integer. @@ -13199,10 +13246,10 @@ static int _sp_exptmod_ex(const sp_int* b, const sp_int* e, int bits, #endif if (err == MP_OKAY) { /* Initialize temporaries. */ - _sp_init_size(t[0], (sp_size_t)(m->used * 2 + 1)); - _sp_init_size(t[1], (sp_size_t)(m->used * 2 + 1)); + _sp_init_size_ct(t[0], (sp_size_t)(m->used * 2 + 1)); + _sp_init_size_ct(t[1], (sp_size_t)(m->used * 2 + 1)); #ifndef WC_NO_CACHE_RESISTANT - _sp_init_size(t[2], (sp_size_t)(m->used * 2 + 1)); + _sp_init_size_ct(t[2], (sp_size_t)(m->used * 2 + 1)); #endif /* 2. t[0] = b mod m @@ -13245,7 +13292,7 @@ static int _sp_exptmod_ex(const sp_int* b, const sp_int* e, int bits, } #else /* 4.1. t[s] = t[s] ^ 2 */ -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[0], s^1, t[2], m->used); _sp_cond_copy(t[1], s, t[2], m->used); #else @@ -13254,7 +13301,7 @@ static int _sp_exptmod_ex(const sp_int* b, const sp_int* e, int bits, t[2]); #endif err = sp_sqrmod(t[2], m, t[2]); -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[2], s^1, t[0], m->used); _sp_cond_copy(t[2], s, t[1], m->used); #else @@ -13272,7 +13319,7 @@ static int _sp_exptmod_ex(const sp_int* b, const sp_int* e, int bits, /* 4.4 s = s | y */ s |= y; /* 4.5. t[j] = t[j] * b */ -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[0], j^1, t[2], m->used); _sp_cond_copy(t[1], j, t[2], m->used); #else @@ -13281,7 +13328,7 @@ static int _sp_exptmod_ex(const sp_int* b, const sp_int* e, int bits, t[2]); #endif err = _sp_mulmod(t[2], b, m, t[2]); -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[2], j^1, t[0], m->used); _sp_cond_copy(t[2], j, t[1], m->used); #else @@ -13343,10 +13390,10 @@ static int _sp_exptmod_ex(const sp_int* b, const sp_int* e, int bits, ALLOC_SP_INT_ARRAY(t, m->used * 2 + 1, 4, err, NULL); if (err == MP_OKAY) { /* Initialize temporaries. */ - _sp_init_size(t[0], m->used * 2 + 1); - _sp_init_size(t[1], m->used * 2 + 1); - _sp_init_size(t[2], m->used * 2 + 1); - _sp_init_size(t[3], m->used * 2 + 1); + _sp_init_size_ct(t[0], m->used * 2 + 1); + _sp_init_size_ct(t[1], m->used * 2 + 1); + _sp_init_size_ct(t[2], m->used * 2 + 1); + _sp_init_size_ct(t[3], m->used * 2 + 1); /* 1. Ensure base is less than modulus. */ if (_sp_cmp_abs(b, m) != MP_LT) { @@ -13378,7 +13425,7 @@ static int _sp_exptmod_ex(const sp_int* b, const sp_int* e, int bits, err = sp_mulmod(t[0], t[1], m, t[2]); /* 3.3. t[3] = t[y] ^ 2 */ if (err == MP_OKAY) { -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[0], y^1, t[3], m->used); _sp_cond_copy(t[1], y, t[3], m->used); #else @@ -13456,10 +13503,10 @@ static int _sp_exptmod_mont_ex(const sp_int* b, const sp_int* e, int bits, ALLOC_SP_INT_ARRAY(t, m->used * 2U + 1U, 4, err, NULL); if (err == MP_OKAY) { /* Initialize temporaries. */ - _sp_init_size(t[0], (sp_size_t)(m->used * 2 + 1)); - _sp_init_size(t[1], (sp_size_t)(m->used * 2 + 1)); - _sp_init_size(t[2], (sp_size_t)(m->used * 2 + 1)); - _sp_init_size(t[3], (sp_size_t)(m->used * 2 + 1)); + _sp_init_size_ct(t[0], (sp_size_t)(m->used * 2 + 1)); + _sp_init_size_ct(t[1], (sp_size_t)(m->used * 2 + 1)); + _sp_init_size_ct(t[2], (sp_size_t)(m->used * 2 + 1)); + _sp_init_size_ct(t[3], (sp_size_t)(m->used * 2 + 1)); /* 1. Ensure base is less than modulus. */ if (_sp_cmp_abs(b, m) != MP_LT) { @@ -13507,7 +13554,7 @@ static int _sp_exptmod_mont_ex(const sp_int* b, const sp_int* e, int bits, /* 6. For i in (bits-1)...0 */ for (i = bits - 1; (err == MP_OKAY) && (i >= 0); i--) { /* 6.1. t[s] = t[s] ^ 2 */ -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[0], s^1, t[3], m->used); _sp_cond_copy(t[1], s, t[3], m->used); #else @@ -13519,7 +13566,7 @@ static int _sp_exptmod_mont_ex(const sp_int* b, const sp_int* e, int bits, if (err == MP_OKAY) { err = _sp_mont_red(t[3], m, mp, 0); } -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[3], s^1, t[0], m->used); _sp_cond_copy(t[3], s, t[1], m->used); #else @@ -13538,7 +13585,7 @@ static int _sp_exptmod_mont_ex(const sp_int* b, const sp_int* e, int bits, s |= y; /* 6.5. t[j] = t[j] * bm */ -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[0], j^1, t[3], m->used); _sp_cond_copy(t[1], j, t[3], m->used); #else @@ -13550,7 +13597,7 @@ static int _sp_exptmod_mont_ex(const sp_int* b, const sp_int* e, int bits, if (err == MP_OKAY) { err = _sp_mont_red(t[3], m, mp, 0); } -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[3], j^1, t[0], m->used); _sp_cond_copy(t[3], j, t[1], m->used); #else @@ -13618,10 +13665,10 @@ static int _sp_exptmod_mont_ex(const sp_int* b, const sp_int* e, int bits, ALLOC_SP_INT_ARRAY(t, m->used * 2 + 1, 4, err, NULL); if (err == MP_OKAY) { /* Initialize temporaries. */ - _sp_init_size(t[0], m->used * 2 + 1); - _sp_init_size(t[1], m->used * 2 + 1); - _sp_init_size(t[2], m->used * 2 + 1); - _sp_init_size(t[3], m->used * 2 + 1); + _sp_init_size_ct(t[0], m->used * 2 + 1); + _sp_init_size_ct(t[1], m->used * 2 + 1); + _sp_init_size_ct(t[2], m->used * 2 + 1); + _sp_init_size_ct(t[3], m->used * 2 + 1); /* 1. Ensure base is less than modulus. */ if (_sp_cmp_abs(b, m) != MP_LT) { @@ -13667,7 +13714,7 @@ static int _sp_exptmod_mont_ex(const sp_int* b, const sp_int* e, int bits, } /* 4.3. t[3] = t[y] ^ 2 */ if (err == MP_OKAY) { -#ifdef WC_NO_PTR_INT_CAST +#ifndef WOLFSSL_SP_INT_MODEXP_PTR_COPY _sp_cond_copy(t[0], y^1, t[3], m->used); _sp_cond_copy(t[1], y, t[3], m->used); #else diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 3c3a15619de..06a1ada4323 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1669,9 +1669,27 @@ int fp_addmod_ct(fp_int *a, fp_int *b, fp_int *c, fp_int *d) #ifdef TFM_TIMING_RESISTANT +/* The cache-resistant exptmod ladders select the working value from R[0] or + * R[1] on each exponent bit. By default this is done with fp_cond_copy(), which + * accesses both objects every iteration so the touched address does not depend + * on the secret bit (resists co-resident L1D cache attacks such as Prime+Probe + * between SMT siblings). + * + * Defining WOLFSSL_SP_FAST_MODEXP_COPY (the same opt-in used by the SP math + * backends) selects the faster variant that instead computes a single + * secret-dependent pointer with wc_off_on_addr masking and copies only the + * selected object. It is faster but leaks the exponent at cache-line + * granularity, so only enable it where a co-resident cache observer is outside + * the threat model. The fast variant rebuilds a pointer from integer arithmetic + * on two addresses, which capability targets cannot do, so it is forced off + * when WC_NO_PTR_INT_CAST is defined. */ +#if defined(WOLFSSL_SP_FAST_MODEXP_COPY) && !defined(WC_NO_PTR_INT_CAST) + #define WC_FP_MODEXP_PTR_COPY +#endif + /* The WC_PROTECT_ENCRYPTED_MEM ladder has no WC_NO_CACHE_RESISTANT variant, so * it needs this helper even when cache resistance is off. */ -#if defined(WC_NO_PTR_INT_CAST) && (!defined(WC_NO_CACHE_RESISTANT) || \ +#if !defined(WC_FP_MODEXP_PTR_COPY) && (!defined(WC_NO_CACHE_RESISTANT) || \ defined(WC_PROTECT_ENCRYPTED_MEM)) /* Copy a into r when copy is 1, in constant time. * Used where the address of the operand cannot be derived from the secret @@ -1682,7 +1700,7 @@ int fp_addmod_ct(fp_int *a, fp_int *b, fp_int *c, fp_int *d) * alt_fp_int, whose dp[] is only FP_SIZE_ECC digits under ALT_ECC_SIZE. Every * caller below passes a local fp_int from the exptmod ladders, which is. */ -static void fp_cond_copy(const fp_int* a, int copy, fp_int* r) +WC_MAYBE_UNUSED static void fp_cond_copy(const fp_int* a, int copy, fp_int* r) { fp_digit mask = (fp_digit)0 - (fp_digit)(copy != 0); int imask = 0 - (copy != 0); @@ -1892,7 +1910,7 @@ int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y) case TFM_EXPTMOD_NB_SQR: #ifdef WC_NO_CACHE_RESISTANT err = fp_sqr(&nb->R[nb->y], &nb->R[nb->y]); - #elif defined(WC_NO_PTR_INT_CAST) + #elif !defined(WC_FP_MODEXP_PTR_COPY) fp_cond_copy(&nb->R[0], nb->y^1, &nb->R[2]); fp_cond_copy(&nb->R[1], nb->y, &nb->R[2]); err = fp_sqr(&nb->R[2], &nb->R[2]); @@ -1913,7 +1931,7 @@ int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y) case TFM_EXPTMOD_NB_SQR_RED: #ifdef WC_NO_CACHE_RESISTANT err = fp_montgomery_reduce(&nb->R[nb->y], P, nb->mp); - #elif defined(WC_NO_PTR_INT_CAST) + #elif !defined(WC_FP_MODEXP_PTR_COPY) err = fp_montgomery_reduce(&nb->R[2], P, nb->mp); fp_cond_copy(&nb->R[2], nb->y^1, &nb->R[0]); fp_cond_copy(&nb->R[2], nb->y, &nb->R[1]); @@ -2083,9 +2101,10 @@ static int _fp_exptmod_ct(fp_int * G, fp_int * X, int digits, fp_int * P, return err; } /* instead of using R[y^1] for mul, which leaks key bit to cache monitor, - * use R[2] as temp, make sure address calc is constant, keep - * &R[0] and &R[1] in cache */ -#ifdef WC_NO_PTR_INT_CAST + * use R[2] as temp, copy through both &R[0] and &R[1] + * (fp_cond_copy) so the accessed address does not depend on the key bit; + * WOLFSSL_SP_FAST_MODEXP_COPY instead selects one masked address */ +#ifndef WC_FP_MODEXP_PTR_COPY fp_cond_copy(&R[2], y, &R[0]); fp_cond_copy(&R[2], y^1, &R[1]); #else @@ -2095,9 +2114,10 @@ static int _fp_exptmod_ct(fp_int * G, fp_int * X, int digits, fp_int * P, #endif /* instead of using R[y] for sqr, which leaks key bit to cache monitor, - * use R[2] as temp, make sure address calc is constant, keep - * &R[0] and &R[1] in cache */ -#ifdef WC_NO_PTR_INT_CAST + * use R[2] as temp, copy through both &R[0] and &R[1] + * (fp_cond_copy) so the accessed address does not depend on the key bit; + * WOLFSSL_SP_FAST_MODEXP_COPY instead selects one masked address */ +#ifndef WC_FP_MODEXP_PTR_COPY fp_cond_copy(&R[0], y^1, &R[2]); fp_cond_copy(&R[1], y, &R[2]); #else @@ -2115,7 +2135,7 @@ static int _fp_exptmod_ct(fp_int * G, fp_int * X, int digits, fp_int * P, WC_FREE_VAR_EX(R, NULL, DYNAMIC_TYPE_BIGINT); return err; } -#ifdef WC_NO_PTR_INT_CAST +#ifndef WC_FP_MODEXP_PTR_COPY fp_cond_copy(&R[2], y^1, &R[0]); fp_cond_copy(&R[2], y, &R[1]); #else @@ -2252,9 +2272,10 @@ static int _fp_exptmod_ct(fp_int * G, fp_int * X, int digits, fp_int * P, } /* instead of using R[y] for sqr, which leaks key bit to cache monitor, - * use R[3] as temp, make sure address calc is constant, keep - * &R[0] and &R[1] in cache */ -#ifdef WC_NO_PTR_INT_CAST + * use R[3] as temp, copy through both &R[0] and &R[1] + * (fp_cond_copy) so the accessed address does not depend on the key bit; + * WOLFSSL_SP_FAST_MODEXP_COPY instead selects one masked address */ +#ifndef WC_FP_MODEXP_PTR_COPY fp_cond_copy(&R[0], y^1, &R[3]); fp_cond_copy(&R[1], y, &R[3]); #else