mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-17 10:06:06 -05:00
Windows: notify users after EFI bootloader CA refresh
Record EFI bootloader resource set changes during PostOOBE refreshes and mark a machine-wide rescue disk reminder. Show the reminder on VeraCrypt startup using the existing generic rescue disk prompt and Create Rescue Disk flow.
This commit is contained in:
@@ -2640,7 +2640,7 @@ namespace VeraCrypt
|
||||
IDR_EFI_DCSINFO_2023
|
||||
};
|
||||
|
||||
static const wchar_t *EfiBootLoaderDiagnosticsRegistryKey = L"Software\\VeraCrypt\\Diagnostics\\EfiBootLoader";
|
||||
static const wchar_t *EfiBootLoaderDiagnosticsRegistryKey = VC_EFI_BOOT_LOADER_DIAGNOSTICS_REGISTRY_KEY;
|
||||
|
||||
static bool ReadFirmwareEnvironmentVariableBuffer (const wchar_t* name, const wchar_t* guid, std::vector<uint8>& value, DWORD* pLastError = NULL)
|
||||
{
|
||||
@@ -2732,6 +2732,75 @@ namespace VeraCrypt
|
||||
return selection;
|
||||
}
|
||||
|
||||
static bool ReadRecordedEfiBootLoaderResourceSet (DWORD& resourceSet)
|
||||
{
|
||||
resourceSet = 0;
|
||||
return ReadLocalMachineRegistryDword (
|
||||
(wchar_t *) EfiBootLoaderDiagnosticsRegistryKey,
|
||||
(wchar_t *) VC_EFI_BOOT_LOADER_RESOURCE_SET_VALUE_NAME,
|
||||
&resourceSet) && resourceSet != 0;
|
||||
}
|
||||
|
||||
static DWORD ReadEfiBootLoaderRescueDiskPromptId ()
|
||||
{
|
||||
DWORD promptId = 0;
|
||||
ReadLocalMachineRegistryDword (
|
||||
(wchar_t *) EfiBootLoaderDiagnosticsRegistryKey,
|
||||
(wchar_t *) VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_ID_VALUE_NAME,
|
||||
&promptId);
|
||||
return promptId;
|
||||
}
|
||||
|
||||
static bool WriteEfiBootLoaderDiagnosticsRegistryDword (const wchar_t *valueName, DWORD value)
|
||||
{
|
||||
#ifndef SETUP
|
||||
if (!IsAdmin () && IsUacSupported ())
|
||||
{
|
||||
try
|
||||
{
|
||||
Elevator::WriteLocalMachineRegistryDwordValue ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, (wchar_t *) valueName, value);
|
||||
return true;
|
||||
}
|
||||
catch (...) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return WriteLocalMachineRegistryDword ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, (wchar_t *) valueName, value) ? true : false;
|
||||
}
|
||||
|
||||
static void MarkEfiBootLoaderRescueDiskRecreationNeeded (const EfiBootLoaderImages& images)
|
||||
{
|
||||
if (!images.ResourceSet)
|
||||
return;
|
||||
|
||||
DWORD previousLastError = GetLastError ();
|
||||
DWORD promptId = ReadEfiBootLoaderRescueDiskPromptId () + 1;
|
||||
if (promptId == 0)
|
||||
promptId = 1;
|
||||
|
||||
WriteEfiBootLoaderDiagnosticsRegistryDword (VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_RESOURCE_SET_VALUE_NAME, images.ResourceSet);
|
||||
WriteEfiBootLoaderDiagnosticsRegistryDword (VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_ID_VALUE_NAME, promptId);
|
||||
SetLastError (previousLastError);
|
||||
}
|
||||
|
||||
static void RecordEfiBootLoaderRescueDiskResourceSet (const EfiBootLoaderImages& images)
|
||||
{
|
||||
if (!images.ResourceSet)
|
||||
return;
|
||||
|
||||
DWORD previousLastError = GetLastError ();
|
||||
WriteEfiBootLoaderDiagnosticsRegistryDword (VC_EFI_BOOT_LOADER_RESCUE_DISK_RESOURCE_SET_VALUE_NAME, images.ResourceSet);
|
||||
SetLastError (previousLastError);
|
||||
}
|
||||
|
||||
static void ClearEfiBootLoaderDiagnosticsRegistry ()
|
||||
{
|
||||
DWORD previousLastError = GetLastError ();
|
||||
::DeleteRegistryKey (HKEY_LOCAL_MACHINE, EfiBootLoaderDiagnosticsRegistryKey);
|
||||
SetLastError (previousLastError);
|
||||
}
|
||||
|
||||
static void RecordEfiBootLoaderResourceSetSelection (const EfiBootLoaderImages& images)
|
||||
{
|
||||
if (!images.ResourceSet || !images.SelectionReason)
|
||||
@@ -2744,7 +2813,7 @@ namespace VeraCrypt
|
||||
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, (wchar_t *) VC_EFI_BOOT_LOADER_RESOURCE_SET_VALUE_NAME, images.ResourceSet);
|
||||
WriteLocalMachineRegistryDword ((wchar_t *) EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderFirmwareDbLastError", images.FirmwareDbError);
|
||||
WriteLocalMachineRegistryString (EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderSelectionReason", images.SelectionReason, FALSE);
|
||||
WriteLocalMachineRegistryString (EfiBootLoaderDiagnosticsRegistryKey, L"EfiBootLoaderSelectionTimeUtc", selectionTimeUtc, FALSE);
|
||||
@@ -3003,18 +3072,18 @@ namespace VeraCrypt
|
||||
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 (EfiBootLoaderResources2023, VC_EFI_BOOT_LOADER_RESOURCE_SET_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);
|
||||
return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, VC_EFI_BOOT_LOADER_RESOURCE_SET_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);
|
||||
return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, VC_EFI_BOOT_LOADER_RESOURCE_SET_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);
|
||||
return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, VC_EFI_BOOT_LOADER_RESOURCE_SET_2011, L"Secure Boot is disabled and firmware db could not be read; using 2011 compatibility fallback", dwError);
|
||||
#ifndef SETUP
|
||||
if (!IsAdmin () && IsUacSupported ())
|
||||
{
|
||||
@@ -3024,13 +3093,13 @@ namespace VeraCrypt
|
||||
BOOL bElevatedContainsMicrosoft2023UefiCAs = FALSE;
|
||||
Elevator::GetEfiBootLoaderSigningSupport (&bElevatedContainsMicrosoft2023UefiCAs);
|
||||
if (bElevatedContainsMicrosoft2023UefiCAs)
|
||||
return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2023, 2023, L"elevated helper reported Microsoft 2023 UEFI CA support", dwError);
|
||||
return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2023, VC_EFI_BOOT_LOADER_RESOURCE_SET_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);
|
||||
return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, VC_EFI_BOOT_LOADER_RESOURCE_SET_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);
|
||||
return MakeEfiBootLoaderResourceSelection (EfiBootLoaderResources2011, VC_EFI_BOOT_LOADER_RESOURCE_SET_2011, L"firmware db could not be read; using 2011 compatibility fallback", dwError);
|
||||
}
|
||||
|
||||
static void ThrowMissingEfiResource (const wchar_t* resourceName, bool rescueDisk)
|
||||
@@ -3093,6 +3162,35 @@ namespace VeraCrypt
|
||||
BackupEfiBootLoaderImageIfDifferent (efiBoot, L"\\EFI\\VeraCrypt\\DcsInfo.dcs", L"\\EFI\\VeraCrypt\\DcsInfo.dcs.vc_backup", images.DcsInfo, images.SizeDcsInfo);
|
||||
}
|
||||
|
||||
static bool EfiBootLoaderImageDiffers (EfiBoot& efiBoot, const wchar_t* imageName, uint8* replacementData, DWORD replacementSize)
|
||||
{
|
||||
std::vector<uint8> currentImage;
|
||||
if (!efiBoot.ReadFileToBuffer (imageName, currentImage))
|
||||
return false;
|
||||
|
||||
return (currentImage.size () != replacementSize)
|
||||
|| ((replacementSize != 0) && (memcmp (currentImage.data (), replacementData, replacementSize) != 0));
|
||||
}
|
||||
|
||||
static bool EfiBootLoaderImagesDiffer (EfiBoot& efiBoot, const EfiBootLoaderImages& images)
|
||||
{
|
||||
return EfiBootLoaderImageDiffers (efiBoot, L"\\EFI\\VeraCrypt\\DcsBoot.efi", images.DcsBoot, images.SizeDcsBoot)
|
||||
|| EfiBootLoaderImageDiffers (efiBoot, L"\\EFI\\VeraCrypt\\DcsInt.dcs", images.DcsInt, images.SizeDcsInt)
|
||||
|| EfiBootLoaderImageDiffers (efiBoot, L"\\EFI\\VeraCrypt\\DcsCfg.dcs", images.DcsCfg, images.SizeDcsCfg)
|
||||
|| EfiBootLoaderImageDiffers (efiBoot, L"\\EFI\\VeraCrypt\\LegacySpeaker.dcs", images.LegacySpeaker, images.SizeLegacySpeaker)
|
||||
|| EfiBootLoaderImageDiffers (efiBoot, L"\\EFI\\VeraCrypt\\DcsInfo.dcs", images.DcsInfo, images.SizeDcsInfo);
|
||||
}
|
||||
|
||||
static bool EfiBootLoaderRefreshRequiresRescueDiskPrompt (EfiBoot& efiBoot, const EfiBootLoaderImages& images)
|
||||
{
|
||||
DWORD recordedResourceSet = 0;
|
||||
bool bRecordedResourceSetKnown = ReadRecordedEfiBootLoaderResourceSet (recordedResourceSet);
|
||||
if (bRecordedResourceSetKnown && recordedResourceSet == images.ResourceSet)
|
||||
return false;
|
||||
|
||||
return EfiBootLoaderImagesDiffer (efiBoot, images);
|
||||
}
|
||||
|
||||
static void SaveEfiBootLoaderImages (EfiBoot& efiBoot, const EfiBootLoaderImages& images, bool backupExistingImages = false)
|
||||
{
|
||||
if (backupExistingImages)
|
||||
@@ -4158,6 +4256,7 @@ namespace VeraCrypt
|
||||
const bool bRefreshMsBootloader = !bModifiedMsBoot
|
||||
|| bMissingMsBoot
|
||||
|| (EfiBootInst.FileExists (szStdMsBootloader) && EfiBootInst.IsVeraCryptBootLoader (szStdMsBootloader));
|
||||
const bool bRescueDiskPromptRequired = EfiBootLoaderRefreshRequiresRescueDiskPrompt (EfiBootInst, efiImages);
|
||||
|
||||
// Keep the firmware-visible loader path valid before the larger module refresh.
|
||||
if (bRefreshMsBootloader && !EfiBootInst.FileExists (szStdMsBootloader))
|
||||
@@ -4215,6 +4314,8 @@ namespace VeraCrypt
|
||||
EfiBootInst.CopyFile (L"\\EFI\\VeraCrypt\\DcsBoot.efi", szStdEfiBootloader);
|
||||
}
|
||||
}
|
||||
if (bRescueDiskPromptRequired)
|
||||
MarkEfiBootLoaderRescueDiskRecreationNeeded (efiImages);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -4575,6 +4676,7 @@ namespace VeraCrypt
|
||||
{
|
||||
File isoFile (isoImagePath, false, true);
|
||||
isoFile.Write (RescueZipData, RescueZipSize);
|
||||
RecordEfiBootLoaderRescueDiskResourceSet (efiImages);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -5324,6 +5426,8 @@ namespace VeraCrypt
|
||||
device.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
|
||||
}
|
||||
|
||||
ClearEfiBootLoaderDiagnosticsRegistry ();
|
||||
|
||||
if (!IsAdmin() && IsUacSupported())
|
||||
{
|
||||
Elevator::UpdateSetupConfigFile (false);
|
||||
|
||||
+48
-1
@@ -3739,9 +3739,56 @@ void SavePostInstallTasksSettings (int command)
|
||||
}
|
||||
|
||||
|
||||
static BOOL ReadEfiBootLoaderDiagnosticsDword (const wchar_t *valueName, DWORD *value)
|
||||
{
|
||||
return ReadLocalMachineRegistryDword (
|
||||
(wchar_t *) VC_EFI_BOOT_LOADER_DIAGNOSTICS_REGISTRY_KEY,
|
||||
(wchar_t *) valueName,
|
||||
value);
|
||||
}
|
||||
|
||||
|
||||
static BOOL EfiBootLoaderRescueDiskResourceSetMatches (DWORD resourceSet)
|
||||
{
|
||||
DWORD rescueDiskResourceSet = 0;
|
||||
|
||||
return resourceSet != 0
|
||||
&& ReadEfiBootLoaderDiagnosticsDword (VC_EFI_BOOT_LOADER_RESCUE_DISK_RESOURCE_SET_VALUE_NAME, &rescueDiskResourceSet)
|
||||
&& rescueDiskResourceSet == resourceSet;
|
||||
}
|
||||
|
||||
|
||||
static BOOL IsEfiBootLoaderRescueDiskPromptPending (void)
|
||||
{
|
||||
DWORD promptId = 0;
|
||||
DWORD recordedResourceSet = 0;
|
||||
DWORD promptResourceSet = 0;
|
||||
|
||||
if (ReadEfiBootLoaderDiagnosticsDword (VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_ID_VALUE_NAME, &promptId) && promptId != 0)
|
||||
{
|
||||
if (!ReadEfiBootLoaderDiagnosticsDword (VC_EFI_BOOT_LOADER_RESCUE_DISK_PROMPT_RESOURCE_SET_VALUE_NAME, &promptResourceSet))
|
||||
{
|
||||
if (!ReadEfiBootLoaderDiagnosticsDword (VC_EFI_BOOT_LOADER_RESOURCE_SET_VALUE_NAME, &promptResourceSet))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return !EfiBootLoaderRescueDiskResourceSetMatches (promptResourceSet);
|
||||
}
|
||||
|
||||
if (ReadEfiBootLoaderDiagnosticsDword (VC_EFI_BOOT_LOADER_RESOURCE_SET_VALUE_NAME, &recordedResourceSet)
|
||||
&& recordedResourceSet == VC_EFI_BOOT_LOADER_RESOURCE_SET_2023)
|
||||
{
|
||||
return !EfiBootLoaderRescueDiskResourceSetMatches (recordedResourceSet);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void DoPostInstallTasks (HWND hwndDlg)
|
||||
{
|
||||
BOOL bDone = FALSE;
|
||||
BOOL bEfiBootLoaderRescueDiskPromptPending = IsEfiBootLoaderRescueDiskPromptPending ();
|
||||
|
||||
if (FileExists (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL)))
|
||||
{
|
||||
@@ -3759,7 +3806,7 @@ void DoPostInstallTasks (HWND hwndDlg)
|
||||
bDone = TRUE;
|
||||
}
|
||||
|
||||
if (FileExists (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_RESCUE_DISK)))
|
||||
if (FileExists (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_RESCUE_DISK)) || bEfiBootLoaderRescueDiskPromptPending)
|
||||
{
|
||||
if (AskYesNo ("AFTER_UPGRADE_RESCUE_DISK", hwndDlg) == IDYES)
|
||||
PostMessage (hwndDlg, VC_APPMSG_CREATE_RESCUE_DISK, 0, 0);
|
||||
|
||||
@@ -82,6 +82,14 @@ enum
|
||||
#define TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES L"Post-Install Task - Release Notes"
|
||||
#define TC_APPD_FILENAME_POST_INSTALL_TASK_RESCUE_DISK L"Post-Install Task - Rescue Disk"
|
||||
|
||||
#define VC_EFI_BOOT_LOADER_DIAGNOSTICS_REGISTRY_KEY L"Software\\VeraCrypt\\Diagnostics\\EfiBootLoader"
|
||||
#define VC_EFI_BOOT_LOADER_RESOURCE_SET_2011 2011
|
||||
#define VC_EFI_BOOT_LOADER_RESOURCE_SET_2023 2023
|
||||
#define VC_EFI_BOOT_LOADER_RESOURCE_SET_VALUE_NAME L"EfiBootLoaderResourceSet"
|
||||
#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_FILENAME_RENAMED_SUFFIX L"_old"
|
||||
|
||||
/* customer service control code to build device list */
|
||||
|
||||
Reference in New Issue
Block a user