mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Windows EFI Bootloader: modifications to prepare EFI system encryption support (common files with DcsBoot)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
|
||||
by the TrueCrypt License 3.0.
|
||||
|
||||
Modifications and additions to the original source code (contained in this file)
|
||||
Modifications and additions to the original source code (contained in this file)
|
||||
and all other portions of this file are Copyright (c) 2013-2016 IDRIX
|
||||
and are governed by the Apache License 2.0 the full text of which is
|
||||
contained in the file License.txt included in VeraCrypt binary and source
|
||||
@@ -33,7 +33,7 @@ static BOOL DeviceFilterActive = FALSE;
|
||||
|
||||
BOOL BootArgsValid = FALSE;
|
||||
BootArguments BootArgs;
|
||||
static uint16 BootLoaderSegment;
|
||||
static uint64 BootLoaderArgsPtr;
|
||||
static BOOL BootDriveSignatureValid = FALSE;
|
||||
|
||||
static KMUTEX MountMutex;
|
||||
@@ -69,21 +69,22 @@ static int64 DecoySystemWipedAreaEnd;
|
||||
PKTHREAD DecoySystemWipeThread = NULL;
|
||||
static NTSTATUS DecoySystemWipeResult;
|
||||
|
||||
uint64 BootArgsRegions[] = { EFI_BOOTARGS_REGIONS };
|
||||
|
||||
NTSTATUS LoadBootArguments ()
|
||||
{
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
PHYSICAL_ADDRESS bootArgsAddr;
|
||||
byte *mappedBootArgs;
|
||||
uint16 bootLoaderSegment;
|
||||
uint16 bootLoaderArgsIndex;
|
||||
|
||||
KeInitializeMutex (&MountMutex, 0);
|
||||
|
||||
for (bootLoaderSegment = TC_BOOT_LOADER_SEGMENT;
|
||||
bootLoaderSegment >= TC_BOOT_LOADER_SEGMENT - 64 * 1024 / 16 && status != STATUS_SUCCESS;
|
||||
bootLoaderSegment -= 32 * 1024 / 16)
|
||||
for (bootLoaderArgsIndex = 0;
|
||||
bootLoaderArgsIndex < sizeof(BootArgsRegions)/ sizeof(BootArgsRegions[1]) && status != STATUS_SUCCESS;
|
||||
++bootLoaderArgsIndex)
|
||||
{
|
||||
bootArgsAddr.QuadPart = (bootLoaderSegment << 4) + TC_BOOT_LOADER_ARGS_OFFSET;
|
||||
bootArgsAddr.QuadPart = BootArgsRegions[bootLoaderArgsIndex] + TC_BOOT_LOADER_ARGS_OFFSET;
|
||||
Dump ("Checking BootArguments at 0x%x\n", bootArgsAddr.LowPart);
|
||||
|
||||
mappedBootArgs = MmMapIoSpace (bootArgsAddr, sizeof (BootArguments), MmCached);
|
||||
@@ -107,7 +108,7 @@ NTSTATUS LoadBootArguments ()
|
||||
// Sanity check: for valid boot argument, the password is less than 64 bytes long
|
||||
if (bootArguments->BootPassword.Length <= MAX_PASSWORD)
|
||||
{
|
||||
BootLoaderSegment = bootLoaderSegment;
|
||||
BootLoaderArgsPtr = BootArgsRegions[bootLoaderArgsIndex];
|
||||
|
||||
BootArgs = *bootArguments;
|
||||
BootArgsValid = TRUE;
|
||||
@@ -168,7 +169,7 @@ NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
|
||||
Extension = (DriveFilterExtension *) filterDeviceObject->DeviceExtension;
|
||||
memset (Extension, 0, sizeof (DriveFilterExtension));
|
||||
|
||||
status = IoAttachDeviceToDeviceStackSafe (filterDeviceObject, pdo, &(Extension->LowerDeviceObject));
|
||||
status = IoAttachDeviceToDeviceStackSafe (filterDeviceObject, pdo, &(Extension->LowerDeviceObject));
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
goto err;
|
||||
@@ -183,7 +184,7 @@ NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
|
||||
Extension->IsDriveFilterDevice = Extension->Queue.IsFilterDevice = TRUE;
|
||||
Extension->DeviceObject = Extension->Queue.DeviceObject = filterDeviceObject;
|
||||
Extension->Pdo = pdo;
|
||||
|
||||
|
||||
Extension->Queue.LowerDeviceObject = Extension->LowerDeviceObject;
|
||||
IoInitializeRemoveLock (&Extension->Queue.RemoveLock, 'LRCV', 0, 0);
|
||||
|
||||
@@ -216,7 +217,7 @@ static void DismountDrive (DriveFilterExtension *Extension, BOOL stopIoQueue)
|
||||
{
|
||||
Dump ("Dismounting drive\n");
|
||||
ASSERT (Extension->DriveMounted);
|
||||
|
||||
|
||||
if (stopIoQueue && EncryptedIoQueueIsRunning (&Extension->Queue))
|
||||
EncryptedIoQueueStop (&Extension->Queue);
|
||||
|
||||
@@ -250,7 +251,7 @@ static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte*
|
||||
// TC_BOOT_SECTOR_USER_CONFIG_OFFSET = 438
|
||||
//
|
||||
// we have: TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE
|
||||
|
||||
|
||||
WHIRLPOOL_init (&whirlpool);
|
||||
sha512_begin (&sha2);
|
||||
// read the first 512 bytes
|
||||
@@ -322,6 +323,8 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password,
|
||||
char *header;
|
||||
int pkcs5_prf = 0, pim = 0;
|
||||
byte *mappedCryptoInfo = NULL;
|
||||
PARTITION_INFORMATION_EX pi;
|
||||
BOOL bIsGPT = FALSE;
|
||||
|
||||
Dump ("MountDrive pdo=%p\n", Extension->Pdo);
|
||||
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||
@@ -372,11 +375,16 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password,
|
||||
goto ret;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi))))
|
||||
{
|
||||
bIsGPT = (pi.PartitionStyle == PARTITION_STYLE_GPT)? TRUE : FALSE;
|
||||
}
|
||||
|
||||
if (BootArgs.CryptoInfoLength > 0)
|
||||
{
|
||||
PHYSICAL_ADDRESS cryptoInfoAddress;
|
||||
|
||||
cryptoInfoAddress.QuadPart = (BootLoaderSegment << 4) + BootArgs.CryptoInfoOffset;
|
||||
PHYSICAL_ADDRESS cryptoInfoAddress;
|
||||
|
||||
cryptoInfoAddress.QuadPart = BootLoaderArgsPtr + BootArgs.CryptoInfoOffset;
|
||||
#ifdef DEBUG
|
||||
Dump ("Wiping memory %x %d\n", cryptoInfoAddress.LowPart, BootArgs.CryptoInfoLength);
|
||||
#endif
|
||||
@@ -386,7 +394,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password,
|
||||
/* Get the parameters used for booting to speed up driver startup and avoid testing irrelevant PRFs */
|
||||
BOOT_CRYPTO_HEADER* pBootCryptoInfo = (BOOT_CRYPTO_HEADER*) mappedCryptoInfo;
|
||||
Hash* pHash = HashGet(pBootCryptoInfo->pkcs5);
|
||||
if (pHash && pHash->SystemEncryption)
|
||||
if (pHash && (bIsGPT || pHash->SystemEncryption))
|
||||
pkcs5_prf = pBootCryptoInfo->pkcs5;
|
||||
}
|
||||
}
|
||||
@@ -401,20 +409,20 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password,
|
||||
|
||||
// calculate Fingerprint
|
||||
ComputeBootLoaderFingerprint (Extension->LowerDeviceObject, header);
|
||||
|
||||
|
||||
if (Extension->Queue.CryptoInfo->hiddenVolume)
|
||||
{
|
||||
int64 hiddenPartitionOffset = BootArgs.HiddenSystemPartitionStart;
|
||||
Dump ("Hidden volume start offset = %I64d\n", Extension->Queue.CryptoInfo->EncryptedAreaStart.Value + hiddenPartitionOffset);
|
||||
|
||||
|
||||
Extension->HiddenSystem = TRUE;
|
||||
|
||||
Extension->Queue.RemapEncryptedArea = TRUE;
|
||||
Extension->Queue.RemappedAreaOffset = hiddenPartitionOffset + Extension->Queue.CryptoInfo->EncryptedAreaStart.Value - BootArgs.DecoySystemPartitionStart;
|
||||
Extension->Queue.RemappedAreaDataUnitOffset = Extension->Queue.CryptoInfo->EncryptedAreaStart.Value / ENCRYPTION_DATA_UNIT_SIZE - BootArgs.DecoySystemPartitionStart / ENCRYPTION_DATA_UNIT_SIZE;
|
||||
|
||||
|
||||
Extension->Queue.CryptoInfo->EncryptedAreaStart.Value = BootArgs.DecoySystemPartitionStart;
|
||||
|
||||
|
||||
if (Extension->Queue.CryptoInfo->VolumeSize.Value > hiddenPartitionOffset - BootArgs.DecoySystemPartitionStart)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
@@ -473,7 +481,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password,
|
||||
}
|
||||
|
||||
status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &BootDriveLength, sizeof (BootDriveLength));
|
||||
|
||||
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
Dump ("Failed to get drive length - error %x\n", status);
|
||||
@@ -482,7 +490,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password,
|
||||
}
|
||||
else
|
||||
Extension->Queue.MaxReadAheadOffset = BootDriveLength;
|
||||
|
||||
|
||||
status = EncryptedIoQueueStart (&Extension->Queue);
|
||||
if (!NT_SUCCESS (status))
|
||||
TC_BUG_CHECK (status);
|
||||
@@ -538,7 +546,7 @@ static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension)
|
||||
|
||||
Dump ("Saving: ConfiguredEncryptedAreaStart=%I64d (%I64d) ConfiguredEncryptedAreaEnd=%I64d (%I64d)\n", Extension->ConfiguredEncryptedAreaStart / 1024 / 1024, Extension->ConfiguredEncryptedAreaStart, Extension->ConfiguredEncryptedAreaEnd / 1024 / 1024, Extension->ConfiguredEncryptedAreaEnd);
|
||||
Dump ("Saving: EncryptedAreaStart=%I64d (%I64d) EncryptedAreaEnd=%I64d (%I64d)\n", Extension->Queue.EncryptedAreaStart / 1024 / 1024, Extension->Queue.EncryptedAreaStart, Extension->Queue.EncryptedAreaEnd / 1024 / 1024, Extension->Queue.EncryptedAreaEnd);
|
||||
|
||||
|
||||
if (Extension->Queue.EncryptedAreaStart == -1 || Extension->Queue.EncryptedAreaEnd == -1
|
||||
|| Extension->Queue.EncryptedAreaEnd <= Extension->Queue.EncryptedAreaStart)
|
||||
{
|
||||
@@ -690,7 +698,7 @@ static NTSTATUS OnStartDeviceCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP
|
||||
}
|
||||
|
||||
KeInitializeEvent (&Extension->MountWorkItemCompletedEvent, SynchronizationEvent, FALSE);
|
||||
IoQueueWorkItem (workItem, MountDriveWorkItemRoutine, DelayedWorkQueue, Extension);
|
||||
IoQueueWorkItem (workItem, MountDriveWorkItemRoutine, DelayedWorkQueue, Extension);
|
||||
|
||||
KeWaitForSingleObject (&Extension->MountWorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL);
|
||||
IoFreeWorkItem (workItem);
|
||||
@@ -829,7 +837,7 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
if (Extension->BootDrive)
|
||||
{
|
||||
status = EncryptedIoQueueAddIrp (&Extension->Queue, Irp);
|
||||
|
||||
|
||||
if (status != STATUS_PENDING)
|
||||
TCCompleteDiskIrp (Irp, status, 0);
|
||||
|
||||
@@ -907,7 +915,7 @@ void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp)
|
||||
{
|
||||
Dump ("Header reopened\n");
|
||||
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;
|
||||
@@ -1037,7 +1045,7 @@ static NTSTATUS HiberDriverWriteFunctionFilter (int filterNumber, PLARGE_INTEGER
|
||||
|
||||
if (writeB)
|
||||
return (*OriginalHiberDriverWriteFunctionsB[filterNumber]) (writeOffset, encryptedDataMdl);
|
||||
|
||||
|
||||
return (*OriginalHiberDriverWriteFunctionsA[filterNumber]) (arg0WriteA, writeOffset, encryptedDataMdl, arg3WriteA);
|
||||
}
|
||||
|
||||
@@ -1281,11 +1289,11 @@ static VOID SetupThreadProc (PVOID threadArg)
|
||||
byte *wipeBuffer = NULL;
|
||||
byte wipeRandChars[TC_WIPE_RAND_CHAR_COUNT];
|
||||
byte wipeRandCharsUpdate[TC_WIPE_RAND_CHAR_COUNT];
|
||||
|
||||
|
||||
KIRQL irql;
|
||||
NTSTATUS status;
|
||||
|
||||
// generate real random values for wipeRandChars and
|
||||
// generate real random values for wipeRandChars and
|
||||
// wipeRandCharsUpdate instead of relying on uninitialized stack memory
|
||||
LARGE_INTEGER iSeed;
|
||||
KeQuerySystemTime( &iSeed );
|
||||
@@ -1312,7 +1320,7 @@ static VOID SetupThreadProc (PVOID threadArg)
|
||||
burn (digest, SHA512_DIGESTSIZE);
|
||||
burn (&tctx, sizeof (tctx));
|
||||
}
|
||||
|
||||
|
||||
burn (&iSeed, sizeof(iSeed));
|
||||
|
||||
SetupResult = STATUS_UNSUCCESSFUL;
|
||||
@@ -1388,7 +1396,7 @@ static VOID SetupThreadProc (PVOID threadArg)
|
||||
}
|
||||
|
||||
EncryptedIoQueueResumeFromHold (&Extension->Queue);
|
||||
|
||||
|
||||
Dump ("EncryptedAreaStart=%I64d\n", Extension->Queue.EncryptedAreaStart);
|
||||
Dump ("EncryptedAreaEnd=%I64d\n", Extension->Queue.EncryptedAreaEnd);
|
||||
Dump ("ConfiguredEncryptedAreaStart=%I64d\n", Extension->ConfiguredEncryptedAreaStart);
|
||||
@@ -1497,7 +1505,7 @@ static VOID SetupThreadProc (PVOID threadArg)
|
||||
}
|
||||
|
||||
EncryptDataUnits (wipeBuffer, &dataUnit, setupBlockSize / ENCRYPTION_DATA_UNIT_SIZE, Extension->Queue.CryptoInfo);
|
||||
memcpy (wipeRandCharsUpdate, wipeBuffer, sizeof (wipeRandCharsUpdate));
|
||||
memcpy (wipeRandCharsUpdate, wipeBuffer, sizeof (wipeRandCharsUpdate));
|
||||
}
|
||||
|
||||
status = TCWriteDevice (BootDriveFilterExtension->LowerDeviceObject, wipeBuffer, offset, setupBlockSize);
|
||||
@@ -1512,7 +1520,7 @@ static VOID SetupThreadProc (PVOID threadArg)
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (wipeRandChars, wipeRandCharsUpdate, sizeof (wipeRandCharsUpdate));
|
||||
memcpy (wipeRandChars, wipeRandCharsUpdate, sizeof (wipeRandCharsUpdate));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1658,7 +1666,7 @@ NTSTATUS StartBootEncryptionSetup (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_ST
|
||||
|
||||
SetupInProgress = TRUE;
|
||||
status = TCStartThread (SetupThreadProc, DeviceObject, &EncryptionSetupThread);
|
||||
|
||||
|
||||
if (!NT_SUCCESS (status))
|
||||
SetupInProgress = FALSE;
|
||||
|
||||
@@ -1754,7 +1762,7 @@ void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp)
|
||||
bootEncStatus->HiddenSysLeakProtectionCount = HiddenSysLeakProtectionCount;
|
||||
|
||||
bootEncStatus->HiddenSystem = Extension->HiddenSystem;
|
||||
|
||||
|
||||
if (Extension->HiddenSystem)
|
||||
bootEncStatus->HiddenSystemPartitionStart = BootArgs.HiddenSystemPartitionStart;
|
||||
}
|
||||
@@ -1790,7 +1798,7 @@ void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp)
|
||||
irp->IoStatus.Information = 0;
|
||||
if (BootArgsValid && BootDriveFound && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted && BootDriveFilterExtension->HeaderCryptoInfo)
|
||||
{
|
||||
BootLoaderFingerprintRequest *bootLoaderFingerprint = (BootLoaderFingerprintRequest *) irp->AssociatedIrp.SystemBuffer;
|
||||
BootLoaderFingerprintRequest *bootLoaderFingerprint = (BootLoaderFingerprintRequest *) irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
/* compute the fingerprint again and check if it is the same as the one retrieved during boot */
|
||||
char *header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
|
||||
@@ -1820,7 +1828,7 @@ void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp)
|
||||
}
|
||||
else
|
||||
{
|
||||
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1931,7 +1939,7 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg)
|
||||
DecoySystemWipeResult = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto ret;
|
||||
}
|
||||
|
||||
|
||||
wipeRandBuffer = TCalloc (TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE);
|
||||
if (!wipeRandBuffer)
|
||||
{
|
||||
@@ -1956,7 +1964,7 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg)
|
||||
}
|
||||
|
||||
memcpy (wipeCryptoInfo->k2, WipeDecoyRequest.WipeKey + EAGetKeySize (ea), EAGetKeySize (ea));
|
||||
|
||||
|
||||
if (!EAInitMode (wipeCryptoInfo))
|
||||
{
|
||||
DecoySystemWipeResult = STATUS_INVALID_PARAMETER;
|
||||
@@ -1969,7 +1977,7 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg)
|
||||
burn (WipeDecoyRequest.WipeKey, sizeof (WipeDecoyRequest.WipeKey));
|
||||
|
||||
offset.QuadPart = Extension->ConfiguredEncryptedAreaStart;
|
||||
|
||||
|
||||
Dump ("Wiping decoy system: start offset = %I64d\n", offset.QuadPart);
|
||||
|
||||
while (!DecoySystemWipeThreadAbortRequested)
|
||||
@@ -2073,7 +2081,7 @@ NTSTATUS StartDecoySystemWipe (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_
|
||||
|
||||
DecoySystemWipeInProgress = TRUE;
|
||||
status = TCStartThread (DecoySystemWipeThreadProc, DeviceObject, &DecoySystemWipeThread);
|
||||
|
||||
|
||||
if (!NT_SUCCESS (status))
|
||||
DecoySystemWipeInProgress = FALSE;
|
||||
|
||||
@@ -2112,7 +2120,7 @@ void GetDecoySystemWipeStatus (PIRP irp, PIO_STACK_LOCATION irpSp)
|
||||
}
|
||||
else
|
||||
wipeStatus->WipedAreaEnd = DecoySystemWipedAreaEnd;
|
||||
|
||||
|
||||
irp->IoStatus.Information = sizeof (DecoySystemWipeStatus);
|
||||
irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user