Coverage Report

Created: 2020-08-01 06:18

/src/botan/build/include/botan/secmem.h
Line
Count
Source (jump to first uncovered line)
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>
21
class secure_allocator
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
      secure_allocator() noexcept = default;
39
      secure_allocator(const secure_allocator&) noexcept = default;
40
      secure_allocator& operator=(const secure_allocator&) noexcept = default;
41
      ~secure_allocator() noexcept = default;
42
43
      template<typename U>
44
      secure_allocator(const secure_allocator<U>&) noexcept {}
45
46
      T* allocate(std::size_t n)
47
96.7M
         {
48
96.7M
         return static_cast<T*>(allocate_memory(n, sizeof(T)));
49
96.7M
         }
Botan::secure_allocator<unsigned long>::allocate(unsigned long)
Line
Count
Source
47
93.1M
         {
48
93.1M
         return static_cast<T*>(allocate_memory(n, sizeof(T)));
49
93.1M
         }
Botan::secure_allocator<unsigned char>::allocate(unsigned long)
Line
Count
Source
47
3.52M
         {
48
3.52M
         return static_cast<T*>(allocate_memory(n, sizeof(T)));
49
3.52M
         }
Botan::secure_allocator<unsigned int>::allocate(unsigned long)
Line
Count
Source
47
136k
         {
48
136k
         return static_cast<T*>(allocate_memory(n, sizeof(T)));
49
136k
         }
Unexecuted instantiation: Botan::secure_allocator<unsigned short>::allocate(unsigned long)
50
51
      void deallocate(T* p, std::size_t n)
52
96.7M
         {
53
96.7M
         deallocate_memory(p, n, sizeof(T));
54
96.7M
         }
Botan::secure_allocator<unsigned long>::deallocate(unsigned long*, unsigned long)
Line
Count
Source
52
93.1M
         {
53
93.1M
         deallocate_memory(p, n, sizeof(T));
54
93.1M
         }
Botan::secure_allocator<unsigned char>::deallocate(unsigned char*, unsigned long)
Line
Count
Source
52
3.52M
         {
53
3.52M
         deallocate_memory(p, n, sizeof(T));
54
3.52M
         }
Botan::secure_allocator<unsigned int>::deallocate(unsigned int*, unsigned long)
Line
Count
Source
52
136k
         {
53
136k
         deallocate_memory(p, n, sizeof(T));
54
136k
         }
Unexecuted instantiation: Botan::secure_allocator<unsigned short>::deallocate(unsigned short*, unsigned long)
55
   };
56
57
template<typename T, typename U> inline bool
58
operator==(const secure_allocator<T>&, const secure_allocator<U>&)
59
   { return true; }
60
61
template<typename T, typename U> inline bool
62
operator!=(const secure_allocator<T>&, const secure_allocator<U>&)
63
491k
   { return false; }
bool Botan::operator!=<unsigned char, unsigned char>(Botan::secure_allocator<unsigned char> const&, Botan::secure_allocator<unsigned char> const&)
Line
Count
Source
63
491k
   { return false; }
Unexecuted instantiation: bool Botan::operator!=<unsigned short, unsigned short>(Botan::secure_allocator<unsigned short> const&, Botan::secure_allocator<unsigned short> const&)
64
65
template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>;
66
template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>;
67
68
// For better compatibility with 1.10 API
69
template<typename T> using SecureVector = secure_vector<T>;
70
71
template<typename T>
72
std::vector<T> unlock(const secure_vector<T>& in)
73
7.87k
   {
74
7.87k
   std::vector<T> out(in.size());
75
7.87k
   copy_mem(out.data(), in.data(), in.size());
76
7.87k
   return out;
77
7.87k
   }
78
79
template<typename T, typename Alloc>
80
size_t buffer_insert(std::vector<T, Alloc>& buf,
81
                     size_t buf_offset,
82
                     const T input[],
83
                     size_t input_length)
84
972k
   {
85
972k
   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
86
972k
   const size_t to_copy = std::min(input_length, buf.size() - buf_offset);
87
972k
   if(to_copy > 0)
88
618k
      {
89
618k
      copy_mem(&buf[buf_offset], input, to_copy);
90
618k
      }
91
972k
   return to_copy;
92
972k
   }
