diff --git a/doc/html/en/System Encryption.html b/doc/html/en/System Encryption.html
index ae74cab9..e13b7d81 100644
--- a/doc/html/en/System Encryption.html
+++ b/doc/html/en/System Encryption.html
@@ -73,6 +73,7 @@ Thus, when setting or entering your password, it's crucial to type it manually u
Note: By default, Windows 7 and later boot from a special small partition. The partition contains files that are required to boot the system. Windows allows only applications that have administrator privileges to write to the partition (when the system is
running). In EFI boot mode, which is the default on modern PCs, VeraCrypt can not encrypt this partition since it must remain unencrypted so that the BIOS can load the EFI bootloader from it. This in turn implies that in EFI boot mode, VeraCrypt offers only to encrypt the system partition where Windows is installed (the user can later manually encrypt other data partitions using VeraCrypt).
In MBR legacy boot mode, VeraCrypt encrypts the partition only if you choose to encrypt the whole system drive (as opposed to choosing to encrypt only the partition where Windows is installed).
+In EFI boot mode with Secure Boot enabled, VeraCrypt selects the installed Microsoft UEFI CA-signed bootloader set during install, repair, upgrade, or Windows PostOOBE repair. If you manually change firmware Secure Boot db entries, run VeraCrypt repair or reinstall to refresh the installed bootloader set.
Next Section >>
diff --git a/doc/html/en/VeraCrypt Rescue Disk.html b/doc/html/en/VeraCrypt Rescue Disk.html
index 54aebfdf..86ad5d9c 100644
--- a/doc/html/en/VeraCrypt Rescue Disk.html
+++ b/doc/html/en/VeraCrypt Rescue Disk.html
@@ -93,6 +93,8 @@ To boot a VeraCrypt Rescue Disk, insert it into a USB port or your CD/DVD drive
configuration screen appears, restart (reset) the computer again and start pressing F2 or Delete repeatedly as soon as you restart (reset) the computer. When a BIOS configuration screen appears, configure your BIOS to boot from the USB drive and CD/DVD drive first (for
information on how to do so, please refer to the documentation for your BIOS/motherboard or contact your computer vendor's technical support team for assistance). Then restart your computer. The VeraCrypt Rescue Disk screen should appear now. Note: In the
case of MBR legacy boot mode, you can select 'Repair Options' on the VeraCrypt Rescue Disk screen by pressing F8 on your keyboard.
+In EFI boot mode with Secure Boot enabled, the VeraCrypt Rescue Disk uses the Microsoft UEFI CA-signed bootloader set selected from the computer's current Secure Boot db state when the Rescue Disk is created. If firmware or Secure Boot db entries are later changed, create a new VeraCrypt Rescue Disk. A Rescue Disk created on a computer that trusts only one Microsoft UEFI CA generation may not Secure-Boot on a different computer that trusts only the other generation.
+Installed EFI bootloader files are refreshed only during VeraCrypt install, repair, upgrade, or Windows PostOOBE repair paths. If you manually change firmware Secure Boot db entries, run VeraCrypt repair or reinstall to refresh the installed bootloader set.
If your VeraCrypt Rescue Disk is damaged, you can create a new one by selecting
System > Create Rescue Disk. To find out whether your VeraCrypt Rescue Disk is damaged, insert it into a USB port (or into your CD/DVD drive in case of MBR legacy boot mode) and select
System > Verify Rescue Disk.
diff --git a/src/Common/BaseCom.cpp b/src/Common/BaseCom.cpp
index 2319576b..265611fd 100644
--- a/src/Common/BaseCom.cpp
+++ b/src/Common/BaseCom.cpp
@@ -437,6 +437,33 @@ DWORD BaseCom::GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKe
return ERROR_SUCCESS;
}
+DWORD BaseCom::GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported)
+{
+ if (!pMicrosoft2023UefiCAsSupported)
+ return ERROR_INVALID_PARAMETER;
+
+ try
+ {
+ BootEncryption bootEnc (NULL);
+ bootEnc.GetEfiBootLoaderSigningSupport (pMicrosoft2023UefiCAsSupported);
+ }
+ catch (SystemException &)
+ {
+ return GetLastError();
+ }
+ catch (Exception &e)
+ {
+ e.Show (NULL);
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+ catch (...)
+ {
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+
+ return ERROR_SUCCESS;
+}
+
DWORD BaseCom::WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMessage, int pim, int hashAlg)
{
if (!customUserMessage)
diff --git a/src/Common/BaseCom.h b/src/Common/BaseCom.h
index c083e663..c947953a 100644
--- a/src/Common/BaseCom.h
+++ b/src/Common/BaseCom.h
@@ -119,6 +119,7 @@ public:
static DWORD WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMessage, int pim, int hashAlg);
static DWORD UpdateSetupConfigFile (BOOL bForInstall);
static DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
+ static DWORD GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported);
static DWORD NotifyService (DWORD dwNotifyCode);
static DWORD FastFileResize (BSTR filePath, __int64 fileSize);
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index f7a01cf7..6a688a5c 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -631,6 +631,18 @@ namespace VeraCrypt
}
}
+ static void GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported)
+ {
+ Elevate();
+
+ DWORD result = ElevatedComInstance->GetEfiBootLoaderSigningSupport (pMicrosoft2023UefiCAsSupported);
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
static void WriteEfiBootSectorUserConfig (uint8 userConfig, const string &customUserMessage, int pim, int hashAlg)
{
Elevate();
@@ -755,6 +767,7 @@ namespace VeraCrypt
static void WriteEfiBootSectorUserConfig (uint8 userConfig, const string &customUserMessage, int pim, int hashAlg) { throw ParameterIncorrect (SRC_POS); }
static void UpdateSetupConfigFile (bool bForInstall) { throw ParameterIncorrect (SRC_POS); }
static void GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded) { throw ParameterIncorrect (SRC_POS); }
+ static void GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported) { throw ParameterIncorrect (SRC_POS); }
static void RegisterSystemFavoritesService(BOOL registerService) { throw ParameterIncorrect(SRC_POS); }
static BOOL IsPagingFileActive(BOOL checkNonWindowsPartitionsOnly) { throw ParameterIncorrect(SRC_POS); }
static void WriteLocalMachineRegistryDwordValue(wchar_t* keyPath, wchar_t* valueName, DWORD value) { throw ParameterIncorrect(SRC_POS); }
@@ -2504,6 +2517,530 @@ namespace VeraCrypt
}
static const wchar_t* EfiVarGuid = L"{8BE4DF61-93CA-11D2-AA0D-00E098032B8C}";
+ static const wchar_t* EfiImageSecurityDatabaseGuid = L"{D719B2CB-3D3A-4596-A3BC-DAD00E67656F}";
+
+ struct EfiBootLoaderResourceSet
+ {
+ int DcsBoot;
+ int DcsInt;
+ int DcsCfg;
+ int LegacySpeaker;
+ int DcsRescue;
+ int DcsInfo;
+ };
+
+ struct EfiBootLoaderImages
+ {
+ uint8 *DcsBoot;
+ DWORD SizeDcsBoot;
+ uint8 *DcsInt;
+ DWORD SizeDcsInt;
+ uint8 *DcsCfg;
+ DWORD SizeDcsCfg;
+ uint8 *LegacySpeaker;
+ DWORD SizeLegacySpeaker;
+ uint8 *DcsRescue;
+ DWORD SizeDcsRescue;
+ uint8 *DcsInfo;
+ DWORD SizeDcsInfo;
+ DWORD ResourceSet;
+ const wchar_t *SelectionReason;
+ DWORD FirmwareDbError;
+ };
+
+ struct EfiBootLoaderResourceSelection
+ {
+ const EfiBootLoaderResourceSet *Resources;
+ DWORD ResourceSet;
+ const wchar_t *Reason;
+ DWORD FirmwareDbError;
+ };
+
+ static const EfiBootLoaderResourceSet EfiBootLoaderResources2011 =
+ {
+ IDR_EFI_DCSBOOT_2011,
+ IDR_EFI_DCSINT_2011,
+ IDR_EFI_DCSCFG_2011,
+ IDR_EFI_LEGACYSPEAKER_2011,
+ IDR_EFI_DCSRE_2011,
+ IDR_EFI_DCSINFO_2011
+ };
+
+ static const EfiBootLoaderResourceSet EfiBootLoaderResources2023 =
+ {
+ IDR_EFI_DCSBOOT_2023,
+ IDR_EFI_DCSINT_2023,
+ IDR_EFI_DCSCFG_2023,
+ IDR_EFI_LEGACYSPEAKER_2023,
+ IDR_EFI_DCSRE_2023,
+ IDR_EFI_DCSINFO_2023
+ };
+
+ static const wchar_t *EfiBootLoaderDiagnosticsRegistryKey = L"Software\\VeraCrypt\\Diagnostics\\EfiBootLoader";
+
+ static bool ReadFirmwareEnvironmentVariableBuffer (const wchar_t* name, const wchar_t* guid, std::vector& value, DWORD* pLastError = NULL)
+ {
+ bool bRet = false;
+ DWORD dwError = ERROR_SUCCESS;
+ BOOL bPrivilegesSet = IsPrivilegeEnabled (SE_SYSTEM_ENVIRONMENT_NAME);
+ BOOL bPrivilegeEnabled = FALSE;
+ const DWORD maxBufferSize = 16 * 1024 * 1024;
+ DWORD bufferSize = 16384;
+
+ value.clear ();
+ if (pLastError)
+ *pLastError = ERROR_SUCCESS;
+
+ if (!bPrivilegesSet)
+ {
+ if (!SetPrivilege (SE_SYSTEM_ENVIRONMENT_NAME, TRUE))
+ {
+ dwError = GetLastError ();
+ if (dwError == ERROR_SUCCESS)
+ dwError = ERROR_PRIVILEGE_NOT_HELD;
+ if (pLastError)
+ *pLastError = dwError;
+ SetLastError (dwError);
+ return false;
+ }
+
+ bPrivilegeEnabled = TRUE;
+ }
+
+ try
+ {
+ while (bufferSize <= maxBufferSize)
+ {
+ value.resize (bufferSize);
+
+ SetLastError (ERROR_SUCCESS);
+ DWORD dwLen = GetFirmwareEnvironmentVariableW (name, guid, value.data(), bufferSize);
+ if (dwLen != 0)
+ {
+ value.resize (dwLen);
+ bRet = true;
+ break;
+ }
+
+ dwError = GetLastError ();
+ if (dwError == ERROR_SUCCESS)
+ {
+ value.resize (0);
+ bRet = true;
+ break;
+ }
+
+ if ((dwError != ERROR_INSUFFICIENT_BUFFER) || (bufferSize == maxBufferSize))
+ break;
+
+ bufferSize = (bufferSize > (maxBufferSize / 2)) ? maxBufferSize : (bufferSize * 2);
+ }
+ }
+ catch (...)
+ {
+ if (bPrivilegeEnabled)
+ SetPrivilege (SE_SYSTEM_ENVIRONMENT_NAME, FALSE);
+
+ throw;
+ }
+
+ if (bPrivilegeEnabled)
+ SetPrivilege (SE_SYSTEM_ENVIRONMENT_NAME, FALSE);
+
+ if (!bRet)
+ {
+ value.clear ();
+ if (dwError == ERROR_SUCCESS)
+ dwError = GetLastError ();
+ if (dwError == ERROR_SUCCESS)
+ dwError = ERROR_INVALID_DATA;
+ if (pLastError)
+ *pLastError = dwError;
+ SetLastError (dwError);
+ }
+
+ return bRet;
+ }
+
+ static EfiBootLoaderResourceSelection MakeEfiBootLoaderResourceSelection (const EfiBootLoaderResourceSet& resources, DWORD resourceSet, const wchar_t *reason, DWORD firmwareDbError)
+ {
+ EfiBootLoaderResourceSelection selection = { &resources, resourceSet, reason, firmwareDbError };
+ return selection;
+ }
+
+ static void RecordEfiBootLoaderResourceSetSelection (const EfiBootLoaderImages& images)
+ {
+ if (!images.ResourceSet || !images.SelectionReason)
+ return;
+
+ DWORD previousLastError = GetLastError ();
+ WCHAR selectionTimeUtc[32] = {0};
+ SYSTEMTIME systemTime;
+ GetSystemTime (&systemTime);
+ StringCchPrintfW (selectionTimeUtc, ARRAYSIZE (selectionTimeUtc), L"%04u-%02u-%02uT%02u:%02u:%02uZ",
+ systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
+
+ WriteLocalMachineRegistryDword ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderResourceSet", images.ResourceSet);
+ WriteLocalMachineRegistryDword ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderFirmwareDbLastError", images.FirmwareDbError);
+ WriteLocalMachineRegistryString (EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderSelectionReason", images.SelectionReason, FALSE);
+ WriteLocalMachineRegistryString (EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderSelectionTimeUtc", selectionTimeUtc, FALSE);
+ SetLastError (previousLastError);
+ }
+
+ static uint32 ReadUint32LittleEndian (const uint8* buffer)
+ {
+ return (uint32) buffer[0]
+ | ((uint32) buffer[1] << 8)
+ | ((uint32) buffer[2] << 16)
+ | ((uint32) buffer[3] << 24);
+ }
+
+ static bool BufferEquals (const uint8* buffer, const uint8* expected, size_t expectedSize)
+ {
+ // Callers of this overload must first verify that buffer contains at least expectedSize bytes.
+ return memcmp (buffer, expected, expectedSize) == 0;
+ }
+
+ static bool BufferEquals (const uint8* buffer, size_t bufferSize, const uint8* expected, size_t expectedSize)
+ {
+ return (bufferSize == expectedSize) && BufferEquals (buffer, expected, expectedSize);
+ }
+
+ static bool FirmwareDbBufferContainsMicrosoft2023UefiCAs (const std::vector& db)
+ {
+ // Microsoft documents these CAs as valid db entries in EFI_CERT_X509_GUID or EFI_CERT_RSA2048_GUID form:
+ // https://learn.microsoft.com/windows-hardware/manufacture/desktop/windows-secure-boot-key-creation-and-management-guidance
+ // EFI_CERT_X509_GUID {a5c059a1-94e4-4aa7-87b5-ab155c2bf072}
+ static const uint8 efiCertX509Guid[16] = { 0xA1, 0x59, 0xC0, 0xA5, 0xE4, 0x94, 0xA7, 0x4A, 0x87, 0xB5, 0xAB, 0x15, 0x5C, 0x2B, 0xF0, 0x72 };
+ // EFI_CERT_RSA2048_GUID {3c5766e8-269c-4e34-aa14-ed776e85b3b6}
+ static const uint8 efiCertRsa2048Guid[16] = { 0xE8, 0x66, 0x57, 0x3C, 0x9C, 0x26, 0x34, 0x4E, 0xAA, 0x14, 0xED, 0x77, 0x6E, 0x85, 0xB3, 0xB6 };
+ const size_t efiRsa2048KeySize = 256;
+
+ // X.509 entries are matched by embedded CA public-key modulus bytes; RSA2048 entries contain this modulus directly.
+ // This is a byte-presence heuristic for bootloader-set selection, not full certificate-chain validation.
+ // Microsoft UEFI CA 2023, SHA-1 thumbprint B5EEB4A6706048073F0ED296E7F580A790B59EAA.
+ // DER source: https://go.microsoft.com/fwlink/?linkid=2239872, SHA-256 F6124E34125BEE3FE6D79A574EAA7B91C0E7BD9D929C1A321178EFD611DAD901.
+ static const uint8 microsoftUefiCa2023Rsa2048Modulus[256] =
+ {
+ 0xBD, 0x22, 0x2A, 0xAE, 0xEF, 0x1A, 0x31, 0x85,
+ 0x13, 0x78, 0x51, 0xA7, 0x9B, 0xFD, 0xFC, 0x78,
+ 0xD1, 0x63, 0xB8, 0x1A, 0x9B, 0x63, 0xF5, 0x12,
+ 0x06, 0xDB, 0x4B, 0x41, 0x35, 0x6A, 0x6F, 0xAB,
+ 0xF5, 0x6A, 0x04, 0xCC, 0x97, 0xCF, 0xBB, 0xD4,
+ 0x08, 0x09, 0x1A, 0x61, 0x3A, 0x0D, 0xE6, 0xB3,
+ 0xA0, 0x46, 0xFF, 0x09, 0xAD, 0xDE, 0x80, 0x24,
+ 0xDC, 0x12, 0x80, 0xF2, 0x5F, 0xD9, 0x16, 0xED,
+ 0xE2, 0x42, 0x9D, 0xCD, 0x2F, 0x4D, 0x61, 0x02,
+ 0x61, 0x8A, 0x1C, 0x4B, 0x1D, 0x18, 0x62, 0x39,
+ 0x86, 0x97, 0x71, 0xAD, 0x3E, 0x7F, 0x5D, 0x71,
+ 0x13, 0x4B, 0xE9, 0x2A, 0x00, 0xC1, 0xBE, 0xD5,
+ 0xB7, 0x00, 0x9F, 0x5E, 0x65, 0xB2, 0x2C, 0x1A,
+ 0xFF, 0x74, 0xED, 0xEA, 0x83, 0xD2, 0x39, 0x89,
+ 0x33, 0x35, 0x73, 0x7D, 0xA0, 0xA2, 0xFA, 0x40,
+ 0xE4, 0x66, 0x50, 0x58, 0xAA, 0xFC, 0x87, 0xE8,
+ 0x5C, 0x20, 0x83, 0x34, 0xEC, 0xAB, 0xE2, 0x0B,
+ 0xC5, 0x5F, 0x3E, 0xFF, 0x48, 0x2B, 0x11, 0x91,
+ 0x26, 0xEF, 0x18, 0x6E, 0x57, 0xC5, 0x9F, 0x18,
+ 0x73, 0x99, 0xEF, 0xE1, 0x6A, 0x74, 0x2B, 0xBB,
+ 0x2F, 0x7F, 0x50, 0x8E, 0x1D, 0xDA, 0x3D, 0x76,
+ 0xB6, 0x04, 0xE5, 0xCC, 0x2E, 0x10, 0xC7, 0x83,
+ 0x1B, 0x83, 0xA3, 0xE4, 0xA5, 0x13, 0x13, 0x71,
+ 0x6E, 0x33, 0x78, 0xA3, 0xA8, 0x3C, 0xEC, 0x48,
+ 0x26, 0x5E, 0xC7, 0xC6, 0x5E, 0x0D, 0x87, 0x9A,
+ 0xAA, 0xCC, 0x55, 0x34, 0x81, 0xAD, 0x9D, 0x90,
+ 0xF5, 0xE6, 0x96, 0x63, 0xA6, 0xE8, 0x07, 0x20,
+ 0x17, 0xC8, 0x93, 0x1E, 0xD2, 0xAE, 0xA4, 0xDC,
+ 0xAE, 0x7D, 0x59, 0xBF, 0x88, 0x5E, 0x62, 0x0C,
+ 0xAE, 0x5B, 0xF2, 0x29, 0x40, 0x56, 0x1D, 0x26,
+ 0x40, 0xDE, 0x85, 0xA6, 0xAD, 0x56, 0xD1, 0xCF,
+ 0x55, 0x47, 0x76, 0x5F, 0x9C, 0x39, 0xDB, 0x03
+ };
+
+ // Microsoft Option ROM UEFI CA 2023, SHA-1 thumbprint 3FB39E2B8BD183BF9E4594E72183CA60AFCD4277.
+ // DER source: https://go.microsoft.com/fwlink/?linkid=2284009, SHA-256 E5BE3E64C6E66A281457ECDECE0D6D0787577AAD2A3A0144262C10C14BA8D8F1.
+ static const uint8 microsoftOptionRomUefiCa2023Rsa2048Modulus[256] =
+ {
+ 0xD3, 0x0B, 0xFE, 0x89, 0xCD, 0xCD, 0xB6, 0xEE,
+ 0xDC, 0xE5, 0x1A, 0x8D, 0xDC, 0xCA, 0x21, 0x1A,
+ 0x0F, 0x22, 0x2F, 0x0B, 0xB5, 0x32, 0x84, 0x35,
+ 0xC0, 0xBE, 0x6F, 0x70, 0x93, 0x55, 0xB4, 0x47,
+ 0xCC, 0x49, 0x03, 0xC2, 0xFE, 0xCF, 0xBA, 0x32,
+ 0x65, 0x64, 0xB7, 0x35, 0xBD, 0x04, 0x3B, 0x44,
+ 0x64, 0x2F, 0xA0, 0xF2, 0xDD, 0xE1, 0x5D, 0xBA,
+ 0xE7, 0xBD, 0x39, 0x9A, 0xBD, 0xCB, 0x4B, 0xE1,
+ 0x83, 0xAA, 0x1B, 0xE8, 0x6F, 0x4E, 0x4C, 0x91,
+ 0x52, 0x43, 0xA5, 0xC4, 0x50, 0x55, 0x68, 0xF5,
+ 0xDA, 0xAC, 0x48, 0xA2, 0x9C, 0xEC, 0x35, 0xA7,
+ 0x04, 0x56, 0x68, 0x19, 0xE2, 0xB1, 0x62, 0xD4,
+ 0x92, 0xF4, 0x85, 0x3F, 0x34, 0xA1, 0x15, 0x67,
+ 0x87, 0x21, 0x6E, 0x1F, 0xC9, 0xD8, 0x35, 0x32,
+ 0xB8, 0x3D, 0xCB, 0x58, 0xCA, 0x29, 0x43, 0x54,
+ 0x4A, 0x7E, 0x8B, 0x55, 0x7B, 0x23, 0x7A, 0x3A,
+ 0xB6, 0x9D, 0x43, 0x07, 0x04, 0x6B, 0x9A, 0x6B,
+ 0xF4, 0xF0, 0x20, 0xFF, 0xFA, 0xA6, 0xDF, 0xA2,
+ 0x9E, 0x49, 0xE8, 0x55, 0xC5, 0x75, 0x88, 0x44,
+ 0xAC, 0xA4, 0x41, 0x3A, 0x03, 0x7C, 0xBB, 0xE9,
+ 0x93, 0xE4, 0x6C, 0xF1, 0xED, 0x79, 0x26, 0xC7,
+ 0x8B, 0x32, 0xF7, 0x59, 0x49, 0x25, 0x31, 0x00,
+ 0x67, 0x18, 0x0C, 0x67, 0xFB, 0x40, 0xC5, 0x5D,
+ 0x76, 0x3D, 0x09, 0x87, 0xC2, 0x2D, 0x8C, 0x5F,
+ 0x2B, 0x5A, 0x1E, 0x01, 0x0F, 0x33, 0xAF, 0x65,
+ 0x08, 0x90, 0x4F, 0xFC, 0x64, 0x5B, 0x9C, 0xA3,
+ 0x5C, 0xD6, 0x53, 0x1B, 0x51, 0x01, 0x9F, 0x98,
+ 0xCF, 0xC4, 0x53, 0xC5, 0xB1, 0xDF, 0xB3, 0x68,
+ 0x6F, 0x45, 0x4B, 0xC8, 0x45, 0x85, 0xC8, 0x1D,
+ 0xB8, 0x9E, 0xD1, 0x77, 0x71, 0xA0, 0xD5, 0xA2,
+ 0x77, 0x87, 0xEC, 0x67, 0x2E, 0xB9, 0x87, 0x06,
+ 0x46, 0xDD, 0x41, 0x43, 0x40, 0x6A, 0x5F, 0x2F
+ };
+ const size_t efiGuidSize = 16;
+ const size_t efiSignatureListHeaderSize = efiGuidSize + sizeof (uint32) * 3;
+ const size_t efiSignatureOwnerSize = efiGuidSize;
+ bool bContainsMicrosoftUefiCa2023 = false;
+ bool bContainsMicrosoftOptionRomUefiCa2023 = false;
+ size_t offset = 0;
+
+ while (offset < db.size ())
+ {
+ if (db.size () - offset < efiSignatureListHeaderSize)
+ return false;
+
+ const uint8* signatureList = &db[offset];
+ uint32 signatureListSize = ReadUint32LittleEndian (signatureList + efiGuidSize);
+ uint32 signatureHeaderSize = ReadUint32LittleEndian (signatureList + efiGuidSize + sizeof (uint32));
+ uint32 signatureSize = ReadUint32LittleEndian (signatureList + efiGuidSize + sizeof (uint32) * 2);
+
+ if ((signatureListSize < efiSignatureListHeaderSize)
+ || (signatureListSize > db.size () - offset)
+ || (signatureHeaderSize > signatureListSize - efiSignatureListHeaderSize))
+ return false;
+
+ size_t signaturesOffset = offset + efiSignatureListHeaderSize + signatureHeaderSize;
+ size_t signaturesSize = signatureListSize - efiSignatureListHeaderSize - signatureHeaderSize;
+
+ if (BufferEquals (signatureList, efiCertX509Guid, efiGuidSize))
+ {
+ if (signatureSize < efiSignatureOwnerSize)
+ return false;
+ if ((signaturesSize % signatureSize) != 0)
+ return false;
+
+ for (size_t signatureOffset = signaturesOffset; signatureOffset < offset + signatureListSize; signatureOffset += signatureSize)
+ {
+ const uint8* certificate = &db[signatureOffset + efiSignatureOwnerSize];
+ size_t certificateSize = signatureSize - efiSignatureOwnerSize;
+
+ if (!bContainsMicrosoftUefiCa2023
+ && BufferHasPattern (certificate, certificateSize, microsoftUefiCa2023Rsa2048Modulus, sizeof (microsoftUefiCa2023Rsa2048Modulus)))
+ {
+ bContainsMicrosoftUefiCa2023 = true;
+ }
+ else if (!bContainsMicrosoftOptionRomUefiCa2023
+ && BufferHasPattern (certificate, certificateSize, microsoftOptionRomUefiCa2023Rsa2048Modulus, sizeof (microsoftOptionRomUefiCa2023Rsa2048Modulus)))
+ {
+ bContainsMicrosoftOptionRomUefiCa2023 = true;
+ }
+
+ if (bContainsMicrosoftUefiCa2023 && bContainsMicrosoftOptionRomUefiCa2023)
+ return true;
+ }
+ }
+ else if (BufferEquals (signatureList, efiCertRsa2048Guid, efiGuidSize))
+ {
+ if (signatureHeaderSize != 0
+ || signatureSize != efiSignatureOwnerSize + efiRsa2048KeySize
+ || (signaturesSize % signatureSize) != 0)
+ {
+ return false;
+ }
+
+ for (size_t signatureOffset = signaturesOffset; signatureOffset < offset + signatureListSize; signatureOffset += signatureSize)
+ {
+ const uint8* publicKey = &db[signatureOffset + efiSignatureOwnerSize];
+
+ if (!bContainsMicrosoftUefiCa2023
+ && BufferEquals (publicKey, efiRsa2048KeySize, microsoftUefiCa2023Rsa2048Modulus, sizeof (microsoftUefiCa2023Rsa2048Modulus)))
+ {
+ bContainsMicrosoftUefiCa2023 = true;
+ }
+ else if (!bContainsMicrosoftOptionRomUefiCa2023
+ && BufferEquals (publicKey, efiRsa2048KeySize, microsoftOptionRomUefiCa2023Rsa2048Modulus, sizeof (microsoftOptionRomUefiCa2023Rsa2048Modulus)))
+ {
+ bContainsMicrosoftOptionRomUefiCa2023 = true;
+ }
+
+ if (bContainsMicrosoftUefiCa2023 && bContainsMicrosoftOptionRomUefiCa2023)
+ return true;
+ }
+ }
+
+ offset += signatureListSize;
+ }
+
+ return false;
+ }
+
+#ifdef VC_EFI_BOOTLOADER_SELECTION_TEST
+ bool TestFirmwareDbBufferContainsMicrosoft2023UefiCAs (const uint8* db, size_t dbSize)
+ {
+ std::vector firmwareDb;
+ if (dbSize != 0)
+ {
+ if (!db)
+ return false;
+ firmwareDb.assign (db, db + dbSize);
+ }
+
+ return FirmwareDbBufferContainsMicrosoft2023UefiCAs (firmwareDb);
+ }
+#endif
+
+ static bool TryFirmwareDbContainsMicrosoft2023UefiCAs (bool& bContainsMicrosoft2023UefiCAs)
+ {
+ std::vector db;
+ DWORD dwError = ERROR_SUCCESS;
+ if (!ReadFirmwareEnvironmentVariableBuffer (L"db", EfiImageSecurityDatabaseGuid, db, &dwError))
+ {
+ SetLastError (dwError);
+ return false;
+ }
+
+ bContainsMicrosoft2023UefiCAs = FirmwareDbBufferContainsMicrosoft2023UefiCAs (db);
+ return true;
+ }
+
+ static bool IsFirmwareDbUnavailableError (DWORD dwError)
+ {
+ return (dwError == ERROR_ENVVAR_NOT_FOUND) || (dwError == ERROR_INVALID_FUNCTION);
+ }
+
+ static bool TryFirmwareSecureBootEnabled (bool& bSecureBootEnabled, DWORD* pLastError = NULL)
+ {
+ std::vector secureBoot;
+ DWORD dwError = ERROR_SUCCESS;
+ if (!ReadFirmwareEnvironmentVariableBuffer (L"SecureBoot", EfiVarGuid, secureBoot, &dwError))
+ {
+ if (pLastError)
+ *pLastError = dwError;
+ SetLastError (dwError);
+ return false;
+ }
+
+ bSecureBootEnabled = (secureBoot.size () >= 1) && (secureBoot[0] == 1);
+ return true;
+ }
+
+ static EfiBootLoaderResourceSelection GetPreferredEfiBootLoaderResourceSet ()
+ {
+ // The current 2023 DCS set uses both Microsoft UEFI CA 2023 and Microsoft Option ROM UEFI CA 2023:
+ // DcsInt.dcs and LegacySpeaker.dcs are signed through the Option ROM UEFI CA 2023 chain.
+ // If db cannot be read, keep the pre-2023 universal behavior and use the 2011 compatibility fallback.
+ bool bContainsMicrosoft2023UefiCAs = false;
+ if (TryFirmwareDbContainsMicrosoft2023UefiCAs (bContainsMicrosoft2023UefiCAs))
+ {
+ if (bContainsMicrosoft2023UefiCAs)
+ return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2023, 2023, L"firmware db contains Microsoft UEFI CA 2023 and Microsoft Option ROM UEFI CA 2023", ERROR_SUCCESS);
+
+ return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, 2011, L"firmware db does not contain both Microsoft 2023 UEFI CAs", ERROR_SUCCESS);
+ }
+
+ DWORD dwError = GetLastError ();
+ if (IsFirmwareDbUnavailableError (dwError))
+ return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, 2011, L"firmware db is unavailable; using 2011 compatibility fallback", dwError);
+
+ bool bSecureBootEnabled = false;
+ if (TryFirmwareSecureBootEnabled (bSecureBootEnabled) && !bSecureBootEnabled)
+ return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, 2011, L"Secure Boot is disabled and firmware db could not be read; using 2011 compatibility fallback", dwError);
+#ifndef SETUP
+ if (!IsAdmin () && IsUacSupported ())
+ {
+ // This may prompt for elevation from non-admin Mount/Format paths. EFI rescue
+ // media and bootloader repair need accurate firmware db detection to avoid
+ // selecting a Microsoft CA set unsupported by the current Secure Boot db.
+ BOOL bElevatedContainsMicrosoft2023UefiCAs = FALSE;
+ Elevator::GetEfiBootLoaderSigningSupport (&bElevatedContainsMicrosoft2023UefiCAs);
+ if (bElevatedContainsMicrosoft2023UefiCAs)
+ return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2023, 2023, L"elevated helper reported Microsoft 2023 UEFI CA support", dwError);
+
+ return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, 2011, L"elevated helper did not report Microsoft 2023 UEFI CA support", dwError);
+ }
+#endif
+
+ return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, 2011, L"firmware db could not be read; using 2011 compatibility fallback", dwError);
+ }
+
+ static void ThrowMissingEfiResource (const wchar_t* resourceName, bool rescueDisk)
+ {
+ if (rescueDisk)
+ throw ParameterIncorrect (SRC_POS);
+
+ throw ErrorException (wstring (L"Out of resource ") + resourceName, SRC_POS);
+ }
+
+ static uint8* MapEfiBootLoaderResource (int resourceId, const wchar_t* resourceName, DWORD& size, bool rescueDisk)
+ {
+ uint8 *resource = MapResource (L"BIN", resourceId, &size);
+ if (!resource)
+ ThrowMissingEfiResource (resourceName, rescueDisk);
+
+ return resource;
+ }
+
+ static EfiBootLoaderImages MapEfiBootLoaderImages (bool rescueDisk)
+ {
+ EfiBootLoaderResourceSelection selection = GetPreferredEfiBootLoaderResourceSet ();
+ const EfiBootLoaderResourceSet& resources = *selection.Resources;
+ EfiBootLoaderImages images = {0};
+
+ images.DcsBoot = MapEfiBootLoaderResource (resources.DcsBoot, L"DcsBoot", images.SizeDcsBoot, rescueDisk);
+ images.DcsInt = MapEfiBootLoaderResource (resources.DcsInt, L"DcsInt", images.SizeDcsInt, rescueDisk);
+ images.DcsCfg = MapEfiBootLoaderResource (resources.DcsCfg, L"DcsCfg", images.SizeDcsCfg, rescueDisk);
+ images.LegacySpeaker = MapEfiBootLoaderResource (resources.LegacySpeaker, L"LegacySpeaker", images.SizeLegacySpeaker, rescueDisk);
+ images.DcsRescue = MapEfiBootLoaderResource (resources.DcsRescue, L"DcsRe", images.SizeDcsRescue, rescueDisk);
+ images.DcsInfo = MapEfiBootLoaderResource (resources.DcsInfo, L"DcsInfo", images.SizeDcsInfo, rescueDisk);
+ images.ResourceSet = selection.ResourceSet;
+ images.SelectionReason = selection.Reason;
+ images.FirmwareDbError = selection.FirmwareDbError;
+
+ return images;
+ }
+
+ static void BackupEfiBootLoaderImageIfDifferent (EfiBoot& efiBoot, const wchar_t* imageName, const wchar_t* backupName, uint8* replacementData, DWORD replacementSize)
+ {
+ std::vector currentImage;
+ if (!efiBoot.ReadFileToBuffer (imageName, currentImage))
+ return;
+
+ if ((currentImage.size () != replacementSize)
+ || ((replacementSize != 0) && (memcmp (currentImage.data (), replacementData, replacementSize) != 0)))
+ {
+ // Preserve the first divergent image as the rollback snapshot; later CA refreshes must not overwrite it.
+ if (!efiBoot.FileExists (backupName))
+ efiBoot.SaveFile (backupName, currentImage.data (), (DWORD) currentImage.size ());
+ }
+ }
+
+ static void BackupEfiBootLoaderImagesIfDifferent (EfiBoot& efiBoot, const EfiBootLoaderImages& images)
+ {
+ BackupEfiBootLoaderImageIfDifferent (efiBoot, L"\\EFI\\VeraCrypt\\DcsBoot.efi", L"\\EFI\\VeraCrypt\\DcsBoot.efi.vc_backup", images.DcsBoot, images.SizeDcsBoot);
+ BackupEfiBootLoaderImageIfDifferent (efiBoot, L"\\EFI\\VeraCrypt\\DcsInt.dcs", L"\\EFI\\VeraCrypt\\DcsInt.dcs.vc_backup", images.DcsInt, images.SizeDcsInt);
+ BackupEfiBootLoaderImageIfDifferent (efiBoot, L"\\EFI\\VeraCrypt\\DcsCfg.dcs", L"\\EFI\\VeraCrypt\\DcsCfg.dcs.vc_backup", images.DcsCfg, images.SizeDcsCfg);
+ BackupEfiBootLoaderImageIfDifferent (efiBoot, L"\\EFI\\VeraCrypt\\LegacySpeaker.dcs", L"\\EFI\\VeraCrypt\\LegacySpeaker.dcs.vc_backup", images.LegacySpeaker, images.SizeLegacySpeaker);
+ BackupEfiBootLoaderImageIfDifferent (efiBoot, L"\\EFI\\VeraCrypt\\DcsInfo.dcs", L"\\EFI\\VeraCrypt\\DcsInfo.dcs.vc_backup", images.DcsInfo, images.SizeDcsInfo);
+ }
+
+ static void SaveEfiBootLoaderImages (EfiBoot& efiBoot, const EfiBootLoaderImages& images, bool backupExistingImages = false)
+ {
+ if (backupExistingImages)
+ BackupEfiBootLoaderImagesIfDifferent (efiBoot, images);
+
+ efiBoot.SaveFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", images.DcsBoot, images.SizeDcsBoot);
+ efiBoot.SaveFile (L"\\EFI\\VeraCrypt\\DcsInt.dcs", images.DcsInt, images.SizeDcsInt);
+ efiBoot.SaveFile (L"\\EFI\\VeraCrypt\\DcsCfg.dcs", images.DcsCfg, images.SizeDcsCfg);
+ efiBoot.SaveFile (L"\\EFI\\VeraCrypt\\LegacySpeaker.dcs", images.LegacySpeaker, images.SizeLegacySpeaker);
+ efiBoot.SaveFile (L"\\EFI\\VeraCrypt\\DcsInfo.dcs", images.DcsInfo, images.SizeDcsInfo);
+ RecordEfiBootLoaderResourceSetSelection (images);
+ }
void
GetVolumeESP(wstring& path, wstring& bootVolumePath)
@@ -3442,32 +3979,16 @@ namespace VeraCrypt
Warning ("ADMIN_PRIVILEGES_WARN_DEVICES", ParentWindow);
}
}
- DWORD sizeDcsBoot;
- uint8 *dcsBootImg = MapResource(L"BIN", IDR_EFI_DCSBOOT, &sizeDcsBoot);
- if (!dcsBootImg)
- throw ErrorException(L"Out of resource DcsBoot", SRC_POS);
- DWORD sizeDcsInt;
- uint8 *dcsIntImg = MapResource(L"BIN", IDR_EFI_DCSINT, &sizeDcsInt);
- if (!dcsIntImg)
- throw ErrorException(L"Out of resource DcsInt", SRC_POS);
- DWORD sizeDcsCfg;
- uint8 *dcsCfgImg = MapResource(L"BIN", IDR_EFI_DCSCFG, &sizeDcsCfg);
- if (!dcsCfgImg)
- throw ErrorException(L"Out of resource DcsCfg", SRC_POS);
- DWORD sizeLegacySpeaker;
- uint8 *LegacySpeakerImg = MapResource(L"BIN", IDR_EFI_LEGACYSPEAKER, &sizeLegacySpeaker);
- if (!LegacySpeakerImg)
- throw ErrorException(L"Out of resource LegacySpeaker", SRC_POS);
+ EfiBootLoaderImages efiImages = MapEfiBootLoaderImages (false);
+ // Kept as aliases for the legacy EFI\Boot\bootx64.efi replacement block below.
+ DWORD sizeDcsBoot = efiImages.SizeDcsBoot;
+ uint8 *dcsBootImg = efiImages.DcsBoot;
#ifdef VC_EFI_CUSTOM_MODE
DWORD sizeBootMenuLocker;
uint8 *BootMenuLockerImg = MapResource(L"BIN", IDR_EFI_DCSBML, &sizeBootMenuLocker);
if (!BootMenuLockerImg)
throw ErrorException(L"Out of resource DcsBml", SRC_POS);
#endif
- DWORD sizeDcsInfo;
- uint8 *DcsInfoImg = MapResource(L"BIN", IDR_EFI_DCSINFO, &sizeDcsInfo);
- if (!DcsInfoImg)
- throw ErrorException(L"Out of resource DcsInfo", SRC_POS);
EfiBootInst.PrepareBootPartition(PostOOBEMode);
@@ -3477,14 +3998,16 @@ namespace VeraCrypt
bool bAlreadyExist;
const char* g_szMsBootString = "bootmgfw.pdb";
unsigned __int64 loaderSize = 0;
+ const wchar_t * szStdMsBootloader = L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi";
+ const wchar_t * szBackupMsBootloader = L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc";
const wchar_t * szStdEfiBootloader = L"\\EFI\\Boot\\bootx64.efi";
const wchar_t * szBackupEfiBootloader = L"\\EFI\\Boot\\original_bootx64.vc_backup";
if (preserveUserConfig)
{
- bool bModifiedMsBoot = true, bMissingMsBoot = false;;
- if (EfiBootInst.FileExists (L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"))
- EfiBootInst.GetFileSize(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", loaderSize);
+ bool bModifiedMsBoot = true, bMissingMsBoot = false, bMsBootloaderMovedToBackup = false;
+ if (EfiBootInst.FileExists (szStdMsBootloader))
+ EfiBootInst.GetFileSize(szStdMsBootloader, loaderSize);
else
bMissingMsBoot = true;
@@ -3492,20 +4015,21 @@ namespace VeraCrypt
if (PostOOBEMode)
EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi", SetBootEntry, ForceFirstBootEntry, SetBootNext);
- if (EfiBootInst.FileExists (L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc"))
+ if (EfiBootInst.FileExists (szBackupMsBootloader))
{
if (loaderSize > 32768)
{
std::vector bootLoaderBuf ((size_t) loaderSize);
- EfiBootInst.ReadFile(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", &bootLoaderBuf[0], (DWORD) loaderSize);
+ EfiBootInst.ReadFile(szStdMsBootloader, &bootLoaderBuf[0], (DWORD) loaderSize);
// look for bootmgfw.efi identifiant string
if (BufferHasPattern (bootLoaderBuf.data (), (size_t) loaderSize, g_szMsBootString, strlen (g_szMsBootString)))
{
bModifiedMsBoot = false;
// replace the backup with this version
- EfiBootInst.RenameFile (L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc", TRUE);
+ if (EfiBootInst.RenameFile (szStdMsBootloader, szBackupMsBootloader, TRUE))
+ bMsBootloaderMovedToBackup = true;
}
}
}
@@ -3516,7 +4040,7 @@ namespace VeraCrypt
{
std::vector bootLoaderBuf ((size_t) loaderSize);
- EfiBootInst.ReadFile(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", &bootLoaderBuf[0], (DWORD) loaderSize);
+ EfiBootInst.ReadFile(szStdMsBootloader, &bootLoaderBuf[0], (DWORD) loaderSize);
// look for bootmgfw.efi identifiant string
if (BufferHasPattern (bootLoaderBuf.data (), (size_t) loaderSize, g_szMsBootString, strlen (g_szMsBootString)))
@@ -3525,7 +4049,8 @@ namespace VeraCrypt
if (!bModifiedMsBoot)
{
- EfiBootInst.RenameFile (L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc", TRUE);
+ if (EfiBootInst.RenameFile (szStdMsBootloader, szBackupMsBootloader, TRUE))
+ bMsBootloaderMovedToBackup = true;
}
else
{
@@ -3551,7 +4076,7 @@ namespace VeraCrypt
if (BufferHasPattern (bootLoaderBuf.data (), (size_t) loaderSize, g_szMsBootString, strlen (g_szMsBootString)))
{
bFound = true;
- EfiBootInst.RenameFile(loaderPath.c_str(), L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc", TRUE);
+ EfiBootInst.RenameFile(loaderPath.c_str(), szBackupMsBootloader, TRUE);
}
}
}
@@ -3563,16 +4088,47 @@ namespace VeraCrypt
}
if (PostOOBEMode && EfiBootInst.FileExists (L"\\EFI\\VeraCrypt\\DcsBoot.efi"))
- {
- // check if bootmgfw.efi has been set again to Microsoft version
- // if yes, replace it with our bootloader after it was copied to bootmgfw_ms.vc
- if (!bModifiedMsBoot || bMissingMsBoot)
- EfiBootInst.CopyFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi");
+ {
+ const bool bRefreshMsBootloader = !bModifiedMsBoot
+ || bMissingMsBoot
+ || (EfiBootInst.FileExists (szStdMsBootloader) && EfiBootInst.IsVeraCryptBootLoader (szStdMsBootloader));
+
+ // Keep the firmware-visible loader path valid before the larger module refresh.
+ if (bRefreshMsBootloader && !EfiBootInst.FileExists (szStdMsBootloader))
+ {
+ try
+ {
+ EfiBootInst.CopyFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", szStdMsBootloader);
+ }
+ catch (...)
+ {
+ if (bMsBootloaderMovedToBackup)
+ EfiBootInst.RenameFile (szBackupMsBootloader, szStdMsBootloader, TRUE);
+ throw;
+ }
+ }
+
+ SaveEfiBootLoaderImages (EfiBootInst, efiImages, true);
+#ifdef VC_EFI_CUSTOM_MODE
+ EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker);
+#endif
+
+ // check if bootmgfw.efi has been set again to Microsoft version.
+ // If yes, replace it with our bootloader after it was copied to bootmgfw_ms.vc.
+ // If it is already a VeraCrypt copy, refresh it because the firmware db may now
+ // trust a different Microsoft CA than the one selected at original install time.
+ if (bRefreshMsBootloader)
+ {
+ EfiBootInst.CopyFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", szStdMsBootloader);
+ }
if (EfiBootInst.FileExists (szStdEfiBootloader))
{
- // check if standard bootloader under EFI\Boot has been set to Microsoft version
- // if yes, replace it with our bootloader
+ // check if standard bootloader under EFI\Boot has been set to Microsoft version.
+ // If yes, replace it with our bootloader. If it is already a VeraCrypt copy,
+ // refresh it because the firmware db may now trust a different Microsoft CA
+ // than the one selected at original install time.
+ bool bStdEfiBootloaderUpdated = false;
EfiBootInst.GetFileSize(szStdEfiBootloader, loaderSize);
if (loaderSize > 32768)
{
@@ -3585,22 +4141,23 @@ namespace VeraCrypt
{
EfiBootInst.RenameFile (szStdEfiBootloader, szBackupEfiBootloader, TRUE);
EfiBootInst.CopyFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", szStdEfiBootloader);
+ bStdEfiBootloaderUpdated = true;
}
}
+ if (!bStdEfiBootloaderUpdated && EfiBootInst.IsVeraCryptBootLoader (szStdEfiBootloader))
+ {
+ EfiBootInst.CopyFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", szStdEfiBootloader);
+ }
}
return;
}
}
EfiBootInst.MkDir(L"\\EFI\\VeraCrypt", bAlreadyExist);
- EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsBoot.efi", dcsBootImg, sizeDcsBoot);
- EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsInt.dcs", dcsIntImg, sizeDcsInt);
- EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsCfg.dcs", dcsCfgImg, sizeDcsCfg);
- EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\LegacySpeaker.dcs", LegacySpeakerImg, sizeLegacySpeaker);
+ SaveEfiBootLoaderImages (EfiBootInst, efiImages);
#ifdef VC_EFI_CUSTOM_MODE
EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker);
#endif
- EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsInfo.dcs", DcsInfoImg, sizeDcsInfo);
if (!preserveUserConfig)
EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\PlatformInfo");
EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi", SetBootEntry, ForceFirstBootEntry, SetBootNext);
@@ -3812,36 +4369,13 @@ namespace VeraCrypt
if (bIsGPT)
{
// create EFI disk structure
- DWORD sizeDcsBoot;
- uint8 *dcsBootImg = MapResource(L"BIN", IDR_EFI_DCSBOOT, &sizeDcsBoot);
- if (!dcsBootImg)
- throw ParameterIncorrect (SRC_POS);
- DWORD sizeDcsInt;
- uint8 *dcsIntImg = MapResource(L"BIN", IDR_EFI_DCSINT, &sizeDcsInt);
- if (!dcsIntImg)
- throw ParameterIncorrect (SRC_POS);
- DWORD sizeDcsCfg;
- uint8 *dcsCfgImg = MapResource(L"BIN", IDR_EFI_DCSCFG, &sizeDcsCfg);
- if (!dcsCfgImg)
- throw ParameterIncorrect (SRC_POS);
- DWORD sizeLegacySpeaker;
- uint8 *LegacySpeakerImg = MapResource(L"BIN", IDR_EFI_LEGACYSPEAKER, &sizeLegacySpeaker);
- if (!LegacySpeakerImg)
- throw ParameterIncorrect (SRC_POS);
+ EfiBootLoaderImages efiImages = MapEfiBootLoaderImages (true);
#ifdef VC_EFI_CUSTOM_MODE
DWORD sizeBootMenuLocker;
uint8 *BootMenuLockerImg = MapResource(L"BIN", IDR_EFI_DCSBML, &sizeBootMenuLocker);
if (!BootMenuLockerImg)
throw ParameterIncorrect (SRC_POS);
#endif
- DWORD sizeDcsRescue;
- uint8 *DcsRescueImg = MapResource(L"BIN", IDR_EFI_DCSRE, &sizeDcsRescue);
- if (!DcsRescueImg)
- throw ParameterIncorrect (SRC_POS);
- DWORD sizeDcsInfo;
- uint8 *DcsInfoImg = MapResource(L"BIN", IDR_EFI_DCSINFO, &sizeDcsInfo);
- if (!DcsInfoImg)
- throw ParameterIncorrect (SRC_POS);
WCHAR szTmpPath[MAX_PATH + 1], szTmpFilePath[MAX_PATH + 1];
if (!GetTempPathW (MAX_PATH, szTmpPath))
@@ -3865,21 +4399,21 @@ namespace VeraCrypt
finally_do_arg (zip_t**, &z, { if (*finally_arg) zip_discard (*finally_arg);});
- if (!ZipAdd (z, "EFI/Boot/bootx64.efi", DcsRescueImg, sizeDcsRescue))
+ if (!ZipAdd (z, "EFI/Boot/bootx64.efi", efiImages.DcsRescue, efiImages.SizeDcsRescue))
throw ParameterIncorrect (SRC_POS);
#ifdef VC_EFI_CUSTOM_MODE
if (!ZipAdd (z, "EFI/VeraCrypt/DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker))
throw ParameterIncorrect (SRC_POS);
#endif
- if (!ZipAdd (z, "EFI/VeraCrypt/DcsBoot.efi", dcsBootImg, sizeDcsBoot))
+ if (!ZipAdd (z, "EFI/VeraCrypt/DcsBoot.efi", efiImages.DcsBoot, efiImages.SizeDcsBoot))
throw ParameterIncorrect (SRC_POS);
- if (!ZipAdd (z, "EFI/VeraCrypt/DcsCfg.dcs", dcsCfgImg, sizeDcsCfg))
+ if (!ZipAdd (z, "EFI/VeraCrypt/DcsCfg.dcs", efiImages.DcsCfg, efiImages.SizeDcsCfg))
throw ParameterIncorrect (SRC_POS);
- if (!ZipAdd (z, "EFI/VeraCrypt/DcsInt.dcs", dcsIntImg, sizeDcsInt))
+ if (!ZipAdd (z, "EFI/VeraCrypt/DcsInt.dcs", efiImages.DcsInt, efiImages.SizeDcsInt))
throw ParameterIncorrect (SRC_POS);
- if (!ZipAdd (z, "EFI/VeraCrypt/LegacySpeaker.dcs", LegacySpeakerImg, sizeLegacySpeaker))
+ if (!ZipAdd (z, "EFI/VeraCrypt/LegacySpeaker.dcs", efiImages.LegacySpeaker, efiImages.SizeLegacySpeaker))
throw ParameterIncorrect (SRC_POS);
- if (!ZipAdd (z, "EFI/VeraCrypt/DcsInfo.dcs", DcsInfoImg, sizeDcsInfo))
+ if (!ZipAdd (z, "EFI/VeraCrypt/DcsInfo.dcs", efiImages.DcsInfo, efiImages.SizeDcsInfo))
throw ParameterIncorrect (SRC_POS);
Buffer volHeader(TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
@@ -5252,6 +5786,25 @@ namespace VeraCrypt
}
}
#endif
+
+ void BootEncryption::GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported)
+ {
+ if (!pMicrosoft2023UefiCAsSupported)
+ {
+ SetLastError (ERROR_INVALID_PARAMETER);
+ throw SystemException (SRC_POS);
+ }
+
+ bool bContainsMicrosoft2023UefiCAs = false;
+ if (!TryFirmwareDbContainsMicrosoft2023UefiCAs (bContainsMicrosoft2023UefiCAs))
+ {
+ *pMicrosoft2023UefiCAsSupported = FALSE;
+ return;
+ }
+
+ *pMicrosoft2023UefiCAsSupported = bContainsMicrosoft2023UefiCAs ? TRUE : FALSE;
+ }
+
#ifndef SETUP
void BootEncryption::CheckRequirements ()
{
diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h
index 543316aa..568a9f45 100644
--- a/src/Common/BootEncryption.h
+++ b/src/Common/BootEncryption.h
@@ -27,6 +27,10 @@ using namespace std;
namespace VeraCrypt
{
+#ifdef VC_EFI_BOOTLOADER_SELECTION_TEST
+ bool TestFirmwareDbBufferContainsMicrosoft2023UefiCAs (const uint8* db, size_t dbSize);
+#endif
+
class File
{
public:
@@ -317,6 +321,7 @@ namespace VeraCrypt
void RestoreSystemLoader ();
static void UpdateSetupConfigFile (bool bForInstall);
void GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
+ void GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported);
bool IsUsingUnsupportedAlgorithm(LONG driverVersion);
void NotifyService (DWORD dwNotifyCmd);
protected:
diff --git a/src/Common/Common.rc b/src/Common/Common.rc
index fd20e426..bb9f617d 100644
--- a/src/Common/Common.rc
+++ b/src/Common/Common.rc
@@ -556,15 +556,21 @@ IDR_RESCUE_LOADER_AES_SHA2 BIN "..\\Boot\\Windows\\Rescue_AE
IDR_RESCUE_LOADER_SERPENT_SHA2 BIN "..\\Boot\\Windows\\Rescue_Serpent_SHA2\\BootLoader.com.gz"
IDR_RESCUE_LOADER_TWOFISH_SHA2 BIN "..\\Boot\\Windows\\Rescue_Twofish_SHA2\\BootLoader.com.gz"
IDR_RESCUE_LOADER_CAMELLIA_SHA2 BIN "..\\Boot\\Windows\\Rescue_Camellia_SHA2\\BootLoader.com.gz"
-IDR_EFI_DCSBOOT BIN "..\\Boot\\EFI\\DcsBoot.efi"
-IDR_EFI_DCSINT BIN "..\\Boot\\EFI\\DcsInt.efi"
-IDR_EFI_DCSCFG BIN "..\\Boot\\EFI\\DcsCfg.efi"
-IDR_EFI_LEGACYSPEAKER BIN "..\\Boot\\EFI\\LegacySpeaker.efi"
+IDR_EFI_DCSBOOT_2011 BIN "..\\Boot\\EFI\\2011UEFICA\\DcsBoot.efi"
+IDR_EFI_DCSINT_2011 BIN "..\\Boot\\EFI\\2011UEFICA\\DcsInt.efi"
+IDR_EFI_DCSCFG_2011 BIN "..\\Boot\\EFI\\2011UEFICA\\DcsCfg.efi"
+IDR_EFI_LEGACYSPEAKER_2011 BIN "..\\Boot\\EFI\\2011UEFICA\\LegacySpeaker.efi"
#ifdef VC_EFI_CUSTOM_MODE
IDR_EFI_DCSBML BIN "..\\Boot\\EFI\\DcsBml.efi"
#endif
-IDR_EFI_DCSRE BIN "..\\Boot\\EFI\\DcsRe.efi"
-IDR_EFI_DCSINFO BIN "..\\Boot\\EFI\\DcsInfo.efi"
+IDR_EFI_DCSRE_2011 BIN "..\\Boot\\EFI\\2011UEFICA\\DcsRe.efi"
+IDR_EFI_DCSINFO_2011 BIN "..\\Boot\\EFI\\2011UEFICA\\DcsInfo.efi"
+IDR_EFI_DCSBOOT_2023 BIN "..\\Boot\\EFI\\2023UEFICA\\DcsBoot.efi"
+IDR_EFI_DCSINT_2023 BIN "..\\Boot\\EFI\\2023UEFICA\\DcsInt.efi"
+IDR_EFI_DCSCFG_2023 BIN "..\\Boot\\EFI\\2023UEFICA\\DcsCfg.efi"
+IDR_EFI_LEGACYSPEAKER_2023 BIN "..\\Boot\\EFI\\2023UEFICA\\LegacySpeaker.efi"
+IDR_EFI_DCSRE_2023 BIN "..\\Boot\\EFI\\2023UEFICA\\DcsRe.efi"
+IDR_EFI_DCSINFO_2023 BIN "..\\Boot\\EFI\\2023UEFICA\\DcsInfo.efi"
#endif
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/src/Common/Registry.c b/src/Common/Registry.c
index bcbba3bc..9e665d43 100644
--- a/src/Common/Registry.c
+++ b/src/Common/Registry.c
@@ -199,7 +199,7 @@ BOOL WriteLocalMachineRegistryMultiString (wchar_t *subKey, wchar_t *name, wchar
return TRUE;
}
-BOOL WriteLocalMachineRegistryString (wchar_t *subKey, wchar_t *name, wchar_t *str, BOOL expandable)
+BOOL WriteLocalMachineRegistryString (const wchar_t *subKey, const wchar_t *name, const wchar_t *str, BOOL expandable)
{
HKEY hkey = 0;
DWORD disp;
@@ -297,4 +297,4 @@ void GetRestorePointRegKeyName (wchar_t *regk, size_t cbRegk)
// The string is split in order to prevent some antivirus packages from falsely reporting
// VeraCrypt.exe to contain a possible Trojan horse because of this string (heuristic scan).
StringCbPrintfW (regk, cbRegk,L"%s%s%s%s", L"Software\\Microsoft\\Windows", L" NT\\Curren", L"tVersion\\Sy", L"stemRestore");
-}
\ No newline at end of file
+}
diff --git a/src/Common/Registry.h b/src/Common/Registry.h
index 360f4ef8..232ae2af 100644
--- a/src/Common/Registry.h
+++ b/src/Common/Registry.h
@@ -24,7 +24,7 @@ DWORD ReadRegistryBytes (wchar_t *path, wchar_t *name, char *value, int maxLen);
void WriteRegistryInt (wchar_t *subKey, wchar_t *name, int value);
BOOL WriteLocalMachineRegistryDword (wchar_t *subKey, wchar_t *name, DWORD value);
BOOL WriteLocalMachineRegistryMultiString (wchar_t *subKey, wchar_t *name, wchar_t *multiString, DWORD size);
-BOOL WriteLocalMachineRegistryString (wchar_t *subKey, wchar_t *name, wchar_t *str, BOOL expandable);
+BOOL WriteLocalMachineRegistryString (const wchar_t *subKey, const wchar_t *name, const wchar_t *str, BOOL expandable);
void WriteRegistryString (wchar_t *subKey, wchar_t *name, wchar_t *str);
BOOL WriteRegistryBytes (wchar_t *path, wchar_t *name, char *str, DWORD size);
BOOL DeleteLocalMachineRegistryKey (wchar_t *parentKey, wchar_t *subKeyToDelete);
diff --git a/src/Common/Resource.h b/src/Common/Resource.h
index dd10b2df..93c7ab08 100644
--- a/src/Common/Resource.h
+++ b/src/Common/Resource.h
@@ -67,13 +67,19 @@
#define IDR_BOOT_LOADER_CAMELLIA_SHA2 563
#define IDR_RESCUE_BOOT_SECTOR_CAMELLIA_SHA2 564
#define IDR_RESCUE_LOADER_CAMELLIA_SHA2 565
-#define IDR_EFI_DCSBOOT 566
-#define IDR_EFI_DCSINT 567
-#define IDR_EFI_DCSCFG 568
-#define IDR_EFI_LEGACYSPEAKER 569
+#define IDR_EFI_DCSBOOT_2011 566
+#define IDR_EFI_DCSINT_2011 567
+#define IDR_EFI_DCSCFG_2011 568
+#define IDR_EFI_LEGACYSPEAKER_2011 569
#define IDR_EFI_DCSBML 570
-#define IDR_EFI_DCSRE 571
-#define IDR_EFI_DCSINFO 578
+#define IDR_EFI_DCSRE_2011 571
+#define IDR_EFI_DCSINFO_2011 578
+#define IDR_EFI_DCSBOOT_2023 579
+#define IDR_EFI_DCSINT_2023 580
+#define IDR_EFI_DCSCFG_2023 581
+#define IDR_EFI_LEGACYSPEAKER_2023 582
+#define IDR_EFI_DCSRE_2023 583
+#define IDR_EFI_DCSINFO_2023 584
#define IDC_HW_AES_LABEL_LINK 5000
#define IDC_HW_AES 5001
#define IDC_PARALLELIZATION_LABEL_LINK 5002
@@ -227,7 +233,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
-#define _APS_NEXT_RESOURCE_VALUE 578
+#define _APS_NEXT_RESOURCE_VALUE 585
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 5147
#define _APS_NEXT_SYMED_VALUE 101
diff --git a/src/Format/Format.vcxproj b/src/Format/Format.vcxproj
index 4ba04157..1562b5db 100644
--- a/src/Format/Format.vcxproj
+++ b/src/Format/Format.vcxproj
@@ -511,12 +511,18 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-arm64.exe" >NUL:
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -599,4 +605,4 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-arm64.exe" >NUL:
-
\ No newline at end of file
+
diff --git a/src/Format/FormatCom.cpp b/src/Format/FormatCom.cpp
index a78c96fb..77cc0f7d 100644
--- a/src/Format/FormatCom.cpp
+++ b/src/Format/FormatCom.cpp
@@ -176,6 +176,11 @@ public:
return BaseCom::GetSecureBootConfig (pSecureBootEnabled, pVeraCryptKeysLoaded);
}
+ virtual DWORD STDMETHODCALLTYPE GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported)
+ {
+ return BaseCom::GetEfiBootLoaderSigningSupport (pMicrosoft2023UefiCAsSupported);
+ }
+
virtual DWORD STDMETHODCALLTYPE WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMessage, int pim, int hashAlg)
{
return BaseCom::WriteEfiBootSectorUserConfig (userConfig, customUserMessage,pim, hashAlg);
diff --git a/src/Format/FormatCom.idl b/src/Format/FormatCom.idl
index 7276de81..1f93f5f7 100644
--- a/src/Format/FormatCom.idl
+++ b/src/Format/FormatCom.idl
@@ -16,7 +16,7 @@ import "..\Common\Password.h";
[
uuid(56327DDA-F1A7-4e13-B128-520D129BDEF6),
helpstring("VeraCrypt Format UAC Support Library"),
- version(2.10) // Update ComSetup.cpp when changing version number
+ version(2.11) // Update ComSetup.cpp when changing version number
]
library TrueCryptFormatCom
{
@@ -51,6 +51,7 @@ library TrueCryptFormatCom
DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
DWORD NotifyService (DWORD dwNotifyCode);
DWORD FastFileResize (BSTR filePath, __int64 fileSize);
+ DWORD GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported);
};
[
diff --git a/src/Mount/MainCom.cpp b/src/Mount/MainCom.cpp
index 745b71c6..066e48c1 100644
--- a/src/Mount/MainCom.cpp
+++ b/src/Mount/MainCom.cpp
@@ -193,6 +193,11 @@ public:
return BaseCom::GetSecureBootConfig (pSecureBootEnabled, pVeraCryptKeysLoaded);
}
+ virtual DWORD STDMETHODCALLTYPE GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported)
+ {
+ return BaseCom::GetEfiBootLoaderSigningSupport (pMicrosoft2023UefiCAsSupported);
+ }
+
virtual DWORD STDMETHODCALLTYPE WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMessage, int pim, int hashAlg)
{
return BaseCom::WriteEfiBootSectorUserConfig (userConfig, customUserMessage,pim, hashAlg);
diff --git a/src/Mount/MainCom.idl b/src/Mount/MainCom.idl
index 06c2e48f..510efa2f 100644
--- a/src/Mount/MainCom.idl
+++ b/src/Mount/MainCom.idl
@@ -16,7 +16,7 @@ import "..\Common\Password.h";
[
uuid(9ACF6176-5FC4-4690-A025-B3306A50EB6A),
helpstring("VeraCrypt Main UAC Support Library"),
- version(2.13) // Update ComSetup.cpp when changing version number
+ version(2.14) // Update ComSetup.cpp when changing version number
]
library TrueCryptMainCom
{
@@ -55,6 +55,7 @@ library TrueCryptMainCom
DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
DWORD NotifyService (DWORD dwNotifyCode);
DWORD FastFileResize (BSTR filePath, __int64 fileSize);
+ DWORD GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSupported);
};
[
diff --git a/src/Setup/ComSetup.cpp b/src/Setup/ComSetup.cpp
index df5c567e..f985e9c7 100644
--- a/src/Setup/ComSetup.cpp
+++ b/src/Setup/ComSetup.cpp
@@ -11,10 +11,10 @@
*/
#define TC_MAIN_COM_VERSION_MAJOR 2
-#define TC_MAIN_COM_VERSION_MINOR 13
+#define TC_MAIN_COM_VERSION_MINOR 14
#define TC_FORMAT_COM_VERSION_MAJOR 2
-#define TC_FORMAT_COM_VERSION_MINOR 10
+#define TC_FORMAT_COM_VERSION_MINOR 11
#include
#include
diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c
index ee5edeaa..0b93ed1c 100644
--- a/src/Setup/Setup.c
+++ b/src/Setup/Setup.c
@@ -1441,6 +1441,8 @@ BOOL DoRegUninstall (HWND hwndDlg, BOOL bRemoveDeprecated)
RegDeleteKeyExW (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", KEY_WOW64_32KEY, 0);
RegDeleteKeyExW (HKEY_CURRENT_USER, L"Software\\VeraCrypt", KEY_WOW64_32KEY, 0);
+ DeleteRegistryKey (HKEY_LOCAL_MACHINE, L"Software\\VeraCrypt\\Diagnostics\\EfiBootLoader");
+ RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\VeraCrypt\\Diagnostics");
RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\VeraCryptVolume\\Shell\\open\\command");
RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\VeraCryptVolume\\Shell\\open");
diff --git a/src/SetupDLL/ComSetup.cpp b/src/SetupDLL/ComSetup.cpp
index 63593443..b316368d 100644
--- a/src/SetupDLL/ComSetup.cpp
+++ b/src/SetupDLL/ComSetup.cpp
@@ -10,11 +10,13 @@
code distribution packages.
*/
+// Keep these in sync with MainCom.idl and FormatCom.idl. MSI unregister targets these
+// exact typelib versions before removing older versions.
#define TC_MAIN_COM_VERSION_MAJOR 2
-#define TC_MAIN_COM_VERSION_MINOR 11
+#define TC_MAIN_COM_VERSION_MINOR 14
#define TC_FORMAT_COM_VERSION_MAJOR 2
-#define TC_FORMAT_COM_VERSION_MINOR 9
+#define TC_FORMAT_COM_VERSION_MINOR 11
#include
#include
@@ -52,9 +54,9 @@ extern "C" BOOL RegisterComServers (wchar_t *modulePath)
UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR, 0, SYS_WIN32);
UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR, 0, SYS_WIN32);
// unregister older versions that may still exist
- for (WORD i = 7; i >= 1; i--)
+ for (WORD i = 9; i >= 1; i--)
UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR-i, 0, SYS_WIN32);
- for (WORD i = 5; i >= 1; i--)
+ for (WORD i = 6; i >= 1; i--)
UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR-i, 0, SYS_WIN32);
CRegObject ro;
@@ -95,9 +97,9 @@ extern "C" BOOL UnregisterComServers (wchar_t *modulePath)
return FALSE;
// unregister older versions that may still exist
- for (WORD i = 7; i >= 1; i--)
+ for (WORD i = 9; i >= 1; i--)
UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR-i, 0, SYS_WIN32);
- for (WORD i = 5; i >= 1; i--)
+ for (WORD i = 6; i >= 1; i--)
UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR-i, 0, SYS_WIN32);
wchar_t module[1024];
diff --git a/src/SetupDLL/Setup.c b/src/SetupDLL/Setup.c
index 23769623..42cf0370 100644
--- a/src/SetupDLL/Setup.c
+++ b/src/SetupDLL/Setup.c
@@ -1730,6 +1730,9 @@ BOOL DoRegUninstall_Dll (MSIHANDLE hInstaller, BOOL bRemoveDeprecated)
RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\VeraCryptVolume");
*/
+ DeleteRegistryKey (HKEY_LOCAL_MACHINE, L"Software\\VeraCrypt\\Diagnostics\\EfiBootLoader");
+ RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\VeraCrypt\\Diagnostics");
+
if (!bRemoveDeprecated)
{
HKEY hKey;