Merge branch 'development-restricted' into more-ct
diff --git a/library/bignum.c b/library/bignum.c
index 0a0022c..9c19fc9 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -83,7 +83,7 @@
      * That is if X is negative (X_is_negative == 1), then X < Y is true and it
      * is false if X is positive (X_is_negative == 0).
      */
-    different_sign = mbedtls_ct_bool_xor(X_is_negative, Y_is_negative); // non-zero if different sign
+    different_sign = mbedtls_ct_bool_ne(X_is_negative, Y_is_negative); // true if different sign
     result = mbedtls_ct_bool_and(different_sign, X_is_negative);
 
     /*
diff --git a/library/cipher.c b/library/cipher.c
index de7f837..cfb2401 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -30,6 +30,7 @@
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
 #include "mbedtls/constant_time.h"
+#include "constant_time_internal.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -848,7 +849,7 @@
                             size_t *data_len)
 {
     size_t i, pad_idx;
-    unsigned char padding_len, bad = 0;
+    unsigned char padding_len;
 
     if (NULL == input || NULL == data_len) {
         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
@@ -857,18 +858,19 @@
     padding_len = input[input_len - 1];
     *data_len = input_len - padding_len;
 
-    /* Avoid logical || since it results in a branch */
-    bad |= padding_len > input_len;
-    bad |= padding_len == 0;
+    mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
+    bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
 
     /* The number of bytes checked must be independent of padding_len,
      * so pick input_len, which is usually 8 or 16 (one block) */
     pad_idx = input_len - padding_len;
     for (i = 0; i < input_len; i++) {
-        bad |= (input[i] ^ padding_len) * (i >= pad_idx);
+        mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx);
+        mbedtls_ct_condition_t different  = mbedtls_ct_uint_ne(input[i], padding_len);
+        bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
     }
 
-    return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
+    return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
 }
 #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
 
@@ -891,24 +893,28 @@
 static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,
                                      size_t *data_len)
 {
-    size_t i;
-    unsigned char done = 0, prev_done, bad;
-
     if (NULL == input || NULL == data_len) {
         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     }
 
-    bad = 0x80;
+    mbedtls_ct_condition_t in_padding = MBEDTLS_CT_TRUE;
+    mbedtls_ct_condition_t bad = MBEDTLS_CT_TRUE;
+
     *data_len = 0;
-    for (i = input_len; i > 0; i--) {
-        prev_done = done;
-        done |= (input[i - 1] != 0);
-        *data_len |= (i - 1) * (done != prev_done);
-        bad ^= input[i - 1] * (done != prev_done);
+
+    for (ptrdiff_t i = (ptrdiff_t) (input_len) - 1; i >= 0; i--) {
+        mbedtls_ct_condition_t is_nonzero = mbedtls_ct_bool(input[i]);
+
+        mbedtls_ct_condition_t hit_first_nonzero = mbedtls_ct_bool_and(is_nonzero, in_padding);
+
+        *data_len = mbedtls_ct_size_if(hit_first_nonzero, i, *data_len);
+
+        bad = mbedtls_ct_bool_if(hit_first_nonzero, mbedtls_ct_uint_ne(input[i], 0x80), bad);
+
+        in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_bool_not(is_nonzero));
     }
 
-    return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
-
+    return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
 }
 #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
 
