mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-24 12:03:28 +01:00
Windows Driver: Add registry settings to control driver internal encryption queue Under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\veracrypt: - VeraCryptEncryptionFragmentSize (REG_DWORD): size of encryption data fragment in KiB. Default is 256. - VeraCryptEncryptionIoRequestCount (REG_DWORD): maximum number of parallel I/O requests. Default is 16. - VeraCryptEncryptionItemCount (REG_DWORD): maximum number of encryption queue items processed in parallel. Default is 8.
This commit is contained in:
parent
4ed2bf5427
commit
5640de3584
@ -407,6 +407,10 @@ typedef struct
|
|||||||
#define TC_DRIVER_CONFIG_REG_VALUE_NAME DRIVER_STR("VeraCryptConfig")
|
#define TC_DRIVER_CONFIG_REG_VALUE_NAME DRIVER_STR("VeraCryptConfig")
|
||||||
#define TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME DRIVER_STR("VeraCryptEncryptionFreeCpuCount")
|
#define TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME DRIVER_STR("VeraCryptEncryptionFreeCpuCount")
|
||||||
|
|
||||||
|
#define VC_ENCRYPTION_IO_REQUEST_COUNT DRIVER_STR("VeraCryptEncryptionIoRequestCount")
|
||||||
|
#define VC_ENCRYPTION_ITEM_COUNT DRIVER_STR("VeraCryptEncryptionItemCount")
|
||||||
|
#define VC_ENCRYPTION_FRAGMENT_SIZE DRIVER_STR("VeraCryptEncryptionFragmentSize")
|
||||||
|
|
||||||
// WARNING: Modifying the following values can introduce incompatibility with previous versions.
|
// WARNING: Modifying the following values can introduce incompatibility with previous versions.
|
||||||
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1
|
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1
|
||||||
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2
|
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2
|
||||||
|
@ -775,9 +775,10 @@ static VOID MainThreadProc (PVOID threadArg)
|
|||||||
|
|
||||||
while (dataRemaining > 0)
|
while (dataRemaining > 0)
|
||||||
{
|
{
|
||||||
BOOL isLastFragment = dataRemaining <= TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
|
ULONG queueFragmentSize = queue->FragmentSize;
|
||||||
|
BOOL isLastFragment = dataRemaining <= queueFragmentSize;
|
||||||
|
|
||||||
ULONG dataFragmentLength = isLastFragment ? dataRemaining : TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
|
ULONG dataFragmentLength = isLastFragment ? dataRemaining : queueFragmentSize;
|
||||||
activeFragmentBuffer = (activeFragmentBuffer == queue->FragmentBufferA ? queue->FragmentBufferB : queue->FragmentBufferA);
|
activeFragmentBuffer = (activeFragmentBuffer == queue->FragmentBufferA ? queue->FragmentBufferB : queue->FragmentBufferA);
|
||||||
|
|
||||||
InterlockedIncrement (&queue->IoThreadPendingRequestCount);
|
InterlockedIncrement (&queue->IoThreadPendingRequestCount);
|
||||||
@ -847,9 +848,9 @@ static VOID MainThreadProc (PVOID threadArg)
|
|||||||
if (isLastFragment)
|
if (isLastFragment)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
dataRemaining -= TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
|
dataRemaining -= queueFragmentSize;
|
||||||
dataBuffer += TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
|
dataBuffer += queueFragmentSize;
|
||||||
fragmentOffset.QuadPart += TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
|
fragmentOffset.QuadPart += queueFragmentSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -971,7 +972,11 @@ NTSTATUS EncryptedIoQueueStart (EncryptedIoQueue *queue)
|
|||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
EncryptedIoQueueBuffer *buffer;
|
EncryptedIoQueueBuffer *buffer;
|
||||||
int i;
|
int i, preallocatedIoRequestCount, preallocatedItemCount, fragmentSize;
|
||||||
|
|
||||||
|
preallocatedIoRequestCount = EncryptionIoRequestCount;
|
||||||
|
preallocatedItemCount = EncryptionItemCount;
|
||||||
|
fragmentSize = EncryptionFragmentSize;
|
||||||
|
|
||||||
queue->StartPending = TRUE;
|
queue->StartPending = TRUE;
|
||||||
queue->ThreadExitRequested = FALSE;
|
queue->ThreadExitRequested = FALSE;
|
||||||
@ -986,30 +991,84 @@ NTSTATUS EncryptedIoQueueStart (EncryptedIoQueue *queue)
|
|||||||
KeInitializeEvent (&queue->PoolBufferFreeEvent, SynchronizationEvent, FALSE);
|
KeInitializeEvent (&queue->PoolBufferFreeEvent, SynchronizationEvent, FALSE);
|
||||||
KeInitializeEvent (&queue->QueueResumedEvent, SynchronizationEvent, FALSE);
|
KeInitializeEvent (&queue->QueueResumedEvent, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
queue->FragmentBufferA = TCalloc (TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE);
|
retry_fragmentAllocate:
|
||||||
|
queue->FragmentBufferA = TCalloc (fragmentSize);
|
||||||
if (!queue->FragmentBufferA)
|
if (!queue->FragmentBufferA)
|
||||||
goto noMemory;
|
{
|
||||||
|
if (fragmentSize > TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE)
|
||||||
|
{
|
||||||
|
fragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
|
||||||
|
goto retry_fragmentAllocate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto noMemory;
|
||||||
|
}
|
||||||
|
|
||||||
queue->FragmentBufferB = TCalloc (TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE);
|
queue->FragmentBufferB = TCalloc (fragmentSize);
|
||||||
if (!queue->FragmentBufferB)
|
if (!queue->FragmentBufferB)
|
||||||
goto noMemory;
|
{
|
||||||
|
if (fragmentSize > TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE)
|
||||||
|
{
|
||||||
|
fragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
|
||||||
|
TCfree (queue->FragmentBufferA);
|
||||||
|
queue->FragmentBufferA = NULL;
|
||||||
|
goto retry_fragmentAllocate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto noMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue->ReadAheadBufferValid = FALSE;
|
||||||
|
queue->ReadAheadBuffer = TCalloc (fragmentSize);
|
||||||
|
if (!queue->ReadAheadBuffer)
|
||||||
|
{
|
||||||
|
if (fragmentSize > TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE)
|
||||||
|
{
|
||||||
|
fragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
|
||||||
|
TCfree (queue->FragmentBufferA);
|
||||||
|
TCfree (queue->FragmentBufferB);
|
||||||
|
queue->FragmentBufferA = NULL;
|
||||||
|
queue->FragmentBufferB = NULL;
|
||||||
|
goto retry_fragmentAllocate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto noMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue->FragmentSize = fragmentSize;
|
||||||
|
|
||||||
KeInitializeEvent (&queue->FragmentBufferAFreeEvent, SynchronizationEvent, TRUE);
|
KeInitializeEvent (&queue->FragmentBufferAFreeEvent, SynchronizationEvent, TRUE);
|
||||||
KeInitializeEvent (&queue->FragmentBufferBFreeEvent, SynchronizationEvent, TRUE);
|
KeInitializeEvent (&queue->FragmentBufferBFreeEvent, SynchronizationEvent, TRUE);
|
||||||
|
|
||||||
queue->ReadAheadBufferValid = FALSE;
|
retry_preallocated:
|
||||||
queue->ReadAheadBuffer = TCalloc (TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE);
|
|
||||||
if (!queue->ReadAheadBuffer)
|
|
||||||
goto noMemory;
|
|
||||||
|
|
||||||
// Preallocate buffers
|
// Preallocate buffers
|
||||||
for (i = 0; i < TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT; ++i)
|
for (i = 0; i < preallocatedIoRequestCount; ++i)
|
||||||
{
|
{
|
||||||
if (i < TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT && !GetPoolBuffer (queue, sizeof (EncryptedIoQueueItem)))
|
if (i < preallocatedItemCount && !GetPoolBuffer (queue, sizeof (EncryptedIoQueueItem)))
|
||||||
goto noMemory;
|
{
|
||||||
|
if (preallocatedItemCount > TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT)
|
||||||
|
{
|
||||||
|
preallocatedItemCount = TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT;
|
||||||
|
preallocatedIoRequestCount = TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT;
|
||||||
|
FreePoolBuffers (queue);
|
||||||
|
goto retry_preallocated;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto noMemory;
|
||||||
|
}
|
||||||
|
|
||||||
if (!GetPoolBuffer (queue, sizeof (EncryptedIoRequest)))
|
if (!GetPoolBuffer (queue, sizeof (EncryptedIoRequest)))
|
||||||
goto noMemory;
|
{
|
||||||
|
if (preallocatedIoRequestCount > TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT)
|
||||||
|
{
|
||||||
|
preallocatedItemCount = TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT;
|
||||||
|
preallocatedIoRequestCount = TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT;
|
||||||
|
FreePoolBuffers (queue);
|
||||||
|
goto retry_preallocated;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto noMemory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (buffer = queue->FirstPoolBuffer; buffer != NULL; buffer = buffer->NextBuffer)
|
for (buffer = queue->FirstPoolBuffer; buffer != NULL; buffer = buffer->NextBuffer)
|
||||||
|
@ -121,6 +121,8 @@ typedef struct
|
|||||||
SIZE_T SecRegionSize;
|
SIZE_T SecRegionSize;
|
||||||
|
|
||||||
volatile BOOL ThreadBlockReadWrite;
|
volatile BOOL ThreadBlockReadWrite;
|
||||||
|
|
||||||
|
int FragmentSize;
|
||||||
} EncryptedIoQueue;
|
} EncryptedIoQueue;
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,6 +148,9 @@ static KeAreAllApcsDisabledFn KeAreAllApcsDisabledPtr = NULL;
|
|||||||
static KeSetSystemGroupAffinityThreadFn KeSetSystemGroupAffinityThreadPtr = NULL;
|
static KeSetSystemGroupAffinityThreadFn KeSetSystemGroupAffinityThreadPtr = NULL;
|
||||||
static KeQueryActiveGroupCountFn KeQueryActiveGroupCountPtr = NULL;
|
static KeQueryActiveGroupCountFn KeQueryActiveGroupCountPtr = NULL;
|
||||||
static KeQueryActiveProcessorCountExFn KeQueryActiveProcessorCountExPtr = NULL;
|
static KeQueryActiveProcessorCountExFn KeQueryActiveProcessorCountExPtr = NULL;
|
||||||
|
int EncryptionIoRequestCount = 0;
|
||||||
|
int EncryptionItemCount = 0;
|
||||||
|
int EncryptionFragmentSize = 0;
|
||||||
|
|
||||||
POOL_TYPE ExDefaultNonPagedPoolType = NonPagedPool;
|
POOL_TYPE ExDefaultNonPagedPoolType = NonPagedPool;
|
||||||
ULONG ExDefaultMdlProtection = 0;
|
ULONG ExDefaultMdlProtection = 0;
|
||||||
@ -4795,6 +4798,50 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry)
|
|||||||
TCfree (data);
|
TCfree (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (driverEntry && NT_SUCCESS (TCReadRegistryKey (&name, VC_ENCRYPTION_IO_REQUEST_COUNT, &data)))
|
||||||
|
{
|
||||||
|
if (data->Type == REG_DWORD)
|
||||||
|
EncryptionIoRequestCount = *(uint32 *) data->Data;
|
||||||
|
|
||||||
|
TCfree (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driverEntry && NT_SUCCESS (TCReadRegistryKey (&name, VC_ENCRYPTION_ITEM_COUNT, &data)))
|
||||||
|
{
|
||||||
|
if (data->Type == REG_DWORD)
|
||||||
|
EncryptionItemCount = *(uint32 *) data->Data;
|
||||||
|
|
||||||
|
TCfree (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driverEntry && NT_SUCCESS (TCReadRegistryKey (&name, VC_ENCRYPTION_FRAGMENT_SIZE, &data)))
|
||||||
|
{
|
||||||
|
if (data->Type == REG_DWORD)
|
||||||
|
EncryptionFragmentSize = *(uint32 *) data->Data;
|
||||||
|
|
||||||
|
TCfree (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driverEntry)
|
||||||
|
{
|
||||||
|
if (EncryptionIoRequestCount < TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT)
|
||||||
|
EncryptionIoRequestCount = TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT;
|
||||||
|
|
||||||
|
if (EncryptionItemCount == 0)
|
||||||
|
EncryptionItemCount = EncryptionIoRequestCount / 2;
|
||||||
|
else if (EncryptionItemCount >= EncryptionIoRequestCount)
|
||||||
|
EncryptionItemCount = EncryptionIoRequestCount - 1;
|
||||||
|
|
||||||
|
/* EncryptionFragmentSize value in registry is expressed in KiB */
|
||||||
|
if (EncryptionFragmentSize == 0)
|
||||||
|
EncryptionFragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE / 1024;
|
||||||
|
else if (EncryptionFragmentSize > (8 * TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE / 1024))
|
||||||
|
EncryptionFragmentSize = 8 * TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE / 1024;
|
||||||
|
|
||||||
|
EncryptionFragmentSize = EncryptionFragmentSize * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +125,9 @@ extern BOOL CacheBootPassword;
|
|||||||
extern BOOL CacheBootPim;
|
extern BOOL CacheBootPim;
|
||||||
extern BOOL BlockSystemTrimCommand;
|
extern BOOL BlockSystemTrimCommand;
|
||||||
extern BOOL AllowWindowsDefrag;
|
extern BOOL AllowWindowsDefrag;
|
||||||
|
extern int EncryptionIoRequestCount;
|
||||||
|
extern int EncryptionItemCount;
|
||||||
|
extern int EncryptionFragmentSize;
|
||||||
/* Helper macro returning x seconds in units of 100 nanoseconds */
|
/* Helper macro returning x seconds in units of 100 nanoseconds */
|
||||||
#define WAIT_SECONDS(x) ((x)*10000000)
|
#define WAIT_SECONDS(x) ((x)*10000000)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user