diff --git a/src/Common/BaseCom.cpp b/src/Common/BaseCom.cpp index cf418c68..7b510614 100644 --- a/src/Common/BaseCom.cpp +++ b/src/Common/BaseCom.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #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); diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index 03899414..cee921dc 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -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& db) - { - FirmwareDbMicrosoftUefiCaSupport support; - return FirmwareDbBufferGetMicrosoftUefiCaSupport (db, support) && FirmwareDbMicrosoftUefiCaSupportContains2023Set (support); - } - - static bool FirmwareDbBufferContainsMicrosoftCorporationUefiCa2011 (const std::vector& db) - { - FirmwareDbMicrosoftUefiCaSupport support; - return FirmwareDbBufferGetMicrosoftUefiCaSupport (db, support) && support.ContainsMicrosoftCorporationUefiCa2011; - } - - 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); - } - - // 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 firmwareDb; - if (dbSize != 0) - { - if (!db) - return false; - firmwareDb.assign (db, db + dbSize); - } - - return FirmwareDbBufferContainsMicrosoftCorporationUefiCa2011 (firmwareDb); - } -#endif - static bool TryFirmwareDbGetMicrosoftUefiCaSupport (FirmwareDbMicrosoftUefiCaSupport& support) { std::vector 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)); } diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index 3d9cde00..2611dc1b 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -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: diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index eef51754..a3b756e5 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -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" diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index ef68e072..287a3032 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -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; } diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c index ccfe4252..dde0f602 100644 --- a/src/Setup/Setup.c +++ b/src/Setup/Setup.c @@ -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);