diff --git a/config.h b/config.h index 9f0054ab..295a5b72 100644 --- a/config.h +++ b/config.h @@ -61,14 +61,17 @@ // Defining this will cause Crypto++ to make only one call to CryptAcquireContext. #define WORKAROUND_MS_BUG_Q258000 -// Avoid putting "CryptoPP::" in front of everything in Doxygen output #ifdef CRYPTOPP_DOXYGEN_PROCESSING +// Avoid putting "CryptoPP::" in front of everything in Doxygen output # define CryptoPP # define NAMESPACE_BEGIN(x) # define NAMESPACE_END +// Get Doxygen to generate better documentation for these typedefs +# define DOCUMENTED_TYPEDEF(x, y) class y : public x {}; #else # define NAMESPACE_BEGIN(x) namespace x { # define NAMESPACE_END } +# define DOCUMENTED_TYPEDEF(x, y) typedef x y; #endif #define ANONYMOUS_NAMESPACE_BEGIN namespace { #define USING_NAMESPACE(x) using namespace x; @@ -233,7 +236,7 @@ NAMESPACE_END # define OS_RNG_AVAILABLE #endif -#ifdef CRYPTOPP_UNIX_AVAILABLE +#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) # define NONBLOCKING_RNG_AVAILABLE # define BLOCKING_RNG_AVAILABLE # define OS_RNG_AVAILABLE @@ -246,6 +249,14 @@ NAMESPACE_END # define THREADS_AVAILABLE #endif +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +# define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 +#endif + +#if defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) +# define CRYPTOPP_MEMALIGN_AVAILABLE +#endif + #endif // NO_OS_DEPENDENCE // ***************** DLL related ******************** diff --git a/integer.cpp b/integer.cpp index 503ba268..ff62879d 100644 --- a/integer.cpp +++ b/integer.cpp @@ -20,14 +20,18 @@ #ifdef SSE2_INTRINSICS_AVAILABLE #ifdef __GNUC__ #include - #include #include #include + #ifdef CRYPTOPP_MEMALIGN_AVAILABLE + #include + #else + #include + #endif #else #include #endif #elif defined(_MSC_VER) && defined(_M_IX86) - #pragma message("You do no seem to have the Visual C++ Processor Pack installed, so use of SSE2 intrinsics will be disabled.") + #pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 intrinsics will be disabled.") #elif defined(__GNUC__) && defined(__i386__) #warning "You do not have GCC 3.3 or later, or did not specify -msse2 compiler option, so use of SSE2 intrinsics will be disabled." #endif @@ -44,26 +48,40 @@ bool FunctionAssignIntToInteger(const std::type_info &valueType, void *pInteger, static const char s_RunAtStartup = (AssignIntToInteger = FunctionAssignIntToInteger, 0); -#if defined(SSE2_INTRINSICS_AVAILABLE) || defined(_MSC_VER) +#ifdef SSE2_INTRINSICS_AVAILABLE template CPP_TYPENAME AllocatorBase::pointer AlignedAllocator::allocate(size_type n, const void *) { CheckSize(n); if (n == 0) return NULL; -#ifdef SSE2_INTRINSICS_AVAILABLE if (n >= 4) { void *p; - #ifdef __GNUC__ - while (!(p = memalign(16, sizeof(T)*n))) - #else + #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE while (!(p = _mm_malloc(sizeof(T)*n, 16))) + #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE) + while (!(p = memalign(16, sizeof(T)*n))) + #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) + while (!(p = malloc(sizeof(T)*n))) + #else + while (!(p = (byte *)malloc(sizeof(T)*n + 8))) // assume malloc alignment is at least 8 #endif CallNewHandler(); + + #ifdef CRYPTOPP_NO_ALIGNED_ALLOC + assert(m_pBlock == NULL); + m_pBlock = p; + if (!IsAlignedOn(p, 16)) + { + assert(IsAlignedOn(p, 8)); + p = (byte *)p + 8; + } + #endif + + assert(IsAlignedOn(p, 16)); return (T*)p; } -#endif return new T[n]; } @@ -71,15 +89,19 @@ template void AlignedAllocator::deallocate(void *p, size_type n) { memset(p, 0, n*sizeof(T)); -#ifdef SSE2_INTRINSICS_AVAILABLE if (n >= 4) - #ifdef __GNUC__ - free(p); - #else + { + #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE _mm_free(p); + #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC) + assert(m_pBlock == p || (byte *)m_pBlock+8 == p); + free(m_pBlock); + m_pBlock = NULL; + #else + free(p); #endif + } else -#endif delete [] (T *)p; } #endif diff --git a/integer.h b/integer.h index aebbb41a..58990615 100644 --- a/integer.h +++ b/integer.h @@ -14,11 +14,13 @@ #ifdef _M_IX86 #if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || (defined(__ICL) && (__ICL >= 500)) #define SSE2_INTRINSICS_AVAILABLE + #define CRYPTOPP_MM_MALLOC_AVAILABLE #elif defined(_MSC_VER) // _mm_free seems to be the only way to tell if the Processor Pack is installed or not #include #if defined(_mm_free) #define SSE2_INTRINSICS_AVAILABLE + #define CRYPTOPP_MM_MALLOC_AVAILABLE #endif #endif #endif @@ -32,10 +34,7 @@ NAMESPACE_BEGIN(CryptoPP) -#if defined(SSE2_INTRINSICS_AVAILABLE) || defined(_MSC_VER) - // Defined this class for MSVC even if processor pack is not installed, - // so that the library can be compiled with processor pack, and calling app - // compiled without it. +#if defined(SSE2_INTRINSICS_AVAILABLE) template class AlignedAllocator : public AllocatorBase { @@ -48,11 +47,17 @@ NAMESPACE_BEGIN(CryptoPP) { return StandardReallocate(*this, p, oldSize, newSize, preserve); } + + #if !(defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) || defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE)) + #define CRYPTOPP_NO_ALIGNED_ALLOC + AlignedAllocator() : m_pBlock(NULL) {} + protected: + void *m_pBlock; + #endif }; template class CRYPTOPP_DLL AlignedAllocator; typedef SecBlock > SecAlignedWordBlock; - #else typedef SecWordBlock SecAlignedWordBlock; #endif diff --git a/secblock.h b/secblock.h index ea95e35d..67971447 100644 --- a/secblock.h +++ b/secblock.h @@ -59,9 +59,11 @@ typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize if (preserve) { - typename A::pointer newPointer = a.allocate(newSize, NULL); + A b; + typename A::pointer newPointer = b.allocate(newSize, NULL); memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize)); a.deallocate(p, oldSize); + std::swap(a, b); return newPointer; } else @@ -181,7 +183,11 @@ public: return p; } - return StandardReallocate(*this, p, oldSize, newSize, preserve); + pointer newPointer = allocate(newSize, NULL); + if (preserve) + memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize)); + deallocate(p, oldSize); + return newPointer; } size_type max_size() const {return STDMAX(m_fallbackAllocator.max_size(), S);}