mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Crypto: Use Hyper-V AES-NI detection workaround when displaying AES hardware availability in GUI.
This commit is contained in:
@@ -5517,12 +5517,13 @@ BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP
|
||||
|
||||
|
||||
uint32 driverConfig = ReadDriverConfigurationFlags();
|
||||
int isAesHwSupported = is_aes_hw_cpu_supported();
|
||||
|
||||
SetDlgItemTextW (hwndDlg, IDC_HW_AES, (wstring (L" ") + (GetString (is_aes_hw_cpu_supported() ? ((driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? "UISTR_DISABLED" : "UISTR_YES") : "NOT_APPLICABLE_OR_NOT_AVAILABLE"))).c_str());
|
||||
SetDlgItemTextW (hwndDlg, IDC_HW_AES, (wstring (L" ") + (GetString (isAesHwSupported ? ((driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? "UISTR_DISABLED" : "UISTR_YES") : "NOT_APPLICABLE_OR_NOT_AVAILABLE"))).c_str());
|
||||
|
||||
ToHyperlink (hwndDlg, IDC_HW_AES_LABEL_LINK);
|
||||
|
||||
if (is_aes_hw_cpu_supported() && (driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION))
|
||||
if (isAesHwSupported && (driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION))
|
||||
{
|
||||
Warning ("DISABLED_HW_AES_AFFECTS_PERFORMANCE", hwndDlg);
|
||||
}
|
||||
|
||||
@@ -286,17 +286,20 @@
|
||||
|
||||
; byte is_aes_hw_cpu_supported ();
|
||||
|
||||
export_function is_aes_hw_cpu_supported
|
||||
push %[R]bx
|
||||
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov eax, ecx
|
||||
shr eax, 25
|
||||
and eax, 1
|
||||
|
||||
pop %[R]bx
|
||||
ret
|
||||
; We comment this since we have an alternative C implementation
|
||||
; that supports Hyper-V detection workaround
|
||||
;
|
||||
; export_function is_aes_hw_cpu_supported
|
||||
; push %[R]bx
|
||||
;
|
||||
; mov eax, 1
|
||||
; cpuid
|
||||
; mov eax, ecx
|
||||
; shr eax, 25
|
||||
; and eax, 1
|
||||
;
|
||||
; pop %[R]bx
|
||||
; ret
|
||||
|
||||
|
||||
; void aes_hw_cpu_decrypt (const byte *ks, byte *data);
|
||||
|
||||
@@ -192,6 +192,47 @@ VC_INLINE int IsAMD(const uint32 output[4])
|
||||
(output[3] /*EDX*/ == 0x444D4163);
|
||||
}
|
||||
|
||||
static int Detect_MS_HyperV_AES ()
|
||||
{
|
||||
int hasAesNI = 0;
|
||||
// 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];
|
||||
char HvProductName[13];
|
||||
|
||||
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
|
||||
__try
|
||||
{
|
||||
__m128i block, subkey, ciphered;
|
||||
// perform AES round.
|
||||
block = _mm_setr_epi32(0x11223344,0x55667788,0x99AABBCC,0xDDEEFF00);
|
||||
subkey = _mm_setr_epi32(0xA5A5A5A5,0xA5A5A5A5,0x5A5A5A5A,0x5A5A5A5A);
|
||||
ciphered = _mm_aesenc_si128(block, subkey);
|
||||
hasAesNI = (ciphered.m128i_u64[0] == LL(0x2f4654b9485061fa) && ciphered.m128i_u64[1] == LL(0xc8b51f1fe1256f99));
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
// ignore error if AES-NI not supported
|
||||
}
|
||||
#if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
|
||||
KeRestoreFloatingPointState (&floatingPointState);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return hasAesNI;
|
||||
}
|
||||
|
||||
void DetectX86Features()
|
||||
{
|
||||
uint32 cpuid[4], cpuid1[4];
|
||||
@@ -215,40 +256,7 @@ void DetectX86Features()
|
||||
// reference: http://artemonsecurity.com/vmde.pdf
|
||||
if (!g_hasAESNI && (cpuid1[2] & (1<<31)))
|
||||
{
|
||||
// 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 cpuid2[4];
|
||||
char HvProductName[13];
|
||||
|
||||
CpuId(0x40000000, cpuid2);
|
||||
memcpy (HvProductName, &cpuid2[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
|
||||
__try
|
||||
{
|
||||
__m128i block, subkey, ciphered;
|
||||
// perform AES round.
|
||||
block = _mm_setr_epi32(0x11223344,0x55667788,0x99AABBCC,0xDDEEFF00);
|
||||
subkey = _mm_setr_epi32(0xA5A5A5A5,0xA5A5A5A5,0x5A5A5A5A,0x5A5A5A5A);
|
||||
ciphered = _mm_aesenc_si128(block, subkey);
|
||||
g_hasAESNI = (ciphered.m128i_u64[0] == LL(0x2f4654b9485061fa) && ciphered.m128i_u64[1] == LL(0xc8b51f1fe1256f99));
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
// ignore error if AES-NI not supported
|
||||
}
|
||||
#if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
|
||||
KeRestoreFloatingPointState (&floatingPointState);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
g_hasAESNI = Detect_MS_HyperV_AES ();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -282,4 +290,27 @@ void DetectX86Features()
|
||||
*((volatile int*)&g_x86DetectionDone) = 1;
|
||||
}
|
||||
|
||||
int is_aes_hw_cpu_supported ()
|
||||
{
|
||||
int bHasAESNI = 0;
|
||||
uint32 cpuid[4];
|
||||
|
||||
if (CpuId(1, cpuid))
|
||||
{
|
||||
if (cpuid[2] & (1<<25))
|
||||
bHasAESNI = 1;
|
||||
#if (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)))
|
||||
{
|
||||
bHasAESNI = Detect_MS_HyperV_AES ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return bHasAESNI;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#ifdef TC_AES_HW_CPU
|
||||
# include "Crypto/Aes_hw_cpu.h"
|
||||
# include "Crypto/cpu.h"
|
||||
#endif
|
||||
|
||||
namespace VeraCrypt
|
||||
@@ -181,7 +182,7 @@ namespace VeraCrypt
|
||||
|
||||
if (!stateValid)
|
||||
{
|
||||
state = is_aes_hw_cpu_supported() ? true : false;
|
||||
state = g_hasAESNI ? true : false;
|
||||
stateValid = true;
|
||||
}
|
||||
return state && HwSupportEnabled;
|
||||
|
||||
Reference in New Issue
Block a user