Botan 3.12.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
36
37 public:
38 typedef T value_type;
39 typedef std::size_t size_type;
40
41 secure_allocator() noexcept = default;
42 secure_allocator(const secure_allocator&) noexcept = default;
43 secure_allocator& operator=(const secure_allocator&) noexcept = default;
44 secure_allocator(secure_allocator&&) noexcept = default;
45 secure_allocator& operator=(secure_allocator&&) noexcept = default;
46
47 ~secure_allocator() noexcept = default;
48
49 template <typename U>
50 explicit secure_allocator(const secure_allocator<U>& /*other*/) noexcept {}
51
52 T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
53
54 void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
55};
56
57template <typename T, typename U>
58inline bool operator==(const secure_allocator<T>& /*a*/, const secure_allocator<U>& /*b*/) {
59 return true;
60}
61
62template <typename T, typename U>
63inline bool operator!=(const secure_allocator<T>& /*a*/, const secure_allocator<U>& /*b*/) {
64 return false;
65}
66
67template <typename T>
68using secure_vector = std::vector<T, secure_allocator<T>>;
69
70#if !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_DISABLE_DEPRECATED_FEATURES)
71template <typename T>
72using secure_deque = std::deque<T, secure_allocator<T>>;
73#endif
74
75// For better compatibility with 1.10 API
76template <typename T>
78
79template <typename T>
80secure_vector<T> lock(const std::vector<T>& in) {
81 return secure_vector<T>(in.begin(), in.end());
82}
83
84template <typename T>
85std::vector<T> unlock(const secure_vector<T>& in) {
86 return std::vector<T>(in.begin(), in.end());
87}
88
89// TODO(Botan4) remove these += operators entirely
90
91template <typename T, typename Alloc, typename Alloc2>
92std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::vector<T, Alloc2>& in) {
93 out.insert(out.end(), in.begin(), in.end());
94 return out;
95}
96
97template <typename T, typename Alloc>
98std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, std::span<const T> in) {
99 out.insert(out.end(), in.begin(), in.end());
100 return out;
101}
102
103template <typename T, typename Alloc>
104std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in) {
105 out.push_back(in);
106 return out;
107}
108
109template <typename T, typename Alloc, typename L>
110std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::pair<const T*, L>& in) {
111 out.insert(out.end(), in.first, in.first + in.second);
112 return out;
113}
114
115template <typename T, typename Alloc, typename L>
116std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::pair<T*, L>& in) {
117 out.insert(out.end(), in.first, in.first + in.second);
118 return out;
119}
120
121/**
122* Zeroise the values; length remains unchanged
123*
124* Note this is not intended for cases where the compiler might elide
125* the writes as being without side-effects; use secure_scrub_memory
126* for that.
127*
128* TODO(Botan4): make these not-inlined and only for secure_vector, eg declare
129* void zeroize(secure_vector<uint8_t>& v);
130* void zeroize(secure_vector<uint16_t>& v);
131* void zeroize(secure_vector<uint32_t>& v);
132* void zeroize(secure_vector<uint64_t>& v);
133*
134* @param vec the vector to zeroise
135*/
136template <typename T, typename Alloc>
137void zeroise(std::vector<T, Alloc>& vec) {
138 for(size_t i = 0; i != vec.size(); ++i) {
139 vec[i] = static_cast<T>(0);
140 }
141}
142
143/**
144* Zeroise the values then free the memory
145*
146* TODO(Botan4): make these not-inlined and only for secure_vector, eg declare
147* void zap(secure_vector<uint8_t>& v);
148* void zap(secure_vector<uint16_t>& v);
149* void zap(secure_vector<uint32_t>& v);
150* void zap(secure_vector<uint64_t>& v);
151*
152* [And maybe rename as well]
153*
154* @param vec the vector to zeroise and free
155*/
156template <typename T, typename Alloc>
157void zap(std::vector<T, Alloc>& vec) {
158 zeroise(vec);
159 vec.clear();
160 vec.shrink_to_fit();
161}
162
163} // namespace Botan
164
165#endif
T * allocate(std::size_t n)
Definition secmem.h:52
void deallocate(T *p, std::size_t n)
Definition secmem.h:54
secure_allocator() noexcept=default
std::size_t size_type
Definition secmem.h:39
void zeroise(std::vector< T, Alloc > &vec)
Definition secmem.h:137
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:157
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:80
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition alg_id.cpp:68
std::vector< T > unlock(const secure_vector< T > &in)
Definition secmem.h:85
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition alg_id.cpp:53
std::deque< T, secure_allocator< T > > secure_deque
Definition secmem.h:72
std::vector< T, Alloc > & operator+=(std::vector< T, Alloc > &out, const std::vector< T, Alloc2 > &in)
Definition secmem.h:92
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:68
secure_vector< T > SecureVector
Definition secmem.h:77