diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 67a05f83b8..c80e286baf 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -247,6 +247,9 @@ #if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN) #error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer" #endif +#if defined(MBEDTLS_HAS_MEMSAN) && defined(MBEDTLS_HAVE_ASM) +#error "MemorySanitizer does not support assembly implementation" +#endif #undef MBEDTLS_HAS_MEMSAN // temporary macro defined above #if defined(MBEDTLS_CCM_C) && \ diff --git a/library/constant_time_impl.h b/library/constant_time_impl.h index 2a4574ba68..aeaeecb7de 100644 --- a/library/constant_time_impl.h +++ b/library/constant_time_impl.h @@ -36,24 +36,9 @@ #pragma GCC diagnostic ignored "-Wredundant-decls" #endif -/* 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) -#define MBEDTLS_CT_NO_ASM -#endif -#endif - /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ #if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && (!defined(__ARMCC_VERSION) || \ - __ARMCC_VERSION >= 6000000) && !defined(MBEDTLS_CT_NO_ASM) + __ARMCC_VERSION >= 6000000) #define MBEDTLS_CT_ASM #if (defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) #define MBEDTLS_CT_ARM_ASM diff --git a/tests/scripts/components-sanitizers.sh b/tests/scripts/components-sanitizers.sh index 5b79d2b778..c9648aa48d 100644 --- a/tests/scripts/components-sanitizers.sh +++ b/tests/scripts/components-sanitizers.sh @@ -42,6 +42,7 @@ component_test_memsan_constant_flow () { scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm + scripts/config.py unset MBEDTLS_HAVE_ASM CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan . make @@ -60,6 +61,7 @@ component_test_memsan_constant_flow_psa () { scripts/config.py full scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm + scripts/config.py unset MBEDTLS_HAVE_ASM CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan . make @@ -93,7 +95,6 @@ component_release_test_valgrind_constant_flow () { # 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 @@ -101,6 +102,32 @@ component_release_test_valgrind_constant_flow () { make memcheck } +component_release_test_valgrind_constant_flow_no_asm () { + # This tests both (1) everything that valgrind's memcheck usually checks + # (heap buffer overflows, use of uninitialized memory, use-after-free, + # etc.) and (2) branches or memory access depending on secret values, + # which will be reported as uninitialized memory. To distinguish between + # secret and actually uninitialized: + # - unset MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - does the failure persist? + # - or alternatively, build with debug info and manually run the offending + # test suite with valgrind --track-origins=yes, then check if the origin + # was TEST_CF_SECRET() or something else. + msg "build: cmake release GCC, full config minus MBEDTLS_USE_PSA_CRYPTO, minus MBEDTLS_HAVE_ASM with constant flow testing" + scripts/config.py full + scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO + scripts/config.py unset MBEDTLS_AESNI_C + scripts/config.py unset MBEDTLS_HAVE_ASM + skip_suites_without_constant_flow + cmake -D CMAKE_BUILD_TYPE:String=Release . + make + + # this only shows a summary of the results (how many of each type) + # details are left in Testing//DynamicAnalysis.xml + msg "test: some suites (full minus MBEDTLS_USE_PSA_CRYPTO, minus MBEDTLS_HAVE_ASM, valgrind + constant flow)" + make memcheck +} + component_release_test_valgrind_constant_flow_psa () { # This tests both (1) everything that valgrind's memcheck usually checks # (heap buffer overflows, use of uninitialized memory, use-after-free, @@ -145,6 +172,7 @@ component_test_tsan () { component_test_memsan () { msg "build: MSan (clang)" # ~ 1 min 20s scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm + scripts/config.py unset MBEDTLS_HAVE_ASM CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan . make