Botan 3.13.0
Crypto and TLS for C&
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/allocator.h>
12#include <botan/types.h> // IWYU pragma: export
13#include <span>
14#include <type_traits>
15#include <vector> // IWYU pragma: export
16
17#if !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_DISABLE_DEPRECATED_FEATURES)
18 // TODO(Botan4) remove this
19 #include <deque>
20#endif
21
22namespace Botan {
23
24template <typename T>
25#if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0
26/*
27 * Check exists to prevent someone from doing something that will
28 * probably crash anyway (like secure_vector<non_POD_t> where ~non_POD_t
29 * deletes a member pointer which was zeroed before it ran).
30 * MSVC in debug mode uses non-integral proxy types in container types
31 * like std::vector, thus we disable the check there.
32 */
33 requires std::is_integral_v<T> || std::is_enum_v<T>
34#endif
35
36/**
37* An allocator which zeroizes memory before releasing it
38*
39* Restricted to integral and enum types, since a non-trivial destructor
40* would run after the object had already been zeroized.
41*/
43
44 public:
45 /**
46 * The type being allocated
47 */
48 typedef T value_type;
49
50 /**
51 * The type used to express allocation sizes
52 */
53 typedef std::size_t size_type;
54
55 /**
56 * Default constructor
57 */
58 secure_allocator() noexcept = default;
59
60 /**
61 * Copy constructor
62 */
63 secure_allocator(const secure_allocator&) noexcept = default;
64
65 /**
66 * Copy assignment
67 * @return reference to this
68 */
69 secure_allocator& operator=(const secure_allocator&) noexcept = default;
70
71 /**
72 * Move constructor
73 */
74 secure_allocator(secure_allocator&&) noexcept = default;
75
76 /**
77 * Move assignment
78 * @return reference to this
79 */
80 secure_allocator& operator=(secure_allocator&&) noexcept = default;
81
82 ~secure_allocator() noexcept = default;
83
84 /**
85 * Convert an allocator for a different type
86 */
87 template <typename U>
88 explicit secure_allocator(const secure_allocator<U>& /*other*/) noexcept {}
89
90 /**
91 * Allocate storage for n objects
92 * @param n the number of objects
93 * @return a pointer to the allocated storage
94 */
95 T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
96
97 /**
98 * Zeroize and release storage previously returned by allocate
99 * @param p the pointer to release
100 * @param n the number of objects p was allocated for
101 */
102 void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
103};
104
105/**
106* Compare two secure allocators
107*
108* All instances are interchangeable, so this is always true.
109* @return always true
110*/
111template <typename T, typename U>
112inline bool operator==(const secure_allocator<T>& /*a*/, const secure_allocator<U>& /*b*/) {
113 return true;
114}
115
116/**
117* Compare two secure allocators
118*
119* All instances are interchangeable, so this is always false.
120* @return always false
121*/
122template <typename T, typename U>
123inline bool operator!=(const secure_allocator<T>& /*a*/, const secure_allocator<U>& /*b*/) {
124 return false;
125}
126
127template <typename T>
128using secure_vector = std::vector<T, secure_allocator<T>>;
129
130#if !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_DISABLE_DEPRECATED_FEATURES)
131template <typename T>
132using secure_deque = std::deque<T, secure_allocator<T>>;
133#endif
134
135// For better compatibility with 1.10 API
136template <typename T>
138
139/**
140* Copy a vector into a secure_vector
141* @param in the vector to copy
142* @return a secure_vector holding the same contents
143*/
144template <typename T>
145secure_vector<T> lock(const std::vector<T>& in) {
146 return secure_vector<T>(in.begin(), in.end());
147}
148
149/**
150* Copy a secure_vector into an ordinary vector
151* @param in the vector to copy
152* @return a std::vector holding the same contents
153*/
154template <typename T>
155std::vector<T> unlock(const secure_vector<T>& in) {
156 return std::vector<T>(in.begin(), in.end());
157}
158
159// TODO(Botan4) remove these += operators entirely
160
161/**
162* Append the contents of one vector to another
163* @param out the vector to append to
164* @param in the vector to append
165* @return reference to out
166*/
167template <typename T, typename Alloc, typename Alloc2>
168std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::vector<T, Alloc2>& in) {
169 out.insert(out.end(), in.begin(), in.end());
170 return out;
171}
172
173/**
174* Append the contents of a span to a vector
175* @param out the vector to append to
176* @param in the elements to append
177* @return reference to out
178*/
179template <typename T, typename Alloc>
180std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, std::span<const T> in) {
181 out.insert(out.end(), in.begin(), in.end());
182 return out;
183}
184
185/**
186* Append a single element to a vector
187* @param out the vector to append to
188* @param in the element to append
189* @return reference to out
190*/
191template <typename T, typename Alloc>
192std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in) {
193 out.push_back(in);
194 return out;
195}
196
197/**
198* Append a (pointer, length) pair to a vector
199* @param out the vector to append to
200* @param in the elements to append
201* @return reference to out
202*/
203template <typename T, typename Alloc, typename L>
204std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::pair<const T*, L>& in) {
205 if(in.second > 0) {
206 out.insert(out.end(), in.first, in.first + in.second);
207 }
208 return out;
209}
210
211/**
212* Append a (pointer, length) pair to a vector
213* @param out the vector to append to
214* @param in the elements to append
215* @return reference to out
216*/
217template <typename T, typename Alloc, typename L>
218std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::pair<T*, L>& in) {
219 if(in.second > 0) {
220 out.insert(out.end(), in.first, in.first + in.second);
221 }
222 return out;
223}
224
225/**
226* Zeroise the values; length remains unchanged
227*
228* Note this is not intended for cases where the compiler might elide
229* the writes as being without side-effects; use secure_scrub_memory
230* for that.
231*
232* TODO(Botan4): make these not-inlined and only for secure_vector, eg declare
233* void zeroize(secure_vector<uint8_t>& v);
234* void zeroize(secure_vector<uint16_t>& v);
235* void zeroize(secure_vector<uint32_t>& v);
236* void zeroize(secure_vector<uint64_t>& v);
237*
238* @param vec the vector to zeroise
239*/
240template <typename T, typename Alloc>
241void zeroise(std::vector<T, Alloc>& vec) {
242 for(size_t i = 0; i != vec.size(); ++i) {
243 vec[i] = static_cast<T>(0);
244 }
245}
246
247/**
248* Zeroise the values then free the memory
249*
250* TODO(Botan4): make these not-inlined and only for secure_vector, eg declare
251* void zap(secure_vector<uint8_t>& v);
252* void zap(secure_vector<uint16_t>& v);
253* void zap(secure_vector<uint32_t>& v);
254* void zap(secure_vector<uint64_t>& v);
255*
256* [And maybe rename as well]
257*
258* @param vec the vector to zeroise and free
259*/
260template <typename T, typename Alloc>
261void zap(std::vector<T, Alloc>& vec) {
262 zeroise(vec);
263 vec.clear();
264 vec.shrink_to_fit();
265}
266
267} // namespace Botan
268
269#endif
T * allocate(std::size_t n)
Definition secmem.h:95
void deallocate(T *p, std::size_t n)
Definition secmem.h:102
secure_allocator() noexcept=default
std::size_t size_type
Definition secmem.h:53
void zeroise(std::vector< T, Alloc > &vec)
Definition secmem.h:241
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:261
void deallocate_memory(void *p, size_t elems, size_t elem_size)
Definition allocator.cpp:50
secure_vector< T > lock(const std::vector< T > &in)
Definition secmem.h:145
std::vector< T > unlock(const secure_vector< T > &in)
Definition secmem.h:155
std::deque< T, secure_allocator< T > > secure_deque
Definition secmem.h:132
std::vector< T, Alloc > & operator+=(std::vector< T, Alloc > &out, const std::vector< T, Alloc2 > &in)
Definition secmem.h:168
bool operator!=(const AlgorithmIdentifier &x, const AlgorithmIdentifier &y)
Definition alg_id.cpp:58
BOTAN_MALLOC_FN void * allocate_memory(size_t elems, size_t elem_size)
Definition allocator.cpp:21
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
bool operator==(const AlgorithmIdentifier &x, const AlgorithmIdentifier &y)
Definition alg_id.cpp:54
secure_vector< T > SecureVector
Definition secmem.h:137