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 6237)
8 #endif
9 
10 #ifndef CRYPTOPP_IMPORTS
11 
12 #include "misc.h"
13 #include "words.h"
14 #include "words.h"
15 #include "stdcpp.h"
16 #include "integer.h"
17 
18 // for memalign
19 #if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX)
20 # include <malloc.h>
21 #endif
22 
23 NAMESPACE_BEGIN(CryptoPP)
24 
25 void xorbuf(byte *buf, const byte *mask, size_t count)
26 {
27  assert(buf != NULL);
28  assert(mask != NULL);
29  assert(count > 0);
30 
31  size_t i=0;
32  if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
33  {
34  if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
35  {
36  for (i=0; i<count/8; i++)
37  ((word64*)buf)[i] ^= ((word64*)mask)[i];
38  count -= 8*i;
39  if (!count)
40  return;
41  buf += 8*i;
42  mask += 8*i;
43  }
44 
45  for (i=0; i<count/4; i++)
46  ((word32*)buf)[i] ^= ((word32*)mask)[i];
47  count -= 4*i;
48  if (!count)
49  return;
50  buf += 4*i;
51  mask += 4*i;
52  }
53 
54  for (i=0; i<count; i++)
55  buf[i] ^= mask[i];
56 }
57 
58 void xorbuf(byte *output, const byte *input, const byte *mask, size_t count)
59 {
60  assert(output != NULL);
61  assert(input != NULL);
62  assert(count > 0);
63 
64  size_t i=0;
65  if (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask))
66  {
67  if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(output) && IsAligned<word64>(input) && IsAligned<word64>(mask))
68  {
69  for (i=0; i<count/8; i++)
70  ((word64*)output)[i] = ((word64*)input)[i] ^ ((word64*)mask)[i];
71  count -= 8*i;
72  if (!count)
73  return;
74  output += 8*i;
75  input += 8*i;
76  mask += 8*i;
77  }
78 
79  for (i=0; i<count/4; i++)
80  ((word32*)output)[i] = ((word32*)input)[i] ^ ((word32*)mask)[i];
81  count -= 4*i;
82  if (!count)
83  return;
84  output += 4*i;
85  input += 4*i;
86  mask += 4*i;
87  }
88 
89  for (i=0; i<count; i++)
90  output[i] = input[i] ^ mask[i];
91 }
92 
93 bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
94 {
95  assert(buf != NULL);
96  assert(mask != NULL);
97  assert(count > 0);
98 
99  size_t i=0;
100  byte acc8 = 0;
101 
102  if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
103  {
104  word32 acc32 = 0;
105  if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
106  {
107  word64 acc64 = 0;
108  for (i=0; i<count/8; i++)
109  acc64 |= ((word64*)buf)[i] ^ ((word64*)mask)[i];
110  count -= 8*i;
111  if (!count)
112  return acc64 == 0;
113  buf += 8*i;
114  mask += 8*i;
115  acc32 = word32(acc64) | word32(acc64>>32);
116  }
117 
118  for (i=0; i<count/4; i++)
119  acc32 |= ((word32*)buf)[i] ^ ((word32*)mask)[i];
120  count -= 4*i;
121  if (!count)
122  return acc32 == 0;
123  buf += 4*i;
124  mask += 4*i;
125  acc8 = byte(acc32) | byte(acc32>>8) | byte(acc32>>16) | byte(acc32>>24);
126  }
127 
128  for (i=0; i<count; i++)
129  acc8 |= buf[i] ^ mask[i];
130  return acc8 == 0;
131 }
132 
133 #if !(defined(_MSC_VER) && (_MSC_VER < 1300))
134 using std::new_handler;
135 using std::set_new_handler;
136 #endif
137 
139 {
140  new_handler newHandler = set_new_handler(NULL);
141  if (newHandler)
142  set_new_handler(newHandler);
143 
144  if (newHandler)
145  newHandler();
146  else
147  throw std::bad_alloc();
148 }
149 
150 #if CRYPTOPP_BOOL_ALIGN16
151 
152 void * AlignedAllocate(size_t size)
153 {
154  byte *p;
155 #if defined(CRYPTOPP_APPLE_ALLOC_AVAILABLE)
156  while ((p = (byte *)calloc(1, size)) == NULL)
157 #elif defined(CRYPTOPP_MM_MALLOC_AVAILABLE)
158  while ((p = (byte *)_mm_malloc(size, 16)) == NULL)
159 #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
160  while ((p = (byte *)memalign(16, size)) == NULL)
161 #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16)
162  while ((p = (byte *)malloc(size)) == NULL)
163 #else
164  while ((p = (byte *)malloc(size + 16)) == NULL)
165 #endif
166  CallNewHandler();
167 
168 #ifdef CRYPTOPP_NO_ALIGNED_ALLOC
169  size_t adjustment = 16-((size_t)p%16);
170  p += adjustment;
171  p[-1] = (byte)adjustment;
172 #endif
173 
174  assert(IsAlignedOn(p, 16));
175  return p;
176 }
177 
178 void AlignedDeallocate(void *p)
179 {
180 #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
181  _mm_free(p);
182 #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)
183  p = (byte *)p - ((byte *)p)[-1];
184  free(p);
185 #else
186  free(p);
187 #endif
188 }
189 
190 #endif
191 
192 void * UnalignedAllocate(size_t size)
193 {
194  void *p;
195  while ((p = malloc(size)) == NULL)
196  CallNewHandler();
197  return p;
198 }
199 
200 void UnalignedDeallocate(void *p)
201 {
202  free(p);
203 }
204 
205 NAMESPACE_END
206 
207 #endif
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:801
void * UnalignedAllocate(size_t size)
Allocates a buffer.
Definition: misc.cpp:192
void CallNewHandler()
Attempts to reclaim unused memory.
Definition: misc.cpp:138
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:25
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:93
Crypto++ library namespace.
void UnalignedDeallocate(void *ptr)
Frees a buffer allocated with UnalignedAllocate.
Definition: misc.cpp:200
void * AlignedAllocate(size_t size)
Allocates a buffer on 16-byte boundary.