Botan  2.6.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;
62  secure_allocator& operator=(const secure_allocator&) BOTAN_NOEXCEPT = default;
63  ~secure_allocator() BOTAN_NOEXCEPT = default;
64 #endif
65 
66  template<typename U>
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  BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
109  const size_t to_copy = std::min(input_length, buf.size() - buf_offset);
110  if(to_copy > 0)
111  {
112  copy_mem(&buf[buf_offset], input, to_copy);
113  }
114  return to_copy;
115  }
116 
117 template<typename T, typename Alloc, typename Alloc2>
118 size_t buffer_insert(std::vector<T, Alloc>& buf,
119  size_t buf_offset,
120  const std::vector<T, Alloc2>& input)
121  {
122  BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
123  const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);
124  if(to_copy > 0)
125  {
126  copy_mem(&buf[buf_offset], input.data(), to_copy);
127  }
128  return to_copy;
129  }
130 
131 template<typename T, typename Alloc, typename Alloc2>
132 std::vector<T, Alloc>&
133 operator+=(std::vector<T, Alloc>& out,
134  const std::vector<T, Alloc2>& in)
135  {
136  const size_t copy_offset = out.size();
137  out.resize(out.size() + in.size());
138  if(in.size() > 0)
139  {
140  copy_mem(&out[copy_offset], in.data(), in.size());
141  }
142  return out;
143  }
144 
145 template<typename T, typename Alloc>
146 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in)
147  {
148  out.push_back(in);
149  return out;
150  }
151 
152 template<typename T, typename Alloc, typename L>
153 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
154  const std::pair<const T*, L>& in)
155  {
156  const size_t copy_offset = out.size();
157  out.resize(out.size() + in.second);
158  if(in.second > 0)
159  {
160  copy_mem(&out[copy_offset], in.first, in.second);
161  }
162  return out;
163  }
164 
165 template<typename T, typename Alloc, typename L>
166 std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
167  const std::pair<T*, L>& in)
168  {
169  const size_t copy_offset = out.size();
170  out.resize(out.size() + in.second);
171  if(in.second > 0)
172  {
173  copy_mem(&out[copy_offset], in.first, in.second);
174  }
175  return out;
176  }
177 
178 /**
179 * Zeroise the values; length remains unchanged
180 * @param vec the vector to zeroise
181 */
182 template<typename T, typename Alloc>
183 void zeroise(std::vector<T, Alloc>& vec)
184  {
185  clear_mem(vec.data(), vec.size());
186  }
187 
188 /**
189 * Zeroise the values then free the memory
190 * @param vec the vector to zeroise and free
191 */
192 template<typename T, typename Alloc>
193 void zap(std::vector<T, Alloc>& vec)
194  {
195  zeroise(vec);
196  vec.clear();
197  vec.shrink_to_fit();
198  }
199 
200 }
201 
202 #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:193
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:97
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:43
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:133
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:108
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:183