VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2019-03-02 10:14:21 +0100
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2019-03-02 10:23:39 +0100
commit321715202aed04dd9892d1c0686d080763ab212d (patch)
tree770d69a4a7bbb992ab0aaf4cb4625e07d2a5255b
parentedd1b00126fa39396fbb76c73cc3ea17aa955fc8 (diff)
downloadVeraCrypt-321715202aed04dd9892d1c0686d080763ab212d.tar.gz
VeraCrypt-321715202aed04dd9892d1c0686d080763ab212d.zip
Windows: Generalize RAM encryption for keys to VeraCrypt binaries, especially Format and Expander
-rw-r--r--src/Common/Crypto.c10
-rw-r--r--src/Common/Crypto.h9
-rw-r--r--src/Common/Dlgcode.c82
-rw-r--r--src/Common/Dlgcode.h3
-rw-r--r--src/Common/EncryptionThreadPool.c2
-rw-r--r--src/Common/Format.c7
-rw-r--r--src/Common/Tcdefs.h3
-rw-r--r--src/Common/Tests.c5
-rw-r--r--src/Crypto/Crypto.vcxproj6
-rw-r--r--src/Crypto/Crypto.vcxproj.filters18
-rw-r--r--src/ExpandVolume/ExpandVolume.c7
-rw-r--r--src/Format/InPlace.c41
12 files changed, 187 insertions, 6 deletions
diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c
index 6a918953..501cd165 100644
--- a/src/Common/Crypto.c
+++ b/src/Common/Crypto.c
@@ -1295,7 +1295,7 @@ byte GetRandomIndex (ChaCha20RngCtx* pCtx, byte elementsCount)
return index;
}
-#if defined(_WIN64) && !defined (_UEFI) && defined(TC_WINDOWS_DRIVER)
+#if defined(_WIN64) && !defined (_UEFI)
/* declaration of variables and functions used for RAM encryption on 64-bit build */
static byte* pbKeyDerivationArea = NULL;
static ULONG cbKeyDerivationArea = 0;
@@ -1306,15 +1306,19 @@ static uint64 CipherIVMask = 0;
ULONG AllocTag = 'MMCV';
#endif
+#if !defined(PAGE_SIZE)
+#define PAGE_SIZE 4096
+#endif
+
BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback)
{
ChaCha20RngCtx ctx;
byte pbSeed[CHACHA20RNG_KEYSZ + CHACHA20RNG_IVSZ];
#ifdef TC_WINDOWS_DRIVER
byte i, tagLength;
-#endif
Dump ("InitializeSecurityParameters BEGIN\n");
+#endif
rngCallback (pbSeed, sizeof (pbSeed));
@@ -1362,9 +1366,11 @@ BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback)
FAST_ERASE64 (pbSeed, sizeof (pbSeed));
burn (&ctx, sizeof (ctx));
+#ifdef TC_WINDOWS_DRIVER
burn (&tagLength, 1);
Dump ("InitializeSecurityParameters return=TRUE END\n");
+#endif
return TRUE;
}
diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h
index 5a8724f6..600fee92 100644
--- a/src/Common/Crypto.h
+++ b/src/Common/Crypto.h
@@ -385,10 +385,17 @@ void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *s
void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo);
void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo);
-#if defined(_WIN64) && !defined (_UEFI) && defined(TC_WINDOWS_DRIVER)
+#if defined(_WIN64) && !defined (_UEFI)
BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback);
void ClearSecurityParameters();
+#ifdef TC_WINDOWS_DRIVER
void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData, unsigned char* pbData2, size_t cbData2);
+#else
+void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData,
+ unsigned char* pbData2, size_t cbData2,
+ unsigned char* pbData3, size_t cbData3,
+ unsigned char* pbData4, size_t cbData4);
+#endif
uint64 VcGetEncryptionID (PCRYPTO_INFO pCryptoInfo);
void VcProtectKeys (PCRYPTO_INFO pCryptoInfo, uint64 encID);
void VcUnprotectKeys (PCRYPTO_INFO pCryptoInfo, uint64 encID);
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 3d8ee6fc..6d6ed69b 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -60,6 +60,8 @@
#include "Boot/Windows/BootCommon.h"
#include "Progress.h"
#include "zip.h"
+#include "rdrand.h"
+#include "jitterentropy.h"
#ifdef TCMOUNT
#include "Mount/Mount.h"
@@ -3203,6 +3205,17 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
InitHelpFileName ();
#ifndef SETUP
+#ifdef _WIN64
+ if (IsOSAtLeast (WIN_7))
+ {
+ EnableRamEncryption ((ReadDriverConfigurationFlags() & VC_DRIVER_CONFIG_ENABLE_RAM_ENCRYPTION) ? TRUE : FALSE);
+ if (IsRamEncryptionEnabled())
+ {
+ if (!InitializeSecurityParameters(GetAppRandomSeed))
+ AbortProcess("OUTOFMEMORY");
+ }
+ }
+#endif
if (!EncryptionThreadPoolStart (ReadEncryptionThreadPoolFreeCpuCountLimit()))
{
handleWin32Error (NULL, SRC_POS);
@@ -13894,3 +13907,72 @@ BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void
return bRet;
}
+
+#if !defined(SETUP) && defined(_WIN64)
+
+#define RtlGenRandom SystemFunction036
+extern "C" BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+
+void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed)
+{
+ LARGE_INTEGER iSeed;
+ SYSTEMTIME sysTime;
+ byte digest[WHIRLPOOL_DIGESTSIZE];
+ WHIRLPOOL_CTX tctx;
+ size_t count;
+
+ while (cbRandSeed)
+ {
+ WHIRLPOOL_init (&tctx);
+ // we hash current content of digest buffer which is uninitialized the first time
+ WHIRLPOOL_add (digest, WHIRLPOOL_DIGESTSIZE, &tctx);
+
+ // we use various time information as source of entropy
+ GetSystemTime (&sysTime);
+ WHIRLPOOL_add ((unsigned char *) &sysTime, sizeof(sysTime), &tctx);
+ if (QueryPerformanceCounter (&iSeed))
+ WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx);
+ if (QueryPerformanceFrequency (&iSeed))
+ WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx);
+
+ /* use Windows random generator as entropy source */
+ if (RtlGenRandom (digest, sizeof (digest)))
+ WHIRLPOOL_add (digest, sizeof(digest), &tctx);
+
+ /* use JitterEntropy library to get good quality random bytes based on CPU timing jitter */
+ if (0 == jent_entropy_init ())
+ {
+ struct rand_data *ec = jent_entropy_collector_alloc (1, 0);
+ if (ec)
+ {
+ ssize_t rndLen = jent_read_entropy (ec, (char*) digest, sizeof (digest));
+ if (rndLen > 0)
+ WHIRLPOOL_add (digest, (unsigned int) rndLen, &tctx);
+ jent_entropy_collector_free (ec);
+ }
+ }
+
+ // use RDSEED or RDRAND from CPU as source of entropy if enabled
+ if ( IsCpuRngEnabled() &&
+ ( (HasRDSEED() && RDSEED_getBytes (digest, sizeof (digest)))
+ || (HasRDRAND() && RDRAND_getBytes (digest, sizeof (digest)))
+ ))
+ {
+ WHIRLPOOL_add (digest, sizeof(digest), &tctx);
+ }
+ WHIRLPOOL_finalize (&tctx, digest);
+
+ count = VC_MIN (cbRandSeed, sizeof (digest));
+
+ // copy digest value to seed buffer
+ memcpy (pbRandSeed, digest, count);
+ cbRandSeed -= count;
+ pbRandSeed += count;
+ }
+
+ FAST_ERASE64 (digest, sizeof (digest));
+ FAST_ERASE64 (&iSeed.QuadPart, 8);
+ burn (&sysTime, sizeof(sysTime));
+ burn (&tctx, sizeof(tctx));
+}
+#endif
diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h
index e97e50cf..8a75f264 100644
--- a/src/Common/Dlgcode.h
+++ b/src/Common/Dlgcode.h
@@ -537,6 +537,9 @@ BOOL VerifyModuleSignature (const wchar_t* path);
void GetInstallationPath (HWND hwndDlg, wchar_t* szInstallPath, DWORD cchSize, BOOL* pbInstallPathDetermined);
BOOL GetSetupconfigLocation (wchar_t* path, DWORD cchSize);
BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void* pattern, size_t patternLen);
+#ifdef _WIN64
+void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed);
+#endif
#ifdef __cplusplus
}
diff --git a/src/Common/EncryptionThreadPool.c b/src/Common/EncryptionThreadPool.c
index fdf1101c..461f2847 100644
--- a/src/Common/EncryptionThreadPool.c
+++ b/src/Common/EncryptionThreadPool.c
@@ -111,7 +111,7 @@ static TC_MUTEX DequeueMutex;
static TC_EVENT WorkItemReadyEvent;
static TC_EVENT WorkItemCompletedEvent;
-#if defined(_WIN64) && defined(TC_WINDOWS_DRIVER)
+#if defined(_WIN64)
void EncryptDataUnitsCurrentThreadEx (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
if (IsRamEncryptionEnabled())
diff --git a/src/Common/Format.c b/src/Common/Format.c
index b67ac511..bd33f754 100644
--- a/src/Common/Format.c
+++ b/src/Common/Format.c
@@ -171,6 +171,13 @@ int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams)
return nStatus? nStatus : ERR_OUTOFMEMORY;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VcProtectKeys (cryptoInfo, VcGetEncryptionID (cryptoInfo));
+ }
+#endif
+
begin_format:
if (volParams->bDevice)
diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h
index ec1df6a4..ed7b330e 100644
--- a/src/Common/Tcdefs.h
+++ b/src/Common/Tcdefs.h
@@ -343,6 +343,9 @@ extern VOID NTAPI KeRestoreExtendedProcessorState (
# define Dump(...)
# define DumpMem(...)
# endif
+#elif !defined (TC_WINDOWS_BOOT)
+# define Dump(...)
+# define DumpMem(...)
#endif
#if !defined (trace_msg) && !defined (TC_WINDOWS_BOOT)
diff --git a/src/Common/Tests.c b/src/Common/Tests.c
index be0018a8..0af4313e 100644
--- a/src/Common/Tests.c
+++ b/src/Common/Tests.c
@@ -720,6 +720,11 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci)
if (!EAInitMode (ci, key2))
return FALSE;
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ VcProtectKeys (ci, VcGetEncryptionID (ci));
+#endif
+
// Each data unit will contain the same plaintext
for (i = 0; i < nbrUnits; i++)
{
diff --git a/src/Crypto/Crypto.vcxproj b/src/Crypto/Crypto.vcxproj
index 9f351bee..027a87e0 100644
--- a/src/Crypto/Crypto.vcxproj
+++ b/src/Crypto/Crypto.vcxproj
@@ -232,6 +232,9 @@
<ClCompile Include="SerpentFast_simd.cpp" />
<ClCompile Include="Sha2.c" />
<ClCompile Include="Streebog.c" />
+ <ClCompile Include="t1ha2.c" />
+ <ClCompile Include="t1ha2_selfcheck.c" />
+ <ClCompile Include="t1ha_selfcheck.c" />
<ClCompile Include="Twofish.c" />
<ClCompile Include="Whirlpool.c" />
</ItemGroup>
@@ -258,6 +261,9 @@
<ClInclude Include="SerpentFast_sbox.h" />
<ClInclude Include="Sha2.h" />
<ClInclude Include="Streebog.h" />
+ <ClInclude Include="t1ha.h" />
+ <ClInclude Include="t1ha_bits.h" />
+ <ClInclude Include="t1ha_selfcheck.h" />
<ClInclude Include="Twofish.h" />
<ClInclude Include="Whirlpool.h" />
</ItemGroup>
diff --git a/src/Crypto/Crypto.vcxproj.filters b/src/Crypto/Crypto.vcxproj.filters
index 7a8da57e..e7b3c3a5 100644
--- a/src/Crypto/Crypto.vcxproj.filters
+++ b/src/Crypto/Crypto.vcxproj.filters
@@ -72,6 +72,15 @@
<ClCompile Include="jitterentropy-base.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="t1ha_selfcheck.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="t1ha2.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="t1ha2_selfcheck.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Aes.h">
@@ -146,6 +155,15 @@
<ClInclude Include="jitterentropy-base-user.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="t1ha.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="t1ha_bits.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="t1ha_selfcheck.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="Aes_hw_cpu.asm">
diff --git a/src/ExpandVolume/ExpandVolume.c b/src/ExpandVolume/ExpandVolume.c
index 0a9733a4..5a476ba3 100644
--- a/src/ExpandVolume/ExpandVolume.c
+++ b/src/ExpandVolume/ExpandVolume.c
@@ -672,6 +672,13 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas
goto error;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled())
+ {
+ VcProtectKeys (cryptoInfo, VcGetEncryptionID (cryptoInfo));
+ }
+#endif
+
if (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM)
{
nStatus = ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG;
diff --git a/src/Format/InPlace.c b/src/Format/InPlace.c
index b2f1b386..7117a8a4 100644
--- a/src/Format/InPlace.c
+++ b/src/Format/InPlace.c
@@ -869,6 +869,13 @@ int EncryptPartitionInPlaceResume (HANDLE dev,
if (nStatus != ERR_SUCCESS)
goto closing_seq;
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VcProtectKeys (masterCryptoInfo, VcGetEncryptionID (masterCryptoInfo));
+ VcProtectKeys (headerCryptoInfo, VcGetEncryptionID (headerCryptoInfo));
+ }
+#endif
remainingBytes = masterCryptoInfo->VolumeSize.Value - masterCryptoInfo->EncryptedAreaLength.Value;
@@ -1389,6 +1396,13 @@ int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile
if (nStatus != ERR_SUCCESS)
goto closing_seq;
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VcProtectKeys (masterCryptoInfo, VcGetEncryptionID (masterCryptoInfo));
+ VcProtectKeys (headerCryptoInfo, VcGetEncryptionID (headerCryptoInfo));
+ }
+#endif
if (masterCryptoInfo->LegacyVolume)
{
@@ -1784,6 +1798,7 @@ int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_IN
DWORD dwError;
uint32 headerCrc32;
byte *fieldPos;
+ PCRYPTO_INFO pCryptoInfo = headerCryptoInfo;
header = (byte *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE);
@@ -1804,8 +1819,23 @@ int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_IN
goto closing_seq;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled())
+ {
+ pCryptoInfo = crypto_open();
+ if (!pCryptoInfo)
+ {
+ nStatus = ERR_OUTOFMEMORY;
+ goto closing_seq;
+ }
+
+ memcpy (pCryptoInfo, headerCryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (pCryptoInfo, VcGetEncryptionID (headerCryptoInfo));
+ }
+#endif
+
- DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
+ DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, pCryptoInfo);
if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241)
{
@@ -1828,7 +1858,7 @@ int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_IN
fieldPos = (byte *) header + TC_HEADER_OFFSET_HEADER_CRC;
mputLong (fieldPos, headerCrc32);
- EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
+ EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, pCryptoInfo);
if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0
@@ -1843,6 +1873,13 @@ closing_seq:
dwError = GetLastError();
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled() && pCryptoInfo)
+ {
+ crypto_close(pCryptoInfo);
+ }
+#endif
+
burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
TCfree (header);