From 55719e929ccff0e3086c1d1ea50037e0e991c201 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Mon, 28 Jun 2021 23:43:55 +0100 Subject: [PATCH] ct: use inline static instead of macros --- src/common/ct_check.h | 82 +++++++++++++++++++++++-------------------- test/ct.cpp | 29 +++++++-------- 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/common/ct_check.h b/src/common/ct_check.h index cc10d89b..90569431 100644 --- a/src/common/ct_check.h +++ b/src/common/ct_check.h @@ -1,49 +1,55 @@ #ifndef CT_CHECK_H #define CT_CHECK_H +// helper +#define VOID(V) ((void)V) + // Uses Clang's Memory Sanitizer -#if defined(PQC_USE_CTSANITIZER) -#if defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer) +#if defined(PQC_USE_CTSANITIZER) && defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer) +#include #include -// Set sz bytes of memory starting at x as uninitialized. Switches on -// constat time checks. -#define CT_DYE(x,sz) __msan_allocated_memory(x,sz) -// Set sz bytes of memory starting at x as initialized. Switches off -// constat time checks. -#define CT_PURIFY(x, sz) __msan_unpoison(x, sz) -// This macro is useful for testing. It instructs memory sanitizer -// that code expects to do reads from unintialized memory. -#define CT_EXPECT_UMR() __msan_set_expect_umr(1) -// This macro works in tandem with CT_EXPECT_UMR. It checks if -// unintialized memory read has occured, if not, it will report -// an error. In current version, code needs to be compiled -// with `-mllvm -msan-keep-going=1` flags in order to work -// correctly (otherwise, runtime will be stopped between -// macros with message "Existing"). -#define CT_REQUIRE_UMR() __msan_set_expect_umr(0) -#else -#error("Clang is required to use CT_SANITIZER.") -#endif -// Uses Valgrind's Memcheck (aka ctgrind) #elif defined(PQC_USE_CTGRIND) #include #include -// Set sz bytes of memory starting at x as uninitialized. Switches on -// constat time checks. -#define CT_DYE(p,sz) VALGRIND_MAKE_MEM_UNDEFINED(p,sz) -// Set sz bytes of memory starting at x as initialized. Switches off -// constat time checks. -#define CT_PURIFY(p,sz) VALGRIND_MAKE_MEM_DEFINED(p,sz) -// Not supported in Valgrind -#define CT_EXPECT_UMR() -// Not supported in Valgrind -#define CT_REQUIRE_UMR() +#endif + +// Set sz bytes of memory starting at address p as uninitialized. Switches on constat time checks. +static inline void ct_poison(const volatile void *p, size_t sz) { +#if defined(PQC_USE_CTSANITIZER) && defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer) + __msan_allocated_memory(p,sz); +#elif defined(PQC_USE_CTGRIND) + VALGRIND_MAKE_MEM_UNDEFINED(p,sz); +#else + VOID(p), VOID(sz); +#endif +} -#elif // no ct-checks -#define CT_DYE(x,sz) -#define CT_PURIFY(x, sz) -#define CT_EXPECT_UMR() -#define CT_REQUIRE_UMR() -#endif // defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer) +// Set sz bytes of memory starting at p as initialized. Switches off constat time checks. +static inline void ct_purify(const volatile void *p, size_t sz) { +#if defined(PQC_USE_CTSANITIZER) && defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer) + __msan_unpoison(p,sz); +#elif defined(PQC_USE_CTGRIND) + VALGRIND_MAKE_MEM_DEFINED(p,sz); +#else + VOID(p), VOID(sz); +#endif +} + +// Function instructs memory sanitizer that code expects to do operation on unintialized memory. +static inline void ct_expect_umr() { +#if defined(PQC_USE_CTSANITIZER) && defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer) + __msan_set_expect_umr(1); +#endif +} + +// Checks if action on unintialized memory has occured. If this is not a case +// then error is reported. It works in tandem with ct_expect_umr(). In current version of +// MSan, the code needs to be compiled with `-mllvm -msan-keep-going=1` flags in order to work +// correctly. +static inline void ct_require_umr() { +#if defined(PQC_USE_CTSANITIZER) && defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer) + __msan_set_expect_umr(0); +#endif +} #endif // CT_CHECK_H diff --git a/test/ct.cpp b/test/ct.cpp index 8fd5f18e..6209215e 100644 --- a/test/ct.cpp +++ b/test/ct.cpp @@ -3,11 +3,6 @@ #include #include #include -// tests from https://github.com/agl/ctgrind/blob/master/test.c - -void nothing(void) { - printf("exiting..."); -} TEST(ConstantTime, CtGrind_Negative) { unsigned char a[16], b[16]; @@ -15,16 +10,16 @@ TEST(ConstantTime, CtGrind_Negative) { memset(a, 42, 16); memset(b, 42, 16); - CT_DYE(a, 16); + ct_poison(a, 16); for (i = 0; i < 16; i++) { - CT_EXPECT_UMR(); + ct_expect_umr(); if (a[i] != b[i]) { break; } - CT_REQUIRE_UMR(); + ct_require_umr(); } - CT_PURIFY(a, 16); + ct_purify(a, 16); // Ensure buffers are not optimized-out ASSERT_EQ(a[0], b[0]); } @@ -36,16 +31,16 @@ TEST(ConstantTime, CtGrind_Positive_NoAccess) { memset(a, 42, sizeof(a)); memset(b, 42, sizeof(b)); - CT_DYE(a, 16); + ct_poison(a, 16); for (i = 0; i < 16; i++) { result |= a[i] ^ b[i]; } - CT_PURIFY(a, 16); + ct_purify(a, 16); // Purify result, to allow check that otherwise // would be not constant-time. - CT_PURIFY(&result, 1); + ct_purify(&result, 1); ASSERT_EQ(result, 0); } @@ -56,15 +51,15 @@ TEST(ConstantTime, CtGrind_Negative_UseSecretAsIndex) { unsigned char result; memset(a, 42, sizeof(a)); - CT_DYE(a, 16); + ct_poison(a, 16); - CT_EXPECT_UMR(); + ct_expect_umr(); result = tab[a[0] & 1]; - CT_REQUIRE_UMR(); + ct_require_umr(); - CT_PURIFY(a, 16); + ct_purify(a, 16); // Ensure variables are not optimized-out - CT_PURIFY(&result, 1); + ct_purify(&result, 1); ASSERT_EQ(result, 1); }