Botan
1.11.15
|
00001 /* 00002 * Secure Memory Buffers 00003 * (C) 1999-2007,2012 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__ 00009 #define BOTAN_SECURE_MEMORY_BUFFERS_H__ 00010 00011 #include <botan/mem_ops.h> 00012 #include <algorithm> 00013 #include <vector> 00014 #include <deque> 00015 00016 #if defined(BOTAN_HAS_LOCKING_ALLOCATOR) 00017 #include <botan/locking_allocator.h> 00018 #endif 00019 00020 namespace Botan { 00021 00022 template<typename T> 00023 class secure_allocator 00024 { 00025 public: 00026 typedef T value_type; 00027 00028 typedef T* pointer; 00029 typedef const T* const_pointer; 00030 00031 typedef T& reference; 00032 typedef const T& const_reference; 00033 00034 typedef std::size_t size_type; 00035 typedef std::ptrdiff_t difference_type; 00036 00037 secure_allocator() noexcept {} 00038 00039 ~secure_allocator() noexcept {} 00040 00041 pointer address(reference x) const noexcept 00042 { return std::addressof(x); } 00043 00044 const_pointer address(const_reference x) const noexcept 00045 { return std::addressof(x); } 00046 00047 pointer allocate(size_type n, const void* = 0) 00048 { 00049 #if defined(BOTAN_HAS_LOCKING_ALLOCATOR) 00050 if(pointer p = static_cast<pointer>(mlock_allocator::instance().allocate(n, sizeof(T)))) 00051 return p; 00052 #endif 00053 00054 pointer p = new T[n]; 00055 clear_mem(p, n); 00056 return p; 00057 } 00058 00059 void deallocate(pointer p, size_type n) 00060 { 00061 zero_mem(p, n); 00062 00063 #if defined(BOTAN_HAS_LOCKING_ALLOCATOR) 00064 if(mlock_allocator::instance().deallocate(p, n, sizeof(T))) 00065 return; 00066 #endif 00067 00068 delete [] p; 00069 } 00070 00071 size_type max_size() const noexcept 00072 { 00073 return static_cast<size_type>(-1) / sizeof(T); 00074 } 00075 00076 template<typename U, typename... Args> 00077 void construct(U* p, Args&&... args) 00078 { 00079 ::new(static_cast<void*>(p)) U(std::forward<Args>(args)...); 00080 } 00081 00082 template<typename U> void destroy(U* p) { p->~U(); } 00083 }; 00084 00085 template<typename T> inline bool 00086 operator==(const secure_allocator<T>&, const secure_allocator<T>&) 00087 { return true; } 00088 00089 template<typename T> inline bool 00090 operator!=(const secure_allocator<T>&, const secure_allocator<T>&) 00091 { return false; } 00092 00093 template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>; 00094 template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>; 00095 00096 template<typename T> 00097 std::vector<T> unlock(const secure_vector<T>& in) 00098 { 00099 std::vector<T> out(in.size()); 00100 copy_mem(&out[0], &in[0], in.size()); 00101 return out; 00102 } 00103 00104 template<typename T, typename Alloc> 00105 size_t buffer_insert(std::vector<T, Alloc>& buf, 00106 size_t buf_offset, 00107 const T input[], 00108 size_t input_length) 00109 { 00110 const size_t to_copy = std::min(input_length, buf.size() - buf_offset); 00111 copy_mem(&buf[buf_offset], input, to_copy); 00112 return to_copy; 00113 } 00114 00115 template<typename T, typename Alloc, typename Alloc2> 00116 size_t buffer_insert(std::vector<T, Alloc>& buf, 00117 size_t buf_offset, 00118 const std::vector<T, Alloc2>& input) 00119 { 00120 const size_t to_copy = std::min(input.size(), buf.size() - buf_offset); 00121 copy_mem(&buf[buf_offset], &input[0], to_copy); 00122 return to_copy; 00123 } 00124 00125 template<typename T, typename Alloc, typename Alloc2> 00126 std::vector<T, Alloc>& 00127 operator+=(std::vector<T, Alloc>& out, 00128 const std::vector<T, Alloc2>& in) 00129 { 00130 const size_t copy_offset = out.size(); 00131 out.resize(out.size() + in.size()); 00132 copy_mem(&out[copy_offset], &in[0], in.size()); 00133 return out; 00134 } 00135 00136 template<typename T, typename Alloc> 00137 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in) 00138 { 00139 out.push_back(in); 00140 return out; 00141 } 00142 00143 template<typename T, typename Alloc, typename L> 00144 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, 00145 const std::pair<const T*, L>& in) 00146 { 00147 const size_t copy_offset = out.size(); 00148 out.resize(out.size() + in.second); 00149 copy_mem(&out[copy_offset], in.first, in.second); 00150 return out; 00151 } 00152 00153 template<typename T, typename Alloc, typename L> 00154 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, 00155 const std::pair<T*, L>& in) 00156 { 00157 const size_t copy_offset = out.size(); 00158 out.resize(out.size() + in.second); 00159 copy_mem(&out[copy_offset], in.first, in.second); 00160 return out; 00161 } 00162 00163 /** 00164 * Zeroise the values; length remains unchanged 00165 * @param vec the vector to zeroise 00166 */ 00167 template<typename T, typename Alloc> 00168 void zeroise(std::vector<T, Alloc>& vec) 00169 { 00170 clear_mem(&vec[0], vec.size()); 00171 } 00172 00173 /** 00174 * Zeroise the values then free the memory 00175 * @param vec the vector to zeroise and free 00176 */ 00177 template<typename T, typename Alloc> 00178 void zap(std::vector<T, Alloc>& vec) 00179 { 00180 zeroise(vec); 00181 vec.clear(); 00182 vec.shrink_to_fit(); 00183 } 00184 00185 } 00186 00187 #endif