Add size_t variants of constant-time functions.

These will be used in follow-up commits. The _s names are taken from
upstream, to ease importing code. I've also promoted the CONSTTIME_*
macros from the test. None of them are really necessary except
~0u cannot substitute for CONSTTIME_TRUE_S on 64-bit platforms, so
having the macros seems safer.

Once everything is converted, I expect the unsigned versions can be
removed, so I've made the _8 and _int functions act on size_t rather
than unsigned. The users of these functions basically only believe that
array indices and bytes exist.

BUG=22

Change-Id: I987bfb0c708dc726a6f2afcb05b6619bbd600564
Reviewed-on: https://boringssl-review.googlesource.com/14306
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/cipher/e_tls.c b/crypto/cipher/e_tls.c
index 7d9bbee..7af44f3 100644
--- a/crypto/cipher/e_tls.c
+++ b/crypto/cipher/e_tls.c
@@ -273,7 +273,7 @@
       return 0;
     }
   } else {
-    padding_ok = ~0u;
+    padding_ok = CONSTTIME_TRUE;
     data_plus_mac_len = total;
     /* |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has
      * already been checked against the MAC size at the top of the function. */
diff --git a/crypto/constant_time_test.cc b/crypto/constant_time_test.cc
index adfe272..628681f 100644
--- a/crypto/constant_time_test.cc
+++ b/crypto/constant_time_test.cc
@@ -49,14 +49,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <limits>
+
 #include <gtest/gtest.h>
 
 
-static const unsigned CONSTTIME_TRUE = (unsigned)(~0);
-static const unsigned CONSTTIME_FALSE = 0;
-static const uint8_t CONSTTIME_TRUE_8 = 0xff;
-static const uint8_t CONSTTIME_FALSE_8 = 0;
-
 static unsigned FromBool(bool b) {
   return b ? CONSTTIME_TRUE : CONSTTIME_FALSE;
 }
@@ -65,6 +62,10 @@
   return b ? CONSTTIME_TRUE_8 : CONSTTIME_FALSE_8;
 }
 