@@ -932,7 +938,8 @@
                                      size_t *data_len)
 {
     size_t i, pad_idx;
-    unsigned char padding_len, bad = 0;
+    unsigned char padding_len;
+    mbedtls_ct_condition_t bad;
 
     if (NULL == input || NULL == data_len) {
         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
@@ -942,16 +949,19 @@
     *data_len = input_len - padding_len;
 
     /* Avoid logical || since it results in a branch */
-    bad |= padding_len > input_len;
-    bad |= padding_len == 0;
+    bad = mbedtls_ct_uint_gt(padding_len, input_len);
+    bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
 
     /* The number of bytes checked must be independent of padding_len */
     pad_idx = input_len - padding_len;
     for (i = 0; i < input_len - 1; i++) {
-        bad |= input[i] * (i >= pad_idx);
+        mbedtls_ct_condition_t is_padding = mbedtls_ct_uint_ge(i, pad_idx);
+        mbedtls_ct_condition_t nonzero_pad_byte;
+        nonzero_pad_byte = mbedtls_ct_bool_if_else_0(is_padding, mbedtls_ct_bool(input[i]));
+        bad = mbedtls_ct_bool_or(bad, nonzero_pad_byte);
     }
 
-    return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
+    return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
 }
 #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
 
@@ -962,18 +972,14 @@
 static void add_zeros_padding(unsigned char *output,
                               size_t output_len, size_t data_len)
 {
-    size_t i;
-
-    for (i = data_len; i < output_len; i++) {
-        output[i] = 0x00;
-    }
+    memset(output + data_len, 0, output_len - data_len);
 }
 
 static int get_zeros_padding(unsigned char *input, size_t input_len,
                              size_t *data_len)
 {
     size_t i;
-    unsigned char done = 0, prev_done;
+    mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE, prev_done;
 
     if (NULL == input || NULL == data_len) {
         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
@@ -982,8 +988,8 @@
     *data_len = 0;
     for (i = input_len; i > 0; i--) {
         prev_done = done;
-        done |= (input[i-1] != 0);
-        *data_len |= i * (done != prev_done);
+        done = mbedtls_ct_bool_or(done, mbedtls_ct_uint_ne(input[i-1], 0));
+        *data_len = mbedtls_ct_size_if(mbedtls_ct_bool_ne(done, prev_done), i, *data_len);
     }
 
     return 0;
diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h
index 8da15a8..34b33b0 100644
--- a/library/constant_time_impl.h
+++ b/library/constant_time_impl.h
@@ -350,6 +350,14 @@
     return (unsigned) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0);
 }
 
+static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,
+                                                        mbedtls_ct_condition_t if1,
+                                                        mbedtls_ct_condition_t if0)
+{
+    return (mbedtls_ct_condition_t) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1,
+                                                  (mbedtls_ct_uint_t) if0);
+}
+
 #if defined(MBEDTLS_BIGNUM_C)
 
 static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition,
@@ -373,6 +381,12 @@
     return (unsigned) (condition & if1);
 }
 
+static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
+                                                               mbedtls_ct_condition_t if1)
+{
+    return (mbedtls_ct_condition_t) (condition & if1);
+}
+
 #if defined(MBEDTLS_BIGNUM_C)
 
 static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
@@ -383,6 +397,17 @@
 
 #endif /* MBEDTLS_BIGNUM_C */
 
+static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0)
+{
+    return -((int) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) (-if1),
+                                 (mbedtls_ct_uint_t) (-if0)));
+}
+
+static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1)
+{
+    return -((int) (condition & (-if1)));
+}
+
 static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
                                                         mbedtls_ct_uint_t y)
 {
@@ -407,8 +432,8 @@
     return ~mbedtls_ct_uint_gt(x, y);
 }
 
-static inline mbedtls_ct_condition_t mbedtls_ct_bool_xor(mbedtls_ct_condition_t x,
-                                                         mbedtls_ct_condition_t y)
+static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
+                                                        mbedtls_ct_condition_t y)
 {
     return (mbedtls_ct_condition_t) (x ^ y);
 }
diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h
index 323edef..63eb104 100644
--- a/library/constant_time_internal.h
+++ b/library/constant_time_internal.h
@@ -194,11 +194,11 @@
 static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
                                                         mbedtls_ct_uint_t y);
 
-/** Boolean "xor" operation.
+/** Boolean not-equals operation.
  *
  * Functionally equivalent to:
  *
- * \p x ^ \p y
+ * \p x != \p y
  *
  * \param x     The first value to analyze.
  * \param y     The second value to analyze.
@@ -206,11 +206,11 @@
  * \note        This is more efficient than mbedtls_ct_uint_ne if both arguments are
  *              mbedtls_ct_condition_t.
  *
- * \return      MBEDTLS_CT_TRUE if \p x ^ \p y,
+ * \return      MBEDTLS_CT_TRUE if \p x != \p y,
  *              otherwise MBEDTLS_CT_FALSE.
  */
-static inline mbedtls_ct_condition_t mbedtls_ct_bool_xor(mbedtls_ct_condition_t x,
-                                                         mbedtls_ct_condition_t y);
+static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
+                                                        mbedtls_ct_condition_t y);
 
 /** Boolean "and" operation.
  *
@@ -291,6 +291,22 @@
                                           unsigned if1,
                                           unsigned if0);
 
+/** Choose between two mbedtls_ct_condition_t values.
+ *
+ * Functionally equivalent to:
+ *
+ * condition ? if1 : if0.
+ *
+ * \param condition     Condition to test.
+ * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
+ * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
+ *
+ * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
+ */
+static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,
+                                                        mbedtls_ct_condition_t if1,
+                                                        mbedtls_ct_condition_t if0);
+
 #if defined(MBEDTLS_BIGNUM_C)
 
 /** Choose between two mbedtls_mpi_uint values.
@@ -327,6 +343,23 @@
  */
 static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1);
 
+/** Choose between an mbedtls_ct_condition_t and 0.
+ *
+ * Functionally equivalent to:
+ *
+ * condition ? if1 : 0.
+ *
+ * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but
+ * results in smaller code size.
+ *
+ * \param condition     Condition to test.
+ * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
+ *
+ * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
+ */
+static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
+                                                               mbedtls_ct_condition_t if1);
+
 /** Choose between a size_t value and 0.
  *
  * Functionally equivalent to:
@@ -378,6 +411,35 @@
                                                          unsigned char c,
                                                          unsigned char t);
 
+/** Choose between two error values. The values must be zero or negative.
+ *
+ * Functionally equivalent to:
+ *
+ * condition ? if1 : if0.
+ *
+ * \param condition     Condition to test.
+ * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
+ * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
+ *
+ * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
+ */
+static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0);
+
+/** Choose between an error value and 0. The error value must be zero or negative.
+ *
+ * Functionally equivalent to:
+ *
+ * condition ? if1 : 0.
+ *
+ * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but
+ * results in smaller code size.
+ *
+ * \param condition     Condition to test.
+ * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
+ *
+ * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
+ */
+static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1);
 
 /* ============================================================================
  * Block memory operations
diff --git a/library/nist_kw.c b/library/nist_kw.c
index d73e82f..7bdc807 100644
--- a/library/nist_kw.c
+++ b/library/nist_kw.c
@@ -421,8 +421,8 @@
          * larger than 8, because of the type wrap around.
          */
         padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen;
-        ret = -((int) mbedtls_ct_uint_if(mbedtls_ct_uint_gt(padlen, 7),
-                                         -MBEDTLS_ERR_CIPHER_AUTH_FAILED, -ret));
+        ret = mbedtls_ct_error_if(mbedtls_ct_uint_gt(padlen, 7),
+                                  MBEDTLS_ERR_CIPHER_AUTH_FAILED, ret);
         padlen &= 7;
 
         /* Check padding in "constant-time" */
diff --git a/library/rsa.c b/library/rsa.c
index 02626b3..3c538bf 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -158,12 +158,10 @@
      * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
      *   plaintext does not fit in the output buffer.
      * - 0 if the padding is correct. */
