• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

misc.h

00001 #ifndef CRYPTOPP_MISC_H
00002 #define CRYPTOPP_MISC_H
00003 
00004 #include "cryptlib.h"
00005 #include "smartptr.h"
00006 #include <string.h>     // for memcpy and memmove
00007 
00008 #ifdef _MSC_VER
00009     #include <stdlib.h>
00010     #if _MSC_VER >= 1400
00011         // VC2005 workaround: disable declarations that conflict with winnt.h
00012         #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
00013         #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2
00014         #define _interlockedbittestandset64 CRYPTOPP_DISABLED_INTRINSIC_3
00015         #define _interlockedbittestandreset64 CRYPTOPP_DISABLED_INTRINSIC_4
00016         #include <intrin.h>
00017         #undef _interlockedbittestandset
00018         #undef _interlockedbittestandreset
00019         #undef _interlockedbittestandset64
00020         #undef _interlockedbittestandreset64
00021         #define CRYPTOPP_FAST_ROTATE(x) 1
00022     #elif _MSC_VER >= 1300
00023         #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
00024     #else
00025         #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
00026     #endif
00027 #elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
00028     (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
00029     #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
00030 #elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions
00031     #define CRYPTOPP_FAST_ROTATE(x) 1
00032 #else
00033     #define CRYPTOPP_FAST_ROTATE(x) 0
00034 #endif
00035 
00036 #ifdef __BORLANDC__
00037 #include <mem.h>
00038 #endif
00039 
00040 #if defined(__GNUC__) && defined(__linux__)
00041 #define CRYPTOPP_BYTESWAP_AVAILABLE
00042 #include <byteswap.h>
00043 #include <cstring>
00044 #endif
00045 
00046 NAMESPACE_BEGIN(CryptoPP)
00047 
00048 // ************** compile-time assertion ***************
00049 
00050 template <bool b>
00051 struct CompileAssert
00052 {
00053     static char dummy[2*b-1];
00054 };
00055 
00056 #define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
00057 #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
00058 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
00059 #else
00060 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
00061 #endif
00062 #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
00063 #define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
00064 
00065 // ************** misc classes ***************
00066 
00067 class CRYPTOPP_DLL Empty
00068 {
00069 };
00070 
00071 //! _
00072 template <class BASE1, class BASE2>
00073 class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2
00074 {
00075 };
00076 
00077 //! _
00078 template <class BASE1, class BASE2, class BASE3>
00079 class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3
00080 {
00081 };
00082 
00083 template <class T>
00084 class ObjectHolder
00085 {
00086 protected:
00087     T m_object;
00088 };
00089 
00090 class NotCopyable
00091 {
00092 public:
00093     NotCopyable() {}
00094 private:
00095     NotCopyable(const NotCopyable &);
00096     void operator=(const NotCopyable &);
00097 };
00098 
00099 template <class T>
00100 struct NewObject
00101 {
00102     T* operator()() const {return new T;}
00103 };
00104 
00105 /*! This function safely initializes a static object in a multithreaded environment without using locks.
00106     It may leak memory when two threads try to initialize the static object at the same time
00107     but this should be acceptable since each static object is only initialized once per session.
00108 */
00109 template <class T, class F = NewObject<T>, int instance=0>
00110 class Singleton
00111 {
00112 public:
00113     Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {}
00114 
00115     // prevent this function from being inlined
00116     CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const;
00117 
00118 private:
00119     F m_objectFactory;
00120 };
00121 
00122 template <class T, class F, int instance>
00123 const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
00124 {
00125     static simple_ptr<T> s_pObject;
00126     static char s_objectState = 0;
00127 
00128 retry:
00129     switch (s_objectState)
00130     {
00131     case 0:
00132         s_objectState = 1;
00133         try
00134         {
00135             s_pObject.m_p = m_objectFactory();
00136         }
00137         catch(...)
00138         {
00139             s_objectState = 0;
00140             throw;
00141         }
00142         s_objectState = 2;
00143         break;
00144     case 1:
00145         goto retry;
00146     default:
00147         break;
00148     }
00149     return *s_pObject.m_p;
00150 }
00151 
00152 // ************** misc functions ***************
00153 
00154 #if (!__STDC_WANT_SECURE_LIB__)
00155 inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
00156 {
00157     if (count > sizeInBytes)
00158         throw InvalidArgument("memcpy_s: buffer overflow");
00159     memcpy(dest, src, count);
00160 }
00161 
00162 inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
00163 {
00164     if (count > sizeInBytes)
00165         throw InvalidArgument("memmove_s: buffer overflow");
00166     memmove(dest, src, count);
00167 }
00168 #endif
00169 
00170 inline void * memset_z(void *ptr, int value, size_t num)
00171 {
00172 // avoid extranous warning on GCC 4.3.2 Ubuntu 8.10
00173 #if CRYPTOPP_GCC_VERSION >= 30001
00174     if (__builtin_constant_p(num) && num==0)
00175         return ptr;
00176 #endif
00177     return memset(ptr, value, num);
00178 }
00179 
00180 // can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
00181 template <class T> inline const T& STDMIN(const T& a, const T& b)
00182 {
00183     return b < a ? b : a;
00184 }
00185 
00186 template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b)
00187 {
00188     CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0));
00189     assert(a==0 || a>0);    // GCC workaround: get rid of the warning "comparison is always true due to limited range of data type"
00190     assert(b>=0);
00191 
00192     if (sizeof(T1)<=sizeof(T2))
00193         return b < (T2)a ? (T1)b : a;
00194     else
00195         return (T1)b < a ? (T1)b : a;
00196 }
00197 
00198 template <class T> inline const T& STDMAX(const T& a, const T& b)
00199 {
00200     return a < b ? b : a;
00201 }
00202 
00203 #define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue
00204 
00205 // this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
00206 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
00207 // these may be faster on other CPUs/compilers
00208 // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
00209 // #define GETBYTE(x, y) (((byte *)&(x))[y])
00210 
00211 #define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y)))
00212 
00213 template <class T>
00214 unsigned int Parity(T value)
00215 {
00216     for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
00217         value ^= value >> i;
00218     return (unsigned int)value&1;
00219 }
00220 
00221 template <class T>
00222 unsigned int BytePrecision(const T &value)
00223 {
00224     if (!value)
00225         return 0;
00226 
00227     unsigned int l=0, h=8*sizeof(value);
00228 
00229     while (h-l > 8)
00230     {
00231         unsigned int t = (l+h)/2;
00232         if (value >> t)
00233             l = t;
00234         else
00235             h = t;
00236     }
00237 
00238     return h/8;
00239 }
00240 
00241 template <class T>
00242 unsigned int BitPrecision(const T &value)
00243 {
00244     if (!value)
00245         return 0;
00246 
00247     unsigned int l=0, h=8*sizeof(value);
00248 
00249     while (h-l > 1)
00250     {
00251         unsigned int t = (l+h)/2;
00252         if (value >> t)
00253             l = t;
00254         else
00255             h = t;
00256     }
00257 
00258     return h;
00259 }
00260 
00261 template <class T>
00262 inline T Crop(T value, size_t size)
00263 {
00264     if (size < 8*sizeof(value))
00265         return T(value & ((T(1) << size) - 1));
00266     else
00267         return value;
00268 }
00269 
00270 template <class T1, class T2>
00271 inline bool SafeConvert(T1 from, T2 &to)
00272 {
00273     to = (T2)from;
00274     if (from != to || (from > 0) != (to > 0))
00275         return false;
00276     return true;
00277 }
00278 
00279 inline size_t BitsToBytes(size_t bitCount)
00280 {
00281     return ((bitCount+7)/(8));
00282 }
00283 
00284 inline size_t BytesToWords(size_t byteCount)
00285 {
00286     return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
00287 }
00288 
00289 inline size_t BitsToWords(size_t bitCount)
00290 {
00291     return ((bitCount+WORD_BITS-1)/(WORD_BITS));
00292 }
00293 
00294 inline size_t BitsToDwords(size_t bitCount)
00295 {
00296     return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
00297 }
00298 
00299 CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count);
00300 CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count);
00301 
00302 CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
00303 
00304 template <class T>
00305 inline bool IsPowerOf2(const T &n)
00306 {
00307     return n > 0 && (n & (n-1)) == 0;
00308 }
00309 
00310 template <class T1, class T2>
00311 inline T2 ModPowerOf2(const T1 &a, const T2 &b)
00312 {
00313     assert(IsPowerOf2(b));
00314     return T2(a) & (b-1);
00315 }
00316 
00317 template <class T1, class T2>
00318 inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
00319 {
00320     if (IsPowerOf2(m))
00321         return n - ModPowerOf2(n, m);
00322     else
00323         return n - n%m;
00324 }
00325 
00326 template <class T1, class T2>
00327 inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
00328 {
00329     if (n+m-1 < n)
00330         throw InvalidArgument("RoundUpToMultipleOf: integer overflow");
00331     return RoundDownToMultipleOf(n+m-1, m);
00332 }
00333 
00334 template <class T>
00335 inline unsigned int GetAlignmentOf(T *dummy=NULL)   // VC60 workaround
00336 {
00337 #ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
00338     if (sizeof(T) < 16)
00339         return 1;
00340 #endif
00341 
00342 #if (_MSC_VER >= 1300)
00343     return __alignof(T);
00344 #elif defined(__GNUC__)
00345     return __alignof__(T);
00346 #elif CRYPTOPP_BOOL_SLOW_WORD64
00347     return UnsignedMin(4U, sizeof(T));
00348 #else
00349     return sizeof(T);
00350 #endif
00351 }
00352 
00353 inline bool IsAlignedOn(const void *p, unsigned int alignment)
00354 {
00355     return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0);
00356 }
00357 
00358 template <class T>
00359 inline bool IsAligned(const void *p, T *dummy=NULL) // VC60 workaround
00360 {
00361     return IsAlignedOn(p, GetAlignmentOf<T>());
00362 }
00363 
00364 #ifdef IS_LITTLE_ENDIAN
00365     typedef LittleEndian NativeByteOrder;
00366 #else
00367     typedef BigEndian NativeByteOrder;
00368 #endif
00369 
00370 inline ByteOrder GetNativeByteOrder()
00371 {
00372     return NativeByteOrder::ToEnum();
00373 }
00374 
00375 inline bool NativeByteOrderIs(ByteOrder order)
00376 {
00377     return order == GetNativeByteOrder();
00378 }
00379 
00380 template <class T>
00381 std::string IntToString(T a, unsigned int base = 10)
00382 {
00383     if (a == 0)
00384         return "0";
00385     bool negate = false;
00386     if (a < 0)
00387     {
00388         negate = true;
00389         a = 0-a;    // VC .NET does not like -a
00390     }
00391     std::string result;
00392     while (a > 0)
00393     {
00394         T digit = a % base;
00395         result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
00396         a /= base;
00397     }
00398     if (negate)
00399         result = "-" + result;
00400     return result;
00401 }
00402 
00403 template <class T1, class T2>
00404 inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
00405 {
00406     return T1((a > b) ? (a - b) : 0);
00407 }
00408 
00409 template <class T>
00410 inline CipherDir GetCipherDir(const T &obj)
00411 {
00412     return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
00413 }
00414 
00415 CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler();
00416 
00417 inline void IncrementCounterByOne(byte *inout, unsigned int s)
00418 {
00419     for (int i=s-1, carry=1; i>=0 && carry; i--)
00420         carry = !++inout[i];
00421 }
00422 
00423 inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
00424 {
00425     int i, carry;
00426     for (i=s-1, carry=1; i>=0 && carry; i--)
00427         carry = ((output[i] = input[i]+1) == 0);
00428     memcpy_s(output, s, input, i+1);
00429 }
00430 
00431 // ************** rotate functions ***************
00432 
00433 template <class T> inline T rotlFixed(T x, unsigned int y)
00434 {
00435     assert(y < sizeof(T)*8);
00436     return T((x<<y) | (x>>(sizeof(T)*8-y)));
00437 }
00438 
00439 template <class T> inline T rotrFixed(T x, unsigned int y)
00440 {
00441     assert(y < sizeof(T)*8);
00442     return T((x>>y) | (x<<(sizeof(T)*8-y)));
00443 }
00444 
00445 template <class T> inline T rotlVariable(T x, unsigned int y)
00446 {
00447     assert(y < sizeof(T)*8);
00448     return T((x<<y) | (x>>(sizeof(T)*8-y)));
00449 }
00450 
00451 template <class T> inline T rotrVariable(T x, unsigned int y)
00452 {
00453     assert(y < sizeof(T)*8);
00454     return T((x>>y) | (x<<(sizeof(T)*8-y)));
00455 }
00456 
00457 template <class T> inline T rotlMod(T x, unsigned int y)
00458 {
00459     y %= sizeof(T)*8;
00460     return T((x<<y) | (x>>(sizeof(T)*8-y)));
00461 }
00462 
00463 template <class T> inline T rotrMod(T x, unsigned int y)
00464 {
00465     y %= sizeof(T)*8;
00466     return T((x>>y) | (x<<(sizeof(T)*8-y)));
00467 }
00468 
00469 #ifdef _MSC_VER
00470 
00471 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00472 {
00473     assert(y < 8*sizeof(x));
00474     return y ? _lrotl(x, y) : x;
00475 }
00476 
00477 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00478 {
00479     assert(y < 8*sizeof(x));
00480     return y ? _lrotr(x, y) : x;
00481 }
00482 
00483 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00484 {
00485     assert(y < 8*sizeof(x));
00486     return _lrotl(x, y);
00487 }
00488 
00489 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00490 {
00491     assert(y < 8*sizeof(x));
00492     return _lrotr(x, y);
00493 }
00494 
00495 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00496 {
00497     return _lrotl(x, y);
00498 }
00499 
00500 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00501 {
00502     return _lrotr(x, y);
00503 }
00504 
00505 #endif // #ifdef _MSC_VER
00506 
00507 #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
00508 // Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions
00509 
00510 template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y)
00511 {
00512     assert(y < 8*sizeof(x));
00513     return y ? _rotl64(x, y) : x;
00514 }
00515 
00516 template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y)
00517 {
00518     assert(y < 8*sizeof(x));
00519     return y ? _rotr64(x, y) : x;
00520 }
00521 
00522 template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y)
00523 {
00524     assert(y < 8*sizeof(x));
00525     return _rotl64(x, y);
00526 }
00527 
00528 template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y)
00529 {
00530     assert(y < 8*sizeof(x));
00531     return _rotr64(x, y);
00532 }
00533 
00534 template<> inline word64 rotlMod<word64>(word64 x, unsigned int y)
00535 {
00536     return _rotl64(x, y);
00537 }
00538 
00539 template<> inline word64 rotrMod<word64>(word64 x, unsigned int y)
00540 {
00541     return _rotr64(x, y);
00542 }
00543 
00544 #endif // #if _MSC_VER >= 1310
00545 
00546 #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
00547 // Intel C++ Compiler 10.0 gives undefined externals with these
00548 
00549 template<> inline word16 rotlFixed<word16>(word16 x, unsigned int y)
00550 {
00551     assert(y < 8*sizeof(x));
00552     return y ? _rotl16(x, y) : x;
00553 }
00554 
00555 template<> inline word16 rotrFixed<word16>(word16 x, unsigned int y)
00556 {
00557     assert(y < 8*sizeof(x));
00558     return y ? _rotr16(x, y) : x;
00559 }
00560 
00561 template<> inline word16 rotlVariable<word16>(word16 x, unsigned int y)
00562 {
00563     assert(y < 8*sizeof(x));
00564     return _rotl16(x, y);
00565 }
00566 
00567 template<> inline word16 rotrVariable<word16>(word16 x, unsigned int y)
00568 {
00569     assert(y < 8*sizeof(x));
00570     return _rotr16(x, y);
00571 }
00572 
00573 template<> inline word16 rotlMod<word16>(word16 x, unsigned int y)
00574 {
00575     return _rotl16(x, y);
00576 }
00577 
00578 template<> inline word16 rotrMod<word16>(word16 x, unsigned int y)
00579 {
00580     return _rotr16(x, y);
00581 }
00582 
00583 template<> inline byte rotlFixed<byte>(byte x, unsigned int y)
00584 {
00585     assert(y < 8*sizeof(x));
00586     return y ? _rotl8(x, y) : x;
00587 }
00588 
00589 template<> inline byte rotrFixed<byte>(byte x, unsigned int y)
00590 {
00591     assert(y < 8*sizeof(x));
00592     return y ? _rotr8(x, y) : x;
00593 }
00594 
00595 template<> inline byte rotlVariable<byte>(byte x, unsigned int y)
00596 {
00597     assert(y < 8*sizeof(x));
00598     return _rotl8(x, y);
00599 }
00600 
00601 template<> inline byte rotrVariable<byte>(byte x, unsigned int y)
00602 {
00603     assert(y < 8*sizeof(x));
00604     return _rotr8(x, y);
00605 }
00606 
00607 template<> inline byte rotlMod<byte>(byte x, unsigned int y)
00608 {
00609     return _rotl8(x, y);
00610 }
00611 
00612 template<> inline byte rotrMod<byte>(byte x, unsigned int y)
00613 {
00614     return _rotr8(x, y);
00615 }
00616 
00617 #endif // #if _MSC_VER >= 1400
00618 
00619 #if (defined(__MWERKS__) && TARGET_CPU_PPC)
00620 
00621 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
00622 {
00623     assert(y < 32);
00624     return y ? __rlwinm(x,y,0,31) : x;
00625 }
00626 
00627 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
00628 {
00629     assert(y < 32);
00630     return y ? __rlwinm(x,32-y,0,31) : x;
00631 }
00632 
00633 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
00634 {
00635     assert(y < 32);
00636     return (__rlwnm(x,y,0,31));
00637 }
00638 
00639 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
00640 {
00641     assert(y < 32);
00642     return (__rlwnm(x,32-y,0,31));
00643 }
00644 
00645 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
00646 {
00647     return (__rlwnm(x,y,0,31));
00648 }
00649 
00650 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
00651 {
00652     return (__rlwnm(x,32-y,0,31));
00653 }
00654 
00655 #endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC)
00656 
00657 // ************** endian reversal ***************
00658 
00659 template <class T>
00660 inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
00661 {
00662     if (order == LITTLE_ENDIAN_ORDER)
00663         return GETBYTE(value, index);
00664     else
00665         return GETBYTE(value, sizeof(T)-index-1);
00666 }
00667 
00668 inline byte ByteReverse(byte value)
00669 {
00670     return value;
00671 }
00672 
00673 inline word16 ByteReverse(word16 value)
00674 {
00675 #ifdef CRYPTOPP_BYTESWAP_AVAILABLE
00676     return bswap_16(value);
00677 #elif defined(_MSC_VER) && _MSC_VER >= 1300
00678     return _byteswap_ushort(value);
00679 #else
00680     return rotlFixed(value, 8U);
00681 #endif
00682 }
00683 
00684 inline word32 ByteReverse(word32 value)
00685 {
00686 #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
00687     __asm__ ("bswap %0" : "=r" (value) : "0" (value));
00688     return value;
00689 #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
00690     return bswap_32(value);
00691 #elif defined(__MWERKS__) && TARGET_CPU_PPC
00692     return (word32)__lwbrx(&value,0);
00693 #elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
00694     return _byteswap_ulong(value);
00695 #elif CRYPTOPP_FAST_ROTATE(32)
00696     // 5 instructions with rotate instruction, 9 without
00697     return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
00698 #else
00699     // 6 instructions with rotate instruction, 8 without
00700     value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00701     return rotlFixed(value, 16U);
00702 #endif
00703 }
00704 
00705 inline word64 ByteReverse(word64 value)
00706 {
00707 #if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
00708     __asm__ ("bswap %0" : "=r" (value) : "0" (value));
00709     return value;
00710 #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
00711     return bswap_64(value);
00712 #elif defined(_MSC_VER) && _MSC_VER >= 1300
00713     return _byteswap_uint64(value);
00714 #elif CRYPTOPP_BOOL_SLOW_WORD64
00715     return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
00716 #else
00717     value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
00718     value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
00719     return rotlFixed(value, 32U);
00720 #endif
00721 }
00722 
00723 inline byte BitReverse(byte value)
00724 {
00725     value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
00726     value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
00727     return rotlFixed(value, 4U);
00728 }
00729 
00730 inline word16 BitReverse(word16 value)
00731 {
00732     value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
00733     value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
00734     value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
00735     return ByteReverse(value);
00736 }
00737 
00738 inline word32 BitReverse(word32 value)
00739 {
00740     value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
00741     value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
00742     value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
00743     return ByteReverse(value);
00744 }
00745 
00746 inline word64 BitReverse(word64 value)
00747 {
00748 #if CRYPTOPP_BOOL_SLOW_WORD64
00749     return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
00750 #else
00751     value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
00752     value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
00753     value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
00754     return ByteReverse(value);
00755 #endif
00756 }
00757 
00758 template <class T>
00759 inline T BitReverse(T value)
00760 {
00761     if (sizeof(T) == 1)
00762         return (T)BitReverse((byte)value);
00763     else if (sizeof(T) == 2)
00764         return (T)BitReverse((word16)value);
00765     else if (sizeof(T) == 4)
00766         return (T)BitReverse((word32)value);
00767     else
00768     {
00769         assert(sizeof(T) == 8);
00770         return (T)BitReverse((word64)value);
00771     }
00772 }
00773 
00774 template <class T>
00775 inline T ConditionalByteReverse(ByteOrder order, T value)
00776 {
00777     return NativeByteOrderIs(order) ? value : ByteReverse(value);
00778 }
00779 
00780 template <class T>
00781 void ByteReverse(T *out, const T *in, size_t byteCount)
00782 {
00783     assert(byteCount % sizeof(T) == 0);
00784     size_t count = byteCount/sizeof(T);
00785     for (size_t i=0; i<count; i++)
00786         out[i] = ByteReverse(in[i]);
00787 }
00788 
00789 template <class T>
00790 inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount)
00791 {
00792     if (!NativeByteOrderIs(order))
00793         ByteReverse(out, in, byteCount);
00794     else if (in != out)
00795         memcpy_s(out, byteCount, in, byteCount);
00796 }
00797 
00798 template <class T>
00799 inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
00800 {
00801     const size_t U = sizeof(T);
00802     assert(inlen <= outlen*U);
00803     memcpy_s(out, outlen*U, in, inlen);
00804     memset_z((byte *)out+inlen, 0, outlen*U-inlen);
00805     ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
00806 }
00807 
00808 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
00809 inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *)
00810 {
00811     return block[0];
00812 }
00813 
00814 inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *)
00815 {
00816     return (order == BIG_ENDIAN_ORDER)
00817         ? block[1] | (block[0] << 8)
00818         : block[0] | (block[1] << 8);
00819 }
00820 
00821 inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *)
00822 {
00823     return (order == BIG_ENDIAN_ORDER)
00824         ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
00825         : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
00826 }
00827 
00828 inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *)
00829 {
00830     return (order == BIG_ENDIAN_ORDER)
00831         ?
00832         (word64(block[7]) |
00833         (word64(block[6]) <<  8) |
00834         (word64(block[5]) << 16) |
00835         (word64(block[4]) << 24) |
00836         (word64(block[3]) << 32) |
00837         (word64(block[2]) << 40) |
00838         (word64(block[1]) << 48) |
00839         (word64(block[0]) << 56))
00840         :
00841         (word64(block[0]) |
00842         (word64(block[1]) <<  8) |
00843         (word64(block[2]) << 16) |
00844         (word64(block[3]) << 24) |
00845         (word64(block[4]) << 32) |
00846         (word64(block[5]) << 40) |
00847         (word64(block[6]) << 48) |
00848         (word64(block[7]) << 56));
00849 }
00850 
00851 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock)
00852 {
00853     block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
00854 }
00855 
00856 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock)
00857 {
00858     if (order == BIG_ENDIAN_ORDER)
00859     {
00860         if (xorBlock)
00861         {
00862             block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00863             block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00864         }
00865         else
00866         {
00867             block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00868             block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00869         }
00870     }
00871     else
00872     {
00873         if (xorBlock)
00874         {
00875             block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00876             block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00877         }
00878         else
00879         {
00880             block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00881             block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00882         }
00883     }
00884 }
00885 
00886 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock)
00887 {
00888     if (order == BIG_ENDIAN_ORDER)
00889     {
00890         if (xorBlock)
00891         {
00892             block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00893             block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00894             block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00895             block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00896         }
00897         else
00898         {
00899             block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00900             block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00901             block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00902             block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00903         }
00904     }
00905     else
00906     {
00907         if (xorBlock)
00908         {
00909             block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00910             block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00911             block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00912             block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00913         }
00914         else
00915         {
00916             block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00917             block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00918             block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00919             block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00920         }
00921     }
00922 }
00923 
00924 inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock)
00925 {
00926     if (order == BIG_ENDIAN_ORDER)
00927     {
00928         if (xorBlock)
00929         {
00930             block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
00931             block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
00932             block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
00933             block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
00934             block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00935             block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00936             block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00937             block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00938         }
00939         else
00940         {
00941             block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
00942             block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
00943             block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
00944             block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
00945             block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00946             block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00947             block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00948             block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00949         }
00950     }
00951     else
00952     {
00953         if (xorBlock)
00954         {
00955             block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00956             block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00957             block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00958             block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00959             block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
00960             block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
00961             block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
00962             block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
00963         }
00964         else
00965         {
00966             block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
00967             block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
00968             block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
00969             block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
00970             block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
00971             block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
00972             block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
00973             block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
00974         }
00975     }
00976 }
00977 #endif  // #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
00978 
00979 template <class T>
00980 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
00981 {
00982 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
00983     if (!assumeAligned)
00984         return UnalignedGetWordNonTemplate(order, block, (T*)NULL);
00985     assert(IsAligned<T>(block));
00986 #endif
00987     return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
00988 }
00989 
00990 template <class T>
00991 inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
00992 {
00993     result = GetWord<T>(assumeAligned, order, block);
00994 }
00995 
00996 template <class T>
00997 inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
00998 {
00999 #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
01000     if (!assumeAligned)
01001         return UnalignedPutWordNonTemplate(order, block, value, xorBlock);
01002     assert(IsAligned<T>(block));
01003     assert(IsAligned<T>(xorBlock));
01004 #endif
01005     *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast<const T *>(xorBlock) : 0);
01006 }
01007 
01008 template <class T, class B, bool A=false>
01009 class GetBlock
01010 {
01011 public:
01012     GetBlock(const void *block)
01013         : m_block((const byte *)block) {}
01014 
01015     template <class U>
01016     inline GetBlock<T, B, A> & operator()(U &x)
01017     {
01018         CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
01019         x = GetWord<T>(A, B::ToEnum(), m_block);
01020         m_block += sizeof(T);
01021         return *this;
01022     }
01023 
01024 private:
01025     const byte *m_block;
01026 };
01027 
01028 template <class T, class B, bool A=false>
01029 class PutBlock
01030 {
01031 public:
01032     PutBlock(const void *xorBlock, void *block)
01033         : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
01034 
01035     template <class U>
01036     inline PutBlock<T, B, A> & operator()(U x)
01037     {
01038         PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
01039         m_block += sizeof(T);
01040         if (m_xorBlock)
01041             m_xorBlock += sizeof(T);
01042         return *this;
01043     }
01044 
01045 private:
01046     const byte *m_xorBlock;
01047     byte *m_block;
01048 };
01049 
01050 template <class T, class B, bool GA=false, bool PA=false>
01051 struct BlockGetAndPut
01052 {
01053     // function needed because of C++ grammatical ambiguity between expression-statements and declarations
01054     static inline GetBlock<T, B, GA> Get(const void *block) {return GetBlock<T, B, GA>(block);}
01055     typedef PutBlock<T, B, PA> Put;
01056 };
01057 
01058 template <class T>
01059 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
01060 {
01061     if (!NativeByteOrderIs(order))
01062         value = ByteReverse(value);
01063 
01064     return std::string((char *)&value, sizeof(value));
01065 }
01066 
01067 template <class T>
01068 T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
01069 {
01070     T value = 0;
01071     memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value)));
01072     return NativeByteOrderIs(order) ? value : ByteReverse(value);
01073 }
01074 
01075 // ************** help remove warning on g++ ***************
01076 
01077 template <bool overflow> struct SafeShifter;
01078 
01079 template<> struct SafeShifter<true>
01080 {
01081     template <class T>
01082     static inline T RightShift(T value, unsigned int bits)
01083     {
01084         return 0;
01085     }
01086 
01087     template <class T>
01088     static inline T LeftShift(T value, unsigned int bits)
01089     {
01090         return 0;
01091     }
01092 };
01093 
01094 template<> struct SafeShifter<false>
01095 {
01096     template <class T>
01097     static inline T RightShift(T value, unsigned int bits)
01098     {
01099         return value >> bits;
01100     }
01101 
01102     template <class T>
01103     static inline T LeftShift(T value, unsigned int bits)
01104     {
01105         return value << bits;
01106     }
01107 };
01108 
01109 template <unsigned int bits, class T>
01110 inline T SafeRightShift(T value)
01111 {
01112     return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
01113 }
01114 
01115 template <unsigned int bits, class T>
01116 inline T SafeLeftShift(T value)
01117 {
01118     return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
01119 }
01120 
01121 // ************** use one buffer for multiple data members ***************
01122 
01123 #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);}
01124 #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);}
01125 #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);}
01126 #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);}
01127 #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);}
01128 #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);}
01129 #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);}
01130 #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);}
01131 #define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate;
01132 
01133 NAMESPACE_END
01134 
01135 #endif

Generated on Tue Jun 30 2015 19:07:04 for Crypto++ by  doxygen 1.7.1