Compare commits

...

7 Commits

Author SHA1 Message Date
Wendigo
2605a31e0d
Merge bcb8490430 into b6f3d8a23a 2024-11-24 16:56:06 +01:00
Mounir IDRASSI
b6f3d8a23a
Translations: Fix issues in Slovenian translation. Complete translation of some entries 2024-11-24 13:46:08 +01:00
Mounir IDRASSI
e798d88407
Translations: Update Slovenian translation (contributed by Prof. Sasa Divjak) 2024-11-24 13:43:34 +01:00
Mounir IDRASSI
53bbee3a7c
Windows Driver: Set version to 1.26.17.1. Update signed drivers. 2024-11-24 11:26:41 +01:00
Mounir IDRASSI
453ff2880e
Windows Driver: Make max work items count configurable. Increase default to 1024. Queue write IRPs.
- Made the maximum work items count configurable to allow flexibility based on system needs.
  - Increased the default value of max work items count to 1024 to better handle high-throughput scenarios.
  - Queue write IRPs in system worker thread to avoid potential deadlocks in write scenarios.
2024-11-23 17:44:48 +01:00
Mounir IDRASSI
5a85c54c6e
Windows Driver: Optimize spinlock usage in CompleteIrpWorkItemRoutine
Reduce the critical section protected by spinlock to only cover the list manipulation operation. Move the ActiveWorkItems counter decrement outside the spinlock using InterlockedDecrement, and separate event signaling from the locked section.
This change minimizes time spent at raised IRQL (DISPATCH_LEVEL) and reduces potential for lock contention.
2024-11-22 15:19:10 +01:00
Wendigo
bcb8490430 fix default algos 2023-05-27 21:57:55 +03:00
14 changed files with 464 additions and 437 deletions

File diff suppressed because it is too large Load Diff

View File

@ -396,6 +396,7 @@ typedef struct
int EncryptionIoRequestCount;
int EncryptionItemCount;
int EncryptionFragmentSize;
int EncryptionMaxWorkItems;
} EncryptionQueueParameters;
#pragma pack (pop)
@ -418,6 +419,7 @@ typedef struct
#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")
#define VC_ENCRYPTION_MAX_WORK_ITEMS DRIVER_STR("VeraCryptEncryptionMaxWorkItems")
#define VC_ERASE_KEYS_SHUTDOWN DRIVER_STR("VeraCryptEraseKeysShutdown")

View File

@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,26,17,0
PRODUCTVERSION 1,26,17,0
FILEVERSION 1,26,17,1
PRODUCTVERSION 1,26,17,1
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L

View File

@ -108,7 +108,7 @@
<Inf>
<ProviderName>
</ProviderName>
<TimeStamp>1.26.17.0</TimeStamp>
<TimeStamp>1.26.17.1</TimeStamp>
</Inf>
<Link>
<AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib</AdditionalDependencies>
@ -134,7 +134,7 @@ copy $(OutDir)veracrypt.inf "$(SolutionDir)Debug\Setup Files\veracrypt.inf"</Com
<Inf>
<ProviderName>
</ProviderName>
<TimeStamp>1.26.17.0</TimeStamp>
<TimeStamp>1.26.17.1</TimeStamp>
</Inf>
<Link>
<AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib</AdditionalDependencies>
@ -160,7 +160,7 @@ copy $(OutDir)veracrypt.inf "$(SolutionDir)Release\Setup Files\veracrypt.inf"</C
<Inf>
<ProviderName>
</ProviderName>
<TimeStamp>1.26.17.0</TimeStamp>
<TimeStamp>1.26.17.1</TimeStamp>
</Inf>
<Link>
<AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib</AdditionalDependencies>
@ -186,7 +186,7 @@ copy $(OutDir)veracrypt.inf "$(SolutionDir)Release\Setup Files\veracrypt.inf"</C
<Inf>
<ProviderName>
</ProviderName>
<TimeStamp>1.26.17.0</TimeStamp>
<TimeStamp>1.26.17.1</TimeStamp>
</Inf>
<Link>
<AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib</AdditionalDependencies>

