diff options
Diffstat (limited to 'src/Driver')
-rw-r--r-- | src/Driver/DriveFilter.c | 266 | ||||
-rw-r--r-- | src/Driver/DriveFilter.h | 3 | ||||
-rw-r--r-- | src/Driver/Driver.rc | 8 | ||||
-rw-r--r-- | src/Driver/Driver.vcxproj | 16 | ||||
-rw-r--r-- | src/Driver/Driver.vcxproj.filters | 48 | ||||
-rw-r--r-- | src/Driver/DumpFilter.c | 4 | ||||
-rw-r--r-- | src/Driver/EncryptedIoQueue.c | 105 | ||||
-rw-r--r-- | src/Driver/EncryptedIoQueue.h | 6 | ||||
-rw-r--r-- | src/Driver/Fuse/Driver.make | 2 | ||||
-rw-r--r-- | src/Driver/Fuse/FuseService.cpp | 19 | ||||
-rw-r--r-- | src/Driver/Fuse/FuseService.h | 2 | ||||
-rw-r--r-- | src/Driver/Ntdriver.c | 1405 | ||||
-rw-r--r-- | src/Driver/Ntdriver.h | 17 | ||||
-rw-r--r-- | src/Driver/Ntvol.c | 152 | ||||
-rw-r--r-- | src/Driver/VolumeFilter.c | 60 | ||||
-rw-r--r-- | src/Driver/veracrypt_vs2019.vcxproj | 598 | ||||
-rw-r--r-- | src/Driver/veracrypt_vs2019.vcxproj.filters | 326 |
17 files changed, 2657 insertions, 380 deletions
diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c index 08bebe18..49d62126 100644 --- a/src/Driver/DriveFilter.c +++ b/src/Driver/DriveFilter.c @@ -28,6 +28,8 @@ #include "DriveFilter.h" #include "Boot/Windows/BootCommon.h" #include "cpu.h" +#include "rdrand.h" +#include "chachaRng.h" static BOOL DeviceFilterActive = FALSE; @@ -73,23 +75,26 @@ static int64 DecoySystemWipedAreaEnd; PKTHREAD DecoySystemWipeThread = NULL; static NTSTATUS DecoySystemWipeResult; -uint64 BootArgsRegions[] = { EFI_BOOTARGS_REGIONS }; +static uint64 BootArgsRegionsDefault[] = { EFI_BOOTARGS_REGIONS_DEFAULT }; +static uint64 BootArgsRegionsEFI[] = { EFI_BOOTARGS_REGIONS_EFI }; -NTSTATUS LoadBootArguments () +NTSTATUS LoadBootArguments (BOOL bIsEfi) { NTSTATUS status = STATUS_UNSUCCESSFUL; PHYSICAL_ADDRESS bootArgsAddr; byte *mappedBootArgs; byte *mappedCryptoInfo = NULL; uint16 bootLoaderArgsIndex; + uint64* BootArgsRegionsPtr = bIsEfi? BootArgsRegionsEFI : BootArgsRegionsDefault; + size_t BootArgsRegionsCount = bIsEfi? sizeof(BootArgsRegionsEFI)/ sizeof(BootArgsRegionsEFI[0]) : sizeof(BootArgsRegionsDefault)/ sizeof(BootArgsRegionsDefault[0]); KeInitializeMutex (&MountMutex, 0); // __debugbreak(); for (bootLoaderArgsIndex = 0; - bootLoaderArgsIndex < sizeof(BootArgsRegions)/ sizeof(BootArgsRegions[1]) && status != STATUS_SUCCESS; + bootLoaderArgsIndex < BootArgsRegionsCount && status != STATUS_SUCCESS; ++bootLoaderArgsIndex) { - bootArgsAddr.QuadPart = BootArgsRegions[bootLoaderArgsIndex] + TC_BOOT_LOADER_ARGS_OFFSET; + bootArgsAddr.QuadPart = BootArgsRegionsPtr[bootLoaderArgsIndex] + TC_BOOT_LOADER_ARGS_OFFSET; Dump ("Checking BootArguments at 0x%x\n", bootArgsAddr.LowPart); mappedBootArgs = MmMapIoSpace (bootArgsAddr, sizeof (BootArguments), MmCached); @@ -114,9 +119,9 @@ NTSTATUS LoadBootArguments () } // Sanity check: for valid boot argument, the password is less than 64 bytes long - if (bootArguments->BootPassword.Length <= MAX_PASSWORD) + if (bootArguments->BootPassword.Length <= MAX_LEGACY_PASSWORD) { - BootLoaderArgsPtr = BootArgsRegions[bootLoaderArgsIndex]; + BootLoaderArgsPtr = BootArgsRegionsPtr[bootLoaderArgsIndex]; BootArgs = *bootArguments; BootArgsValid = TRUE; @@ -215,7 +220,7 @@ NTSTATUS LoadBootArguments () NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) { - DriveFilterExtension *Extension; + DriveFilterExtension *Extension = NULL; NTSTATUS status; PDEVICE_OBJECT filterDeviceObject = NULL; PDEVICE_OBJECT attachedDeviceObject; @@ -270,7 +275,7 @@ NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) err: if (filterDeviceObject) { - if (Extension->LowerDeviceObject) + if (Extension && Extension->LowerDeviceObject) IoDetachDevice (Extension->LowerDeviceObject); IoDeleteDevice (filterDeviceObject); @@ -288,13 +293,40 @@ static void DismountDrive (DriveFilterExtension *Extension, BOOL stopIoQueue) if (stopIoQueue && EncryptedIoQueueIsRunning (&Extension->Queue)) EncryptedIoQueueStop (&Extension->Queue); - crypto_close (Extension->Queue.CryptoInfo); + crypto_close ((PCRYPTO_INFO) Extension->Queue.CryptoInfo); Extension->Queue.CryptoInfo = NULL; - crypto_close (Extension->HeaderCryptoInfo); + crypto_close ((PCRYPTO_INFO) Extension->HeaderCryptoInfo); Extension->HeaderCryptoInfo = NULL; Extension->DriveMounted = FALSE; + + Dump ("Drive dismount done!\n"); +} + +static void InvalidateVolumeKeys (EXTENSION *Extension) +{ + Dump ("Invalidating volume encryption keys\n"); + + Extension->Queue.ThreadBlockReadWrite = TRUE; + + crypto_eraseKeys ((PCRYPTO_INFO) Extension->Queue.CryptoInfo); + crypto_eraseKeys ((PCRYPTO_INFO) Extension->cryptoInfo); + + Dump ("Volume encryption keys invalidated!\n"); +} + +static void InvalidateDriveFilterKeys (DriveFilterExtension *Extension) +{ + Dump ("Invalidating drive filter encryption keys\n"); + ASSERT (Extension->DriveMounted); + + Extension->Queue.ThreadBlockReadWrite = TRUE; + + crypto_eraseKeys ((PCRYPTO_INFO) Extension->Queue.CryptoInfo); + crypto_eraseKeys ((PCRYPTO_INFO) Extension->HeaderCryptoInfo); + + Dump ("Drive filter encryption keys invalidated!\n"); } static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* ioBuffer /* ioBuffer must be at least 512 bytes long */) @@ -330,8 +362,8 @@ static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; #ifdef _WIN64 XSTATE_SAVE SaveState; - if (g_isIntel && HasSAVX()) - saveStatus = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState); + if (IsCpuIntel() && HasSAVX()) + saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); #else KFLOATING_SAVE floatingPointState; if (HasISSE() || (HasSSSE3() && HasMMX())) @@ -373,7 +405,7 @@ static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* if (NT_SUCCESS (saveStatus)) #ifdef _WIN64 - KeRestoreExtendedProcessorState(&SaveState); + KeRestoreExtendedProcessorStateVC(&SaveState); #else KeRestoreFloatingPointState (&floatingPointState); #endif @@ -488,7 +520,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, pim = (int) (BootArgs.Flags >> 16); - if (ReadVolumeHeader (!hiddenVolume, header, password, pkcs5_prf, pim, FALSE, &Extension->Queue.CryptoInfo, Extension->HeaderCryptoInfo) == 0) + if (ReadVolumeHeader (!hiddenVolume, header, password, pkcs5_prf, pim, &Extension->Queue.CryptoInfo, Extension->HeaderCryptoInfo) == 0) { // Header decrypted status = STATUS_SUCCESS; @@ -567,7 +599,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, for(i = 0; i<pwdCache->Count; ++i){ if (CacheBootPassword && pwdCache->Pwd[i].Length > 0) { int cachedPim = CacheBootPim? (int) (pwdCache->Pim[i]) : 0; - AddPasswordToCache (&pwdCache->Pwd[i], cachedPim); + AddLegacyPasswordToCache (&pwdCache->Pwd[i], cachedPim); } } burn(pwdCache, sizeof(*pwdCache)); @@ -579,7 +611,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, if (CacheBootPassword && BootArgs.BootPassword.Length > 0) { int cachedPim = CacheBootPim? pim : 0; - AddPasswordToCache (&BootArgs.BootPassword, cachedPim); + AddLegacyPasswordToCache (&BootArgs.BootPassword, cachedPim); } burn (&BootArgs.BootPassword, sizeof (BootArgs.BootPassword)); @@ -610,6 +642,15 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, } else Extension->Queue.MaxReadAheadOffset = BootDriveLength; + + /* encrypt keys */ +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + VcProtectKeys (Extension->HeaderCryptoInfo, VcGetEncryptionID (Extension->HeaderCryptoInfo)); + VcProtectKeys (Extension->Queue.CryptoInfo, VcGetEncryptionID (Extension->Queue.CryptoInfo)); + } +#endif status = EncryptedIoQueueStart (&Extension->Queue); if (!NT_SUCCESS (status)) @@ -619,6 +660,12 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, { CrashDumpEnabled = TRUE; HibernationEnabled = TRUE; +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + HibernationEnabled = FALSE; + } +#endif } else if (!LegacyHibernationDriverFilterActive) StartLegacyHibernationDriverFilter(); @@ -681,8 +728,18 @@ static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension) uint32 headerCrc32; uint64 encryptedAreaLength = Extension->Queue.EncryptedAreaEnd + 1 - Extension->Queue.EncryptedAreaStart; byte *fieldPos = header + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH; + PCRYPTO_INFO pCryptoInfo = Extension->HeaderCryptoInfo; +#ifdef _WIN64 + CRYPTO_INFO tmpCI; + if (IsRamEncryptionEnabled()) + { + memcpy (&tmpCI, pCryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (pCryptoInfo)); + pCryptoInfo = &tmpCI; + } +#endif - DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, Extension->HeaderCryptoInfo); + DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, pCryptoInfo); if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241) { @@ -697,7 +754,13 @@ static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension) fieldPos = header + TC_HEADER_OFFSET_HEADER_CRC; mputLong (fieldPos, headerCrc32); - EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, Extension->HeaderCryptoInfo); + EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, pCryptoInfo); +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + burn (&tmpCI, sizeof (CRYPTO_INFO)); + } +#endif } status = TCWriteDevice (Extension->LowerDeviceObject, header, offset, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); @@ -781,7 +844,13 @@ static void CheckDeviceTypeAndMount (DriveFilterExtension *filterExtension) TC_BUG_CHECK (status); if (!BootDriveFound) - MountDrive (filterExtension, &BootArgs.BootPassword, &BootArgs.HeaderSaltCrc32); + { + Password bootPass = {0}; + bootPass.Length = BootArgs.BootPassword.Length; + memcpy (bootPass.Text, BootArgs.BootPassword.Text, BootArgs.BootPassword.Length); + MountDrive (filterExtension, &bootPass, &BootArgs.HeaderSaltCrc32); + burn (&bootPass, sizeof (bootPass)); + } KeReleaseMutex (&MountMutex, FALSE); } @@ -917,16 +986,20 @@ static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilte while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP, NULL, 0, NULL, 0) == STATUS_INSUFFICIENT_RESOURCES); } -#if 0 // Dismount of the system drive is disabled until there is a way to do it without causing system errors (see the documentation for more info) + // Dismount the system drive on shutdown on Windows 7 and later if (DriverShuttingDown + && EraseKeysOnShutdown + && IsOSAtLeast (WIN_7) && Extension->BootDrive && Extension->DriveMounted && irpSp->MinorFunction == IRP_MN_SET_POWER && irpSp->Parameters.Power.Type == DevicePowerState) { DismountDrive (Extension, TRUE); +#ifdef _WIN64 + ClearSecurityParameters (); +#endif } -#endif // 0 PoStartNextPowerIrp (Irp); @@ -941,6 +1014,51 @@ static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilte return status; } +static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterExtension *Extension, PIO_STACK_LOCATION irpSp) +{ + BOOL bBlockTrim = BlockSystemTrimCommand || IsHiddenSystemRunning(); + NTSTATUS status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); + if (!NT_SUCCESS (status)) + return TCCompleteIrp (Irp, status, 0); + + switch (irpSp->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES: + Dump ("DriverFilter-DispatchControl: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES\n"); + if (bBlockTrim) + { + PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); + DWORD inputLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; + if (inputLength >= sizeof (DEVICE_MANAGE_DATA_SET_ATTRIBUTES)) + { + PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pInputAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer; + DEVICE_DATA_MANAGEMENT_SET_ACTION action = pInputAttrs->Action; + if (action == DeviceDsmAction_Trim) + { + Dump ("DriverFilter-DispatchControl: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Trim.\n"); + + if (bBlockTrim) + { + Dump ("DriverFilter-DispatchControl:: TRIM command blocked.\n"); + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); + } + } + } + } + break; + case IOCTL_DISK_GROW_PARTITION: + Dump ("DriverFilter-DispatchControl: IOCTL_DISK_GROW_PARTITION blocked\n"); + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return TCCompleteDiskIrp (Irp, STATUS_UNSUCCESSFUL, 0); + break; + } + + status = PassIrp (Extension->LowerDeviceObject, Irp); + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return status; +} + NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) { @@ -970,6 +1088,9 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) case IRP_MJ_POWER: return DispatchPower (DeviceObject, Irp, Extension, irpSp); + + case IRP_MJ_DEVICE_CONTROL: + return DispatchControl (DeviceObject, Irp, Extension, irpSp); } status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); @@ -982,6 +1103,40 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) return status; } +void EmergencyClearAllKeys (PIRP irp, PIO_STACK_LOCATION irpSp) +{ + irp->IoStatus.Information = 0; + + if (!IoIsSystemThread (PsGetCurrentThread()) && !UserCanAccessDriveDevice()) + { + irp->IoStatus.Status = STATUS_ACCESS_DENIED; + } + else + { + int drive; + for (drive = MIN_MOUNTED_VOLUME_DRIVE_NUMBER; drive <= MAX_MOUNTED_VOLUME_DRIVE_NUMBER; ++drive) + { + PDEVICE_OBJECT device = GetVirtualVolumeDeviceObject (drive); + if (device) + { + PEXTENSION extension = (PEXTENSION) device->DeviceExtension; + if (extension) + { + InvalidateVolumeKeys (extension); + } + } + } + + if (BootDriveFound && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted) + InvalidateDriveFilterKeys (BootDriveFilterExtension); + +#ifdef _WIN64 + ClearSecurityParameters(); +#endif + + irp->IoStatus.Status = STATUS_SUCCESS; + } +} void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) { @@ -1001,7 +1156,7 @@ void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) return; if (!BootDriveFound || !BootDriveFilterExtension || !BootDriveFilterExtension->DriveMounted || !BootDriveFilterExtension->HeaderCryptoInfo - || request->VolumePassword.Length > MAX_PASSWORD + || request->VolumePassword.Length > MAX_LEGACY_PASSWORD || request->pkcs5_prf < 0 || request->pkcs5_prf > LAST_PRF_ID || request->pim < 0 @@ -1031,12 +1186,24 @@ void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) goto ret; } - if (ReadVolumeHeader (!BootDriveFilterExtension->HiddenSystem, header, &request->VolumePassword, request->pkcs5_prf, request->pim, FALSE, NULL, BootDriveFilterExtension->HeaderCryptoInfo) == 0) +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + VcUnprotectKeys (BootDriveFilterExtension->HeaderCryptoInfo, VcGetEncryptionID (BootDriveFilterExtension->HeaderCryptoInfo)); + } +#endif + + if (ReadVolumeHeader (!BootDriveFilterExtension->HiddenSystem, header, &request->VolumePassword, request->pkcs5_prf, request->pim, NULL, BootDriveFilterExtension->HeaderCryptoInfo) == 0) { Dump ("Header reopened\n"); +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + VcProtectKeys (BootDriveFilterExtension->HeaderCryptoInfo, VcGetEncryptionID(BootDriveFilterExtension->HeaderCryptoInfo)); + } +#endif ComputeBootLoaderFingerprint (BootDriveFilterExtension->LowerDeviceObject, header); - - BootDriveFilterExtension->Queue.CryptoInfo->header_creation_time = BootDriveFilterExtension->HeaderCryptoInfo->header_creation_time; + BootDriveFilterExtension->Queue.CryptoInfo->pkcs5 = BootDriveFilterExtension->HeaderCryptoInfo->pkcs5; BootDriveFilterExtension->Queue.CryptoInfo->noIterations = BootDriveFilterExtension->HeaderCryptoInfo->noIterations; BootDriveFilterExtension->Queue.CryptoInfo->volumePim = BootDriveFilterExtension->HeaderCryptoInfo->volumePim; @@ -1151,7 +1318,7 @@ static NTSTATUS HiberDriverWriteFunctionFilter (int filterNumber, PLARGE_INTEGER if (BootDriveFilterExtension->Queue.RemapEncryptedArea) dataUnit.Value += BootDriveFilterExtension->Queue.RemappedAreaDataUnitOffset; - EncryptDataUnitsCurrentThread (HibernationWriteBuffer + (intersectStart - offset), + EncryptDataUnitsCurrentThreadEx (HibernationWriteBuffer + (intersectStart - offset), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, BootDriveFilterExtension->Queue.CryptoInfo); @@ -1415,33 +1582,17 @@ static VOID SetupThreadProc (PVOID threadArg) // generate real random values for wipeRandChars and // wipeRandCharsUpdate instead of relying on uninitialized stack memory - LARGE_INTEGER iSeed; - KeQuerySystemTime( &iSeed ); - if (KeGetCurrentIrql() < DISPATCH_LEVEL) - { - ULONG ulRandom; - ulRandom = RtlRandomEx( &iSeed.LowPart ); - memcpy (wipeRandChars, &ulRandom, TC_WIPE_RAND_CHAR_COUNT); - ulRandom = RtlRandomEx( &ulRandom ); - memcpy (wipeRandCharsUpdate, &ulRandom, TC_WIPE_RAND_CHAR_COUNT); - burn (&ulRandom, sizeof(ulRandom)); - } - else - { - byte digest[SHA512_DIGESTSIZE]; - sha512_ctx tctx; - sha512_begin (&tctx); - sha512_hash ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); - sha512_end (digest, &tctx); + ChaCha20RngCtx rngCtx; + byte pbSeed[CHACHA20RNG_KEYSZ + CHACHA20RNG_IVSZ]; - memcpy (wipeRandChars, digest, TC_WIPE_RAND_CHAR_COUNT); - memcpy (wipeRandCharsUpdate, &digest[SHA512_DIGESTSIZE - TC_WIPE_RAND_CHAR_COUNT], TC_WIPE_RAND_CHAR_COUNT); + GetDriverRandomSeed (pbSeed, sizeof (pbSeed)); + ChaCha20RngInit (&rngCtx, pbSeed, GetDriverRandomSeed, 0); - burn (digest, SHA512_DIGESTSIZE); - burn (&tctx, sizeof (tctx)); - } - - burn (&iSeed, sizeof(iSeed)); + ChaCha20RngGetBytes (&rngCtx, wipeRandChars, TC_WIPE_RAND_CHAR_COUNT); + ChaCha20RngGetBytes (&rngCtx, wipeRandCharsUpdate, TC_WIPE_RAND_CHAR_COUNT); + + burn (&rngCtx, sizeof (rngCtx)); + FAST_ERASE64 (pbSeed, sizeof (pbSeed)); SetupResult = STATUS_UNSUCCESSFUL; @@ -1962,8 +2113,8 @@ void GetBootEncryptionAlgorithmName (PIRP irp, PIO_STACK_LOCATION irpSp) wchar_t BootEncryptionAlgorithmNameW[256]; wchar_t BootPrfAlgorithmNameW[256]; GetBootEncryptionAlgorithmNameRequest *request = (GetBootEncryptionAlgorithmNameRequest *) irp->AssociatedIrp.SystemBuffer; - EAGetName (BootEncryptionAlgorithmNameW, BootDriveFilterExtension->Queue.CryptoInfo->ea, 0); - HashGetName2 (BootPrfAlgorithmNameW, BootDriveFilterExtension->Queue.CryptoInfo->pkcs5); + EAGetName (BootEncryptionAlgorithmNameW, 256, BootDriveFilterExtension->Queue.CryptoInfo->ea, 0); + HashGetName2 (BootPrfAlgorithmNameW, 256, BootDriveFilterExtension->Queue.CryptoInfo->pkcs5); RtlStringCbPrintfA (request->BootEncryptionAlgorithmName, sizeof (request->BootEncryptionAlgorithmName), "%S", BootEncryptionAlgorithmNameW); RtlStringCbPrintfA (request->BootPrfAlgorithmName, sizeof (request->BootPrfAlgorithmName), "%S", BootPrfAlgorithmNameW); @@ -2082,15 +2233,18 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg) DecoySystemWipeResult = STATUS_INVALID_PARAMETER; goto ret; } - - memcpy (wipeCryptoInfo->k2, WipeDecoyRequest.WipeKey + EAGetKeySize (ea), EAGetKeySize (ea)); - if (!EAInitMode (wipeCryptoInfo)) + if (!EAInitMode (wipeCryptoInfo, WipeDecoyRequest.WipeKey + EAGetKeySize (ea))) { DecoySystemWipeResult = STATUS_INVALID_PARAMETER; goto err; } +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + VcProtectKeys (wipeCryptoInfo, VcGetEncryptionID (wipeCryptoInfo)); +#endif + EncryptDataUnits (wipeRandBuffer, &dataUnit, wipeBlockSize / ENCRYPTION_DATA_UNIT_SIZE, wipeCryptoInfo); memcpy (wipeRandChars, wipeRandBuffer, sizeof (wipeRandChars)); diff --git a/src/Driver/DriveFilter.h b/src/Driver/DriveFilter.h index 9ce151c7..b164fa5b 100644 --- a/src/Driver/DriveFilter.h +++ b/src/Driver/DriveFilter.h @@ -70,9 +70,10 @@ CRYPTO_INFO *GetSystemDriveCryptoInfo (); BOOL IsBootDriveMounted (); BOOL IsBootEncryptionSetupInProgress (); BOOL IsHiddenSystemRunning (); -NTSTATUS LoadBootArguments (); +NTSTATUS LoadBootArguments (BOOL bIsEfi); static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension); NTSTATUS StartBootEncryptionSetup (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp); +void EmergencyClearAllKeys (PIRP irp, PIO_STACK_LOCATION irpSp); void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp); NTSTATUS StartDecoySystemWipe (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp); void StartLegacyHibernationDriverFilter (); diff --git a/src/Driver/Driver.rc b/src/Driver/Driver.rc index 69952f34..ed2e4560 100644 --- a/src/Driver/Driver.rc +++ b/src/Driver/Driver.rc @@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,22,3,0 - PRODUCTVERSION 1,22,3,0 + FILEVERSION 1,26,10,0 + PRODUCTVERSION 1,26,10,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,11 +45,11 @@ BEGIN BEGIN VALUE "CompanyName", "IDRIX" VALUE "FileDescription", "VeraCrypt Driver" - VALUE "FileVersion", "1.22" + VALUE "FileVersion", "1.26.10" VALUE "LegalTrademarks", "VeraCrypt" VALUE "OriginalFilename", "veracrypt.sys" VALUE "ProductName", "VeraCrypt" - VALUE "ProductVersion", "1.22" + VALUE "ProductVersion", "1.26.10" END END BLOCK "VarFileInfo" diff --git a/src/Driver/Driver.vcxproj b/src/Driver/Driver.vcxproj index 381d2083..7c92f05b 100644 --- a/src/Driver/Driver.vcxproj +++ b/src/Driver/Driver.vcxproj @@ -192,9 +192,22 @@ BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Cry <ItemDefinitionGroup> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\Crypto\blake2s.c" /> + <ClCompile Include="..\Crypto\blake2s_SSE2.c" /> + <ClCompile Include="..\Crypto\blake2s_SSE41.c" /> + <ClCompile Include="..\Crypto\blake2s_SSSE3.c" /> <ClCompile Include="..\Crypto\Camellia.c" /> + <ClCompile Include="..\Crypto\chacha-xmm.c" /> + <ClCompile Include="..\Crypto\chacha256.c" /> + <ClCompile Include="..\Crypto\chachaRng.c" /> + <ClCompile Include="..\Crypto\jitterentropy-base.c" /> + <ClCompile Include="..\Crypto\rdrand.c" /> <ClCompile Include="..\Crypto\SerpentFast.c" /> <ClCompile Include="..\Crypto\SerpentFast_simd.cpp" /> + <ClCompile Include="..\Crypto\Streebog.c" /> + <ClCompile Include="..\Crypto\t1ha2.c" /> + <ClCompile Include="..\Crypto\t1ha2_selfcheck.c" /> + <ClCompile Include="..\Crypto\t1ha_selfcheck.c" /> <ClCompile Include="DriveFilter.c" /> <ClCompile Include="DumpFilter.c" /> <ClCompile Include="EncryptedIoQueue.c" /> @@ -214,7 +227,6 @@ BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Cry <ClCompile Include="..\Common\Xts.c" /> <ClCompile Include="..\Crypto\Aeskey.c" /> <ClCompile Include="..\Crypto\Aestab.c" /> - <ClCompile Include="..\Crypto\Rmd160.c" /> <ClCompile Include="..\Crypto\Sha2.c" /> <ClCompile Include="..\Crypto\Twofish.c" /> <ClCompile Include="..\Crypto\Whirlpool.c" /> @@ -225,6 +237,7 @@ BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Cry <None Include="..\Crypto\Aes_x86.asm" /> <None Include="..\Crypto\Camellia_aesni_x64.S" /> <None Include="..\Crypto\Camellia_x64.S" /> + <None Include="..\Crypto\rdrand_ml.asm" /> <None Include="..\Crypto\sha256-x86-nayuki.S"> <FileType>Document</FileType> </None> @@ -266,6 +279,7 @@ BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Cry <ClInclude Include="..\Common\Apidrvr.h" /> <ClInclude Include="..\Common\Cache.h" /> <ClInclude Include="..\Common\Common.h" /> + <ClInclude Include="..\Crypto\rdrand.h" /> <ClInclude Include="DriveFilter.h" /> <ClInclude Include="DumpFilter.h" /> <ClInclude Include="EncryptedIoQueue.h" /> diff --git a/src/Driver/Driver.vcxproj.filters b/src/Driver/Driver.vcxproj.filters index 3622c7a8..41d7a8c4 100644 --- a/src/Driver/Driver.vcxproj.filters +++ b/src/Driver/Driver.vcxproj.filters @@ -87,9 +87,6 @@ <ClCompile Include="..\Crypto\Aestab.c"> <Filter>Source Files\Crypto</Filter> </ClCompile> - <ClCompile Include="..\Crypto\Rmd160.c"> - <Filter>Source Files\Crypto</Filter> - </ClCompile> <ClCompile Include="..\Crypto\Sha2.c"> <Filter>Source Files\Crypto</Filter> </ClCompile> @@ -108,6 +105,45 @@ <ClCompile Include="..\Crypto\SerpentFast_simd.cpp"> <Filter>Source Files\Crypto</Filter> </ClCompile> + <ClCompile Include="..\Crypto\rdrand.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chacha256.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chachaRng.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chacha-xmm.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Streebog.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\jitterentropy-base.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha_selfcheck.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha2.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha2_selfcheck.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s_SSE2.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s_SSE41.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s_SSSE3.c"> + <Filter>Source Files\Crypto</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <None Include="..\Crypto\Aes_hw_cpu.asm"> @@ -179,6 +215,9 @@ <None Include="..\Crypto\sha512_avx2_x64.asm"> <Filter>Source Files\Crypto</Filter> </None> + <None Include="..\Crypto\rdrand_ml.asm"> + <Filter>Source Files\Crypto</Filter> + </None> </ItemGroup> <ItemGroup> <ClInclude Include="..\Common\Apidrvr.h"> @@ -229,6 +268,9 @@ <ClInclude Include="..\Common\Xts.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\Crypto\rdrand.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="Driver.rc"> diff --git a/src/Driver/DumpFilter.c b/src/Driver/DumpFilter.c index 2b58d061..725a4fe0 100644 --- a/src/Driver/DumpFilter.c +++ b/src/Driver/DumpFilter.c @@ -127,7 +127,7 @@ NTSTATUS DumpFilterEntry (PFILTER_EXTENSION filterExtension, PFILTER_INITIALIZAT goto err; } - WriteFilterBufferSize = filterInitData->MaxPagesPerWrite * PAGE_SIZE; + WriteFilterBufferSize = ((SIZE_T)filterInitData->MaxPagesPerWrite) * PAGE_SIZE; #ifdef _WIN64 highestAcceptableWriteBufferAddr.QuadPart = 0x7FFffffFFFFLL; @@ -218,7 +218,7 @@ static NTSTATUS DumpFilterWrite (PFILTER_EXTENSION filterExtension, PLARGE_INTEG dataUnit.Value += BootDriveFilterExtension->Queue.RemappedAreaDataUnitOffset; } - EncryptDataUnitsCurrentThread (WriteFilterBuffer + (intersectStart - offset), + EncryptDataUnitsCurrentThreadEx (WriteFilterBuffer + (intersectStart - offset), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, BootDriveFilterExtension->Queue.CryptoInfo); diff --git a/src/Driver/EncryptedIoQueue.c b/src/Driver/EncryptedIoQueue.c index f7e453fd..bdf139a1 100644 --- a/src/Driver/EncryptedIoQueue.c +++ b/src/Driver/EncryptedIoQueue.c @@ -383,7 +383,9 @@ static VOID IoThreadProc (PVOID threadArg) // Perform IO request if no preceding request of the item failed if (NT_SUCCESS (request->Item->Status)) { - if (queue->IsFilterDevice) + if (queue->ThreadBlockReadWrite) + request->Item->Status = STATUS_DEVICE_BUSY; + else if (queue->IsFilterDevice) { if (queue->RemapEncryptedArea && request->EncryptedLength > 0) { @@ -396,7 +398,7 @@ static VOID IoThreadProc (PVOID threadArg) for (subFragment = 0 ; subFragment < 3; ++subFragment) { LARGE_INTEGER subFragmentOffset; - ULONG subFragmentLength; + ULONG subFragmentLength = 0; subFragmentOffset.QuadPart = request->Offset.QuadPart; switch (subFragment) @@ -773,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); @@ -794,7 +797,7 @@ static VOID MainThreadProc (PVOID threadArg) request->OrigDataBufferFragment = dataBuffer; request->Length = dataFragmentLength; - if (queue->IsFilterDevice) + if (queue->IsFilterDevice || queue->bSupportPartialEncryption) { if (queue->EncryptedAreaStart == -1 || queue->EncryptedAreaEnd == -1) { @@ -845,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; } } } @@ -969,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; @@ -984,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 c4a105e8..2ab9dc5b 100644 --- a/src/Driver/EncryptedIoQueue.h +++ b/src/Driver/EncryptedIoQueue.h @@ -24,6 +24,7 @@ #define TC_ENC_IO_QUEUE_PREALLOCATED_ITEM_COUNT 8 #define TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_COUNT 16 +#define TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_MAX_COUNT 8192 typedef struct EncryptedIoQueueBufferStruct @@ -48,6 +49,7 @@ typedef struct // File-handle-based IO HANDLE HostFileHandle; + BOOL bSupportPartialEncryption; int64 VirtualDeviceLength; SECURITY_CLIENT_CONTEXT *SecurityClientContext; @@ -119,6 +121,10 @@ typedef struct byte* SecRegionData; SIZE_T SecRegionSize; + + volatile BOOL ThreadBlockReadWrite; + + int FragmentSize; } EncryptedIoQueue; diff --git a/src/Driver/Fuse/Driver.make b/src/Driver/Fuse/Driver.make index f58785b9..b3640115 100644 --- a/src/Driver/Fuse/Driver.make +++ b/src/Driver/Fuse/Driver.make @@ -15,6 +15,6 @@ NAME := Driver OBJS := OBJS += FuseService.o -CXXFLAGS += $(shell pkg-config fuse --cflags) +CXXFLAGS += $(shell $(PKG_CONFIG) fuse --cflags) include $(BUILD_INC)/Makefile.inc diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp index 026883d1..bc3d1023 100644 --- a/src/Driver/Fuse/FuseService.cpp +++ b/src/Driver/Fuse/FuseService.cpp @@ -10,7 +10,12 @@ code distribution packages. */ +#ifdef TC_OPENBSD +#define FUSE_USE_VERSION 26 +#else #define FUSE_USE_VERSION 25 +#endif + #include <errno.h> #include <fcntl.h> #include <fuse.h> @@ -51,7 +56,11 @@ namespace VeraCrypt return 0; } +#ifdef TC_OPENBSD + static void *fuse_service_init (struct fuse_conn_info *) +#else static void *fuse_service_init () +#endif { try { @@ -221,7 +230,7 @@ namespace VeraCrypt FuseService::ReadVolumeSectors (BufferPtr ((byte *) buf, size), offset); } } - catch (MissingVolumeData) + catch (MissingVolumeData&) { return 0; } @@ -350,7 +359,7 @@ namespace VeraCrypt { throw; } - catch (std::bad_alloc) + catch (std::bad_alloc&) { return -ENOMEM; } @@ -583,7 +592,11 @@ namespace VeraCrypt SignalHandlerPipe->GetWriteFD(); +#ifdef TC_OPENBSD + _exit (fuse_main (argc, argv, &fuse_service_oper, NULL)); +#else _exit (fuse_main (argc, argv, &fuse_service_oper)); +#endif } VolumeInfo FuseService::OpenVolumeInfo; @@ -592,5 +605,5 @@ namespace VeraCrypt VolumeSlotNumber FuseService::SlotNumber; uid_t FuseService::UserId; gid_t FuseService::GroupId; - auto_ptr <Pipe> FuseService::SignalHandlerPipe; + unique_ptr <Pipe> FuseService::SignalHandlerPipe; } diff --git a/src/Driver/Fuse/FuseService.h b/src/Driver/Fuse/FuseService.h index 4b844013..872cb368 100644 --- a/src/Driver/Fuse/FuseService.h +++ b/src/Driver/Fuse/FuseService.h @@ -70,7 +70,7 @@ namespace VeraCrypt static VolumeSlotNumber SlotNumber; static uid_t UserId; static gid_t GroupId; - static auto_ptr <Pipe> SignalHandlerPipe; + static unique_ptr <Pipe> SignalHandlerPipe; }; } diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index 73930404..b337ad86 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -13,6 +13,8 @@ #include "TCdefs.h" #include <ntddk.h> +#include <initguid.h> +#include <Ntddstor.h> #include "Crypto.h" #include "Fat.h" #include "Tests.h" @@ -30,6 +32,9 @@ #include "Cache.h" #include "Volumes.h" #include "VolumeFilter.h" +#include "cpu.h" +#include "rdrand.h" +#include "jitterentropy.h" #include <tchar.h> #include <initguid.h> @@ -69,6 +74,42 @@ #define IOCTL_VOLUME_IS_DYNAMIC CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif +#ifndef StorageDeviceLBProvisioningProperty +#define StorageDeviceLBProvisioningProperty 11 +#endif + +#ifndef DeviceDsmAction_OffloadRead +#define DeviceDsmAction_OffloadRead ( 3 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_OffloadWrite +#define DeviceDsmAction_OffloadWrite 4 +#endif + +#ifndef DeviceDsmAction_Allocation +#define DeviceDsmAction_Allocation ( 5 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_Repair +#define DeviceDsmAction_Repair ( 6 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_Scrub +#define DeviceDsmAction_Scrub ( 7 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_DrtQuery +#define DeviceDsmAction_DrtQuery ( 8 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_DrtClear +#define DeviceDsmAction_DrtClear ( 9 | DeviceDsmActionFlag_NonDestructive) +#endif + +#ifndef DeviceDsmAction_DrtDisable +#define DeviceDsmAction_DrtDisable (10 | DeviceDsmActionFlag_NonDestructive) +#endif + /* Init section, which is thrown away as soon as DriverEntry returns */ #pragma alloc_text(INIT,DriverEntry) #pragma alloc_text(INIT,TCCreateRootDeviceObject) @@ -92,18 +133,166 @@ BOOL VolumeClassFilterRegistered = FALSE; BOOL CacheBootPassword = FALSE; BOOL CacheBootPim = FALSE; BOOL NonAdminSystemFavoritesAccessDisabled = FALSE; +BOOL BlockSystemTrimCommand = FALSE; +BOOL AllowWindowsDefrag = FALSE; +BOOL EraseKeysOnShutdown = TRUE; // by default, we erase encryption keys on system shutdown static size_t EncryptionThreadPoolFreeCpuCountLimit = 0; static BOOL SystemFavoriteVolumeDirty = FALSE; static BOOL PagingFileCreationPrevented = FALSE; static BOOL EnableExtendedIoctlSupport = FALSE; +static BOOL AllowTrimCommand = FALSE; +static BOOL RamEncryptionActivated = FALSE; static KeSaveExtendedProcessorStateFn KeSaveExtendedProcessorStatePtr = NULL; static KeRestoreExtendedProcessorStateFn KeRestoreExtendedProcessorStatePtr = NULL; +static ExGetFirmwareEnvironmentVariableFn ExGetFirmwareEnvironmentVariablePtr = NULL; +static KeQueryInterruptTimePreciseFn KeQueryInterruptTimePrecisePtr = NULL; +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; PDEVICE_OBJECT VirtualVolumeDeviceObjects[MAX_MOUNTED_VOLUME_DRIVE_NUMBER + 1]; +BOOL AlignValue (ULONG ulValue, ULONG ulAlignment, ULONG *pulResult) +{ + BOOL bRet = FALSE; + HRESULT hr; + if (ulAlignment == 0) + { + *pulResult = ulValue; + bRet = TRUE; + } + else + { + ulAlignment -= 1; + hr = ULongAdd (ulValue, ulAlignment, &ulValue); + if (S_OK == hr) + { + *pulResult = ulValue & (~ulAlignment); + bRet = TRUE; + } + } + + return bRet; +} + +BOOL IsUefiBoot () +{ + BOOL bStatus = FALSE; + NTSTATUS ntStatus = STATUS_NOT_IMPLEMENTED; + + Dump ("IsUefiBoot BEGIN\n"); + ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); + + if (ExGetFirmwareEnvironmentVariablePtr) + { + ULONG valueLengh = 0; + UNICODE_STRING emptyName; + GUID guid; + RtlInitUnicodeString(&emptyName, L""); + memset (&guid, 0, sizeof(guid)); + Dump ("IsUefiBoot calling ExGetFirmwareEnvironmentVariable\n"); + ntStatus = ExGetFirmwareEnvironmentVariablePtr (&emptyName, &guid, NULL, &valueLengh, NULL); + Dump ("IsUefiBoot ExGetFirmwareEnvironmentVariable returned 0x%08x\n", ntStatus); + } + else + { + Dump ("IsUefiBoot ExGetFirmwareEnvironmentVariable not found on the system\n"); + } + + if (STATUS_NOT_IMPLEMENTED != ntStatus) + bStatus = TRUE; + + Dump ("IsUefiBoot bStatus = %s END\n", bStatus? "TRUE" : "FALSE"); + return bStatus; +} + +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 uninitialized 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); + if (KeQueryInterruptTimePrecisePtr) + { + iSeed.QuadPart = KeQueryInterruptTimePrecisePtr (&iSeed2.QuadPart); + WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); + WHIRLPOOL_add ((unsigned char *) &(iSeed2.QuadPart), sizeof(iSeed2.QuadPart), &tctx); + } + else + { + iSeed.QuadPart = KeQueryInterruptTime (); + WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); + } + + /* use JitterEntropy library to get good quality random bytes based on CPU timing jitter */ + if (0 == jent_entropy_init ()) + { + struct rand_data *ec = jent_entropy_collector_alloc (1, 0); + if (ec) + { + ssize_t rndLen = jent_read_entropy (ec, (char*) digest, sizeof (digest)); + if (rndLen > 0) + WHIRLPOOL_add (digest, (unsigned int) rndLen, &tctx); + jent_entropy_collector_free (ec); + } + } + + // 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) { @@ -111,7 +300,7 @@ NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) LONG version; int i; - Dump ("DriverEntry " TC_APP_NAME " " VERSION_STRING "\n"); + Dump ("DriverEntry " TC_APP_NAME " " VERSION_STRING VERSION_STRING_SUFFIX "\n"); DetectX86Features (); @@ -126,14 +315,46 @@ NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) ExDefaultMdlProtection = MdlMappingNoExecute; } + // KeAreAllApcsDisabled is available starting from Windows Server 2003 + if ((OsMajorVersion > 5) || (OsMajorVersion == 5 && OsMinorVersion >= 2)) + { + UNICODE_STRING KeAreAllApcsDisabledFuncName; + RtlInitUnicodeString(&KeAreAllApcsDisabledFuncName, L"KeAreAllApcsDisabled"); + + KeAreAllApcsDisabledPtr = (KeAreAllApcsDisabledFn) MmGetSystemRoutineAddress(&KeAreAllApcsDisabledFuncName); + } + // KeSaveExtendedProcessorState/KeRestoreExtendedProcessorState are available starting from Windows 7 + // KeQueryActiveGroupCount/KeQueryActiveProcessorCountEx/KeSetSystemGroupAffinityThread are available starting from Windows 7 if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 1)) { - UNICODE_STRING saveFuncName, restoreFuncName; + UNICODE_STRING saveFuncName, restoreFuncName, groupCountFuncName, procCountFuncName, setAffinityFuncName; RtlInitUnicodeString(&saveFuncName, L"KeSaveExtendedProcessorState"); RtlInitUnicodeString(&restoreFuncName, L"KeRestoreExtendedProcessorState"); + RtlInitUnicodeString(&groupCountFuncName, L"KeQueryActiveGroupCount"); + RtlInitUnicodeString(&procCountFuncName, L"KeQueryActiveProcessorCountEx"); + RtlInitUnicodeString(&setAffinityFuncName, L"KeSetSystemGroupAffinityThread"); KeSaveExtendedProcessorStatePtr = (KeSaveExtendedProcessorStateFn) MmGetSystemRoutineAddress(&saveFuncName); KeRestoreExtendedProcessorStatePtr = (KeRestoreExtendedProcessorStateFn) MmGetSystemRoutineAddress(&restoreFuncName); + KeSetSystemGroupAffinityThreadPtr = (KeSetSystemGroupAffinityThreadFn) MmGetSystemRoutineAddress(&setAffinityFuncName); + KeQueryActiveGroupCountPtr = (KeQueryActiveGroupCountFn) MmGetSystemRoutineAddress(&groupCountFuncName); + KeQueryActiveProcessorCountExPtr = (KeQueryActiveProcessorCountExFn) MmGetSystemRoutineAddress(&procCountFuncName); + } + + // ExGetFirmwareEnvironmentVariable is available starting from Windows 8 + if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 2)) + { + UNICODE_STRING funcName; + RtlInitUnicodeString(&funcName, L"ExGetFirmwareEnvironmentVariable"); + ExGetFirmwareEnvironmentVariablePtr = (ExGetFirmwareEnvironmentVariableFn) MmGetSystemRoutineAddress(&funcName); + } + + // KeQueryInterruptTimePrecise is available starting from Windows 8.1 + if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 3)) + { + UNICODE_STRING funcName; + RtlInitUnicodeString(&funcName, L"KeQueryInterruptTimePrecise"); + KeQueryInterruptTimePrecisePtr = (KeQueryInterruptTimePreciseFn) MmGetSystemRoutineAddress(&funcName); } // Load dump filter if the main driver is already loaded @@ -165,7 +386,7 @@ NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) TC_BUG_CHECK (STATUS_INVALID_PARAMETER); } - LoadBootArguments(); + LoadBootArguments(IsUefiBoot ()); VolumeClassFilterRegistered = IsVolumeClassFilterRegistered(); DriverObject->DriverExtension->AddDevice = DriverAddDevice; @@ -174,6 +395,22 @@ NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) TCfree (startKeyValue); } +#ifdef _WIN64 + if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 1)) + { + // we enable RAM encryption only starting from Windows 7 + if (RamEncryptionActivated) + { + if (t1ha_selfcheck__t1ha2() != 0) + TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + if (!InitializeSecurityParameters(GetDriverRandomSeed)) + TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + + EnableRamEncryption (TRUE); + } + } +#endif + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i) { DriverObject->MajorFunction[i] = TCDispatchQueueIRP; @@ -213,7 +450,7 @@ NTSTATUS DriverAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) return DriveFilterAddDevice (driverObject, pdo); } - +#if defined (DEBUG) || defined (DEBUG_TRACE) // Dumps a memory region to debug output void DumpMemory (void *mem, int size) { @@ -238,6 +475,7 @@ void DumpMemory (void *mem, int size) m+=8; } } +#endif BOOL IsAllZeroes (unsigned char* pbData, DWORD dwDataLen) { @@ -250,6 +488,54 @@ BOOL IsAllZeroes (unsigned char* pbData, DWORD dwDataLen) return TRUE; } +static wchar_t UpperCaseUnicodeChar (wchar_t c) +{ + if (c >= L'a' && c <= L'z') + return (c - L'a') + L'A'; + return c; +} + +static BOOL StringNoCaseCompare (const wchar_t* str1, const wchar_t* str2, size_t len) +{ + if (str1 && str2) + { + while (len) + { + if (UpperCaseUnicodeChar (*str1) != UpperCaseUnicodeChar (*str2)) + return FALSE; + str1++; + str2++; + len--; + } + } + + return TRUE; +} + +static BOOL CheckStringLength (const wchar_t* str, size_t cchSize, size_t minLength, size_t maxLength, size_t* pcchLength) +{ + size_t actualLength; + for (actualLength = 0; actualLength < cchSize; actualLength++) + { + if (str[actualLength] == 0) + break; + } + + if (pcchLength) + *pcchLength = actualLength; + + if (actualLength == cchSize) + return FALSE; + + if ((minLength != ((size_t) -1)) && (actualLength < minLength)) + return FALSE; + + if ((maxLength != ((size_t) -1)) && (actualLength > maxLength)) + return FALSE; + + return TRUE; +} + BOOL ValidateIOBufferSize (PIRP irp, size_t requiredBufferSize, ValidateIOBufferSizeType type) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (irp); @@ -710,6 +996,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION case IOCTL_DISK_GET_MEDIA_TYPES: case IOCTL_DISK_GET_DRIVE_GEOMETRY: + case IOCTL_STORAGE_GET_MEDIA_TYPES: + case IOCTL_DISK_UPDATE_DRIVE_SIZE: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_GEOMETRY)\n"); /* Return the drive geometry for the disk. Note that we return values which were made up to suit the disk size. */ @@ -745,8 +1033,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION outputBuffer->Geometry.TracksPerCylinder = Extension->TracksPerCylinder; outputBuffer->Geometry.SectorsPerTrack = Extension->SectorsPerTrack; outputBuffer->Geometry.BytesPerSector = Extension->BytesPerSector; - /* add one sector to DiskLength since our partition size is DiskLength and its offset if BytesPerSector */ - outputBuffer->DiskSize.QuadPart = Extension->DiskLength + Extension->BytesPerSector; + // Add 1MB to the disk size to emulate the geometry of a real MBR disk + outputBuffer->DiskSize.QuadPart = Extension->DiskLength + BYTES_PER_MB; if (bFullBuffer) { @@ -774,25 +1062,6 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION } break; - case IOCTL_STORAGE_GET_MEDIA_TYPES: - Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_GET_MEDIA_TYPES)\n"); - /* Return the drive geometry for the disk. Note that we - return values which were made up to suit the disk size. */ - if (ValidateIOBufferSize (Irp, sizeof (DISK_GEOMETRY), ValidateOutput)) - { - PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY) - Irp->AssociatedIrp.SystemBuffer; - - outputBuffer->MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia; - outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders; - outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder; - outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack; - outputBuffer->BytesPerSector = Extension->BytesPerSector; - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof (DISK_GEOMETRY); - } - break; - case IOCTL_STORAGE_GET_MEDIA_TYPES_EX: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_GET_MEDIA_TYPES_EX)\n"); if (ValidateIOBufferSize (Irp, sizeof (GET_MEDIA_TYPES), ValidateOutput)) @@ -839,19 +1108,40 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_QUERY_PROPERTY)\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; - if (EnableExtendedIoctlSupport) + if (EnableExtendedIoctlSupport || Extension->TrimEnabled) { if (ValidateIOBufferSize (Irp, sizeof (STORAGE_PROPERTY_QUERY), ValidateInput)) { PSTORAGE_PROPERTY_QUERY pStoragePropQuery = (PSTORAGE_PROPERTY_QUERY) Irp->AssociatedIrp.SystemBuffer; STORAGE_QUERY_TYPE type = pStoragePropQuery->QueryType; - Dump ("IOCTL_STORAGE_QUERY_PROPERTY - PropertyId = %d, type = %d\n", pStoragePropQuery->PropertyId, type); + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - PropertyId = %d, type = %d, InputBufferLength = %d, OutputBufferLength = %d\n", pStoragePropQuery->PropertyId, type, (int) irpSp->Parameters.DeviceIoControl.InputBufferLength, (int) irpSp->Parameters.DeviceIoControl.OutputBufferLength); - /* return error if an unsupported type is encountered */ - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; - - if ( (pStoragePropQuery->PropertyId == StorageAccessAlignmentProperty) + if (Extension->bRawDevice && + (pStoragePropQuery->PropertyId == (STORAGE_PROPERTY_ID) StorageDeviceLBProvisioningProperty) + ) + { + IO_STATUS_BLOCK IoStatus; + Dump ("ProcessVolumeDeviceControlIrp: sending IOCTL_STORAGE_QUERY_PROPERTY (%d) to device\n", (int) pStoragePropQuery->PropertyId); + Irp->IoStatus.Status = ZwDeviceIoControlFile ( + Extension->hDeviceFile, + NULL, + NULL, + NULL, + &IoStatus, + IOCTL_STORAGE_QUERY_PROPERTY, + Irp->AssociatedIrp.SystemBuffer, + irpSp->Parameters.DeviceIoControl.InputBufferLength, + Irp->AssociatedIrp.SystemBuffer, + irpSp->Parameters.DeviceIoControl.OutputBufferLength); + Dump ("ProcessVolumeDeviceControlIrp: ZwDeviceIoControlFile returned 0x%.8X\n", (DWORD) Irp->IoStatus.Status); + if (Irp->IoStatus.Status == STATUS_SUCCESS) + { + Irp->IoStatus.Status = IoStatus.Status; + Irp->IoStatus.Information = IoStatus.Information; + } + } + else if ( (pStoragePropQuery->PropertyId == StorageAccessAlignmentProperty) || (pStoragePropQuery->PropertyId == StorageDeviceProperty) || (pStoragePropQuery->PropertyId == StorageAdapterProperty) || (pStoragePropQuery->PropertyId == StorageDeviceSeekPenaltyProperty) @@ -865,12 +1155,14 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION } else if (type == PropertyStandardQuery) { + ULONG descriptorSize; switch (pStoragePropQuery->PropertyId) { case StorageDeviceProperty: { + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceProperty\n"); /* Add 0x00 for NULL terminating string used as ProductId, ProductRevision, SerialNumber, VendorId */ - ULONG descriptorSize = sizeof (STORAGE_DEVICE_DESCRIPTOR) + 1; + descriptorSize = sizeof (STORAGE_DEVICE_DESCRIPTOR) + 1; if (ValidateIOBufferSize (Irp, descriptorSize, ValidateOutput)) { PSTORAGE_DEVICE_DESCRIPTOR outputBuffer = (PSTORAGE_DEVICE_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; @@ -899,7 +1191,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION break; case StorageAdapterProperty: { - ULONG descriptorSize = sizeof (STORAGE_ADAPTER_DESCRIPTOR); + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageAdapterProperty\n"); + descriptorSize = sizeof (STORAGE_ADAPTER_DESCRIPTOR); if (ValidateIOBufferSize (Irp, descriptorSize, ValidateOutput)) { PSTORAGE_ADAPTER_DESCRIPTOR outputBuffer = (PSTORAGE_ADAPTER_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; @@ -925,6 +1218,7 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION break; case StorageAccessAlignmentProperty: { + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageAccessAlignmentProperty\n"); if (ValidateIOBufferSize (Irp, sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), ValidateOutput)) { PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR outputBuffer = (PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; @@ -948,13 +1242,14 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION break; case StorageDeviceSeekPenaltyProperty: { + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceSeekPenaltyProperty\n"); if (ValidateIOBufferSize (Irp, sizeof (DEVICE_SEEK_PENALTY_DESCRIPTOR), ValidateOutput)) { PDEVICE_SEEK_PENALTY_DESCRIPTOR outputBuffer = (PDEVICE_SEEK_PENALTY_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; - + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceSeekPenaltyProperty: set IncursSeekPenalty to %s\n", Extension->IncursSeekPenalty? "TRUE" : "FALSE"); outputBuffer->Version = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); outputBuffer->Size = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); - outputBuffer->IncursSeekPenalty = TRUE; //TODO: in case of SSD drive, we should probably return FALSE + outputBuffer->IncursSeekPenalty = (BOOLEAN) Extension->IncursSeekPenalty; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (DEVICE_SEEK_PENALTY_DESCRIPTOR); } @@ -970,13 +1265,14 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION break; case StorageDeviceTrimProperty: { + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceTrimProperty\n"); if (ValidateIOBufferSize (Irp, sizeof (DEVICE_TRIM_DESCRIPTOR), ValidateOutput)) { PDEVICE_TRIM_DESCRIPTOR outputBuffer = (PDEVICE_TRIM_DESCRIPTOR) Irp->AssociatedIrp.SystemBuffer; - + Dump ("IOCTL_STORAGE_QUERY_PROPERTY - StorageDeviceTrimProperty: set TrimEnabled to %s\n", Extension->TrimEnabled? "TRUE" : "FALSE"); outputBuffer->Version = sizeof(DEVICE_TRIM_DESCRIPTOR); outputBuffer->Size = sizeof(DEVICE_TRIM_DESCRIPTOR); - outputBuffer->TrimEnabled = FALSE; /* TODO: implement Trim support for SSD drives */ + outputBuffer->TrimEnabled = (BOOLEAN) Extension->TrimEnabled; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (DEVICE_TRIM_DESCRIPTOR); } @@ -993,8 +1289,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION } } } - } - } + } + } break; @@ -1009,7 +1305,7 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION outputBuffer->BootIndicator = FALSE; outputBuffer->RecognizedPartition = TRUE; outputBuffer->RewritePartition = FALSE; - outputBuffer->StartingOffset.QuadPart = Extension->BytesPerSector; + outputBuffer->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; outputBuffer->PartitionNumber = 1; outputBuffer->HiddenSectors = 0; @@ -1026,7 +1322,7 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION outputBuffer->PartitionStyle = PARTITION_STYLE_MBR; outputBuffer->RewritePartition = FALSE; - outputBuffer->StartingOffset.QuadPart = Extension->BytesPerSector; + outputBuffer->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; outputBuffer->PartitionNumber = 1; outputBuffer->Mbr.PartitionType = Extension->PartitionType; @@ -1054,7 +1350,7 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION outputBuffer->PartitionEntry->BootIndicator = FALSE; outputBuffer->PartitionEntry->RecognizedPartition = TRUE; outputBuffer->PartitionEntry->RewritePartition = FALSE; - outputBuffer->PartitionEntry->StartingOffset.QuadPart = Extension->BytesPerSector; + outputBuffer->PartitionEntry->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; outputBuffer->PartitionEntry->PartitionNumber = 1; outputBuffer->PartitionEntry->HiddenSectors = 0; @@ -1090,7 +1386,7 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION outputBuffer->PartitionEntry->Mbr.BootIndicator = FALSE; outputBuffer->PartitionEntry->Mbr.RecognizedPartition = TRUE; outputBuffer->PartitionEntry->RewritePartition = FALSE; - outputBuffer->PartitionEntry->StartingOffset.QuadPart = Extension->BytesPerSector; + outputBuffer->PartitionEntry->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; outputBuffer->PartitionEntry->PartitionNumber = 1; outputBuffer->PartitionEntry->Mbr.HiddenSectors = 0; @@ -1145,7 +1441,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION else { IO_STATUS_BLOCK ioStatus; - PVOID buffer = TCalloc (max (pVerifyInformation->Length, PAGE_SIZE)); + DWORD dwBuffersize = min (pVerifyInformation->Length, 16 * PAGE_SIZE); + PVOID buffer = TCalloc (dwBuffersize); if (!buffer) { @@ -1153,14 +1450,29 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION } else { - LARGE_INTEGER offset = pVerifyInformation->StartingOffset; + LARGE_INTEGER offset; + DWORD dwRemainingBytes = pVerifyInformation->Length, dwReadCount; offset.QuadPart = ullNewOffset; - Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, pVerifyInformation->Length, &offset, NULL); - TCfree (buffer); + while (dwRemainingBytes) + { + dwReadCount = min (dwBuffersize, dwRemainingBytes); + Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, dwReadCount, &offset, NULL); - if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != pVerifyInformation->Length) - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != dwReadCount) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + break; + } + else if (!NT_SUCCESS (Irp->IoStatus.Status)) + break; + + dwRemainingBytes -= dwReadCount; + offset.QuadPart += (ULONGLONG) dwReadCount; + } + + burn (buffer, dwBuffersize); + TCfree (buffer); } } @@ -1215,8 +1527,10 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)\n"); - // Vista's filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed. - if (!(OsMajorVersion == 6 && OsMinorVersion == 0)) + // Vista's, Windows 8.1 and later filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed. + if (!(OsMajorVersion == 6 && OsMinorVersion == 0) + && !(IsOSAtLeast (WIN_8_1) && AllowWindowsDefrag && Extension->bRawDevice) + ) { Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; @@ -1224,10 +1538,24 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION else if (ValidateIOBufferSize (Irp, sizeof (VOLUME_DISK_EXTENTS), ValidateOutput)) { VOLUME_DISK_EXTENTS *extents = (VOLUME_DISK_EXTENTS *) Irp->AssociatedIrp.SystemBuffer; + - // No extent data can be returned as this is not a physical drive. - memset (extents, 0, sizeof (*extents)); - extents->NumberOfDiskExtents = 0; + if (IsOSAtLeast (WIN_8_1)) + { + // Windows 10 filesystem defragmenter works only if we report an extent with a real disk number + // So in the case of a VeraCrypt disk based volume, we use the disk number + // of the underlaying physical disk and we report a single extent + extents->NumberOfDiskExtents = 1; + extents->Extents[0].DiskNumber = Extension->DeviceNumber; + extents->Extents[0].StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk + extents->Extents[0].ExtentLength.QuadPart = Extension->DiskLength; + } + else + { + // Vista: No extent data can be returned as this is not a physical drive. + memset (extents, 0, sizeof (*extents)); + extents->NumberOfDiskExtents = 0; + } Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (*extents); @@ -1247,8 +1575,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION capacity->Version = sizeof (STORAGE_READ_CAPACITY); capacity->Size = sizeof (STORAGE_READ_CAPACITY); capacity->BlockLength = Extension->BytesPerSector; - capacity->NumberOfBlocks.QuadPart = (Extension->DiskLength / Extension->BytesPerSector) + 1; - capacity->DiskLength.QuadPart = Extension->DiskLength + Extension->BytesPerSector; + capacity->DiskLength.QuadPart = Extension->DiskLength + BYTES_PER_MB; // Add 1MB to the disk size to emulate the geometry of a real MBR disk + capacity->NumberOfBlocks.QuadPart = capacity->DiskLength.QuadPart / capacity->BlockLength; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (STORAGE_READ_CAPACITY); @@ -1361,6 +1689,21 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION break; + case IOCTL_DISK_UPDATE_PROPERTIES: + Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_SUCCESS for IOCTL_DISK_UPDATE_PROPERTIES\n"); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + break; + + case IOCTL_DISK_MEDIA_REMOVAL: + case IOCTL_STORAGE_MEDIA_REMOVAL: + Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_SUCCESS for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + break; + case IOCTL_DISK_GET_CLUSTER_INFO: Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_NOT_SUPPORTED for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; @@ -1371,20 +1714,228 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Irp->IoStatus.Information = 0; } break; + + case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES: + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES\n"); + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Information = 0; + if (Extension->bRawDevice && Extension->TrimEnabled) + { + if (ValidateIOBufferSize (Irp, sizeof (DEVICE_MANAGE_DATA_SET_ATTRIBUTES), ValidateInput)) + { + PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); + DWORD inputLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; + PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pInputAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer; + DEVICE_DATA_MANAGEMENT_SET_ACTION action = pInputAttrs->Action; + BOOL bEntireSet = pInputAttrs->Flags & DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE? TRUE : FALSE; + ULONGLONG minSizedataSet = (ULONGLONG) pInputAttrs->DataSetRangesOffset + (ULONGLONG) pInputAttrs->DataSetRangesLength; + ULONGLONG minSizeParameter = (ULONGLONG) pInputAttrs->ParameterBlockOffset + (ULONGLONG) pInputAttrs->ParameterBlockLength; + ULONGLONG minSizeGeneric = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + (ULONGLONG) pInputAttrs->ParameterBlockLength + (ULONGLONG) pInputAttrs->DataSetRangesLength; + PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pNewSetAttrs = NULL; + ULONG ulNewInputLength = 0; + BOOL bForwardIoctl = FALSE; + + if (((ULONGLONG) inputLength) >= minSizeGeneric && ((ULONGLONG) inputLength) >= minSizedataSet && ((ULONGLONG) inputLength) >= minSizeParameter) + { + if (bEntireSet) + { + if (minSizedataSet) + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data set range specified=> Error.\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + } + else + { + DWORD dwDataSetOffset; + DWORD dwDataSetLength = sizeof(DEVICE_DATA_SET_RANGE); + + if (AlignValue (inputLength, sizeof(DEVICE_DATA_SET_RANGE), &dwDataSetOffset)) + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set. Setting data range to all volume.\n"); + + if (S_OK == ULongAdd(dwDataSetOffset, dwDataSetLength, &ulNewInputLength)) + { + pNewSetAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) TCalloc (ulNewInputLength); + if (pNewSetAttrs) + { + PDEVICE_DATA_SET_RANGE pRange = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pNewSetAttrs) + dwDataSetOffset); + + memcpy (pNewSetAttrs, pInputAttrs, inputLength); + + pRange->StartingOffset = (ULONGLONG) Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset; + pRange->LengthInBytes = Extension->DiskLength; + + pNewSetAttrs->Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES); + pNewSetAttrs->Action = action; + pNewSetAttrs->Flags = pInputAttrs->Flags & (~DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE); + pNewSetAttrs->ParameterBlockOffset = pInputAttrs->ParameterBlockOffset; + pNewSetAttrs->ParameterBlockLength = pInputAttrs->ParameterBlockLength; + pNewSetAttrs->DataSetRangesOffset = dwDataSetOffset; + pNewSetAttrs->DataSetRangesLength = dwDataSetLength; + + bForwardIoctl = TRUE; + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - Failed to allocate memory.\n"); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + } + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data range length computation overflowed.\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + } + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data set offset computation overflowed.\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + } + } + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - creating new data set range from input range.\n"); + ulNewInputLength = inputLength; + pNewSetAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) TCalloc (inputLength); + if (pNewSetAttrs) + { + PDEVICE_DATA_SET_RANGE pNewRanges = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pNewSetAttrs) + pInputAttrs->DataSetRangesOffset); + PDEVICE_DATA_SET_RANGE pInputRanges = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pInputAttrs) + pInputAttrs->DataSetRangesOffset); + DWORD dwInputRangesCount = 0, dwNewRangesCount = 0, i; + ULONGLONG ullStartingOffset, ullNewOffset, ullEndOffset; + HRESULT hResult; + + memcpy (pNewSetAttrs, pInputAttrs, inputLength); + + dwInputRangesCount = pInputAttrs->DataSetRangesLength / sizeof(DEVICE_DATA_SET_RANGE); + + for (i = 0; i < dwInputRangesCount; i++) + { + ullStartingOffset = (ULONGLONG) pInputRanges[i].StartingOffset; + hResult = ULongLongAdd(ullStartingOffset, + (ULONGLONG) Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset, + &ullNewOffset); + if (hResult != S_OK) + continue; + else if (S_OK != ULongLongAdd(ullStartingOffset, (ULONGLONG) pInputRanges[i].LengthInBytes, &ullEndOffset)) + continue; + else if (ullEndOffset > (ULONGLONG) Extension->DiskLength) + continue; + else if (ullNewOffset > 0) + { + pNewRanges[dwNewRangesCount].StartingOffset = (LONGLONG) ullNewOffset; + pNewRanges[dwNewRangesCount].LengthInBytes = pInputRanges[i].LengthInBytes; + + dwNewRangesCount++; + } + } + + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - %d valid range processed from %d range in input.\n", (int) dwNewRangesCount, (int) dwInputRangesCount); + + pNewSetAttrs->DataSetRangesLength = dwNewRangesCount * sizeof (DEVICE_DATA_SET_RANGE); + + bForwardIoctl = TRUE; + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - Failed to allocate memory.\n"); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + } + } + } + else + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - buffer containing DEVICE_MANAGE_DATA_SET_ATTRIBUTES has invalid length.\n"); + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + } + + + if (bForwardIoctl) + { + if (action == DeviceDsmAction_Trim) + { + Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Trim.\n"); + + if (Extension->cryptoInfo->hiddenVolume || !AllowTrimCommand) + { + Dump ("ProcessVolumeDeviceControlIrp: TRIM command filtered\n"); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + } + else + { + IO_STATUS_BLOCK IoStatus; + Dump ("ProcessVolumeDeviceControlIrp: sending TRIM to device\n"); + Irp->IoStatus.Status = ZwDeviceIoControlFile ( + Extension->hDeviceFile, + NULL, + NULL, + NULL, + &IoStatus, + IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, + (PVOID) pNewSetAttrs, + ulNewInputLength, + NULL, + 0); + Dump ("ProcessVolumeDeviceControlIrp: ZwDeviceIoControlFile returned 0x%.8X\n", (DWORD) Irp->IoStatus.Status); + if (Irp->IoStatus.Status == STATUS_SUCCESS) + { + Irp->IoStatus.Status = IoStatus.Status; + Irp->IoStatus.Information = IoStatus.Information; + } + else + Irp->IoStatus.Information = 0; + } + } + else + { + switch (action) + { + case DeviceDsmAction_Notification: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Notification\n"); break; + case DeviceDsmAction_OffloadRead: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_OffloadRead\n"); break; + case DeviceDsmAction_OffloadWrite: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_OffloadWrite\n"); break; + case DeviceDsmAction_Allocation: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Allocation\n"); break; + case DeviceDsmAction_Scrub: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Scrub\n"); break; + case DeviceDsmAction_DrtQuery: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_DrtQuery\n"); break; + case DeviceDsmAction_DrtClear: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_DrtClear\n"); break; + case DeviceDsmAction_DrtDisable: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_DrtDisable\n"); break; + default: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - unknown action %d\n", (int) action); break; + } + + } + } + + if (pNewSetAttrs) + TCfree (pNewSetAttrs); + } + } +#if defined (DEBUG) || defined (DEBUG_TRACE) + else + Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_INVALID_DEVICE_REQUEST for IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES\n"); +#endif + break; case IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT: - case IOCTL_DISK_MEDIA_REMOVAL: case IOCTL_VOLUME_QUERY_ALLOCATION_HINT: case FT_BALANCED_READ_MODE: case IOCTL_STORAGE_GET_DEVICE_NUMBER: + case IOCTL_MOUNTDEV_LINK_CREATED: Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_INVALID_DEVICE_REQUEST for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; break; default: - Dump ("ProcessVolumeDeviceControlIrp (unknown code 0x%.8X)\n", irpSp->Parameters.DeviceIoControl.IoControlCode); - return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); - } + Dump ("ProcessVolumeDeviceControlIrp (unknown code 0x%.8X)\n", irpSp->Parameters.DeviceIoControl.IoControlCode); + return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); + } #if defined(DEBUG) || defined (DEBG_TRACE) if (!NT_SUCCESS (Irp->IoStatus.Status)) @@ -1408,7 +1959,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case TC_IOCTL_GET_DRIVER_VERSION: - case TC_IOCTL_LEGACY_GET_DRIVER_VERSION: + if (ValidateIOBufferSize (Irp, sizeof (LONG), ValidateOutput)) { LONG tmp = VERSION_NUM; @@ -1474,10 +2025,30 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex IO_STATUS_BLOCK IoStatus; LARGE_INTEGER offset; ACCESS_MASK access = FILE_READ_ATTRIBUTES; + PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); if (!ValidateIOBufferSize (Irp, sizeof (OPEN_TEST_STRUCT), ValidateInputOutput)) break; + if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (OPEN_TEST_STRUCT)) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } + + // check that opentest->wszFileName is a device path that starts with "\\Device\\Harddisk" + // 16 is the length of "\\Device\\Harddisk" which is the minimum + if ( !CheckStringLength (opentest->wszFileName, TC_MAX_PATH, 16, (size_t) -1, NULL) + || (!StringNoCaseCompare (opentest->wszFileName, L"\\Device\\Harddisk", 16)) + ) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } + + EnsureNullTerminatedString (opentest->wszFileName, sizeof (opentest->wszFileName)); RtlInitUnicodeString (&FullFileName, opentest->wszFileName); @@ -1595,7 +2166,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex &offset, NULL); - if (NT_SUCCESS (ntStatus)) + if (NT_SUCCESS (ntStatus) && (IoStatus.Information >= TC_VOLUME_HEADER_EFFECTIVE_SIZE)) { /* compute the ID of this volume: SHA-256 of the effective header */ sha256 (opentest->volumeIDs[volumeType], readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); @@ -1631,11 +2202,26 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex UNICODE_STRING FullFileName; IO_STATUS_BLOCK IoStatus; LARGE_INTEGER offset; - byte readBuffer [TC_SECTOR_SIZE_BIOS]; + size_t devicePathLen = 0; + WCHAR* wszPath = NULL; if (!ValidateIOBufferSize (Irp, sizeof (GetSystemDriveConfigurationRequest), ValidateInputOutput)) break; + // check that request->DevicePath has the expected format "\\Device\\HarddiskXXX\\Partition0" + // 28 is the length of "\\Device\\Harddisk0\\Partition0" which is the minimum + // 30 is the length of "\\Device\\Harddisk255\\Partition0" which is the maximum + wszPath = request->DevicePath; + if ( !CheckStringLength (wszPath, TC_MAX_PATH, 28, 30, &devicePathLen) + || (memcmp (wszPath, L"\\Device\\Harddisk", 16 * sizeof (WCHAR))) + || (memcmp (wszPath + (devicePathLen - 11), L"\\Partition0", 11 * sizeof (WCHAR))) + ) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } + EnsureNullTerminatedString (request->DevicePath, sizeof (request->DevicePath)); RtlInitUnicodeString (&FullFileName, request->DevicePath); @@ -1647,68 +2233,88 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (NT_SUCCESS (ntStatus)) { - // Determine if the first sector contains a portion of the VeraCrypt Boot Loader - offset.QuadPart = 0; // MBR - - ntStatus = ZwReadFile (NtFileHandle, - NULL, - NULL, - NULL, - &IoStatus, - readBuffer, - sizeof(readBuffer), - &offset, - NULL); - - if (NT_SUCCESS (ntStatus)) + byte *readBuffer = TCalloc (TC_MAX_VOLUME_SECTOR_SIZE); + if (!readBuffer) { - size_t i; - - // Check for dynamic drive - request->DriveIsDynamic = FALSE; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + } + else + { + // Determine if the first sector contains a portion of the VeraCrypt Boot Loader + offset.QuadPart = 0; // MBR + + ntStatus = ZwReadFile (NtFileHandle, + NULL, + NULL, + NULL, + &IoStatus, + readBuffer, + TC_MAX_VOLUME_SECTOR_SIZE, + &offset, + NULL); - if (readBuffer[510] == 0x55 && readBuffer[511] == 0xaa) + if (NT_SUCCESS (ntStatus)) { - int i; - for (i = 0; i < 4; ++i) + // check that we could read all needed data + if (IoStatus.Information >= TC_SECTOR_SIZE_BIOS) { - if (readBuffer[446 + i * 16 + 4] == PARTITION_LDM) + size_t i; + + // Check for dynamic drive + request->DriveIsDynamic = FALSE; + + if (readBuffer[510] == 0x55 && readBuffer[511] == 0xaa) { - request->DriveIsDynamic = TRUE; - break; + int i; + for (i = 0; i < 4; ++i) + { + if (readBuffer[446 + i * 16 + 4] == PARTITION_LDM) + { + request->DriveIsDynamic = TRUE; + break; + } + } } - } - } - request->BootLoaderVersion = 0; - request->Configuration = 0; - request->UserConfiguration = 0; - request->CustomUserMessage[0] = 0; + request->BootLoaderVersion = 0; + request->Configuration = 0; + request->UserConfiguration = 0; + request->CustomUserMessage[0] = 0; - // Search for the string "VeraCrypt" - for (i = 0; i < sizeof (readBuffer) - strlen (TC_APP_NAME); ++i) - { - if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) - { - request->BootLoaderVersion = BE16 (*(uint16 *) (readBuffer + TC_BOOT_SECTOR_VERSION_OFFSET)); - request->Configuration = readBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET]; - - if (request->BootLoaderVersion != 0 && request->BootLoaderVersion <= VERSION_NUM) + // Search for the string "VeraCrypt" + for (i = 0; i < TC_SECTOR_SIZE_BIOS - strlen (TC_APP_NAME); ++i) { - request->UserConfiguration = readBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET]; - memcpy (request->CustomUserMessage, readBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); + if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) + { + request->BootLoaderVersion = BE16 (*(uint16 *) (readBuffer + TC_BOOT_SECTOR_VERSION_OFFSET)); + request->Configuration = readBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET]; + + if (request->BootLoaderVersion != 0 && request->BootLoaderVersion <= VERSION_NUM) + { + request->UserConfiguration = readBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET]; + memcpy (request->CustomUserMessage, readBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); + } + break; + } } - break; + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof (*request); + } + else + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; } } + else + { + Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Information = 0; + } - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof (*request); - } - else - { - Irp->IoStatus.Status = ntStatus; - Irp->IoStatus.Information = 0; + TCfree (readBuffer); } ZwClose (NtFileHandle); @@ -1787,7 +2393,6 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER; // Normal/outer volume (hidden volume protected) else list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL; // Normal volume - list->truecryptMode[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->bTrueCryptMode; } } @@ -1796,21 +2401,6 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex } break; - case TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES: - if (ValidateIOBufferSize (Irp, sizeof (uint32), ValidateOutput)) - { - // Prevent the user from downgrading to versions lower than 5.0 by faking mounted volumes. - // The user could render the system unbootable by downgrading when boot encryption - // is active or being set up. - - memset (Irp->AssociatedIrp.SystemBuffer, 0, irpSp->Parameters.DeviceIoControl.OutputBufferLength); - *(uint32 *) Irp->AssociatedIrp.SystemBuffer = 0xffffFFFF; - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = irpSp->Parameters.DeviceIoControl.OutputBufferLength; - } - break; - case TC_IOCTL_GET_VOLUME_PROPERTIES: if (ValidateIOBufferSize (Irp, sizeof (VOLUME_PROPERTIES_STRUCT), ValidateInputOutput)) { @@ -1843,6 +2433,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex prop->volumeHeaderFlags = ListExtension->cryptoInfo->HeaderFlags; prop->readOnly = ListExtension->bReadOnly; prop->removable = ListExtension->bRemovable; + prop->mountDisabled = ListExtension->bMountManager? FALSE : TRUE; prop->partitionInInactiveSysEncScope = ListExtension->PartitionInInactiveSysEncScope; prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume; @@ -2078,12 +2669,13 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (ValidateIOBufferSize (Irp, sizeof (MOUNT_STRUCT), ValidateInputOutput)) { MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; + PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); - if (mount->VolumePassword.Length > MAX_PASSWORD || mount->ProtectedHidVolPassword.Length > MAX_PASSWORD + if ((irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (MOUNT_STRUCT)) + || mount->VolumePassword.Length > MAX_PASSWORD || mount->ProtectedHidVolPassword.Length > MAX_PASSWORD || mount->pkcs5_prf < 0 || mount->pkcs5_prf > LAST_PRF_ID || mount->VolumePim < -1 || mount->VolumePim == INT_MAX || mount->ProtectedHidVolPkcs5Prf < 0 || mount->ProtectedHidVolPkcs5Prf > LAST_PRF_ID - || (mount->bTrueCryptMode != FALSE && mount->bTrueCryptMode != TRUE) ) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; @@ -2101,7 +2693,6 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword)); burn (&mount->pkcs5_prf, sizeof (mount->pkcs5_prf)); burn (&mount->VolumePim, sizeof (mount->VolumePim)); - burn (&mount->bTrueCryptMode, sizeof (mount->bTrueCryptMode)); burn (&mount->ProtectedHidVolPkcs5Prf, sizeof (mount->ProtectedHidVolPkcs5Prf)); burn (&mount->ProtectedHidVolPim, sizeof (mount->ProtectedHidVolPim)); } @@ -2112,6 +2703,14 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex { UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; PDEVICE_OBJECT ListDevice = GetVirtualVolumeDeviceObject (unmount->nDosDriveNo); + PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); + + if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (UNMOUNT_STRUCT)) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } unmount->nReturnCode = ERR_DRIVE_NOT_FOUND; @@ -2132,6 +2731,14 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (ValidateIOBufferSize (Irp, sizeof (UNMOUNT_STRUCT), ValidateInputOutput)) { UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; + PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); + + if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (UNMOUNT_STRUCT)) + { + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Information = 0; + break; + } unmount->nReturnCode = UnmountAllDevices (unmount, unmount->ignoreOpenFiles); @@ -2140,6 +2747,11 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex } break; + case VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS: + EmergencyClearAllKeys (Irp, irpSp); + WipeCache(); + break; + case TC_IOCTL_BOOT_ENCRYPTION_SETUP: Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp); Irp->IoStatus.Information = 0; @@ -2266,6 +2878,27 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex } break; + case VC_IOCTL_IS_RAM_ENCRYPTION_ENABLED: + if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput)) + { + *(int *) Irp->AssociatedIrp.SystemBuffer = IsRamEncryptionEnabled() ? 1 : 0; + Irp->IoStatus.Information = sizeof (int); + Irp->IoStatus.Status = STATUS_SUCCESS; + } + break; + + case VC_IOCTL_ENCRYPTION_QUEUE_PARAMS: + if (ValidateIOBufferSize (Irp, sizeof (EncryptionQueueParameters), ValidateOutput)) + { + EncryptionQueueParameters* pParams = (EncryptionQueueParameters*) Irp->AssociatedIrp.SystemBuffer; + pParams->EncryptionFragmentSize = EncryptionFragmentSize; + pParams->EncryptionIoRequestCount = EncryptionIoRequestCount; + pParams->EncryptionItemCount = EncryptionItemCount; + Irp->IoStatus.Information = sizeof (EncryptionQueueParameters); + Irp->IoStatus.Status = STATUS_SUCCESS; + } + break; + default: return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); } @@ -2541,6 +3174,21 @@ VOID VolumeThreadProc (PVOID Context) Extension->Queue.HostFileHandle = Extension->hDeviceFile; Extension->Queue.VirtualDeviceLength = Extension->DiskLength; Extension->Queue.MaxReadAheadOffset.QuadPart = Extension->HostLength; + if (bDevice && pThreadBlock->mount->bPartitionInInactiveSysEncScope + && (!Extension->cryptoInfo->hiddenVolume) + && (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value) + ) + { + // Support partial encryption only in the case of system encryption + Extension->Queue.EncryptedAreaStart = 0; + Extension->Queue.EncryptedAreaEnd = Extension->cryptoInfo->EncryptedAreaLength.Value - 1; + if (Extension->Queue.CryptoInfo->EncryptedAreaLength.Value == 0) + { + Extension->Queue.EncryptedAreaStart = -1; + Extension->Queue.EncryptedAreaEnd = -1; + } + Extension->Queue.bSupportPartialEncryption = TRUE; + } if (Extension->SecurityClientContextValid) Extension->Queue.SecurityClientContext = &Extension->SecurityClientContext; @@ -2674,6 +3322,9 @@ LPWSTR TCTranslateCode (ULONG ulCode) TC_CASE_RET_NAME (TC_IOCTL_WIPE_PASSWORD_CACHE); TC_CASE_RET_NAME (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR); TC_CASE_RET_NAME (VC_IOCTL_GET_DRIVE_GEOMETRY_EX); + TC_CASE_RET_NAME (VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS); + TC_CASE_RET_NAME (VC_IOCTL_IS_RAM_ENCRYPTION_ENABLED); + TC_CASE_RET_NAME (VC_IOCTL_ENCRYPTION_QUEUE_PARAMS); TC_CASE_RET_NAME (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS); @@ -2772,6 +3423,8 @@ LPWSTR TCTranslateCode (ULONG ulCode) return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES"); else if (ulCode == IOCTL_DISK_IS_CLUSTERED) return (LPWSTR) _T ("IOCTL_DISK_IS_CLUSTERED"); + else if (ulCode == IOCTL_DISK_UPDATE_DRIVE_SIZE) + return (LPWSTR) _T ("IOCTL_DISK_UPDATE_DRIVE_SIZE"); else if (ulCode == IOCTL_STORAGE_GET_MEDIA_TYPES) return (LPWSTR) _T ("IOCTL_STORAGE_GET_MEDIA_TYPES"); else if (ulCode == IOCTL_STORAGE_GET_HOTPLUG_INFO) @@ -2798,6 +3451,10 @@ LPWSTR TCTranslateCode (ULONG ulCode) return (LPWSTR) _T ("IOCTL_VOLUME_POST_ONLINE"); else if (ulCode == IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT) return (LPWSTR) _T ("IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT"); + else if (ulCode == IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES) + return (LPWSTR) _T ("IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES"); + else if (ulCode == IOCTL_DISK_GROW_PARTITION) + return (LPWSTR) _T ("IOCTL_DISK_GROW_PARTITION"); else if (ulCode == IRP_MJ_READ) return (LPWSTR) _T ("IRP_MJ_READ"); else if (ulCode == IRP_MJ_WRITE) @@ -2848,31 +3505,21 @@ void TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) if (Extension->SecurityClientContextValid) { - if (OsMajorVersion == 5 && OsMinorVersion == 0) - { - ObDereferenceObject (Extension->SecurityClientContext.ClientToken); - } - else - { - // Windows 2000 does not support PsDereferenceImpersonationToken() used by SeDeleteClientSecurity(). - // TODO: Use only SeDeleteClientSecurity() once support for Windows 2000 is dropped. - - VOID (*PsDereferenceImpersonationTokenD) (PACCESS_TOKEN ImpersonationToken); - UNICODE_STRING name; - RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken"); + VOID (*PsDereferenceImpersonationTokenD) (PACCESS_TOKEN ImpersonationToken); + UNICODE_STRING name; + RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken"); - PsDereferenceImpersonationTokenD = MmGetSystemRoutineAddress (&name); - if (!PsDereferenceImpersonationTokenD) - TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED); + PsDereferenceImpersonationTokenD = MmGetSystemRoutineAddress (&name); + if (!PsDereferenceImpersonationTokenD) + TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED); -# define PsDereferencePrimaryToken -# define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD +# define PsDereferencePrimaryToken +# define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD - SeDeleteClientSecurity (&Extension->SecurityClientContext); + SeDeleteClientSecurity (&Extension->SecurityClientContext); -# undef PsDereferencePrimaryToken -# undef PsDereferenceImpersonationToken - } +# undef PsDereferencePrimaryToken +# undef PsDereferenceImpersonationToken } VirtualVolumeDeviceObjects[Extension->nDosDriveNo] = NULL; @@ -2912,6 +3559,18 @@ void OnShutdownPending () while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0) == STATUS_INSUFFICIENT_RESOURCES); } +typedef struct +{ + PWSTR deviceName; ULONG IoControlCode; void *InputBuffer; ULONG InputBufferSize; void *OutputBuffer; ULONG OutputBufferSize; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} TCDeviceIoControlWorkItemArgs; + +static VOID TCDeviceIoControlWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, TCDeviceIoControlWorkItemArgs *arg) +{ + arg->Status = TCDeviceIoControl (arg->deviceName, arg->IoControlCode, arg->InputBuffer, arg->InputBufferSize, arg->OutputBuffer, arg->OutputBufferSize); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} NTSTATUS TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, void *InputBuffer, ULONG InputBufferSize, void *OutputBuffer, ULONG OutputBufferSize) { @@ -2923,6 +3582,30 @@ NTSTATUS TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, void *InputBu KEVENT event; UNICODE_STRING name; + if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) + { + TCDeviceIoControlWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.deviceName = deviceName; + args.IoControlCode = IoControlCode; + args.InputBuffer = InputBuffer; + args.InputBufferSize = InputBufferSize; + args.OutputBuffer = OutputBuffer; + args.OutputBufferSize = OutputBufferSize; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, TCDeviceIoControlWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + RtlInitUnicodeString(&name, deviceName); ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject); @@ -2983,7 +3666,7 @@ NTSTATUS SendDeviceIoControlRequest (PDEVICE_OBJECT deviceObject, ULONG ioContro PIRP irp; KEVENT event; - if (KeGetCurrentIrql() > APC_LEVEL) + if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) { SendDeviceIoControlRequestWorkItemArgs args; @@ -3036,11 +3719,16 @@ NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *dr LARGE_INTEGER offset; byte *sectorBuffer; ULONGLONG startTime; + ULONG sectorSize; if (!UserCanAccessDriveDevice()) return STATUS_ACCESS_DENIED; - sectorBuffer = TCalloc (TC_SECTOR_SIZE_BIOS); + status = GetDeviceSectorSize (driveDeviceObject, §orSize); + if (!NT_SUCCESS (status)) + return status; + + sectorBuffer = TCalloc (sectorSize); if (!sectorBuffer) return STATUS_INSUFFICIENT_RESOURCES; @@ -3055,12 +3743,12 @@ NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *dr } startTime = KeQueryInterruptTime (); - for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += TC_SECTOR_SIZE_BIOS) + for (offset.QuadPart = sysLength.QuadPart; ; offset.QuadPart += sectorSize) { - status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, TC_SECTOR_SIZE_BIOS); + status = TCReadDevice (driveDeviceObject, sectorBuffer, offset, sectorSize); if (NT_SUCCESS (status)) - status = TCWriteDevice (driveDeviceObject, sectorBuffer, offset, TC_SECTOR_SIZE_BIOS); + status = TCWriteDevice (driveDeviceObject, sectorBuffer, offset, sectorSize); if (!NT_SUCCESS (status)) { @@ -3299,6 +3987,136 @@ NTSTATUS MountManagerUnmount (int nDosDriveNo) return ntStatus; } +typedef struct +{ + MOUNT_STRUCT* mount; PEXTENSION NewExtension; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} UpdateFsVolumeInformationWorkItemArgs; + +static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewExtension); + +static VOID UpdateFsVolumeInformationWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, UpdateFsVolumeInformationWorkItemArgs *arg) +{ + arg->Status = UpdateFsVolumeInformation (arg->mount, arg->NewExtension); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} + +static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewExtension) +{ + HANDLE volumeHandle; + PFILE_OBJECT volumeFileObject; + ULONG labelLen = (ULONG) wcslen (mount->wszLabel); + BOOL bIsNTFS = FALSE; + ULONG labelMaxLen, labelEffectiveLen; + + if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) + { + UpdateFsVolumeInformationWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.mount = mount; + args.NewExtension = NewExtension; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, UpdateFsVolumeInformationWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + + __try + { + if (NT_SUCCESS (TCOpenFsVolume (NewExtension, &volumeHandle, &volumeFileObject))) + { + __try + { + ULONG fsStatus; + + if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_IS_VOLUME_DIRTY, NULL, 0, &fsStatus, sizeof (fsStatus))) + && (fsStatus & VOLUME_IS_DIRTY)) + { + mount->FilesystemDirty = TRUE; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + mount->FilesystemDirty = TRUE; + } + + // detect if the filesystem is NTFS or FAT + __try + { + NTFS_VOLUME_DATA_BUFFER ntfsData; + if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &ntfsData, sizeof (ntfsData)))) + { + bIsNTFS = TRUE; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + bIsNTFS = FALSE; + } + + NewExtension->bIsNTFS = bIsNTFS; + mount->bIsNTFS = bIsNTFS; + + if (labelLen > 0) + { + if (bIsNTFS) + labelMaxLen = 32; // NTFS maximum label length + else + labelMaxLen = 11; // FAT maximum label length + + // calculate label effective length + labelEffectiveLen = labelLen > labelMaxLen? labelMaxLen : labelLen; + + // correct the label in the device + memset (&NewExtension->wszLabel[labelEffectiveLen], 0, 33 - labelEffectiveLen); + memcpy (mount->wszLabel, NewExtension->wszLabel, 33); + + // set the volume label + __try + { + IO_STATUS_BLOCK ioblock; + ULONG labelInfoSize = sizeof(FILE_FS_LABEL_INFORMATION) + (labelEffectiveLen * sizeof(WCHAR)); + FILE_FS_LABEL_INFORMATION* labelInfo = (FILE_FS_LABEL_INFORMATION*) TCalloc (labelInfoSize); + if (labelInfo) + { + labelInfo->VolumeLabelLength = labelEffectiveLen * sizeof(WCHAR); + memcpy (labelInfo->VolumeLabel, mount->wszLabel, labelInfo->VolumeLabelLength); + + if (STATUS_SUCCESS == ZwSetVolumeInformationFile (volumeHandle, &ioblock, labelInfo, labelInfoSize, FileFsLabelInformation)) + { + mount->bDriverSetLabel = TRUE; + NewExtension->bDriverSetLabel = TRUE; + } + + TCfree(labelInfo); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + + } + } + + TCCloseFsVolume (volumeHandle, volumeFileObject); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + + } + + return STATUS_SUCCESS; +} + NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) { @@ -3386,12 +4204,6 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) { if (mount->nReturnCode == 0) { - HANDLE volumeHandle; - PFILE_OBJECT volumeFileObject; - ULONG labelLen = (ULONG) wcslen (mount->wszLabel); - BOOL bIsNTFS = FALSE; - ULONG labelMaxLen, labelEffectiveLen; - Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode, NewExtension->bReadOnly); if (NewExtension->bReadOnly) @@ -3412,88 +4224,24 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) } if (mount->bMountManager) + { MountManagerMount (mount); + // We create symbolic link even if mount manager is notified of + // arriving volume as it apparently sometimes fails to create the link + CreateDriveLink (mount->nDosDriveNo); + } NewExtension->bMountManager = mount->bMountManager; - // We create symbolic link even if mount manager is notified of - // arriving volume as it apparently sometimes fails to create the link - CreateDriveLink (mount->nDosDriveNo); - mount->FilesystemDirty = FALSE; - if (NT_SUCCESS (TCOpenFsVolume (NewExtension, &volumeHandle, &volumeFileObject))) + if (mount->bMountManager) { - __try - { - ULONG fsStatus; - - if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_IS_VOLUME_DIRTY, NULL, 0, &fsStatus, sizeof (fsStatus))) - && (fsStatus & VOLUME_IS_DIRTY)) - { - mount->FilesystemDirty = TRUE; - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - mount->FilesystemDirty = TRUE; - } - - // detect if the filesystem is NTFS or FAT - __try - { - NTFS_VOLUME_DATA_BUFFER ntfsData; - if (NT_SUCCESS (TCFsctlCall (volumeFileObject, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &ntfsData, sizeof (ntfsData)))) - { - bIsNTFS = TRUE; - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - bIsNTFS = FALSE; - } - - NewExtension->bIsNTFS = bIsNTFS; - mount->bIsNTFS = bIsNTFS; - - if (labelLen > 0) + NTSTATUS updateStatus = UpdateFsVolumeInformation (mount, NewExtension); + if (!NT_SUCCESS (updateStatus)) { - if (bIsNTFS) - labelMaxLen = 32; // NTFS maximum label length - else - labelMaxLen = 11; // FAT maximum label length - - // calculate label effective length - labelEffectiveLen = labelLen > labelMaxLen? labelMaxLen : labelLen; - - // correct the label in the device - memset (&NewExtension->wszLabel[labelEffectiveLen], 0, 33 - labelEffectiveLen); - memcpy (mount->wszLabel, NewExtension->wszLabel, 33); - - // set the volume label - __try - { - IO_STATUS_BLOCK ioblock; - ULONG labelInfoSize = sizeof(FILE_FS_LABEL_INFORMATION) + (labelEffectiveLen * sizeof(WCHAR)); - FILE_FS_LABEL_INFORMATION* labelInfo = (FILE_FS_LABEL_INFORMATION*) TCalloc (labelInfoSize); - labelInfo->VolumeLabelLength = labelEffectiveLen * sizeof(WCHAR); - memcpy (labelInfo->VolumeLabel, mount->wszLabel, labelInfo->VolumeLabelLength); - - if (STATUS_SUCCESS == ZwSetVolumeInformationFile (volumeHandle, &ioblock, labelInfo, labelInfoSize, FileFsLabelInformation)) - { - mount->bDriverSetLabel = TRUE; - NewExtension->bDriverSetLabel = TRUE; - } - - TCfree(labelInfo); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - - } + Dump ("MountDevice: UpdateFsVolumeInformation failed with status 0x%08x\n", updateStatus); } - - TCCloseFsVolume (volumeHandle, volumeFileObject); } } else @@ -3507,6 +4255,20 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) } } +typedef struct +{ + UNMOUNT_STRUCT *unmountRequest; PDEVICE_OBJECT deviceObject; BOOL ignoreOpenFiles; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} UnmountDeviceWorkItemArgs; + + +static VOID UnmountDeviceWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, UnmountDeviceWorkItemArgs *arg) +{ + arg->Status = UnmountDevice (arg->unmountRequest, arg->deviceObject, arg->ignoreOpenFiles); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} + NTSTATUS UnmountDevice (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles) { PEXTENSION extension = deviceObject->DeviceExtension; @@ -3514,6 +4276,27 @@ NTSTATUS UnmountDevice (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT deviceObj HANDLE volumeHandle; PFILE_OBJECT volumeFileObject; + if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) + { + UnmountDeviceWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.deviceObject = deviceObject; + args.unmountRequest = unmountRequest; + args.ignoreOpenFiles = ignoreOpenFiles; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, UnmountDeviceWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + Dump ("UnmountDevice %d\n", extension->nDosDriveNo); ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject); @@ -3784,18 +4567,35 @@ NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information) } -size_t GetCpuCount () +size_t GetCpuCount (WORD* pGroupCount) { - KAFFINITY activeCpuMap = KeQueryActiveProcessors(); - size_t mapSize = sizeof (activeCpuMap) * 8; size_t cpuCount = 0; + if (KeQueryActiveGroupCountPtr && KeQueryActiveProcessorCountExPtr) + { + USHORT i, groupCount = KeQueryActiveGroupCountPtr (); + for (i = 0; i < groupCount; i++) + { + cpuCount += (size_t) KeQueryActiveProcessorCountExPtr (i); + } - while (mapSize--) + if (pGroupCount) + *pGroupCount = groupCount; + } + else { - if (activeCpuMap & 1) - ++cpuCount; + KAFFINITY activeCpuMap = KeQueryActiveProcessors(); + size_t mapSize = sizeof (activeCpuMap) * 8; - activeCpuMap >>= 1; + while (mapSize--) + { + if (activeCpuMap & 1) + ++cpuCount; + + activeCpuMap >>= 1; + } + + if (pGroupCount) + *pGroupCount = 1; } if (cpuCount == 0) @@ -3804,6 +4604,35 @@ size_t GetCpuCount () return cpuCount; } +USHORT GetCpuGroup (size_t index) +{ + if (KeQueryActiveGroupCountPtr && KeQueryActiveProcessorCountExPtr) + { + USHORT i, groupCount = KeQueryActiveGroupCountPtr (); + size_t cpuCount = 0; + for (i = 0; i < groupCount; i++) + { + cpuCount += (size_t) KeQueryActiveProcessorCountExPtr (i); + if (cpuCount >= index) + { + return i; + } + } + } + + return 0; +} + +void SetThreadCpuGroupAffinity (USHORT index) +{ + if (KeSetSystemGroupAffinityThreadPtr) + { + GROUP_AFFINITY groupAffinity = {0}; + groupAffinity.Mask = ~0ULL; + groupAffinity.Group = index; + KeSetSystemGroupAffinityThreadPtr (&groupAffinity, NULL); + } +} void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes) { @@ -3815,7 +4644,7 @@ void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes) void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout) { LARGE_INTEGER waitInterval; - waitInterval.QuadPart = retryDelay * -10000; + waitInterval.QuadPart = ((LONGLONG)retryDelay) * -10000; ASSERT (KeGetCurrentIrql() <= APC_LEVEL); ASSERT (retryDelay > 0 && retryDelay <= timeout); @@ -3963,11 +4792,26 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry) if (flags & TC_DRIVER_CONFIG_CACHE_BOOT_PIM) CacheBootPim = TRUE; + + if (flags & VC_DRIVER_CONFIG_BLOCK_SYS_TRIM) + BlockSystemTrimCommand = TRUE; + + /* clear VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION if it is set */ + if (flags & VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION) + { + flags ^= VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION; + WriteRegistryConfigFlags (flags); + } + + RamEncryptionActivated = (flags & VC_DRIVER_CONFIG_ENABLE_RAM_ENCRYPTION) ? TRUE : FALSE; } EnableHwEncryption ((flags & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? FALSE : TRUE); + EnableCpuRng ((flags & VC_DRIVER_CONFIG_ENABLE_CPU_RNG) ? TRUE : FALSE); EnableExtendedIoctlSupport = (flags & TC_DRIVER_CONFIG_ENABLE_EXTENDED_IOCTL)? TRUE : FALSE; + AllowTrimCommand = (flags & VC_DRIVER_CONFIG_ALLOW_NONSYS_TRIM)? TRUE : FALSE; + AllowWindowsDefrag = (flags & VC_DRIVER_CONFIG_ALLOW_WINDOWS_DEFRAG)? TRUE : FALSE; } else status = STATUS_INVALID_PARAMETER; @@ -3983,6 +4827,65 @@ 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; + else if (EncryptionIoRequestCount > TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_MAX_COUNT) + EncryptionIoRequestCount = TC_ENC_IO_QUEUE_PREALLOCATED_IO_REQUEST_MAX_COUNT; + + if ((EncryptionItemCount == 0) || (EncryptionItemCount > (EncryptionIoRequestCount / 2))) + EncryptionItemCount = EncryptionIoRequestCount / 2; + + /* EncryptionFragmentSize value in registry is expressed in KiB */ + /* Maximum allowed value for EncryptionFragmentSize is 2048 KiB */ + EncryptionFragmentSize *= 1024; + if (EncryptionFragmentSize == 0) + 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 (driverEntry && NT_SUCCESS (TCReadRegistryKey (&name, VC_ERASE_KEYS_SHUTDOWN, &data))) + { + if (data->Type == REG_DWORD) + { + if (*((uint32 *) data->Data)) + EraseKeysOnShutdown = TRUE; + else + EraseKeysOnShutdown = FALSE; + } + + TCfree (data); + } + + return status; } @@ -4172,7 +5075,7 @@ BOOL IsOSAtLeast (OSVersionEnum reqMinOS) >= (major << 16 | minor << 8)); } -NTSTATUS NTAPI KeSaveExtendedProcessorState ( +NTSTATUS NTAPI KeSaveExtendedProcessorStateVC ( __in ULONG64 Mask, PXSTATE_SAVE XStateSave ) @@ -4187,7 +5090,7 @@ NTSTATUS NTAPI KeSaveExtendedProcessorState ( } } -VOID NTAPI KeRestoreExtendedProcessorState ( +VOID NTAPI KeRestoreExtendedProcessorStateVC ( PXSTATE_SAVE XStateSave ) { @@ -4195,4 +5098,12 @@ VOID NTAPI KeRestoreExtendedProcessorState ( { (KeRestoreExtendedProcessorStatePtr) (XStateSave); } -}
\ No newline at end of file +} + +BOOLEAN VC_KeAreAllApcsDisabled (VOID) +{ + if (KeAreAllApcsDisabledPtr) + return (KeAreAllApcsDisabledPtr) (); + else + return FALSE; +} diff --git a/src/Driver/Ntdriver.h b/src/Driver/Ntdriver.h index fd4d3559..3bbeb457 100644 --- a/src/Driver/Ntdriver.h +++ b/src/Driver/Ntdriver.h @@ -66,6 +66,10 @@ typedef struct EXTENSION ULONG HostMaximumTransferLength; ULONG HostMaximumPhysicalPages; ULONG HostAlignmentMask; + ULONG DeviceNumber; + + BOOL IncursSeekPenalty; + BOOL TrimEnabled; KEVENT keVolumeEvent; /* Event structure used when setting up a device */ @@ -119,7 +123,12 @@ extern ULONG OsMinorVersion; extern BOOL VolumeClassFilterRegistered; extern BOOL CacheBootPassword; extern BOOL CacheBootPim; - +extern BOOL BlockSystemTrimCommand; +extern BOOL AllowWindowsDefrag; +extern int EncryptionIoRequestCount; +extern int EncryptionItemCount; +extern int EncryptionFragmentSize; +extern BOOL EraseKeysOnShutdown; /* Helper macro returning x seconds in units of 100 nanoseconds */ #define WAIT_SECONDS(x) ((x)*10000000) @@ -168,7 +177,9 @@ NTSTATUS TCCompleteIrp (PIRP irp, NTSTATUS status, ULONG_PTR information); NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information); NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize); BOOL UserCanAccessDriveDevice (); -size_t GetCpuCount (); +size_t GetCpuCount (WORD* pGroupCount); +USHORT GetCpuGroup (size_t index); +void SetThreadCpuGroupAffinity (USHORT index); void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes); void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout); BOOL IsDriveLetterAvailable (int nDosDriveNo, DeviceNamespaceType namespaceType); @@ -185,6 +196,8 @@ BOOL IsVolumeAccessibleByCurrentUser (PEXTENSION volumeDeviceExtension); void GetElapsedTimeInit (LARGE_INTEGER *lastPerfCounter); int64 GetElapsedTime (LARGE_INTEGER *lastPerfCounter); BOOL IsOSAtLeast (OSVersionEnum reqMinOS); +PDEVICE_OBJECT GetVirtualVolumeDeviceObject (int driveNumber); +void GetDriverRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed); #define TC_BUG_CHECK(status) KeBugCheckEx (SECURITY_SYSTEM, __LINE__, (ULONG_PTR) status, 0, 'VC') diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c index 81549ba1..444468c5 100644 --- a/src/Driver/Ntvol.c +++ b/src/Driver/Ntvol.c @@ -43,21 +43,23 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, PWSTR pwszMountVolume, BOOL bRawDevice) { - FILE_STANDARD_INFORMATION FileStandardInfo; + FILE_STANDARD_INFORMATION FileStandardInfo = { 0 }; FILE_BASIC_INFORMATION FileBasicInfo; OBJECT_ATTRIBUTES oaFileAttributes; UNICODE_STRING FullFileName; IO_STATUS_BLOCK IoStatusBlock; PCRYPTO_INFO cryptoInfoPtr = NULL; PCRYPTO_INFO tmpCryptoInfo = NULL; - LARGE_INTEGER lDiskLength; + LARGE_INTEGER lDiskLength = { 0 }; __int64 partitionStartingOffset = 0; int volumeType; char *readBuffer = 0; NTSTATUS ntStatus = 0; - BOOL forceAccessCheck = (!bRawDevice && !(OsMajorVersion == 5 &&OsMinorVersion == 0)); // Windows 2000 does not support OBJ_FORCE_ACCESS_CHECK attribute + BOOL forceAccessCheck = !bRawDevice; BOOL disableBuffering = TRUE; BOOL exclusiveAccess = mount->bExclusiveAccess; + /* when mounting with hidden volume protection, we cache the passwords after both outer and hidden volumes are mounted successfully*/ + BOOL bAutoCachePassword = mount->bProtectHiddenVolume? FALSE : mount->bCache; Extension->pfoDeviceFile = NULL; Extension->hDeviceFile = NULL; @@ -68,6 +70,12 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, Extension->HostMaximumPhysicalPages = 17; Extension->HostAlignmentMask = 0; + /* default values for non-SSD drives */ + Extension->IncursSeekPenalty = TRUE; + Extension->TrimEnabled = FALSE; + + Extension->DeviceNumber = (ULONG) -1; + RtlInitUnicodeString (&FullFileName, pwszMountVolume); InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL); KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE); @@ -80,6 +88,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, } mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = FALSE; + mount->VolumeMountedReadOnlyAfterPartialSysEnc = FALSE; // If we are opening a device, query its size first if (bRawDevice) @@ -90,6 +99,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, DISK_GEOMETRY_EX dg; STORAGE_PROPERTY_QUERY storagePropertyQuery = {0}; byte* dgBuffer; + STORAGE_DEVICE_NUMBER storageDeviceNumber; ntStatus = IoGetDeviceObjectPointer (&FullFileName, FILE_READ_DATA | FILE_READ_ATTRIBUTES, @@ -143,6 +153,13 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, TCfree (dgBuffer); + if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, + IOCTL_STORAGE_GET_DEVICE_NUMBER, + (char*) &storageDeviceNumber, sizeof (storageDeviceNumber)))) + { + Extension->DeviceNumber = storageDeviceNumber.DeviceNumber; + } + lDiskLength.QuadPart = dg.DiskSize.QuadPart; Extension->HostBytesPerSector = dg.Geometry.BytesPerSector; Extension->HostBytesPerPhysicalSector = dg.Geometry.BytesPerSector; @@ -152,6 +169,8 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, { STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR alignmentDesc = {0}; STORAGE_ADAPTER_DESCRIPTOR adapterDesc = {0}; + DEVICE_SEEK_PENALTY_DESCRIPTOR penaltyDesc = {0}; + DEVICE_TRIM_DESCRIPTOR trimDesc = {0}; storagePropertyQuery.PropertyId = StorageAccessAlignmentProperty; storagePropertyQuery.QueryType = PropertyStandardQuery; @@ -178,6 +197,28 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, Extension->HostMaximumPhysicalPages = adapterDesc.MaximumPhysicalPages; Extension->HostAlignmentMask = adapterDesc.AlignmentMask; } + + storagePropertyQuery.PropertyId = StorageDeviceSeekPenaltyProperty; + penaltyDesc.Version = sizeof (DEVICE_SEEK_PENALTY_DESCRIPTOR); + penaltyDesc.Size = sizeof (DEVICE_SEEK_PENALTY_DESCRIPTOR); + + if (NT_SUCCESS (TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*) &storagePropertyQuery, sizeof(storagePropertyQuery), + (char *) &penaltyDesc, sizeof (penaltyDesc)))) + { + Extension->IncursSeekPenalty = penaltyDesc.IncursSeekPenalty; + } + + storagePropertyQuery.PropertyId = StorageDeviceTrimProperty; + trimDesc.Version = sizeof (DEVICE_TRIM_DESCRIPTOR); + trimDesc.Size = sizeof (DEVICE_TRIM_DESCRIPTOR); + + if (NT_SUCCESS (TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*) &storagePropertyQuery, sizeof(storagePropertyQuery), + (char *) &trimDesc, sizeof (trimDesc)))) + { + Extension->TrimEnabled = trimDesc.TrimEnabled; + } } // Drive geometry is used only when IOCTL_DISK_GET_PARTITION_INFO fails @@ -186,7 +227,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, lDiskLength.QuadPart = pix.PartitionLength.QuadPart; partitionStartingOffset = pix.StartingOffset.QuadPart; } - // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX + // If IOCTL_DISK_GET_PARTITION_INFO_EX fails, switch to IOCTL_DISK_GET_PARTITION_INFO else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char *) &pi, sizeof (pi)))) { lDiskLength.QuadPart = pi.PartitionLength.QuadPart; @@ -265,7 +306,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, if (mount->bMountReadOnly || ntStatus == STATUS_ACCESS_DENIED) { ntStatus = ZwCreateFile (&Extension->hDeviceFile, - GENERIC_READ | SYNCHRONIZE, + GENERIC_READ | (!bRawDevice && mount->bPreserveTimestamp? FILE_WRITE_ATTRIBUTES : 0) | SYNCHRONIZE, &oaFileAttributes, &IoStatusBlock, NULL, @@ -280,6 +321,26 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, NULL, 0); + if (!NT_SUCCESS (ntStatus) && !bRawDevice && mount->bPreserveTimestamp) + { + /* try again without FILE_WRITE_ATTRIBUTES */ + ntStatus = ZwCreateFile (&Extension->hDeviceFile, + GENERIC_READ | SYNCHRONIZE, + &oaFileAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL | + FILE_ATTRIBUTE_SYSTEM, + exclusiveAccess ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_RANDOM_ACCESS | + FILE_WRITE_THROUGH | + (disableBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0) | + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + } + if (NT_SUCCESS (ntStatus) && !mount->bMountReadOnly) mount->VolumeMountedReadOnlyAfterAccessDenied = TRUE; @@ -324,6 +385,18 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, Extension->fileLastWriteTime = FileBasicInfo.LastWriteTime; Extension->fileLastChangeTime = FileBasicInfo.ChangeTime; Extension->bTimeStampValid = TRUE; + + // we tell the system not to update LastAccessTime, LastWriteTime, and ChangeTime + FileBasicInfo.CreationTime.QuadPart = 0; + FileBasicInfo.LastAccessTime.QuadPart = -1; + FileBasicInfo.LastWriteTime.QuadPart = -1; + FileBasicInfo.ChangeTime.QuadPart = -1; + + ZwSetInformationFile (Extension->hDeviceFile, + &IoStatusBlock, + &FileBasicInfo, + sizeof (FileBasicInfo), + FileBasicInformation); } ntStatus = ZwQueryInformationFile (Extension->hDeviceFile, @@ -414,7 +487,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, // Header of a volume that is not within the scope of system encryption, or // header of a system hidden volume (containing a hidden OS) - LARGE_INTEGER headerOffset; + LARGE_INTEGER headerOffset = {0}; if (mount->UseBackupHeader && lDiskLength.QuadPart <= TC_TOTAL_VOLUME_HEADERS_SIZE) continue; @@ -532,26 +605,24 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, { mount->nReturnCode = ReadVolumeHeaderWCache ( FALSE, - mount->bCache, + bAutoCachePassword, mount->bCachePim, readBuffer, &mount->ProtectedHidVolPassword, mount->ProtectedHidVolPkcs5Prf, mount->ProtectedHidVolPim, - mount->bTrueCryptMode, &tmpCryptoInfo); } else { mount->nReturnCode = ReadVolumeHeaderWCache ( mount->bPartitionInInactiveSysEncScope && volumeType == TC_VOLUME_TYPE_NORMAL, - mount->bCache, + bAutoCachePassword, mount->bCachePim, readBuffer, &mount->VolumePassword, mount->pkcs5_prf, mount->VolumePim, - mount->bTrueCryptMode, &Extension->cryptoInfo); } @@ -569,6 +640,11 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, goto error; } +#ifdef _WIN64 + if (IsRamEncryptionEnabled() && (volumeType == TC_VOLUME_TYPE_NORMAL || !mount->bProtectHiddenVolume)) + VcProtectKeys (Extension->cryptoInfo, VcGetEncryptionID (Extension->cryptoInfo)); +#endif + Dump ("Volume header decrypted\n"); Dump ("Required program version = %x\n", (int) Extension->cryptoInfo->RequiredProgramVersion); Dump ("Legacy volume = %d\n", (int) Extension->cryptoInfo->LegacyVolume); @@ -602,10 +678,9 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, if (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value) { - // Partial encryption is not supported for volumes mounted as regular - mount->nReturnCode = ERR_ENCRYPTION_NOT_COMPLETED; - ntStatus = STATUS_SUCCESS; - goto error; + // mount as readonly in case of partial system encryption + Extension->bReadOnly = mount->bMountReadOnly = TRUE; + mount->VolumeMountedReadOnlyAfterPartialSysEnc = TRUE; } } else if (Extension->cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) @@ -625,7 +700,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, if (Extension->cryptoInfo->hiddenVolume && IsHiddenSystemRunning()) { // Prevent mount of a hidden system partition if the system hosted on it is currently running - if (memcmp (Extension->cryptoInfo->master_keydata, GetSystemDriveCryptoInfo()->master_keydata, EAGetKeySize (Extension->cryptoInfo->ea)) == 0) + if (memcmp (Extension->cryptoInfo->master_keydata_hash, GetSystemDriveCryptoInfo()->master_keydata_hash, sizeof(Extension->cryptoInfo->master_keydata_hash)) == 0) { mount->nReturnCode = ERR_VOL_ALREADY_MOUNTED; ntStatus = STATUS_SUCCESS; @@ -723,8 +798,7 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, Extension->TracksPerCylinder = 1; Extension->SectorsPerTrack = 1; Extension->BytesPerSector = Extension->cryptoInfo->SectorSize; - // Add extra sector since our virtual partition starts at Extension->BytesPerSector and not 0 - Extension->NumberOfCylinders = (Extension->DiskLength / Extension->BytesPerSector) + 1; + Extension->NumberOfCylinders = Extension->DiskLength / Extension->BytesPerSector; Extension->PartitionType = 0; Extension->bRawDevice = bRawDevice; @@ -751,6 +825,13 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, // decrypt the hidden volume header. if (!(volumeType == TC_VOLUME_TYPE_NORMAL && mount->bProtectHiddenVolume)) { + /* in case of mounting with hidden volume protection, we cache both passwords manually after bother outer and hidden volumes are mounted*/ + if (mount->bProtectHiddenVolume && mount->bCache) + { + AddPasswordToCache(&mount->VolumePassword, mount->VolumePim, mount->bCachePim); + AddPasswordToCache(&mount->ProtectedHidVolPassword, mount->ProtectedHidVolPim, mount->bCachePim); + } + TCfree (readBuffer); if (tmpCryptoInfo != NULL) @@ -843,6 +924,18 @@ void TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) } } +typedef struct +{ + PDEVICE_OBJECT deviceObject; PEXTENSION Extension; ULONG ioControlCode; void *inputBuffer; int inputBufferSize; void *outputBuffer; int outputBufferSize; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} TCSendHostDeviceIoControlRequestExWorkItemArgs; + +static VOID TCSendHostDeviceIoControlRequestExWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, TCSendHostDeviceIoControlRequestExWorkItemArgs *arg) +{ + arg->Status = TCSendHostDeviceIoControlRequestEx (arg->deviceObject, arg->Extension, arg->ioControlCode, arg->inputBuffer, arg->inputBufferSize, arg->outputBuffer, arg->outputBufferSize); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} NTSTATUS TCSendHostDeviceIoControlRequestEx (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, @@ -858,6 +951,31 @@ NTSTATUS TCSendHostDeviceIoControlRequestEx (PDEVICE_OBJECT DeviceObject, UNREFERENCED_PARAMETER(DeviceObject); /* Remove compiler warning */ + if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) + { + TCSendHostDeviceIoControlRequestExWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.deviceObject = DeviceObject; + args.Extension = Extension; + args.ioControlCode = IoControlCode; + args.inputBuffer = InputBuffer; + args.inputBufferSize = InputBufferSize; + args.outputBuffer = OutputBuffer; + args.outputBufferSize = OutputBufferSize; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, TCSendHostDeviceIoControlRequestExWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + KeClearEvent (&Extension->keVolumeEvent); Irp = IoBuildDeviceIoControlRequest (IoControlCode, diff --git a/src/Driver/VolumeFilter.c b/src/Driver/VolumeFilter.c index a3d323be..29d02673 100644 --- a/src/Driver/VolumeFilter.c +++ b/src/Driver/VolumeFilter.c @@ -25,7 +25,7 @@ uint32 HiddenSysLeakProtectionCount = 0; NTSTATUS VolumeFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) { - VolumeFilterExtension *Extension; + VolumeFilterExtension *Extension = NULL; NTSTATUS status; PDEVICE_OBJECT filterDeviceObject = NULL; PDEVICE_OBJECT attachedDeviceObject; @@ -72,7 +72,7 @@ NTSTATUS VolumeFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) err: if (filterDeviceObject) { - if (Extension->LowerDeviceObject) + if (Extension && Extension->LowerDeviceObject) IoDetachDevice (Extension->LowerDeviceObject); IoDeleteDevice (filterDeviceObject); @@ -125,6 +125,32 @@ static NTSTATUS OnStartDeviceCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP return STATUS_CONTINUE_COMPLETION; } +static BOOL IsSystemVolumePartition (VolumeFilterExtension *Extension) +{ + NTSTATUS status; + BOOL bRet = FALSE; + DriveFilterExtension *bootDriveExtension = GetBootDriveFilterExtension(); + STORAGE_DEVICE_NUMBER storageDeviceNumber; + + if (!bootDriveExtension->SystemStorageDeviceNumberValid) + TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + + status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &storageDeviceNumber, sizeof (storageDeviceNumber)); + + if (NT_SUCCESS (status) && bootDriveExtension->SystemStorageDeviceNumber == storageDeviceNumber.DeviceNumber) + { + PARTITION_INFORMATION_EX partition; + status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partition, sizeof (partition)); + + if (NT_SUCCESS (status) && partition.StartingOffset.QuadPart == bootDriveExtension->ConfiguredEncryptedAreaStart) + { + bRet = TRUE; + } + } + + return bRet; +} + static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { @@ -139,25 +165,10 @@ static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFi case IOCTL_DISK_IS_WRITABLE: { // All volumes except the system volume must be read-only - - DriveFilterExtension *bootDriveExtension = GetBootDriveFilterExtension(); - STORAGE_DEVICE_NUMBER storageDeviceNumber; - - if (!bootDriveExtension->SystemStorageDeviceNumberValid) - TC_BUG_CHECK (STATUS_INVALID_PARAMETER); - - status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &storageDeviceNumber, sizeof (storageDeviceNumber)); - - if (NT_SUCCESS (status) && bootDriveExtension->SystemStorageDeviceNumber == storageDeviceNumber.DeviceNumber) + if (IsSystemVolumePartition(Extension)) { - PARTITION_INFORMATION_EX partition; - status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partition, sizeof (partition)); - - if (NT_SUCCESS (status) && partition.StartingOffset.QuadPart == bootDriveExtension->ConfiguredEncryptedAreaStart) - { - IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); - return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); - } + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); } IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); @@ -194,6 +205,15 @@ static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFi IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); + + case IOCTL_DISK_GROW_PARTITION: + if (IsSystemVolumePartition(Extension)) + { + Dump ("VolumeFilter-DispatchControl: IOCTL_DISK_GROW_PARTITION blocked\n"); + IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); + return TCCompleteDiskIrp (Irp, STATUS_UNSUCCESSFUL, 0); + } + break; } } diff --git a/src/Driver/veracrypt_vs2019.vcxproj b/src/Driver/veracrypt_vs2019.vcxproj new file mode 100644 index 00000000..e956bcb0 --- /dev/null +++ b/src/Driver/veracrypt_vs2019.vcxproj @@ -0,0 +1,598 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Common\Cache.c" /> + <ClCompile Include="..\Common\Crc.c" /> + <ClCompile Include="..\Common\Crypto.c" /> + <ClCompile Include="..\Common\EncryptionThreadPool.c" /> + <ClCompile Include="..\Common\Endian.c" /> + <ClCompile Include="..\Common\GfMul.c" /> + <ClCompile Include="..\Common\Pkcs5.c" /> + <ClCompile Include="..\Common\Tests.c" /> + <ClCompile Include="..\Common\Volumes.c" /> + <ClCompile Include="..\Common\Wipe.c" /> + <ClCompile Include="..\Common\Xts.c" /> + <ClCompile Include="..\Crypto\Aescrypt.c" /> + <ClCompile Include="..\Crypto\Aeskey.c" /> + <ClCompile Include="..\Crypto\Aestab.c" /> + <ClCompile Include="..\Crypto\blake2s.c" /> + <ClCompile Include="..\Crypto\blake2s_SSE2.c" /> + <ClCompile Include="..\Crypto\blake2s_SSE41.c" /> + <ClCompile Include="..\Crypto\blake2s_SSSE3.c" /> + <ClCompile Include="..\Crypto\Camellia.c" /> + <ClCompile Include="..\Crypto\chacha-xmm.c" /> + <ClCompile Include="..\Crypto\chacha256.c" /> + <ClCompile Include="..\Crypto\chachaRng.c" /> + <ClCompile Include="..\Crypto\cpu.c" /> + <ClCompile Include="..\Crypto\jitterentropy-base.c" /> + <ClCompile Include="..\Crypto\kuznyechik.c" /> + <ClCompile Include="..\Crypto\kuznyechik_simd.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\Crypto\rdrand.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\Crypto\SerpentFast.c" /> + <ClCompile Include="..\Crypto\SerpentFast_simd.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\Crypto\Sha2.c" /> + <ClCompile Include="..\Crypto\Streebog.c" /> + <ClCompile Include="..\Crypto\t1ha2.c" /> + <ClCompile Include="..\Crypto\t1ha2_selfcheck.c" /> + <ClCompile Include="..\Crypto\t1ha_selfcheck.c" /> + <ClCompile Include="..\Crypto\Twofish.c" /> + <ClCompile Include="..\Crypto\Whirlpool.c" /> + <ClCompile Include="Ntdriver.c" /> + <ClCompile Include="VolumeFilter.c" /> + <ClCompile Include="DriveFilter.c" /> + <ClCompile Include="DumpFilter.c" /> + <ClCompile Include="EncryptedIoQueue.c" /> + <ClCompile Include="Ntvol.c" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4B41C7B5-75C6-40A2-AF4D-55BC1E012BCD}</ProjectGuid> + <TemplateGuid>{f2f62967-0815-4fd7-9b86-6eedcac766eb}</TemplateGuid> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <Configuration>Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <RootNamespace>veracrypt</RootNamespace> + <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion> + <ProjectName>driver</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <_NT_TARGET_VERSION>0x0A00</_NT_TARGET_VERSION> + <SupportsPackaging>false</SupportsPackaging> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <_NT_TARGET_VERSION>0x0A00</_NT_TARGET_VERSION> + <SupportsPackaging>false</SupportsPackaging> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <_NT_TARGET_VERSION>0x0A00</_NT_TARGET_VERSION> + <SupportsPackaging>false</SupportsPackaging> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <_NT_TARGET_VERSION>0x0A00</_NT_TARGET_VERSION> + <SupportsPackaging>false</SupportsPackaging> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <_NT_TARGET_VERSION>0x0A00</_NT_TARGET_VERSION> + <SupportsPackaging>false</SupportsPackaging> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>WDM</DriverType> + <_NT_TARGET_VERSION>0x0A00</_NT_TARGET_VERSION> + <SupportsPackaging>false</SupportsPackaging> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + <OutDir>$(SolutionDir)$(Platform)\$(ConfigurationName)\</OutDir> + <TargetName>veracrypt</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>veracrypt</TargetName> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>veracrypt</TargetName> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)$(Platform)\$(ConfigurationName)\</OutDir> + <TargetName>veracrypt</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>veracrypt</TargetName> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>veracrypt</TargetName> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Link> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_WIN32;_NO_CRT_STDIO_INLINE;DEBUG;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4064;4627;4627;4366;4100;4057;4457;4456;4152;4213;4244;4127;4706;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <PostBuildEvent> + <Command>copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-arm64.sys"</Command> + </PostBuildEvent> + <Inf> + <SpecifyDriverVerDirectiveVersion>false</SpecifyDriverVerDirectiveVersion> + </Inf> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Link> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_WIN32;_NO_CRT_STDIO_INLINE;DEBUG;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4064;4627;4627;4366;4100;4057;4457;4456;4152;4213;4244;4127;4706;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <PostBuildEvent> + <Command>copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-arm64.sys"</Command> + </PostBuildEvent> + <Inf> + <SpecifyDriverVerDirectiveVersion>false</SpecifyDriverVerDirectiveVersion> + </Inf> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Link> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_WIN32;_NO_CRT_STDIO_INLINE;DEBUG;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4064;4627;4627;4366;4100;4057;4457;4456;4152;4213;4244;4127;4706;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <PostBuildEvent> + <Command>copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-arm64.sys"</Command> + </PostBuildEvent> + <Inf> + <SpecifyDriverVerDirectiveVersion>false</SpecifyDriverVerDirectiveVersion> + </Inf> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Link> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_WIN32;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4064;4627;4627;4366;4100;4057;4457;4456;4152;4213;4244;4127;4706;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <PostBuildEvent> + <Command>copy $(TargetPath) "..\Release\Setup Files\VeraCrypt-arm64.sys"</Command> + </PostBuildEvent> + <Inf> + <SpecifyArchitecture>true</SpecifyArchitecture> + <SpecifyDriverVerDirectiveVersion>false</SpecifyDriverVerDirectiveVersion> + </Inf> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Link> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_WIN32;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4064;4627;4627;4366;4100;4057;4457;4456;4152;4213;4244;4127;4706;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <PostBuildEvent> + <Command>copy $(TargetPath) "..\Release\Setup Files\VeraCrypt-arm64.sys"</Command> + </PostBuildEvent> + <Inf> + <SpecifyArchitecture>true</SpecifyArchitecture> + <SpecifyDriverVerDirectiveVersion>false</SpecifyDriverVerDirectiveVersion> + </Inf> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Link> + <AdditionalDependencies>fltmgr.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + </Link> + <ClCompile> + <AdditionalIncludeDirectories>$(SolutionDir)Common;$(SolutionDir)Crypto;$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>TC_WINDOWS_DRIVER;_WIN32;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4064;4627;4627;4366;4100;4057;4457;4456;4152;4213;4244;4127;4706;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + <PostBuildEvent> + <Command>copy $(TargetPath) "..\Release\Setup Files\VeraCrypt-arm64.sys"</Command> + </PostBuildEvent> + <Inf> + <SpecifyArchitecture>true</SpecifyArchitecture> + <SpecifyDriverVerDirectiveVersion>false</SpecifyDriverVerDirectiveVersion> + </Inf> + </ItemDefinitionGroup> + <ItemGroup> + <FilesToPackage Include="$(TargetPath)" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Crypto\Aes.h" /> + <ClInclude Include="..\Crypto\Aesopt.h" /> + <ClInclude Include="..\Crypto\AesSmall.h" /> + <ClInclude Include="..\Crypto\Aestab.h" /> + <ClInclude Include="..\Crypto\Aes_hw_cpu.h" /> + <ClInclude Include="..\Crypto\Camellia.h" /> + <ClInclude Include="..\Crypto\chacha256.h" /> + <ClInclude Include="..\Crypto\chachaRng.h" /> + <ClInclude Include="..\Crypto\chacha_u1.h" /> + <ClInclude Include="..\Crypto\chacha_u4.h" /> + <ClInclude Include="..\Crypto\config.h" /> + <ClInclude Include="..\Crypto\cpu.h" /> + <ClInclude Include="..\Crypto\GostCipher.h" /> + <ClInclude Include="..\Crypto\jitterentropy-base-user.h" /> + <ClInclude Include="..\Crypto\jitterentropy.h" /> + <ClInclude Include="..\Crypto\kuznyechik.h" /> + <ClInclude Include="..\Crypto\misc.h" /> + <ClInclude Include="..\Crypto\rdrand.h" /> + <ClInclude Include="..\Crypto\Rmd160.h" /> + <ClInclude Include="..\Crypto\SerpentFast.h" /> + <ClInclude Include="..\Crypto\SerpentFast_sbox.h" /> + <ClInclude Include="..\Crypto\Sha2.h" /> + <ClInclude Include="..\Crypto\Streebog.h" /> + <ClInclude Include="..\Crypto\t1ha.h" /> + <ClInclude Include="..\Crypto\t1ha_bits.h" /> + <ClInclude Include="..\Crypto\t1ha_selfcheck.h" /> + <ClInclude Include="..\Crypto\Twofish.h" /> + <ClInclude Include="..\Crypto\Whirlpool.h" /> + <ClInclude Include="DriveFilter.h" /> + <ClInclude Include="DumpFilter.h" /> + <ClInclude Include="EncryptedIoQueue.h" /> + <ClInclude Include="Ntdriver.h" /> + <ClInclude Include="Ntvol.h" /> + <ClInclude Include="Resource.h" /> + <ClInclude Include="VolumeFilter.h" /> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Aes_hw_cpu.asm"> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -g -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -g -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -g -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -g -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -g -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win64 -Ox -g -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Aes_x64.asm"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Aes_x86.asm"> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & nasm.exe -Xvc -f win32 -Ox -g --prefix _ -o "$(TargetDir)\%(Filename).obj" "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Twofish_x64.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Camellia_aesni_x64.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Camellia_x64.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha256-x86-nayuki.S"> + <FileType>Document</FileType> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha256_avx1_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha256_avx2_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha256_sse4_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512-x86-nayuki.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512-x64-nayuki.S"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512_avx1_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512_avx2_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\sha512_sse4_x64.asm"> + <FileType>Document</FileType> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\rdrand_ml.asm"> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\rdseed_ml.asm"> + <FileType>Document</FileType> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)" +</Command> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="Driver.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/src/Driver/veracrypt_vs2019.vcxproj.filters b/src/Driver/veracrypt_vs2019.vcxproj.filters new file mode 100644 index 00000000..f0c7d0e3 --- /dev/null +++ b/src/Driver/veracrypt_vs2019.vcxproj.filters @@ -0,0 +1,326 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + <Filter Include="Driver Files"> + <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + </Filter> + <Filter Include="Crypto"> + <UniqueIdentifier>{27c1f176-3bb2-46ab-abe5-d5ea01d8d4c9}</UniqueIdentifier> + </Filter> + <Filter Include="Crypto\Source Files"> + <UniqueIdentifier>{a5c1dc1f-29ec-4ea8-b535-61dd2c5e4342}</UniqueIdentifier> + </Filter> + <Filter Include="Crypto\Header Files"> + <UniqueIdentifier>{e69db28f-0030-4532-9d70-5c11b63d1e2b}</UniqueIdentifier> + </Filter> + <Filter Include="Common"> + <UniqueIdentifier>{c9095cb6-8efa-4261-902e-a9b8afa443d6}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="DriveFilter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="DumpFilter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="EncryptedIoQueue.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Ntvol.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="VolumeFilter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Aeskey.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Aestab.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Camellia.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chacha-xmm.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chacha256.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\chachaRng.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\cpu.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\jitterentropy-base.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\kuznyechik.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\kuznyechik_simd.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\rdrand.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\SerpentFast.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\SerpentFast_simd.cpp"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Sha2.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Streebog.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha2.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha2_selfcheck.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\t1ha_selfcheck.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Twofish.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Whirlpool.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Common\Cache.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\Crc.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\Crypto.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\EncryptionThreadPool.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\Endian.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\GfMul.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\Pkcs5.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\Tests.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\Volumes.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\Wipe.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Common\Xts.c"> + <Filter>Common</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\Aescrypt.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="Ntdriver.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s_SSE2.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s_SSE41.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Crypto\blake2s_SSSE3.c"> + <Filter>Crypto\Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="DriveFilter.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="DumpFilter.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="EncryptedIoQueue.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Ntdriver.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Ntvol.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="VolumeFilter.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Aes.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Aes_hw_cpu.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Aesopt.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Aestab.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Camellia.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\chacha256.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\chachaRng.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\chacha_u1.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\chacha_u4.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\config.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\cpu.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\GostCipher.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\jitterentropy-base-user.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\jitterentropy.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\kuznyechik.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\misc.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\rdrand.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Rmd160.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\SerpentFast.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\SerpentFast_sbox.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Sha2.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Streebog.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\t1ha.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\t1ha_bits.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\t1ha_selfcheck.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Twofish.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\Whirlpool.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Crypto\AesSmall.h"> + <Filter>Crypto\Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Crypto\Aes_hw_cpu.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Aes_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Aes_x86.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Twofish_x64.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Camellia_aesni_x64.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\Camellia_x64.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha256-x86-nayuki.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha256_avx1_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha256_avx2_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha256_sse4_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512-x86-nayuki.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512-x64-nayuki.S"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512_avx1_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512_avx2_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\sha512_sse4_x64.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\rdrand_ml.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + <CustomBuild Include="..\Crypto\rdseed_ml.asm"> + <Filter>Crypto\Source Files</Filter> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="Driver.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file |