diff options
Diffstat (limited to 'src/lib/base')
-rw-r--r-- | src/lib/base/info.txt | 2 | ||||
-rw-r--r-- | src/lib/base/secmem.h | 205 |
2 files changed, 206 insertions, 1 deletions
diff --git a/src/lib/base/info.txt b/src/lib/base/info.txt index e09351596..19eee6608 100644 --- a/src/lib/base/info.txt +++ b/src/lib/base/info.txt @@ -4,6 +4,7 @@ buf_comp.h init.h key_spec.h lookup.h +secmem.h scan_name.h sym_algo.h symkey.h @@ -17,7 +18,6 @@ algo_registry.h define TRANSFORM 20131209 <requires> -alloc block hash hex diff --git a/src/lib/base/secmem.h b/src/lib/base/secmem.h new file mode 100644 index 000000000..63d4e5296 --- /dev/null +++ b/src/lib/base/secmem.h @@ -0,0 +1,205 @@ +/* +* 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 <botan/mem_ops.h> +#include <algorithm> +#include <vector> +#include <deque> + +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + #include <botan/locking_allocator.h> +#endif + +namespace Botan { + +template<typename T> +class secure_allocator + { + public: + typedef T value_type; + + typedef T* pointer; + typedef const T* const_pointer; + + typedef T& reference; + typedef const T& const_reference; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + secure_allocator() BOTAN_NOEXCEPT {} + + template<typename U> + secure_allocator(const secure_allocator<U>&) BOTAN_NOEXCEPT {} + + ~secure_allocator() BOTAN_NOEXCEPT {} + + pointer address(reference x) const BOTAN_NOEXCEPT + { return std::addressof(x); } + + const_pointer address(const_reference x) const BOTAN_NOEXCEPT + { return std::addressof(x); } + + pointer allocate(size_type n, const void* = 0) + { +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + if(pointer p = static_cast<pointer>(mlock_allocator::instance().allocate(n, sizeof(T)))) + return p; +#endif + + pointer p = new T[n]; + clear_mem(p, n); + return p; + } + + void deallocate(pointer p, size_type n) + { + zero_mem(p, n); + +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + if(mlock_allocator::instance().deallocate(p, n, sizeof(T))) + return; +#endif + + delete [] p; + } + + size_type max_size() const BOTAN_NOEXCEPT + { + return static_cast<size_type>(-1) / sizeof(T); + } + + template<typename U, typename... Args> + void construct(U* p, Args&&... args) + { + ::new(static_cast<void*>(p)) U(std::forward<Args>(args)...); + } + + template<typename U> void destroy(U* p) { p->~U(); } + }; + +template<typename T, typename U> inline bool +operator==(const secure_allocator<T>&, const secure_allocator<U>&) + { return true; } + +template<typename T, typename U> inline bool +operator!=(const secure_allocator<T>&, const secure_allocator<U>&) + { return false; } + +template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>; +template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>; + +template<typename T> +std::vector<T> unlock(const secure_vector<T>& in) + { + std::vector<T> out(in.size()); + copy_mem(out.data(), in.data(), in.size()); + return out; + } + +template<typename T, typename Alloc> +size_t buffer_insert(std::vector<T, Alloc>& buf, + size_t buf_offset, + const T input[], + size_t input_length) + { + const size_t to_copy = std::min(input_length, buf.size() - buf_offset); + if (to_copy > 0) + { + copy_mem(&buf[buf_offset], input, to_copy); + } + return to_copy; + } + +template<typename T, typename Alloc, typename Alloc2> +size_t buffer_insert(std::vector<T, Alloc>& buf, + size_t buf_offset, + const std::vector<T, Alloc2>& input) + { + const size_t to_copy = std::min(input.size(), buf.size() - buf_offset); + if (to_copy > 0) + { + copy_mem(&buf[buf_offset], input.data(), to_copy); + } + return to_copy; + } + +template<typename T, typename Alloc, typename Alloc2> +std::vector<T, Alloc>& +operator+=(std::vector<T, Alloc>& out, + const std::vector<T, Alloc2>& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.size()); + if (in.size() > 0) + { + copy_mem(&out[copy_offset], in.data(), in.size()); + } + return out; + } + +template<typename T, typename Alloc> +std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in) + { + out.push_back(in); + return out; + } + +template<typename T, typename Alloc, typename L> +std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, + const std::pair<const T*, L>& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.second); + if (in.second > 0) + { + copy_mem(&out[copy_offset], in.first, in.second); + } + return out; + } + +template<typename T, typename Alloc, typename L> +std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, + const std::pair<T*, L>& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.second); + if (in.second > 0) + { + copy_mem(&out[copy_offset], in.first, in.second); + } + return out; + } + +/** +* Zeroise the values; length remains unchanged +* @param vec the vector to zeroise +*/ +template<typename T, typename Alloc> +void zeroise(std::vector<T, Alloc>& vec) + { + clear_mem(vec.data(), vec.size()); + } + +/** +* Zeroise the values then free the memory +* @param vec the vector to zeroise and free +*/ +template<typename T, typename Alloc> +void zap(std::vector<T, Alloc>& vec) + { + zeroise(vec); + vec.clear(); + vec.shrink_to_fit(); + } + +} + +#endif |