VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Crypto/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Crypto/cpu.c')
-rw-r--r--src/Crypto/cpu.c58
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 ()