From 202caea3a983198231e4ebde458817355e6629fb Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Tue, 15 Jan 2019 15:03:08 +0100 Subject: Windows: enhancements to EFI system encryption, like handling of Multi-Boot and better compatibility with Windows Upgrade process. --- src/Common/BootEncryption.cpp | 109 +++++++++++++++++++++++++++--------------- src/Common/BootEncryption.h | 7 ++- src/Common/Language.xml | 1 + src/Common/Tcdefs.h | 2 +- 4 files changed, 79 insertions(+), 40 deletions(-) (limited to 'src/Common') diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index 9f065615..2bf7991c 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -2800,7 +2800,7 @@ namespace VeraCrypt throw_sys_if (!::CopyFileW (path.c_str(), targetPath.c_str(), FALSE)); } - BOOL EfiBoot::RenameFile(const wchar_t* name, wchar_t* nameNew, BOOL bForce) { + BOOL EfiBoot::RenameFile(const wchar_t* name, const wchar_t* nameNew, BOOL bForce) { wstring path = EfiBootPartPath; path += name; wstring pathNew = EfiBootPartPath; @@ -3069,12 +3069,14 @@ namespace VeraCrypt { // Save modules bool bAlreadyExist; + const char* g_szMsBootString = "bootmgfw.pdb"; + unsigned __int64 loaderSize = 0; + const wchar_t * szStdEfiBootloader = Is64BitOs()? L"\\EFI\\Boot\\bootx64.efi": L"\\EFI\\Boot\\bootia32.efi"; + const wchar_t * szBackupEfiBootloader = Is64BitOs()? L"\\EFI\\Boot\\original_bootx64.vc_backup": L"\\EFI\\Boot\\original_bootia32.vc_backup"; if (preserveUserConfig) { bool bModifiedMsBoot = true; - const char* g_szMsBootString = "bootmgfw.pdb"; - unsigned __int64 loaderSize = 0; EfiBootInst.GetFileSize(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", loaderSize); if (EfiBootInst.FileExists (L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc")) @@ -3150,12 +3152,30 @@ namespace VeraCrypt // if yes, replace it with our bootloader after it was copied to bootmgfw_ms.vc if (!bModifiedMsBoot) EfiBootInst.CopyFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); + + if (EfiBootInst.FileExists (szStdEfiBootloader)) + { + // check if standard bootloader under EFI\Boot has been set to Microsoft version + // if yes, replace it with our bootloader + EfiBootInst.GetFileSize(szStdEfiBootloader, loaderSize); + if (loaderSize > 32768) + { + std::vector bootLoaderBuf ((size_t) loaderSize); + + EfiBootInst.ReadFile(szStdEfiBootloader, &bootLoaderBuf[0], (DWORD) loaderSize); + + // look for bootmgfw.efi identifiant string + if (BufferHasPattern (bootLoaderBuf.data (), (size_t) loaderSize, g_szMsBootString, strlen (g_szMsBootString))) + { + EfiBootInst.RenameFile (szStdEfiBootloader, szBackupEfiBootloader, TRUE); + EfiBootInst.CopyFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", szStdEfiBootloader); + } + } + } return; } } - const wchar_t * szStdEfiBootloader = Is64BitOs()? L"\\EFI\\Boot\\bootx64.efi": L"\\EFI\\Boot\\bootia32.efi"; - EfiBootInst.MkDir(L"\\EFI\\VeraCrypt", bAlreadyExist); EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsBoot.efi", dcsBootImg, sizeDcsBoot); EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsInt.dcs", dcsIntImg, sizeDcsInt); @@ -3170,7 +3190,26 @@ namespace VeraCrypt EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi"); if (EfiBootInst.FileExists (szStdEfiBootloader)) - EfiBootInst.SaveFile(szStdEfiBootloader, dcsBootImg, sizeDcsBoot); + { + // check if standard bootloader under EFI\Boot is Microsoft one or if it is ours + // if both cases, replace it with our bootloader otherwise do nothing + EfiBootInst.GetFileSize(szStdEfiBootloader, loaderSize); + std::vector bootLoaderBuf ((size_t) loaderSize); + EfiBootInst.ReadFile(szStdEfiBootloader, &bootLoaderBuf[0], (DWORD) loaderSize); + + // look for bootmgfw.efi or VeraCrypt identifiant strings + if ( ((loaderSize > 32768) && BufferHasPattern (bootLoaderBuf.data (), (size_t) loaderSize, g_szMsBootString, strlen (g_szMsBootString))) + ) + { + EfiBootInst.RenameFile (szStdEfiBootloader, szBackupEfiBootloader, TRUE); + EfiBootInst.SaveFile(szStdEfiBootloader, dcsBootImg, sizeDcsBoot); + } + if ( ((loaderSize <= 32768) && BufferHasPattern (bootLoaderBuf.data (), (size_t) loaderSize, _T(TC_APP_NAME), strlen (TC_APP_NAME) * 2)) + ) + { + EfiBootInst.SaveFile(szStdEfiBootloader, dcsBootImg, sizeDcsBoot); + } + } EfiBootInst.SaveFile(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", dcsBootImg, sizeDcsBoot); // move configuration file from old location (if it exists) to new location // we don't force the move operation if the new location already exists @@ -4080,8 +4119,6 @@ namespace VeraCrypt } unsigned __int64 loaderSize = 0; std::vector bootLoaderBuf; - const wchar_t * szStdEfiBootloader = Is64BitOs()? L"\\EFI\\Boot\\bootx64.efi": L"\\EFI\\Boot\\bootia32.efi"; - const wchar_t * szBackupEfiBootloader = Is64BitOs()? L"\\EFI\\Boot\\original_bootx64.vc_backup": L"\\EFI\\Boot\\original_bootia32.vc_backup"; const wchar_t * szStdMsBootloader = L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"; const wchar_t * szBackupMsBootloader = L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc"; const char* g_szMsBootString = "bootmgfw.pdb"; @@ -4134,36 +4171,7 @@ namespace VeraCrypt } EfiBootInst.CopyFile (szStdMsBootloader, szBackupMsBootloader); - - if (EfiBootInst.FileExists (szStdEfiBootloader)) - { - EfiBootInst.GetFileSize (szStdEfiBootloader, loaderSize); - - bootLoaderBuf.resize ((size_t) loaderSize); - - EfiBootInst.ReadFile (szStdEfiBootloader, &bootLoaderBuf[0], (DWORD) loaderSize); - - // Prevent VeraCrypt EFI loader from being backed up - if (BufferHasPattern (bootLoaderBuf.data (), (size_t) loaderSize, _T(TC_APP_NAME), wcslen (_T(TC_APP_NAME)) * 2)) - { - if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED", ParentWindow) == IDNO) - throw UserAbort (SRC_POS); - - // check if backup exists already and if it has bootmgfw signature - if (EfiBootInst.FileExists (szBackupEfiBootloader)) - { - // perform the backup on disk using this file - EfiBootInst.CopyFile (szBackupEfiBootloader, GetSystemLoaderBackupPath().c_str()); - } - - return; - } - - EfiBootInst.CopyFile (szStdEfiBootloader, GetSystemLoaderBackupPath().c_str()); - EfiBootInst.CopyFile (szStdEfiBootloader, szBackupEfiBootloader); - } - else - EfiBootInst.CopyFile (szStdMsBootloader, GetSystemLoaderBackupPath().c_str()); + EfiBootInst.CopyFile (szStdMsBootloader, GetSystemLoaderBackupPath().c_str()); } else @@ -4683,6 +4691,21 @@ namespace VeraCrypt #endif } + void BootEncryption::SetServiceConfigurationFlag (uint32 flag, bool state) + { + DWORD configMap = ReadDriverConfigurationFlags(); + + if (state) + configMap |= flag; + else + configMap &= ~flag; +#ifdef SETUP + WriteLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, TC_SYSTEM_FAVORITES_SERVICE_NAME L"Config", configMap); +#else + WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Services\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, TC_SYSTEM_FAVORITES_SERVICE_NAME L"Config", configMap); +#endif + } + #ifndef SETUP void BootEncryption::RegisterSystemFavoritesService (BOOL registerService) @@ -5359,6 +5382,16 @@ namespace VeraCrypt return configMap; } + uint32 BootEncryption::ReadServiceConfigurationFlags () + { + DWORD configMap; + + if (!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, TC_SYSTEM_FAVORITES_SERVICE_NAME L"Config", &configMap)) + configMap = 0; + + return configMap; + } + void BootEncryption::WriteBootDriveSector (uint64 offset, byte *data) { WriteBootDriveSectorRequest request; diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index ea0e728c..0b5fe4f0 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -210,7 +210,7 @@ namespace VeraCrypt void CopyFile(const wchar_t* name, const wchar_t* targetName); bool FileExists(const wchar_t* name); - BOOL RenameFile(const wchar_t* name, wchar_t* nameNew, BOOL bForce); + BOOL RenameFile(const wchar_t* name, const wchar_t* nameNew, BOOL bForce); BOOL DelFile(const wchar_t* name); BOOL MkDir(const wchar_t* name, bool& bAlreadyExists); BOOL ReadConfig (const wchar_t* name, EfiBootConf& conf); @@ -280,6 +280,7 @@ namespace VeraCrypt void ProbeRealSystemDriveSize (); bool ReadBootSectorConfig (byte *config, size_t bufLength, byte *userConfig = nullptr, string *customUserMessage = nullptr, uint16 *bootLoaderVersion = nullptr); uint32 ReadDriverConfigurationFlags (); + uint32 ReadServiceConfigurationFlags (); void RegisterBootDriver (bool hiddenSystem); void RegisterFilterDriver (bool registerDriver, FilterType filterType); void RegisterSystemFavoritesService (BOOL registerService); @@ -290,6 +291,7 @@ namespace VeraCrypt void InitialSecurityChecksForHiddenOS (); void RestrictPagingFilesToSystemPartition (); void SetDriverConfigurationFlag (uint32 flag, bool state); + void SetServiceConfigurationFlag (uint32 flag, bool state); void SetDriverServiceStartType (DWORD startType); void SetHiddenOSCreationPhase (unsigned int newPhase); void StartDecryption (BOOL discardUnreadableEncryptedSectors); @@ -356,6 +358,9 @@ namespace VeraCrypt #define TC_SYSTEM_FAVORITES_SERVICE_NAME _T(TC_APP_NAME) L"SystemFavorites" #define TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP L"Event Log" #define TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION L"/systemFavoritesService" +#define VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT L"/SkipMount" + +#define VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER 0x1 #define VC_WINDOWS_UPGRADE_POSTOOBE_CMDLINE_OPTION L"/PostOOBE" diff --git a/src/Common/Language.xml b/src/Common/Language.xml index b2700e6d..1921b1aa 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1431,6 +1431,7 @@ 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 + Starting diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h index 5915e401..8f201448 100644 --- a/src/Common/Tcdefs.h +++ b/src/Common/Tcdefs.h @@ -61,7 +61,7 @@ extern unsigned short _rotl16(unsigned short value, unsigned char shift); #define VERSION_NUM 0x0124 // Release date -#define TC_STR_RELEASE_DATE L"January 12, 2019" +#define TC_STR_RELEASE_DATE L"January 15, 2019" #define TC_RELEASE_DATE_YEAR 2019 #define TC_RELEASE_DATE_MONTH 1 -- cgit v1.2.3