Crypto++  5.6.5
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  CRYPTOPP_ASSERT(buf != NULL);
31  CRYPTOPP_ASSERT(mask != NULL);
32  CRYPTOPP_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  CRYPTOPP_ASSERT(output != NULL);
64  CRYPTOPP_ASSERT(input != NULL);
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_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  CRYPTOPP_ASSERT(buf != NULL);
99  CRYPTOPP_ASSERT(mask != NULL);
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_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 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, NULL, 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(NULL, 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 
201 {
202  using std::new_handler;
203  using std::set_new_handler;
204 
205  new_handler newHandler = set_new_handler(NULL);
206  if (newHandler)
207  set_new_handler(newHandler);
208 
209  if (newHandler)
210  newHandler();
211  else
212  throw std::bad_alloc();
213 }
214 
215 #if CRYPTOPP_BOOL_ALIGN16
216 
217 void * AlignedAllocate(size_t size)
218 {
219  byte *p;
220 #if defined(CRYPTOPP_APPLE_ALLOC_AVAILABLE)
221  while ((p = (byte *)calloc(1, size)) == NULL)
222 #elif defined(CRYPTOPP_MM_MALLOC_AVAILABLE)
223  while ((p = (byte *)_mm_malloc(size, 16)) == NULL)
224 #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
225  while ((p = (byte *)memalign(16, size)) == NULL)
226 #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16)
227  while ((p = (byte *)malloc(size)) == NULL)
228 #else
229  while ((p = (byte *)malloc(size + 16)) == NULL)
230 #endif
231  CallNewHandler();
232 
233 #ifdef CRYPTOPP_NO_ALIGNED_ALLOC
234  size_t adjustment = 16-((size_t)p%16);
235  p += adjustment;
236  p[-1] = (byte)adjustment;
237 #endif
238 
240  return p;
241 }
242 
243 void AlignedDeallocate(void *p)
244 {
245 #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
246  _mm_free(p);
247 #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)
248  p = (byte *)p - ((byte *)p)[-1];
249  free(p);
250 #else
251  free(p);
252 #endif
253 }
254 
255 #endif
256 
257 void * UnalignedAllocate(size_t size)
258 {
259  void *p;
260  while ((p = malloc(size)) == NULL)
261  CallNewHandler();
262  return p;
263 }
264 
265 void UnalignedDeallocate(void *p)
266 {
267  free(p);
268 }
269 
270 NAMESPACE_END
271 
272 #endif
An invalid argument was detected.
Definition: cryptlib.h:184
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:954
void * UnalignedAllocate(size_t size)
Allocates a buffer.
Definition: misc.cpp:257
void CallNewHandler()
Attempts to reclaim unused memory.
Definition: misc.cpp:200
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:62
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:539
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:265
void * AlignedAllocate(size_t size)
Allocates a buffer on 16-byte boundary.