diff options
Diffstat (limited to 'src/Crypto/cpu.c')
-rw-r--r-- | src/Crypto/cpu.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c index effde6ba..174596eb 100644 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -17,6 +17,10 @@ #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]) @@ -207,6 +211,7 @@ 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]) @@ -306,6 +311,35 @@ static int Detect_MS_HyperV_AES () #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}; @@ -334,6 +368,7 @@ void DetectX86Features() 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 @@ -439,6 +474,7 @@ void DisableCPUExtendedFeatures () g_hasSSSE3 = 0; g_hasAESNI = 0; g_hasCLMUL = 0; + g_hasSHA256 = 0; } #endif |