Botan  2.1.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 * Scrub memory contents in a way that a compiler should not elide,
19 * using some system specific technique. Note that this function might
20 * not zero the memory (for example, in some hypothetical
21 * implementation it might combine the memory contents with the output
22 * of a system PRNG), but if you can detect any difference in behavior
23 * at runtime then the clearing is side-effecting and you can just
24 * use `clear_mem`.
25 *
26 * Use this function to scrub memory just before deallocating it, or on
27 * a stack buffer before returning from the function.
28 *
29 * @param ptr a pointer to memory to scrub
30 * @param n the number of bytes pointed to by ptr
31 */
32 BOTAN_DLL void secure_scrub_memory(void* ptr, size_t n);
33 
34 /**
35 * Zero out some bytes
36 * @param ptr a pointer to memory to zero
37 * @param bytes the number of bytes to zero in ptr
38 */
39 inline void clear_bytes(void* ptr, size_t bytes)
40  {
41  if(bytes > 0)
42  {
43  std::memset(ptr, 0, bytes);
44  }
45  }
46 
47 /**
48 * Zero memory before use. This simply calls memset and should not be
49 * used in cases where the compiler cannot see the call as a
50 * side-effecting operation (for example, if calling clear_mem before
51 * deallocating memory, the compiler would be allowed to omit the call
52 * to memset entirely under the as-if rule.)
53 *
54 * @param ptr a pointer to an array of Ts to zero
55 * @param n the number of Ts pointed to by ptr
56 */
57 template<typename T> inline void clear_mem(T* ptr, size_t n)
58  {
59  clear_bytes(ptr, sizeof(T)*n);
60  }
61 
62 /**
63 * Copy memory
64 * @param out the destination array
65 * @param in the source array
66 * @param n the number of elements of in/out
67 */
68 template<typename T> inline void copy_mem(T* out, const T* in, size_t n)
69  {
70  if(n > 0)
71  {
72  std::memmove(out, in, sizeof(T)*n);
73  }
74  }
75 
76 /**
77 * Set memory to a fixed value
78 * @param ptr a pointer to an array
79 * @param n the number of Ts pointed to by ptr
80 * @param val the value to set each byte to
81 */
82 template<typename T>
83 inline void set_mem(T* ptr, size_t n, uint8_t val)
84  {
85  if(n > 0)
86  {
87  std::memset(ptr, val, sizeof(T)*n);
88  }
89  }
90 
91 /**
92 * Memory comparison, input insensitive
93 * @param p1 a pointer to an array
94 * @param p2 a pointer to another array
95 * @param n the number of Ts in p1 and p2
96 * @return true iff p1[i] == p2[i] forall i in [0...n)
97 */
98 template<typename T> inline bool same_mem(const T* p1, const T* p2, size_t n)
99  {
100  volatile T difference = 0;
101 
102  for(size_t i = 0; i != n; ++i)
103  difference |= (p1[i] ^ p2[i]);
104 
105  return difference == 0;
106  }
107 
108 /**
109 * XOR_ arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length
110 * @param out the input/output buffer
111 * @param in the read-only input buffer
112 * @param length the length of the buffers
113 */
114 template<typename T>
115 void xor_buf(T out[], const T in[], size_t length)
116  {
117  for(size_t i = 0; i != length; ++i)
118  {
119  out[i] ^= in[i];
120  }
121  }
122 
123 /**
124 * XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length
125 * @param out the output buffer
126 * @param in the first input buffer
127 * @param in2 the second output buffer
128 * @param length the length of the three buffers
129 */
130 template<typename T> void xor_buf(T out[],
131  const T in[],
132  const T in2[],
133  size_t length)
134  {
135  for(size_t i = 0; i != length; ++i)
136  {
137  out[i] = in[i] ^ in2[i];
138  }
139  }
140 
141 template<typename Alloc, typename Alloc2>
142 void xor_buf(std::vector<uint8_t, Alloc>& out,
143  const std::vector<uint8_t, Alloc2>& in,
144  size_t n)
145  {
146  xor_buf(out.data(), in.data(), n);
147  }
148 
149 template<typename Alloc>
150 void xor_buf(std::vector<uint8_t, Alloc>& out,
151  const uint8_t* in,
152  size_t n)
153  {
154  xor_buf(out.data(), in, n);
155  }
156 
157 template<typename Alloc, typename Alloc2>
158 void xor_buf(std::vector<uint8_t, Alloc>& out,
159  const uint8_t* in,
160  const std::vector<uint8_t, Alloc2>& in2,
161  size_t n)
162  {
163  xor_buf(out.data(), in, in2.data(), n);
164  }
165 
166 template<typename T, typename Alloc, typename Alloc2>
167 std::vector<T, Alloc>&
168 operator^=(std::vector<T, Alloc>& out,
169  const std::vector<T, Alloc2>& in)
170  {
171  if(out.size() < in.size())
172  out.resize(in.size());
173 
174  xor_buf(out.data(), in.data(), in.size());
175  return out;
176  }
177 
178 }
179 
180 #endif
void clear_bytes(void *ptr, size_t bytes)
Definition: mem_ops.h:39
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
std::vector< T, Alloc > & operator^=(std::vector< T, Alloc > &out, const std::vector< T, Alloc2 > &in)
Definition: mem_ops.h:168
void secure_scrub_memory(void *ptr, size_t n)
Definition: mem_ops.cpp:17
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:98
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:57
void set_mem(T *ptr, size_t n, uint8_t val)
Definition: mem_ops.h:83
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Definition: alg_id.cpp:13