VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Driver
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2019-02-08 00:48:12 (GMT)
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2019-02-08 00:50:12 (GMT)
commitba5da0946c3abaa93d1161ca512c3c326cda3736 (patch)
tree128c238dea40ac0de0c7de8e0b02810eabc8e564 /src/Driver
parente5b9cee8681dc45340321f759079b344a3b2676c (diff)
downloadVeraCrypt-ba5da0946c3abaa93d1161ca512c3c326cda3736.zip
VeraCrypt-ba5da0946c3abaa93d1161ca512c3c326cda3736.tar.gz
Windows: Add implementation of ChaCha20 based random generator. Use it for driver need of random bytes (currently only wipe bytes but more to come later).
Diffstat (limited to 'src/Driver')
-rw-r--r--src/Driver/DriveFilter.c42
-rw-r--r--src/Driver/Driver.vcxproj4
-rw-r--r--src/Driver/Driver.vcxproj.filters12
-rw-r--r--src/Driver/Ntdriver.c60
-rw-r--r--src/Driver/Ntdriver.h1
5 files changed, 86 insertions, 33 deletions
diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c
index 6228009..3c7687f 100644
--- a/src/Driver/DriveFilter.c
+++ b/src/Driver/DriveFilter.c
@@ -29,6 +29,7 @@
#include "Boot/Windows/BootCommon.h"
#include "cpu.h"
#include "rdrand.h"
+#include "chachaRng.h"
static BOOL DeviceFilterActive = FALSE;
@@ -1521,42 +1522,17 @@ static VOID SetupThreadProc (PVOID threadArg)
// generate real random values for wipeRandChars and
// wipeRandCharsUpdate instead of relying on uninitialized stack memory
- LARGE_INTEGER iSeed;
- byte digest[WHIRLPOOL_DIGESTSIZE];
- WHIRLPOOL_CTX tctx;
-
-#ifndef _WIN64
- KFLOATING_SAVE floatingPointState;
- NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
- if (HasISSE())
- saveStatus = KeSaveFloatingPointState (&floatingPointState);
-#endif
+ ChaCha20RngCtx rngCtx;
+ byte pbSeed[CHACHA20RNG_KEYSZ + CHACHA20RNG_IVSZ];
- KeQuerySystemTime( &iSeed );
- WHIRLPOOL_init (&tctx);
- WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx);
- // 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);
+ GetDriverRandomSeed (pbSeed, sizeof (pbSeed));
+ ChaCha20RngInit (&rngCtx, pbSeed, GetDriverRandomSeed, 0);
-#if !defined (_WIN64)
- if (NT_SUCCESS (saveStatus))
- KeRestoreFloatingPointState (&floatingPointState);
-#endif
-
- memcpy (wipeRandChars, digest, TC_WIPE_RAND_CHAR_COUNT);
- memcpy (wipeRandCharsUpdate, &digest[WHIRLPOOL_DIGESTSIZE - TC_WIPE_RAND_CHAR_COUNT], TC_WIPE_RAND_CHAR_COUNT);
+ ChaCha20RngGetBytes (&rngCtx, wipeRandChars, TC_WIPE_RAND_CHAR_COUNT);
+ ChaCha20RngGetBytes (&rngCtx, wipeRandCharsUpdate, TC_WIPE_RAND_CHAR_COUNT);
- burn (digest, WHIRLPOOL_DIGESTSIZE);
- burn (&tctx, sizeof (tctx));
-
- burn (&iSeed, sizeof(iSeed));
+ burn (&rngCtx, sizeof (rngCtx));
+ FAST_ERASE64 (pbSeed, sizeof (pbSeed));
SetupResult = STATUS_UNSUCCESSFUL;
diff --git a/src/Driver/Driver.vcxproj b/src/Driver/Driver.vcxproj
index 894873d..7104be8 100644
--- a/src/Driver/Driver.vcxproj
+++ b/src/Driver/Driver.vcxproj
@@ -193,9 +193,13 @@ BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Cry
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\Crypto\Camellia.c" />
+ <ClCompile Include="..\Crypto\chacha-xmm.c" />
+ <ClCompile Include="..\Crypto\chacha256.c" />
+ <ClCompile Include="..\Crypto\chachaRng.c" />
<ClCompile Include="..\Crypto\rdrand.c" />
<ClCompile Include="..\Crypto\SerpentFast.c" />
<ClCompile Include="..\Crypto\SerpentFast_simd.cpp" />
+ <ClCompile Include="..\Crypto\Streebog.c" />
<ClCompile Include="DriveFilter.c" />
<ClCompile Include="DumpFilter.c" />
<ClCompile Include="EncryptedIoQueue.c" />
diff --git a/src/Driver/Driver.vcxproj.filters b/src/Driver/Driver.vcxproj.filters
index 74cd18e..20227b4 100644
--- a/src/Driver/Driver.vcxproj.filters
+++ b/src/Driver/Driver.vcxproj.filters
@@ -111,6 +111,18 @@
<ClCompile Include="..\Crypto\rdrand.c">
<Filter>Source Files\Crypto</Filter>
</ClCompile>
+ <ClCompile Include="..\Crypto\chacha256.c">
+ <Filter>Source Files\Crypto</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Crypto\chachaRng.c">
+ <Filter>Source Files\Crypto</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Crypto\chacha-xmm.c">
+ <Filter>Source Files\Crypto</Filter>
+ </ClCompile>
+ <ClCompile Include="..\Crypto\Streebog.c">
+ <Filter>Source Files\Crypto</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\Crypto\Aes_hw_cpu.asm">
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c
index 7e3a08b..9719c91 100644
--- a/src/Driver/Ntdriver.c
+++ b/src/Driver/Ntdriver.c
@@ -30,6 +30,8 @@
#include "Cache.h"
#include "Volumes.h"
#include "VolumeFilter.h"
+#include "cpu.h"
+#include "rdrand.h"
#include <tchar.h>
#include <initguid.h>
@@ -143,6 +145,64 @@ ULONG ExDefaultMdlProtection = 0;
PDEVICE_OBJECT VirtualVolumeDeviceObjects[MAX_MOUNTED_VOLUME_DRIVE_NUMBER + 1];
+void GetDriverRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed)
+{
+ LARGE_INTEGER iSeed, iSeed2;
+ byte digest[WHIRLPOOL_DIGESTSIZE];
+ WHIRLPOOL_CTX tctx;
+ size_t count;
+
+#ifndef _WIN64
+ KFLOATING_SAVE floatingPointState;
+ NTSTATUS saveStatus = STATUS_INVALID_PARAMETER;
+ if (HasISSE())
+ saveStatus = KeSaveFloatingPointState (&floatingPointState);
+#endif
+
+ while (cbRandSeed)
+ {
+ WHIRLPOOL_init (&tctx);
+ // we hash current content of digest buffer which is initialized the first time
+ WHIRLPOOL_add (digest, WHIRLPOOL_DIGESTSIZE, &tctx);
+
+ // we use various time information as source of entropy
+ KeQuerySystemTime( &iSeed );
+ WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx);
+ iSeed = KeQueryPerformanceCounter (&iSeed2);
+ WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx);
+ WHIRLPOOL_add ((unsigned char *) &(iSeed2.QuadPart), sizeof(iSeed2.QuadPart), &tctx);
+ iSeed.QuadPart = KeQueryInterruptTime ();
+ WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx);
+
+ // 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;
+ }
+
+#if !defined (_WIN64)
+ if (NT_SUCCESS (saveStatus))
+ KeRestoreFloatingPointState (&floatingPointState);
+#endif
+
+ FAST_ERASE64 (digest, sizeof (digest));
+ FAST_ERASE64 (&iSeed.QuadPart, 8);
+ FAST_ERASE64 (&iSeed2.QuadPart, 8);
+ burn (&tctx, sizeof(tctx));
+}
+
NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
diff --git a/src/Driver/Ntdriver.h b/src/Driver/Ntdriver.h
index 42b0919..2e4d655 100644
--- a/src/Driver/Ntdriver.h
+++ b/src/Driver/Ntdriver.h
@@ -191,6 +191,7 @@ void GetElapsedTimeInit (LARGE_INTEGER *lastPerfCounter);
int64 GetElapsedTime (LARGE_INTEGER *lastPerfCounter);
BOOL IsOSAtLeast (OSVersionEnum reqMinOS);
PDEVICE_OBJECT GetVirtualVolumeDeviceObject (int driveNumber);
+void GetDriverRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed);
#define TC_BUG_CHECK(status) KeBugCheckEx (SECURITY_SYSTEM, __LINE__, (ULONG_PTR) status, 0, 'VC')