diff --git a/config.h b/config.h index 2e71bcb8..5e495aa7 100644 --- a/config.h +++ b/config.h @@ -33,9 +33,26 @@ // #define NO_OS_DEPENDENCE // Define this to use features provided by Microsoft's CryptoAPI. -// Currently the only feature used is random number generation. +// Currently the only feature used is Windows random number generation. // This macro will be ignored if NO_OS_DEPENDENCE is defined. -#define USE_MS_CRYPTOAPI +// #define USE_MS_CRYPTOAPI + +// Define this to use features provided by Microsoft's CryptoNG API. +// CryptoNG API is available in Vista and above and its cross platform, +// including desktop apps and store apps. Currently the only feature +// used is Windows random number generation. +// This macro will be ignored if NO_OS_DEPENDENCE is defined. +// #define USE_MS_CNGAPI + +// If the user did not make a choice, then select CryptoNG if either +// Visual Studio 2015 is available, or Windows 10 or above is available. +#if !defined(USE_MS_CRYPTOAPI) && !defined(USE_MS_CNGAPI) +# if (_MSC_VER >= 1900) || ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/)) +# define USE_MS_CNGAPI +# else +# define USE_MS_CRYPTOAPI +# endif +#endif // Define this to ensure C/C++ standard compliance and respect for GCC aliasing rules and other alignment fodder. If you // experience a break with GCC at -O3, you should try this first. Guard it in case its set on the command line (and it differs). @@ -362,7 +379,7 @@ NAMESPACE_END // 8037: non-const function called for const object. needed to work around BCB2006 bug # pragma warn -8037 #endif - + // [GCC Bug 53431] "C++ preprocessor ignores #pragma GCC diagnostic". Clang honors it. #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE # pragma GCC diagnostic ignored "-Wunknown-pragmas" @@ -381,7 +398,7 @@ NAMESPACE_END #define CRYPTOPP_DISABLE_ASM #define CRYPTOPP_DISABLE_SSE2 #endif - + // Apple's Clang prior to 5.0 cannot handle SSE2 (and Apple does not use LLVM Clang numbering...) #if defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 50000) # define CRYPTOPP_DISABLE_ASM @@ -453,7 +470,7 @@ NAMESPACE_END #else #define CRYPTOPP_NO_ALIGNED_ALLOC #endif - + // Apple always provides 16-byte aligned, and tells us to use calloc // http://developer.apple.com/library/mac/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html @@ -466,7 +483,7 @@ NAMESPACE_END # define CRYPTOPP_NOINLINE __attribute__((noinline)) #else # define CRYPTOPP_NOINLINE_DOTDOTDOT ... -# define CRYPTOPP_NOINLINE +# define CRYPTOPP_NOINLINE #endif // how to declare class constants @@ -491,13 +508,13 @@ NAMESPACE_END #else #define CRYPTOPP_BOOL_X86 0 #endif - + #if (defined(_M_X64) || defined(__x86_64__)) && !CRYPTOPP_BOOL_X32 #define CRYPTOPP_BOOL_X64 1 #else #define CRYPTOPP_BOOL_X64 0 #endif - + // Undo the ASM and Intrinsic related defines due to X32. #if CRYPTOPP_BOOL_X32 # undef CRYPTOPP_BOOL_X64 @@ -505,6 +522,29 @@ NAMESPACE_END # undef CRYPTOPP_X64_MASM_AVAILABLE #endif +#if defined(__arm__) || defined(__aarch32__) || defined(_M_ARM) + #define CRYPTOPP_BOOL_ARM32 1 +#else + #define CRYPTOPP_BOOL_ARM32 0 +#endif + +#if defined(__aarch64__) + #define CRYPTOPP_BOOL_ARM64 1 +#else + #define CRYPTOPP_BOOL_ARM64 0 +#endif + +#if !defined(CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE) +# if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) && ((CRYPTOPP_GCC_VERSION >= 40400) || (CRYPTOPP_CLANG_VERSION >= 20800) || (CRYPTOPP_MSC_VERSION >= 1700)) +# if defined(__ARM_NEON__) || defined(__ARM_NEON) || defined(_M_ARM) +# define CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 1 +# endif +# endif +#endif + +#ifndef CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE +# define CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 0 +#endif #if !defined(CRYPTOPP_NO_UNALIGNED_DATA_ACCESS) && !defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS) #if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || defined(__powerpc__) || (__ARM_FEATURE_UNALIGNED >= 1)) #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS @@ -522,7 +562,7 @@ NAMESPACE_END #if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun) #define CRYPTOPP_UNIX_AVAILABLE #endif - + #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #define CRYPTOPP_BSD_AVAILABLE #endif @@ -531,33 +571,43 @@ NAMESPACE_END # define HIGHRES_TIMER_AVAILABLE #endif +#ifdef CRYPTOPP_WIN32_AVAILABLE +# if !defined(WINAPI_FAMILY) +# define THREAD_TIMER_AVAILABLE +# elif defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# define THREAD_TIMER_AVAILABLE +# endif +# endif +#endif + #ifdef CRYPTOPP_UNIX_AVAILABLE # define HAS_BERKELEY_STYLE_SOCKETS -#endif - -#ifdef CRYPTOPP_WIN32_AVAILABLE -# define HAS_WINDOWS_STYLE_SOCKETS -#endif - -#if defined(HIGHRES_TIMER_AVAILABLE) && (defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(HAS_WINDOWS_STYLE_SOCKETS)) # define SOCKETS_AVAILABLE #endif +// Sockets are only available under Windows Runtime desktop partition apps (despite the MSDN literature) +#ifdef CRYPTOPP_WIN32_AVAILABLE +# define HAS_WINDOWS_STYLE_SOCKETS +# if !defined(WINAPI_FAMILY) +# define SOCKETS_AVAILABLE +# elif defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# define SOCKETS_AVAILABLE +# endif +# endif +#endif + #if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS)) # define USE_WINDOWS_STYLE_SOCKETS #else # define USE_BERKELEY_STYLE_SOCKETS #endif -#if defined(HIGHRES_TIMER_AVAILABLE) && defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) +#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(SOCKETS_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) # define WINDOWS_PIPES_AVAILABLE #endif -#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(USE_MS_CRYPTOAPI) -# define NONBLOCKING_RNG_AVAILABLE -# define OS_RNG_AVAILABLE -#endif - #if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) # define NONBLOCKING_RNG_AVAILABLE # define BLOCKING_RNG_AVAILABLE @@ -567,8 +617,24 @@ NAMESPACE_END #endif #ifdef CRYPTOPP_WIN32_AVAILABLE +# if !defined(WINAPI_FAMILY) # define HAS_WINTHREADS # define THREADS_AVAILABLE +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# elif defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# define HAS_WINTHREADS +# define THREADS_AVAILABLE +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# elif !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# if ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/)) +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# endif +# endif +# endif #endif #endif // NO_OS_DEPENDENCE @@ -662,7 +728,20 @@ NAMESPACE_END #endif // C++11 or C++14 is available -#if defined(CRYPTOPP_CXX11) +#if defined(CRYPTOPP_CXX11) + +// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; and Intel 13.0. +#if (CRYPTOPP_MSC_VERSION >= 1700) +# define CRYPTOPP_CXX11_ATOMICS 1 +#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300) +# define CRYPTOPP_CXX11_ATOMICS 1 +#elif defined(__clang__) +# if __has_feature(cxx_atomic) +# define CRYPTOPP_CXX11_ATOMICS 1 +# endif +#elif (CRYPTOPP_GCC_VERSION >= 40400) +# define CRYPTOPP_CXX11_ATOMICS 1 +#endif // atomics // alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0. #if (CRYPTOPP_MSC_VERSION >= 1900) @@ -693,7 +772,7 @@ NAMESPACE_END #elif (CRYPTOPP_GCC_VERSION >= 40600) # define CRYPTOPP_CXX11_NOEXCEPT 1 #endif // noexcept compilers - + // variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; and Intel 12.1. #if (CRYPTOPP_MSC_VERSION >= 1800) # define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1 @@ -711,7 +790,7 @@ NAMESPACE_END // Needed because we are catching warnings with GCC and MSC #endif // CRYPTOPP_CXX11 - + #if defined(CRYPTOPP_CXX11_NOEXCEPT) # define CRYPTOPP_THROW noexcept(false) # define CRYPTOPP_NO_THROW noexcept(true) diff --git a/config.recommend b/config.recommend index ad845e88..08caa96d 100644 --- a/config.recommend +++ b/config.recommend @@ -33,9 +33,26 @@ // #define NO_OS_DEPENDENCE // Define this to use features provided by Microsoft's CryptoAPI. -// Currently the only feature used is random number generation. +// Currently the only feature used is Windows random number generation. // This macro will be ignored if NO_OS_DEPENDENCE is defined. -#define USE_MS_CRYPTOAPI +// #define USE_MS_CRYPTOAPI + +// Define this to use features provided by Microsoft's CryptoNG API. +// CryptoNG API is available in Vista and above and its cross platform, +// including desktop apps and store apps. Currently the only feature +// used is Windows random number generation. +// This macro will be ignored if NO_OS_DEPENDENCE is defined. +// #define USE_MS_CNGAPI + +// If the user did not make a choice, then select CryptoNG if either +// Visual Studio 2015 is available, or Windows 10 or above is available. +#if !defined(USE_MS_CRYPTOAPI) && !defined(USE_MS_CNGAPI) +# if (_MSC_VER >= 1900) || ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/)) +# define USE_MS_CNGAPI +# else +# define USE_MS_CRYPTOAPI +# endif +#endif // Define this to ensure C/C++ standard compliance and respect for GCC aliasing rules and other alignment fodder. If you // experience a break with GCC at -O3, you should try this first. Guard it in case its set on the command line (and it differs). @@ -362,7 +379,7 @@ NAMESPACE_END // 8037: non-const function called for const object. needed to work around BCB2006 bug # pragma warn -8037 #endif - + // [GCC Bug 53431] "C++ preprocessor ignores #pragma GCC diagnostic". Clang honors it. #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE # pragma GCC diagnostic ignored "-Wunknown-pragmas" @@ -381,7 +398,7 @@ NAMESPACE_END #define CRYPTOPP_DISABLE_ASM #define CRYPTOPP_DISABLE_SSE2 #endif - + // Apple's Clang prior to 5.0 cannot handle SSE2 (and Apple does not use LLVM Clang numbering...) #if defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 50000) # define CRYPTOPP_DISABLE_ASM @@ -453,7 +470,7 @@ NAMESPACE_END #else #define CRYPTOPP_NO_ALIGNED_ALLOC #endif - + // Apple always provides 16-byte aligned, and tells us to use calloc // http://developer.apple.com/library/mac/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html @@ -466,7 +483,7 @@ NAMESPACE_END # define CRYPTOPP_NOINLINE __attribute__((noinline)) #else # define CRYPTOPP_NOINLINE_DOTDOTDOT ... -# define CRYPTOPP_NOINLINE +# define CRYPTOPP_NOINLINE #endif // how to declare class constants @@ -491,13 +508,13 @@ NAMESPACE_END #else #define CRYPTOPP_BOOL_X86 0 #endif - + #if (defined(_M_X64) || defined(__x86_64__)) && !CRYPTOPP_BOOL_X32 #define CRYPTOPP_BOOL_X64 1 #else #define CRYPTOPP_BOOL_X64 0 #endif - + // Undo the ASM and Intrinsic related defines due to X32. #if CRYPTOPP_BOOL_X32 # undef CRYPTOPP_BOOL_X64 @@ -505,6 +522,29 @@ NAMESPACE_END # undef CRYPTOPP_X64_MASM_AVAILABLE #endif +#if defined(__arm__) || defined(__aarch32__) || defined(_M_ARM) + #define CRYPTOPP_BOOL_ARM32 1 +#else + #define CRYPTOPP_BOOL_ARM32 0 +#endif + +#if defined(__aarch64__) + #define CRYPTOPP_BOOL_ARM64 1 +#else + #define CRYPTOPP_BOOL_ARM64 0 +#endif + +#if !defined(CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE) +# if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) && ((CRYPTOPP_GCC_VERSION >= 40400) || (CRYPTOPP_CLANG_VERSION >= 20800) || (CRYPTOPP_MSC_VERSION >= 1700)) +# if defined(__ARM_NEON__) || defined(__ARM_NEON) || defined(_M_ARM) +# define CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 1 +# endif +# endif +#endif + +#ifndef CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE +# define CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 0 +#endif #if !defined(CRYPTOPP_NO_UNALIGNED_DATA_ACCESS) && !defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS) #if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || defined(__powerpc__) || (__ARM_FEATURE_UNALIGNED >= 1)) #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS @@ -522,7 +562,7 @@ NAMESPACE_END #if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun) #define CRYPTOPP_UNIX_AVAILABLE #endif - + #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #define CRYPTOPP_BSD_AVAILABLE #endif @@ -531,33 +571,43 @@ NAMESPACE_END # define HIGHRES_TIMER_AVAILABLE #endif +#ifdef CRYPTOPP_WIN32_AVAILABLE +# if !defined(WINAPI_FAMILY) +# define THREAD_TIMER_AVAILABLE +# elif defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# define THREAD_TIMER_AVAILABLE +# endif +# endif +#endif + #ifdef CRYPTOPP_UNIX_AVAILABLE # define HAS_BERKELEY_STYLE_SOCKETS -#endif - -#ifdef CRYPTOPP_WIN32_AVAILABLE -# define HAS_WINDOWS_STYLE_SOCKETS -#endif - -#if defined(HIGHRES_TIMER_AVAILABLE) && (defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(HAS_WINDOWS_STYLE_SOCKETS)) # define SOCKETS_AVAILABLE #endif +// Sockets are only available under Windows Runtime desktop partition apps (despite the MSDN literature) +#ifdef CRYPTOPP_WIN32_AVAILABLE +# define HAS_WINDOWS_STYLE_SOCKETS +# if !defined(WINAPI_FAMILY) +# define SOCKETS_AVAILABLE +# elif defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# define SOCKETS_AVAILABLE +# endif +# endif +#endif + #if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS)) # define USE_WINDOWS_STYLE_SOCKETS #else # define USE_BERKELEY_STYLE_SOCKETS #endif -#if defined(HIGHRES_TIMER_AVAILABLE) && defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) +#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(SOCKETS_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) # define WINDOWS_PIPES_AVAILABLE #endif -#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(USE_MS_CRYPTOAPI) -# define NONBLOCKING_RNG_AVAILABLE -# define OS_RNG_AVAILABLE -#endif - #if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) # define NONBLOCKING_RNG_AVAILABLE # define BLOCKING_RNG_AVAILABLE @@ -567,8 +617,24 @@ NAMESPACE_END #endif #ifdef CRYPTOPP_WIN32_AVAILABLE +# if !defined(WINAPI_FAMILY) # define HAS_WINTHREADS # define THREADS_AVAILABLE +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# elif defined(WINAPI_FAMILY) +# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# define HAS_WINTHREADS +# define THREADS_AVAILABLE +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# elif !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) +# if ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/)) +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# endif +# endif +# endif #endif #endif // NO_OS_DEPENDENCE @@ -662,7 +728,20 @@ NAMESPACE_END #endif // C++11 or C++14 is available -#if defined(CRYPTOPP_CXX11) +#if defined(CRYPTOPP_CXX11) + +// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; and Intel 13.0. +#if (CRYPTOPP_MSC_VERSION >= 1700) +# define CRYPTOPP_CXX11_ATOMICS 1 +#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300) +# define CRYPTOPP_CXX11_ATOMICS 1 +#elif defined(__clang__) +# if __has_feature(cxx_atomic) +# define CRYPTOPP_CXX11_ATOMICS 1 +# endif +#elif (CRYPTOPP_GCC_VERSION >= 40400) +# define CRYPTOPP_CXX11_ATOMICS 1 +#endif // atomics // alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0. #if (CRYPTOPP_MSC_VERSION >= 1900) @@ -693,7 +772,7 @@ NAMESPACE_END #elif (CRYPTOPP_GCC_VERSION >= 40600) # define CRYPTOPP_CXX11_NOEXCEPT 1 #endif // noexcept compilers - + // variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; and Intel 12.1. #if (CRYPTOPP_MSC_VERSION >= 1800) # define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1 @@ -711,7 +790,7 @@ NAMESPACE_END // Needed because we are catching warnings with GCC and MSC #endif // CRYPTOPP_CXX11 - + #if defined(CRYPTOPP_CXX11_NOEXCEPT) # define CRYPTOPP_THROW noexcept(false) # define CRYPTOPP_NO_THROW noexcept(true) diff --git a/cpu.cpp b/cpu.cpp index 2c5ee728..b6454953 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -24,6 +24,10 @@ NAMESPACE_BEGIN(CryptoPP) +// MacPorts/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it. +#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) +#define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0)) + #ifdef CRYPTOPP_CPUID_AVAILABLE #if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 @@ -168,10 +172,6 @@ bool g_x86DetectionDone = false; bool g_hasMMX = false, g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasSSE4 = false, g_hasAESNI = false, g_hasCLMUL = false, g_isP4 = false, g_hasRDRAND = false, g_hasRDSEED = false; word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; -// MacPorts/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it. -#define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) -#define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0)) - static inline bool IsIntel(const word32 output[4]) { // This is the "GenuineIntel" string @@ -251,6 +251,47 @@ void DetectX86Features() *((volatile bool*)&g_x86DetectionDone) = true; } +// http://community.arm.com/groups/android-community/blog/2014/10/10/runtime-detection-of-cpu-features-on-an-armv8-a-cpu +// http://stackoverflow.com/questions/26701262/how-to-check-the-existence-of-neon-on-arm +#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) + +bool g_ArmDetectionDone = false; +bool g_hasNEON = false, g_hasCRC32 = false; + +// This is avaiable in a status register, but we need privileged code to perform the read +word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + +#if HAVE_GCC_CONSTRUCTOR1 +void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 50))) DetectArmFeatures() +#elif HAVE_GCC_CONSTRUCTOR0 +void __attribute__ ((constructor)) DetectArmFeatures() +#else +void DetectArmFeatures() +#endif +{ +#if defined(__linux__) && defined(__aarch64__) // ARM-64 + const unsigned long hwcaps = getauxval(AT_HWCAP); + g_hasNEON = !!(hwcaps & HWCAP_ASIMD); +# if defined(__ARM_FEATURE_CRC32) + g_hasCRC32 = !!(hwcaps & HWCAP_CRC32); +# else + g_hasCRC32 = false; +# endif +#elif defined(__linux__) // ARM-32 + const unsigned long hwcaps = getauxval(AT_HWCAP); + g_hasNEON = !!(hwcaps & HWCAP_ARM_NEON); +# if defined(__ARM_FEATURE_CRC32) + g_hasCRC32 = !!(hwcaps & HWCAP_ARM_CRC32); +# else + g_hasCRC32 = false; +# endif +#elif defined(_WIN32) && defined(_M_ARM) // Microsoft ARM + g_hasNEON = true; + g_hasCRC32 = false; +#endif + *((volatile bool*)&g_ArmDetectionDone) = true; +} + #endif NAMESPACE_END diff --git a/cpu.h b/cpu.h index ff3e39d4..ede40de9 100644 --- a/cpu.h +++ b/cpu.h @@ -1,14 +1,30 @@ // cpu.h - written and placed in the public domain by Wei Dai -//! \file -//! \headerfile cpu.h -//! \brief Classes, functions, intrinsics and features for X86, X32 nd X64 assembly +//! \file cpu.h +//! \brief Functions for CPU features and intrinsics +//! \details At the moment, the functions are used heavily in X86/X32/X64 code paths +// for SSE, SSE2 and SSE4. The funtions are also used on occassion for AArch32 +//! and AArch64 code paths for NEON. #ifndef CRYPTOPP_CPU_H #define CRYPTOPP_CPU_H #include "config.h" +#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) +# if defined(__linux__) +# include +# include +# include +# endif +# if CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE +# include +# endif +# if defined(__ARM_FEATURE_CRC32) || (__ARM_ACLE >= 200) +# include +# endif +#endif // ARM-32 or ARM-64 + #ifdef CRYPTOPP_GENERATE_X64_MASM #define CRYPTOPP_X86_ASM_AVAILABLE @@ -111,7 +127,7 @@ NAMESPACE_BEGIN(CryptoPP) #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 #define CRYPTOPP_CPUID_AVAILABLE - + // these should not be used directly extern CRYPTOPP_DLL bool g_x86DetectionDone; extern CRYPTOPP_DLL bool g_hasMMX; @@ -218,6 +234,42 @@ inline int GetCacheLineSize() return g_cacheLineSize; } +#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) + +extern bool g_ArmDetectionDone; +extern bool g_hasNEON, g_hasCRC32; +void CRYPTOPP_API DetectArmFeatures(); + +//! \brief Determine if an ARM processor has Advanced SIMD available +//! \returns true if the hardware is capable of Advanced SIMD at runtime, false otherwise. +//! \details Runtime support requires compile time support. +inline bool HasNEON() +{ + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasNEON; +} + +//! \brief Determine if an ARM processor has CRC32 available +//! \returns true if the hardware is capable of CRC32 at runtime, false otherwise. +//! \details Runtime support requires compile time support. When compiling with GCC, you may +//! need to compile with -march=armv8-a+crc. +inline bool HasCRC32() +{ + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasCRC32; +} + +//! \brief Provides the cache line size at runtime +//! \returns true if the hardware is capable of CRC32 at runtime, false otherwise. +//! \details GetCacheLineSize() provides is an estimate using CRYPTOPP_L1_CACHE_LINE_SIZE. +//! The runtime instructions to query the processor are privileged. +inline int GetCacheLineSize() +{ + return CRYPTOPP_L1_CACHE_LINE_SIZE; +} + #else inline int GetCacheLineSize() @@ -225,10 +277,12 @@ inline int GetCacheLineSize() return CRYPTOPP_L1_CACHE_LINE_SIZE; } -#endif +#endif // X86/X32/X64 and ARM #endif +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + #ifdef CRYPTOPP_GENERATE_X64_MASM #define AS1(x) x*newline* #define AS2(x, y) x, y*newline* @@ -431,6 +485,8 @@ inline int GetCacheLineSize() ASL(labelPrefix##9)\ AS2( add outputPtr, increment*16) +#endif // X86/X32/X64 + NAMESPACE_END -#endif +#endif // CRYPTOPP_CPU_H