mirror of
https://github.com/henrydcase/pqc.git
synced 2024-11-22 23:48:58 +00:00
ct: use inline static instead of macros
This commit is contained in:
parent
caa97d8dfb
commit
55719e929c
@ -1,49 +1,55 @@
|
|||||||
#ifndef CT_CHECK_H
|
#ifndef CT_CHECK_H
|
||||||
#define CT_CHECK_H
|
#define CT_CHECK_H
|
||||||
|
|
||||||
|
// helper
|
||||||
|
#define VOID(V) ((void)V)
|
||||||
|
|
||||||
// Uses Clang's Memory Sanitizer
|
// Uses Clang's Memory Sanitizer
|
||||||
#if defined(PQC_USE_CTSANITIZER)
|
#if defined(PQC_USE_CTSANITIZER) && defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer)
|
||||||
#if defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer)
|
#include <stddef.h>
|
||||||
#include <sanitizer/msan_interface.h>
|
#include <sanitizer/msan_interface.h>
|
||||||
// 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)
|
#elif defined(PQC_USE_CTGRIND)
|
||||||
#include <valgrind/valgrind.h>
|
#include <valgrind/valgrind.h>
|
||||||
#include <valgrind/memcheck.h>
|
#include <valgrind/memcheck.h>
|
||||||
// Set sz bytes of memory starting at x as uninitialized. Switches on
|
#endif
|
||||||
// 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()
|
|
||||||
|
|
||||||
#elif // no ct-checks
|
// Set sz bytes of memory starting at address p as uninitialized. Switches on constat time checks.
|
||||||
#define CT_DYE(x,sz)
|
static inline void ct_poison(const volatile void *p, size_t sz) {
|
||||||
#define CT_PURIFY(x, sz)
|
#if defined(PQC_USE_CTSANITIZER) && defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer)
|
||||||
#define CT_EXPECT_UMR()
|
__msan_allocated_memory(p,sz);
|
||||||
#define CT_REQUIRE_UMR()
|
#elif defined(PQC_USE_CTGRIND)
|
||||||
#endif // defined(__clang__) && defined(__has_feature) && __has_feature(memory_sanitizer)
|
VALGRIND_MAKE_MEM_UNDEFINED(p,sz);
|
||||||
|
#else
|
||||||
|
VOID(p), VOID(sz);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
#endif // CT_CHECK_H
|
||||||
|
29
test/ct.cpp
29
test/ct.cpp
@ -3,11 +3,6 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <common/ct_check.h>
|
#include <common/ct_check.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
// tests from https://github.com/agl/ctgrind/blob/master/test.c
|
|
||||||
|
|
||||||
void nothing(void) {
|
|
||||||
printf("exiting...");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ConstantTime, CtGrind_Negative) {
|
TEST(ConstantTime, CtGrind_Negative) {
|
||||||
unsigned char a[16], b[16];
|
unsigned char a[16], b[16];
|
||||||
@ -15,16 +10,16 @@ TEST(ConstantTime, CtGrind_Negative) {
|
|||||||
memset(a, 42, 16);
|
memset(a, 42, 16);
|
||||||
memset(b, 42, 16);
|
memset(b, 42, 16);
|
||||||
|
|
||||||
CT_DYE(a, 16);
|
ct_poison(a, 16);
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
CT_EXPECT_UMR();
|
ct_expect_umr();
|
||||||
if (a[i] != b[i]) {
|
if (a[i] != b[i]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CT_REQUIRE_UMR();
|
ct_require_umr();
|
||||||
}
|
}
|
||||||
|
|
||||||
CT_PURIFY(a, 16);
|
ct_purify(a, 16);
|
||||||
// Ensure buffers are not optimized-out
|
// Ensure buffers are not optimized-out
|
||||||
ASSERT_EQ(a[0], b[0]);
|
ASSERT_EQ(a[0], b[0]);
|
||||||
}
|
}
|
||||||
@ -36,16 +31,16 @@ TEST(ConstantTime, CtGrind_Positive_NoAccess) {
|
|||||||
memset(a, 42, sizeof(a));
|
memset(a, 42, sizeof(a));
|
||||||
memset(b, 42, sizeof(b));
|
memset(b, 42, sizeof(b));
|
||||||
|
|
||||||
CT_DYE(a, 16);
|
ct_poison(a, 16);
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
result |= a[i] ^ b[i];
|
result |= a[i] ^ b[i];
|
||||||
}
|
}
|
||||||
CT_PURIFY(a, 16);
|
ct_purify(a, 16);
|
||||||
|
|
||||||
// Purify result, to allow check that otherwise
|
// Purify result, to allow check that otherwise
|
||||||
// would be not constant-time.
|
// would be not constant-time.
|
||||||
CT_PURIFY(&result, 1);
|
ct_purify(&result, 1);
|
||||||
ASSERT_EQ(result, 0);
|
ASSERT_EQ(result, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,15 +51,15 @@ TEST(ConstantTime, CtGrind_Negative_UseSecretAsIndex) {
|
|||||||
unsigned char result;
|
unsigned char result;
|
||||||
memset(a, 42, sizeof(a));
|
memset(a, 42, sizeof(a));
|
||||||
|
|
||||||
CT_DYE(a, 16);
|
ct_poison(a, 16);
|
||||||
|
|
||||||
CT_EXPECT_UMR();
|
ct_expect_umr();
|
||||||
result = tab[a[0] & 1];
|
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
|
// Ensure variables are not optimized-out
|
||||||
CT_PURIFY(&result, 1);
|
ct_purify(&result, 1);
|
||||||
ASSERT_EQ(result, 1);
|
ASSERT_EQ(result, 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user