From c9ed5dee695272fb4f0a4aa141526d24998b68e8 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sat, 13 May 2023 12:47:02 +0100 Subject: [PATCH 1/9] Add aarch64 const-time asm Signed-off-by: Dave Rodgman --- library/constant_time_impl.h | 44 ++++++++++++++++++++++++++++++++ library/constant_time_internal.h | 2 ++ 2 files changed, 46 insertions(+) diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index 0c3cde99d1..a5284cb7a6 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -120,6 +120,19 @@ static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) * Otherwise, we define a plain C fallback which (in May 2023) does not get optimised into * conditional instructions or branches by trunk clang, gcc, or MSVC v19. */ +#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + mbedtls_ct_uint_t s; + asm volatile ("neg %x[s], %x[x] \n\t" + "orr %x[x], %x[s], %x[x] \n\t" + "asr %x[x], %x[x], 63" + : + [s] "=&r" (s), + [x] "+&r" (x) + : + : + ); + return (mbedtls_ct_condition_t) x; +#else const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x); #if defined(_MSC_VER) /* MSVC has a warning about unary minus on unsigned, but this is @@ -132,19 +145,49 @@ static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) #if defined(_MSC_VER) #pragma warning( pop ) #endif +#endif } static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition, mbedtls_ct_uint_t if1, mbedtls_ct_uint_t if0) { +#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + asm volatile ("and %x[if1], %x[if1], %x[condition] \n\t" + "mvn %x[condition], %x[condition] \n\t" + "and %x[condition], %x[condition], %x[if0] \n\t" + "orr %x[condition], %x[if1], %x[condition]" + : + [condition] "+&r" (condition), + [if1] "+&r" (if1) + : + [if0] "r" (if0) + : + ); + return (mbedtls_ct_uint_t) condition; +#else mbedtls_ct_condition_t not_cond = (mbedtls_ct_condition_t) (~mbedtls_ct_compiler_opaque(condition)); return (mbedtls_ct_uint_t) ((condition & if1) | (not_cond & if0)); +#endif } static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y) { +#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + uint64_t s1, s2; + asm volatile ("eor %x[s1], %x[y], %x[x] \n\t" + "sub %x[s2], %x[x], %x[y] \n\t" + "bic %x[s2], %x[s2], %[s1] \n\t" + "and %x[s1], %x[s1], %x[y] \n\t" + "orr %x[s1], %x[s2], %x[s1] \n\t" + "asr %x[x], %x[s1], 63" + : [s1] "=&r" (s1), [s2] "=&r" (s2), [x] "+r" (x) + : [y] "r" (y) + : + ); + return (mbedtls_ct_condition_t) x; +#else /* Ensure that the compiler cannot optimise the following operations over x and y, * even if it knows the value of x and y. */ @@ -173,6 +216,7 @@ static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbe // Convert to a condition (i.e., all bits set iff non-zero) return mbedtls_ct_bool(ret); +#endif } static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(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 dabf720aa4..44b74aec63 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -85,12 +85,14 @@ typedef ptrdiff_t mbedtls_ct_int_t; typedef uint64_t mbedtls_ct_condition_t; typedef uint64_t mbedtls_ct_uint_t; typedef int64_t mbedtls_ct_int_t; +#define MBEDTLS_CT_SIZE_64 #define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX)) #else /* Pointer size <= 32-bit, and no 64-bit MPIs */ typedef uint32_t mbedtls_ct_condition_t; typedef uint32_t mbedtls_ct_uint_t; typedef int32_t mbedtls_ct_int_t; +#define MBEDTLS_CT_SIZE_32 #define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX)) #endif #define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0)) From ef2527901e3b410764e4dde15bb14f04568f69ce Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sat, 13 May 2023 12:48:02 +0100 Subject: [PATCH 2/9] Add aarch32 const-time asm Signed-off-by: Dave Rodgman --- library/constant_time_impl.h | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index a5284cb7a6..3c82bd53fa 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -132,6 +132,18 @@ static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) : ); return (mbedtls_ct_condition_t) x; +#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) + uint32_t s; + asm volatile ("neg %[s], %[x] \n\t" + "orr %[x], %[x], %[s] \n\t" + "asr %[x], %[x], #31" + : + [s] "=&l" (s), + [x] "+&l" (x) + : + : + ); + return (mbedtls_ct_condition_t) x; #else const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x); #if defined(_MSC_VER) @@ -165,6 +177,19 @@ static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition, : ); return (mbedtls_ct_uint_t) condition; +#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) + asm volatile ("and %[if1], %[if1], %[condition] \n\t" + "mvn %[condition], %[condition] \n\t" + "and %[condition], %[condition], %[if0] \n\t" + "orr %[condition], %[if1], %[condition]" + : + [condition] "+&l" (condition), + [if1] "+&l" (if1) + : + [if0] "l" (if0) + : + ); + return (mbedtls_ct_uint_t) condition; #else mbedtls_ct_condition_t not_cond = (mbedtls_ct_condition_t) (~mbedtls_ct_compiler_opaque(condition)); @@ -187,6 +212,25 @@ static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbe : ); return (mbedtls_ct_condition_t) x; +#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) + uint32_t s1; + asm volatile ( +#if defined(__thumb__) && !defined(__thumb2__) + "mov %[s1], %[x] \n\t" + "eor %[s1], %[s1], %[y] \n\t" +#else + "eor %[s1], %[x], %[y] \n\t" +#endif + "sub %[x], %[x], %[y] \n\t" + "bic %[x], %[x], %[s1] \n\t" + "and %[y], %[s1], %[y] \n\t" + "orr %[x], %[x], %[y] \n\t" + "asr %[x], %[x], #31" + : [s1] "=&l" (s1), [x] "+&l" (x), [y] "+&l" (y) + : + : + ); + return (mbedtls_ct_condition_t) x; #else /* Ensure that the compiler cannot optimise the following operations over x and y, * even if it knows the value of x and y. From 822c9c7d4edc88bc703adbaeb01017075f9ec7dc Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 12 Jun 2023 15:38:49 +0100 Subject: [PATCH 3/9] Fix unified asm syntax issue Signed-off-by: Dave Rodgman --- library/constant_time_impl.h | 61 +++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index 3c82bd53fa..35b0ee8442 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -134,14 +134,39 @@ static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) return (mbedtls_ct_condition_t) x; #elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) uint32_t s; - asm volatile ("neg %[s], %[x] \n\t" - "orr %[x], %[x], %[s] \n\t" - "asr %[x], %[x], #31" + /* + * Selecting unified syntax is needed for gcc, and harmless on clang. + * + * This is needed because on Thumb 1, condition flags are always set, so + * e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist). + * + * Under Thumb 1 unified syntax, only the "negs" form is accepted, and + * under divided syntax, only the "neg" form is accepted. clang only + * supports unified syntax. + * + * On Thumb 2 and Arm, both compilers are happy with the "s" suffix, + * although we don't actually care about setting the flags. + * + * For gcc, restore divided syntax afterwards - otherwise old versions of gcc + * seem to apply unified syntax globally, which breaks other asm code. + */ +#if !defined(__clang__) +#define RESTORE_ASM_SYNTAX ".syntax divided \n\t" +#else +#define RESTORE_ASM_SYNTAX +#endif + + asm volatile (".syntax unified \n\t" + "negs %[s], %[x] \n\t" + "orrs %[x], %[x], %[s] \n\t" + "asrs %[x], %[x], #31 \n\t" + RESTORE_ASM_SYNTAX : [s] "=&l" (s), [x] "+&l" (x) : : + "cc" /* clobbers flag bits */ ); return (mbedtls_ct_condition_t) x; #else @@ -178,16 +203,19 @@ static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition, ); return (mbedtls_ct_uint_t) condition; #elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) - asm volatile ("and %[if1], %[if1], %[condition] \n\t" - "mvn %[condition], %[condition] \n\t" - "and %[condition], %[condition], %[if0] \n\t" - "orr %[condition], %[if1], %[condition]" + asm volatile (".syntax unified \n\t" + "ands %[if1], %[if1], %[condition] \n\t" + "mvns %[condition], %[condition] \n\t" + "ands %[condition], %[condition], %[if0] \n\t" + "orrs %[condition], %[if1], %[condition] \n\t" + RESTORE_ASM_SYNTAX : [condition] "+&l" (condition), [if1] "+&l" (if1) : [if0] "l" (if0) : + "cc" ); return (mbedtls_ct_uint_t) condition; #else @@ -215,20 +243,23 @@ static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbe #elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) uint32_t s1; asm volatile ( + ".syntax unified \n\t" #if defined(__thumb__) && !defined(__thumb2__) - "mov %[s1], %[x] \n\t" - "eor %[s1], %[s1], %[y] \n\t" + "movs %[s1], %[x] \n\t" + "eors %[s1], %[s1], %[y] \n\t" #else - "eor %[s1], %[x], %[y] \n\t" + "eors %[s1], %[x], %[y] \n\t" #endif - "sub %[x], %[x], %[y] \n\t" - "bic %[x], %[x], %[s1] \n\t" - "and %[y], %[s1], %[y] \n\t" - "orr %[x], %[x], %[y] \n\t" - "asr %[x], %[x], #31" + "subs %[x], %[x], %[y] \n\t" + "bics %[x], %[x], %[s1] \n\t" + "ands %[y], %[s1], %[y] \n\t" + "orrs %[x], %[x], %[y] \n\t" + "asrs %[x], %[x], #31 \n\t" + RESTORE_ASM_SYNTAX : [s1] "=&l" (s1), [x] "+&l" (x), [y] "+&l" (y) : : + "cc" ); return (mbedtls_ct_condition_t) x; #else From 246210e3c4782e8ec392fbc3fbbf6ce3276e131d Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 31 Jul 2023 18:07:44 +0100 Subject: [PATCH 4/9] Test CT asm under valgrind Signed-off-by: Dave Rodgman --- library/constant_time_impl.h | 10 ++++++++-- tests/scripts/all.sh | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index 35b0ee8442..111b9af5a0 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -48,8 +48,14 @@ #pragma GCC diagnostic ignored "-Wredundant-decls" #endif -/* Disable asm under Memsan because it confuses Memsan and generates false errors */ -#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) +/* Disable asm under Memsan because it confuses Memsan and generates false errors. + * + * We also disable under Valgrind by default, because it's more useful + * for Valgrind to test the plain C implementation. MBEDTLS_TEST_CONSTANT_FLOW_ASM //no-check-names + * may be set to permit building asm under Valgrind. + */ +#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) || \ + (defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) && !defined(MBEDTLS_TEST_CONSTANT_FLOW_ASM)) //no-check-names #define MBEDTLS_CT_NO_ASM #elif defined(__has_feature) #if __has_feature(memory_sanitizer) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 2afc18166f..300ca1a8c1 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1892,6 +1892,16 @@ skip_suites_without_constant_flow () { export SKIP_TEST_SUITES } +skip_all_except_given_suite () { + # Skip all but the given test suite + SKIP_TEST_SUITES=$( + ls -1 tests/suites/test_suite_*.function | + grep -v $1.function | + sed 's/tests.suites.test_suite_//; s/\.function$//' | + tr '\n' ,) + export SKIP_TEST_SUITES +} + component_test_memsan_constant_flow () { # This tests both (1) accesses to undefined memory, and (2) branches or # memory access depending on secret values. To distinguish between those: @@ -1951,6 +1961,16 @@ component_test_valgrind_constant_flow () { # details are left in Testing//DynamicAnalysis.xml msg "test: some suites (full minus MBEDTLS_USE_PSA_CRYPTO, valgrind + constant flow)" make memcheck + + # Test asm path in constant time module - by default, it will test the plain C + # path under Valgrind or Memsan. Running only the constant_time tests is fast (<1s) + msg "test: valgrind asm constant_time" + scripts/config.py --force set MBEDTLS_TEST_CONSTANT_FLOW_ASM + skip_all_except_given_suite test_suite_constant_time + cmake -D CMAKE_BUILD_TYPE:String=Release . + make clean + make + make memcheck } component_test_valgrind_constant_flow_psa () { From 42391b4378e5855735e97ea9541cf93ba107e3f2 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 May 2023 10:33:21 +0100 Subject: [PATCH 5/9] Perf improvement in memcpy_if Signed-off-by: Dave Rodgman --- library/constant_time.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/constant_time.c b/library/constant_time.c index 86cc066b03..6c7ef56782 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -152,8 +152,13 @@ void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, const unsigned char *src2, size_t len) { +#if defined(MBEDTLS_CT_SIZE_64) + const uint64_t mask = (uint64_t) condition; + const uint64_t not_mask = (uint64_t) ~mbedtls_ct_compiler_opaque(condition); +#else const uint32_t mask = (uint32_t) condition; const uint32_t not_mask = (uint32_t) ~mbedtls_ct_compiler_opaque(condition); +#endif /* If src2 is NULL, setup src2 so that we read from the destination address. * @@ -167,11 +172,19 @@ void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, /* dest[i] = c1 == c2 ? src[i] : dest[i] */ size_t i = 0; #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) +#if defined(MBEDTLS_CT_SIZE_64) + for (; (i + 8) <= len; i += 8) { + uint64_t a = mbedtls_get_unaligned_uint64(src1 + i) & mask; + uint64_t b = mbedtls_get_unaligned_uint64(src2 + i) & not_mask; + mbedtls_put_unaligned_uint64(dest + i, a | b); + } +#else for (; (i + 4) <= len; i += 4) { uint32_t a = mbedtls_get_unaligned_uint32(src1 + i) & mask; uint32_t b = mbedtls_get_unaligned_uint32(src2 + i) & not_mask; mbedtls_put_unaligned_uint32(dest + i, a | b); } +#endif /* defined(MBEDTLS_CT_SIZE_64) */ #endif /* MBEDTLS_EFFICIENT_UNALIGNED_ACCESS */ for (; i < len; i++) { dest[i] = (src1[i] & mask) | (src2[i] & not_mask); From 3ab114e3da2a5a471768be5914f3e60bdabd17f3 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 21 Aug 2023 07:54:11 +0100 Subject: [PATCH 6/9] Move non-function-specific macro outside of function definition Signed-off-by: Dave Rodgman --- library/constant_time_impl.h | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index 111b9af5a0..ab393979ef 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -115,6 +115,28 @@ static inline mbedtls_ct_uint_t mbedtls_ct_compiler_opaque(mbedtls_ct_uint_t x) #endif } +/* + * Selecting unified syntax is needed for gcc, and harmless on clang. + * + * This is needed because on Thumb 1, condition flags are always set, so + * e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist). + * + * Under Thumb 1 unified syntax, only the "negs" form is accepted, and + * under divided syntax, only the "neg" form is accepted. clang only + * supports unified syntax. + * + * On Thumb 2 and Arm, both compilers are happy with the "s" suffix, + * although we don't actually care about setting the flags. + * + * For gcc, restore divided syntax afterwards - otherwise old versions of gcc + * seem to apply unified syntax globally, which breaks other asm code. + */ +#if !defined(__clang__) +#define RESTORE_ASM_SYNTAX ".syntax divided \n\t" +#else +#define RESTORE_ASM_SYNTAX +#endif + /* Convert a number into a condition in constant time. */ static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) { @@ -140,28 +162,6 @@ static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) return (mbedtls_ct_condition_t) x; #elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) uint32_t s; - /* - * Selecting unified syntax is needed for gcc, and harmless on clang. - * - * This is needed because on Thumb 1, condition flags are always set, so - * e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist). - * - * Under Thumb 1 unified syntax, only the "negs" form is accepted, and - * under divided syntax, only the "neg" form is accepted. clang only - * supports unified syntax. - * - * On Thumb 2 and Arm, both compilers are happy with the "s" suffix, - * although we don't actually care about setting the flags. - * - * For gcc, restore divided syntax afterwards - otherwise old versions of gcc - * seem to apply unified syntax globally, which breaks other asm code. - */ -#if !defined(__clang__) -#define RESTORE_ASM_SYNTAX ".syntax divided \n\t" -#else -#define RESTORE_ASM_SYNTAX -#endif - asm volatile (".syntax unified \n\t" "negs %[s], %[x] \n\t" "orrs %[x], %[x], %[s] \n\t" From 0ce0fbc32ae3f89af65bd40a58b54cb0ab1c1404 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 21 Aug 2023 07:58:50 +0100 Subject: [PATCH 7/9] Simplify aarch64 asm for mbedtls_ct_uint_lt Signed-off-by: Dave Rodgman --- library/constant_time_impl.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index ab393979ef..971388c19a 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -234,14 +234,14 @@ static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition, static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y) { #if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) - uint64_t s1, s2; + uint64_t s1; asm volatile ("eor %x[s1], %x[y], %x[x] \n\t" - "sub %x[s2], %x[x], %x[y] \n\t" - "bic %x[s2], %x[s2], %[s1] \n\t" + "sub %x[x], %x[x], %x[y] \n\t" + "bic %x[x], %x[x], %[s1] \n\t" "and %x[s1], %x[s1], %x[y] \n\t" - "orr %x[s1], %x[s2], %x[s1] \n\t" + "orr %x[s1], %x[x], %x[s1] \n\t" "asr %x[x], %x[s1], 63" - : [s1] "=&r" (s1), [s2] "=&r" (s2), [x] "+r" (x) + : [s1] "=&r" (s1), [x] "+&r" (x) : [y] "r" (y) : ); From 0c99a9083ef633183951c80354fc506ca4e80567 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 21 Aug 2023 17:06:24 +0100 Subject: [PATCH 8/9] Avoid signed right shift UB Signed-off-by: Dave Rodgman --- library/constant_time_impl.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index 971388c19a..54bd2b0ede 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -183,8 +183,14 @@ static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) #pragma warning( push ) #pragma warning( disable : 4146 ) #endif - return (mbedtls_ct_condition_t) (((mbedtls_ct_int_t) ((-xo) | -(xo >> 1))) >> - (MBEDTLS_CT_SIZE - 1)); + // y is negative (i.e., top bit set) iff x is non-zero + mbedtls_ct_int_t y = (-xo) | -(xo >> 1); + + // extract only the sign bit of y so that y == 1 (if x is non-zero) or 0 (if x is zero) + y = (((mbedtls_ct_uint_t) y) >> (MBEDTLS_CT_SIZE - 1)); + + // -y has all bits set (if x is non-zero), or all bits clear (if x is zero) + return (mbedtls_ct_condition_t) (-y); #if defined(_MSC_VER) #pragma warning( pop ) #endif From e20d6884635f8cdf5fe72c3fb5c3dd1e637f4364 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Aug 2023 08:46:18 +0100 Subject: [PATCH 9/9] Fix missing operand modifier Co-authored-by: Yanray Wang Signed-off-by: Dave Rodgman --- library/constant_time_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index 54bd2b0ede..bf841fe8ad 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -243,7 +243,7 @@ static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbe uint64_t s1; asm volatile ("eor %x[s1], %x[y], %x[x] \n\t" "sub %x[x], %x[x], %x[y] \n\t" - "bic %x[x], %x[x], %[s1] \n\t" + "bic %x[x], %x[x], %x[s1] \n\t" "and %x[s1], %x[s1], %x[y] \n\t" "orr %x[s1], %x[x], %x[s1] \n\t" "asr %x[x], %x[s1], 63"