From cf48b532b447faa969347fef183c6e8921c4ded2 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Tue, 26 Feb 2019 01:50:27 +0100 Subject: Windows: Implement RAM encryption for keys on 64-bit machines using ChaCha12 cipher and t1ha non-cryptographic fast hash (https://github.com/leo-yuriev/t1ha) --- src/Driver/DriveFilter.c | 54 ++++++++++++++++++++++++++++++++++----- src/Driver/Driver.vcxproj | 3 +++ src/Driver/Driver.vcxproj.filters | 9 +++++++ src/Driver/DumpFilter.c | 2 +- src/Driver/Ntdriver.c | 23 ++++++++++++++++- src/Driver/Ntvol.c | 4 +++ 6 files changed, 87 insertions(+), 8 deletions(-) (limited to 'src/Driver') diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c index 3c7687f8..5fbacac4 100644 --- a/src/Driver/DriveFilter.c +++ b/src/Driver/DriveFilter.c @@ -94,9 +94,9 @@ NTSTATUS LoadBootArguments () bootArgsAddr.QuadPart = BootArgsRegions[bootLoaderArgsIndex] + TC_BOOT_LOADER_ARGS_OFFSET; Dump ("Checking BootArguments at 0x%x\n", bootArgsAddr.LowPart); - mappedBootArgs = MmMapIoSpace (bootArgsAddr, sizeof (BootArguments), MmCached); - if (!mappedBootArgs) - return STATUS_INSUFFICIENT_RESOURCES; + mappedBootArgs = MmMapIoSpace (bootArgsAddr, sizeof (BootArguments), MmCached); + if (!mappedBootArgs) + return STATUS_INSUFFICIENT_RESOURCES; if (TC_IS_BOOT_ARGUMENTS_SIGNATURE (mappedBootArgs)) { @@ -639,6 +639,12 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, } else Extension->Queue.MaxReadAheadOffset = BootDriveLength; + + /* encrypt keys */ +#ifdef _WIN64 + VcProtectKeys (Extension->HeaderCryptoInfo, VcGetEncryptionID (Extension->HeaderCryptoInfo)); + VcProtectKeys (Extension->Queue.CryptoInfo, VcGetEncryptionID (Extension->Queue.CryptoInfo)); +#endif status = EncryptedIoQueueStart (&Extension->Queue); if (!NT_SUCCESS (status)) @@ -710,8 +716,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) { @@ -726,7 +742,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); @@ -961,6 +983,9 @@ static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilte && irpSp->Parameters.Power.Type == DevicePowerState) { DismountDrive (Extension, TRUE); +#ifdef _WIN64 + ClearSecurityParameters (); +#endif } PoStartNextPowerIrp (Irp); @@ -1087,6 +1112,10 @@ void EmergencyClearAllKeys (PIRP irp, PIO_STACK_LOCATION irpSp) if (BootDriveFound && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted) InvalidateDriveFilterKeys (BootDriveFilterExtension); +#ifdef _WIN64 + ClearSecurityParameters(); +#endif + irp->IoStatus.Status = STATUS_SUCCESS; } } @@ -1139,9 +1168,22 @@ void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) goto ret; } +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + VcUnprotectKeys (BootDriveFilterExtension->HeaderCryptoInfo, VcGetEncryptionID (BootDriveFilterExtension->HeaderCryptoInfo)); + } +#endif + if (ReadVolumeHeader (!BootDriveFilterExtension->HiddenSystem, header, &request->VolumePassword, request->pkcs5_prf, request->pim, FALSE, 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->pkcs5 = BootDriveFilterExtension->HeaderCryptoInfo->pkcs5; @@ -1258,7 +1300,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); diff --git a/src/Driver/Driver.vcxproj b/src/Driver/Driver.vcxproj index 5744934b..58a21d3d 100644 --- a/src/Driver/Driver.vcxproj +++ b/src/Driver/Driver.vcxproj @@ -201,6 +201,9 @@ BuildDriver.cmd -rebuild -debug -x64 "$(SolutionDir)\Common" "$(SolutionDir)\Cry + + + diff --git a/src/Driver/Driver.vcxproj.filters b/src/Driver/Driver.vcxproj.filters index a6f5da3c..f260fb56 100644 --- a/src/Driver/Driver.vcxproj.filters +++ b/src/Driver/Driver.vcxproj.filters @@ -126,6 +126,15 @@ Source Files\Crypto + + Source Files\Crypto + + + Source Files\Crypto + + + Source Files\Crypto + diff --git a/src/Driver/DumpFilter.c b/src/Driver/DumpFilter.c index 2b58d061..fc1c7d37 100644 --- a/src/Driver/DumpFilter.c +++ b/src/Driver/DumpFilter.c @@ -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/Ntdriver.c b/src/Driver/Ntdriver.c index ba2de477..97fb1bf1 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -287,6 +287,24 @@ 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 (IsRamEncryptionEnabled()) + { + if (t1ha_selfcheck__t1ha2() != 0) + TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + if (!InitializeSecurityParameters(GetDriverRandomSeed)) + TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + } + } + else + { + EnableRamEncryption (FALSE); + } +#endif + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i) { DriverObject->MajorFunction[i] = TCDispatchQueueIRP; @@ -326,7 +344,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) { @@ -351,6 +369,7 @@ void DumpMemory (void *mem, int size) m+=8; } } +#endif BOOL IsAllZeroes (unsigned char* pbData, DWORD dwDataLen) { @@ -4453,6 +4472,8 @@ NTSTATUS ReadRegistryConfigFlags (BOOL driverEntry) flags ^= VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION; WriteRegistryConfigFlags (flags); } + + EnableRamEncryption ((flags & VC_DRIVER_CONFIG_ENABLE_RAM_ENCRYPTION) ? TRUE : FALSE); } EnableHwEncryption ((flags & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? FALSE : TRUE); diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c index a317d8be..ab9370f7 100644 --- a/src/Driver/Ntvol.c +++ b/src/Driver/Ntvol.c @@ -591,6 +591,10 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, mount->VolumePim, mount->bTrueCryptMode, &Extension->cryptoInfo); +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + VcProtectKeys (Extension->cryptoInfo, VcGetEncryptionID (Extension->cryptoInfo)); +#endif } ReadVolumeHeaderRecoveryMode = FALSE; -- cgit v1.2.3