diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2019-02-08 01:48:12 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2019-02-08 01:50:12 +0100 |
commit | ba5da0946c3abaa93d1161ca512c3c326cda3736 (patch) | |
tree | 128c238dea40ac0de0c7de8e0b02810eabc8e564 /src/Driver/Ntdriver.c | |
parent | e5b9cee8681dc45340321f759079b344a3b2676c (diff) | |
download | VeraCrypt-ba5da0946c3abaa93d1161ca512c3c326cda3736.tar.gz VeraCrypt-ba5da0946c3abaa93d1161ca512c3c326cda3736.zip |
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/Ntdriver.c')
-rw-r--r-- | src/Driver/Ntdriver.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index 7e3a08bd..9719c91b 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) { |