Botan  2.4.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/types.h> // IWYU pragma: export
12 #include <botan/mem_ops.h> // IWYU pragma: export
13 #include <vector> // IWYU pragma: export
14 #include <algorithm>
15 #include <deque>
16 #include <type_traits>
17 
18 namespace Botan {
19 
20 template<typename T>
22  {
23  public:
24  /*
25  * Assert exists to prevent someone from doing something that will
26  * probably crash anyway (like secure_vector<non_POD_t> where ~non_POD_t
27  * deletes a member pointer which was zeroed before it ran).
28  * MSVC in debug mode uses non-integral proxy types in container types
29  * like std::vector, thus we disable the check there.
30  */
31 #if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0
32  static_assert(std::is_integral<T>::value, "secure_allocator supports only integer types");
33 #endif
34 
35  typedef T value_type;
36  typedef std::size_t size_type;
37 
38 #ifdef BOTAN_BUILD_COMPILER_IS_MSVC_2013
39  secure_allocator() = default;
40  secure_allocator(const secure_allocator&) = default;
41  secure_allocator& operator=(const secure_allocator&) = default;
42  ~secure_allocator() = default;
43 
44  template <typename U>
45  struct rebind
46  {
47  typedef secure_allocator<U> other;
48  };
49 
50  void construct(value_type* mem, const value_type& value)
51  {
52  std::_Construct(mem, value);
53  }
54 
55  void destroy(value_type* mem)
56  {
57  std::_Destroy(mem);
58  }
59 #else
60  secure_allocator() BOTAN_NOEXCEPT = default;
63  ~secure_allocator() BOTAN_NOEXCEPT = default;
64 #endif
65 
66  template<typename U>
67  secure_allocator(const secure_allocator<U>&) BOTAN_NOEXCEPT {}
68 
69  T* allocate(std::size_t n)
70  {
71  return static_cast<T*>(allocate_memory(n, sizeof(T)));
72  }
73 
74  void deallocate(T* p, std::size_t n)
75  {
76  deallocate_memory(p, n, sizeof(T));
77  }
78  };
79 
80 template<typename T, typename U> inline bool
82  { return true; }
83 
84 template<typename T, typename U> inline bool
86  { return false; }
87 
88 template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>;
89 template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>;
90 
91 // For better compatability with 1.10 API
92 template<typename T> using SecureVector = secure_vector<T>;
93 
94 template<typename T>
95 std::vector<T> unlock(const secure_vector<T>& in)
96  {
97  std::vector<T> out(in.size());
98  copy_mem(out.data(), in.data(), in.size());
99  return out;
100  }
101 
102 template<typename T, typename Alloc>
103 size_t buffer_insert(std::vector<T, Alloc>& buf,
104  size_t buf_offset,
105  const T input[],
106  size_t input_length)
107  {
108  const size_t to_copy = std::min(input_length, buf.size() - buf_offset);
109  if(to_copy > 0)
110  {
111  copy_mem(&buf[buf_offset], input, to_copy);
112  }
113  return to_copy;
114  }
115 
116 template<typename T, typename Alloc, typename Alloc2>
117 size_t buffer_insert(std::vector<T, Alloc>& buf,
118  size_t buf_offset,
119  const std::vector<T, Alloc2>& input)
120  {
121  const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);
122  if(to_copy > 0)
123  {
124  copy_mem(&buf[buf_offset], input.data(), to_copy);
125  }
126  return to_copy;
127  }
128 
129 template<typename T, typename Alloc, typename Alloc2>
130 std::vector<T, Alloc>&
131 operator+=(std::vector<T, Alloc>& out,
132  const std::vector<T, Alloc2>& in)
133  {
134  const size_t copy_offset = out.size();
135  out.resize(out.size() + in.size());
136  if(in.size() > 0)
137  {
138  copy_mem(&out[copy_offset], in.data(), in.size());
139  }
140  return out;
141  }
142 
143 template<typename T, typename Alloc>
144 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in)
145  {
146  out.push_back(in);
147  return out;
148  }
149 
150 template<typename T, typename Alloc, typename L>
151 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
152  const std::pair<const T*, L>& in)
153  {
154  const size_t copy_offset = out.size();
155  out.resize(out.size() + in.second);
156  if(in.second > 0)
157  {
158  copy_mem(&out[copy_offset], in.first, in.second);
159  }
160  return out;
161  }
162 
163 template<typename T, typename Alloc, typename L>
164 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
165  const std::pair<T*, L>& in)
166  {
167  const size_t copy_offset = out.size();
168  out.resize(out.size() + in.second);
169  if(in.second > 0)
170  {
171  copy_mem(&out[copy_offset], in.first, in.second);
172  }
173  return out;
174  }
175 
176 /**
177 * Zeroise the values; length remains unchanged
178 * @param vec the vector to zeroise
179 */
180 template<typename T, typename Alloc>
181 void zeroise(std::vector<T, Alloc>& vec)
182  {
183  clear_mem(vec.data(), vec.size());
184  }
185 
186 /**
187 * Zeroise the values then free the memory
188 * @param vec the vector to zeroise and free
189 */
190 template<typename T, typename Alloc>
191 void zap(std::vector<T, Alloc>& vec)
192  {
193  zeroise(vec);
194  vec.clear();
195  vec.shrink_to_fit();
196  }
197 
198 }
199 
200 #endif
void deallocate(T *p, std::size_t n)
Definition: secmem.h:74
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition: alg_id.cpp:90
secure_allocator() BOTAN_NOEXCEPT=default
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:191
std::deque< T, secure_allocator< T > > secure_deque
Definition: secmem.h:89
BOTAN_MALLOC_FN void * allocate_memory(size_t elems, size_t elem_size)
Definition: mem_ops.cpp:16
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:86
T * allocate(std::size_t n)
Definition: secmem.h:69
#define BOTAN_NOEXCEPT
Definition: compiler.h:154
std::size_t size_type
Definition: secmem.h:36
~secure_allocator() BOTAN_NOEXCEPT=default
secure_vector< T > SecureVector
Definition: secmem.h:92
void deallocate_memory(void *p, size_t elems, size_t elem_size)
Definition: mem_ops.cpp:29
std::vector< T, Alloc > & operator+=(std::vector< T, Alloc > &out, const std::vector< T, Alloc2 > &in)
Definition: secmem.h:131
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:97
Definition: alg_id.cpp:13
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:95
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:103
fe T
Definition: ge.cpp:37
secure_allocator(const secure_allocator< U > &) BOTAN_NOEXCEPT
Definition: secmem.h:67
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition: alg_id.cpp:75
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:181