/* * Memory Scrubbing * (C) 2012,2015,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include #if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY) #define NOMINMAX 1 #include #endif namespace Botan { void secure_scrub_memory(void* ptr, size_t n) { #if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY) ::RtlSecureZeroMemory(ptr, n); #elif defined(BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO) && (BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO == 1) /* Call memset through a static volatile pointer, which the compiler should not elide. This construct should be safe in conforming compilers, but who knows. I did confirm that on x86-64 GCC 6.1 and Clang 3.8 both create code that saves the memset address in the data segment and uncondtionally loads and jumps to that address. */ static void* (*const volatile memset_ptr)(void*, int, size_t) = std::memset; (memset_ptr)(ptr, 0, n); #else volatile uint8_t* p = reinterpret_cast(ptr); for(size_t i = 0; i != n; ++i) p[i] = 0; #endif } }