-    ret = -(int) mbedtls_ct_uint_if(
+    ret = mbedtls_ct_error_if(
         bad,
-        (unsigned) (-(MBEDTLS_ERR_RSA_INVALID_PADDING)),
-        mbedtls_ct_uint_if_else_0(
-            output_too_large,
-            (unsigned) (-(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE)))
+        MBEDTLS_ERR_RSA_INVALID_PADDING,
+        mbedtls_ct_error_if_else_0(output_too_large, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE)
         );
 
     /* If the padding is bad or the plaintext is too large, zero the
@@ -1541,8 +1539,8 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t ilen, i, pad_len;
-    unsigned char *p, pad_done;
-    int bad;
+    unsigned char *p;
+    mbedtls_ct_condition_t bad, in_padding;
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
     unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
     unsigned int hlen;
@@ -1602,27 +1600,26 @@
      * Check contents, in "constant-time"
      */
     p = buf;
-    bad = 0;
 
-    bad |= *p++; /* First byte must be 0 */
+    bad = mbedtls_ct_bool(*p++); /* First byte must be 0 */
 
     p += hlen; /* Skip seed */
 
     /* Check lHash */
-    bad |= mbedtls_ct_memcmp(lhash, p, hlen);
+    bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool(mbedtls_ct_memcmp(lhash, p, hlen)));
     p += hlen;
 
     /* Get zero-padding len, but always read till end of buffer
      * (minus one, for the 01 byte) */
     pad_len = 0;
-    pad_done = 0;
+    in_padding = MBEDTLS_CT_TRUE;
     for (i = 0; i < ilen - 2 * hlen - 2; i++) {
-        pad_done |= p[i];
-        pad_len += ((pad_done | (unsigned char) -pad_done) >> 7) ^ 1;
+        in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_uint_eq(p[i], 0));
+        pad_len += mbedtls_ct_uint_if_else_0(in_padding, 1);
     }
 
     p += pad_len;
-    bad |= *p++ ^ 0x01;
+    bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(*p++, 0x01));
 
     /*
      * The only information "leaked" is whether the padding was correct or not
@@ -1630,7 +1627,7 @@
      * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
      * the different error conditions.
      */
