aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--news.rst7
-rw-r--r--src/lib/base/secmem.h2
-rw-r--r--src/lib/compression/compress_utils.cpp2
-rw-r--r--src/lib/utils/locking_allocator/locking_allocator.cpp10
-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.h43
-rw-r--r--src/lib/utils/os_utils.cpp4
7 files changed, 51 insertions, 25 deletions
diff --git a/news.rst b/news.rst
index 7d0c20978..1ca48c6a2 100644
--- a/news.rst
+++ b/news.rst
@@ -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