Add a value barrier in p224_select_point Clang seems to be undoing the constant-time code here. This is another constant-time table lookup, so this is more of the usual problem. Found with the valgrind-based tooling. I didn't switch this to constant_time_conditional_memxor since we still haven't figured out https://crbug.com/boringssl/655, but we definitely need some kind of abstraction for this pattern. Change-Id: Ic11873b23cde31375ac1a326ed09ac1ca53ec913 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64310 Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/ec/p224-64.c b/crypto/fipsmodule/ec/p224-64.c index 9d0242c..d2b7f9f 100644 --- a/crypto/fipsmodule/ec/p224-64.c +++ b/crypto/fipsmodule/ec/p224-64.c
@@ -24,6 +24,7 @@ #include <openssl/err.h> #include <openssl/mem.h> +#include <assert.h> #include <string.h> #include "internal.h" @@ -836,12 +837,12 @@ for (size_t i = 0; i < size; i++) { const p224_limb *inlimbs = &pre_comp[i][0][0]; - uint64_t mask = i ^ idx; - mask |= mask >> 4; - mask |= mask >> 2; - mask |= mask >> 1; - mask &= 1; - mask--; + static_assert(sizeof(uint64_t) <= sizeof(crypto_word_t), + "crypto_word_t too small"); + static_assert(sizeof(size_t) <= sizeof(crypto_word_t), + "crypto_word_t too small"); + // Without a value barrier, Clang adds a branch here. + uint64_t mask = value_barrier_w(constant_time_eq_w(i, idx)); for (size_t j = 0; j < 4 * 3; j++) { outlimbs[j] |= inlimbs[j] & mask; }