Crypto++
|
00001 // misc.cpp - written and placed in the public domain by Wei Dai 00002 00003 #include "pch.h" 00004 00005 #ifndef CRYPTOPP_IMPORTS 00006 00007 #include "misc.h" 00008 #include "words.h" 00009 #include <new> 00010 00011 #if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX) 00012 #include <malloc.h> 00013 #endif 00014 00015 NAMESPACE_BEGIN(CryptoPP) 00016 00017 void xorbuf(byte *buf, const byte *mask, size_t count) 00018 { 00019 size_t i; 00020 00021 if (IsAligned<word32>(buf) && IsAligned<word32>(mask)) 00022 { 00023 if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask)) 00024 { 00025 for (i=0; i<count/8; i++) 00026 ((word64*)buf)[i] ^= ((word64*)mask)[i]; 00027 count -= 8*i; 00028 if (!count) 00029 return; 00030 buf += 8*i; 00031 mask += 8*i; 00032 } 00033 00034 for (i=0; i<count/4; i++) 00035 ((word32*)buf)[i] ^= ((word32*)mask)[i]; 00036 count -= 4*i; 00037 if (!count) 00038 return; 00039 buf += 4*i; 00040 mask += 4*i; 00041 } 00042 00043 for (i=0; i<count; i++) 00044 buf[i] ^= mask[i]; 00045 } 00046 00047 void xorbuf(byte *output, const byte *input, const byte *mask, size_t count) 00048 { 00049 size_t i; 00050 00051 if (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask)) 00052 { 00053 if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(output) && IsAligned<word64>(input) && IsAligned<word64>(mask)) 00054 { 00055 for (i=0; i<count/8; i++) 00056 ((word64*)output)[i] = ((word64*)input)[i] ^ ((word64*)mask)[i]; 00057 count -= 8*i; 00058 if (!count) 00059 return; 00060 output += 8*i; 00061 input += 8*i; 00062 mask += 8*i; 00063 } 00064 00065 for (i=0; i<count/4; i++) 00066 ((word32*)output)[i] = ((word32*)input)[i] ^ ((word32*)mask)[i]; 00067 count -= 4*i; 00068 if (!count) 00069 return; 00070 output += 4*i; 00071 input += 4*i; 00072 mask += 4*i; 00073 } 00074 00075 for (i=0; i<count; i++) 00076 output[i] = input[i] ^ mask[i]; 00077 } 00078 00079 bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count) 00080 { 00081 size_t i; 00082 byte acc8 = 0; 00083 00084 if (IsAligned<word32>(buf) && IsAligned<word32>(mask)) 00085 { 00086 word32 acc32 = 0; 00087 if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask)) 00088 { 00089 word64 acc64 = 0; 00090 for (i=0; i<count/8; i++) 00091 acc64 |= ((word64*)buf)[i] ^ ((word64*)mask)[i]; 00092 count -= 8*i; 00093 if (!count) 00094 return acc64 == 0; 00095 buf += 8*i; 00096 mask += 8*i; 00097 acc32 = word32(acc64) | word32(acc64>>32); 00098 } 00099 00100 for (i=0; i<count/4; i++) 00101 acc32 |= ((word32*)buf)[i] ^ ((word32*)mask)[i]; 00102 count -= 4*i; 00103 if (!count) 00104 return acc32 == 0; 00105 buf += 4*i; 00106 mask += 4*i; 00107 acc8 = byte(acc32) | byte(acc32>>8) | byte(acc32>>16) | byte(acc32>>24); 00108 } 00109 00110 for (i=0; i<count; i++) 00111 acc8 |= buf[i] ^ mask[i]; 00112 return acc8 == 0; 00113 } 00114 00115 #if !(defined(_MSC_VER) && (_MSC_VER < 1300)) 00116 using std::new_handler; 00117 using std::set_new_handler; 00118 #endif 00119 00120 void CallNewHandler() 00121 { 00122 new_handler newHandler = set_new_handler(NULL); 00123 if (newHandler) 00124 set_new_handler(newHandler); 00125 00126 if (newHandler) 00127 newHandler(); 00128 else 00129 throw std::bad_alloc(); 00130 } 00131 00132 #if CRYPTOPP_BOOL_ALIGN16_ENABLED 00133 00134 void * AlignedAllocate(size_t size) 00135 { 00136 byte *p; 00137 #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE 00138 while (!(p = (byte *)_mm_malloc(size, 16))) 00139 #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE) 00140 while (!(p = (byte *)memalign(16, size))) 00141 #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) 00142 while (!(p = (byte *)malloc(size))) 00143 #else 00144 while (!(p = (byte *)malloc(size + 16))) 00145 #endif 00146 CallNewHandler(); 00147 00148 #ifdef CRYPTOPP_NO_ALIGNED_ALLOC 00149 size_t adjustment = 16-((size_t)p%16); 00150 p += adjustment; 00151 p[-1] = (byte)adjustment; 00152 #endif 00153 00154 assert(IsAlignedOn(p, 16)); 00155 return p; 00156 } 00157 00158 void AlignedDeallocate(void *p) 00159 { 00160 #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE 00161 _mm_free(p); 00162 #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC) 00163 p = (byte *)p - ((byte *)p)[-1]; 00164 free(p); 00165 #else 00166 free(p); 00167 #endif 00168 } 00169 00170 #endif 00171 00172 void * UnalignedAllocate(size_t size) 00173 { 00174 void *p; 00175 while (!(p = malloc(size))) 00176 CallNewHandler(); 00177 return p; 00178 } 00179 00180 void UnalignedDeallocate(void *p) 00181 { 00182 free(p); 00183 } 00184 00185 NAMESPACE_END 00186 00187 #endif