diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2015-07-29 00:09:14 +0200 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2015-07-29 00:33:10 +0200 |
commit | 6ca598f8418a1ab12ff7353c534d610b4dbac943 (patch) | |
tree | c7c58d7fbd700e3ab4fef078a58c83c2430d847d | |
parent | 69a8ad5bbaa1be2b3a6548c2b3f930d3aa4379e3 (diff) | |
download | VeraCrypt-6ca598f8418a1ab12ff7353c534d610b4dbac943.tar.gz VeraCrypt-6ca598f8418a1ab12ff7353c534d610b4dbac943.zip |
Windows: Implement Evil-Maid-Attack detection mechanism. Write the correct bootloader when changing the system encryption password: this enables to recover if an attack is detected.
-rw-r--r-- | src/Common/Apidrvr.h | 6 | ||||
-rw-r--r-- | src/Common/BootEncryption.cpp | 59 | ||||
-rw-r--r-- | src/Common/BootEncryption.h | 4 | ||||
-rw-r--r-- | src/Common/Language.xml | 1 | ||||
-rw-r--r-- | src/Common/Volumes.c | 37 | ||||
-rw-r--r-- | src/Common/Volumes.h | 3 | ||||
-rw-r--r-- | src/Driver/DriveFilter.c | 97 | ||||
-rw-r--r-- | src/Driver/DriveFilter.h | 1 | ||||
-rw-r--r-- | src/Driver/Ntdriver.c | 6 | ||||
-rw-r--r-- | src/Mount/Mount.c | 15 |
10 files changed, 221 insertions, 8 deletions
diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index ee40aa8a..16b1641f 100644 --- a/src/Common/Apidrvr.h +++ b/src/Common/Apidrvr.h @@ -61,8 +61,9 @@ #define TC_IOCTL_GET_WARNING_FLAGS TC_IOCTL (35)
#define TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY TC_IOCTL (36)
#define TC_IOCTL_REREAD_DRIVER_CONFIG TC_IOCTL (37)
#define TC_IOCTL_GET_SYSTEM_DRIVE_DUMP_CONFIG TC_IOCTL (38)
+#define VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT TC_IOCTL (39)
// Legacy IOCTLs used before version 5.0
#define TC_IOCTL_LEGACY_GET_DRIVER_VERSION 466968
#define TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES 466948
@@ -255,8 +256,13 @@ typedef struct } GetBootEncryptionAlgorithmNameRequest;
typedef struct
{
+ byte Fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
+} BootLoaderFingerprintRequest;
+
+typedef struct
+{
wchar_t DevicePath[TC_MAX_PATH];
byte Configuration;
BOOL DriveIsDynamic;
uint16 BootLoaderVersion;
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index a83db22d..d9570062 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -825,8 +825,14 @@ namespace VeraCrypt CallDriver (TC_IOCTL_GET_BOOT_LOADER_VERSION, NULL, 0, &version, sizeof (version));
return version;
}
+ void BootEncryption::GetInstalledBootLoaderFingerprint (byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE])
+ {
+ BootLoaderFingerprintRequest request;
+ CallDriver (VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT, NULL, 0, &request, sizeof (request));
+ memcpy (fingerprint, request.Fingerprint, sizeof (request.Fingerprint));
+ }
// Note that this does not require admin rights (it just requires the driver to be running)
bool BootEncryption::IsBootLoaderOnDrive (char *devicePath)
{
@@ -1491,14 +1497,20 @@ namespace VeraCrypt void BootEncryption::InstallBootLoader (bool preserveUserConfig, bool hiddenOSCreation)
{
- byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
+ Device device (GetSystemDriveConfiguration().DevicePath);
+ device.CheckOpened (SRC_POS);
+
+ InstallBootLoader (device, preserveUserConfig, hiddenOSCreation);
+ }
+
+ void BootEncryption::InstallBootLoader (Device& device, bool preserveUserConfig, bool hiddenOSCreation)
+ {
+ byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE] = {0};
CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, hiddenOSCreation);
// Write MBR
- Device device (GetSystemDriveConfiguration().DevicePath);
- device.CheckOpened (SRC_POS);
byte mbr[TC_SECTOR_SIZE_BIOS];
device.SeekAt (0);
device.Read (mbr, sizeof (mbr));
@@ -1529,8 +1541,40 @@ namespace VeraCrypt device.SeekAt (TC_SECTOR_SIZE_BIOS);
device.Write (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, sizeof (bootLoaderBuf) - TC_SECTOR_SIZE_BIOS);
}
+#ifndef SETUP
+ bool BootEncryption::CheckBootloaderFingerprint (bool bSilent)
+ {
+ byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE] = {0};
+ byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
+ byte expectedFingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
+ bool bRet = false;
+
+ try
+ {
+ // read bootloader fingerprint
+ GetInstalledBootLoaderFingerprint (fingerprint);
+
+ // compute expected fingerprint
+ CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, false);
+ ::ComputeBootloaderFingerprint (bootLoaderBuf, sizeof (bootLoaderBuf), expectedFingerprint);
+
+ // compare values
+ if (0 == memcmp (fingerprint, expectedFingerprint, sizeof (expectedFingerprint)))
+ {
+ bRet = true;
+ }
+ }
+ catch (Exception& e)
+ {
+ if (!bSilent)
+ e.Show (ParentWindow);
+ }
+
+ return bRet;
+ }
+#endif
string BootEncryption::GetSystemLoaderBackupPath ()
{
char pathBuf[MAX_PATH];
@@ -2414,8 +2458,17 @@ namespace VeraCrypt reopenRequest.pkcs5_prf = cryptoInfo->pkcs5;
reopenRequest.pim = pim;
finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });
+ try
+ {
+ // force update of bootloader if fingerprint doesn't match
+ if (!CheckBootloaderFingerprint (true))
+ InstallBootLoader (device, true);
+ }
+ catch (...)
+ {}
+
CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest));
}
return result;
diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index 6ac42cd3..c93058ad 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -139,8 +139,9 @@ namespace VeraCrypt VolumeFilter,
DumpFilter
};
+ void SetParentWindow (HWND parent) { ParentWindow = parent; }
void AbortDecoyOSWipe ();
void AbortSetup ();
void AbortSetupWait ();
void CallDriver (DWORD ioctl, void *input = nullptr, DWORD inputSize = 0, void *output = nullptr, DWORD outputSize = 0);
@@ -156,16 +157,19 @@ namespace VeraCrypt DecoySystemWipeStatus GetDecoyOSWipeStatus ();
DWORD GetDriverServiceStartType ();
unsigned int GetHiddenOSCreationPhase ();
uint16 GetInstalledBootLoaderVersion ();
+ void GetInstalledBootLoaderFingerprint (byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE]);
Partition GetPartitionForHiddenOS ();
bool IsBootLoaderOnDrive (char *devicePath);
BootEncryptionStatus GetStatus ();
string GetTempPath ();
void GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties);
SystemDriveConfiguration GetSystemDriveConfiguration ();
void Install (bool hiddenSystem);
+ void InstallBootLoader (Device& device, bool preserveUserConfig = false, bool hiddenOSCreation = false);
void InstallBootLoader (bool preserveUserConfig = false, bool hiddenOSCreation = false);
+ bool CheckBootloaderFingerprint (bool bSilent = false);
void InvalidateCachedSysDriveProperties ();
bool IsCDDrivePresent ();
bool IsHiddenSystemRunning ();
bool IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
diff --git a/src/Common/Language.xml b/src/Common/Language.xml index a02da93c..b84b54cd 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1058,8 +1058,9 @@ <string lang="en" key="TC_BOOT_LOADER_ALREADY_INSTALLED">CAUTION: The VeraCrypt Boot Loader is already installed on your system drive!\n\nIt is possible that another system on your computer is already encrypted.\n\nWARNING: PROCEEDING WITH ENCRYPTION OF THE CURRENTLY RUNNING SYSTEM MAY MAKE OTHER SYSTEM(S) IMPOSSIBLE TO START AND RELATED DATA INACCESSIBLE.\n\nAre you sure you want to continue?</string>
<string lang="en" key="SYS_LOADER_RESTORE_FAILED">Failed to restore the original system loader.\n\nPlease use your VeraCrypt Rescue Disk ('Repair Options' > 'Restore original system loader') or Windows installation medium to replace the VeraCrypt Boot Loader with the Windows system loader.</string>
<string lang="en" key="SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK">The original system loader will not be stored on the Rescue Disk (probable cause: missing backup file).</string>
<string lang="en" key="ERROR_MBR_PROTECTED">Failed to write the MBR sector.\n\nYour BIOS may be configured to protect the MBR sector. Check your BIOS settings (press F2, Delete, or Esc, after powering on your computer) for MBR/antivirus protection.</string>
+ <string lang="en" key="BOOT_LOADER_FINGERPRINT_CHECK_FAILED">WARNING: The verification of VeraCrypt bootloader fingerprint failed!\nYour disk may have been tampered with by an attacker ("Evil Maid" attack).\n\nThis warning can also be triggered if you restored VeraCrypt boot loader using an Rescue Disk generated using a different VeraCrypt version.\n\nYou are advised to change your password immediately which will also restore the correct VeraCrypt bootloader. It is recommended to reinstall VeraCrypt and to take measures to avoid access to this machine by untrusted entities.</string>
<string lang="en" key="BOOT_LOADER_VERSION_INCORRECT_PREFERENCES">The required version of the VeraCrypt Boot Loader is currently not installed. This may prevent some of the settings from being saved.</string>
<string lang="en" key="CUSTOM_BOOT_LOADER_MESSAGE_HELP">Note: In some situations, you may wish to prevent a person (adversary) that is watching you start the computer from knowing that you use VeraCrypt. The above options allow you to do that by customizing the VeraCrypt boot loader screen. If you enable the first option, no texts will be displayed by the boot loader (not even when you enter the wrong password). The computer will appear to be "frozen" while you can type your password. In addition, a custom message can be displayed to mislead the adversary. For example, fake error messages such as "Missing operating system" (which is normally displayed by the Windows boot loader if it finds no Windows boot partition). It is, however, important to note that if the adversary can analyze the content of the hard drive, he can still find out that it contains the VeraCrypt boot loader.</string>
<string lang="en" key="CUSTOM_BOOT_LOADER_MESSAGE_PROMPT">WARNING: Please keep in mind that if you enable this option, the VeraCrypt boot loader will not display any texts (not even when you enter the wrong password). The computer will appear to be "frozen" (unresponsive) while you can type your password (the cursor will NOT move and no asterisk will be displayed when you press a key).\n\nAre you sure you want to enable this option?</string>
<string lang="en" key="SYS_PARTITION_OR_DRIVE_APPEARS_FULLY_ENCRYPTED">Your system partition/drive appears to be fully encrypted.</string>
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index d557d171..545f6c62 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -34,8 +34,9 @@ #include "Pkcs5.h"
#ifdef _WIN32
#include <Strsafe.h>
+#include "../Boot/Windows/BootCommon.h"
#endif
/* Volume header v5 structure (used since TrueCrypt 7.0): */
//
@@ -577,8 +578,44 @@ ret: return status;
}
+#ifdef _WIN32
+void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderSize, byte* fingerprint)
+{
+ // compute Whirlpool+SHA512 fingerprint of bootloader including MBR
+ // we skip user configuration fields:
+ // TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET = 402
+ // => TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE = 4
+ // TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = 406
+ // => TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH = 24
+ // 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_CTX whirlpool;
+ sha512_ctx sha2;
+
+ WHIRLPOOL_init (&whirlpool);
+ sha512_begin (&sha2);
+
+ WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET * 8, &whirlpool);
+ sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET, &sha2);
+
+ WHIRLPOOL_add (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)) * 8, &whirlpool);
+ sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2);
+
+ WHIRLPOOL_add (bootLoaderBuf + TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)) * 8, &whirlpool);
+ sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)), &sha2);
+
+ WHIRLPOOL_add (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS) * 8, &whirlpool);
+ sha512_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2);
+
+ WHIRLPOOL_finalize (&whirlpool, fingerprint);
+ sha512_end (&fingerprint [WHIRLPOOL_DIGESTSIZE], &sha2);
+}
+#endif
+
#else // TC_WINDOWS_BOOT
int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
diff --git a/src/Common/Volumes.h b/src/Common/Volumes.h index 76a14966..016d989f 100644 --- a/src/Common/Volumes.h +++ b/src/Common/Volumes.h @@ -129,8 +129,11 @@ UINT64_STRUCT GetHeaderField64 (byte *header, int offset); #ifdef TC_WINDOWS_BOOT
int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo);
#else
int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int pkcs5_prf, int pim, BOOL truecryptMode, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo);
+#ifdef _WIN32
+void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderSize, byte* fingerprint);
+#endif
#endif
#if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)
int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *encryptedHeader, int ea, int mode, Password *password, int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode);
diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c index d3bc2dc2..4b9117eb 100644 --- a/src/Driver/DriveFilter.c +++ b/src/Driver/DriveFilter.c @@ -34,8 +34,9 @@ static KMUTEX MountMutex; static volatile BOOL BootDriveFound = FALSE;
static DriveFilterExtension *BootDriveFilterExtension = NULL;
static LARGE_INTEGER BootDriveLength;
+static byte BootLoaderFingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
static BOOL CrashDumpEnabled = FALSE;
static BOOL HibernationEnabled = FALSE;
@@ -120,8 +121,11 @@ NTSTATUS LoadBootArguments () if (CacheBootPassword && BootArgs.BootPassword.Length > 0)
AddPasswordToCache (&BootArgs.BootPassword);
+ // clear fingerprint
+ burn (BootLoaderFingerprint, sizeof (BootLoaderFingerprint));
+
status = STATUS_SUCCESS;
}
}
@@ -215,8 +219,79 @@ static void DismountDrive (DriveFilterExtension *Extension, BOOL stopIoQueue) Extension->DriveMounted = FALSE;
}
+static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* ioBuffer /* ioBuffer must be at least 512 bytes long */)
+{
+ NTSTATUS status;
+ LARGE_INTEGER offset;
+ WHIRLPOOL_CTX whirlpool;
+ sha512_ctx sha2;
+ ULONG bytesToRead, remainingBytes, bootloaderTotalSize = TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE;
+
+ // clear fingerprint
+ burn (BootLoaderFingerprint, sizeof (BootLoaderFingerprint));
+
+ // compute Whirlpool+SHA512 fingerprint of bootloader including MBR
+ // we skip user configuration fields:
+ // TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET = 402
+ // => TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE = 4
+ // TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = 406
+ // => TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH = 24
+ // 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
+ offset.QuadPart = 0;
+
+ status = TCReadDevice (LowerDeviceObject, ioBuffer, offset, TC_SECTOR_SIZE_BIOS);
+ if (NT_SUCCESS (status))
+ {
+ WHIRLPOOL_add (ioBuffer, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET * 8, &whirlpool);
+ WHIRLPOOL_add (ioBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)) * 8, &whirlpool);
+ WHIRLPOOL_add (ioBuffer + TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)) * 8, &whirlpool);
+
+ sha512_hash (ioBuffer, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET, &sha2);
+ sha512_hash (ioBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2);
+ sha512_hash (ioBuffer + TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)), &sha2);
+
+ // we has the reste of the bootloader, 512 bytes at a time
+ offset.QuadPart = TC_SECTOR_SIZE_BIOS;
+ remainingBytes = bootloaderTotalSize - TC_SECTOR_SIZE_BIOS;
+
+ while (NT_SUCCESS (status) && (remainingBytes > 0))
+ {
+ bytesToRead = (remainingBytes >= TC_SECTOR_SIZE_BIOS)? TC_SECTOR_SIZE_BIOS : remainingBytes;
+ status = TCReadDevice (LowerDeviceObject, ioBuffer, offset, bytesToRead);
+ if (NT_SUCCESS (status))
+ {
+ remainingBytes -= bytesToRead;
+ offset.QuadPart += bytesToRead;
+ WHIRLPOOL_add (ioBuffer, bytesToRead * 8, &whirlpool);
+ sha512_hash (ioBuffer, bytesToRead, &sha2);
+ }
+ else
+ {
+ Dump ("TCReadDevice error %x during ComputeBootLoaderFingerprint call\n", status);
+ break;
+ }
+ }
+
+ if (NT_SUCCESS (status))
+ {
+ WHIRLPOOL_finalize (&whirlpool, BootLoaderFingerprint);
+ sha512_end (&BootLoaderFingerprint [WHIRLPOOL_DIGESTSIZE], &sha2);
+ }
+ }
+ else
+ {
+ Dump ("TCReadDevice error %x during ComputeBootLoaderFingerprint call\n", status);
+ }
+}
+
static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, uint32 *headerSaltCrc32)
{
BOOL hiddenVolume = (BootArgs.HiddenSystemPartitionStart != 0);
@@ -301,8 +376,11 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, {
// Header decrypted
status = STATUS_SUCCESS;
Dump ("Header decrypted\n");
+
+ // calculate Fingerprint
+ ComputeBootLoaderFingerprint (Extension->LowerDeviceObject, header);
if (Extension->Queue.CryptoInfo->hiddenVolume)
{
int64 hiddenPartitionOffset = BootArgs.HiddenSystemPartitionStart;
@@ -806,8 +884,9 @@ void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) if (ReadVolumeHeader (!BootDriveFilterExtension->HiddenSystem, header, &request->VolumePassword, request->pkcs5_prf, request->pim, FALSE, NULL, BootDriveFilterExtension->HeaderCryptoInfo) == 0)
{
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;
@@ -1680,8 +1759,26 @@ void GetBootLoaderVersion (PIRP irp, PIO_STACK_LOCATION irpSp) }
}
}
+void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp)
+{
+ if (ValidateIOBufferSize (irp, sizeof (BootLoaderFingerprintRequest), ValidateOutput))
+ {
+ if (BootArgsValid)
+ {
+ BootLoaderFingerprintRequest *bootLoaderFingerprint = (BootLoaderFingerprintRequest *) irp->AssociatedIrp.SystemBuffer;
+ memcpy (bootLoaderFingerprint->Fingerprint, BootLoaderFingerprint, sizeof (BootLoaderFingerprint));
+ irp->IoStatus.Information = sizeof (BootLoaderFingerprintRequest);
+ irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ irp->IoStatus.Information = 0;
+ }
+ }
+}
void GetBootEncryptionAlgorithmName (PIRP irp, PIO_STACK_LOCATION irpSp)
{
if (ValidateIOBufferSize (irp, sizeof (GetBootEncryptionAlgorithmNameRequest), ValidateOutput))
diff --git a/src/Driver/DriveFilter.h b/src/Driver/DriveFilter.h index 96ec00ef..7ae0d47d 100644 --- a/src/Driver/DriveFilter.h +++ b/src/Driver/DriveFilter.h @@ -58,8 +58,9 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp); void GetBootDriveVolumeProperties (PIRP irp, PIO_STACK_LOCATION irpSp);
void GetBootEncryptionAlgorithmName (PIRP irp, PIO_STACK_LOCATION irpSp);
void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp);
void GetBootLoaderVersion (PIRP irp, PIO_STACK_LOCATION irpSp);
+void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp);
NTSTATUS GetSetupResult ();
DriveFilterExtension *GetBootDriveFilterExtension ();
CRYPTO_INFO *GetSystemDriveCryptoInfo ();
BOOL IsBootDriveMounted ();
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index a9f15b78..a99ac6d4 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -1028,9 +1028,9 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex UNICODE_STRING FullFileName;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER offset;
byte readBuffer [TC_SECTOR_SIZE_BIOS];
-
+
if (!ValidateIOBufferSize (Irp, sizeof (GetSystemDriveConfigurationRequest), ValidateInputOutput))
break;
EnsureNullTerminatedString (request->DevicePath, sizeof (request->DevicePath));
@@ -1492,8 +1492,12 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex case TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER:
ReopenBootVolumeHeader (Irp, irpSp);
break;
+ case VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT:
+ GetBootLoaderFingerprint (Irp, irpSp);
+ break;
+
case TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME:
GetBootEncryptionAlgorithmName (Irp, irpSp);
break;
diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 66941b15..bebb18d7 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -5768,8 +5768,9 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa ExtractCommandLine (hwndDlg, (char *) lParam);
try
{
+ BootEncObj->SetParentWindow (hwndDlg);
BootEncStatus = BootEncObj->GetStatus();
RecentBootEncStatus = BootEncStatus;
}
catch (...)
@@ -5807,15 +5808,21 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa try
{
if (IsHiddenOSRunning())
{
- if (BootEncObj->GetInstalledBootLoaderVersion() > VERSION_NUM)
+ if (BootEncObj->GetInstalledBootLoaderVersion() != VERSION_NUM)
Warning ("UPDATE_TC_IN_HIDDEN_OS_TOO", hwndDlg);
+ if (!BootEncObj->CheckBootloaderFingerprint ())
+ Warning ("BOOT_LOADER_FINGERPRINT_CHECK_FAILED", hwndDlg);
}
- else if (SysDriveOrPartitionFullyEncrypted (TRUE)
- && BootEncObj->GetInstalledBootLoaderVersion() != VERSION_NUM)
+ else if (SysDriveOrPartitionFullyEncrypted (TRUE))
{
- Warning ("BOOT_LOADER_VERSION_DIFFERENT_FROM_DRIVER_VERSION", hwndDlg);
+ if (BootEncObj->GetInstalledBootLoaderVersion() != VERSION_NUM)
+ {
+ Warning ("BOOT_LOADER_VERSION_DIFFERENT_FROM_DRIVER_VERSION", hwndDlg);
+ }
+ if (!BootEncObj->CheckBootloaderFingerprint ())
+ Warning ("BOOT_LOADER_FINGERPRINT_CHECK_FAILED", hwndDlg);
}
}
catch (...) { }
|