21 #ifndef TAO_CRYPT_MISC_HPP
22 #define TAO_CRYPT_MISC_HPP
25 #if !defined(DO_TAOCRYPT_KERNEL_MODE)
29 #include "kernelc.hpp"
33 #include "type_traits.hpp"
52 void*
operator new (size_t, TaoCrypt::new_t);
53 void*
operator new[](size_t, TaoCrypt::new_t);
55 void operator delete (
void*, TaoCrypt::new_t);
56 void operator delete[](
void*, TaoCrypt::new_t);
65 ::operator
delete(ptr, TaoCrypt::tc);
69 void tcArrayDelete(T* ptr)
74 typedef char builtin[IsFundamentalType<T>::Yes ? 1 : -1];
75 (void)
sizeof(builtin);
77 ::operator
delete[](ptr, TaoCrypt::tc);
80 #define NEW_TC new (TaoCrypt::tc)
87 static void operator delete(
void*) { }
100 void tcArrayDelete(T* ptr)
110 #endif // YASSL_PURE_C
113 #if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
114 #define INTEL_INTRINSICS
116 #elif defined(__MWERKS__) && TARGET_CPU_PPC
117 #define PPC_INTRINSICS
119 #elif defined(__GNUC__) && defined(__i386__)
127 #if defined(__sun__) || defined (__APPLE__)
128 #define TAOCRYPT_DISABLE_X86ASM
132 #if defined(__INTEL_COMPILER)
133 #define TAOCRYPT_DISABLE_X86ASM
139 #if !defined(TAOCRYPT_DISABLE_X86ASM) && ((defined(_MSC_VER) && \
140 !defined(__MWERKS__) && defined(_M_IX86)) || \
141 (defined(__GNUC__) && defined(__i386__)))
142 #define TAOCRYPT_X86ASM_AVAILABLE
146 #ifdef TAOCRYPT_X86ASM_AVAILABLE
149 void CpuId(word32 input, word32 *output);
160 #if defined(TAOCRYPT_X86ASM_AVAILABLE) && !defined(DISABLE_TAO_ASM)
166 #if defined(__GNUC__) && __GNUC__ < 3
167 #define OLD_GCC_OFFSET
171 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
172 # define TAOCRYPT_MALLOC_ALIGNMENT_IS_16
175 #if defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
176 # define TAOCRYPT_MEMALIGN_AVAILABLE
180 #if defined(_WIN32) || defined(__CYGWIN__)
181 #define TAOCRYPT_WIN32_AVAILABLE
184 #if defined(__unix__) || defined(__MACH__)
185 #define TAOCRYPT_UNIX_AVAILABLE
190 #if defined(_MSC_VER) && (_MSC_VER < 1300)
193 #define CPP_TYPENAME typename
198 #define TAOCRYPT_NO_VTABLE __declspec(novtable)
200 #define TAOCRYPT_NO_VTABLE
206 #define STL_NAMESPACE std
209 #define STL_NAMESPACE mySTL
215 #ifdef TAOCRYPT_WIN32_AVAILABLE
217 #ifdef TAOCRYPT_EXPORTS
218 #define TAOCRYPT_IS_DLL
219 #define TAOCRYPT_DLL __declspec(dllexport)
220 #elif defined(TAOCRYPT_IMPORTS)
221 #define TAOCRYPT_IS_DLL
222 #define TAOCRYPT_DLL __declspec(dllimport)
227 #define TAOCRYPT_API __stdcall
228 #define TAOCRYPT_CDECL __cdecl
230 #else // TAOCRYPT_WIN32_AVAILABLE
234 #define TAOCRYPT_CDECL
236 #endif // TAOCRYPT_WIN32_AVAILABLE
242 #if defined(TAOCRYPT_MANUALLY_INSTANTIATE_TEMPLATES) && \
243 !defined(TAOCRYPT_IMPORTS)
244 #define TAOCRYPT_DLL_TEMPLATE_CLASS template class TAOCRYPT_DLL
245 #elif defined(__MWERKS__)
246 #define TAOCRYPT_DLL_TEMPLATE_CLASS extern class TAOCRYPT_DLL
248 #define TAOCRYPT_DLL_TEMPLATE_CLASS extern template class TAOCRYPT_DLL
252 #if defined(TAOCRYPT_MANUALLY_INSTANTIATE_TEMPLATES) && \
253 !defined(TAOCRYPT_EXPORTS)
254 #define TAOCRYPT_STATIC_TEMPLATE_CLASS template class
255 #elif defined(__MWERKS__)
256 #define TAOCRYPT_STATIC_TEMPLATE_CLASS extern class
258 #define TAOCRYPT_STATIC_TEMPLATE_CLASS extern template class
267 static char dummy[2*b-1];
270 #define TAOCRYPT_COMPILE_ASSERT(assertion) \
271 TAOCRYPT_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
273 #if defined(TAOCRYPT_EXPORTS) || defined(TAOCRYPT_IMPORTS)
274 #define TAOCRYPT_COMPILE_ASSERT_INSTANCE(assertion, instance)
276 #define TAOCRYPT_COMPILE_ASSERT_INSTANCE(assertion, instance) \
277 (void)sizeof(CompileAssert<(assertion)>)
280 #define TAOCRYPT_ASSERT_JOIN(X, Y) TAOCRYPT_DO_ASSERT_JOIN(X, Y)
282 #define TAOCRYPT_DO_ASSERT_JOIN(X, Y) X##Y
287 inline unsigned int BitsToBytes(
unsigned int bitCount)
289 return ((bitCount+7)/(8));
292 inline unsigned int BytesToWords(
unsigned int byteCount)
294 return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
297 inline unsigned int BitsToWords(
unsigned int bitCount)
299 return ((bitCount+WORD_BITS-1)/(WORD_BITS));
302 inline void CopyWords(
word* r,
const word* a, word32
n)
304 for (word32
i = 0;
i <
n;
i++)
308 inline unsigned int CountWords(
const word* X,
unsigned int N)
310 while (N && X[N-1]==0)
315 inline void SetWords(
word* r,
word a,
unsigned int n)
317 for (
unsigned int i=0;
i<
n;
i++)
321 enum ByteOrder { LittleEndianOrder = 0, BigEndianOrder = 1 };
322 enum CipherDir {ENCRYPTION, DECRYPTION};
324 inline CipherDir ReverseDir(CipherDir dir)
326 return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION;
329 template <
typename ENUM_TYPE,
int VALUE>
332 static ENUM_TYPE ToEnum() {
return (ENUM_TYPE)VALUE; }
339 #ifndef BIG_ENDIAN_ORDER
345 inline ByteOrder GetHostByteOrder()
347 return HostByteOrder::ToEnum();
350 inline bool HostByteOrderIs(ByteOrder order)
352 return order == GetHostByteOrder();
356 void xorbuf(byte*,
const byte*,
unsigned int);
360 inline bool IsPowerOf2(T n)
362 return n > 0 && (n & (n-1)) == 0;
365 template <
class T1,
class T2>
366 inline T2 ModPowerOf2(
T1 a,
T2 b)
368 return T2(a) & (b-1);
372 inline T RoundDownToMultipleOf(T n, T m)
374 return n - (IsPowerOf2(m) ? ModPowerOf2(n, m) : (n%m));
378 inline T RoundUpToMultipleOf(T n, T m)
380 return RoundDownToMultipleOf(n+m-1, m);
384 inline unsigned int GetAlignment(T* dummy = 0)
386 #if (_MSC_VER >= 1300)
388 #elif defined(__GNUC__)
389 return __alignof__(T);
395 inline bool IsAlignedOn(
const void* p,
unsigned int alignment)
397 return IsPowerOf2(alignment) ? ModPowerOf2((
size_t)p, alignment) == 0
398 : (size_t)p % alignment == 0;
402 inline bool IsAligned(
const void* p, T* dummy = 0)
404 return IsAlignedOn(p, GetAlignment<T>());
408 template <
class T>
inline T rotlFixed(T x,
unsigned int y)
410 return (x<<y) | (x>>(
sizeof(T)*8-y));
413 template <
class T>
inline T rotrFixed(T x,
unsigned int y)
415 return (x>>y) | (x<<(
sizeof(T)*8-y));
418 #ifdef INTEL_INTRINSICS
420 #pragma intrinsic(_lrotl, _lrotr)
422 template<>
inline word32 rotlFixed(word32 x, word32 y)
424 return y ? _lrotl(x, y) : x;
427 template<>
inline word32 rotrFixed(word32 x, word32 y)
429 return y ? _lrotr(x, y) : x;
432 #endif // INTEL_INTRINSICS
440 inline const T& min(
const T& a,
const T& b)
442 return a < b ? a : b;
446 inline word32 ByteReverse(word32 value)
448 #ifdef PPC_INTRINSICS
450 return (word32)__lwbrx(&value,0);
451 #elif defined(FAST_ROTATE)
453 return (rotrFixed(value, 8
U) & 0xff00ff00) |
454 (rotlFixed(value, 8
U) & 0x00ff00ff);
457 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
458 return rotlFixed(value, 16
U);
463 #ifdef WORD64_AVAILABLE
465 inline word64 ByteReverse(word64 value)
467 #ifdef TAOCRYPT_SLOW_WORD64
468 return (word64(ByteReverse(word32(value))) << 32) |
469 ByteReverse(word32(value>>32));
471 value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
472 ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
473 value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |
474 ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
475 return rotlFixed(value, 32
U);
479 #endif // WORD64_AVAILABLE
482 template <
typename T>
483 inline void ByteReverse(T* out,
const T* in, word32 byteCount)
485 word32 count = byteCount/
sizeof(T);
486 for (word32
i=0;
i<count;
i++)
487 out[
i] = ByteReverse(in[
i]);
490 inline void ByteReverse(byte* out,
const byte* in, word32 byteCount)
492 word32* o =
reinterpret_cast<word32*
>(out);
493 const word32*
i =
reinterpret_cast<const word32*
>(in);
494 ByteReverse(o, i, byteCount);
499 inline T ByteReverseIf(T value, ByteOrder order)
501 return HostByteOrderIs(order) ? value : ByteReverse(value);
505 template <
typename T>
506 inline void ByteReverseIf(T* out,
const T* in, word32 bc, ByteOrder order)
508 if (!HostByteOrderIs(order))
509 ByteReverse(out, in, bc);
517 #ifdef LITTLE_ENDIAN_ORDER
518 #ifdef TAOCRYPT_X86ASM_AVAILABLE
519 #define LittleReverse AsmReverse
521 #define LittleReverse ByteReverse
524 #define LittleReverse
529 #ifdef BIG_ENDIAN_ORDER
530 #ifdef TAOCRYPT_X86ASM_AVAILABLE
531 #define BigReverse AsmReverse
533 #define BigReverse ByteReverse
540 #ifdef TAOCRYPT_X86ASM_AVAILABLE
544 inline word32 AsmReverse(word32 wd)
568 inline void GetUserKey(ByteOrder order, T* out, word32 outlen,
const byte* in,
571 const unsigned int U =
sizeof(T);
572 memcpy(out, in, inlen);
573 memset((byte *)out+inlen, 0, outlen*U-inlen);
574 ByteReverseIf(out, out, RoundUpToMultipleOf(inlen, U), order);
581 #pragma warning(disable:4244 4996)
585 inline byte UnalignedGetWordNonTemplate(ByteOrder order,
const byte *
block,
591 inline word16 UnalignedGetWordNonTemplate(ByteOrder order,
const byte*
block,
594 return (order == BigEndianOrder)
595 ? block[1] | (block[0] << 8)
596 : block[0] | (block[1] << 8);
599 inline word32 UnalignedGetWordNonTemplate(ByteOrder order,
const byte* block,
602 return (order == BigEndianOrder)
603 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16)
604 | (word32(block[0]) << 24)
605 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16)
606 | (word32(block[3]) << 24);
610 inline T UnalignedGetWord(ByteOrder order,
const byte *block, T* dummy = 0)
612 return UnalignedGetWordNonTemplate(order, block, dummy);
615 inline void UnalignedPutWord(ByteOrder order, byte *block, byte value,
616 const byte *xorBlock = 0)
618 block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
621 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
623 inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value,
624 const byte *xorBlock = 0)
626 if (order == BigEndianOrder)
628 block[0] = GETBYTE(value, 1);
629 block[1] = GETBYTE(value, 0);
633 block[0] = GETBYTE(value, 0);
634 block[1] = GETBYTE(value, 1);
639 block[0] ^= xorBlock[0];
640 block[1] ^= xorBlock[1];
644 inline void UnalignedPutWord(ByteOrder order, byte* block, word32 value,
645 const byte* xorBlock = 0)
647 if (order == BigEndianOrder)
649 block[0] = GETBYTE(value, 3);
650 block[1] = GETBYTE(value, 2);
651 block[2] = GETBYTE(value, 1);
652 block[3] = GETBYTE(value, 0);
656 block[0] = GETBYTE(value, 0);
657 block[1] = GETBYTE(value, 1);
658 block[2] = GETBYTE(value, 2);
659 block[3] = GETBYTE(value, 3);
664 block[0] ^= xorBlock[0];
665 block[1] ^= xorBlock[1];
666 block[2] ^= xorBlock[2];
667 block[3] ^= xorBlock[3];
673 inline T GetWord(
bool assumeAligned, ByteOrder order,
const byte *block)
676 return ByteReverseIf(*reinterpret_cast<const T *>(block), order);
678 return UnalignedGetWord<T>(order,
block);
682 inline void GetWord(
bool assumeAligned, ByteOrder order, T &result,
685 result = GetWord<T>(assumeAligned, order,
block);
689 inline void PutWord(
bool assumeAligned, ByteOrder order, byte* block, T value,
690 const byte *xorBlock = 0)
695 *
reinterpret_cast<T *
>(
block) = ByteReverseIf(value, order)
696 ^ *
reinterpret_cast<const T *
>(xorBlock);
698 *
reinterpret_cast<T *
>(
block) = ByteReverseIf(value, order);
701 UnalignedPutWord(order, block, value, xorBlock);
704 template <
class T,
class B,
bool A=true>
709 : m_block((
const byte *)block) {}
714 TAOCRYPT_COMPILE_ASSERT(
sizeof(U) >=
sizeof(T));
715 x = GetWord<T>(
A, B::ToEnum(), m_block);
716 m_block +=
sizeof(T);
724 template <
class T,
class B,
bool A = true>
728 PutBlock(
const void *xorBlock,
void *block)
729 : m_xorBlock((
const byte *)xorBlock), m_block((byte *)block) {}
734 PutWord(
A, B::ToEnum(), m_block, (T)x, m_xorBlock);
735 m_block +=
sizeof(T);
737 m_xorBlock +=
sizeof(T);
742 const byte *m_xorBlock;
750 template <
class T,
class B,
bool A= false>
762 template <
bool overflow>
struct SafeShifter;
764 template<>
struct SafeShifter<true>
767 static inline T RightShift(T value,
unsigned int bits)
773 static inline T LeftShift(T value,
unsigned int bits)
779 template<>
struct SafeShifter<false>
782 static inline T RightShift(T value,
unsigned int bits)
784 return value >> bits;
788 static inline T LeftShift(T value,
unsigned int bits)
790 return value << bits;
794 template <
unsigned int bits,
class T>
795 inline T SafeRightShift(T value)
797 return SafeShifter<(bits>=(8*
sizeof(T)))>::RightShift(value, bits);
800 template <
unsigned int bits,
class T>
801 inline T SafeLeftShift(T value)
803 return SafeShifter<(bits>=(8*
sizeof(T)))>::LeftShift(value, bits);
808 word ShiftWordsLeftByBits(
word* r,
unsigned int n,
unsigned int shiftBits)
812 for (
unsigned int i=0;
i<
n;
i++)
815 r[
i] = (u << shiftBits) | carry;
816 carry = u >> (WORD_BITS-shiftBits);
823 word ShiftWordsRightByBits(
word* r,
unsigned int n,
unsigned int shiftBits)
827 for (
int i=n-1;
i>=0;
i--)
830 r[
i] = (u >> shiftBits) | carry;
831 carry = u << (WORD_BITS-shiftBits);
838 void ShiftWordsLeftByWords(
word* r,
unsigned int n,
unsigned int shiftWords)
840 shiftWords = min(shiftWords, n);
843 for (
unsigned int i=n-1;
i>=shiftWords;
i--)
844 r[
i] = r[
i-shiftWords];
845 SetWords(r, 0, shiftWords);
851 void ShiftWordsRightByWords(
word* r,
unsigned int n,
unsigned int shiftWords)
853 shiftWords = min(shiftWords, n);
856 for (
unsigned int i=0;
i+shiftWords<
n;
i++)
857 r[
i] = r[
i+shiftWords];
858 SetWords(r+n-shiftWords, 0, shiftWords);
863 template <
class T1,
class T2>
864 inline T1 SaturatingSubtract(
T1 a,
T2 b)
866 TAOCRYPT_COMPILE_ASSERT_INSTANCE(
T1(-1)>0, 0);
867 TAOCRYPT_COMPILE_ASSERT_INSTANCE(
T2(-1)>0, 1);
868 return T1((a > b) ? (a - b) : 0);
873 unsigned int BytePrecision(
word value);
874 unsigned int BitPrecision(
word);
881 #endif // TAO_CRYPT_MISC_HPP