diff options
Diffstat (limited to 'src/Crypto/cpu.c')
-rw-r--r-- | src/Crypto/cpu.c | 137 |
1 files changed, 116 insertions, 21 deletions
diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c index effde6ba..a5b5bb19 100644 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -15,10 +15,14 @@ #include <setjmp.h> #endif #ifdef CRYPTOPP_CPUID_AVAILABLE +#if defined(__GNUC__) || defined(__clang__) + #include <cpuid.h> // for __get_cpuid and __get_cpuid_count +#endif + #if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 int CpuId(uint32 input, uint32 output[4]) { __cpuid((int *)output, input); @@ -134,15 +138,10 @@ static int TrySSE2() { #if CRYPTOPP_BOOL_X64 return 1; #elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) && !defined(_UEFI) volatile int result = 1; -#if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - if (NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))) - { -#endif __try { #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE AS2(por xmm0, xmm0) // executing SSE2 instruction #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE @@ -152,16 +151,10 @@ static int TrySSE2() } __except (EXCEPTION_EXECUTE_HANDLER) { result = 0; } -#if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) - KeRestoreFloatingPointState (&floatingPointState); - } - else - return 0; -#endif return result; #elif !defined(_UEFI) // longjmp and clobber warnings. Volatile is required. // http://github.com/weidai11/cryptopp/issues/24 // http://stackoverflow.com/q/7721854 @@ -205,10 +198,11 @@ static uint64 xgetbv() volatile int g_x86DetectionDone = 0; volatile int g_hasISSE = 0, g_hasSSE2 = 0, g_hasSSSE3 = 0, g_hasMMX = 0, g_hasAESNI = 0, g_hasCLMUL = 0, g_isP4 = 0; volatile int g_hasAVX = 0, g_hasAVX2 = 0, g_hasBMI2 = 0, g_hasSSE42 = 0, g_hasSSE41 = 0, g_isIntel = 0, g_isAMD = 0; volatile int g_hasRDRAND = 0, g_hasRDSEED = 0; +volatile int g_hasSHA256 = 0; volatile uint32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; VC_INLINE int IsIntel(const uint32 output[4]) { // This is the "GenuineIntel" string @@ -286,28 +280,51 @@ static int Detect_MS_HyperV_AES () CpuId(0x40000000, cpuid); memcpy (HvProductName, &cpuid[1], 12); HvProductName[12] = 0; if (_stricmp(HvProductName, "Microsoft Hv") == 0) { -#if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - if (NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))) - { -#endif hasAesNI = TryAESNI (); - -#if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) - KeRestoreFloatingPointState (&floatingPointState); - } -#endif } return hasAesNI; } #endif +#if defined(__SHA__) || defined(__INTEL_COMPILER) || CRYPTOPP_SHANI_AVAILABLE +extern int TrySHA256(); +#endif + +static BOOL CheckSHA256Support() { +#if CRYPTOPP_BOOL_X64 && CRYPTOPP_SHANI_AVAILABLE +#if defined(_MSC_VER) // Windows with MSVC + int cpuInfo[4] = { 0 }; + __cpuidex(cpuInfo, 7, 0); + return (cpuInfo[1] & (1 << 29)) != 0? TRUE : FALSE; + +#elif defined(__GNUC__) || defined(__clang__) // Linux, FreeBSD, macOS with GCC/Clang + unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0; + // First check if CPUID leaf 7 is supported + if (__get_cpuid(0, &eax, &ebx, &ecx, &edx)) { + if (eax >= 7) { + // Now check SHA-256 support in leaf 7, sub-leaf 0 + if (__get_cpuid_count(7, 0, &eax, &ebx, &ecx, &edx)) { + return (ebx & (1 << 29)) != 0? TRUE : FALSE; + } + } + } + return FALSE; + +#else + #error "Unsupported compiler" +#endif +#else + return FALSE; +#endif +} + + void DetectX86Features() { uint32 cpuid[4] = {0}, cpuid1[4] = {0}, cpuid2[4] = {0}; if (!CpuId(0, cpuid)) return; @@ -332,20 +349,28 @@ void DetectX86Features() g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9)); #ifndef CRYPTOPP_DISABLE_AESNI g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25)); #endif g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1)); + g_hasSHA256 = CheckSHA256Support(); #if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) // Hypervisor = bit 31 of ECX of CPUID leaf 0x1 // reference: http://artemonsecurity.com/vmde.pdf if (!g_hasAESNI && (cpuid1[2] & (1<<31))) { g_hasAESNI = Detect_MS_HyperV_AES (); } #endif +#if defined(__SHA__) || defined(__INTEL_COMPILER) || CRYPTOPP_SHANI_AVAILABLE + if (!g_hasSHA256) + { + g_hasSHA256 = TrySHA256(); + } +#endif + if ((cpuid1[3] & (1 << 25)) != 0) g_hasISSE = 1; else { CpuId(0x080000000, cpuid2); @@ -437,9 +462,79 @@ void DisableCPUExtendedFeatures () g_hasSSE42 = 0; g_hasSSE41 = 0; g_hasSSSE3 = 0; g_hasAESNI = 0; g_hasCLMUL = 0; + g_hasSHA256 = 0; +} + +#endif + +#if CRYPTOPP_BOOL_ARMV8 +#if defined(__linux__) && defined(__aarch64__) +#include <sys/auxv.h> +#ifndef HWCAP_AES +# define HWCAP_AES (1 << 3) +#endif +#ifndef HWCAP_SHA2 +# define HWCAP_SHA2 (1 << 6) +#endif +#endif + +volatile int g_hasAESARM = 0; +volatile int g_hasSHA256ARM = 0; + +inline int CPU_QueryAES() +{ +#if defined(CRYPTOPP_ARM_AES_AVAILABLE) +#if defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_AES) != 0) + return 1; +#elif defined(__APPLE__) && defined(__aarch64__) + // Apple Sillcon (M1) and later + return 1; +#elif defined(_WIN32) && defined(_M_ARM64) +#ifdef TC_WINDOWS_DRIVER + if (ExIsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return 1; +#else + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return 1; +#endif +#endif + return 0; +#else + return 0; +#endif } +inline int CPU_QuerySHA2() +{ +#if defined(CRYPTOPP_ARM_SHA2_AVAILABLE) +#if defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_SHA2) != 0) + return 1; +#elif defined(__APPLE__) && defined(__aarch64__) + // Apple Sillcon (M1) and later + return 1; +#elif defined(_WIN32) && defined(_M_ARM64) +#ifdef TC_WINDOWS_DRIVER + if (ExIsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return 1; +#else + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return 1; +#endif +#endif + return 0; +#else + return 0; #endif +} + +void DetectArmFeatures() +{ + g_hasAESARM = CPU_QueryAES(); + g_hasSHA256ARM = CPU_QuerySHA2(); +} +#endif
\ No newline at end of file |