Coverage Report

Created: 2026-06-08 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/build/include/public/botan/secmem.h
Line
Count
Source
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 <algorithm>
14
#include <span>
15
#include <type_traits>
16
#include <vector>  // IWYU pragma: export
17
18
#if !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_DISABLE_DEPRECATED_FEATURES)
19
   // TODO(Botan4) remove this
20
   #include <deque>
21
#endif
22
23
namespace Botan {
24
25
template <typename T>
26
#if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0
27
/*
28
  * Check 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
   requires std::is_integral_v<T> || std::is_enum_v<T>
35
#endif
36
class secure_allocator {
37
38
   public:
39
      typedef T value_type;
40
      typedef std::size_t size_type;
41
42
      secure_allocator() noexcept = default;
43
      secure_allocator(const secure_allocator&) noexcept = default;
44
      secure_allocator& operator=(const secure_allocator&) noexcept = default;
45
      secure_allocator(secure_allocator&&) noexcept = default;
46
      secure_allocator& operator=(secure_allocator&&) noexcept = default;
47
48
      ~secure_allocator() noexcept = default;
49
50
      template <typename U>
51
      explicit secure_allocator(const secure_allocator<U>& /*other*/) noexcept {}
52
53
1.21M
      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
Botan::secure_allocator<unsigned char>::allocate(unsigned long)
Line
Count
Source
53
65.1k
      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
Botan::secure_allocator<unsigned long>::allocate(unsigned long)
Line
Count
Source
53
1.14M
      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
Botan::secure_allocator<unsigned int>::allocate(unsigned long)
Line
Count
Source
53
5.37k
      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
Unexecuted instantiation: Botan::secure_allocator<unsigned short>::allocate(unsigned long)
54
55
1.21M
      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
Botan::secure_allocator<unsigned long>::deallocate(unsigned long*, unsigned long)
Line
Count
Source
55
1.14M
      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
Botan::secure_allocator<unsigned char>::deallocate(unsigned char*, unsigned long)
Line
Count
Source
55
65.1k
      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
Botan::secure_allocator<unsigned int>::deallocate(unsigned int*, unsigned long)
Line
Count
Source
55
5.37k
      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
