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.c36
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