diff options
Diffstat (limited to 'src/Crypto/cpu.c')
-rw-r--r-- | src/Crypto/cpu.c | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c index b8316962..effde6ba 100644 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -2,6 +2,9 @@ #include "cpu.h" #include "misc.h" +#if defined(_MSC_VER) && !defined(_UEFI) +#include "rdrand.h" +#endif #ifndef EXCEPTION_EXECUTE_HANDLER #define EXCEPTION_EXECUTE_HANDLER 1 @@ -218,8 +221,8 @@ VC_INLINE int IsAMD(const uint32 output[4]) { // This is the "AuthenticAMD" string return (output[1] /*EBX*/ == 0x68747541) && - (output[2] /*ECX*/ == 0x69746E65) && - (output[3] /*EDX*/ == 0x444D4163); + (output[2] /*ECX*/ == 0x444D4163) && + (output[3] /*EDX*/ == 0x69746E65); } VC_INLINE int IsHygon(const uint32 output[4]) @@ -277,7 +280,7 @@ static int Detect_MS_HyperV_AES () // when Hyper-V is enabled on older versions of Windows Server (i.e. 2008 R2), the AES-NI capability // gets masked out for all applications, even running on the host. // We try to detect Hyper-V virtual CPU and perform a dummy AES-NI operation to check its real presence - uint32 cpuid[4]; + uint32 cpuid[4] = {0}; char HvProductName[13]; CpuId(0x40000000, cpuid); @@ -327,7 +330,9 @@ void DetectX86Features() g_hasSSE42 = g_hasSSE2 && (cpuid1[2] & (1 << 20)); g_hasSSE41 = g_hasSSE2 && (cpuid1[2] & (1 << 19)); 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)); #if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) @@ -343,7 +348,6 @@ void DetectX86Features() g_hasISSE = 1; else { - uint32 cpuid2[4]; CpuId(0x080000000, cpuid2); if (cpuid2[0] >= 0x080000001) { @@ -386,33 +390,37 @@ void DetectX86Features() } } } +#if defined(_MSC_VER) && !defined(_UEFI) + /* Add check fur buggy RDRAND (AMD Ryzen case) even if we always use RDSEED instead of RDRAND when RDSEED available */ + if (g_hasRDRAND) + { + if ( RDRAND_getBytes ((unsigned char*) cpuid, sizeof (cpuid)) + && (cpuid[0] == 0xFFFFFFFF) && (cpuid[1] == 0xFFFFFFFF) + && (cpuid[2] == 0xFFFFFFFF) && (cpuid[3] == 0xFFFFFFFF) + ) + { + g_hasRDRAND = 0; + g_hasRDSEED = 0; + } + } - if (!g_cacheLineSize) - g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - - *((volatile int*)&g_x86DetectionDone) = 1; -} - -int is_aes_hw_cpu_supported () -{ - int bHasAESNI = 0; - uint32 cpuid[4]; - - if (CpuId(1, cpuid)) + if (g_hasRDSEED) { - if (cpuid[2] & (1<<25)) - bHasAESNI = 1; -#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 (!bHasAESNI && (cpuid[2] & (1<<31))) + if ( RDSEED_getBytes ((unsigned char*) cpuid, sizeof (cpuid)) + && (cpuid[0] == 0xFFFFFFFF) && (cpuid[1] == 0xFFFFFFFF) + && (cpuid[2] == 0xFFFFFFFF) && (cpuid[3] == 0xFFFFFFFF) + ) { - bHasAESNI = Detect_MS_HyperV_AES (); + g_hasRDRAND = 0; + g_hasRDSEED = 0; } -#endif } +#endif - return bHasAESNI; + if (!g_cacheLineSize) + g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + + *((volatile int*)&g_x86DetectionDone) = 1; } void DisableCPUExtendedFeatures () |