VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2021-12-20 00:14:24 +0100
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2021-12-20 00:18:58 +0100
commit5640de3584aa5d3ab327ecd7345ded2e0096b464 (patch)
tree46aad7f454b4797e6377acc41ebc3356a2817799
parent4ed2bf5427539c4111c256f54dd00342c6a3f45f (diff)
downloadVeraCrypt-5640de3584aa5d3ab327ecd7345ded2e0096b464.tar.gz
VeraCrypt-5640de3584aa5d3ab327ecd7345ded2e0096b464.zip
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.
-rw-r--r--src/Common/Apidrvr.h4
-rw-r--r--src/Driver/EncryptedIoQueue.c97
-rw-r--r--src/Driver/EncryptedIoQueue.h2
-rw-r--r--src/Driver/Ntdriver.c47
-rw-r--r--src/Driver/Ntdriver.h3
5 files changed, 134 insertions, 19 deletions
diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h
index c56d9ff7..368d4a72 100644
--- a/src/Common/Apidrvr.h
+++ b/src/Common/Apidrvr.h
@@ -407,6 +407,10 @@ typedef struct
#define TC_DRIVER_CONFIG_REG_VALUE_NAME DRIVER_STR("VeraCryptConfig")
#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.
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2
diff --git a/src/Driver/EncryptedIoQueue.c b/src/Driver/EncryptedIoQueue.c
index 85b9a330..6900fc0d 100644
--- a/src/Driver/EncryptedIoQueue.c
+++ b/src/Driver/EncryptedIoQueue.c
@@ -775,9 +775,10 @@ static VOID MainThreadProc (PVOID threadArg)
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);
InterlockedIncrement (&queue->IoThreadPendingRequestCount);
@@ -847,9 +848,9 @@ static VOID MainThreadProc (PVOID threadArg)
if (isLastFragment)
break;
- dataRemaining -= TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
- dataBuffer += TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
- fragmentOffset.QuadPart += TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
+ dataRemaining -= queueFragmentSize;
+ dataBuffer += queueFragmentSize;
+ fragmentOffset.QuadPart += queueFragmentSize;
}
}
}
@@ -971,7 +972,11 @@ NTSTATUS EncryptedIoQueueStart (EncryptedIoQueue *queue)
{
NTSTATUS status;
EncryptedIoQueueBuffer *buffer;
- int i;
+ int i, preallocatedIoRequestCount, preallocatedItemCount, fragmentSize;
+
+ preallocatedIoRequestCount = EncryptionIoRequestCount;
+ preallocatedItemCount = EncryptionItemCount;
+ fragmentSize = EncryptionFragmentSize;
queue->StartPending = TRUE;
queue->ThreadExitRequested = FALSE;
@@ -986,30 +991,84 @@ NTSTATUS EncryptedIoQueueStart (EncryptedIoQueue *queue)
KeInitializeEvent (&queue->PoolBufferFreeEvent, 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)
- 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)
- goto noMemory;
-
- KeInitializeEvent (&queue->FragmentBufferAFreeEvent, SynchronizationEvent, TRUE);
- KeInitializeEvent (&queue->FragmentBufferBFreeEvent, SynchronizationEvent, TRUE);
+ {
+ 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 (TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE);
+ queue->ReadAheadBuffer = TCalloc (fragmentSize);
if (!queue->ReadAheadBuffer)
- goto noMemory;
+ {
+ 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->FragmentBufferBFreeEvent, SynchronizationEvent, TRUE);
+retry_preallocated:
// 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)))
- goto noMemory;
+ if (i < preallocatedItemCount && !GetPoolBuffer (queue, sizeof (EncryptedIoQueueItem)))
+ {
+ 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)))
- 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)
diff --git a/src/Driver/EncryptedIoQueue.h b/src/Driver/EncryptedIoQueue.h
index 184e1714..d9bef42b 100644
--- a/src/Driver/EncryptedIoQueue.h
+++ b/src/Driver/EncryptedIoQueue.h
@@ -121,6 +121,8 @@ typedef struct
SIZE_T SecRegionSize;
volatile BOOL ThreadBlockReadWrite;
+
+ int FragmentSize;
} EncryptedIoQueue;
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c
index c778cfed..50b66ab6 100644
--- a/src/Driver/Ntdriver.c
+++ b/src/Driver/Ntdriver.c
@@ -148,6 +148,9 @@ static KeAreAllApcsDisabledFn KeAreAllApcsDisabledPtr = NULL;
static KeSetSystemGroupAffinityThreadFn KeSetSystemGroupAffinityThreadPtr = NULL;
static KeQueryActiveGroupCountFn KeQueryActiveGroupCountPtr = NULL;
static KeQueryActiveProcessorCountExFn KeQueryActiveProcessorCountExPtr = NULL;
+int EncryptionIoRequestCount = 0;
+int EncryptionItemCount = 0;
+int EncryptionFragmentSize = 0;
POOL_TYPE ExDefaultNonPagedPoolType = NonPagedPool;
ULONG ExDefaultMdlProtection = 0;
@@ -4795,6 +4798,50 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry)
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;
}
diff --git a/src/Driver/Ntdriver.h b/src/Driver/Ntdriver.h
index 47ae49f7..b7e2d56e 100644
--- a/src/Driver/Ntdriver.h
+++ b/src/Driver/Ntdriver.h
@@ -125,6 +125,9 @@ extern BOOL CacheBootPassword;
extern BOOL CacheBootPim;
extern BOOL BlockSystemTrimCommand;
extern BOOL AllowWindowsDefrag;
+extern int EncryptionIoRequestCount;
+extern int EncryptionItemCount;
+extern int EncryptionFragmentSize;
/* Helper macro returning x seconds in units of 100 nanoseconds */
#define WAIT_SECONDS(x) ((x)*10000000)