Botan  2.1.0
Crypto and TLS for C++11
secmem.h
Go to the documentation of this file.
1 /*
2 * Secure Memory Buffers
3 * (C) 1999-2007,2012 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__
9 #define BOTAN_SECURE_MEMORY_BUFFERS_H__
10 
11 #include <botan/mem_ops.h>
12 #include <algorithm>
13 #include <vector>
14 #include <deque>
15 #include <type_traits>
16 
17 #if defined(BOTAN_HAS_LOCKING_ALLOCATOR)
18  #include <botan/locking_allocator.h>
19 #endif
20 
21 namespace Botan {
22 
23 template<typename T>
25  {
26  public:
27  /*
28  * Assert exists to prevent someone from doing something that will
29  * probably crash anyway (like secure_vector<non_POD_t> where ~non_POD_t
30  * deletes a member pointer which was zeroed before it ran).
31  * MSVC in debug mode uses non-integral proxy types in container types
32  * like std::vector, thus we disable the check there.
33  */
34 #if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0
35  static_assert(std::is_integral<T>::value, "secure_allocator supports only integer types");
36 #endif
37 
38  typedef T value_type;
39 
40  typedef T* pointer;
41  typedef const T* const_pointer;
42 
43  typedef T& reference;
44  typedef const T& const_reference;
45 
46  typedef std::size_t size_type;
47  typedef std::ptrdiff_t difference_type;
48 
49 #ifdef BOTAN_BUILD_COMPILER_IS_MSVC_2013
50  secure_allocator() = default;
51  secure_allocator(const secure_allocator&) = default;
52  secure_allocator& operator=(const secure_allocator&) = default;
53  ~secure_allocator() = default;
54 #else
55  secure_allocator() BOTAN_NOEXCEPT = default;
57  secure_allocator& operator=(const secure_allocator&) BOTAN_NOEXCEPT = default;
58  ~secure_allocator() BOTAN_NOEXCEPT = default;
59 #endif
60 
61  template<typename U>
63 
64  pointer address(reference x) const BOTAN_NOEXCEPT
65  { return std::addressof(x); }
66 
67  const_pointer address(const_reference x) const BOTAN_NOEXCEPT
68  { return std::addressof(x); }
69 
70  pointer allocate(size_type n, const void* = 0)
71  {
72 #if defined(BOTAN_HAS_LOCKING_ALLOCATOR)
73  if(pointer p = static_cast<pointer>(mlock_allocator::instance().allocate(n, sizeof(T))))
74  return p;
75 #endif
76 
77  pointer p = new T[n];
78  clear_mem(p, n);
79  return p;
80  }
81 
82  void deallocate(pointer p, size_type n)
83  {
84  secure_scrub_memory(p, n);
85 
86 #if defined(BOTAN_HAS_LOCKING_ALLOCATOR)
87  if(mlock_allocator::instance().deallocate(p, n, sizeof(T)))
88  return;
89 #endif
90 
91  delete [] p;
92  }
93 
94  size_type max_size() const BOTAN_NOEXCEPT
95  {
96  return static_cast<size_type>(-1) / sizeof(T);
97  }
98 
99  template<typename U, typename... Args>
100  void construct(U* p, Args&&... args)
101  {
102  ::new(static_cast<void*>(p)) U(std::forward<Args>(args)...);
103  }
104 
105 #ifdef _MSC_VER
106 #pragma warning(push)
107 #pragma warning(disable: 4100)
108  template<typename U> void destroy(U* p) { p->~U(); }
109 #pragma warning(pop)
110 #endif
111  };
112 
113 template<typename T, typename U> inline bool
115  { return true; }
116 
117 template<typename T, typename U> inline bool
119  { return false; }
120 
121 template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>;
122 template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>;
123 
124 template<typename T>
125 std::vector<T> unlock(const secure_vector<T>& in)
126  {
127  std::vector<T> out(in.size());
128  copy_mem(out.data(), in.data(), in.size());
129  return out;
130  }
131 
132 template<typename T, typename Alloc>
133 size_t buffer_insert(std::vector<T, Alloc>& buf,
134  size_t buf_offset,
135  const T input[],
136  size_t input_length)
137  {
138  const size_t to_copy = std::min(input_length, buf.size() - buf_offset);
139  if (to_copy > 0)
140  {
141  copy_mem(&buf[buf_offset], input, to_copy);
142  }
143  return to_copy;
144  }
145 
146 template<typename T, typename Alloc, typename Alloc2>
147 size_t buffer_insert(std::vector<T, Alloc>& buf,
148  size_t buf_offset,
149  const std::vector<T, Alloc2>& input)
150  {
151  const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);
152  if (to_copy > 0)
153  {
154  copy_mem(&buf[buf_offset], input.data(), to_copy);
155  }
156  return to_copy;
157  }
158 
159 template<typename T, typename Alloc, typename Alloc2>
160 std::vector<T, Alloc>&
161 operator+=(std::vector<T, Alloc>& out,
162  const std::vector<T, Alloc2>& in)
163  {
164  const size_t copy_offset = out.size();
165  out.resize(out.size() + in.size());
166  if (in.size() > 0)
167  {
168  copy_mem(&out[copy_offset], in.data(), in.size());
169  }
170  return out;
171  }
172 
173 template<typename T, typename Alloc>
174 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in)
175  {
176  out.push_back(in);
177  return out;
178  }
179 
180 template<typename T, typename Alloc, typename L>
181 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
182  const std::pair<const T*, L>& in)
183  {
184  const size_t copy_offset = out.size();
185  out.resize(out.size() + in.second);
186  if (in.second > 0)
187  {
188  copy_mem(&out[copy_offset], in.first, in.second);
189  }
190  return out;
191  }
192 
193 template<typename T, typename Alloc, typename L>
194 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
195  const std::pair<T*, L>& in)
196  {
197  const size_t copy_offset = out.size();
198  out.resize(out.size() + in.second);
199  if (in.second > 0)
200  {
201  copy_mem(&out[copy_offset], in.first, in.second);
202  }
203  return out;
204  }
205 
206 /**
207 * Zeroise the values; length remains unchanged
208 * @param vec the vector to zeroise
209 */
210 template<typename T, typename Alloc>
211 void zeroise(std::vector<T, Alloc>& vec)
212  {
213  clear_mem(vec.data(), vec.size());
214  }
215 
216 /**
217 * Zeroise the values then free the memory
218 * @param vec the vector to zeroise and free
219 */
220 template<typename T, typename Alloc>
221 void zap(std::vector<T, Alloc>& vec)
222  {
223  zeroise(vec);
224  vec.clear();
225  vec.shrink_to_fit();
226  }
227 
228 }
229 
230 #endif
void secure_scrub_memory(void *ptr, size_t n)
Definition: mem_ops.cpp:17
const T & const_reference
Definition: secmem.h:44
secure_allocator() BOTAN_NOEXCEPT=default
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:221
static mlock_allocator & instance()
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition: alg_id.cpp:82
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:57
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition: alg_id.cpp:67
void construct(U *p, Args &&...args)
Definition: secmem.h:100
#define BOTAN_NOEXCEPT
Definition: compiler.h:116
std::deque< T, secure_allocator< T >> secure_deque
Definition: secmem.h:122
std::size_t size_type
Definition: secmem.h:46
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
~secure_allocator() BOTAN_NOEXCEPT=default
size_type max_size() const BOTAN_NOEXCEPT
Definition: secmem.h:94
std::vector< T, Alloc > & operator+=(std::vector< T, Alloc > &out, const std::vector< T, Alloc2 > &in)
Definition: secmem.h:161
pointer allocate(size_type n, const void *=0)
Definition: secmem.h:70
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Definition: alg_id.cpp:13
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
std::ptrdiff_t difference_type
Definition: secmem.h:47
secure_allocator & operator=(const secure_allocator &) BOTAN_NOEXCEPT=default
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:133
const T * const_pointer
Definition: secmem.h:41
T min(T a, T b)
Definition: ct_utils.h:180
secure_allocator(const secure_allocator< U > &) BOTAN_NOEXCEPT
Definition: secmem.h:62
const_pointer address(const_reference x) const BOTAN_NOEXCEPT
Definition: secmem.h:67
void deallocate(pointer p, size_type n)
Definition: secmem.h:82
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:211
pointer address(reference x) const BOTAN_NOEXCEPT
Definition: secmem.h:64