From d3e7ed96f3685d83dcc39a18574be1dd2cc8f2f6 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 12 Jan 2019 01:24:25 +0100 Subject: Windows: Implement feature that enables clearing of encryption keys when a new device is inserted. Better implementation for update of EFI bootloader without usage of drive letters (this can fix random issues encountered during Windows upgrade). --- src/Common/Apidrvr.h | 1 + src/Common/BootEncryption.cpp | 74 ++++++++++++++----------------------------- src/Common/BootEncryption.h | 8 ++--- src/Common/Language.xml | 2 ++ 4 files changed, 29 insertions(+), 56 deletions(-) (limited to 'src/Common') diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index 2d996d2c..0298e204 100644 --- a/src/Common/Apidrvr.h +++ b/src/Common/Apidrvr.h @@ -416,5 +416,6 @@ typedef struct #define VC_DRIVER_CONFIG_ALLOW_NONSYS_TRIM 0x80 #define VC_DRIVER_CONFIG_BLOCK_SYS_TRIM 0x100 #define VC_DRIVER_CONFIG_ALLOW_WINDOWS_DEFRAG 0x200 +#define VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION 0x400 #endif /* _WIN32 */ diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index 4992e086..364f0869 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -994,10 +994,16 @@ namespace VeraCrypt Device::Device (wstring path, bool readOnly) { - FileOpen = false; - Elevated = false; + wstring effectivePath; + FileOpen = false; + Elevated = false; + + if (path.find(L"\\\\?\\") == 0) + effectivePath = path; + else + effectivePath = wstring (L"\\\\.\\") + path; - Handle = CreateFile ((wstring (L"\\\\.\\") + path).c_str(), + Handle = CreateFile (effectivePath.c_str(), readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL); @@ -1978,8 +1984,7 @@ namespace VeraCrypt } else { - finally_do ({ EfiBootInst.DismountBootPartition(); }); - EfiBootInst.MountBootPartition(0); + EfiBootInst.PrepareBootPartition(); if (! (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)) pim = -1; @@ -2492,8 +2497,6 @@ namespace VeraCrypt } EfiBoot::EfiBoot() { - ZeroMemory(EfiBootPartPath, sizeof(EfiBootPartPath)); - ZeroMemory (BootVolumePath, sizeof (BootVolumePath)); ZeroMemory (&sdn, sizeof (sdn)); ZeroMemory (&partInfo, sizeof (partInfo)); m_bMounted = false; @@ -2521,34 +2524,21 @@ namespace VeraCrypt } PUNICODE_STRING pStr = (PUNICODE_STRING) tempBuf; - memcpy (BootVolumePath, pStr->Buffer, min (pStr->Length, (sizeof (BootVolumePath) - 2))); - bBootVolumePathSelected = true; - } + BootVolumePath = pStr->Buffer; + + EfiBootPartPath = L"\\\\?"; + EfiBootPartPath += &pStr->Buffer[7]; - void EfiBoot::SelectBootVolume(WCHAR* bootVolumePath) { - wstring str; - str = bootVolumePath; - memcpy (BootVolumePath, &str[0], min (str.length() * 2, (sizeof (BootVolumePath) - 2))); bBootVolumePathSelected = true; } - void EfiBoot::MountBootPartition(WCHAR letter) { + void EfiBoot::PrepareBootPartition() { if (!bBootVolumePathSelected) { SelectBootVolumeESP(); } - - if (!letter) { - if (!GetFreeDriveLetter(&EfiBootPartPath[0])) { - throw ErrorException(L"No free letter to mount EFI boot partition", SRC_POS); - } - } else { - EfiBootPartPath[0] = letter; - } - EfiBootPartPath[1] = ':'; - EfiBootPartPath[2] = 0; - throw_sys_if(!DefineDosDevice(DDD_RAW_TARGET_PATH, EfiBootPartPath, BootVolumePath)); - - Device dev(EfiBootPartPath, TRUE); + std::wstring devicePath = L"\\\\?\\GLOBALROOT"; + devicePath += BootVolumePath; + Device dev(devicePath.c_str(), TRUE); try { @@ -2556,7 +2546,6 @@ namespace VeraCrypt } catch (...) { - DefineDosDevice(DDD_REMOVE_DEFINITION, EfiBootPartPath, NULL); throw; } @@ -2566,20 +2555,9 @@ namespace VeraCrypt dev.Close(); if (!bSuccess) { - DefineDosDevice(DDD_REMOVE_DEFINITION, EfiBootPartPath, NULL); SetLastError (dwLastError); throw SystemException(SRC_POS); - } - - m_bMounted = true; - } - - void EfiBoot::DismountBootPartition() { - if (m_bMounted) - { - DefineDosDevice(DDD_REMOVE_DEFINITION, EfiBootPartPath, NULL); - m_bMounted = false; - } + } } bool EfiBoot::IsEfiBoot() { @@ -3085,8 +3063,7 @@ namespace VeraCrypt if (!DcsInfoImg) throw ErrorException(L"Out of resource DcsInfo", SRC_POS); - finally_do ({ EfiBootInst.DismountBootPartition(); }); - EfiBootInst.MountBootPartition(0); + EfiBootInst.PrepareBootPartition(); try { @@ -4110,9 +4087,7 @@ namespace VeraCrypt const char* g_szMsBootString = "bootmgfw.pdb"; bool bModifiedMsBoot = true; - finally_do ({ EfiBootInst.DismountBootPartition(); }); - - EfiBootInst.MountBootPartition(0); + EfiBootInst.PrepareBootPartition(); EfiBootInst.GetFileSize(szStdMsBootloader, loaderSize); bootLoaderBuf.resize ((size_t) loaderSize); @@ -4233,9 +4208,7 @@ namespace VeraCrypt } } - finally_do ({ EfiBootInst.DismountBootPartition(); }); - - EfiBootInst.MountBootPartition(0); + EfiBootInst.PrepareBootPartition(); EfiBootInst.DeleteStartExec(); EfiBootInst.DeleteStartExec(0xDC5B, L"Driver"); // remove DcsBml boot driver it was installed @@ -4735,8 +4708,7 @@ namespace VeraCrypt } else { - finally_do ({ EfiBootInst.DismountBootPartition(); }); - EfiBootInst.MountBootPartition(0); + EfiBootInst.PrepareBootPartition(); memcpy (pSdn, EfiBootInst.GetStorageDeviceNumber(), sizeof (STORAGE_DEVICE_NUMBER)); } } diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index 58cdd2e0..ea0e728c 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -199,8 +199,7 @@ namespace VeraCrypt public: EfiBoot(); - void MountBootPartition(WCHAR letter); - void DismountBootPartition(); + void PrepareBootPartition(); bool IsEfiBoot(); void DeleteStartExec(uint16 statrtOrderNum = 0xDC5B, wchar_t* type = NULL); @@ -219,17 +218,16 @@ namespace VeraCrypt BOOL WriteConfig (const wchar_t* name, bool preserveUserConfig, int pim, int hashAlgo, const char* passPromptMsg, HWND hwndDlg); BOOL DelDir(const wchar_t* name); void SelectBootVolumeESP(); - void SelectBootVolume(WCHAR* bootVolumePath); PSTORAGE_DEVICE_NUMBER GetStorageDeviceNumber () { return &sdn;} protected: bool m_bMounted; - WCHAR EfiBootPartPath[3]; + std::wstring EfiBootPartPath; STORAGE_DEVICE_NUMBER sdn; PARTITION_INFORMATION_EX partInfo; WCHAR tempBuf[1024]; bool bBootVolumePathSelected; - WCHAR BootVolumePath[MAX_PATH]; + std::wstring BootVolumePath; }; class BootEncryption diff --git a/src/Common/Language.xml b/src/Common/Language.xml index 5fc4ce7d..b2700e6d 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1429,6 +1429,8 @@ WARNING: Defragmenting non-system partitions/drives may leak metadata about their content or cause issues with hidden volumes they may contain.\n\nContinue? Virtual Device The selected mounted volume is not associated with its drive letter in Windows and so it can not be opened in Windows Explorer. + Clear encryption keys from memory if a new device is inserted + IMPORTANT NOTES:\n - Please keep in mind that this option will not persist after a shutdown/reboot so you will need to select it again next time the machine is started.\n\n - With this option enabled and after a new device is connected, the machine will freeze and it will eventually crash with a BSOD since Windows can not access the encrypted disk after its keys are cleared from memory.\n -- cgit v1.2.3