Windows: harden EFI Secure Boot CA fallback

Validate SecureBoot firmware data before trusting fallback selection and mark the unsupported-db helper as noreturn.

Record unsupported Secure Boot db refusals in EFI loader diagnostics, and avoid stale rescue-disk prompts after a refusal.

Reuse the central EFI loader selection policy for elevated signing-support checks instead of duplicating fallback/refusal logic.

Translate unsupported Secure Boot db failures across elevation without duplicate generic dialogs, surface stored-PIM refresh failures, and log unattended loader update failures.
This commit is contained in:
Mounir IDRASSI
2026-06-19 19:32:04 +09:00
parent 8a60f152ab
commit 3650fdfca4
6 changed files with 73 additions and 100 deletions
+22
View File
@@ -13,6 +13,7 @@
#include <atlcomcli.h>
#include <atlconv.h>
#include <comutil.h>
#include <string.h>
#include <windows.h>
#include "BaseCom.h"
#include "BootEncryption.h"
@@ -21,6 +22,11 @@
using namespace VeraCrypt;
static bool IsUnsupportedEfiSecureBootDbException (const ErrorException &e)
{
return e.ErrLangId && strcmp (e.ErrLangId, "SYSENC_EFI_UNSUPPORTED_SECUREBOOT_CA") == 0;
}
HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv)
{
WCHAR monikerName[1024];
@@ -318,6 +324,14 @@ DWORD BaseCom::InstallEfiBootLoader (BOOL preserveUserConfig, BOOL hiddenOSCreat
{
return GetLastError();
}
catch (ErrorException &e)
{
if (IsUnsupportedEfiSecureBootDbException (e))
return VC_ERROR_EFI_UNSUPPORTED_SECURE_BOOT_DB;
e.Show (NULL);
return ERROR_EXCEPTION_IN_SERVICE;
}
catch (Exception &e)
{
e.Show (NULL);
@@ -451,6 +465,14 @@ DWORD BaseCom::GetEfiBootLoaderSigningSupport (BOOL* pMicrosoft2023UefiCAsSuppor
{
return GetLastError();
}
catch (ErrorException &e)
{
if (IsUnsupportedEfiSecureBootDbException (e))
return VC_ERROR_EFI_UNSUPPORTED_SECURE_BOOT_DB;
e.Show (NULL);
return ERROR_EXCEPTION_IN_SERVICE;
}
catch (Exception &e)
{
e.Show (NULL);
+34 -95
View File
@@ -585,6 +585,8 @@ namespace VeraCrypt
DWORD result = ElevatedComInstance->InstallEfiBootLoader (preserveUserConfig ? TRUE : FALSE, hiddenOSCreation ? TRUE : FALSE, pim, hashAlg);
if (result != ERROR_SUCCESS)
{
if (result == VC_ERROR_EFI_UNSUPPORTED_SECURE_BOOT_DB)
throw ErrorException ("SYSENC_EFI_UNSUPPORTED_SECUREBOOT_CA", SRC_POS);
SetLastError (result);
throw SystemException(SRC_POS);
}
@@ -662,6 +664,8 @@ namespace VeraCrypt
DWORD result = ElevatedComInstance->GetEfiBootLoaderSigningSupport (pMicrosoft2023UefiCAsSupported);
if (result != ERROR_SUCCESS)
{
if (result == VC_ERROR_EFI_UNSUPPORTED_SECURE_BOOT_DB)
throw ErrorException ("SYSENC_EFI_UNSUPPORTED_SECUREBOOT_CA", SRC_POS);
SetLastError (result);
throw SystemException(SRC_POS);
}
@@ -2823,6 +2827,11 @@ namespace VeraCrypt
systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
WriteLocalMachineRegistryDword ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, (wchar_t *) VC_EFI_BOOT_LOADER_RESOURCE_SET_VALUE_NAME, resourceSet);
if (!resourceSet)
{
WriteLocalMachineRegistryDword ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, (wchar_t *) VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_ID_VALUE_NAME, 0);
WriteLocalMachineRegistryDword ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, (wchar_t *) VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_RESOURCE_SET_VALUE_NAME, 0);
}
WriteLocalMachineRegistryDword ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderFirmwareDbLastError", firmwareDbError);
WriteLocalMachineRegistryString (EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderSelectionReason", selectionReason, FALSE);
WriteLocalMachineRegistryString (EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderSelectionTimeUtc", selectionTimeUtc, FALSE);
@@ -3096,49 +3105,6 @@ namespace VeraCrypt
return true;
}
#ifdef VC_EFI_BOOTLOADER_SELECTION_TEST
static bool FirmwareDbBufferContainsMicrosoft2023UefiCAs (const std::vector<uint8>& db)
{
FirmwareDbMicrosoftUefiCaSupport support;
return FirmwareDbBufferGetMicrosoftUefiCaSupport (db, support) && FirmwareDbMicrosoftUefiCaSupportContains2023Set (support);
}
static bool FirmwareDbBufferContainsMicrosoftCorporationUefiCa2011 (const std::vector<uint8>& db)
{
FirmwareDbMicrosoftUefiCaSupport support;
return FirmwareDbBufferGetMicrosoftUefiCaSupport (db, support) && support.ContainsMicrosoftCorporationUefiCa2011;
}
bool TestFirmwareDbBufferContainsMicrosoft2023UefiCAs (const uint8* db, size_t dbSize)
{
std::vector<uint8> firmwareDb;
if (dbSize != 0)
{
if (!db)
return false;
firmwareDb.assign (db, db + dbSize);
}
return FirmwareDbBufferContainsMicrosoft2023UefiCAs (firmwareDb);
}
// Feed a db captured from a machine that trusts Microsoft Corporation UEFI CA 2011
// (for example the output of PowerShell Get-SecureBootUEFI db) to validate detection
// of the 2011 modulus against real firmware data.
bool TestFirmwareDbBufferContainsMicrosoftCorporationUefiCa2011 (const uint8* db, size_t dbSize)
{
std::vector<uint8> firmwareDb;
if (dbSize != 0)
{
if (!db)
return false;
firmwareDb.assign (db, db + dbSize);
}
return FirmwareDbBufferContainsMicrosoftCorporationUefiCa2011 (firmwareDb);
}
#endif
static bool TryFirmwareDbGetMicrosoftUefiCaSupport (FirmwareDbMicrosoftUefiCaSupport& support)
{
std::vector<uint8> db;
@@ -3175,11 +3141,19 @@ namespace VeraCrypt
return false;
}
bSecureBootEnabled = (secureBoot.size () >= 1) && (secureBoot[0] == 1);
if (secureBoot.size () != 1 || (secureBoot[0] != 0 && secureBoot[0] != 1))
{
if (pLastError)
*pLastError = ERROR_INVALID_DATA;
SetLastError (ERROR_INVALID_DATA);
return false;
}
bSecureBootEnabled = secureBoot[0] == 1;
return true;
}
static void ThrowUnsupportedEfiSecureBootDb (const wchar_t *reason, DWORD firmwareDbError)
static __declspec(noreturn) void ThrowUnsupportedEfiSecureBootDb (const wchar_t *reason, DWORD firmwareDbError)
{
RecordEfiBootLoaderResourceSetSelectionDiagnostics (0, reason, firmwareDbError);
throw ErrorException ("SYSENC_EFI_UNSUPPORTED_SECUREBOOT_CA", SRC_POS);
@@ -3261,7 +3235,8 @@ namespace VeraCrypt
if (!bSecureBootStateKnown && !IsFirmwareDbUnavailableError (secureBootLastError))
ThrowUnsupportedEfiSecureBootDb (L"firmware db and Secure Boot state could not be read; refusing to select an unsupported EFI bootloader signing CA", dwError);
ThrowUnsupportedEfiSecureBootDb (L"firmware db could not be read; refusing to select an unsupported EFI bootloader signing CA", dwError);
// All Secure Boot state cases are handled above.
TC_THROW_FATAL_EXCEPTION;
}
static void ThrowMissingEfiResource (const wchar_t* resourceName, bool rescueDisk)
@@ -6133,54 +6108,7 @@ namespace VeraCrypt
throw SystemException (SRC_POS);
}
FirmwareDbMicrosoftUefiCaSupport support;
if (!TryFirmwareDbGetMicrosoftUefiCaSupport (support))
{
DWORD dwError = GetLastError ();
bool bSecureBootEnabled = false;
bool bSecureBootStateKnown = TryFirmwareSecureBootEnabled (bSecureBootEnabled);
DWORD secureBootLastError = bSecureBootStateKnown ? ERROR_SUCCESS : GetLastError ();
if (bSecureBootStateKnown && bSecureBootEnabled)
ThrowUnsupportedEfiSecureBootDb (L"Secure Boot is enabled but firmware db could not be read; refusing to select an unsupported EFI bootloader signing CA", dwError);
if (!bSecureBootStateKnown && !IsFirmwareDbUnavailableError (secureBootLastError))
ThrowUnsupportedEfiSecureBootDb (L"firmware db and Secure Boot state could not be read; refusing to select an unsupported EFI bootloader signing CA", dwError);
*pMicrosoft2023UefiCAsSupported = FALSE;
return;
}
if (FirmwareDbMicrosoftUefiCaSupportContains2023Set (support))
{
*pMicrosoft2023UefiCAsSupported = TRUE;
return;
}
if (support.ContainsMicrosoftCorporationUefiCa2011)
{
*pMicrosoft2023UefiCAsSupported = FALSE;
return;
}
bool bSecureBootEnabled = false;
bool bSecureBootStateKnown = TryFirmwareSecureBootEnabled (bSecureBootEnabled);
DWORD secureBootLastError = bSecureBootStateKnown ? ERROR_SUCCESS : GetLastError ();
if (bSecureBootStateKnown && !bSecureBootEnabled)
{
*pMicrosoft2023UefiCAsSupported = FALSE;
return;
}
if (!bSecureBootStateKnown && IsFirmwareDbUnavailableError (secureBootLastError))
{
*pMicrosoft2023UefiCAsSupported = FALSE;
return;
}
if (bSecureBootStateKnown)
ThrowUnsupportedEfiSecureBootDb (L"Secure Boot is enabled but firmware db does not contain Microsoft Corporation UEFI CA 2011 or the Microsoft 2023 UEFI CA pair required by VeraCrypt", ERROR_SUCCESS);
ThrowUnsupportedEfiSecureBootDb (L"firmware db does not contain a supported Microsoft UEFI CA and Secure Boot state could not be read; refusing to select an unsupported EFI bootloader signing CA", secureBootLastError);
*pMicrosoft2023UefiCAsSupported = GetPreferredEfiBootLoaderResourceSet ().ResourceSet == VC_EFI_BOOT_LOADER_RESOURCE_SET_2023;
}
#ifndef SETUP
@@ -6581,8 +6509,19 @@ namespace VeraCrypt
if (storedPimUpdateNeeded || !CheckBootloaderFingerprint (true))
InstallBootLoader (device, true, false, pim, cryptoInfo->pkcs5);
}
catch (Exception &e)
{
if (storedPimUpdateNeeded)
{
e.Show (hwndDlg);
result = ERR_OS_ERROR;
}
}
catch (...)
{}
{
if (storedPimUpdateNeeded)
result = ERR_OS_ERROR;
}
CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest));
}
-5
View File
@@ -27,11 +27,6 @@ using namespace std;
namespace VeraCrypt
{
#ifdef VC_EFI_BOOTLOADER_SELECTION_TEST
bool TestFirmwareDbBufferContainsMicrosoft2023UefiCAs (const uint8* db, size_t dbSize);
bool TestFirmwareDbBufferContainsMicrosoftCorporationUefiCa2011 (const uint8* db, size_t dbSize);
#endif
class File
{
public:
+1
View File
@@ -89,6 +89,7 @@ enum
#define VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_ID_VALUE_NAME L"EfiBootLoaderRescueDiskPromptId"
#define VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_RESOURCE_SET_VALUE_NAME L"EfiBootLoaderRescueDiskPromptResourceSet"
#define VC_EFI_BOOT_LOADER_RESCUE_DISK_RESOURCE_SET_VALUE_NAME L"EfiBootLoaderRescueDiskResourceSet"
#define VC_ERROR_EFI_UNSUPPORTED_SECURE_BOOT_DB ((DWORD) 0xE0000201)
#define VC_FILENAME_RENAMED_SUFFIX L"_old"
+10
View File
@@ -10886,8 +10886,13 @@ static void SystemFavoritesServiceUpdateLoaderProcessing (BOOL bForce)
SystemFavoritesServiceLogInfo (L"SystemFavoritesServiceUpdateLoaderProcessing: InstallBootLoader called");
}
}
catch (Exception &)
{
SystemFavoritesServiceLogError (L"SystemFavoritesServiceUpdateLoaderProcessing failed while updating the boot loader.");
}
catch (...)
{
SystemFavoritesServiceLogError (L"SystemFavoritesServiceUpdateLoaderProcessing failed with an unexpected exception while updating the boot loader.");
}
}
}
@@ -11197,8 +11202,13 @@ int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpsz
bootEnc.InstallBootLoader (true);
}
}
catch (Exception &)
{
SystemFavoritesServiceLogError (L"PostOOBE boot loader update failed.");
}
catch (...)
{
SystemFavoritesServiceLogError (L"PostOOBE boot loader update failed with an unexpected exception.");
}
return 0;
}
+6
View File
@@ -1807,6 +1807,12 @@ BOOL UpgradeBootLoader (HWND hwndDlg)
}
return TRUE;
}
catch (ErrorException &e)
{
e.Show (hwndDlg);
if (e.ErrLangId && strcmp (e.ErrLangId, "SYSENC_EFI_UNSUPPORTED_SECUREBOOT_CA") == 0)
return FALSE;
}
catch (Exception &e)
{
e.Show (hwndDlg);