From 67a429f31fd3d1b37c5365cc58b70588b8645d62 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Mon, 27 Jul 2020 14:35:05 +0200 Subject: [PATCH] Suppress a harmless variable-time optimization by clang in _int_cmov Follow up on 52a03512c1d800603b5c923c1a28bdba12dadb30 --- src/util.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/util.h b/src/util.h index 8289e23e0c5db..17f6b1851cf81 100644 --- a/src/util.h +++ b/src/util.h @@ -197,10 +197,15 @@ static SECP256K1_INLINE void memczero(void *s, size_t len, int flag) { /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized and non-negative.*/ static SECP256K1_INLINE void secp256k1_int_cmov(int *r, const int *a, int flag) { unsigned int mask0, mask1, r_masked, a_masked; + /* Access flag with a volatile-qualified lvalue. + This prevents clang from figuring out (after inlining) that flag can + take only be 0 or 1, which leads to variable time code. */ + volatile int vflag = flag; + /* Casting a negative int to unsigned and back to int is implementation defined behavior */ VERIFY_CHECK(*r >= 0 && *a >= 0); - mask0 = (unsigned int)flag + ~0u; + mask0 = (unsigned int)vflag + ~0u; mask1 = ~mask0; r_masked = ((unsigned int)*r & mask0); a_masked = ((unsigned int)*a & mask1);