Unexecuted instantiation: Botan::secure_allocator<unsigned short>::deallocate(unsigned short*, unsigned long)
56
};
57
58
template <typename T, typename U>
59
inline bool operator==(const secure_allocator<T>& /*a*/, const secure_allocator<U>& /*b*/) {
60
   return true;
61
}
62
63
template <typename T, typename U>
64
6.26k
inline bool operator!=(const secure_allocator<T>& /*a*/, const secure_allocator<U>& /*b*/) {
65
6.26k
   return false;
66
6.26k
}
67
68
template <typename T>
69
using secure_vector = std::vector<T, secure_allocator<T>>;
70
71
#if !defined(BOTAN_IS_BEING_BUILT) && !defined(BOTAN_DISABLE_DEPRECATED_FEATURES)
72
template <typename T>
73
using secure_deque = std::deque<T, secure_allocator<T>>;
74
#endif
75
76
// For better compatibility with 1.10 API
77
template <typename T>
78
using SecureVector = secure_vector<T>;
79
80
template <typename T>
81
secure_vector<T> lock(const std::vector<T>& in) {
82
   return secure_vector<T>(in.begin(), in.end());
83
}
84
85
template <typename T>
86
0
std::vector<T> unlock(const secure_vector<T>& in) {
87
0
   return std::vector<T>(in.begin(), in.end());
88
0
}
89
90
template <typename T, typename Alloc, typename Alloc2>
91
12
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::vector<T, Alloc2>& in) {
92
12
   out.insert(out.end(), in.begin(), in.end());
93
12
   return out;
94
12
}
std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >& Botan::operator+=<unsigned char, Botan::secure_allocator<unsigned char>, Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Line
Count
Source
91
12
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::vector<T, Alloc2>& in) {
92
12
   out.insert(out.end(), in.begin(), in.end());
93
12
   return out;
94
12
}
Unexecuted instantiation: std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >& Botan::operator+=<unsigned char, std::__1::allocator<unsigned char>, std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >& Botan::operator+=<unsigned char, Botan::secure_allocator<unsigned char>, std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
95
96
template <typename T, typename Alloc>
97
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, std::span<const T> in) {
98
   out.insert(out.end(), in.begin(), in.end());
99
   return out;
100
}
101
102
template <typename T, typename Alloc>
103
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in) {
104
   out.push_back(in);
105
   return out;
106
}
107
108
template <typename T, typename Alloc, typename L>
109
5.24k
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::pair<const T*, L>& in) {
110
5.24k
   out.insert(out.end(), in.first, in.first + in.second);
111
5.24k
   return out;
112
5.24k
}
std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >& Botan::operator+=<unsigned char, Botan::secure_allocator<unsigned char>, unsigned long>(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, std::__1::pair<unsigned char const*, unsigned long> const&)
Line
Count
Source
109
1.35k
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::pair<const T*, L>& in) {
110
1.35k
   out.insert(out.end(), in.first, in.first + in.second);
111
1.35k
   return out;
112
1.35k
}
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >& Botan::operator+=<unsigned char, std::__1::allocator<unsigned char>, unsigned long>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, std::__1::pair<unsigned char const*, unsigned long> const&)
Line
Count
Source
109
3.89k
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::pair<const T*, L>& in) {
110
3.89k
   out.insert(out.end(), in.first, in.first + in.second);
111
3.89k
   return out;
112
3.89k
}
113
114
template <typename T, typename Alloc, typename L>
115
192
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, const std::pair<T*, L>& in) {
116
192
   out.insert(out.end(), in.first, in.first + in.second);
117
192
   return out;
118
192
}
119
120
/**
121
* Zeroise the values; length remains unchanged
122
* @param vec the vector to zeroise
123
*/
124
template <typename T, typename Alloc>
125
3.10k
void zeroise(std::vector<T, Alloc>& vec) {
126
3.10k
   std::fill(vec.begin(), vec.end(), static_cast<T>(0));
127
3.10k
}
void Botan::zeroise<unsigned char, Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&)
Line
Count
Source
125
1.33k
void zeroise(std::vector<T, Alloc>& vec) {
126
1.33k
   std::fill(vec.begin(), vec.end(), static_cast<T>(0));
127
1.33k
}
void Botan::zeroise<unsigned long, Botan::secure_allocator<unsigned long> >(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&)
Line
Count
Source
125
445
void zeroise(std::vector<T, Alloc>& vec) {
126
445
   std::fill(vec.begin(), vec.end(), static_cast<T>(0));
127
445
}
void Botan::zeroise<unsigned char, std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&)
Line
Count
Source
125
1.33k
void zeroise(std::vector<T, Alloc>& vec) {
126
1.33k
   std::fill(vec.begin(), vec.end(), static_cast<T>(0));
127
1.33k
}
Unexecuted instantiation: void Botan::zeroise<unsigned int, Botan::secure_allocator<unsigned int> >(std::__1::vector<unsigned int, Botan::secure_allocator<unsigned int> >&)
Unexecuted instantiation: void Botan::zeroise<unsigned short, Botan::secure_allocator<unsigned short> >(std::__1::vector<unsigned short, Botan::secure_allocator<unsigned short> >&)
128
129
/**
130
* Zeroise the values then free the memory
131
* @param vec the vector to zeroise and free
132
*/
133
template <typename T, typename Alloc>
134
445
void zap(std::vector<T, Alloc>& vec) {
135
445
   zeroise(vec);
136
445
   vec.clear();
137
445
   vec.shrink_to_fit();
138
445
}
Unexecuted instantiation: void Botan::zap<unsigned char, Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&)
void Botan::zap<unsigned long, Botan::secure_allocator<unsigned long> >(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&)
Line
Count
Source
134
445
void zap(std::vector<T, Alloc>& vec) {
135
445
   zeroise(vec);
136
445
   vec.clear();
137
445
   vec.shrink_to_fit();
138
445
}
Unexecuted instantiation: void Botan::zap<unsigned char, std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&)
Unexecuted instantiation: void Botan::zap<unsigned int, Botan::secure_allocator<unsigned int> >(std::__1::vector<unsigned int, Botan::secure_allocator<unsigned int> >&)
Unexecuted instantiation: void Botan::zap<unsigned short, Botan::secure_allocator<unsigned short> >(std::__1::vector<unsigned short, Botan::secure_allocator<unsigned short> >&)
139
140
}  // namespace Botan
141
142
#endif