+static size_t FromBoolS(bool b) {
+  return b ? CONSTTIME_TRUE_S : CONSTTIME_FALSE_S;
+}
+
 static unsigned test_values[] = {
     0,
     1,
@@ -80,28 +81,63 @@
 
 static uint8_t test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
 
+static size_t test_values_s[] = {
+    0,
+    1,
+    1024,
+    12345,
+    32000,
+#if defined(OPENSSL_64_BIT)
+    0xffffffff / 2 - 1,
+    0xffffffff / 2,
+    0xffffffff / 2 + 1,
+    0xffffffff - 1,
+    0xffffffff,
+#endif
+    std::numeric_limits<size_t>::max() / 2 - 1,
+    std::numeric_limits<size_t>::max() / 2,
+    std::numeric_limits<size_t>::max() / 2 + 1,
+    std::numeric_limits<size_t>::max() - 1,
+    std::numeric_limits<size_t>::max(),
+};
+
 static int signed_test_values[] = {
     0,     1,      -1,      1024,    -1024,       12345,      -12345,
     32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1, INT_MIN + 1};
 
 TEST(ConstantTimeTest, Test) {
-  for (unsigned a : test_values) {
+  for (size_t a : test_values_s) {
     SCOPED_TRACE(a);
 
-    EXPECT_EQ(FromBool(a == 0), constant_time_is_zero(a));
+    EXPECT_EQ(FromBoolS(a == 0), constant_time_is_zero_s(a));
     EXPECT_EQ(FromBool8(a == 0), constant_time_is_zero_8(a));
 
+    for (size_t b : test_values_s) {
+      SCOPED_TRACE(b);
+
+      EXPECT_EQ(FromBoolS(a < b), constant_time_lt_s(a, b));
+      EXPECT_EQ(FromBool8(a < b), constant_time_lt_8(a, b));
+
+      EXPECT_EQ(FromBoolS(a >= b), constant_time_ge_s(a, b));
+      EXPECT_EQ(FromBool8(a >= b), constant_time_ge_8(a, b));
+
+      EXPECT_EQ(FromBoolS(a == b), constant_time_eq_s(a, b));
+      EXPECT_EQ(FromBool8(a == b), constant_time_eq_8(a, b));
+
+      EXPECT_EQ(a, constant_time_select_s(CONSTTIME_TRUE_S, a, b));
+      EXPECT_EQ(b, constant_time_select_s(CONSTTIME_FALSE_S, a, b));
+    }
+  }
+
+  for (unsigned a : test_values) {
+    SCOPED_TRACE(a);
+    EXPECT_EQ(FromBool(a == 0), constant_time_is_zero(a));
     for (unsigned b : test_values) {
       SCOPED_TRACE(b);
 
       EXPECT_EQ(FromBool(a < b), constant_time_lt(a, b));
-      EXPECT_EQ(FromBool8(a < b), constant_time_lt_8(a, b));
-
       EXPECT_EQ(FromBool(a >= b), constant_time_ge(a, b));
-      EXPECT_EQ(FromBool8(a >= b), constant_time_ge_8(a, b));
-
       EXPECT_EQ(FromBool(a == b), constant_time_eq(a, b));
-      EXPECT_EQ(FromBool8(a == b), constant_time_eq_8(a, b));
 
       EXPECT_EQ(a, constant_time_select(CONSTTIME_TRUE, a, b));
       EXPECT_EQ(b, constant_time_select(CONSTTIME_FALSE, a, b));
@@ -113,10 +149,14 @@
     for (int b : signed_test_values) {
       SCOPED_TRACE(b);
 
+      // constant_time_select_int accepts both size_t and unsigned masks.
       EXPECT_EQ(a, constant_time_select_int(CONSTTIME_TRUE, a, b));
       EXPECT_EQ(b, constant_time_select_int(CONSTTIME_FALSE, a, b));
 
-      EXPECT_EQ(FromBool(a == b), constant_time_eq_int(a, b));
+      EXPECT_EQ(a, constant_time_select_int(CONSTTIME_TRUE_S, a, b));
+      EXPECT_EQ(b, constant_time_select_int(CONSTTIME_FALSE_S, a, b));
+
+      EXPECT_EQ(FromBoolS(a == b), constant_time_eq_int(a, b));
       EXPECT_EQ(FromBool8(a == b), constant_time_eq_int_8(a, b));
     }
   }
diff --git a/crypto/internal.h b/crypto/internal.h
index 2724956..4e6026f 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -186,14 +186,27 @@
  * unsigned int lt = constant_time_lt(a, b);
  * c = constant_time_select(lt, a, b); */
 
+#define CONSTTIME_TRUE_S ~((size_t)0)
+#define CONSTTIME_FALSE_S ((size_t)0)
+#define CONSTTIME_TRUE ~0u
+#define CONSTTIME_FALSE 0u
+#define CONSTTIME_TRUE_8 ((uint8_t)0xff)
+#define CONSTTIME_FALSE_8 ((uint8_t)0)
+
+/* constant_time_msb_s returns the given value with the MSB copied to all the
+ * other bits. */
+static inline size_t constant_time_msb_s(size_t a) {
+  return 0u - (a >> (sizeof(a) * 8 - 1));
+}
+
 /* constant_time_msb returns the given value with the MSB copied to all the
  * other bits. */
 static inline unsigned int constant_time_msb(unsigned int a) {
-  return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
+  return 0u - (a >> (sizeof(a) * 8 - 1));
 }
 
-/* constant_time_lt returns 0xff..f if a < b and 0 otherwise. */
-static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) {
+/* constant_time_lt_s returns 0xff..f if a < b and 0 otherwise. */
+static inline size_t constant_time_lt_s(size_t a, size_t b) {
   /* Consider the two cases of the problem:
    *   msb(a) == msb(b): a < b iff the MSB of a - b is set.
    *   msb(a) != msb(b): a < b iff the MSB of b is set.
@@ -225,26 +238,38 @@
    * (check-sat)
    * (get-model)
    */
-  return constant_time_msb(a^((a^b)|((a-b)^a)));
+  return constant_time_msb_s(a^((a^b)|((a-b)^a)));
 }
 
-/* constant_time_lt_8 acts like |constant_time_lt| but returns an 8-bit mask. */
-static inline uint8_t constant_time_lt_8(unsigned int a, unsigned int b) {
-  return (uint8_t)(constant_time_lt(a, b));
+/* constant_time_lt acts like |constant_time_lt_s| but acts on |unsigned|. */
+static inline unsigned constant_time_lt(unsigned a, unsigned b) {
+  return (unsigned)constant_time_lt_s(a, b);
 }
 
-/* constant_time_gt returns 0xff..f if a >= b and 0 otherwise. */
-static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) {
-  return ~constant_time_lt(a, b);
+/* constant_time_lt_8 acts like |constant_time_lt_s| but returns an 8-bit
+ * mask. */
+static inline uint8_t constant_time_lt_8(size_t a, size_t b) {
+  return (uint8_t)(constant_time_lt_s(a, b));
 }
 
-/* constant_time_ge_8 acts like |constant_time_ge| but returns an 8-bit mask. */
-static inline uint8_t constant_time_ge_8(unsigned int a, unsigned int b) {
-  return (uint8_t)(constant_time_ge(a, b));
+/* constant_time_ge_s returns 0xff..f if a >= b and 0 otherwise. */
+static inline size_t constant_time_ge_s(size_t a, size_t b) {
+  return ~constant_time_lt_s(a, b);
+}
+
+/* constant_time_ge acts like |constant_time_ge_s| but acts on |unsigned|. */
+static inline unsigned constant_time_ge(unsigned a, unsigned b) {
+  return (unsigned)(constant_time_ge_s(a, b));
+}
+
+/* constant_time_ge_8 acts like |constant_time_ge_s| but returns an 8-bit
+ * mask. */
+static inline uint8_t constant_time_ge_8(size_t a, size_t b) {
+  return (uint8_t)(constant_time_ge_s(a, b));
 }
 
 /* constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise. */
-static inline unsigned int constant_time_is_zero(unsigned int a) {
+static inline size_t constant_time_is_zero_s(size_t a) {
   /* Here is an SMT-LIB verification of this formula:
    *
    * (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32)
@@ -257,55 +282,72 @@
    * (check-sat)
    * (get-model)
    */
-  return constant_time_msb(~a & (a - 1));
+  return constant_time_msb_s(~a & (a - 1));
 }
 
-/* constant_time_is_zero_8 acts like constant_time_is_zero but returns an 8-bit
+/* constant_time_is_zero acts like |constant_time_is_zero_s| but acts on
+ * |unsigned|. */
+static inline unsigned constant_time_is_zero(unsigned a) {
+  return (unsigned)constant_time_is_zero_s(a);
+}
+
+/* constant_time_is_zero_8 acts like |constant_time_is_zero_s| but returns an
+ * 8-bit mask. */
+static inline uint8_t constant_time_is_zero_8(size_t a) {
+  return (uint8_t)(constant_time_is_zero_s(a));
+}
+
+/* constant_time_eq_s returns 0xff..f if a == b and 0 otherwise. */
+static inline size_t constant_time_eq_s(size_t a, size_t b) {
+  return constant_time_is_zero_s(a ^ b);
+}
+
+/* constant_time_eq acts like |constant_time_eq_s| but acts on |unsigned|. */
+static inline unsigned constant_time_eq(unsigned a, unsigned b) {
+  return (unsigned)constant_time_eq_s(a, b);
+}
+
+/* constant_time_eq_8 acts like |constant_time_eq_s| but returns an 8-bit
  * mask. */
-static inline uint8_t constant_time_is_zero_8(unsigned int a) {
-  return (uint8_t)(constant_time_is_zero(a));
+static inline uint8_t constant_time_eq_8(size_t a, size_t b) {
+  return (uint8_t)(constant_time_eq_s(a, b));
 }
 
-/* constant_time_eq returns 0xff..f if a == b and 0 otherwise. */
-static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) {
-  return constant_time_is_zero(a ^ b);
-}
-
-/* constant_time_eq_8 acts like |constant_time_eq| but returns an 8-bit mask. */
-static inline uint8_t constant_time_eq_8(unsigned int a, unsigned int b) {
-  return (uint8_t)(constant_time_eq(a, b));
-}
-
-/* constant_time_eq_int acts like |constant_time_eq| but works on int values. */
-static inline unsigned int constant_time_eq_int(int a, int b) {
-  return constant_time_eq((unsigned)(a), (unsigned)(b));
+/* constant_time_eq_int acts like |constant_time_eq_s| but works on int
+ * values. */
+static inline size_t constant_time_eq_int(int a, int b) {
+  return constant_time_eq_s((size_t)(a), (size_t)(b));
 }
 
 /* constant_time_eq_int_8 acts like |constant_time_eq_int| but returns an 8-bit
  * mask. */
 static inline uint8_t constant_time_eq_int_8(int a, int b) {
-  return constant_time_eq_8((unsigned)(a), (unsigned)(b));
+  return constant_time_eq_8((size_t)(a), (size_t)(b));
 }
 
-/* constant_time_select returns (mask & a) | (~mask & b). When |mask| is all 1s
- * or all 0s (as returned by the methods above), the select methods return
+/* constant_time_select_s returns (mask & a) | (~mask & b). When |mask| is all
+ * 1s or all 0s (as returned by the methods above), the select methods return
  * either |a| (if |mask| is nonzero) or |b| (if |mask| is zero). */
-static inline unsigned int constant_time_select(unsigned int mask,
-                                                unsigned int a, unsigned int b) {
+static inline size_t constant_time_select_s(size_t mask, size_t a, size_t b) {
   return (mask & a) | (~mask & b);
 }
 
+static inline unsigned constant_time_select(unsigned mask, unsigned a,
+                                            unsigned b) {
+  return (unsigned)(constant_time_select_s(mask, a, b));
+}
+
 /* constant_time_select_8 acts like |constant_time_select| but operates on
  * 8-bit values. */
 static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a,
                                              uint8_t b) {
-  return (uint8_t)(constant_time_select(mask, a, b));
+  return (uint8_t)(constant_time_select_s(mask, a, b));
 }
 
 /* constant_time_select_int acts like |constant_time_select| but operates on
  * ints. */
-static inline int constant_time_select_int(unsigned int mask, int a, int b) {
-  return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
+static inline int constant_time_select_int(size_t mask, int a, int b) {
+  return (int)(constant_time_select_s(mask, (size_t)(a), (size_t)(b)));
 }
 
 
diff --git a/crypto/rsa/padding.c b/crypto/rsa/padding.c
index ac583c4..c6751af 100644
--- a/crypto/rsa/padding.c
+++ b/crypto/rsa/padding.c
@@ -205,7 +205,7 @@
   unsigned first_byte_is_zero = constant_time_eq(from[0], 0);
   unsigned second_byte_is_two = constant_time_eq(from[1], 2);
 
-  unsigned i, zero_index = 0, looking_for_index = ~0u;
+  unsigned i, zero_index = 0, looking_for_index = CONSTTIME_TRUE;
   for (i = 2; i < from_len; i++) {
     unsigned equals0 = constant_time_is_zero(from[i]);
     zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i,
@@ -439,7 +439,7 @@
   bad = ~constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
   bad |= ~constant_time_is_zero(from[0]);
 
-  looking_for_one_byte = ~0u;
+  looking_for_one_byte = CONSTTIME_TRUE;
   for (i = mdlen; i < dblen; i++) {
     unsigned equals1 = constant_time_eq(db[i], 1);
     unsigned equals0 = constant_time_eq(db[i], 0);