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();
|
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);
|
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);
|
Warning ("DISABLED_HW_AES_AFFECTS_PERFORMANCE", hwndDlg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,17 +286,20 @@
|
|||||||
|
|
||||||
; byte is_aes_hw_cpu_supported ();
|
; byte is_aes_hw_cpu_supported ();
|
||||||
|
|
||||||
export_function is_aes_hw_cpu_supported
|
; We comment this since we have an alternative C implementation
|
||||||
push %[R]bx
|
; that supports Hyper-V detection workaround
|
||||||
|
;
|
||||||
mov eax, 1
|
; export_function is_aes_hw_cpu_supported
|
||||||
cpuid
|
; push %[R]bx
|
||||||
mov eax, ecx
|
;
|
||||||
shr eax, 25
|
; mov eax, 1
|
||||||
and eax, 1
|
; cpuid
|
||||||
|
; mov eax, ecx
|
||||||
pop %[R]bx
|
; shr eax, 25
|
||||||
ret
|
; and eax, 1
|
||||||
|
;
|
||||||
|
; pop %[R]bx
|
||||||
|
; ret
|
||||||
|
|
||||||
|
|
||||||
; void aes_hw_cpu_decrypt (const byte *ks, byte *data);
|
; 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);
|
(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()
|
void DetectX86Features()
|
||||||
{
|
{
|
||||||
uint32 cpuid[4], cpuid1[4];
|
uint32 cpuid[4], cpuid1[4];
|
||||||
@@ -215,40 +256,7 @@ void DetectX86Features()
|
|||||||
// reference: http://artemonsecurity.com/vmde.pdf
|
// reference: http://artemonsecurity.com/vmde.pdf
|
||||||
if (!g_hasAESNI && (cpuid1[2] & (1<<31)))
|
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
|
g_hasAESNI = Detect_MS_HyperV_AES ();
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -282,4 +290,27 @@ void DetectX86Features()
|
|||||||
*((volatile int*)&g_x86DetectionDone) = 1;
|
*((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
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return bHasAESNI;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#ifdef TC_AES_HW_CPU
|
#ifdef TC_AES_HW_CPU
|
||||||
# include "Crypto/Aes_hw_cpu.h"
|
# include "Crypto/Aes_hw_cpu.h"
|
||||||
|
# include "Crypto/cpu.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace VeraCrypt
|
namespace VeraCrypt
|
||||||
@@ -181,7 +182,7 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
if (!stateValid)
|
if (!stateValid)
|
||||||
{
|
{
|
||||||
state = is_aes_hw_cpu_supported() ? true : false;
|
state = g_hasAESNI ? true : false;
|
||||||
stateValid = true;
|
stateValid = true;
|
||||||
}
|
}
|
||||||
return state && HwSupportEnabled;
|
return state && HwSupportEnabled;
|
||||||
|
|||||||
Reference in New Issue
Block a user