diff options
-rw-r--r-- | news.rst | 7 | ||||
-rw-r--r-- | src/lib/base/secmem.h | 2 | ||||
-rw-r--r-- | src/lib/compression/compress_utils.cpp | 2 | ||||
-rw-r--r-- | src/lib/utils/locking_allocator/locking_allocator.cpp | 10 | ||||
-rw-r--r-- | src/lib/utils/mem_ops.cpp (renamed from src/lib/utils/zero_mem.cpp) | 8 | ||||
-rw-r--r-- | src/lib/utils/mem_ops.h | 43 | ||||
-rw-r--r-- | src/lib/utils/os_utils.cpp | 4 |
7 files changed, 51 insertions, 25 deletions
@@ -59,8 +59,13 @@ Version 1.11.34, Not Yet Released * Add support to output bakefiles with new `configure.py` option `--with-bakefile`. Bakefile creates Visual Studio or Xcode project files for example. +* The function `zero_mem` has been renamed `secure_scrub_memory` to be + more clear about this functions semantics and intended usage. + * The LibraryInitializer type, which has been a no-op since 1.11.14, - is now officially deprecated. + is now officially deprecated. It does nothing, has done nothing, and + will continue not doing anything, until it is eventually removed in + a future release. At which point it may indeed cease doing nothing. Version 1.11.33, 2016-10-26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/lib/base/secmem.h b/src/lib/base/secmem.h index a99132507..758045c93 100644 --- a/src/lib/base/secmem.h +++ b/src/lib/base/secmem.h @@ -73,7 +73,7 @@ class secure_allocator void deallocate(pointer p, size_type n) { - zero_mem(p, n); + secure_scrub_memory(p, n); #if defined(BOTAN_HAS_LOCKING_ALLOCATOR) if(mlock_allocator::instance().deallocate(p, n, sizeof(T))) diff --git a/src/lib/compression/compress_utils.cpp b/src/lib/compression/compress_utils.cpp index 2af629b9c..65361fba8 100644 --- a/src/lib/compression/compress_utils.cpp +++ b/src/lib/compression/compress_utils.cpp @@ -46,7 +46,7 @@ void Compression_Alloc_Info::do_free(void* ptr) if(i == m_current_allocs.end()) throw Exception("Compression_Alloc_Info::free got pointer not allocated by us"); - zero_mem(ptr, i->second); + secure_scrub_memory(ptr, i->second); std::free(ptr); m_current_allocs.erase(i); } diff --git a/src/lib/utils/locking_allocator/locking_allocator.cpp b/src/lib/utils/locking_allocator/locking_allocator.cpp index 770464d92..8b15b417e 100644 --- a/src/lib/utils/locking_allocator/locking_allocator.cpp +++ b/src/lib/utils/locking_allocator/locking_allocator.cpp @@ -128,12 +128,6 @@ bool mlock_allocator::deallocate(void* p, size_t num_elems, size_t elem_size) if(!m_pool) return false; - /* - We do not have to zero the memory here, as - secure_allocator::deallocate does that for all arguments before - invoking the deallocator (us or delete[]) - */ - size_t n = num_elems * elem_size; /* @@ -146,6 +140,8 @@ bool mlock_allocator::deallocate(void* p, size_t num_elems, size_t elem_size) if(!ptr_in_pool(m_pool, m_poolsize, p, n)) return false; + std::memset(ptr, 0, n); + lock_guard_type<mutex_type> lock(m_mutex); const size_t start = static_cast<byte*>(p) - m_pool; @@ -216,7 +212,7 @@ mlock_allocator::~mlock_allocator() { if(m_pool) { - zero_mem(m_pool, m_poolsize); + secure_scrub_memory(m_pool, m_poolsize); OS::free_locked_pages(m_pool, m_poolsize); m_pool = nullptr; } diff --git a/src/lib/utils/zero_mem.cpp b/src/lib/utils/mem_ops.cpp index df195048a..461b03d6b 100644 --- a/src/lib/utils/zero_mem.cpp +++ b/src/lib/utils/mem_ops.cpp @@ -1,6 +1,6 @@ - /* -* Zero Memory -* (C) 2012,2015 Jack Lloyd +/* +* Memory Scrubbing +* (C) 2012,2015,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -13,7 +13,7 @@ namespace Botan { -void zero_mem(void* ptr, size_t n) +void secure_scrub_memory(void* ptr, size_t n) { #if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY) ::RtlSecureZeroMemory(ptr, n); diff --git a/src/lib/utils/mem_ops.h b/src/lib/utils/mem_ops.h index 0d2d0dab0..b4cf7f76c 100644 --- a/src/lib/utils/mem_ops.h +++ b/src/lib/utils/mem_ops.h @@ -15,26 +15,51 @@ namespace Botan { /** -* Zeroize memory -* @param ptr a pointer to memory to zero out +* Scrub memory contents in a way that a compiler should not elide, +* using some system specific technique. Note that this function might +* not zero the memory (for example, in some hypothetical +* implementation it might combine the memory contents with the output +* of a system PRNG), but if you can detect any difference in behavior +* at runtime then the clearing is side-effecting and you can just +* use `clear_mem`. +* +* Use this function to scrub memory just before deallocating it, or on +* a stack buffer before returning from the function. +* +* @param ptr a pointer to memory to scrub * @param n the number of bytes pointed to by ptr */ -BOTAN_DLL void zero_mem(void* ptr, size_t n); +BOTAN_DLL void secure_scrub_memory(void* ptr, size_t n); /** -* Zeroize memory -* @param ptr a pointer to an array -* @param n the number of Ts pointed to by ptr +* Zero out some bytes +* @param ptr a pointer to memory to zero +* @param bytes the number of bytes to zero in ptr */ -template<typename T> inline void clear_mem(T* ptr, size_t n) +inline void clear_bytes(void* ptr, size_t bytes) { - if(n > 0) + if(bytes > 0) { - std::memset(ptr, 0, sizeof(T)*n); + std::memset(ptr, 0, bytes); } } /** +* Zero memory before use. This simply calls memset and should not be +* used in cases where the compiler cannot see the call as a +* side-effecting operation (for example, if calling clear_mem before +* deallocating memory, the compiler would be allowed to omit the call +* to memset entirely under the as-if rule.) +* +* @param ptr a pointer to an array of Ts to zero +* @param n the number of Ts pointed to by ptr +*/ +template<typename T> inline void clear_mem(T* ptr, size_t n) + { + clear_bytes(ptr, sizeof(T)*n); + } + +/** * Copy memory * @param out the destination array * @param in the source array diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp index 4020a4be3..f40426613 100644 --- a/src/lib/utils/os_utils.cpp +++ b/src/lib/utils/os_utils.cpp @@ -283,11 +283,11 @@ void free_locked_pages(void* ptr, size_t length) return; #if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) - zero_mem(ptr, length); + secure_scrub_memory(ptr, length); ::munlock(ptr, length); ::munmap(ptr, length); #elif defined BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK - zero_mem(ptr, length); + secure_scrub_memory(ptr, length); ::VirtualUnlock(ptr, length); ::VirtualFree(ptr, 0, MEM_RELEASE); #else |