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