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

Generated on Mon Aug 9 2010 15:56:35 for Crypto++ by  doxygen 1.7.1