Botan  2.10.0
Crypto and TLS for C++11
mem_ops.h
Go to the documentation of this file.
1 /*
2 * Memory Operations
3 * (C) 1999-2009,2012,2015 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_MEMORY_OPS_H_
9 #define BOTAN_MEMORY_OPS_H_
10 
11 #include <botan/types.h>
12 #include <cstring>
13 #include <vector>
14 
15 namespace Botan {
16 
17 /**
18 * Allocate a memory buffer by some method. This should only be used for
19 * primitive types (uint8_t, uint32_t, etc).
20 *
21 * @param elems the number of elements
22 * @param elem_size the size of each element
23 * @return pointer to allocated and zeroed memory, or throw std::bad_alloc on failure
24 */
26 
27 /**
28 * Free a pointer returned by allocate_memory
29 * @param p the pointer returned by allocate_memory
30 * @param elems the number of elements, as passed to allocate_memory
31 * @param elem_size the size of each element, as passed to allocate_memory
32 */
33 BOTAN_PUBLIC_API(2,3) void deallocate_memory(void* p, size_t elems, size_t elem_size);
34 
35 /**
36 * Ensure the allocator is initialized
37 */
39 
41  {
42  public:
44  };
45 
46 /**
47 * Scrub memory contents in a way that a compiler should not elide,
48 * using some system specific technique. Note that this function might
49 * not zero the memory (for example, in some hypothetical
50 * implementation it might combine the memory contents with the output
51 * of a system PRNG), but if you can detect any difference in behavior
52 * at runtime then the clearing is side-effecting and you can just
53 * use `clear_mem`.
54 *
55 * Use this function to scrub memory just before deallocating it, or on
56 * a stack buffer before returning from the function.
57 *
58 * @param ptr a pointer to memory to scrub
59 * @param n the number of bytes pointed to by ptr
60 */
61 BOTAN_PUBLIC_API(2,0) void secure_scrub_memory(void* ptr, size_t n);
62 
63 /**
64 * Memory comparison, input insensitive
65 * @param x a pointer to an array
66 * @param y a pointer to another array
67 * @param len the number of Ts in x and y
68 * @return 0xFF iff x[i] == y[i] forall i in [0...n) or 0x00 otherwise
69 */
70 BOTAN_PUBLIC_API(2,9) uint8_t ct_compare_u8(const uint8_t x[],
71  const uint8_t y[],
72  size_t len);
73 
74 /**
75 * Memory comparison, input insensitive
76 * @param x a pointer to an array
77 * @param y a pointer to another array
78 * @param len the number of Ts in x and y
79 * @return true iff x[i] == y[i] forall i in [0...n)
80 */
81 inline bool constant_time_compare(const uint8_t x[],
82  const uint8_t y[],
83  size_t len)
84  {
85  return ct_compare_u8(x, y, len) == 0xFF;
86  }
87 
88 /**
89 * Zero out some bytes
90 * @param ptr a pointer to memory to zero
91 * @param bytes the number of bytes to zero in ptr
92 */
93 inline void clear_bytes(void* ptr, size_t bytes)
94  {
95  if(bytes > 0)
96  {
97  std::memset(ptr, 0, bytes);
98  }
99  }
100 
101 /**
102 * Zero memory before use. This simply calls memset and should not be
103 * used in cases where the compiler cannot see the call as a
104 * side-effecting operation (for example, if calling clear_mem before
105 * deallocating memory, the compiler would be allowed to omit the call
106 * to memset entirely under the as-if rule.)
107 *
108 * @param ptr a pointer to an array of Ts to zero
109 * @param n the number of Ts pointed to by ptr
110 */
111 template<typename T> inline void clear_mem(T* ptr, size_t n)
112  {
113  clear_bytes(ptr, sizeof(T)*n);
114  }
115 
116 /**
117 * Copy memory
118 * @param out the destination array
119 * @param in the source array
120 * @param n the number of elements of in/out
121 */
122 template<typename T> inline void copy_mem(T* out, const T* in, size_t n)
123  {
124  if(n > 0)
125  {
126  std::memmove(out, in, sizeof(T)*n);
127  }
128  }
129 
130 template<typename T> inline void typecast_copy(uint8_t out[], T in)
131  {
132  std::memcpy(out, &in, sizeof(T));
133  }
134 
135 template<typename T> inline void typecast_copy(T& out, const uint8_t in[])
136  {
137  std::memcpy(&out, in, sizeof(T));
138  }
139 
140 template<typename T> inline void typecast_copy(T out[], const uint8_t in[], size_t N)
141  {
142  std::memcpy(out, in, sizeof(T)*N);
143  }
144 
145 /**
146 * Set memory to a fixed value
147 * @param ptr a pointer to an array of bytes
148 * @param n the number of Ts pointed to by ptr
149 * @param val the value to set each byte to
150 */
151 inline void set_mem(uint8_t* ptr, size_t n, uint8_t val)
152  {
153  if(n > 0)
154  {
155  std::memset(ptr, val, n);
156  }
157  }
158 
159 inline const uint8_t* cast_char_ptr_to_uint8(const char* s)
160  {
161  return reinterpret_cast<const uint8_t*>(s);
162  }
163 
164 inline const char* cast_uint8_ptr_to_char(const uint8_t* b)
165  {
166  return reinterpret_cast<const char*>(b);
167  }
168 
169 inline uint8_t* cast_char_ptr_to_uint8(char* s)
170  {
171  return reinterpret_cast<uint8_t*>(s);
172  }
173 
174 inline char* cast_uint8_ptr_to_char(uint8_t* b)
175  {
176  return reinterpret_cast<char*>(b);
177  }
178 
179 /**
180 * Memory comparison, input insensitive
181 * @param p1 a pointer to an array
182 * @param p2 a pointer to another array
183 * @param n the number of Ts in p1 and p2
184 * @return true iff p1[i] == p2[i] forall i in [0...n)
185 */
186 template<typename T> inline bool same_mem(const T* p1, const T* p2, size_t n)
187  {
188  volatile T difference = 0;
189 
190  for(size_t i = 0; i != n; ++i)
191  difference |= (p1[i] ^ p2[i]);
192 
193  return difference == 0;
194  }
195 
196 /**
197 * XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length
198 * @param out the input/output buffer
199 * @param in the read-only input buffer
200 * @param length the length of the buffers
201 */
202 inline void xor_buf(uint8_t out[],
203  const uint8_t in[],
204  size_t length)
205  {
206  while(length >= 16)
207  {
208  uint64_t x0, x1, y0, y1;
209 
210  typecast_copy(x0, in);
211  typecast_copy(x1, in + 8);
212  typecast_copy(y0, out);
213  typecast_copy(y1, out + 8);
214 
215  y0 ^= x0;
216  y1 ^= x1;
217  typecast_copy(out, y0);
218  typecast_copy(out + 8, y1);
219  out += 16; in += 16; length -= 16;
220  }
221 
222  while(length > 0)
223  {
224  out[0] ^= in[0];
225  out += 1;
226  in += 1;
227  length -= 1;
228  }
229  }
230 
231 /**
232 * XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length
233 * @param out the output buffer
234 * @param in the first input buffer
235 * @param in2 the second output buffer
236 * @param length the length of the three buffers
237 */
238 inline void xor_buf(uint8_t out[],
239  const uint8_t in[],
240  const uint8_t in2[],
241  size_t length)
242  {
243  while(length >= 16)
244  {
245  uint64_t x0, x1, y0, y1;
246  typecast_copy(x0, in);
247  typecast_copy(x1, in + 8);
248  typecast_copy(y0, in2);
249  typecast_copy(y1, in2 + 8);
250 
251  x0 ^= y0;
252  x1 ^= y1;
253  typecast_copy(out, x0);
254  typecast_copy(out + 8, x1);
255  out += 16; in += 16; in2 += 16; length -= 16;
256  }
257 
258  for(size_t i = 0; i != length; ++i)
259  out[i] = in[i] ^ in2[i];
260  }
261 
262 template<typename Alloc, typename Alloc2>
263 void xor_buf(std::vector<uint8_t, Alloc>& out,
264  const std::vector<uint8_t, Alloc2>& in,
265  size_t n)
266  {
267  xor_buf(out.data(), in.data(), n);
268  }
269 
270 template<typename Alloc>
271 void xor_buf(std::vector<uint8_t, Alloc>& out,
272  const uint8_t* in,
273  size_t n)
274  {
275  xor_buf(out.data(), in, n);
276  }
277 
278 template<typename Alloc, typename Alloc2>
279 void xor_buf(std::vector<uint8_t, Alloc>& out,
280  const uint8_t* in,
281  const std::vector<uint8_t, Alloc2>& in2,
282  size_t n)
283  {
284  xor_buf(out.data(), in, in2.data(), n);
285  }
286 
287 template<typename Alloc, typename Alloc2>
288 std::vector<uint8_t, Alloc>&
289 operator^=(std::vector<uint8_t, Alloc>& out,
290  const std::vector<uint8_t, Alloc2>& in)
291  {
292  if(out.size() < in.size())
293  out.resize(in.size());
294 
295  xor_buf(out.data(), in.data(), in.size());
296  return out;
297  }
298 
299 }
300 
301 #endif
void clear_bytes(void *ptr, size_t bytes)
Definition: mem_ops.h:93
BigInt const BigInt & x
Definition: numthry.h:139
std::string size_t len
Definition: pk_keys.h:305
BigInt size_t n
Definition: bigint.h:1096
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:186
bool const OID & b
Definition: asn1_oid.h:109
size_t elem_size
Definition: mem_ops.h:25
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:111
void set_mem(uint8_t *ptr, size_t n, uint8_t val)
Definition: mem_ops.h:151
void typecast_copy(uint8_t out[], T in)
Definition: mem_ops.h:130
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:159
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:81
void const uint8_t in[]
Definition: mgf1.h:26
BOTAN_MALLOC_FN void * allocate_memory(size_t elems, size_t elem_size)
Definition: mem_ops.cpp:18
#define BOTAN_MALLOC_FN
Definition: compiler.h:93
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:202
uint8_t ct_compare_u8(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.cpp:53
BigInt const BigInt & p
Definition: numthry.h:150
std::vector< uint8_t, Alloc > & operator^=(std::vector< uint8_t, Alloc > &out, const std::vector< uint8_t, Alloc2 > &in)
Definition: mem_ops.h:289
void deallocate_memory(void *p, size_t elems, size_t elem_size)
Definition: mem_ops.cpp:31
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:122
Definition: alg_id.cpp:13
uint8_t out[]
Definition: pbkdf2.h:19
size_t bytes
Definition: ffi.h:150
class BOTAN_PUBLIC_API(2, 0) AlgorithmIdentifier final bool BOTAN_PUBLIC_API(2, 0) operator
Name Constraints.
Definition: asn1_obj.h:65
void secure_scrub_memory(void *ptr, size_t n)
Definition: os_utils.cpp:51
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:164
uint32_t * val
Definition: ffi.h:794
const OctetString & y
Definition: symkey.h:126
fe T
Definition: ge.cpp:37
const BigInt const PointGFp & p2
Definition: point_gfp.h:350
class BOTAN_PUBLIC_API(2, 8) Scrypt final class BOTAN_PUBLIC_API(2, 8) Scrypt_Family final void size_t const char size_t const uint8_t size_t size_t N
Definition: scrypt.h:85
size_t elems
Definition: mem_ops.h:33
void initialize_allocator()
Definition: mem_ops.cpp:46