memory: add sanitizing_allocator and sanitizing_blob

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2024-08-26 15:50:33 +02:00
parent d2be6a7c08
commit 8075686eee

View File

@ -50,4 +50,88 @@ namespace stdex
{
return std::shared_ptr<T>(p, no_delete<T>{});
}
// sanitizing_allocator::destroy() member generates p parameter not used warning for primitive datatypes T.
#pragma warning(push)
#pragma warning(disable: 4100)
///
/// An allocator template that sanitizes each memory block before it is destroyed or reallocated
///
/// \note
/// `sanitizing_allocator` introduces a performance penalty. However, it provides an additional level of security.
/// Use for security sensitive data memory storage only.
///
template <class T>
class sanitizing_allocator : public std::allocator<T>
{
public:
///
/// Convert this type to sanitizing_allocator<T2>
///
template <class T2>
struct rebind
{
typedef sanitizing_allocator<T2> other; ///< Other type
};
///
/// Construct default allocator
///
sanitizing_allocator() noexcept : std::allocator<T>()
{}
///
/// Construct by copying
///
sanitizing_allocator(_In_ const sanitizing_allocator<T> &other) : std::allocator<T>(other)
{}
///
/// Construct from a related allocator
///
template <class T2>
sanitizing_allocator(_In_ const sanitizing_allocator<T2> &other) noexcept : std::allocator<T>(other)
{}
///
/// Deallocate object at p sanitizing its content first
///
void deallocate(_In_ T* const p, _In_ const std::size_t n)
{
#ifdef _WIN32
SecureZeroMemory(p, sizeof(T) * n);
#else
memset(p, 0, sizeof(T) * n);
#endif
std::allocator<T>::deallocate(p, n);
}
};
#pragma warning(pop)
///
/// Sanitizing BLOB
///
template <size_t N>
class sanitizing_blob
{
public:
sanitizing_blob()
{
memset(m_data, 0, N);
}
~sanitizing_blob()
{
#ifdef _WIN32
SecureZeroMemory(m_data, N);
#else
memset(m_data, 0, N);
#endif
}
public:
unsigned char m_data[N]; ///< BLOB data
};
}