Securely deallocate a std::vector or a std::string
Sometimes you have to store sensitive data (e.g. passwords or keys) in a C++ standard container as a std::vector
or as a std::string
. Unfortunately the clear()
-function of those containers only deallocates the memory, but does not securely purge the data from memory. Therefore an attacker would be able to read the memory even after deallocation and using the data. The simplest solution to this problem is the usage of an allocator derived from the std::allocator
. The SecureAllocator overrides the deallocate()
function of the std::allocator
and implements the purging of the memory. As the memory is deallocated immediately after setting all values to null, a compiler might optimize this and remove the purging. Hence, the fill_n()
-Function has to be given a volatile pointer.
namespace Secure { template <class T> class SecureAllocator : public std::allocator<T> { public: template<class U> struct rebind { typedef SecureAllocator<U> other; }; SecureAllocator() throw() : std::allocator<T>() { } SecureAllocator(const SecureAllocator& other) throw() : std::allocator<T>(other) { } template <class U> SecureAllocator(const SecureAllocator<U>&) throw() { } void deallocate(T* p, std::size_t n) { std::fill_n((volatile T*)p, n*sizeof(T), 0); std::allocator<T>::deallocate(p, n); } }; }
With this allocator you can make any container that uses a std::allocator secure, e.g:
typedef std::vector<int32_t, Secure::SecureAllocator<int32_t> > SecureVector; typedef std::basic_string<char, std::char_traits<char>, Secure::SecureAllocator<char> > SecureString;