-    if (bad != 0) {
+    if (bad != MBEDTLS_CT_FALSE) {
         ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
         goto cleanup;
     }
diff --git a/tests/suites/test_suite_constant_time.data b/tests/suites/test_suite_constant_time.data
index 82ee869..fcd1689 100644
--- a/tests/suites/test_suite_constant_time.data
+++ b/tests/suites/test_suite_constant_time.data
@@ -646,6 +646,31 @@
 mbedtls_ct_if 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff
 mbedtls_ct_if:"0xffffffffffffffff":"0xffffffffffffffff":"0xffffffffffffffff"
 
+# These values exercise the case where an argument to mbedtls_ct_error_if is INT_MIN
+mbedtls_ct_if 1 0x80000000 0xffffffff
+mbedtls_ct_if:"1":"0x80000000":"0xffffffff"
+
+mbedtls_ct_if 1 0xffffffff 0x80000000
+mbedtls_ct_if:"1":"0xffffffff":"0x80000000"
+
+mbedtls_ct_if 0 0x80000000 0xffffffff
+mbedtls_ct_if:"0":"0x80000000":"0xffffffff"
+
+mbedtls_ct_if 0 0xffffffff 0x80000000
+mbedtls_ct_if:"0":"0xffffffff":"0x80000000"
+
+mbedtls_ct_if 1 0x8000000000000000 0xffffffffffffffff
+mbedtls_ct_if:"1":"0x8000000000000000":"0xffffffffffffffff"
+
+mbedtls_ct_if 1 0xffffffffffffffff 0x8000000000000000
+mbedtls_ct_if:"1":"0xffffffffffffffff":"0x8000000000000000"
+
+mbedtls_ct_if 0 0x8000000000000000 0xffffffffffffffff
+mbedtls_ct_if:"0":"0x8000000000000000":"0xffffffffffffffff"
+
+mbedtls_ct_if 0 0xffffffffffffffff 0x8000000000000000
+mbedtls_ct_if:"0":"0xffffffffffffffff":"0x8000000000000000"
+
 mbedtls_ct_zeroize_if 0x0 0
 mbedtls_ct_zeroize_if:"0x0":0
 
diff --git a/tests/suites/test_suite_constant_time.function b/tests/suites/test_suite_constant_time.function
index 087ccdf..ffcd4d1 100644
--- a/tests/suites/test_suite_constant_time.function
+++ b/tests/suites/test_suite_constant_time.function
@@ -77,8 +77,8 @@
     expected = x1 <= y1 ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     TEST_EQUAL(mbedtls_ct_uint_le(x, y), expected);
 
-    expected = (!!x1) ^ (!!y1) ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
-    TEST_EQUAL(mbedtls_ct_bool_xor(mbedtls_ct_bool(x), mbedtls_ct_bool(y)), expected);
+    expected = (!!x1) != (!!y1) ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
+    TEST_EQUAL(mbedtls_ct_bool_ne(mbedtls_ct_bool(x), mbedtls_ct_bool(y)), expected);
 
     expected = (!!x1) && (!!y1) ? MBEDTLS_CT_TRUE : MBEDTLS_CT_FALSE;
     TEST_EQUAL(mbedtls_ct_bool_and(mbedtls_ct_bool(x), mbedtls_ct_bool(y)), expected);
@@ -124,26 +124,47 @@
     mbedtls_ct_uint_t expected = c ? t : f;
     mbedtls_ct_uint_t expected0 = c ? t : 0;
 
+    /* Avoid UB by checking that -t will fit in an int, i.e.,
+     * t <= abs(INT_MIN), and similar for f.
+     * Define ABS_INT_MIN in a way that avoids UB, then use it to
+     * check t and f before making them negative.
+     */
+    #define ABS_INT_MIN (UINT_MAX - ((unsigned int)(INT_MIN)) + 1U)
+    int t_neg = t <= ABS_INT_MIN ? -t : INT_MIN;
+    int f_neg = f <= ABS_INT_MIN ? -f : INT_MIN;
+    int expected0_neg = c ? t_neg : 0;
+    int expected_neg = c ? t_neg : f_neg;
+
     TEST_CF_SECRET(&c, sizeof(c));
     TEST_CF_SECRET(&t, sizeof(t));
     TEST_CF_SECRET(&f, sizeof(f));
+    TEST_CF_SECRET(&t_neg, sizeof(t));
+    TEST_CF_SECRET(&f_neg, sizeof(f));
 
     TEST_EQUAL(mbedtls_ct_if(c, t, f), expected);
     TEST_EQUAL(mbedtls_ct_size_if(c, t, f), (size_t) expected);
     TEST_EQUAL(mbedtls_ct_uint_if(c, t, f), (unsigned) expected);
+    TEST_EQUAL(mbedtls_ct_bool_if(c, mbedtls_ct_bool(t), mbedtls_ct_bool(f)),
+               mbedtls_ct_bool(expected));
 #if defined(MBEDTLS_BIGNUM_C)
     TEST_EQUAL(mbedtls_ct_mpi_uint_if(c, t, f), (mbedtls_mpi_uint) expected);
 #endif
 
     TEST_EQUAL(mbedtls_ct_uint_if_else_0(c, t), (unsigned) expected0);
     TEST_EQUAL(mbedtls_ct_size_if_else_0(c, (size_t) t), (size_t) expected0);
+    TEST_EQUAL(mbedtls_ct_bool_if_else_0(c, mbedtls_ct_bool(t)), mbedtls_ct_bool(expected0));
 #if defined(MBEDTLS_BIGNUM_C)
     TEST_EQUAL(mbedtls_ct_mpi_uint_if_else_0(c, t), (mbedtls_mpi_uint) expected0);
 #endif
 
+    TEST_EQUAL(mbedtls_ct_error_if_else_0(c, t_neg), expected0_neg);
+    TEST_EQUAL(mbedtls_ct_error_if(c, t_neg, f_neg), expected_neg);
+
     TEST_CF_PUBLIC(&c, sizeof(c));
     TEST_CF_PUBLIC(&t, sizeof(t));
     TEST_CF_PUBLIC(&f, sizeof(f));
+    TEST_CF_PUBLIC(&t_neg, sizeof(t_neg));
+    TEST_CF_PUBLIC(&f_neg, sizeof(f_neg));
 }
 /* END_CASE */