Add mbedtls_ct_error_if, with tests
Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h
index 513f146..d275085 100644
--- a/library/constant_time_impl.h
+++ b/library/constant_time_impl.h
@@ -331,7 +331,6 @@
return (unsigned char) (~(low_mask | high_mask)) & to;
}
-
/* ============================================================================
* Everything below here is trivial wrapper functions
*/
@@ -397,6 +396,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)
{
diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h
index d3d8945..3731107 100644
--- a/library/constant_time_internal.h
+++ b/library/constant_time_internal.h
@@ -411,6 +411,35 @@
unsigned char c,
unsigned char t);
+/** Choose between two error values. The values must be in the range [-32767..0].
+ *
+ * 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 in the range [-32767..0].
+ *
+ * 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/tests/suites/test_suite_constant_time.data b/tests/suites/test_suite_constant_time.data
index 82ee869..111fef6 100644
--- a/tests/suites/test_suite_constant_time.data
+++ b/tests/suites/test_suite_constant_time.data
@@ -646,6 +646,102 @@
mbedtls_ct_if 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff
mbedtls_ct_if:"0xffffffffffffffff":"0xffffffffffffffff":"0xffffffffffffffff"
+mbedtls_ct_error_if 0 0 0
+mbedtls_ct_error_if:0:0:0
+
+mbedtls_ct_error_if 0 0 -1
+mbedtls_ct_error_if:0:0:-1
+
+mbedtls_ct_error_if 0 0 -32766
+mbedtls_ct_error_if:0:0:-32766
+
+mbedtls_ct_error_if 0 0 -32767
+mbedtls_ct_error_if:0:0:-32767
+
+mbedtls_ct_error_if 0 -1 0
+mbedtls_ct_error_if:0:-1:0
+
+mbedtls_ct_error_if 0 -1 -1
+mbedtls_ct_error_if:0:-1:-1
+
+mbedtls_ct_error_if 0 -1 -32766
+mbedtls_ct_error_if:0:-1:-32766
+
+mbedtls_ct_error_if 0 -1 -32767
+mbedtls_ct_error_if:0:-1:-32767
+
+mbedtls_ct_error_if 0 -32766 0
+mbedtls_ct_error_if:0:-32766:0
+
+mbedtls_ct_error_if 0 -32766 -1
+mbedtls_ct_error_if:0:-32766:-1
+
+mbedtls_ct_error_if 0 -32766 -32766
+mbedtls_ct_error_if:0:-32766:-32766
+
+mbedtls_ct_error_if 0 -32766 -32767
+mbedtls_ct_error_if:0:-32766:-32767
+
+mbedtls_ct_error_if 0 -32767 0
+mbedtls_ct_error_if:0:-32767:0
+
+mbedtls_ct_error_if 0 -32767 -1
+mbedtls_ct_error_if:0:-32767:-1
+
+mbedtls_ct_error_if 0 -32767 -32766
+mbedtls_ct_error_if:0:-32767:-32766
+
+mbedtls_ct_error_if 0 -32767 -32767
+mbedtls_ct_error_if:0:-32767:-32767
+
+mbedtls_ct_error_if 1 0 0
+mbedtls_ct_error_if:1:0:0
+
+mbedtls_ct_error_if 1 0 -1
+mbedtls_ct_error_if:1:0:-1
+
+mbedtls_ct_error_if 1 0 -32766
+mbedtls_ct_error_if:1:0:-32766
+
+mbedtls_ct_error_if 1 0 -32767
+mbedtls_ct_error_if:1:0:-32767
+
+mbedtls_ct_error_if 1 -1 0
+mbedtls_ct_error_if:1:-1:0
+
+mbedtls_ct_error_if 1 -1 -1
+mbedtls_ct_error_if:1:-1:-1
+
+mbedtls_ct_error_if 1 -1 -32766
+mbedtls_ct_error_if:1:-1:-32766
+
+mbedtls_ct_error_if 1 -1 -32767
+mbedtls_ct_error_if:1:-1:-32767
+
+mbedtls_ct_error_if 1 -32766 0
+mbedtls_ct_error_if:1:-32766:0
+
+mbedtls_ct_error_if 1 -32766 -1
+mbedtls_ct_error_if:1:-32766:-1
+
+mbedtls_ct_error_if 1 -32766 -32766
+mbedtls_ct_error_if:1:-32766:-32766
+
+mbedtls_ct_error_if 1 -32766 -32767
+mbedtls_ct_error_if:1:-32766:-32767
+
+mbedtls_ct_error_if 1 -32767 0
+mbedtls_ct_error_if:1:-32767:0
+
+mbedtls_ct_error_if 1 -32767 -1
+mbedtls_ct_error_if:1:-32767:-1
+
+mbedtls_ct_error_if 1 -32767 -32766
+mbedtls_ct_error_if:1:-32767:-32766
+
+mbedtls_ct_error_if 1 -32767 -32767
+mbedtls_ct_error_if:1:-32767:-32767
+
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 3d5fa7f..b9a78c8 100644
--- a/tests/suites/test_suite_constant_time.function
+++ b/tests/suites/test_suite_constant_time.function
@@ -115,6 +115,27 @@
/* END_CASE */
/* BEGIN_CASE */
+void mbedtls_ct_error_if(int cond, int t, int f)
+{
+ mbedtls_ct_condition_t c = mbedtls_ct_bool(cond);
+
+ mbedtls_ct_uint_t expected = c ? t : f;
+ mbedtls_ct_uint_t expected0 = c ? t : 0;
+
+ TEST_CF_SECRET(&c, sizeof(c));
+ TEST_CF_SECRET(&t, sizeof(t));
+ TEST_CF_SECRET(&f, sizeof(f));
+
+ TEST_EQUAL(mbedtls_ct_error_if(c, t, f), expected);
+ TEST_EQUAL(mbedtls_ct_error_if_else_0(c, t), expected0);
+
+ TEST_CF_PUBLIC(&c, sizeof(c));
+ TEST_CF_PUBLIC(&t, sizeof(t));
+ TEST_CF_PUBLIC(&f, sizeof(f));
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mbedtls_ct_if(char *c_str, char *t_str, char *f_str)
{
mbedtls_ct_condition_t c = mbedtls_ct_bool(strtoull(c_str, NULL, 16));