/* * Secure Memory Buffers * (C) 1999-2007,2012 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #ifndef BOTAN_SECURE_MEMORY_BUFFERS_H_ #define BOTAN_SECURE_MEMORY_BUFFERS_H_ #include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export #include #include #include namespace Botan { template class secure_allocator { public: /* * Assert exists to prevent someone from doing something that will * probably crash anyway (like secure_vector where ~non_POD_t * deletes a member pointer which was zeroed before it ran). * MSVC in debug mode uses non-integral proxy types in container types * like std::vector, thus we disable the check there. */ #if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0 static_assert(std::is_integral::value, "secure_allocator supports only integer types"); #endif typedef T value_type; typedef std::size_t size_type; secure_allocator() noexcept = default; secure_allocator(const secure_allocator&) noexcept = default; secure_allocator& operator=(const secure_allocator&) noexcept = default; ~secure_allocator() noexcept = default; template secure_allocator(const secure_allocator&) noexcept {} T* allocate(std::size_t n) { return static_cast(allocate_memory(n, sizeof(T))); } void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); } }; template inline bool operator==(const secure_allocator&, const secure_allocator&) { return true; } template inline bool operator!=(const secure_allocator&, const secure_allocator&) { return false; } template using secure_vector = std::vector>; template using secure_deque = std::deque>; // For better compatibility with 1.10 API template using SecureVector = secure_vector; template std::vector unlock(const secure_vector& in) { return std::vector(in.begin(), in.end()); } template std::vector& operator+=(std::vector& out, const std::vector& in) { out.reserve(out.size() + in.size()); out.insert(out.end(), in.begin(), in.end()); return out; } template std::vector& operator+=(std::vector& out, T in) { out.push_back(in); return out; } template std::vector& operator+=(std::vector& out, const std::pair& in) { out.reserve(out.size() + in.second); out.insert(out.end(), in.first, in.first + in.second); return out; } template std::vector& operator+=(std::vector& out, const std::pair& in) { out.reserve(out.size() + in.second); out.insert(out.end(), in.first, in.first + in.second); return out; } /** * Zeroise the values; length remains unchanged * @param vec the vector to zeroise */ template void zeroise(std::vector& vec) { clear_mem(vec.data(), vec.size()); } /** * Zeroise the values then free the memory * @param vec the vector to zeroise and free */ template void zap(std::vector& vec) { zeroise(vec); vec.clear(); vec.shrink_to_fit(); } } #endif