VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/doc/html/Hash Algorithms.html
blob: ea8c19ea01d54d44cf521563a030cdd088ec835b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>

<div>
<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>

<div id="menu">
	<ul>
	  <li><a href="Home.html">Home</a></li>
	  <li><a href="/code/">Source Code</a></li>
	  <li><a href="Downloads.html">Downloads</a></li>
	  <li><a class="active" href="Documentation.html">Documentation</a></li>
	  <li><a href="Donation.html">Donate</a></li>
	  <li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
	</ul>
</div>

<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Hash%20Algorithms.html">Hash Algorithms</a>
</p></div>

<div class="wikidoc">
<h1>Hash Algorithms</h1>
<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
In the Volume Creation Wizard, in the password change dialog window, and in the Keyfile Generator dialog window, you can select a hash algorithm. A user-selected hash algorithm is used by the VeraCrypt Random Number Generator as a pseudorandom &quot;mixing&quot; function,
 and by the header key derivation function (HMAC based on a hash function, as specified in PKCS #5 v2.0) as a pseudorandom function. When creating a new volume, the Random Number Generator generates the master key, secondary key (XTS mode), and salt. For more
 information, please see the section <a href="Random%20Number%20Generator.html" style="text-align:left; color:#0080c0; text-decoration:none.html">
Random Number Generator</a> and section <a href="Header%20Key%20Derivation.html" style="text-align:left; color:#0080c0; text-decoration:none.html">
Header Key Derivation, Salt, and Iteration Count</a>.</div>
<div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
VeraCrypt currently supports the following hash algorithms:</div>
<ul style="text-align:left; margin-top:18px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
<li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">
<a href="BLAKE2s-256.html"><strong style="text-align:left.html">BLAKE2s-256</strong></a>
</li><li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">
<a href="SHA-256.html"><strong style="text-align:left.html">SHA-256</strong></a>
</li><li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">
<a href="SHA-512.html"><strong style="text-align:left.html">SHA-512</strong></a>
</li><li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">
<a href="Whirlpool.html"><strong style="text-align:left.html">Whirlpool</strong></a>
</li><li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">
<strong style="text-align:left"><a href="Streebog.html">Streebog</a></strong>
</li></ul>
<p><a href="BLAKE2s-256.html" style="text-align:left; color:#0080c0; text-decoration:none; font-weight:bold.html">Next Section &gt;&gt;</a></p>
</div><div class="ClearBoth"></div></body></html>
} #endif // function 0 returns the highest basic function understood in EAX if(input == 0) return !!output[0]? 1 : 0; return 1; #else // longjmp and clobber warnings. Volatile is required. // http://github.com/weidai11/cryptopp/issues/24 // http://stackoverflow.com/q/7721854 volatile int result = 1; SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID); if (oldHandler == SIG_ERR) result = 0; if (setjmp(s_jmpNoCPUID)) result = 0; else { asm volatile ( // save ebx in case -fPIC is being used // TODO: this might need an early clobber on EDI. #if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" #else "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" #endif : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3]) : "a" (input), "c" (0) ); } signal(SIGILL, oldHandler); return result; #endif } #endif static int TrySSE2() { #if CRYPTOPP_BOOL_X64 return 1; #elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) && !defined(_UEFI) volatile int result = 1; #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KFLOATING_SAVE floatingPointState; if (NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))) { #endif __try { #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE AS2(por xmm0, xmm0) // executing SSE2 instruction #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE __m128i x = _mm_setzero_si128(); result = _mm_cvtsi128_si32(x) == 0 ? 1 : 0; #endif } __except (EXCEPTION_EXECUTE_HANDLER) { result = 0; } #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KeRestoreFloatingPointState (&floatingPointState); } else return 0; #endif return result; #elif !defined(_UEFI) // longjmp and clobber warnings. Volatile is required. // http://github.com/weidai11/cryptopp/issues/24 // http://stackoverflow.com/q/7721854 volatile int result = 1; SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2); if (oldHandler == SIG_ERR) return 0; if (setjmp(s_jmpNoSSE2)) result = 1; else { #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE __asm __volatile ("por %xmm0, %xmm0"); #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE __m128i x = _mm_setzero_si128(); result = _mm_cvtsi128_si32(x) == 0? 1 : 0; #endif } signal(SIGILL, oldHandler); return result; #else return 1; #endif } int g_x86DetectionDone = 0; int g_hasISSE = 0, g_hasSSE2 = 0, g_hasSSSE3 = 0, g_hasMMX = 0, g_hasAESNI = 0, g_hasCLMUL = 0, g_isP4 = 0; int g_hasAVX = 0, g_hasSSE42 = 0, g_hasSSE41 = 0; uint32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; VC_INLINE int IsIntel(const uint32 output[4]) { // This is the "GenuineIntel" string return (output[1] /*EBX*/ == 0x756e6547) && (output[2] /*ECX*/ == 0x6c65746e) && (output[3] /*EDX*/ == 0x49656e69); } 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); } #if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) static int TryAESNI () { volatile int result = 0; #ifdef _MSC_VER __try #else SigHandler oldHandler = signal(SIGILL, SigIllHandlerAESNI); if (oldHandler == SIG_ERR) return 0; if (setjmp(s_jmpNoAESNI)) result = 0; else #endif { __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); #ifdef _MSC_VER if (ciphered.m128i_u64[0] == LL(0x2f4654b9485061fa) && ciphered.m128i_u64[1] == LL(0xc8b51f1fe1256f99)) #else if (((uint64_t*)(&ciphered))[0] == LL(0x2f4654b9485061fa) && ((uint64_t*)(&ciphered))[1] == LL(0xc8b51f1fe1256f99)) #endif result = 1; } #ifdef _MSC_VER __except (EXCEPTION_EXECUTE_HANDLER) { // ignore error if AES-NI not supported } #else signal(SIGILL, oldHandler); #endif return result; } 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 hasAesNI = TryAESNI (); #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KeRestoreFloatingPointState (&floatingPointState); } #endif } return hasAesNI; } #endif void DetectX86Features() { uint32 cpuid[4], cpuid1[4]; if (!CpuId(0, cpuid)) return; if (!CpuId(1, cpuid1)) return; g_hasMMX = (cpuid1[3] & (1 << 23)) != 0; if ((cpuid1[3] & (1 << 26)) != 0) g_hasSSE2 = TrySSE2(); g_hasAVX = g_hasSSE2 && (cpuid1[2] & (1 << 28)); g_hasSSE42 = g_hasSSE2 && (cpuid1[2] & (1 << 20)); g_hasSSE41 = g_hasSSE2 && (cpuid1[2] & (1 << 19)); g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9)); g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25)); g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<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 (!g_hasAESNI && (cpuid1[2] & (1<<31))) { g_hasAESNI = Detect_MS_HyperV_AES (); } #endif if ((cpuid1[3] & (1 << 25)) != 0) g_hasISSE = 1; else { uint32 cpuid2[4]; CpuId(0x080000000, cpuid2); if (cpuid2[0] >= 0x080000001) { CpuId(0x080000001, cpuid2); g_hasISSE = (cpuid2[3] & (1 << 22)) != 0; } } if (IsIntel(cpuid)) { g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf; g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1); } else if (IsAMD(cpuid)) { CpuId(0x80000005, cpuid); g_cacheLineSize = GETBYTE(cpuid[2], 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 (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))) { bHasAESNI = Detect_MS_HyperV_AES (); } #endif } return bHasAESNI; } #endif