View File

@ -271,6 +271,7 @@ static VOID CompleteIrpWorkItemRoutine(PDEVICE_OBJECT DeviceObject, PVOID Contex
PCOMPLETE_IRP_WORK_ITEM workItem = (PCOMPLETE_IRP_WORK_ITEM)Context;
EncryptedIoQueueItem* item = (EncryptedIoQueueItem * ) workItem->Item;
EncryptedIoQueue* queue = item->Queue;
KIRQL oldIrql;
UNREFERENCED_PARAMETER(DeviceObject);
__try
@ -283,19 +284,14 @@ static VOID CompleteIrpWorkItemRoutine(PDEVICE_OBJECT DeviceObject, PVOID Contex
}
__finally
{
// Return the work item to the free list
KIRQL oldIrql;
KeAcquireSpinLock(&queue->WorkItemLock, &oldIrql);
// Decrement ActiveWorkItems
LONG activeWorkItems = InterlockedDecrement(&queue->ActiveWorkItems);
// If no active work items remain, signal the event
if (activeWorkItems == 0)
if (InterlockedDecrement(&queue->ActiveWorkItems) == 0)
{
KeSetEvent(&queue->NoActiveWorkItemsEvent, IO_NO_INCREMENT, FALSE);
}
// Return the work item to the free list
KeAcquireSpinLock(&queue->WorkItemLock, &oldIrql);
InsertTailList(&queue->FreeWorkItemsList, &workItem->ListEntry);
KeReleaseSpinLock(&queue->WorkItemLock, oldIrql);
@ -307,8 +303,43 @@ static VOID CompleteIrpWorkItemRoutine(PDEVICE_OBJECT DeviceObject, PVOID Contex
}
}
// Handles the completion of the original IRP.
static VOID HandleCompleteOriginalIrp(EncryptedIoQueue* queue, EncryptedIoRequest* request)
{
NTSTATUS status = KeWaitForSingleObject(&queue->WorkItemSemaphore, Executive, KernelMode, FALSE, NULL);
if (queue->ThreadExitRequested)
return;
if (!NT_SUCCESS(status))
{
// Handle wait failure: we call the completion routine directly.
// This is not ideal since it can cause deadlock that we are trying to fix but it is better than losing the IRP.
CompleteOriginalIrp(request->Item, STATUS_INSUFFICIENT_RESOURCES, 0);
}
else
{
// Obtain a work item from the free list.
KIRQL oldIrql;
KeAcquireSpinLock(&queue->WorkItemLock, &oldIrql);
PLIST_ENTRY freeEntry = RemoveHeadList(&queue->FreeWorkItemsList);
KeReleaseSpinLock(&queue->WorkItemLock, oldIrql);
PCOMPLETE_IRP_WORK_ITEM workItem = CONTAINING_RECORD(freeEntry, COMPLETE_IRP_WORK_ITEM, ListEntry);
// Increment ActiveWorkItems.
InterlockedIncrement(&queue->ActiveWorkItems);
KeResetEvent(&queue->NoActiveWorkItemsEvent);
// Prepare the work item.
workItem->Irp = request->Item->OriginalIrp;
workItem->Status = request->Item->Status;
workItem->Information = NT_SUCCESS(request->Item->Status) ? request->Item->OriginalLength : 0;
workItem->Item = request->Item;
// Queue the work item.
IoQueueWorkItem(workItem->WorkItem, CompleteIrpWorkItemRoutine, DelayedWorkQueue, workItem);
}
}
static VOID CompletionThreadProc(PVOID threadArg)
{
@ -352,39 +383,7 @@ static VOID CompletionThreadProc(PVOID threadArg)
if (request->CompleteOriginalIrp)
{
// Wait for a work item to become available
NTSTATUS status = KeWaitForSingleObject(&queue->WorkItemSemaphore, Executive, KernelMode, FALSE, NULL);
if (queue->ThreadExitRequested)
break;
if (!NT_SUCCESS(status))
{
// Handle wait failure: we call the completion routine directly.
// This is not ideal since it can cause deadlock that we are trying to fix but it is better than losing the IRP.
CompleteOriginalIrp(request->Item, STATUS_INSUFFICIENT_RESOURCES, 0);
}
else
{
// Obtain a work item from the free list
KIRQL oldIrql;
KeAcquireSpinLock(&queue->WorkItemLock, &oldIrql);
PLIST_ENTRY freeEntry = RemoveHeadList(&queue->FreeWorkItemsList);
KeReleaseSpinLock(&queue->WorkItemLock, oldIrql);
PCOMPLETE_IRP_WORK_ITEM workItem = CONTAINING_RECORD(freeEntry, COMPLETE_IRP_WORK_ITEM, ListEntry);
// Increment ActiveWorkItems
InterlockedIncrement(&queue->ActiveWorkItems);
KeResetEvent(&queue->NoActiveWorkItemsEvent);
// Prepare the work item
workItem->Irp = request->Item->OriginalIrp;
workItem->Status = request->Item->Status;
workItem->Information = NT_SUCCESS(request->Item->Status) ? request->Item->OriginalLength : 0;
workItem->Item = request->Item;
// Queue the work item
IoQueueWorkItem(workItem->WorkItem, CompleteIrpWorkItemRoutine, DelayedWorkQueue, workItem);
}
HandleCompleteOriginalIrp(queue, request);
}
ReleasePoolBuffer(queue, request);
@ -545,8 +544,7 @@ static VOID IoThreadProc (PVOID threadArg)
if (request->CompleteOriginalIrp)
{
CompleteOriginalIrp (request->Item, request->Item->Status,
NT_SUCCESS (request->Item->Status) ? request->Item->OriginalLength : 0);
HandleCompleteOriginalIrp(queue, request);
}
ReleasePoolBuffer (queue, request);
@ -1152,10 +1150,10 @@ NTSTATUS EncryptedIoQueueStart (EncryptedIoQueue *queue)
// Initialize the free work item list
InitializeListHead(&queue->FreeWorkItemsList);
KeInitializeSemaphore(&queue->WorkItemSemaphore, VC_MAX_WORK_ITEMS, VC_MAX_WORK_ITEMS);
KeInitializeSemaphore(&queue->WorkItemSemaphore, EncryptionMaxWorkItems, EncryptionMaxWorkItems);
KeInitializeSpinLock(&queue->WorkItemLock);
queue->MaxWorkItems = VC_MAX_WORK_ITEMS;
queue->MaxWorkItems = EncryptionMaxWorkItems;
queue->WorkItemPool = (PCOMPLETE_IRP_WORK_ITEM)TCalloc(sizeof(COMPLETE_IRP_WORK_ITEM) * queue->MaxWorkItems);
if (!queue->WorkItemPool)
{

View File

@ -26,7 +26,7 @@
#define TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT 16
#define TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_MAX_COUNT 8192
#define VC_MAX_WORK_ITEMS 256
#define VC_MAX_WORK_ITEMS 1024
typedef struct EncryptedIoQueueBufferStruct
{

View File

@ -145,6 +145,7 @@ static BOOL RamEncryptionActivated = FALSE;
int EncryptionIoRequestCount = 0;
int EncryptionItemCount = 0;
int EncryptionFragmentSize = 0;
int EncryptionMaxWorkItems = 0;
PDEVICE_OBJECT VirtualVolumeDeviceObjects[MAX_MOUNTED_VOLUME_DRIVE_NUMBER + 1];
@ -2776,6 +2777,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex
if (ValidateIOBufferSize (Irp, sizeof (EncryptionQueueParameters), ValidateOutput))
{
EncryptionQueueParameters* pParams = (EncryptionQueueParameters*) Irp->AssociatedIrp.SystemBuffer;
pParams->EncryptionMaxWorkItems = EncryptionMaxWorkItems;
pParams->EncryptionFragmentSize = EncryptionFragmentSize;
pParams->EncryptionIoRequestCount = EncryptionIoRequestCount;
pParams->EncryptionItemCount = EncryptionItemCount;
@ -4646,6 +4648,14 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry)
TCfree (data);
}
if (driverEntry && NT_SUCCESS(TCReadRegistryKey(&name, VC_ENCRYPTION_MAX_WORK_ITEMS, &data)))
{
if (data->Type == REG_DWORD)
EncryptionMaxWorkItems = *(uint32*)data->Data;
TCfree(data);
}
if (driverEntry)
{
if (EncryptionIoRequestCount < TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT)
@ -4663,6 +4673,9 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry)
EncryptionFragmentSize = TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
else if (EncryptionFragmentSize > (8 * TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE))
EncryptionFragmentSize = 8 * TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
if (EncryptionMaxWorkItems == 0)
EncryptionMaxWorkItems = VC_MAX_WORK_ITEMS;
}

View File

@ -128,6 +128,7 @@ extern BOOL AllowWindowsDefrag;
extern int EncryptionIoRequestCount;
extern int EncryptionItemCount;
extern int EncryptionFragmentSize;
extern int EncryptionMaxWorkItems;
extern BOOL EraseKeysOnShutdown;
/* Helper macro returning x seconds in units of 100 nanoseconds */
#define WAIT_SECONDS(x) ((x)*10000000)

View File

@ -4165,6 +4165,8 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
int ea, hid;
wchar_t buf[100];
srand(time(NULL));
// Encryption algorithms
SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_RESETCONTENT, 0, 0);
@ -4180,6 +4182,8 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
AddComboPair (GetDlgItem (hwndDlg, IDC_COMBO_BOX), EAGetName (buf, ARRAYSIZE(buf),ea, 1), ea);
}
nVolumeEA = rand() % 5 + 1;
SelectAlgo (GetDlgItem (hwndDlg, IDC_COMBO_BOX), &nVolumeEA);
ComboSelChangeEA (hwndDlg);
SetFocus (GetDlgItem (hwndDlg, IDC_COMBO_BOX));
@ -4190,14 +4194,21 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (SysEncInEffect ())
{
int x = 0;
hash_algo = bSystemIsGPT? SHA512 : DEFAULT_HASH_ALGORITHM_BOOT;
RandSetHashFunction (hash_algo);
for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++)
{
if ((!HashIsDeprecated (hid)) && (bSystemIsGPT || HashForSystemEncryption (hid)))
{
AddComboPair (GetDlgItem (hwndDlg, IDC_COMBO_BOX_HASH_ALGO), HashGetName(hid), hid);
++x;
}
}
hash_algo = rand() % x + 1;
}
else
{
@ -4207,6 +4218,8 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (!HashIsDeprecated (hid))
AddComboPair (GetDlgItem (hwndDlg, IDC_COMBO_BOX_HASH_ALGO), HashGetName(hid), hid);
}
hash_algo = rand() % 5 + 1;
}
SelectAlgo (GetDlgItem (hwndDlg, IDC_COMBO_BOX_HASH_ALGO), &hash_algo);

View File

@ -10,7 +10,7 @@ signature = "$Windows NT$"
Class = "Encryption" ;This is determined by the work this filter driver does
ClassGuid = {a0a701c0-a511-42ff-aa6c-06dc0395576f} ;This value is determined by the Class
Provider = %ProviderString%
DriverVer = 11/19/2024,1.26.17.0
DriverVer = 11/24/2024,1.26.17.1
CatalogFile = veracrypt.cat
PnpLockdown = 1