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;
     }