unsigned long Botan::buffer_insert<unsigned char, Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, unsigned long, unsigned char const*, unsigned long)
Line
Count
Source
84
969k
   {
85
969k
   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
86
969k
   const size_t to_copy = std::min(input_length, buf.size() - buf_offset);
87
969k
   if(to_copy > 0)
88
616k
      {
89
616k
      copy_mem(&buf[buf_offset], input, to_copy);
90
616k
      }
91
969k
   return to_copy;
92
969k
   }
unsigned long Botan::buffer_insert<unsigned char, std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long, unsigned char const*, unsigned long)
Line
Count
Source
84
3.06k
   {
85
3.06k
   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
86
3.06k
   const size_t to_copy = std::min(input_length, buf.size() - buf_offset);
87
3.06k
   if(to_copy > 0)
88
2.11k
      {
89
2.11k
      copy_mem(&buf[buf_offset], input, to_copy);
90
2.11k
      }
91
3.06k
   return to_copy;
92
3.06k
   }
93
94
template<typename T, typename Alloc, typename Alloc2>
95
size_t buffer_insert(std::vector<T, Alloc>& buf,
96
                     size_t buf_offset,
97
                     const std::vector<T, Alloc2>& input)
98
3.10k
   {
99
3.10k
   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
100
3.10k
   const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);
101
3.10k
   if(to_copy > 0)
102
3.10k
      {
103
3.10k
      copy_mem(&buf[buf_offset], input.data(), to_copy);
104
3.10k
      }
105
3.10k
   return to_copy;
106
3.10k
   }
unsigned long Botan::buffer_insert<unsigned char, Botan::secure_allocator<unsigned char>, std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, unsigned long, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Line
Count
Source
98
3.06k
   {
99
3.06k
   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
100
3.06k
   const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);
101
3.06k
   if(to_copy > 0)
102
3.06k
      {
103
3.06k
      copy_mem(&buf[buf_offset], input.data(), to_copy);
104
3.06k
      }
105
3.06k
   return to_copy;
106
3.06k
   }
unsigned long Botan::buffer_insert<unsigned char, Botan::secure_allocator<unsigned char>, Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, unsigned long, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Line
Count
Source
98
32
   {
99
32
   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
100
32
   const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);
101
32
   if(to_copy > 0)
102
32
      {
103
32
      copy_mem(&buf[buf_offset], input.data(), to_copy);
104
32
      }
105
32
   return to_copy;
106
32
   }
107
108
template<typename T, typename Alloc, typename Alloc2>
109
std::vector<T, Alloc>&
110
operator+=(std::vector<T, Alloc>& out,
111
           const std::vector<T, Alloc2>& in)
112
367k
   {
113
367k
   const size_t copy_offset = out.size();
114
367k
   out.resize(out.size() + in.size());
115
367k
   if(in.size() > 0)
116
325k
      {
117
325k
      copy_mem(&out[copy_offset], in.data(), in.size());
118
325k
      }
119
367k
   return out;
120
367k
   }
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
112
7.45k
   {
113
7.45k
   const size_t copy_offset = out.size();
114
7.45k
   out.resize(out.size() + in.size());
115
7.45k
   if(in.size() > 0)
116
1.33k
      {
117
1.33k
      copy_mem(&out[copy_offset], in.data(), in.size());
118
1.33k
      }
119
7.45k
   return out;
120
7.45k
   }
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&)
Line
Count
Source
112
1.39k
   {
113
1.39k
   const size_t copy_offset = out.size();
114
1.39k
   out.resize(out.size() + in.size());
115
1.39k
   if(in.size() > 0)
116
1.39k
      {
117
1.39k
      copy_mem(&out[copy_offset], in.data(), in.size());
118
1.39k
      }
119
1.39k
   return out;
120
1.39k
   }
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&)
Line
Count
Source
112
351k
   {
113
351k
   const size_t copy_offset = out.size();
114
351k
   out.resize(out.size() + in.size());
115
351k
   if(in.size() > 0)
116
315k
      {
117
315k
      copy_mem(&out[copy_offset], in.data(), in.size());
118
315k
      }
119
351k
   return out;
120
351k
   }
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >& Botan::operator+=<unsigned char, std::__1::allocator<unsigned char>, Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Line
Count
Source
112
7.38k
   {
113
7.38k
   const size_t copy_offset = out.size();
114
7.38k
   out.resize(out.size() + in.size());
115
7.38k
   if(in.size() > 0)
116
7.38k
      {
117
7.38k
      copy_mem(&out[copy_offset], in.data(), in.size());
118
7.38k
      }
119
7.38k
   return out;
120
7.38k
   }
