Crypto++  5.6.5
Free C++ class library of cryptographic schemes
misc.cpp
1 // misc.cpp - originally 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  CRYPTOPP_ASSERT(buf != NULLPTR);
31  CRYPTOPP_ASSERT(mask != NULLPTR);
32  CRYPTOPP_ASSERT(count > 0);
33 
34  size_t i=0;
35  if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
36  {
37  if (!CRYPTOPP_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  CRYPTOPP_ASSERT(output != NULLPTR);
64  CRYPTOPP_ASSERT(input != NULLPTR);
65  CRYPTOPP_ASSERT(count > 0);
66 
67  size_t i=0;
68  if (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask))
69  {
70  if (!CRYPTOPP_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  CRYPTOPP_ASSERT(buf != NULLPTR);
99  CRYPTOPP_ASSERT(mask != NULLPTR);
100  CRYPTOPP_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_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 std::string StringNarrow(const wchar_t *str, bool throwOnError)
137 {
138  CRYPTOPP_ASSERT(str);
139  std::string result;
140 
141  // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
142 #if (CRYPTOPP_MSC_VERSION >= 1400)
143  size_t len=0, size=0;
144  errno_t err = 0;
145 
146  //const wchar_t* ptr = str;
147  //while (*ptr++) len++;
148  len = wcslen(str)+1;
149 
150  err = wcstombs_s(&size, NULLPTR, 0, str, len*sizeof(wchar_t));
151  CRYPTOPP_ASSERT(err == 0);
152  if (err != 0)
153  {
154  if (throwOnError)
155  throw InvalidArgument("StringNarrow: wcstombs_s() call failed with error " + IntToString(err));
156  else
157  return std::string();
158  }
159 
160  result.resize(size);
161  err = wcstombs_s(&size, &result[0], size, str, len*sizeof(wchar_t));
162  CRYPTOPP_ASSERT(err == 0);
163  if (err != 0)
164  {
165  if (throwOnError)
166  throw InvalidArgument("StringNarrow: wcstombs_s() call failed with error " + IntToString(err));
167  else
168  return std::string();
169  }
170 
171  // The safe routine's size includes the NULL.
172  if (!result.empty() && result[size - 1] == '\0')
173  result.erase(size - 1);
174 #else
175  size_t size = wcstombs(NULLPTR, str, 0);
176  CRYPTOPP_ASSERT(size != (size_t)-1);
177  if (size == (size_t)-1)
178  {
179  if (throwOnError)
180  throw InvalidArgument("StringNarrow: wcstombs() call failed");
181  else
182  return std::string();
183  }
184 
185  result.resize(size);
186  size = wcstombs(&result[0], str, size);
187  CRYPTOPP_ASSERT(size != (size_t)-1);
188  if (size == (size_t)-1)
189  {
190  if (throwOnError)
191  throw InvalidArgument("StringNarrow: wcstombs() call failed");
192  else
193  return std::string();
194  }
195 #endif
196 
197  return result;
198 }
199 
200 std::wstring StringWiden(const char *str, bool throwOnError)
201 {
202  CRYPTOPP_ASSERT(str);
203  std::wstring result;
204 
205  // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
206 #if (CRYPTOPP_MSC_VERSION >= 1400)
207  size_t len=0, size=0;
208  errno_t err = 0;
209 
210  //const char* ptr = str;
211  //while (*ptr++) len++;
212  len = std::strlen(str)+1;
213 
214  err = mbstowcs_s(&size, NULLPTR, 0, str, len);
215  CRYPTOPP_ASSERT(err == 0);
216  if (err != 0)
217  {
218  if (throwOnError)
219  throw InvalidArgument("StringWiden: wcstombs_s() call failed with error " + IntToString(err));
220  else
221  return std::wstring();
222  }
223 
224  result.resize(size);
225  err = mbstowcs_s(&size, &result[0], size, str, len);
226  CRYPTOPP_ASSERT(err == 0);
227  if (err != 0)
228  {
229  if (throwOnError)
230  throw InvalidArgument("StringWiden: wcstombs_s() call failed with error " + IntToString(err));
231  else
232  return std::wstring();
233  }
234 
235  // The safe routine's size includes the NULL.
236  if (!result.empty() && result[size - 1] == '\0')
237  result.erase(size - 1);
238 #else
239  size_t size = mbstowcs(NULLPTR, str, 0);
240  CRYPTOPP_ASSERT(size != (size_t)-1);
241  if (size == (size_t)-1)
242  {
243  if (throwOnError)
244  throw InvalidArgument("StringWiden: mbstowcs() call failed");
245  else
246  return std::wstring();
247  }
248 
249  result.resize(size);
250  size = mbstowcs(&result[0], str, size);
251  CRYPTOPP_ASSERT(size != (size_t)-1);
252  if (size == (size_t)-1)
253  {
254  if (throwOnError)
255  throw InvalidArgument("StringWiden: mbstowcs() call failed");
256  else
257  return std::wstring();
258  }
259 #endif
260 
261  return result;
262 }
263 
265 {
266  using std::new_handler;
267  using std::set_new_handler;
268 
269  new_handler newHandler = set_new_handler(NULLPTR);
270  if (newHandler)
271  set_new_handler(newHandler);
272 
273  if (newHandler)
274  newHandler();
275  else
276  throw std::bad_alloc();
277 }
278 
279 #if CRYPTOPP_ALIGN16
280 
281 void * AlignedAllocate(size_t size)
282 {
283  byte *p;
284 #if defined(CRYPTOPP_APPLE_ALLOC_AVAILABLE)
285  while ((p = (byte *)calloc(1, size)) == NULLPTR)
286 #elif defined(CRYPTOPP_MM_MALLOC_AVAILABLE)
287  while ((p = (byte *)_mm_malloc(size, 16)) == NULLPTR)
288 #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
289  while ((p = (byte *)memalign(16, size)) == NULLPTR)
290 #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16)
291  while ((p = (byte *)malloc(size)) == NULLPTR)
292 #else
293  while ((p = (byte *)malloc(size + 16)) == NULLPTR)
294 #endif
295  CallNewHandler();
296 
297 #ifdef CRYPTOPP_NO_ALIGNED_ALLOC
298  size_t adjustment = 16-((size_t)p%16);
299  p += adjustment;
300  p[-1] = (byte)adjustment;
301 #endif
302 
304  return p;
305 }
306 
307 void AlignedDeallocate(void *p)
308 {
309 #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
310  _mm_free(p);
311 #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)
312  p = (byte *)p - ((byte *)p)[-1];
313  free(p);
314 #else
315  free(p);
316 #endif
317 }
318 
319 #endif
320 
321 void * UnalignedAllocate(size_t size)
322 {
323  void *p;
324  while ((p = malloc(size)) == NULLPTR)
325  CallNewHandler();
326  return p;
327 }
328 
329 void UnalignedDeallocate(void *p)
330 {
331  free(p);
332 }
333 
334 NAMESPACE_END
335 
336 #endif
An invalid argument was detected.
Definition: cryptlib.h:194
std::string StringNarrow(const wchar_t *str, bool throwOnError=true)
Converts a wide character C-string to a multibyte string.
Definition: misc.cpp:136
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:1036
void * UnalignedAllocate(size_t size)
Allocates a buffer.
Definition: misc.cpp:321
void CallNewHandler()
Attempts to reclaim unused memory.
Definition: misc.cpp:264
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:61
std::wstring StringWiden(const char *str, bool throwOnError=true)
Converts a multibyte C-string to a wide character string.
Definition: misc.cpp:200
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:582
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
Multiple precision integer with arithmetic operations.
Crypto++ library namespace.
void UnalignedDeallocate(void *ptr)
Frees a buffer allocated with UnalignedAllocate.
Definition: misc.cpp:329
void * AlignedAllocate(size_t size)
Allocates a buffer on 16-byte boundary.