Crypto++ 8.2
Free C&
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// for posix_memalign
26#if defined(CRYPTOPP_POSIX_MEMALIGN_AVAILABLE)
27# include <stdlib.h>
28#endif
29
30NAMESPACE_BEGIN(CryptoPP)
31
32void xorbuf(byte *buf, const byte *mask, size_t count)
33{
34 CRYPTOPP_ASSERT(buf != NULLPTR);
35 CRYPTOPP_ASSERT(mask != NULLPTR);
36 CRYPTOPP_ASSERT(count > 0);
37
38 size_t i=0;
39 if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
40 {
41 if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
42 {
43 for (i=0; i<count/8; i++)
44 ((word64*)(void*)buf)[i] ^= ((word64*)(void*)mask)[i];
45 count -= 8*i;
46 if (!count)
47 return;
48 buf += 8*i;
49 mask += 8*i;
50 }
51
52 for (i=0; i<count/4; i++)
53 ((word32*)(void*)buf)[i] ^= ((word32*)(void*)mask)[i];
54 count -= 4*i;
55 if (!count)
56 return;
57 buf += 4*i;
58 mask += 4*i;
59 }
60
61 for (i=0; i<count; i++)
62 buf[i] ^= mask[i];
63}
64
65void xorbuf(byte *output, const byte *input, const byte *mask, size_t count)
66{
67 CRYPTOPP_ASSERT(output != NULLPTR);
68 CRYPTOPP_ASSERT(input != NULLPTR);
69 CRYPTOPP_ASSERT(count > 0);
70
71 size_t i=0;
72 if (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask))
73 {
74 if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(output) && IsAligned<word64>(input) && IsAligned<word64>(mask))
75 {
76 for (i=0; i<count/8; i++)
77 ((word64*)(void*)output)[i] = ((word64*)(void*)input)[i] ^ ((word64*)(void*)mask)[i];
78 count -= 8*i;
79 if (!count)
80 return;
81 output += 8*i;
82 input += 8*i;
83 mask += 8*i;
84 }
85
86 for (i=0; i<count/4; i++)
87 ((word32*)(void*)output)[i] = ((word32*)(void*)input)[i] ^ ((word32*)(void*)mask)[i];
88 count -= 4*i;
89 if (!count)
90 return;
91 output += 4*i;
92 input += 4*i;
93 mask += 4*i;
94 }
95
96 for (i=0; i<count; i++)
97 output[i] = input[i] ^ mask[i];
98}
99
100bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
101{
102 CRYPTOPP_ASSERT(buf != NULLPTR);
103 CRYPTOPP_ASSERT(mask != NULLPTR);
104 CRYPTOPP_ASSERT(count > 0);
105
106 size_t i=0;
107 byte acc8 = 0;
108
109 if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
110 {
111 word32 acc32 = 0;
112 if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
113 {
114 word64 acc64 = 0;
115 for (i=0; i<count/8; i++)
116 acc64 |= ((word64*)(void*)buf)[i] ^ ((word64*)(void*)mask)[i];
117 count -= 8*i;
118 if (!count)
119 return acc64 == 0;
120 buf += 8*i;
121 mask += 8*i;
122 acc32 = word32(acc64) | word32(acc64>>32);
123 }
124
125 for (i=0; i<count/4; i++)
126 acc32 |= ((word32*)(void*)buf)[i] ^ ((word32*)(void*)mask)[i];
127 count -= 4*i;
128 if (!count)
129 return acc32 == 0;
130 buf += 4*i;
131 mask += 4*i;
132 acc8 = byte(acc32) | byte(acc32>>8) | byte(acc32>>16) | byte(acc32>>24);
133 }
134
135 for (i=0; i<count; i++)
136 acc8 |= buf[i] ^ mask[i];
137 return acc8 == 0;
138}
139
140std::string StringNarrow(const wchar_t *str, bool throwOnError)
141{
142 CRYPTOPP_ASSERT(str);
143 std::string result;
144
145 // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
146#if (CRYPTOPP_MSC_VERSION >= 1400)
147 size_t len=0, size=0;
148 errno_t err = 0;
149
150 //const wchar_t* ptr = str;
151 //while (*ptr++) len++;
152 len = wcslen(str)+1;
153
154 err = wcstombs_s(&size, NULLPTR, 0, str, len*sizeof(wchar_t));
155 CRYPTOPP_ASSERT(err == 0);
156 if (err != 0)
157 {
158 if (throwOnError)
159 throw InvalidArgument("StringNarrow: wcstombs_s() call failed with error " + IntToString(err));
160 else
161 return std::string();
162 }
163
164 result.resize(size);
165 err = wcstombs_s(&size, &result[0], size, str, len*sizeof(wchar_t));
166 CRYPTOPP_ASSERT(err == 0);
167 if (err != 0)
168 {
169 if (throwOnError)
170 throw InvalidArgument("StringNarrow: wcstombs_s() call failed with error " + IntToString(err));
171 else
172 return std::string();
173 }
174
175 // The safe routine's size includes the NULL.
176 if (!result.empty() && result[size - 1] == '\0')
177 result.erase(size - 1);
178#else
179 size_t size = wcstombs(NULLPTR, str, 0);
180 CRYPTOPP_ASSERT(size != (size_t)-1);
181 if (size == (size_t)-1)
182 {
183 if (throwOnError)
184 throw InvalidArgument("StringNarrow: wcstombs() call failed");
185 else
186 return std::string();
187 }
188
189 result.resize(size);
190 size = wcstombs(&result[0], str, size);
191 CRYPTOPP_ASSERT(size != (size_t)-1);
192 if (size == (size_t)-1)
193 {
194 if (throwOnError)
195 throw InvalidArgument("StringNarrow: wcstombs() call failed");
196 else
197 return std::string();
198 }
199#endif
200
201 return result;
202}
203
204std::wstring StringWiden(const char *str, bool throwOnError)
205{
206 CRYPTOPP_ASSERT(str);
207 std::wstring result;
208
209 // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
210#if (CRYPTOPP_MSC_VERSION >= 1400)
211 size_t len=0, size=0;
212 errno_t err = 0;
213
214 //const char* ptr = str;
215 //while (*ptr++) len++;
216 len = std::strlen(str)+1;
217
218 err = mbstowcs_s(&size, NULLPTR, 0, str, len);
219 CRYPTOPP_ASSERT(err == 0);
220 if (err != 0)
221 {
222 if (throwOnError)
223 throw InvalidArgument("StringWiden: wcstombs_s() call failed with error " + IntToString(err));
224 else
225 return std::wstring();
226 }
227
228 result.resize(size);
229 err = mbstowcs_s(&size, &result[0], size, str, len);
230 CRYPTOPP_ASSERT(err == 0);
231 if (err != 0)
232 {
233 if (throwOnError)
234 throw InvalidArgument("StringWiden: wcstombs_s() call failed with error " + IntToString(err));
235 else
236 return std::wstring();
237 }
238
239 // The safe routine's size includes the NULL.
240 if (!result.empty() && result[size - 1] == '\0')
241 result.erase(size - 1);
242#else
243 size_t size = mbstowcs(NULLPTR, str, 0);
244 CRYPTOPP_ASSERT(size != (size_t)-1);
245 if (size == (size_t)-1)
246 {
247 if (throwOnError)
248 throw InvalidArgument("StringWiden: mbstowcs() call failed");
249 else
250 return std::wstring();
251 }
252
253 result.resize(size);
254 size = mbstowcs(&result[0], str, size);
255 CRYPTOPP_ASSERT(size != (size_t)-1);
256 if (size == (size_t)-1)
257 {
258 if (throwOnError)
259 throw InvalidArgument("StringWiden: mbstowcs() call failed");
260 else
261 return std::wstring();
262 }
263#endif
264
265 return result;
266}
267
268void CallNewHandler()
269{
270 using std::new_handler;
271 using std::set_new_handler;
272
273 new_handler newHandler = set_new_handler(NULLPTR);
274 if (newHandler)
275 set_new_handler(newHandler);
276
277 if (newHandler)
278 newHandler();
279 else
280 throw std::bad_alloc();
281}
282
283void * AlignedAllocate(size_t size)
284{
285 byte *p;
286#if 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#elif defined(CRYPTOPP_POSIX_MEMALIGN_AVAILABLE)
293 while (posix_memalign(reinterpret_cast<void**>(&p), 16, size) != 0)
294#else
295 while ((p = (byte *)malloc(size + 16)) == NULLPTR)
296#endif
297 CallNewHandler();
298
299#ifdef CRYPTOPP_NO_ALIGNED_ALLOC
300 size_t adjustment = 16-((size_t)p%16);
301 CRYPTOPP_ASSERT(adjustment > 0);
302 p += adjustment;
303 p[-1] = (byte)adjustment;
304#endif
305
306 // If this assert fires then there are problems that need
307 // to be fixed. Please open a bug report.
309 return p;
310}
311
312void AlignedDeallocate(void *p)
313{
314#ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
315 _mm_free(p);
316#elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)
317 p = (byte *)p - ((byte *)p)[-1];
318 free(p);
319#else
320 free(p);
321#endif
322}
323
324void * UnalignedAllocate(size_t size)
325{
326 void *p;
327 while ((p = malloc(size)) == NULLPTR)
328 CallNewHandler();
329 return p;
330}
331
332void UnalignedDeallocate(void *p)
333{
334 free(p);
335}
336
337NAMESPACE_END
338
339#endif
An invalid argument was detected.
Definition: cryptlib.h:203
Library configuration file.
Multiple precision integer with arithmetic operations.
Utility functions for the Crypto++ library.
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:636
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:1143
Crypto++ library namespace.
Precompiled header file.
Common C++ header files.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69