mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 02:58:02 -06:00
Windows: use modern API to gather system entropy for random generation instead of obsolete that were not working
This commit increases randomness quality by using more dynamic/varied sources of entropy. PDH-based disk and network statistics collection in now added to random pool - Introduced `GetDiskStatistics` to gather disk read/write performance data using PDH API. - Introduced `GetNetworkStatistics` to gather network send/receive performance data using PDH API. - Integrated high-resolution timestamps and random intervals to improve entropy in collected data. - Updated `SlowPoll` function to utilize PDH-based disk and network statistics. - Removed obsolete NetAPI32-based network statistics collection.
This commit is contained in:
@@ -20,6 +20,8 @@
|
|||||||
#include "Crypto\rdrand.h"
|
#include "Crypto\rdrand.h"
|
||||||
#include <Strsafe.h>
|
#include <Strsafe.h>
|
||||||
#include <bcrypt.h>
|
#include <bcrypt.h>
|
||||||
|
#include <pdh.h>
|
||||||
|
#include <pdhmsg.h>
|
||||||
|
|
||||||
static unsigned __int8 buffer[RNG_POOL_SIZE];
|
static unsigned __int8 buffer[RNG_POOL_SIZE];
|
||||||
static unsigned char *pRandPool = NULL;
|
static unsigned char *pRandPool = NULL;
|
||||||
@@ -82,15 +84,45 @@ DWORD ProcessedMouseEventsCounter = 0;
|
|||||||
CRITICAL_SECTION critRandProt; /* The critical section */
|
CRITICAL_SECTION critRandProt; /* The critical section */
|
||||||
BOOL volatile bThreadTerminate = FALSE; /* This variable is shared among thread's so its made volatile */
|
BOOL volatile bThreadTerminate = FALSE; /* This variable is shared among thread's so its made volatile */
|
||||||
|
|
||||||
/* Network library handle for the SlowPoll function */
|
|
||||||
HANDLE hNetAPI32 = NULL;
|
|
||||||
|
|
||||||
// CryptoAPI
|
// CryptoAPI
|
||||||
DWORD CryptoAPILastError = ERROR_SUCCESS;
|
DWORD CryptoAPILastError = ERROR_SUCCESS;
|
||||||
|
|
||||||
typedef DWORD (WINAPI *RtlNtStatusToDosError_t)(NTSTATUS);
|
typedef DWORD (WINAPI *RtlNtStatusToDosError_t)(NTSTATUS);
|
||||||
RtlNtStatusToDosError_t pRtlNtStatusToDosError = NULL;
|
RtlNtStatusToDosError_t pRtlNtStatusToDosError = NULL;
|
||||||
|
|
||||||
|
static HMODULE hPdhLib = NULL;
|
||||||
|
|
||||||
|
typedef PDH_STATUS (WINAPI *PfnPdhOpenQueryW)(LPCWSTR, DWORD_PTR, PDH_HQUERY *);
|
||||||
|
typedef PDH_STATUS (WINAPI *PfnPdhAddCounterW)(PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER *);
|
||||||
|
typedef PDH_STATUS (WINAPI *PfnPdhCollectQueryData)(PDH_HQUERY);
|
||||||
|
typedef PDH_STATUS (WINAPI *PfnPdhGetFormattedCounterValue)(PDH_HCOUNTER, DWORD, LPDWORD, PPDH_FMT_COUNTERVALUE);
|
||||||
|
typedef PDH_STATUS (WINAPI *PfnPdhCloseQuery)(PDH_HQUERY);
|
||||||
|
|
||||||
|
static PfnPdhOpenQueryW pfnPdhOpenQuery = NULL;
|
||||||
|
static PfnPdhAddCounterW pfnPdhAddCounter = NULL;
|
||||||
|
static PfnPdhCollectQueryData pfnPdhCollectQueryData = NULL;
|
||||||
|
static PfnPdhGetFormattedCounterValue pfnPdhGetFormattedCounterValue = NULL;
|
||||||
|
static PfnPdhCloseQuery pfnPdhCloseQuery = NULL;
|
||||||
|
|
||||||
|
static BOOL LoadPdhDll()
|
||||||
|
{
|
||||||
|
if (!hPdhLib)
|
||||||
|
{
|
||||||
|
hPdhLib = LoadLibraryExW(L"pdh.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||||
|
if (!hPdhLib)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pfnPdhOpenQuery = (PfnPdhOpenQueryW) GetProcAddress(hPdhLib, "PdhOpenQueryW");
|
||||||
|
pfnPdhAddCounter = (PfnPdhAddCounterW) GetProcAddress(hPdhLib, "PdhAddCounterW");
|
||||||
|
pfnPdhCollectQueryData = (PfnPdhCollectQueryData) GetProcAddress(hPdhLib, "PdhCollectQueryData");
|
||||||
|
pfnPdhGetFormattedCounterValue = (PfnPdhGetFormattedCounterValue) GetProcAddress(hPdhLib, "PdhGetFormattedCounterValue");
|
||||||
|
pfnPdhCloseQuery = (PfnPdhCloseQuery) GetProcAddress(hPdhLib, "PdhCloseQuery");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pfnPdhOpenQuery && pfnPdhAddCounter && pfnPdhCollectQueryData &&
|
||||||
|
pfnPdhGetFormattedCounterValue && pfnPdhCloseQuery);
|
||||||
|
}
|
||||||
|
|
||||||
/* Init the random number generator, setup the hooks, and start the thread */
|
/* Init the random number generator, setup the hooks, and start the thread */
|
||||||
int RandinitWithCheck ( int* pAlreadyInitialized)
|
int RandinitWithCheck ( int* pAlreadyInitialized)
|
||||||
{
|
{
|
||||||
@@ -191,12 +223,6 @@ void RandStop (BOOL freePool)
|
|||||||
if (PeriodicFastPollThreadHandle)
|
if (PeriodicFastPollThreadHandle)
|
||||||
WaitForSingleObject (PeriodicFastPollThreadHandle, INFINITE);
|
WaitForSingleObject (PeriodicFastPollThreadHandle, INFINITE);
|
||||||
|
|
||||||
if (hNetAPI32 != 0)
|
|
||||||
{
|
|
||||||
FreeLibrary (hNetAPI32);
|
|
||||||
hNetAPI32 = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hMouse = NULL;
|
hMouse = NULL;
|
||||||
hKeyboard = NULL;
|
hKeyboard = NULL;
|
||||||
@@ -254,7 +280,7 @@ BOOL Randmix ()
|
|||||||
if (bRandmixEnabled)
|
if (bRandmixEnabled)
|
||||||
{
|
{
|
||||||
unsigned char hashOutputBuffer [MAX_DIGESTSIZE];
|
unsigned char hashOutputBuffer [MAX_DIGESTSIZE];
|
||||||
#ifndef WOLFCRYPT_BACKEND
|
#ifndef WOLFCRYPT_BACKEND
|
||||||
WHIRLPOOL_CTX wctx;
|
WHIRLPOOL_CTX wctx;
|
||||||
blake2s_state bctx;
|
blake2s_state bctx;
|
||||||
STREEBOG_CTX stctx;
|
STREEBOG_CTX stctx;
|
||||||
@@ -273,11 +299,11 @@ BOOL Randmix ()
|
|||||||
digestSize = SHA256_DIGESTSIZE;
|
digestSize = SHA256_DIGESTSIZE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifndef WOLFCRYPT_BACKEND
|
#ifndef WOLFCRYPT_BACKEND
|
||||||
case BLAKE2S:
|
case BLAKE2S:
|
||||||
digestSize = BLAKE2S_DIGESTSIZE;
|
digestSize = BLAKE2S_DIGESTSIZE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WHIRLPOOL:
|
case WHIRLPOOL:
|
||||||
digestSize = WHIRLPOOL_DIGESTSIZE;
|
digestSize = WHIRLPOOL_DIGESTSIZE;
|
||||||
break;
|
break;
|
||||||
@@ -640,142 +666,192 @@ static unsigned __stdcall PeriodicFastPollThreadProc (void *dummy)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type definitions for function pointers to call NetAPI32 functions */
|
|
||||||
|
|
||||||
typedef
|
/* -------------------------------------------------------------------------------------
|
||||||
DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
|
GetDiskStatistics: This function uses the Windows Performance Data Helper (PDH) API
|
||||||
DWORD dwLevel, DWORD dwOptions,
|
to collect disk statistics. The function collects the number of disk reads and writes
|
||||||
LPBYTE * lpBuffer);
|
per second for all physical disks. The function also collects high-resolution
|
||||||
typedef
|
timestamps before and after the PDH query. The function then adds the collected data
|
||||||
DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
|
to the random pool.
|
||||||
typedef
|
The code waits a short random interval between the two PDH samples to ensures that
|
||||||
DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
|
the performance counters have time to accumulate measurable changes and produce more
|
||||||
|
varied data.
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
NETSTATISTICSGET pNetStatisticsGet = NULL;
|
*/
|
||||||
NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
|
void GetDiskStatistics()
|
||||||
NETAPIBUFFERFREE pNetApiBufferFree = NULL;
|
{
|
||||||
|
if (!LoadPdhDll())
|
||||||
|
return;
|
||||||
|
PDH_STATUS status;
|
||||||
|
PDH_HQUERY query = NULL;
|
||||||
|
PDH_HCOUNTER counterReads = NULL, counterWrites = NULL;
|
||||||
|
PDH_FMT_COUNTERVALUE counterValue;
|
||||||
|
DWORD dwType;
|
||||||
|
LONGLONG llReads = 0, llWrites = 0;
|
||||||
|
DWORDLONG tstampBefore = 0, tstampAfter = 0;
|
||||||
|
LARGE_INTEGER perfCounterBefore, perfCounterAfter;
|
||||||
|
|
||||||
|
// High-resolution timestamps
|
||||||
|
if (!QueryPerformanceCounter(&perfCounterBefore))
|
||||||
|
return;
|
||||||
|
tstampBefore = GetTickCount64();
|
||||||
|
|
||||||
|
// Open PDH query
|
||||||
|
status = pfnPdhOpenQuery(NULL, 0, &query);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// Add counters for disk reads and writes (all physical disks).
|
||||||
|
status = pfnPdhAddCounter(query, L"\\PhysicalDisk(*)\\Disk Reads/sec", 0, &counterReads);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
status = pfnPdhAddCounter(query, L"\\PhysicalDisk(*)\\Disk Writes/sec", 0, &counterWrites);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// First sample
|
||||||
|
status = pfnPdhCollectQueryData(query);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// Wait a short random interval
|
||||||
|
Sleep(10 + (GetCurrentProcessId() % 40));
|
||||||
|
|
||||||
|
// Second sample
|
||||||
|
status = pfnPdhCollectQueryData(query);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// Format counters in PDH_FMT_LARGE
|
||||||
|
status = pfnPdhGetFormattedCounterValue(counterReads, PDH_FMT_LARGE, &dwType, &counterValue);
|
||||||
|
if (status == ERROR_SUCCESS)
|
||||||
|
llReads = counterValue.largeValue;
|
||||||
|
|
||||||
|
status = pfnPdhGetFormattedCounterValue(counterWrites, PDH_FMT_LARGE, &dwType, &counterValue);
|
||||||
|
if (status == ERROR_SUCCESS)
|
||||||
|
llWrites = counterValue.largeValue;
|
||||||
|
|
||||||
|
// Another high-resolution timestamp
|
||||||
|
if (!QueryPerformanceCounter(&perfCounterAfter))
|
||||||
|
goto error;
|
||||||
|
tstampAfter = GetTickCount64();
|
||||||
|
|
||||||
|
// Close PDH query
|
||||||
|
pfnPdhCloseQuery(query);
|
||||||
|
query = NULL;
|
||||||
|
|
||||||
|
// Collect results into the random pool
|
||||||
|
RandaddBuf(&llReads, sizeof(llReads));
|
||||||
|
RandaddBuf(&llWrites, sizeof(llWrites));
|
||||||
|
RandaddBuf(&tstampBefore, sizeof(tstampBefore));
|
||||||
|
RandaddBuf(&tstampAfter, sizeof(tstampAfter));
|
||||||
|
RandaddBuf(&perfCounterBefore.QuadPart, sizeof(perfCounterBefore.QuadPart));
|
||||||
|
RandaddBuf(&perfCounterAfter.QuadPart, sizeof(perfCounterAfter.QuadPart));
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (query)
|
||||||
|
pfnPdhCloseQuery(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------------------
|
||||||
|
GetNetworkStatistics: This function uses the Windows Performance Data Helper (PDH) API
|
||||||
|
to collect network statistics. The function collects the number of bytes sent and
|
||||||
|
received per second for all network interfaces. The function also collects
|
||||||
|
high-resolution timestamps before and after the PDH query. The function then adds the
|
||||||
|
collected data to the random pool.
|
||||||
|
The code waits a short random interval between the two PDH samples to ensures that
|
||||||
|
the performance counters have time to accumulate measurable changes and produce more
|
||||||
|
varied data.
|
||||||
|
*/
|
||||||
|
void GetNetworkStatistics()
|
||||||
|
{
|
||||||
|
if (!LoadPdhDll())
|
||||||
|
return;
|
||||||
|
PDH_STATUS status;
|
||||||
|
PDH_HQUERY query = NULL;
|
||||||
|
PDH_HCOUNTER counterBytesSent = NULL, counterBytesReceived = NULL;
|
||||||
|
PDH_FMT_COUNTERVALUE counterValue;
|
||||||
|
DWORD dwType;
|
||||||
|
LONGLONG llBytesSent = 0, llBytesReceived = 0;
|
||||||
|
DWORDLONG tstampBefore = 0, tstampAfter = 0;
|
||||||
|
LARGE_INTEGER perfCounterBefore, perfCounterAfter;
|
||||||
|
|
||||||
|
// High-resolution timestamps
|
||||||
|
if (!QueryPerformanceCounter(&perfCounterBefore))
|
||||||
|
return;
|
||||||
|
tstampBefore = GetTickCount64();
|
||||||
|
|
||||||
|
// Open PDH query
|
||||||
|
status = pfnPdhOpenQuery(NULL, 0, &query);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// Add counters for network bytes sent and received
|
||||||
|
status = pfnPdhAddCounter(query, L"\\Network Interface(*)\\Bytes Sent/sec", 0, &counterBytesSent);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
status = pfnPdhAddCounter(query, L"\\Network Interface(*)\\Bytes Received/sec", 0, &counterBytesReceived);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// First sample
|
||||||
|
status = pfnPdhCollectQueryData(query);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// Wait short, dynamic interval
|
||||||
|
Sleep(10 + (GetCurrentProcessId() % 40));
|
||||||
|
|
||||||
|
// Second sample
|
||||||
|
status = pfnPdhCollectQueryData(query);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// Format counters
|
||||||
|
status = pfnPdhGetFormattedCounterValue(counterBytesSent, PDH_FMT_LARGE, &dwType, &counterValue);
|
||||||
|
if (status == ERROR_SUCCESS)
|
||||||
|
llBytesSent = counterValue.largeValue;
|
||||||
|
|
||||||
|
status = pfnPdhGetFormattedCounterValue(counterBytesReceived, PDH_FMT_LARGE, &dwType, &counterValue);
|
||||||
|
if (status == ERROR_SUCCESS)
|
||||||
|
llBytesReceived = counterValue.largeValue;
|
||||||
|
|
||||||
|
if (!QueryPerformanceCounter(&perfCounterAfter))
|
||||||
|
goto error;
|
||||||
|
tstampAfter = GetTickCount64();
|
||||||
|
|
||||||
|
// Close PDH query
|
||||||
|
pfnPdhCloseQuery(query);
|
||||||
|
query = NULL;
|
||||||
|
|
||||||
|
// Collect results into our random pool
|
||||||
|
RandaddBuf(&llBytesSent, sizeof(llBytesSent));
|
||||||
|
RandaddBuf(&llBytesReceived, sizeof(llBytesReceived));
|
||||||
|
RandaddBuf(&tstampBefore, sizeof(tstampBefore));
|
||||||
|
RandaddBuf(&tstampAfter, sizeof(tstampAfter));
|
||||||
|
RandaddBuf(&perfCounterBefore.QuadPart, sizeof(perfCounterBefore.QuadPart));
|
||||||
|
RandaddBuf(&perfCounterAfter.QuadPart, sizeof(perfCounterAfter.QuadPart));
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (query)
|
||||||
|
pfnPdhCloseQuery(query);
|
||||||
|
}
|
||||||
|
|
||||||
/* This is the slowpoll function which gathers up network/hard drive
|
/* This is the slowpoll function which gathers up network/hard drive
|
||||||
performance data for the random pool */
|
performance data for the random pool */
|
||||||
BOOL SlowPoll (void)
|
BOOL SlowPoll (void)
|
||||||
{
|
{
|
||||||
static int isWorkstation = -1;
|
|
||||||
static int cbPerfData = 0x10000;
|
|
||||||
HANDLE hDevice;
|
|
||||||
LPBYTE lpBuffer;
|
|
||||||
DWORD dwSize, status;
|
|
||||||
LPWSTR lpszLanW, lpszLanS;
|
|
||||||
int nDrive;
|
|
||||||
NTSTATUS bStatus = 0;
|
NTSTATUS bStatus = 0;
|
||||||
|
|
||||||
/* Find out whether this is an NT server or workstation if necessary */
|
// Gather disk stats via PDH
|
||||||
if (isWorkstation == -1)
|
GetDiskStatistics();
|
||||||
{
|
|
||||||
HKEY hKey;
|
// Gather network stats via PDH
|
||||||
|
GetNetworkStatistics();
|
||||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
|
|
||||||
L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
|
|
||||||
0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
wchar_t szValue[32];
|
|
||||||
dwSize = sizeof (szValue);
|
|
||||||
|
|
||||||
isWorkstation = TRUE;
|
|
||||||
status = RegQueryValueEx (hKey, L"ProductType", 0, NULL,
|
|
||||||
(LPBYTE) szValue, &dwSize);
|
|
||||||
|
|
||||||
if (status == ERROR_SUCCESS && _wcsicmp (szValue, L"WinNT"))
|
|
||||||
/* Note: There are (at least) three cases for
|
|
||||||
ProductType: WinNT = NT Workstation,
|
|
||||||
ServerNT = NT Server, LanmanNT = NT Server
|
|
||||||
acting as a Domain Controller */
|
|
||||||
isWorkstation = FALSE;
|
|
||||||
|
|
||||||
RegCloseKey (hKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Initialize the NetAPI32 function pointers if necessary */
|
|
||||||
if (hNetAPI32 == NULL)
|
|
||||||
{
|
|
||||||
/* Obtain a handle to the module containing the Lan Manager
|
|
||||||
functions */
|
|
||||||
wchar_t dllPath[MAX_PATH];
|
|
||||||
if (GetSystemDirectory (dllPath, MAX_PATH))
|
|
||||||
{
|
|
||||||
StringCchCatW(dllPath, ARRAYSIZE(dllPath), L"\\NETAPI32.DLL");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
StringCchCopyW(dllPath, ARRAYSIZE(dllPath), L"C:\\Windows\\System32\\NETAPI32.DLL");
|
|
||||||
|
|
||||||
hNetAPI32 = LoadLibrary (dllPath);
|
|
||||||
if (hNetAPI32 != NULL)
|
|
||||||
{
|
|
||||||
/* Now get pointers to the functions */
|
|
||||||
pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
|
|
||||||
"NetStatisticsGet");
|
|
||||||
pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
|
|
||||||
"NetApiBufferSize");
|
|
||||||
pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
|
|
||||||
"NetApiBufferFree");
|
|
||||||
|
|
||||||
/* Make sure we got valid pointers for every NetAPI32
|
|
||||||
function */
|
|
||||||
if (pNetStatisticsGet == NULL ||
|
|
||||||
pNetApiBufferSize == NULL ||
|
|
||||||
pNetApiBufferFree == NULL)
|
|
||||||
{
|
|
||||||
/* Free the library reference and reset the
|
|
||||||
static handle */
|
|
||||||
FreeLibrary (hNetAPI32);
|
|
||||||
hNetAPI32 = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get network statistics. Note: Both NT Workstation and NT Server
|
|
||||||
by default will be running both the workstation and server
|
|
||||||
services. The heuristic below is probably useful though on the
|
|
||||||
assumption that the majority of the network traffic will be via
|
|
||||||
the appropriate service */
|
|
||||||
lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
|
|
||||||
lpszLanS = (LPWSTR) WIDE ("LanmanServer");
|
|
||||||
if (hNetAPI32 &&
|
|
||||||
pNetStatisticsGet (NULL,
|
|
||||||
isWorkstation ? lpszLanW : lpszLanS,
|
|
||||||
0, 0, &lpBuffer) == 0)
|
|
||||||
{
|
|
||||||
pNetApiBufferSize (lpBuffer, &dwSize);
|
|
||||||
RandaddBuf ((unsigned char *) lpBuffer, dwSize);
|
|
||||||
pNetApiBufferFree (lpBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get disk I/O statistics for all the hard drives */
|
|
||||||
for (nDrive = 0;; nDrive++)
|
|
||||||
{
|
|
||||||
DISK_PERFORMANCE diskPerformance;
|
|
||||||
wchar_t szDevice[24];
|
|
||||||
|
|
||||||
/* Check whether we can access this device */
|
|
||||||
StringCchPrintfW (szDevice, ARRAYSIZE(szDevice), L"\\\\.\\PhysicalDrive%d", nDrive);
|
|
||||||
hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (hDevice == INVALID_HANDLE_VALUE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
/* Note: This only works if you have turned on the disk
|
|
||||||
performance counters with 'diskperf -y'. These counters
|
|
||||||
are off by default */
|
|
||||||
if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
|
|
||||||
&diskPerformance, sizeof (DISK_PERFORMANCE),
|
|
||||||
&dwSize, NULL))
|
|
||||||
{
|
|
||||||
RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
|
|
||||||
}
|
|
||||||
CloseHandle (hDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bStatus = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
bStatus = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||||
if (NT_SUCCESS(bStatus))
|
if (NT_SUCCESS(bStatus))
|
||||||
@@ -803,7 +879,7 @@ BOOL SlowPoll (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use RDSEED or RDRAND from CPU as source of entropy if present
|
// use RDSEED or RDRAND from CPU as source of entropy if present
|
||||||
if ( IsCpuRngEnabled() &&
|
if ( IsCpuRngEnabled() &&
|
||||||
( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer)))
|
( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer)))
|
||||||
|| (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer)))
|
|| (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer)))
|
||||||
))
|
))
|
||||||
@@ -812,6 +888,8 @@ BOOL SlowPoll (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
burn(buffer, sizeof (buffer));
|
burn(buffer, sizeof (buffer));
|
||||||
|
|
||||||
|
/* Mix the pool */
|
||||||
Randmix();
|
Randmix();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -934,7 +1012,7 @@ BOOL FastPoll (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use RDSEED or RDRAND from CPU as source of entropy if enabled
|
// use RDSEED or RDRAND from CPU as source of entropy if enabled
|
||||||
if ( IsCpuRngEnabled() &&
|
if ( IsCpuRngEnabled() &&
|
||||||
( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer)))
|
( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer)))
|
||||||
|| (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer)))
|
|| (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer)))
|
||||||
))
|
))
|
||||||
|
|||||||
Reference in New Issue
Block a user