Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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>
24 class secure_allocator
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;
56 secure_allocator(const 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>
62 secure_allocator(const secure_allocator<U>&) BOTAN_NOEXCEPT {}
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
114 operator==(const secure_allocator<T>&, const secure_allocator<U>&)
115 { return true; }
116
117 template<typename T, typename U> inline bool
118 operator!=(const secure_allocator<T>&, const secure_allocator<U>&)
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
Botan::secure_allocator::pointer
T * pointer
Definition: secmem.h:40
Botan::secure_scrub_memory
void secure_scrub_memory(void *ptr, size_t n)
Definition: mem_ops.cpp:17
Botan::secure_allocator::const_reference
const T & const_reference
Definition: secmem.h:44
Botan::secure_allocator::secure_allocator
secure_allocator() BOTAN_NOEXCEPT=default
Botan::secure_allocator
Definition: secmem.h:24
Botan::zap
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:221
Botan::mlock_allocator::instance
static mlock_allocator & instance()
Definition: locking_allocator.cpp:221
Botan::operator!=
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition: alg_id.cpp:82
Botan::clear_mem
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:57
Botan::operator==
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition: alg_id.cpp:67
Botan::secure_allocator::construct
void construct(U *p, Args &&...args)
Definition: secmem.h:100
BOTAN_NOEXCEPT
#define BOTAN_NOEXCEPT
Definition: compiler.h:116
Botan::secure_deque
std::deque< T, secure_allocator< T >> secure_deque
Definition: secmem.h:122
Botan::secure_allocator::size_type
std::size_t size_type
Definition: secmem.h:46
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::secure_allocator::~secure_allocator
~secure_allocator() BOTAN_NOEXCEPT=default
Botan::secure_allocator::reference
T & reference
Definition: secmem.h:43
Botan::secure_allocator::max_size
size_type max_size() const BOTAN_NOEXCEPT
Definition: secmem.h:94
Botan::operator+=
std::vector< T, Alloc > & operator+=(std::vector< T, Alloc > &out, const std::vector< T, Alloc2 > &in)
Definition: secmem.h:161
Botan::secure_allocator::allocate
pointer allocate(size_type n, const void *=0)
Definition: secmem.h:70
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Botan
Definition: alg_id.cpp:13
Botan::unlock
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
Botan::secure_allocator::difference_type
std::ptrdiff_t difference_type
Definition: secmem.h:47
Botan::secure_allocator::value_type
T value_type
Definition: secmem.h:35
Botan::secure_allocator::operator=
secure_allocator & operator=(const secure_allocator &) BOTAN_NOEXCEPT=default
Botan::buffer_insert
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:133
Botan::secure_allocator::const_pointer
const T * const_pointer
Definition: secmem.h:41
Botan::CT::min
T min(T a, T b)
Definition: ct_utils.h:180
Botan::secure_allocator::secure_allocator
secure_allocator(const secure_allocator< U > &) BOTAN_NOEXCEPT
Definition: secmem.h:62
Botan::secure_allocator::address
const_pointer address(const_reference x) const BOTAN_NOEXCEPT
Definition: secmem.h:67
Botan::secure_allocator::deallocate
void deallocate(pointer p, size_type n)
Definition: secmem.h:82
Botan::zeroise
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:211
Botan::secure_allocator::address
pointer address(reference x) const BOTAN_NOEXCEPT
Definition: secmem.h:64