aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/base/secmem.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/base/secmem.h')
-rw-r--r--src/lib/base/secmem.h205
1 files changed, 205 insertions, 0 deletions
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