VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Driver/Ntdriver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Driver/Ntdriver.c')
-rw-r--r--src/Driver/Ntdriver.c60
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)
{