Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1276 lines
33 KiB

  1. #ifndef CRYPTOPP_MISC_H
  2. #define CRYPTOPP_MISC_H
  3. #include "cryptlib.h"
  4. #include "smartptr.h"
  5. #include <string.h> // for memcpy and memmove
  6. #ifdef _MSC_VER
  7. #if _MSC_VER >= 1400
  8. // VC2005 workaround: disable declarations that conflict with winnt.h
  9. #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
  10. #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2
  11. #define _interlockedbittestandset64 CRYPTOPP_DISABLED_INTRINSIC_3
  12. #define _interlockedbittestandreset64 CRYPTOPP_DISABLED_INTRINSIC_4
  13. #include <intrin.h>
  14. #undef _interlockedbittestandset
  15. #undef _interlockedbittestandreset
  16. #undef _interlockedbittestandset64
  17. #undef _interlockedbittestandreset64
  18. #define CRYPTOPP_FAST_ROTATE(x) 1
  19. #elif _MSC_VER >= 1300
  20. #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
  21. #else
  22. #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
  23. #endif
  24. #elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
  25. (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
  26. #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
  27. #elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions
  28. #define CRYPTOPP_FAST_ROTATE(x) 1
  29. #else
  30. #define CRYPTOPP_FAST_ROTATE(x) 0
  31. #endif
  32. #ifdef __BORLANDC__
  33. #include <mem.h>
  34. #endif
  35. #if defined(__GNUC__) && defined(__linux__)
  36. #define CRYPTOPP_BYTESWAP_AVAILABLE
  37. #include <byteswap.h>
  38. #endif
  39. NAMESPACE_BEGIN(CryptoPP)
  40. // ************** compile-time assertion ***************
  41. #define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
  42. #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
  43. #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
  44. #else
  45. #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) typedef int CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)[ (assertion) ? 1 : -1]
  46. #endif
  47. #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
  48. #define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
  49. // ************** misc classes ***************
  50. class CRYPTOPP_DLL Empty
  51. {
  52. };
  53. //! _
  54. template <class BASE1, class BASE2>
  55. class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2
  56. {
  57. };
  58. //! _
  59. template <class BASE1, class BASE2, class BASE3>
  60. class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3
  61. {
  62. };
  63. template <class T>
  64. class ObjectHolder
  65. {
  66. protected:
  67. T m_object;
  68. };
  69. class NotCopyable
  70. {
  71. public:
  72. NotCopyable() {}
  73. private:
  74. NotCopyable(const NotCopyable &);
  75. void operator=(const NotCopyable &);
  76. };
  77. template <class T>
  78. struct NewObject
  79. {
  80. T* operator()() const {return new T;}
  81. };
  82. /*! This function safely initializes a static object in a multithreaded environment without using locks (for portability).
  83. Note that if two threads call Ref() at the same time, they may get back different references, and one object
  84. may end up being memory leaked. This is by design.
  85. */
  86. template <class T, class F = NewObject<T>, int instance=0>
  87. class Singleton
  88. {
  89. public:
  90. Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {}
  91. // prevent this function from being inlined
  92. CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const;
  93. private:
  94. F m_objectFactory;
  95. };
  96. template <class T, class F, int instance>
  97. const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
  98. {
  99. static volatile simple_ptr<T> s_pObject;
  100. T *p = s_pObject.m_p;
  101. if (p)
  102. return *p;
  103. T *newObject = m_objectFactory();
  104. p = s_pObject.m_p;
  105. if (p)
  106. {
  107. delete newObject;
  108. return *p;
  109. }
  110. s_pObject.m_p = newObject;
  111. return *newObject;
  112. }
  113. // ************** misc functions ***************
  114. #if (!__STDC_WANT_SECURE_LIB__)
  115. inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
  116. {
  117. if (count > sizeInBytes)
  118. throw InvalidArgument("memcpy_s: buffer overflow");
  119. memcpy(dest, src, count);
  120. }
  121. inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
  122. {
  123. if (count > sizeInBytes)
  124. throw InvalidArgument("memmove_s: buffer overflow");
  125. memmove(dest, src, count);
  126. }
  127. #if __BORLANDC__ >= 0x620
  128. // C++Builder 2010 workaround: can't use std::memcpy_s because it doesn't allow 0 lengths
  129. #define memcpy_s CryptoPP::memcpy_s
  130. #define memmove_s CryptoPP::memmove_s
  131. #endif
  132. #endif
  133. inline void * memset_z(void *ptr, int value, size_t num)
  134. {
  135. // avoid extranous warning on GCC 4.3.2 Ubuntu 8.10
  136. #if CRYPTOPP_GCC_VERSION >= 30001
  137. if (__builtin_constant_p(num) && num==0)
  138. return ptr;
  139. #endif
  140. return memset(ptr, value, num);
  141. }
  142. // can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
  143. template <class T> inline const T& STDMIN(const T& a, const T& b)
  144. {
  145. return b < a ? b : a;
  146. }
  147. template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b)
  148. {
  149. CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0));
  150. assert(a==0 || a>0); // GCC workaround: get rid of the warning "comparison is always true due to limited range of data type"
  151. assert(b>=0);
  152. if (sizeof(T1)<=sizeof(T2))
  153. return b < (T2)a ? (T1)b : a;
  154. else
  155. return (T1)b < a ? (T1)b : a;
  156. }
  157. template <class T> inline const T& STDMAX(const T& a, const T& b)
  158. {
  159. return a < b ? b : a;
  160. }
  161. #define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue
  162. // this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
  163. #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
  164. // these may be faster on other CPUs/compilers
  165. // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
  166. // #define GETBYTE(x, y) (((byte *)&(x))[y])
  167. #define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y)))
  168. template <class T>
  169. unsigned int Parity(T value)
  170. {
  171. for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
  172. value ^= value >> i;
  173. return (unsigned int)value&1;
  174. }
  175. template <class T>
  176. unsigned int BytePrecision(const T &value)
  177. {
  178. if (!value)
  179. return 0;
  180. unsigned int l=0, h=8*sizeof(value);
  181. while (h-l > 8)
  182. {
  183. unsigned int t = (l+h)/2;
  184. if (value >> t)
  185. l = t;
  186. else
  187. h = t;
  188. }
  189. return h/8;
  190. }
  191. template <class T>
  192. unsigned int BitPrecision(const T &value)
  193. {
  194. if (!value)
  195. return 0;
  196. unsigned int l=0, h=8*sizeof(value);
  197. while (h-l > 1)
  198. {
  199. unsigned int t = (l+h)/2;
  200. if (value >> t)
  201. l = t;
  202. else
  203. h = t;
  204. }
  205. return h;
  206. }
  207. inline unsigned int TrailingZeros(word32 v)
  208. {
  209. #if defined(__GNUC__) && CRYPTOPP_GCC_VERSION >= 30400
  210. return __builtin_ctz(v);
  211. #elif defined(_MSC_VER) && _MSC_VER >= 1400
  212. unsigned long result;
  213. _BitScanForward(&result, v);
  214. return result;
  215. #else
  216. // from http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
  217. static const int MultiplyDeBruijnBitPosition[32] =
  218. {
  219. 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
  220. 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
  221. };
  222. return MultiplyDeBruijnBitPosition[((word32)((v & -v) * 0x077CB531U)) >> 27];
  223. #endif
  224. }
  225. inline unsigned int TrailingZeros(word64 v)
  226. {
  227. #if defined(__GNUC__) && CRYPTOPP_GCC_VERSION >= 30400
  228. return __builtin_ctzll(v);
  229. #elif defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(_M_X64) || defined(_M_IA64))
  230. unsigned long result;
  231. _BitScanForward64(&result, v);
  232. return result;
  233. #else
  234. return word32(v) ? TrailingZeros(word32(v)) : 32 + TrailingZeros(word32(v>>32));
  235. #endif
  236. }
  237. template <class T>
  238. inline T Crop(T value, size_t size)
  239. {
  240. if (size < 8*sizeof(value))
  241. return T(value & ((T(1) << size) - 1));
  242. else
  243. return value;
  244. }
  245. template <class T1, class T2>
  246. inline bool SafeConvert(T1 from, T2 &to)
  247. {
  248. to = (T2)from;
  249. if (from != to || (from > 0) != (to > 0))
  250. return false;
  251. return true;
  252. }
  253. inline size_t BitsToBytes(size_t bitCount)
  254. {
  255. return ((bitCount+7)/(8));
  256. }
  257. inline size_t BytesToWords(size_t byteCount)
  258. {
  259. return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
  260. }
  261. inline size_t BitsToWords(size_t bitCount)
  262. {
  263. return ((bitCount+WORD_BITS-1)/(WORD_BITS));
  264. }
  265. inline size_t BitsToDwords(size_t bitCount)
  266. {
  267. return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
  268. }
  269. CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count);
  270. CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count);
  271. CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
  272. template <class T>
  273. inline bool IsPowerOf2(const T &n)
  274. {
  275. return n > 0 && (n & (n-1)) == 0;
  276. }
  277. template <class T1, class T2>
  278. inline T2 ModPowerOf2(const T1 &a, const T2 &b)
  279. {
  280. assert(IsPowerOf2(b));
  281. return T2(a) & (b-1);
  282. }
  283. template <class T1, class T2>
  284. inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
  285. {
  286. if (IsPowerOf2(m))
  287. return n - ModPowerOf2(n, m);
  288. else
  289. return n - n%m;
  290. }
  291. template <class T1, class T2>
  292. inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
  293. {
  294. if (n+m-1 < n)
  295. throw InvalidArgument("RoundUpToMultipleOf: integer overflow");
  296. return RoundDownToMultipleOf(n+m-1, m);
  297. }
  298. template <class T>
  299. inline unsigned int GetAlignmentOf(T *dummy=NULL) // VC60 workaround
  300. {
  301. #ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
  302. if (sizeof(T) < 16)
  303. return 1;
  304. #endif
  305. #if (_MSC_VER >= 1300)
  306. return __alignof(T);
  307. #elif defined(__GNUC__)
  308. return __alignof__(T);
  309. #elif CRYPTOPP_BOOL_SLOW_WORD64
  310. return UnsignedMin(4U, sizeof(T));
  311. #else
  312. return sizeof(T);
  313. #endif
  314. }
  315. inline bool IsAlignedOn(const void *p, unsigned int alignment)
  316. {
  317. return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0);
  318. }
  319. template <class T>
  320. inline bool IsAligned(const void *p, T *dummy=NULL) // VC60 workaround
  321. {
  322. return IsAlignedOn(p, GetAlignmentOf<T>());
  323. }
  324. #ifdef IS_LITTLE_ENDIAN
  325. typedef LittleEndian NativeByteOrder;
  326. #else
  327. typedef BigEndian NativeByteOrder;
  328. #endif
  329. inline ByteOrder GetNativeByteOrder()
  330. {
  331. return NativeByteOrder::ToEnum();
  332. }
  333. inline bool NativeByteOrderIs(ByteOrder order)
  334. {
  335. return order == GetNativeByteOrder();
  336. }
  337. template <class T>
  338. std::string IntToString(T a, unsigned int base = 10)
  339. {
  340. if (a == 0)
  341. return "0";
  342. bool negate = false;
  343. if (a < 0)
  344. {
  345. negate = true;
  346. a = 0-a; // VC .NET does not like -a
  347. }
  348. std::string result;
  349. while (a > 0)
  350. {
  351. T digit = a % base;
  352. result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
  353. a /= base;
  354. }
  355. if (negate)
  356. result = "-" + result;
  357. return result;
  358. }
  359. template <class T1, class T2>
  360. inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
  361. {
  362. return T1((a > b) ? (a - b) : 0);
  363. }
  364. template <class T>
  365. inline CipherDir GetCipherDir(const T &obj)
  366. {
  367. return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
  368. }
  369. CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler();
  370. inline void IncrementCounterByOne(byte *inout, unsigned int s)
  371. {
  372. for (int i=s-1, carry=1; i>=0 && carry; i--)
  373. carry = !++inout[i];
  374. }
  375. inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
  376. {
  377. int i, carry;
  378. for (i=s-1, carry=1; i>=0 && carry; i--)
  379. carry = ((output[i] = input[i]+1) == 0);
  380. memcpy_s(output, s, input, i+1);
  381. }
  382. template <class T>
  383. inline void ConditionalSwap(bool c, T &a, T &b)
  384. {
  385. T t = c * (a ^ b);
  386. a ^= t;
  387. b ^= t;
  388. }
  389. template <class T>
  390. inline void ConditionalSwapPointers(bool c, T &a, T &b)
  391. {
  392. ptrdiff_t t = c * (a - b);
  393. a -= t;
  394. b += t;
  395. }
  396. // see http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/protect-secrets.html
  397. // and https://www.securecoding.cert.org/confluence/display/cplusplus/MSC06-CPP.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data
  398. template <class T>
  399. void SecureWipeBuffer(T *buf, size_t n)
  400. {
  401. // GCC 4.3.2 on Cygwin optimizes away the first store if this loop is done in the forward direction
  402. volatile T *p = buf+n;
  403. while (n--)
  404. *(--p) = 0;
  405. }
  406. #if (_MSC_VER >= 1400 || defined(__GNUC__)) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86)
  407. template<> inline void SecureWipeBuffer(byte *buf, size_t n)
  408. {
  409. volatile byte *p = buf;
  410. #ifdef __GNUC__
  411. asm volatile("rep stosb" : "+c"(n), "+D"(p) : "a"(0) : "memory");
  412. #else
  413. __stosb((byte *)(size_t)p, 0, n);
  414. #endif
  415. }
  416. template<> inline void SecureWipeBuffer(word16 *buf, size_t n)
  417. {
  418. volatile word16 *p = buf;
  419. #ifdef __GNUC__
  420. asm volatile("rep stosw" : "+c"(n), "+D"(p) : "a"(0) : "memory");
  421. #else
  422. __stosw((word16 *)(size_t)p, 0, n);
  423. #endif
  424. }
  425. template<> inline void SecureWipeBuffer(word32 *buf, size_t n)
  426. {
  427. volatile word32 *p = buf;
  428. #ifdef __GNUC__
  429. asm volatile("rep stosl" : "+c"(n), "+D"(p) : "a"(0) : "memory");
  430. #else
  431. __stosd((unsigned long *)(size_t)p, 0, n);
  432. #endif
  433. }
  434. template<> inline void SecureWipeBuffer(word64 *buf, size_t n)
  435. {
  436. #if CRYPTOPP_BOOL_X64
  437. volatile word64 *p = buf;
  438. #ifdef __GNUC__
  439. asm volatile("rep stosq" : "+c"(n), "+D"(p) : "a"(0) : "memory");
  440. #else
  441. __stosq((word64 *)(size_t)p, 0, n);
  442. #endif
  443. #else
  444. SecureWipeBuffer((word32 *)buf, 2*n);
  445. #endif
  446. }
  447. #endif // #if (_MSC_VER >= 1400 || defined(__GNUC__)) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86)
  448. template <class T>
  449. inline void SecureWipeArray(T *buf, size_t n)
  450. {
  451. if (sizeof(T) % 8 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word64>() == 0)
  452. SecureWipeBuffer((word64 *)buf, n * (sizeof(T)/8));
  453. else if (sizeof(T) % 4 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word32>() == 0)
  454. SecureWipeBuffer((word32 *)buf, n * (sizeof(T)/4));
  455. else if (sizeof(T) % 2 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word16>() == 0)
  456. SecureWipeBuffer((word16 *)buf, n * (sizeof(T)/2));
  457. else
  458. SecureWipeBuffer((byte *)buf, n * sizeof(T));
  459. }
  460. // this function uses wcstombs(), which assumes that setlocale() has been called
  461. static std::string StringNarrow(const wchar_t *str, bool throwOnError = true)
  462. {
  463. #ifdef _MSC_VER
  464. #pragma warning(push)
  465. #pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe.
  466. #endif
  467. size_t size = wcstombs(NULL, str, 0);
  468. if (size == size_t(0)-1)
  469. {
  470. if (throwOnError)
  471. throw InvalidArgument("StringNarrow: wcstombs() call failed");
  472. else
  473. return std::string();
  474. }
  475. std::string result(size, 0);
  476. wcstombs(&result[0], str, size);
  477. return result;
  478. #ifdef _MSC_VER
  479. #pragma warning(pop)
  480. #endif
  481. }
  482. #if CRYPTOPP_BOOL_ALIGN16_ENABLED
  483. CRYPTOPP_DLL void * CRYPTOPP_API AlignedAllocate(size_t size);
  484. CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *p);
  485. #endif
  486. CRYPTOPP_DLL void * CRYPTOPP_API UnalignedAllocate(size_t size);
  487. CRYPTOPP_DLL void CRYPTOPP_API UnalignedDeallocate(void *p);
  488. // ************** rotate functions ***************
  489. template <class T> inline T rotlFixed(T x, unsigned int y)
  490. {
  491. assert(y < sizeof(T)*8);
  492. return T((x<<y) | (x>>(sizeof(T)*8-y)));
  493. }
  494. template <class T> inline T rotrFixed(T x, unsigned int y)
  495. {
  496. assert(y < sizeof(T)*8);
  497. return T((x>>y) | (x<<(sizeof(T)*8-y)));
  498. }
  499. template <class T> inline T rotlVariable(T x, unsigned int y)
  500. {
  501. assert(y < sizeof(T)*8);
  502. return T((x<<y) | (x>>(sizeof(T)*8-y)));
  503. }
  504. template <class T> inline T rotrVariable(T x, unsigned int y)
  505. {
  506. assert(y < sizeof(T)*8);
  507. return T((x>>y) | (x<<(sizeof(T)*8-y)));
  508. }
  509. template <class T> inline T rotlMod(T x, unsigned int y)
  510. {
  511. y %= sizeof(T)*8;
  512. return T((x<<y) | (x>>(sizeof(T)*8-y)));
  513. }
  514. template <class T> inline T rotrMod(T x, unsigned int y)
  515. {
  516. y %= sizeof(T)*8;
  517. return T((x>>y) | (x<<(sizeof(T)*8-y)));
  518. }
  519. #ifdef _MSC_VER
  520. template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
  521. {
  522. assert(y < 8*sizeof(x));
  523. return y ? _lrotl(x, y) : x;
  524. }
  525. template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
  526. {
  527. assert(y < 8*sizeof(x));
  528. return y ? _lrotr(x, y) : x;
  529. }
  530. template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
  531. {
  532. assert(y < 8*sizeof(x));
  533. return _lrotl(x, y);
  534. }
  535. template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
  536. {
  537. assert(y < 8*sizeof(x));
  538. return _lrotr(x, y);
  539. }
  540. template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
  541. {
  542. return _lrotl(x, y);
  543. }
  544. template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
  545. {
  546. return _lrotr(x, y);
  547. }
  548. #endif // #ifdef _MSC_VER
  549. #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
  550. // Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions
  551. template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y)
  552. {
  553. assert(y < 8*sizeof(x));
  554. return y ? _rotl64(x, y) : x;
  555. }
  556. template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y)
  557. {
  558. assert(y < 8*sizeof(x));
  559. return y ? _rotr64(x, y) : x;
  560. }
  561. template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y)
  562. {
  563. assert(y < 8*sizeof(x));
  564. return _rotl64(x, y);
  565. }
  566. template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y)
  567. {
  568. assert(y < 8*sizeof(x));
  569. return _rotr64(x, y);
  570. }
  571. template<> inline word64 rotlMod<word64>(word64 x, unsigned int y)
  572. {
  573. return _rotl64(x, y);
  574. }
  575. template<> inline word64 rotrMod<word64>(word64 x, unsigned int y)
  576. {
  577. return _rotr64(x, y);
  578. }
  579. #endif // #if _MSC_VER >= 1310
  580. #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
  581. // Intel C++ Compiler 10.0 gives undefined externals with these
  582. template<> inline word16 rotlFixed<word16>(word16 x, unsigned int y)
  583. {
  584. assert(y < 8*sizeof(x));
  585. return y ? _rotl16(x, y) : x;
  586. }
  587. template<> inline word16 rotrFixed<word16>(word16 x, unsigned int y)
  588. {
  589. assert(y < 8*sizeof(x));
  590. return y ? _rotr16(x, y) : x;
  591. }
  592. template<> inline word16 rotlVariable<word16>(word16 x, unsigned int y)
  593. {
  594. assert(y < 8*sizeof(x));
  595. return _rotl16(x, y);
  596. }
  597. template<> inline word16 rotrVariable<word16>(word16 x, unsigned int y)
  598. {
  599. assert(y < 8*sizeof(x));
  600. return _rotr16(x, y);
  601. }
  602. template<> inline word16 rotlMod<word16>(word16 x, unsigned int y)
  603. {
  604. return _rotl16(x, y);
  605. }
  606. template<> inline word16 rotrMod<word16>(word16 x, unsigned int y)
  607. {
  608. return _rotr16(x, y);
  609. }
  610. template<> inline byte rotlFixed<byte>(byte x, unsigned int y)
  611. {
  612. assert(y < 8*sizeof(x));
  613. return y ? _rotl8(x, y) : x;
  614. }
  615. template<> inline byte rotrFixed<byte>(byte x, unsigned int y)
  616. {
  617. assert(y < 8*sizeof(x));
  618. return y ? _rotr8(x, y) : x;
  619. }
  620. template<> inline byte rotlVariable<byte>(byte x, unsigned int y)
  621. {
  622. assert(y < 8*sizeof(x));
  623. return _rotl8(x, y);
  624. }
  625. template<> inline byte rotrVariable<byte>(byte x, unsigned int y)
  626. {
  627. assert(y < 8*sizeof(x));
  628. return _rotr8(x, y);
  629. }
  630. template<> inline byte rotlMod<byte>(byte x, unsigned int y)
  631. {
  632. return _rotl8(x, y);
  633. }
  634. template<> inline byte rotrMod<byte>(byte x, unsigned int y)
  635. {
  636. return _rotr8(x, y);
  637. }
  638. #endif // #if _MSC_VER >= 1400
  639. #if (defined(__MWERKS__) && TARGET_CPU_PPC)
  640. template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
  641. {
  642. assert(y < 32);
  643. return y ? __rlwinm(x,y,0,31) : x;
  644. }
  645. template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
  646. {
  647. assert(y < 32);
  648. return y ? __rlwinm(x,32-y,0,31) : x;
  649. }
  650. template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
  651. {
  652. assert(y < 32);
  653. return (__rlwnm(x,y,0,31));
  654. }
  655. template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
  656. {
  657. assert(y < 32);
  658. return (__rlwnm(x,32-y,0,31));
  659. }
  660. template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
  661. {
  662. return (__rlwnm(x,y,0,31));
  663. }
  664. template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
  665. {
  666. return (__rlwnm(x,32-y,0,31));
  667. }
  668. #endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC)
  669. // ************** endian reversal ***************
  670. template <class T>
  671. inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
  672. {
  673. if (order == LITTLE_ENDIAN_ORDER)
  674. return GETBYTE(value, index);
  675. else
  676. return GETBYTE(value, sizeof(T)-index-1);
  677. }
  678. inline byte ByteReverse(byte value)
  679. {
  680. return value;
  681. }
  682. inline word16 ByteReverse(word16 value)
  683. {
  684. #ifdef CRYPTOPP_BYTESWAP_AVAILABLE
  685. return bswap_16(value);
  686. #elif defined(_MSC_VER) && _MSC_VER >= 1300
  687. return _byteswap_ushort(value);
  688. #else
  689. return rotlFixed(value, 8U);
  690. #endif
  691. }
  692. inline word32 ByteReverse(word32 value)
  693. {
  694. #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
  695. __asm__ ("bswap %0" : "=r" (value) : "0" (value));
  696. return value;
  697. #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
  698. return bswap_32(value);
  699. #elif defined(__MWERKS__) && TARGET_CPU_PPC
  700. return (word32)__lwbrx(&value,0);
  701. #elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
  702. return _byteswap_ulong(value);
  703. #elif CRYPTOPP_FAST_ROTATE(32)
  704. // 5 instructions with rotate instruction, 9 without
  705. return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
  706. #else
  707. // 6 instructions with rotate instruction, 8 without
  708. value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
  709. return rotlFixed(value, 16U);
  710. #endif
  711. }
  712. inline word64 ByteReverse(word64 value)
  713. {
  714. #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
  715. __asm__ ("bswap %0" : "=r" (value) : "0" (value));
  716. return value;
  717. #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
  718. return bswap_64(value);
  719. #elif defined(_MSC_VER) && _MSC_VER >= 1300
  720. return _byteswap_uint64(value);
  721. #elif CRYPTOPP_BOOL_SLOW_WORD64
  722. return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
  723. #else
  724. value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
  725. value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
  726. return rotlFixed(value, 32U);
  727. #endif
  728. }
  729. inline byte BitReverse(byte value)
  730. {
  731. value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
  732. value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
  733. return rotlFixed(value, 4U);
  734. }
  735. inline word16 BitReverse(word16 value)
  736. {
  737. value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
  738. value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
  739. value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
  740. return ByteReverse(value);
  741. }
  742. inline word32 BitReverse(word32 value)
  743. {
  744. value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
  745. value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
  746. value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
  747. return ByteReverse(value);
  748. }
  749. inline word64 BitReverse(word64 value)
  750. {
  751. #if CRYPTOPP_BOOL_SLOW_WORD64
  752. return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
  753. #else
  754. value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
  755. value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
  756. value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
  757. return ByteReverse(value);
  758. #endif
  759. }
  760. template <class T>
  761. inline T BitReverse(T value)
  762. {
  763. if (sizeof(T) == 1)
  764. return (T)BitReverse((byte)value);
  765. else if (sizeof(T) == 2)
  766. return (T)BitReverse((word16)value);
  767. else if (sizeof(T) == 4)
  768. return (T)BitReverse((word32)value);
  769. else
  770. {
  771. assert(sizeof(T) == 8);
  772. return (T)BitReverse((word64)value);
  773. }
  774. }
  775. template <class T>
  776. inline T ConditionalByteReverse(ByteOrder order, T value)
  777. {
  778. return NativeByteOrderIs(order) ? value : ByteReverse(value);
  779. }
  780. template <class T>
  781. void ByteReverse(T *out, const T *in, size_t byteCount)
  782. {
  783. assert(byteCount % sizeof(T) == 0);
  784. size_t count = byteCount/sizeof(T);
  785. for (size_t i=0; i<count; i++)
  786. out[i] = ByteReverse(in[i]);
  787. }
  788. template <class T>
  789. inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount)
  790. {
  791. if (!NativeByteOrderIs(order))
  792. ByteReverse(out, in, byteCount);
  793. else if (in != out)
  794. memcpy_s(out, byteCount, in, byteCount);
  795. }
  796. template <class T>
  797. inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
  798. {
  799. const size_t U = sizeof(T);
  800. assert(inlen <= outlen*U);
  801. memcpy_s(out, outlen*U, in, inlen);
  802. memset_z((byte *)out+inlen, 0, outlen*U-inlen);
  803. ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
  804. }
  805. #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
  806. inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *)
  807. {
  808. return block[0];
  809. }
  810. inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *)
  811. {
  812. return (order == BIG_ENDIAN_ORDER)
  813. ? block[1] | (block[0] << 8)
  814. : block[0] | (block[1] << 8);
  815. }
  816. inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *)
  817. {
  818. return (order == BIG_ENDIAN_ORDER)
  819. ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
  820. : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
  821. }
  822. inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *)
  823. {
  824. return (order == BIG_ENDIAN_ORDER)
  825. ?
  826. (word64(block[7]) |
  827. (word64(block[6]) << 8) |
  828. (word64(block[5]) << 16) |
  829. (word64(block[4]) << 24) |
  830. (word64(block[3]) << 32) |
  831. (word64(block[2]) << 40) |
  832. (word64(block[1]) << 48) |
  833. (word64(block[0]) << 56))
  834. :
  835. (word64(block[0]) |
  836. (word64(block[1]) << 8) |
  837. (word64(block[2]) << 16) |
  838. (word64(block[3]) << 24) |
  839. (word64(block[4]) << 32) |
  840. (word64(block[5]) << 40) |
  841. (word64(block[6]) << 48) |
  842. (word64(block[7]) << 56));
  843. }
  844. inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock)
  845. {
  846. block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
  847. }
  848. inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock)
  849. {
  850. if (order == BIG_ENDIAN_ORDER)
  851. {
  852. if (xorBlock)
  853. {
  854. block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  855. block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  856. }
  857. else
  858. {
  859. block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  860. block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  861. }
  862. }
  863. else
  864. {
  865. if (xorBlock)
  866. {
  867. block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  868. block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  869. }
  870. else
  871. {
  872. block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  873. block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  874. }
  875. }
  876. }
  877. inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock)
  878. {
  879. if (order == BIG_ENDIAN_ORDER)
  880. {
  881. if (xorBlock)
  882. {
  883. block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
  884. block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
  885. block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  886. block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  887. }
  888. else
  889. {
  890. block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
  891. block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
  892. block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  893. block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  894. }
  895. }
  896. else
  897. {
  898. if (xorBlock)
  899. {
  900. block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  901. block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  902. block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
  903. block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
  904. }
  905. else
  906. {
  907. block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  908. block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  909. block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
  910. block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
  911. }
  912. }
  913. }
  914. inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock)
  915. {
  916. if (order == BIG_ENDIAN_ORDER)
  917. {
  918. if (xorBlock)
  919. {
  920. block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
  921. block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
  922. block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
  923. block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
  924. block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
  925. block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
  926. block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  927. block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  928. }
  929. else
  930. {
  931. block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
  932. block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
  933. block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
  934. block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
  935. block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
  936. block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
  937. block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  938. block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  939. }
  940. }
  941. else
  942. {
  943. if (xorBlock)
  944. {
  945. block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  946. block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  947. block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
  948. block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
  949. block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
  950. block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
  951. block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
  952. block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
  953. }
  954. else
  955. {
  956. block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
  957. block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
  958. block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
  959. block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
  960. block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
  961. block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
  962. block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
  963. block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
  964. }
  965. }
  966. }
  967. #endif // #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
  968. template <class T>
  969. inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
  970. {
  971. #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
  972. if (!assumeAligned)
  973. return UnalignedGetWordNonTemplate(order, block, (T*)NULL);
  974. assert(IsAligned<T>(block));
  975. #endif
  976. return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
  977. }
  978. template <class T>
  979. inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
  980. {
  981. result = GetWord<T>(assumeAligned, order, block);
  982. }
  983. template <class T>
  984. inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
  985. {
  986. #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
  987. if (!assumeAligned)
  988. return UnalignedPutWordNonTemplate(order, block, value, xorBlock);
  989. assert(IsAligned<T>(block));
  990. assert(IsAligned<T>(xorBlock));
  991. #endif
  992. *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast<const T *>(xorBlock) : 0);
  993. }
  994. template <class T, class B, bool A=false>
  995. class GetBlock
  996. {
  997. public:
  998. GetBlock(const void *block)
  999. : m_block((const byte *)block) {}
  1000. template <class U>
  1001. inline GetBlock<T, B, A> & operator()(U &x)
  1002. {
  1003. CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
  1004. x = GetWord<T>(A, B::ToEnum(), m_block);
  1005. m_block += sizeof(T);
  1006. return *this;
  1007. }
  1008. private:
  1009. const byte *m_block;
  1010. };
  1011. template <class T, class B, bool A=false>
  1012. class PutBlock
  1013. {
  1014. public:
  1015. PutBlock(const void *xorBlock, void *block)
  1016. : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
  1017. template <class U>
  1018. inline PutBlock<T, B, A> & operator()(U x)
  1019. {
  1020. PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
  1021. m_block += sizeof(T);
  1022. if (m_xorBlock)
  1023. m_xorBlock += sizeof(T);
  1024. return *this;
  1025. }
  1026. private:
  1027. const byte *m_xorBlock;
  1028. byte *m_block;
  1029. };
  1030. template <class T, class B, bool GA=false, bool PA=false>
  1031. struct BlockGetAndPut
  1032. {
  1033. // function needed because of C++ grammatical ambiguity between expression-statements and declarations
  1034. static inline GetBlock<T, B, GA> Get(const void *block) {return GetBlock<T, B, GA>(block);}
  1035. typedef PutBlock<T, B, PA> Put;
  1036. };
  1037. template <class T>
  1038. std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
  1039. {
  1040. if (!NativeByteOrderIs(order))
  1041. value = ByteReverse(value);
  1042. return std::string((char *)&value, sizeof(value));
  1043. }
  1044. template <class T>
  1045. T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
  1046. {
  1047. T value = 0;
  1048. memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value)));
  1049. return NativeByteOrderIs(order) ? value : ByteReverse(value);
  1050. }
  1051. // ************** help remove warning on g++ ***************
  1052. template <bool overflow> struct SafeShifter;
  1053. template<> struct SafeShifter<true>
  1054. {
  1055. template <class T>
  1056. static inline T RightShift(T value, unsigned int bits)
  1057. {
  1058. return 0;
  1059. }
  1060. template <class T>
  1061. static inline T LeftShift(T value, unsigned int bits)
  1062. {
  1063. return 0;
  1064. }
  1065. };
  1066. template<> struct SafeShifter<false>
  1067. {
  1068. template <class T>
  1069. static inline T RightShift(T value, unsigned int bits)
  1070. {
  1071. return value >> bits;
  1072. }
  1073. template <class T>
  1074. static inline T LeftShift(T value, unsigned int bits)
  1075. {
  1076. return value << bits;
  1077. }
  1078. };
  1079. template <unsigned int bits, class T>
  1080. inline T SafeRightShift(T value)
  1081. {
  1082. return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
  1083. }
  1084. template <unsigned int bits, class T>
  1085. inline T SafeLeftShift(T value)
  1086. {
  1087. return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
  1088. }
  1089. // ************** use one buffer for multiple data members ***************
  1090. #define CRYPTOPP_BLOCK_1(n, t, s) t* m_##n() {return (t *)(m_aggregate+0);} size_t SS1() {return sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
  1091. #define CRYPTOPP_BLOCK_2(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS1());} size_t SS2() {return SS1()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
  1092. #define CRYPTOPP_BLOCK_3(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS2());} size_t SS3() {return SS2()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
  1093. #define CRYPTOPP_BLOCK_4(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS3());} size_t SS4() {return SS3()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
  1094. #define CRYPTOPP_BLOCK_5(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS4());} size_t SS5() {return SS4()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
  1095. #define CRYPTOPP_BLOCK_6(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS5());} size_t SS6() {return SS5()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
  1096. #define CRYPTOPP_BLOCK_7(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS6());} size_t SS7() {return SS6()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
  1097. #define CRYPTOPP_BLOCK_8(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS7());} size_t SS8() {return SS7()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
  1098. #define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate;
  1099. NAMESPACE_END
  1100. #endif