121
122
template<typename T, typename Alloc>
123
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in)
124
   {
125
   out.push_back(in);
126
   return out;
127
   }
128
129
template<typename T, typename Alloc, typename L>
130
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
131
                                  const std::pair<const T*, L>& in)
132
260k
   {
133
260k
   const size_t copy_offset = out.size();
134
260k
   out.resize(out.size() + in.second);
135
260k
   if(in.second > 0)
136
250k
      {
137
250k
      copy_mem(&out[copy_offset], in.first, in.second);
138
250k
      }
139
260k
   return out;
140
260k
   }
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
132
252k
   {
133
252k
   const size_t copy_offset = out.size();
134
252k
   out.resize(out.size() + in.second);
135
252k
   if(in.second > 0)
136
241k
      {
137
241k
      copy_mem(&out[copy_offset], in.first, in.second);
138
241k
      }
139
252k
   return out;
140
252k
   }
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
132
8.06k
   {
133
8.06k
   const size_t copy_offset = out.size();
134
8.06k
   out.resize(out.size() + in.second);
135
8.06k
   if(in.second > 0)
136
8.06k
      {
137
8.06k
      copy_mem(&out[copy_offset], in.first, in.second);
138
8.06k
      }
139
8.06k
   return out;
140
8.06k
   }
141
142
template<typename T, typename Alloc, typename L>
143
std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
144
                                  const std::pair<T*, L>& in)
145
228k
   {
146
228k
   const size_t copy_offset = out.size();
147
228k
   out.resize(out.size() + in.second);
148
228k
   if(in.second > 0)
149
228k
      {
150
228k
      copy_mem(&out[copy_offset], in.first, in.second);
151
228k
      }
152
228k
   return out;
153
228k
   }
154
155
/**
156
* Zeroise the values; length remains unchanged
157
* @param vec the vector to zeroise
158
*/
159
template<typename T, typename Alloc>
160
void zeroise(std::vector<T, Alloc>& vec)
161
708k
   {
162
708k
   clear_mem(vec.data(), vec.size());
163
708k
   }
void Botan::zeroise<unsigned int, Botan::secure_allocator<unsigned int> >(std::__1::vector<unsigned int, Botan::secure_allocator<unsigned int> >&)
Line
Count
Source
161
50.8k
   {
162
50.8k
   clear_mem(vec.data(), vec.size());
163
50.8k
   }
Unexecuted instantiation: void Botan::zeroise<unsigned long, Botan::secure_allocator<unsigned long> >(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&)
void Botan::zeroise<unsigned char, Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&)
Line
Count
Source
161
654k
   {
162
654k
   clear_mem(vec.data(), vec.size());
163
654k
   }
Unexecuted instantiation: void Botan::zeroise<unsigned short, Botan::secure_allocator<unsigned short> >(std::__1::vector<unsigned short, Botan::secure_allocator<unsigned short> >&)
void Botan::zeroise<unsigned char, std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&)
Line
Count
Source
161
3.06k
   {
162
3.06k
   clear_mem(vec.data(), vec.size());
163
3.06k
   }
164
165
/**
166
* Zeroise the values then free the memory
167
* @param vec the vector to zeroise and free
168
*/
169
template<typename T, typename Alloc>
170
void zap(std::vector<T, Alloc>& vec)
171
0
   {
172
0
   zeroise(vec);
173
0
   vec.clear();
174
0
   vec.shrink_to_fit();
175
0
   }
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 long, Botan::secure_allocator<unsigned long> >(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&)
Unexecuted instantiation: void Botan::zap<unsigned char, Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&)
Unexecuted instantiation: void Botan::zap<unsigned short, Botan::secure_allocator<unsigned short> >(std::__1::vector<unsigned short, Botan::secure_allocator<unsigned short> >&)
Unexecuted instantiation: void Botan::zap<unsigned char, std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&)
176
177
}
178
179
#endif