Crypto++  5.6.3
Free C++ class library of cryptographic schemes
misc.cpp
1 // misc.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 #include "config.h"
5 
6 #if CRYPTOPP_MSC_VERSION
7 # pragma warning(disable: 4189)
8 # if (CRYPTOPP_MSC_VERSION >= 1400)
9 # pragma warning(disable: 6237)
10 # endif
11 #endif
12 
13 #ifndef CRYPTOPP_IMPORTS
14 
15 #include "misc.h"
16 #include "words.h"
17 #include "words.h"
18 #include "stdcpp.h"
19 #include "integer.h"
20 
21 // for memalign
22 #if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
23 # include <malloc.h>
24 #endif
25 
26 NAMESPACE_BEGIN(CryptoPP)
27 
28 void xorbuf(byte *buf, const byte *mask, size_t count)
29 {
30  assert(buf != NULL);
31  assert(mask != NULL);
32  assert(count > 0);
33 
34  size_t i=0;
35  if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
36  {
37  if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
38  {
39  for (i=0; i<count/8; i++)
40  ((word64*)(void*)buf)[i] ^= ((word64*)(void*)mask)[i];
41  count -= 8*i;
42  if (!count)
43  return;
44  buf += 8*i;
45  mask += 8*i;
46  }
47 
48  for (i=0; i<count/4; i++)
49  ((word32*)(void*)buf)[i] ^= ((word32*)(void*)mask)[i];
50  count -= 4*i;
51  if (!count)
52  return;
53  buf += 4*i;
54  mask += 4*i;
55  }
56 
57  for (i=0; i<count; i++)
58  buf[i] ^= mask[i];
59 }
60 
61 void xorbuf(byte *output, const byte *input, const byte *mask, size_t count)
62 {
63  assert(output != NULL);
64  assert(input != NULL);
65  assert(count > 0);
66 
67  size_t i=0;
68  if (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask))
69  {
70  if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(output) && IsAligned<word64>(input) && IsAligned<word64>(mask))
71  {
72  for (i=0; i<count/8; i++)
73  ((word64*)(void*)output)[i] = ((word64*)(void*)input)[i] ^ ((word64*)(void*)mask)[i];
74  count -= 8*i;
75  if (!count)
76  return;
77  output += 8*i;
78  input += 8*i;
79  mask += 8*i;
80  }
81 
82  for (i=0; i<count/4; i++)
83  ((word32*)(void*)output)[i] = ((word32*)(void*)input)[i] ^ ((word32*)(void*)mask)[i];
84  count -= 4*i;
85  if (!count)
86  return;
87  output += 4*i;
88  input += 4*i;
89  mask += 4*i;
90  }
91 
92  for (i=0; i<count; i++)
93  output[i] = input[i] ^ mask[i];
94 }
95 
96 bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
97 {
98  assert(buf != NULL);
99  assert(mask != NULL);
100  assert(count > 0);
101 
102  size_t i=0;
103  byte acc8 = 0;
104 
105  if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
106  {
107  word32 acc32 = 0;
108  if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
109  {
110  word64 acc64 = 0;
111  for (i=0; i<count/8; i++)
112  acc64 |= ((word64*)(void*)buf)[i] ^ ((word64*)(void*)mask)[i];
113  count -= 8*i;
114  if (!count)
115  return acc64 == 0;
116  buf += 8*i;
117  mask += 8*i;
118  acc32 = word32(acc64) | word32(acc64>>32);
119  }
120 
121  for (i=0; i<count/4; i++)
122  acc32 |= ((word32*)(void*)buf)[i] ^ ((word32*)(void*)mask)[i];
123  count -= 4*i;
124  if (!count)
125  return acc32 == 0;
126  buf += 4*i;
127  mask += 4*i;
128  acc8 = byte(acc32) | byte(acc32>>8) | byte(acc32>>16) | byte(acc32>>24);
129  }
130 
131  for (i=0; i<count; i++)
132  acc8 |= buf[i] ^ mask[i];
133  return acc8 == 0;
134 }
135 
136 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
137 std::string StringNarrow(const wchar_t *str, bool throwOnError)
138 {
139  assert(str);
140  std::string result;
141 
142  // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
143 #if (CRYPTOPP_MSC_VERSION >= 1400)
144  size_t len=0, size=0;
145  errno_t err = 0;
146 
147  //const wchar_t* ptr = str;
148  //while (*ptr++) len++;
149  len = wcslen(str)+1;
150 
151  err = wcstombs_s(&size, NULL, 0, str, len*sizeof(wchar_t));
152  assert(err == 0);
153  if (err != 0) {goto CONVERSION_ERROR;}
154 
155  result.resize(size);
156  err = wcstombs_s(&size, &result[0], size, str, len*sizeof(wchar_t));
157  assert(err == 0);
158 
159  if (err != 0)
160  {
161 CONVERSION_ERROR:
162  if (throwOnError)
163  throw InvalidArgument("StringNarrow: wcstombs_s() call failed with error " + IntToString(err));
164  else
165  return std::string();
166  }
167 
168  // The safe routine's size includes the NULL.
169  if (!result.empty() && result[size - 1] == '\0')
170  result.erase(size - 1);
171 #else
172  size_t size = wcstombs(NULL, str, 0);
173  assert(size != (size_t)-1);
174  if (size == (size_t)-1) {goto CONVERSION_ERROR;}
175 
176  result.resize(size);
177  size = wcstombs(&result[0], str, size);
178  assert(size != (size_t)-1);
179 
180  if (size == (size_t)-1)
181  {
182 CONVERSION_ERROR:
183  if (throwOnError)
184  throw InvalidArgument("StringNarrow: wcstombs() call failed");
185  else
186  return std::string();
187  }
188 #endif
189 
190  return result;
191 }
192 #endif // StringNarrow and CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
193 
194 #if !(defined(_MSC_VER) && (_MSC_VER < 1300))
195 using std::new_handler;
196 using std::set_new_handler;
197 #endif
198 
200 {
201  new_handler newHandler = set_new_handler(NULL);
202  if (newHandler)
203  set_new_handler(newHandler);
204 
205  if (newHandler)
206  newHandler();
207  else
208  throw std::bad_alloc();
209 }
210 
211 #if CRYPTOPP_BOOL_ALIGN16
212 
213 void * AlignedAllocate(size_t size)
214 {
215  byte *p;
216 #if defined(CRYPTOPP_APPLE_ALLOC_AVAILABLE)
217  while ((p = (byte *)calloc(1, size)) == NULL)
218 #elif defined(CRYPTOPP_MM_MALLOC_AVAILABLE)
219  while ((p = (byte *)_mm_malloc(size, 16)) == NULL)
220 #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
221  while ((p = (byte *)memalign(16, size)) == NULL)
222 #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16)
223  while ((p = (byte *)malloc(size)) == NULL)
224 #else
225  while ((p = (byte *)malloc(size + 16)) == NULL)
226 #endif
227  CallNewHandler();
228 
229 #ifdef CRYPTOPP_NO_ALIGNED_ALLOC
230  size_t adjustment = 16-((size_t)p%16);
231  p += adjustment;
232  p[-1] = (byte)adjustment;
233 #endif
234 
235  assert(IsAlignedOn(p, 16));
236  return p;
237 }
238 
239 void AlignedDeallocate(void *p)
240 {
241 #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
242  _mm_free(p);
243 #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)
244  p = (byte *)p - ((byte *)p)[-1];
245  free(p);
246 #else
247  free(p);
248 #endif
249 }
250 
251 #endif
252 
253 void * UnalignedAllocate(size_t size)
254 {
255  void *p;
256  while ((p = malloc(size)) == NULL)
257  CallNewHandler();
258  return p;
259 }
260 
261 void UnalignedDeallocate(void *p)
262 {
263  free(p);
264 }
265 
266 NAMESPACE_END
267 
268 #endif
An invalid argument was detected.
Definition: cryptlib.h:182
std::string StringNarrow(const wchar_t *str, bool throwOnError=true)
Converts a wide character C-string to a multibyte string.
Definition: misc.cpp:137
Utility functions for the Crypto++ library.
void AlignedDeallocate(void *ptr)
Frees a buffer allocated with AlignedAllocate.
Library configuration file.
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:869
void * UnalignedAllocate(size_t size)
Allocates a buffer.
Definition: misc.cpp:253
void CallNewHandler()
Attempts to reclaim unused memory.
Definition: misc.cpp:199
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:494
bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
Definition: misc.cpp:96
Crypto++ library namespace.
void UnalignedDeallocate(void *ptr)
Frees a buffer allocated with UnalignedAllocate.
Definition: misc.cpp:261
void * AlignedAllocate(size_t size)
Allocates a buffer on 16-byte boundary.