diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.c b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.c index e50f9f2192..d4df2a138f 100644 --- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.c +++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.c @@ -11,9 +11,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *mPrivateData = NULL; BOOLEAN mBootloadersInitted = FALSE; -STATIC CHAR16 mSvBootDataVarName[] = L"SvBootData"; +STATIC CHAR16 mSvBootDataVarName[] = SV_BOOT_DATA_VAR; STATIC CHAR16 mVarStoreName[] = L"SvBootFormData"; -STATIC CHAR16 mSvBootConfigVarName[] = L"SvBootConfig"; +STATIC CHAR16 mSvBootConfigVarName[] = SV_BOOT_CONFIG_VAR; STATIC BOOLEAN mBootloadersShown = FALSE; @@ -457,6 +457,7 @@ SovereignBootWizardInit ( EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText; CHAR16 *NewString; EFI_HANDLE AppHandle; + EFI_FORM_ID FormId; NewString = NULL; AppHandle = NULL; @@ -630,9 +631,9 @@ SovereignBootWizardInit ( ConfigData->AppLaunchCause = SV_BOOT_LAUNCH_BOOT_WITH_DEFAULT_SETTINGS; } } else { - // If not provisioned, the launch cause can only be undefined or boot with defaults + // If not provisioned, the launch cause can not be verification failure if (!SvConfig->SvBootProvisioned && - ConfigData->AppLaunchCause >= SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED) + ConfigData->AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED) { ConfigData->AppLaunchCause = SV_BOOT_LAUNCH_BOOT_WITH_DEFAULT_SETTINGS; } @@ -643,6 +644,31 @@ SovereignBootWizardInit ( ConfigData->AppLaunchCause = SV_BOOT_LAUNCH_BOOT_WITH_DEFAULT_SETTINGS; } + switch (ConfigData->AppLaunchCause) { + case SV_BOOT_LAUNCH_BOOT_WITH_DEFAULT_SETTINGS: + NewString = HiiGetString(HiiHandle, STRING_TOKEN (STR_LAUNCH_CAUSE_DEFAULT_SETTINGS), NULL); + break; + case SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED: + // Override the "do not trust key" to avoid displaying "next bootloader" + NewString = HiiGetString(HiiHandle, STRING_TOKEN (STR_DO_NOT_TRUST_KEY2), NULL); + if (NewString != NULL) { + HiiSetString(HiiHandle, STRING_TOKEN (STR_DO_NOT_TRUST_KEY), NewString, NULL); + } + + NewString = HiiGetString(HiiHandle, STRING_TOKEN (STR_LAUNCH_CAUSE_VERIFICATION_FAILED), NULL); + break; + case SV_BOOT_LAUNCH_VIA_SETUP: + NewString = HiiGetString(HiiHandle, STRING_TOKEN (STR_LAUNCH_CAUSE_SETUP), NULL); + break; + default: + NewString = NULL; + break; + } + + if (NewString != NULL) { + HiiSetString(HiiHandle, STRING_TOKEN (STR_LAUNCH_REASON), NewString, NULL); + } + // // Override Hotkeys, F9 and F10 won't be needed by this application // @@ -655,6 +681,16 @@ SovereignBootWizardInit ( FormBrowserEx2->RegisterHotKey (&HotKey, 0, 0, NULL); } + if (SvConfig->SvBootProvisioned) { + if (ConfigData->AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED) { + FormId = SOVEREIGN_BOOT_WIZARD_CONFIG_FORM_ID; + } else { + FormId = SOVEREIGN_BOOT_WIZARD_INTERACTIVE_MODE_FORM_ID; + } + } else { + FormId = SOVEREIGN_BOOT_WIZARD_WELCOME_FORM_ID; + } + // // turn off the watchdog timer // @@ -666,9 +702,7 @@ SovereignBootWizardInit ( &HiiHandle, 1, &gSovereignBootWizardFormSetGuid, - SvConfig->SvBootProvisioned ? - SOVEREIGN_BOOT_WIZARD_INTERACTIVE_MODE_FORM_ID : - SOVEREIGN_BOOT_WIZARD_WELCOME_FORM_ID, + FormId, NULL, NULL ); diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.h b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.h index 9bd5f79ee1..4b69ea7046 100644 --- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.h +++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.h @@ -15,8 +15,8 @@ Revision History **/ -#ifndef _DRIVER_SAMPLE_H_ -#define _DRIVER_SAMPLE_H_ +#ifndef _SV_BOOT_WIZARD_H_ +#define _SV_BOOT_WIZARD_H_ #include diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardHii.h b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardHii.h index 1d00d147ee..f5b82fd765 100644 --- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardHii.h +++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardHii.h @@ -21,27 +21,11 @@ Revision History: #include #include +#include #include #define SOVEREIGN_BOOT_WIZARD_FORM_DATA_VARSTORE_ID 0x0001 -#define SOVEREIGN_BOOT_WIZARD_FORMSET_GUID \ - { \ - 0xB57031B9, 0x1ABB, 0x45F8, {0xA9, 0xCB, 0xAC, 0x5A, 0xAD, 0x72, 0xAD, 0x31} \ - } - -// Application launch causes. Determine the logic and screens showed -// when the application is launched. -// We want different screens and messages when: -// 1. SV Boot is proviosioned by image fails to verify. -// 2. SV Boot is not yet provisioned or platform booting with default settings. -// 3. Application is launched from setup -#define SV_BOOT_LAUNCH_UNDEFINED 0 -#define SV_BOOT_LAUNCH_BOOT_WITH_DEFAULT_SETTINGS 1 -#define SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED 2 -#define SV_BOOT_LAUNCH_VIA_SETUP 3 -#define SV_BOOT_LAUNCH_MAX 4 - #define SOVEREIGN_BOOT_WIZARD_WELCOME_FORM_ID 1 #define SOVEREIGN_BOOT_WIZARD_CONFIG_FORM_ID 2 #define SOVEREIGN_BOOT_WIZARD_MS_SECURE_BOOT_FORM_ID 3 @@ -68,20 +52,9 @@ Revision History: #define EXIT_FORM3_QUESTION_ID 0x1F03 #define EXIT_FORM9_QUESTION_ID 0x1F09 -extern EFI_GUID gSovereignBootWizardFormSetGuid; #pragma pack(1) -// Data passed from firmware via EFI variables (volatile, BS access) -typedef struct { - UINT8 AppLaunchCause; -} SOVEREIGN_BOOT_WIZARD_CONFIG_DATA; - -// State of SV Boot in EFI variables (non-volatile, BS access) -typedef struct { - BOOLEAN SvBootProvisioned; -} SOVEREIGN_BOOT_WIZARD_NV_CONFIG; - // Form Data typedef struct { UINT8 Unused; diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfr.vfr b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfr.vfr index 487b676f52..e9c65e1f87 100644 --- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfr.vfr +++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfr.vfr @@ -43,6 +43,9 @@ formset title = STRING_TOKEN(STR_FORM1_TITLE); subtitle text = STRING_TOKEN(STR_WELCOME_SUBTITLE); + subtitle text = STRING_TOKEN(STR_EMPTY_STRING); + subtitle text = STRING_TOKEN(STR_LAUNCH_REASON); + subtitle text = STRING_TOKEN(STR_WELCOME_PROMPT); // Empty text field so that none of the options are // highlighted/selected by default. @@ -92,8 +95,13 @@ formset form formid = SOVEREIGN_BOOT_WIZARD_CONFIG_FORM_ID, title = STRING_TOKEN(STR_FORM2_TITLE); + disableif ideqval SvBootData.AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED; subtitle text = STRING_TOKEN(STR_CONFIG_SUBTITLE); subtitle text = STRING_TOKEN(STR_EMPTY_STRING); + endif; + disableif NOT ideqval SvBootData.AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED; + subtitle text = STRING_TOKEN(STR_LAUNCH_REASON); + endif; subtitle text = STRING_TOKEN(STR_BOOTOPT_DESCRIPTION); subtitle text = STRING_TOKEN(STR_HW_PATH); @@ -118,11 +126,13 @@ formset flags = INTERACTIVE, key = TRUST_KEY_AND_BOOT_FORM2_QUESTION_ID; + disableif ideqval SvBootData.AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED; text help = STRING_TOKEN(STR_EMPTY_STRING), text = STRING_TOKEN(STR_TRUST_KEY), flags = INTERACTIVE, key = TRUST_KEY_FORM2_QUESTION_ID; + endif; text help = STRING_TOKEN(STR_EMPTY_STRING), @@ -153,8 +163,8 @@ formset title = STRING_TOKEN(STR_FORM9_TITLE); subtitle text = STRING_TOKEN(STR_INTERACTIVE_MODE_SUBTITLE); - subtitle text = STRING_TOKEN(STR_EMPTY_STRING); + subtitle text = STRING_TOKEN(STR_LAUNCH_REASON); text help = STRING_TOKEN(STR_EMPTY_STRING), diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfrStrings.uni b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfrStrings.uni index 2e2b8f8e13..a1700eb372 100644 --- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfrStrings.uni +++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfrStrings.uni @@ -28,10 +28,19 @@ #string FUNCTION_NINE_STRING #language en-US "F9=Reset to Defaults" #string FUNCTION_TEN_STRING #language en-US "F10=Save" + +// Application launch causes +#string STR_LAUNCH_REASON #language en-US "\n" +#string STR_LAUNCH_CAUSE_DEFAULT_SETTINGS #language en-US "You see this window because you are booting for the first time or restored default system settings.\n\n" +#string STR_LAUNCH_CAUSE_SETUP #language en-US "You see this window because you have explicitly requested to launch the Wizard via system setup.\n" + "If you ended up here by mistake, please exit the application to avoid making changes to your system configuration.\n\n" +#string STR_LAUNCH_CAUSE_VERIFICATION_FAILED #language en-US "You see this window because the system attempted to boot an untrusted image.\n\n" + // Welcome page strings #string STR_FORM1_TITLE #language en-US "Sovereign Boot Provisioning Wizard" -#string STR_WELCOME_SUBTITLE #language en-US "Welcome to Sovereign Boot Provisioning Wizard!\n\n" - "Please select the UEFI Secure Boot scheme you would like to use:" +#string STR_WELCOME_SUBTITLE #language en-US "Welcome to Sovereign Boot Provisioning Wizard!\n" +#string STR_WELCOME_PROMPT #language en-US "The Wizard will assist in setting up the UEFI Secure Boot feature. " + "Please select the UEFI Secure Boot scheme you would like to use:\n" #string STR_SELECT_SOVEREIGN_BOOT #language en-US "Sovereign Boot" #string STR_SELECT_SOVEREIGN_BOOT_HELP #language en-US "" @@ -42,12 +51,12 @@ #string STR_SELECT_DEFAULT_SECURE_BOOT_HELP #language en-US "" #string STR_MS_SECURE_BOOT_FEATURES #language en-US "* Trust firmware's default certificates\n" "* Compatible with common operating systems\n" - "* Does not modify current Secure Boot settings" + "* Enrolls firmware's default Secure Boot keys" // Configuration page strings #string STR_FORM2_TITLE #language en-US "Sovereign Boot Provisioning Wizard" -#string STR_CONFIG_SUBTITLE #language en-US "A new bootloader key has been detected." +#string STR_CONFIG_SUBTITLE #language en-US "A new bootloader/key has been detected." #string STR_BOOTOPT_DESCRIPTION #language en-US "Description: " #string STR_HW_PATH #language en-US "Hardware path: " @@ -57,8 +66,9 @@ #string STR_TRUST_QUESTION #language en-US "Do you want to trust this key/image and continue booting?" #string STR_DO_NOT_TRUST_KEY #language en-US "[Do NOT trust, next key/bootloader]" -#string STR_TRUST_KEY_AND_BOOT #language en-US "[Trust this key and boot]" -#string STR_TRUST_KEY #language en-US "[Trust this key, next key/bootloader]" +#string STR_DO_NOT_TRUST_KEY2 #language en-US "[Do NOT trust]" +#string STR_TRUST_KEY_AND_BOOT #language en-US "[Trust this key/image and boot]" +#string STR_TRUST_KEY #language en-US "[Trust this key/image, next key/bootloader]" #string STR_SHOW_KEY_DETAILS #language en-US "[Show key/certificate details]" // Interactive mode strings diff --git a/DasharoModulePkg/DasharoModulePkg.dec b/DasharoModulePkg/DasharoModulePkg.dec index dd4d79b301..b5b89d0671 100644 --- a/DasharoModulePkg/DasharoModulePkg.dec +++ b/DasharoModulePkg/DasharoModulePkg.dec @@ -89,6 +89,8 @@ gDasharoSystemFeaturesTokenSpaceGuid.PcdIntelMeMenuShowCbntStatus|FALSE|BOOLEAN|0x00000002E gDasharoSystemFeaturesTokenSpaceGuid.PcdShowMemorySpdProfileOption|FALSE|BOOLEAN|0x00000002F gDasharoSystemFeaturesTokenSpaceGuid.PcdShowMemoryIbeccOption|FALSE|BOOLEAN|0x000000030 + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled|FALSE|BOOLEAN|0x000000031 + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState|FALSE|BOOLEAN|0x000000032 [PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx] ## Indicate whether the password is cleared. diff --git a/DasharoModulePkg/Include/DasharoOptions.h b/DasharoModulePkg/Include/DasharoOptions.h index 3ad5e34056..db4866b6d5 100644 --- a/DasharoModulePkg/Include/DasharoOptions.h +++ b/DasharoModulePkg/Include/DasharoOptions.h @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef _DASHARO_OPTIONS_H_ #define _DASHARO_OPTIONS_H_ +#include + // // Names of Dasharo-specific EFI variables in DasharoSystemFeaturesGuid // namespace. @@ -124,6 +126,8 @@ typedef union { DASHARO_WATCHDOG_CONFIG Watchdog; DASHARO_IOMMU_CONFIG Iommu; DASHARO_BATTERY_CONFIG Battery; + + SOVEREIGN_BOOT_WIZARD_NV_CONFIG SvBoot; } DASHARO_VAR_DATA; #endif diff --git a/DasharoModulePkg/Include/Guid/SovereignBoot.h b/DasharoModulePkg/Include/Guid/SovereignBoot.h new file mode 100644 index 0000000000..e3c2d5b4e3 --- /dev/null +++ b/DasharoModulePkg/Include/Guid/SovereignBoot.h @@ -0,0 +1,48 @@ +/** @file + +Copyright (c) 2025, 3mdeb Sp. z o.o. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SOVEREIGN_BOOT_H_ +#define SOVEREIGN_BOOT_H_ + +#define SOVEREIGN_BOOT_WIZARD_FORMSET_GUID \ + { \ + 0xB57031B9, 0x1ABB, 0x45F8, {0xA9, 0xCB, 0xAC, 0x5A, 0xAD, 0x72, 0xAD, 0x31} \ + } + +#define SV_BOOT_DATA_VAR L"SvBootData" +#define SV_BOOT_CONFIG_VAR L"SvBootConfig" + +// Application launch causes. Determine the logic and screens showed +// when the application is launched. +// We want different screens and messages when: +// 1. SV Boot is proviosioned by image fails to verify. +// 2. SV Boot is not yet provisioned or platform booting with default settings. +// 3. Application is launched from setup +#define SV_BOOT_LAUNCH_UNDEFINED 0 +#define SV_BOOT_LAUNCH_BOOT_WITH_DEFAULT_SETTINGS 1 +#define SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED 2 +#define SV_BOOT_LAUNCH_VIA_SETUP 3 +#define SV_BOOT_LAUNCH_MAX 4 + +extern EFI_GUID gSovereignBootWizardFormSetGuid; + +#pragma pack(1) + +// Data passed from firmware via EFI variables (volatile, BS access) +typedef struct { + UINT8 AppLaunchCause; +} SOVEREIGN_BOOT_WIZARD_CONFIG_DATA; + +// State of SV Boot in EFI variables (non-volatile, BS access) +typedef struct { + BOOLEAN SvBootEnabled; + BOOLEAN SvBootProvisioned; +} SOVEREIGN_BOOT_WIZARD_NV_CONFIG; + +#pragma pack() + +#endif diff --git a/DasharoModulePkg/Library/DasharoVariablesLib/DasharoVariablesLib.c b/DasharoModulePkg/Library/DasharoVariablesLib/DasharoVariablesLib.c index 9a00b79208..15398edf03 100644 --- a/DasharoModulePkg/Library/DasharoVariablesLib/DasharoVariablesLib.c +++ b/DasharoModulePkg/Library/DasharoVariablesLib/DasharoVariablesLib.c @@ -31,7 +31,8 @@ typedef struct { DASHARO_VAR_DATA Data; // Value for the variable. UINTN Size; // Number of bytes of Data actually used. - UINT32 Attributes; // EFI variable attributes for this variable. + UINT32 Attributes; // EFI variable attributes for this variable. + EFI_GUID *Guid; // GUID for this variable } VAR_INFO; typedef struct { @@ -75,6 +76,9 @@ STATIC CONST AUTO_VARIABLE mAutoCreatedVariables[] = { { DASHARO_VAR_FAST_BOOT, FixedPcdGetBool (PcdFastBootFeatureEnabled) }, { DASHARO_VAR_USB_PORT_POWER, FixedPcdGetBool (PcdShowPowerMenu) && FixedPcdGetBool (PcdPowerMenuShowUsbPowerOption) }, { DASHARO_VAR_DGPU_STATE, FixedPcdGetBool (PcdShowPowerMenu) && FixedPcdGetBool (PcdPowerMenuShowDGPUPowerOption) }, + { DASHARO_VAR_USB_PORT_POWER, FixedPcdGetBool (PcdShowPowerMenu) && FixedPcdGetBool (PcdPowerMenuShowUsbPowerOption) }, + { DASHARO_VAR_DGPU_STATE, FixedPcdGetBool (PcdShowPowerMenu) && FixedPcdGetBool (PcdPowerMenuShowDGPUPowerOption) }, + { SV_BOOT_CONFIG_VAR, FixedPcdGetBool (PcdSovereignBootEnabled) }, }; /** @@ -94,10 +98,12 @@ GetVariableInfo ( DASHARO_VAR_DATA Data; UINTN Size; UINT32 ExtraAttrs; + EFI_GUID *VarGuid; SetMem (&Data, sizeof (Data), 0); Size = 0; ExtraAttrs = 0; + VarGuid = &gDasharoSystemFeaturesGuid; if (StrCmp (VarName, DASHARO_VAR_BATTERY_CONFIG) == 0) { Data.Battery.StartThreshold = 95; @@ -201,6 +207,11 @@ GetVariableInfo ( } else if (StrCmp (VarName, DASHARO_VAR_DGPU_STATE) == 0) { Data.Uint8 = DASHARO_DGPU_ENABLED; Size = sizeof (Data.Uint8); + } else if (StrCmp (VarName, SV_BOOT_CONFIG_VAR) == 0) { + Data.SvBoot.SvBootEnabled = FixedPcdGetBool (PcdSovereignBootDefaultState); + Data.SvBoot.SvBootProvisioned = FALSE; + Size = sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG); + VarGuid = &gSovereignBootWizardFormSetGuid; } else { DEBUG ((EFI_D_ERROR, "%a(): Unknown variable: %s.\n", __FUNCTION__, VarName)); ASSERT ((0 && "No default value set for a variable.")); @@ -209,6 +220,7 @@ GetVariableInfo ( Value.Data = Data; Value.Size = Size; Value.Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE | ExtraAttrs; + Value.Guid = VarGuid; return Value; } @@ -267,7 +279,7 @@ ResetVariable ( Status = gRT->SetVariable ( VarName, - &gDasharoSystemFeaturesGuid, + VarInfo.Guid, VarInfo.Attributes, VarInfo.Size, &VarInfo.Data @@ -286,16 +298,19 @@ ResetVariable ( STATIC VOID InitVariable ( - CHAR16 *VarName + CHAR16 *VarName ) { EFI_STATUS Status; UINTN BufferSize; + VAR_INFO VarInfo; + + VarInfo = GetVariableInfo (VarName); BufferSize = 0; Status = gRT->GetVariable ( VarName, - &gDasharoSystemFeaturesGuid, + VarInfo.Guid, NULL, &BufferSize, NULL @@ -511,8 +526,8 @@ DasharoMeasureVariables ( EFI_STATUS Status; Status = MeasureVariables (&gDasharoSystemFeaturesGuid); - if (Status == EFI_SUCCESS) - Status = MeasureVariables (&gApuConfigurationFormsetGuid); + Status |= MeasureVariables (&gApuConfigurationFormsetGuid); + Status |= MeasureVariables (&gSovereignBootWizardFormSetGuid); return Status; } diff --git a/DasharoModulePkg/Library/DasharoVariablesLib/DasharoVariablesLib.inf b/DasharoModulePkg/Library/DasharoVariablesLib/DasharoVariablesLib.inf index 5668a0d78d..01785a9b94 100644 --- a/DasharoModulePkg/Library/DasharoVariablesLib/DasharoVariablesLib.inf +++ b/DasharoModulePkg/Library/DasharoVariablesLib/DasharoVariablesLib.inf @@ -41,6 +41,7 @@ [Guids] gDasharoSystemFeaturesGuid ### CONSUMES gApuConfigurationFormsetGuid ### SOMETIMES CONSUMES + gSovereignBootWizardFormSetGuid ### SOMETIMES CONSUMES [Pcd] gDasharoSystemFeaturesTokenSpaceGuid.PcdShowMenu @@ -87,6 +88,8 @@ gDasharoSystemFeaturesTokenSpaceGuid.PcdDgpuOnlyAvailable gDasharoSystemFeaturesTokenSpaceGuid.PcdShowMemorySpdProfileOption gDasharoSystemFeaturesTokenSpaceGuid.PcdShowMemoryIbeccOption + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState gEfiMdePkgTokenSpaceGuid.PcdFastBootFeatureEnabled gEfiMdePkgTokenSpaceGuid.PcdQuietBootFeatureEnabled gDasharoPayloadPkgTokenSpaceGuid.PcdLoadOptionRoms diff --git a/DasharoPayloadPkg/DasharoPayloadPkg.dsc b/DasharoPayloadPkg/DasharoPayloadPkg.dsc index 32fa19fc93..ef12d87fa5 100644 --- a/DasharoPayloadPkg/DasharoPayloadPkg.dsc +++ b/DasharoPayloadPkg/DasharoPayloadPkg.dsc @@ -116,6 +116,7 @@ DEFINE CAPSULE_SUPPORT = FALSE DEFINE CAPSULE_MAIN_FW_GUID = DEFINE GRAPHICAL_CAPSULE_PROGRESS = TRUE + DEFINE SOVEREIGN_BOOT_ENABLE = FALSE # # Network definition @@ -536,6 +537,11 @@ gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultEnable|0 !endif +!if $(SECURE_BOOT_ENABLE) == TRUE + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled|$(SOVEREIGN_BOOT_ENABLE) + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState|TRUE +!endif + !if $(SOURCE_DEBUG_ENABLE) gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2 !endif @@ -762,6 +768,9 @@ SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.inf SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf +!if $(SOVEREIGN_BOOT_ENABLE) == TRUE + DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf +!endif !endif !if $(SETUP_PASSWORD_ENABLE) == TRUE diff --git a/DasharoPayloadPkg/DasharoPayloadPkg.fdf b/DasharoPayloadPkg/DasharoPayloadPkg.fdf index e8744e62af..c289d8e664 100644 --- a/DasharoPayloadPkg/DasharoPayloadPkg.fdf +++ b/DasharoPayloadPkg/DasharoPayloadPkg.fdf @@ -270,6 +270,9 @@ INF SecurityPkg/Pkcs7Verify/Pkcs7VerifyDxe/Pkcs7VerifyDxe.inf INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf INF SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.inf INF SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf +!if $(SOVEREIGN_BOOT_ENABLE) == TRUE + INF DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf +!endif # gDefaultKEKFileGuid FILE FREEFORM = 6F64916E-9F7A-4C35-B952-CD041EFB05A3 { diff --git a/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c index cdef03cbb3..8220e18403 100644 --- a/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c +++ b/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c @@ -190,7 +190,7 @@ SyncFvBootOption ( } EFI_DEVICE_PATH * -FvFilePath ( +BdsFvFilePath ( EFI_GUID *FileGuid ) { @@ -229,7 +229,7 @@ RegisterBootManagerMenuAppBootOption ( EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN OptionNumber; - DevicePath = FvFilePath (&mBootMenuFile); + DevicePath = BdsFvFilePath (&mBootMenuFile); // Use LOAD_OPTION_HIDDEN to not display Boot Manager Menu App in // "One Time Boot" menu. Status = EfiBootManagerInitializeLoadOption ( @@ -274,7 +274,7 @@ UnregisterBootManagerMenuAppBootOption ( INTN OptionIndex; EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; - DevicePath = FvFilePath (&mBootMenuFile); + DevicePath = BdsFvFilePath (&mBootMenuFile); // Use LOAD_OPTION_HIDDEN to not display Boot Manager Menu App in // "One Time Boot" menu. Status = EfiBootManagerInitializeLoadOption ( @@ -1580,17 +1580,18 @@ PlatformBootManagerAfterConsole ( VOID ) { - EFI_STATUS Status; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL White; - CHAR16 *BootMenuKey; - CHAR16 *SetupMenuKey; - BOOLEAN NetBootEnabled; - BOOLEAN FUMEnabled; - BOOLEAN BootMenuEnable; - UINTN VarSize; - EFI_EVENT Event; - EFI_INPUT_KEY Enter; + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL White; + CHAR16 *BootMenuKey; + CHAR16 *SetupMenuKey; + BOOLEAN NetBootEnabled; + BOOLEAN FUMEnabled; + BOOLEAN BootMenuEnable; + UINTN VarSize; + EFI_EVENT Event; + EFI_INPUT_KEY Enter; + SOVEREIGN_BOOT_WIZARD_NV_CONFIG SvBootConfig; Black.Blue = Black.Green = Black.Red = Black.Reserved = 0; White.Blue = White.Green = White.Red = White.Reserved = 0xFF; @@ -1733,9 +1734,32 @@ PlatformBootManagerAfterConsole ( &BootMenuEnable ); + if (FixedPcdGetBool (PcdSovereignBootEnabled)) { + VarSize = sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG); + Status = gRT->GetVariable ( + SV_BOOT_CONFIG_VAR, + &gSovereignBootWizardFormSetGuid, + NULL, + &VarSize, + (VOID *)&SvBootConfig + ); + + if (EFI_ERROR (Status)) { + SvBootConfig.SvBootEnabled = FixedPcdGetBool (PcdSovereignBootDefaultState); + SvBootConfig.SvBootProvisioned = FALSE; + } + } else { + SvBootConfig.SvBootEnabled = FALSE; + SvBootConfig.SvBootProvisioned = FALSE; + } + // Print the prompt and SOL strings only if Quiet Boot and Fast Boot are disabled. // Do not refresh the logo, it should stay intact. - if (!mFastBoot && !mQuietBoot) { + // Don't print the hotkeys if SvBoot is enabled but not yet + // provisioned. We won't be able to use the hotkeys anyways in that case.^M + if (!mFastBoot && !mQuietBoot && + (!SvBootConfig.SvBootEnabled || + (SvBootConfig.SvBootEnabled && SvBootConfig.SvBootProvisioned))) { if (PcdGetBool (PcdPrintSolStrings)) PrintSolStrings(); diff --git a/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h b/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h index 9b181b8fd9..0ec80863e4 100644 --- a/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h +++ b/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h @@ -14,6 +14,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#include + #include #include #include diff --git a/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf index 076ae6eb11..ad17e237ca 100644 --- a/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf +++ b/DasharoPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -73,6 +73,7 @@ gEdkiiSCOTermGuid gEfiPcAnsiGuid gDasharoSystemFeaturesGuid + gSovereignBootWizardFormSetGuid [Protocols] gEfiGenericMemTestProtocolGuid ## CONSUMES @@ -112,3 +113,5 @@ gDasharoSystemFeaturesTokenSpaceGuid.PcdSerialRedirectionDefaultState gDasharoSystemFeaturesTokenSpaceGuid.PcdSerialRedirection2DefaultState gDasharoSystemFeaturesTokenSpaceGuid.PcdHave2ndUart + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState diff --git a/MdeModulePkg/Include/Library/UefiBootManagerLib.h b/MdeModulePkg/Include/Library/UefiBootManagerLib.h index 34e217707e..aac2bb4693 100644 --- a/MdeModulePkg/Include/Library/UefiBootManagerLib.h +++ b/MdeModulePkg/Include/Library/UefiBootManagerLib.h @@ -813,4 +813,17 @@ EfiBootManagerDispatchDeferredImages ( VOID ); +/** + Launch Sovereign Boot Wizard + + @param AppLaunchCause The reason why wizard is beign launched. + + @retval EFI_SUCCESS The wizard successfully loaded and executed, + @retval Others The wizard not found or faield to launch. +**/ +EFI_STATUS +EfiBootManagerLaunchSovereignBootWizard ( + UINT8 AppLaunchCause + ); + #endif diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c index e4559413c7..b11dd4e220 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c @@ -1821,6 +1821,126 @@ BmReportLoadFailure ( ); } +EFI_DEVICE_PATH * +FvFilePath ( + EFI_GUID *FileGuid + ) +{ + + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + + Status = gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + ASSERT_EFI_ERROR (Status); + return AppendDevicePathNode ( + DevicePathFromHandle (LoadedImage->DeviceHandle), + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); +} + +/** + Launch Sovereign Boot Wizard + + @param AppLaunchCause The reason why wizard is beign launched. + + @retval EFI_SUCCESS The wizard successfully loaded and executed, + @retval Others The wizard not found or faield to launch. +**/ +EFI_STATUS +EfiBootManagerLaunchSovereignBootWizard ( + UINT8 AppLaunchCause + ) +{ + EFI_STATUS Status; + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + SOVEREIGN_BOOT_WIZARD_CONFIG_DATA SvBootData; + + if (!FixedPcdGetBool (PcdSovereignBootEnabled)) { + return EFI_NOT_FOUND; + } + + FilePath = FvFilePath (&gSovereignBootWizardFormSetGuid); + if (FilePath == NULL) { + return EFI_NOT_FOUND; + } + + Status = EfiBootManagerInitializeLoadOption ( + &BootOption, + 0, + LoadOptionTypeBoot, + LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_APP, + L"Soverign Boot Wizard", + FilePath, + NULL, + 0 + ); + + if (!EFI_ERROR (Status)) { + // + // Since current no boot from removable media directly is allowed + // + gST->ConOut->ClearScreen (gST->ConOut); + // + // Set the Sovereign Boot Wizard launch cause + // + SvBootData.AppLaunchCause = AppLaunchCause; + gRT->SetVariable ( + SV_BOOT_DATA_VAR, + &gSovereignBootWizardFormSetGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (SOVEREIGN_BOOT_WIZARD_CONFIG_DATA), + &SvBootData + ); + + EfiBootManagerBoot (&BootOption); + // + // Remove the boot option after we return from the wizard + // + EfiBootManagerDeleteLoadOptionVariable (BootOption.OptionNumber, BootOption.OptionType); + + EfiBootManagerFreeLoadOption (&BootOption); + } + + return Status; +} + +/** + Check if it's a Device Path pointing to Sovereign Boot Wizard. + + @param DevicePath Input device path. + + @retval TRUE The device path is Sovereign Boot Wizar File Device Path. + @retval FALSE The device path is NOT Sovereign Boot Wizar File Device Path. +**/ +BOOLEAN +BmIsSovereignBootWizardFilePath ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_HANDLE FvHandle; + VOID *NameGuid; + EFI_STATUS Status; + + Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePath, &FvHandle); + if (!EFI_ERROR (Status)) { + NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevicePath); + if (NameGuid != NULL) { + return CompareGuid (NameGuid, &gSovereignBootWizardFormSetGuid); + } + } + + return FALSE; +} + + /** Attempt to boot the EFI boot option. This routine sets L"BootCurent" and also signals the EFI ready to boot event. If the device path for the option @@ -1847,21 +1967,26 @@ EfiBootManagerBoot ( IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { - EFI_STATUS Status; - EFI_HANDLE ImageHandle; - EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; - UINT16 Uint16; - UINTN OptionNumber; - UINTN OriginalOptionNumber; - EFI_DEVICE_PATH_PROTOCOL *FilePath; - EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath; - VOID *FileBuffer; - UINTN FileSize; - EFI_BOOT_LOGO_PROTOCOL *BootLogo; - EFI_EVENT LegacyBootEvent; - EFI_INPUT_KEY Key; - UINTN Index; - UINT8 *SecureBoot; + EFI_STATUS Status; + EFI_HANDLE ImageHandle; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + UINT16 Uint16; + UINTN OptionNumber; + UINTN OriginalOptionNumber; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath; + VOID *FileBuffer; + UINTN FileSize; + EFI_BOOT_LOGO_PROTOCOL *BootLogo; + EFI_EVENT LegacyBootEvent; + EFI_INPUT_KEY Key; + UINTN Index; + UINT8 *SecureBoot; + UINTN SvBootConfigSize; + SOVEREIGN_BOOT_WIZARD_NV_CONFIG *SvBootConfig; + BOOLEAN ScreenCleared; + + ScreenCleared = FALSE; if (BootOption == NULL) { return; @@ -2003,8 +2128,34 @@ EfiBootManagerBoot ( BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR, Status); BootOption->Status = Status; + // Launch Sovereign Boot Wizard if image verification failed + if (Status == EFI_SECURITY_VIOLATION || Status == EFI_ACCESS_DENIED) { + // Launch it only if THe Sovereign Boto Wizard is enabeld in the build and + // we did not attempt to boot the wizard itself (safety check to avoid recursive loop) + if (FixedPcdGetBool (PcdSovereignBootEnabled) && !BmIsSovereignBootWizardFilePath (BootOption->FilePath)) { + + SvBootConfigSize = sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG); + GetVariable2 (SV_BOOT_CONFIG_VAR, &gSovereignBootWizardFormSetGuid, (VOID **)&SvBootConfig, &SvBootConfigSize); + + // Only if Sovereign Boot is provisioned. We should not end up in this path before provisioning + if ((SvBootConfig != NULL) && SvBootConfig->SvBootEnabled && SvBootConfig->SvBootProvisioned) { + Status = EfiBootManagerLaunchSovereignBootWizard (SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED); + if (EFI_ERROR (Status)) { + if (gST->ConOut != NULL) { + gST->ConOut->ClearScreen (gST->ConOut); + ScreenCleared = TRUE; + AsciiPrint ("The Sovereign Boot Wizard failed to launch or is missing!\n"); + } + } + } + // If user did not trust the image or decided not to boot it, simply display the warning below as usual. + } + } + if (gST->ConOut != NULL) { - gST->ConOut->ClearScreen (gST->ConOut); + if (!ScreenCleared) { + gST->ConOut->ClearScreen (gST->ConOut); + } // // When UEFI Secure Boot is enabled, unsigned modules won't load. diff --git a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h index 48d3850b71..f17d6331e7 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h +++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h @@ -52,6 +52,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include diff --git a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf index 2655d5c5e4..d19049a523 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf +++ b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf @@ -41,6 +41,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + DasharoModulePkg/DasharoModulePkg.dec [LibraryClasses] HobLib @@ -87,6 +88,7 @@ gEfiDiskInfoSdMmcInterfaceGuid ## SOMETIMES_CONSUMES ## GUID gEfiDiskInfoUfsInterfaceGuid ## SOMETIMES_CONSUMES ## GUID gEfiPartTypeSystemPartGuid ## CONSUMES ## GUID + gSovereignBootWizardFormSetGuid ## SOMETIMES_CONSUMES [Protocols] gEfiPciRootBridgeIoProtocolGuid ## CONSUMES @@ -123,3 +125,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDriverHealthConfigureForm ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMaxRepairCount ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdCreatePreInstalledBootOptions ## CONSUMES + +[FixedPcd] + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState diff --git a/MdeModulePkg/Universal/BdsDxe/Bds.h b/MdeModulePkg/Universal/BdsDxe/Bds.h index 2b20fec8f4..2055564734 100644 --- a/MdeModulePkg/Universal/BdsDxe/Bds.h +++ b/MdeModulePkg/Universal/BdsDxe/Bds.h @@ -14,6 +14,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include + +#include +#include #include #include @@ -22,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include #include diff --git a/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf b/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf index 78e2e811a2..f3b2f60f1e 100644 --- a/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf +++ b/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf @@ -55,6 +55,7 @@ PlatformBootManagerLib PcdLib PrintLib + HobLib [Guids] gEfiGlobalVariableGuid ## SOMETIMES_PRODUCES ## Variable:L"BootNext" (The number of next boot option) @@ -77,6 +78,7 @@ gEfiEventReadyToBootGuid ## CONSUMES ## Event gDasharoSystemFeaturesGuid ## CONSUMES ## Variable:L"QuietBoot" ## CONSUMES ## Variable:L"FastBoot" + gSovereignBootWizardFormSetGuid ## SOMETIMES_CONSUMES ## Variable:L"SvBootConfig" [Protocols] gEfiBdsArchProtocolGuid ## PRODUCES @@ -105,6 +107,10 @@ gEfiMdePkgTokenSpaceGuid.PcdFastBootFeatureEnabled ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdQuietBootFeatureEnabled ## CONSUMES +[FixedPcd] + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState + [Depex] TRUE diff --git a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c index 29fed73ca8..aa17cdebc3 100644 --- a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c +++ b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c @@ -720,6 +720,11 @@ BdsEntry ( EFI_STATUS BootManagerMenuStatus; EFI_BOOT_MANAGER_LOAD_OPTION PlatformDefaultBootOption; BOOLEAN PlatformDefaultBootOptionValid; + SOVEREIGN_BOOT_WIZARD_NV_CONFIG SvBootConfig; + UINTN SvBootConfigSize; + EFI_BOOT_MODE BootMode; + EFI_INPUT_KEY Key; + UINTN KeyIndex; HotkeyTriggered = NULL; Status = EFI_SUCCESS; @@ -1098,6 +1103,75 @@ BdsEntry ( EfiBootManagerBoot (&BootManagerMenu); } + // Check Boot Mode + BootMode = GetBootModeHob (); + + if (FixedPcdGetBool (PcdSovereignBootEnabled) && BootMode != BOOT_ON_FLASH_UPDATE) { + SvBootConfigSize = sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG); + Status = gRT->GetVariable ( + SV_BOOT_CONFIG_VAR, + &gSovereignBootWizardFormSetGuid, + NULL, + &SvBootConfigSize, + (VOID *)&SvBootConfig + ); + + if (EFI_ERROR (Status)) { + SvBootConfig.SvBootEnabled = FixedPcdGetBool (PcdSovereignBootDefaultState); + SvBootConfig.SvBootProvisioned = FALSE; + } + + // Handle Invalid state. Sovereign Boot cannot be provisioned when disabled. + if (!SvBootConfig.SvBootEnabled && SvBootConfig.SvBootProvisioned) { + SvBootConfig.SvBootProvisioned = FALSE; + SvBootConfigSize = sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG); + gRT->SetVariable ( + SV_BOOT_CONFIG_VAR, + &gSovereignBootWizardFormSetGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + SvBootConfigSize, + (VOID *)&SvBootConfig + ); + } + + DEBUG ((EFI_D_INFO, "Sovereign Boot Wizard state:\n\tEnabled: %d\n\tProvisioned %d\n", + SvBootConfig.SvBootEnabled, SvBootConfig.SvBootProvisioned)); + + // Only if Sovereing Boot is NOT provisioned or settings has been reset (booting for the first time too) + if (SvBootConfig.SvBootEnabled) { + if (!SvBootConfig.SvBootProvisioned || + BootMode == BOOT_WITH_DEFAULT_SETTINGS || + BootMode == BOOT_WITH_MFG_MODE_SETTINGS) + { + DEBUG ((EFI_D_INFO, "Sovereign Boot: System is not provisioned or boots with default settings. Launching Wizard...\n")); + Status = EfiBootManagerLaunchSovereignBootWizard (SV_BOOT_LAUNCH_BOOT_WITH_DEFAULT_SETTINGS); + if (EFI_ERROR (Status)) { + if (gST->ConOut != NULL) { + gST->ConOut->ClearScreen (gST->ConOut); + AsciiPrint ( + "Booting Sovereign Boot Wizard failed due to '%r'.\n" + "Press any key to continue...\n", + Status); + } + if (gST->ConIn != NULL) { + Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &KeyIndex); + ASSERT_EFI_ERROR (Status); + ASSERT (KeyIndex == 0); + while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {} + } + } + + if (BootManagerMenuStatus != EFI_NOT_FOUND) { + // Boot to Boot Manager Menu/Setup upon Sovereign Boot Wizard exit/failure. + // The Wizard should always boot after provisionign is finished, + // unless there are no Sovereign Boot compatible boot options detected, + // then we still have to fallback to setup. + EfiBootManagerBoot (&BootManagerMenu); + } + } + } + } + if (!PlatformRecovery) { // // Execute SysPrep#### diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c index 6b1408f68c..0ad9bce0ac 100644 --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c @@ -173,7 +173,7 @@ FileIsInFv ( } EFI_DEVICE_PATH * -FvFilePath ( +BdsFvFilePath ( EFI_GUID *FileGuid ) { @@ -221,7 +221,7 @@ RegisterBootManagerMenuAppBootOption ( EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN OptionNumber; - DevicePath = FvFilePath (FileGuid); + DevicePath = BdsFvFilePath (FileGuid); Status = EfiBootManagerInitializeLoadOption ( &NewOption, LoadOptionNumberUnassigned, @@ -2092,14 +2092,39 @@ PlatformBootManagerAfterConsole ( BOOLEAN NetBootEnabled; UINTN VarSize; EFI_STATUS Status; + UINTN SvBootConfigSize; + SOVEREIGN_BOOT_WIZARD_NV_CONFIG SvBootConfig; DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole\n")); + if (FixedPcdGetBool (PcdSovereignBootEnabled)) { + SvBootConfigSize = sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG); + Status = gRT->GetVariable ( + SV_BOOT_CONFIG_VAR, + &gSovereignBootWizardFormSetGuid, + NULL, + &SvBootConfigSize, + (VOID *)&SvBootConfig + ); + + if (EFI_ERROR (Status)) { + SvBootConfig.SvBootEnabled = FixedPcdGetBool (PcdSovereignBootDefaultState); + SvBootConfig.SvBootProvisioned = FALSE; + } + } else { + SvBootConfig.SvBootEnabled = FALSE; + SvBootConfig.SvBootProvisioned = FALSE; + } + // This is probably the earliest we can print this, as before the console is - // not ready yet. - Print(L"F2 to enter Setup\n"); - Print(L"ESC to enter Boot Manager Menu\n"); - Print(L"ENTER to boot directly\n"); + // not ready yet. Don't print the hotkeys if SvBoot is enabled but not yet + // provisioned. We won't be able to use the hotkeys anyways in that case. + if (!SvBootConfig.SvBootEnabled || + (SvBootConfig.SvBootEnabled && SvBootConfig.SvBootProvisioned)) { + Print(L"F2 to enter Setup\n"); + Print(L"ESC to enter Boot Manager Menu\n"); + Print(L"ENTER to boot directly\n"); + } if (PcdGetBool (PcdOvmfFlashVariablesEnable)) { DEBUG (( diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf index 54d5e6c91d..687d7b9a1c 100644 --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -75,6 +75,10 @@ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits ## CONSUMES +[FixedPcd] + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState + [Pcd.IA32, Pcd.X64] gEfiMdePkgTokenSpaceGuid.PcdFSBClock @@ -95,3 +99,4 @@ gGrubFileGuid gEfiTtyTermGuid gDasharoSystemFeaturesGuid + gSovereignBootWizardFormSetGuid diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index f9518cdd0a..0c9b48e46f 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -45,6 +45,7 @@ DEFINE OPAL_PASSWORD_ENABLE = TRUE DEFINE DASHARO_SYSTEM_FEATURES_ENABLE = TRUE DEFINE SETUP_PASSWORD_ENABLE = TRUE + DEFINE SOVEREIGN_BOOT_ENABLE = FALSE # # Network definition @@ -683,6 +684,12 @@ gDasharoSystemFeaturesTokenSpaceGuid.PcdPowerMenuShowDGPUPowerOption|FALSE gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultEnable|0 + +!if $(SECURE_BOOT_ENABLE) == TRUE + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled|$(SOVEREIGN_BOOT_ENABLE) + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState|TRUE +!endif + ################################################################################ # # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform @@ -1053,8 +1060,6 @@ !endif !endif - DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf - # # Hash2 # @@ -1080,6 +1085,11 @@ SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.inf SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf + +!if $(SOVEREIGN_BOOT_ENABLE) == TRUE + DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf +!endif + !endif OvmfPkg/PlatformDxe/Platform.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 9add3d9af3..d3d23ba727 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -288,6 +288,10 @@ INF OvmfPkg/LsiScsiDxe/LsiScsiDxe.inf INF SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.inf INF SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf +!if $(SOVEREIGN_BOOT_ENABLE) == TRUE + INF DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf +!endif + # gDefaultKEKFileGuid FILE FREEFORM = 6F64916E-9F7A-4C35-B952-CD041EFB05A3 { SECTION RAW = DasharoPayloadPkg/SecureBootDefaultKeys/MicCorKEKCA2011_2011-06-24.crt diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr index 88622f503f..e88501b6df 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr @@ -70,6 +70,52 @@ formset endif; endif; + disableif ideqval SECUREBOOT_CONFIGURATION.SvBootAvailable == 0; + subtitle text = STRING_TOKEN(STR_NULL); + subtitle text = STRING_TOKEN(STR_NULL); + subtitle text = STRING_TOKEN(STR_SOVEREIGN_BOOT_OPTIONS); + subtitle text = STRING_TOKEN(STR_NULL); + + checkbox varid = SECUREBOOT_CONFIGURATION.SvBootEnable, + questionid = KEY_SOVEREIGN_BOOT_ENABLE, + prompt = STRING_TOKEN(STR_ENABLE_SOVEREIGN_BOOT_PROMPT), + help = STRING_TOKEN(STR_ENABLE_SOVEREIGN_BOOT_HELP), + flags = INTERACTIVE | RESET_REQUIRED, + endcheckbox; + + // Hidden checkbox for provisioned state, to be used in callback + // whe nefautl settigns are restored. + suppressif TRUE; + checkbox varid = SECUREBOOT_CONFIGURATION.SvBootProvisioned, + questionid = KEY_SOVEREIGN_BOOT_PROVISIONED, + prompt = STRING_TOKEN(STR_SOVEREIGN_BOOT_PRIVISIONED_PROMPT), + help = STRING_TOKEN(STR_SOVEREIGN_BOOT_PRIVISIONED_HELP), + flags = INTERACTIVE | RESET_REQUIRED, + endcheckbox; + endif; + + text + help = STRING_TOKEN(STR_SOVEREIGN_BOOT_STATE_HELP), + text = STRING_TOKEN(STR_SOVEREIGN_BOOT_STATE_PROMPT), + text = STRING_TOKEN(STR_SOVEREIGN_BOOT_STATE_CONTENT); + + disableif ideqval SECUREBOOT_CONFIGURATION.SvBootEnable == 0; + subtitle text = STRING_TOKEN(STR_NULL); + // + // We may hide the menu if Sovereign Boot is not yet provisioned and allow to + // launch the wizard only when system is provisioned to augment the settings. + // + // suppressif ideqval SECUREBOOT_CONFIGURATION.SvBootProvisioned == 0; + text + help = STRING_TOKEN(STR_LAUNCH_SOVEREIGN_BOOT_WIZARD_HELP), + text = STRING_TOKEN(STR_LAUNCH_SOVEREIGN_BOOT_WIZARD_PROMPT), + flags = INTERACTIVE, + key = KEY_LAUNCH_SOVEREIGN_BOOT_WIZARD; + // endif; + endif; + + endif; + endform; // diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf index 21be571bf5..42009dcd5c 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf @@ -37,6 +37,7 @@ MdeModulePkg/MdeModulePkg.dec SecurityPkg/SecurityPkg.dec CryptoPkg/CryptoPkg.dec + DasharoModulePkg/DasharoModulePkg.dec [LibraryClasses] BaseLib @@ -44,6 +45,7 @@ BaseCryptLib MemoryAllocationLib UefiLib + UefiBootManagerLib UefiBootServicesTableLib UefiRuntimeServicesTableLib UefiDriverEntryPoint @@ -60,6 +62,8 @@ [FixedPcd] gEfiSecurityPkgTokenSpaceGuid.PcdSecureBootDefaultEnable + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootEnabled + gDasharoSystemFeaturesTokenSpaceGuid.PcdSovereignBootDefaultState [Guids] ## SOMETIMES_CONSUMES ## Variable:L"CustomMode" @@ -119,11 +123,14 @@ gEfiCertX509Sha384Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the certificate. gEfiCertX509Sha512Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the certificate. + gSovereignBootWizardFormSetGuid ## SOMETIMES CONSUMES + [Protocols] gEfiHiiConfigAccessProtocolGuid ## PRODUCES gEfiDevicePathProtocolGuid ## PRODUCES gEfiHiiPopupProtocolGuid gEfiRealTimeClockArchProtocolGuid ## CONSUMES + gEdkiiFormBrowserEx2ProtocolGuid ## SOMETIMES_CONSUMES [Depex] gEfiHiiConfigRoutingProtocolGuid AND diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index fc95b052f1..7a7acebed3 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c @@ -59,6 +59,7 @@ HII_VENDOR_DEVICE_PATH mSecureBootHiiVendorDevicePath = { }; BOOLEAN mIsEnterSecureBootForm = FALSE; +BOOLEAN mResetSvBootState = FALSE; // // OID ASN.1 Value for Hash Algorithms @@ -298,6 +299,105 @@ SaveSecureBootVariable ( return Status; } +/** + Set Sovereign Boot configuration into variable space. + + @param[in] SvBootEnable The state of Sovereign Boot. + + @retval EFI_SUCCESS The operation is finished successfully. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +SaveSovereignBootVariable ( + IN BOOLEAN SvBootEnable + ) +{ + SOVEREIGN_BOOT_WIZARD_NV_CONFIG SvBootConfig; + EFI_STATUS Status; + UINT32 Attrs; + UINTN VarSize; + + VarSize = sizeof(SOVEREIGN_BOOT_WIZARD_NV_CONFIG); + + Status = gRT->GetVariable ( + SV_BOOT_CONFIG_VAR, + &gSovereignBootWizardFormSetGuid, + &Attrs, + &VarSize, + &SvBootConfig + ); + + if (EFI_ERROR (Status) || + Attrs != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) || + VarSize != sizeof(SOVEREIGN_BOOT_WIZARD_NV_CONFIG) + ) { + SvBootConfig.SvBootProvisioned = FALSE; + } + + if (SvBootConfig.SvBootEnabled == SvBootEnable) { + return EFI_SUCCESS; + } + + SvBootConfig.SvBootEnabled = SvBootEnable; + + Status = gRT->SetVariable ( + SV_BOOT_CONFIG_VAR, + &gSovereignBootWizardFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG), + &SvBootConfig + ); + return Status; +} + +/** + Resets Sovereign Boot configuration and saves it into variable space. + + @retval EFI_SUCCESS The operation is finished successfully. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +ResetSovereignBootState ( + SECUREBOOT_CONFIG_PRIVATE_DATA *Private + ) +{ + SOVEREIGN_BOOT_WIZARD_NV_CONFIG SvBootConfig; + EFI_STATUS Status; + UINT32 Attrs; + UINTN VarSize; + + VarSize = sizeof(SOVEREIGN_BOOT_WIZARD_NV_CONFIG); + + Status = gRT->GetVariable ( + SV_BOOT_CONFIG_VAR, + &gSovereignBootWizardFormSetGuid, + &Attrs, + &VarSize, + &SvBootConfig + ); + + if (EFI_ERROR (Status) || + Attrs != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) || + VarSize != sizeof(SOVEREIGN_BOOT_WIZARD_NV_CONFIG) + ) { + SvBootConfig.SvBootEnabled = FixedPcdGetBool (PcdSovereignBootDefaultState); + } + + SvBootConfig.SvBootProvisioned = FALSE; + + Status = gRT->SetVariable ( + SV_BOOT_CONFIG_VAR, + &gSovereignBootWizardFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG), + &SvBootConfig + ); + + return Status; +} + /** This code checks if the encode type and key strength of X.509 certificate is qualified. @@ -3387,9 +3487,12 @@ SecureBootExtractConfigFromVariable ( UINT8 *SecureBootMode; EFI_TIME CurrTime; + SOVEREIGN_BOOT_WIZARD_NV_CONFIG *SvBootConfig; + SecureBootEnable = NULL; SetupMode = NULL; SecureBootMode = NULL; + SvBootConfig = NULL; // // Initialize the Date and Time using system time. @@ -3460,6 +3563,27 @@ SecureBootExtractConfigFromVariable ( ConfigData->SecureBootMode = *(SecureBootMode); } + ConfigData->SvBootAvailable = FixedPcdGetBool (PcdSovereignBootEnabled); + ConfigData->SvBootEnable = FixedPcdGetBool (PcdSovereignBootDefaultState); + ConfigData->SvBootProvisioned = FALSE; + + if (ConfigData->SvBootAvailable) { + + GetVariable2 (SV_BOOT_CONFIG_VAR, &gSovereignBootWizardFormSetGuid, (VOID **)&SvBootConfig, NULL); + + if (SvBootConfig != NULL) { + ConfigData->SvBootEnable = SvBootConfig->SvBootEnabled; + ConfigData->SvBootProvisioned = SvBootConfig->SvBootProvisioned; + FreePool (SvBootConfig); + } + + HiiSetString ( + Private->HiiHandle, + STRING_TOKEN (STR_SOVEREIGN_BOOT_STATE_CONTENT), + ConfigData->SvBootProvisioned ? L"Yes" : L"No", + NULL); + } + if (SecureBootEnable != NULL) { FreePool (SecureBootEnable); } @@ -3660,6 +3784,13 @@ SecureBootRouteConfig ( } } + if (IfrNvData.SvBootAvailable) { + Status = SaveSovereignBootVariable (IfrNvData.SvBootEnable); + if (EFI_ERROR (Status)) { + return Status; + } + } + *Progress = Configuration + StrLen (Configuration); return EFI_SUCCESS; } @@ -4602,6 +4733,51 @@ KeyEraseAll ( return Status; } +/** + + Check whether a reset is needed, if reset is needed, Popup a menu to notice user. + +**/ +VOID +SetupResetReminder ( + VOID + ) +{ + EFI_INPUT_KEY Key; + CHAR16 *StringBuffer1; + CHAR16 *StringBuffer2; + EFI_STATUS Status; + EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2; + + // + // Use BrowserEx2 protocol to check whether reset is required. + // + Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **)&FormBrowserEx2); + + // + // check any reset required change is applied? if yes, reset system + // + if (!EFI_ERROR (Status) && FormBrowserEx2->IsResetRequired ()) { + StringBuffer1 = AllocateZeroPool (MAX_CHAR * sizeof (CHAR16)); + ASSERT (StringBuffer1 != NULL); + StringBuffer2 = AllocateZeroPool (MAX_CHAR * sizeof (CHAR16)); + ASSERT (StringBuffer2 != NULL); + StrCpyS (StringBuffer1, MAX_CHAR, L"Configuration changed. Reset to apply it Now."); + StrCpyS (StringBuffer2, MAX_CHAR, L"Press ENTER to reset"); + // + // Popup a menu to notice user + // + do { + CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + FreePool (StringBuffer1); + FreePool (StringBuffer2); + + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + } +} + /** This function is called to provide results data to the driver. @@ -4778,6 +4954,21 @@ SecureBootCallback ( goto EXIT; } + if (Action == EFI_BROWSER_ACTION_SUBMITTED) { + Status = EFI_UNSUPPORTED; + if (QuestionId == KEY_SOVEREIGN_BOOT_PROVISIONED) { + Status = EFI_SUCCESS; + if (mResetSvBootState && !Value->b) { + Status = ResetSovereignBootState (Private); + if (GetBrowserDataResult) { + SecureBootExtractConfigFromVariable (Private, IfrNvData); + } + mResetSvBootState = FALSE; + } + } + goto EXIT; + } + if ((Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE) && @@ -4813,6 +5004,34 @@ SecureBootCallback ( break; + case KEY_SOVEREIGN_BOOT_ENABLE: + Status = EFI_SUCCESS; + if (!Value->b) { + Status = gBS->LocateProtocol (&gEfiHiiPopupProtocolGuid, NULL, (VOID **)&HiiPopup); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = HiiPopup->CreatePopup ( + HiiPopup, + EfiHiiPopupStyleInfo, + EfiHiiPopupTypeYesNo, + Private->HiiHandle, + STRING_TOKEN (STR_SV_RESET_TO_DEFAULTS_POPUP), + &UserSelection + ); + if (UserSelection == EfiHiiPopupSelectionNo) { + // If the user decided not to disable Sovereign Boot, + // restore the enabled state and don't reset keys. + if (GetBrowserDataResult) { + Value->b = TRUE; + IfrNvData->SvBootEnable = TRUE; + } + } + } + + break; + case KEY_SECURE_BOOT_KEK_OPTION: case KEY_SECURE_BOOT_DB_OPTION: case KEY_SECURE_BOOT_DBX_OPTION: @@ -5308,6 +5527,16 @@ SecureBootCallback ( Status = KeyEnrollReset (); } + if (EFI_ERROR (Status)) { + return Status; + } + + // Resetting the keys need to reset the Sovereign Boot state + // as we will no longer have the trusted keys in db + if (FixedPcdGetBool (PcdSovereignBootEnabled)) { + Status = ResetSovereignBootState (Private); + } + // // Update secure boot strings after key reset // @@ -5334,6 +5563,17 @@ SecureBootCallback ( if (UserSelection == EfiHiiPopupSelectionYes) { Status = KeyEraseAll (); } + + if (EFI_ERROR (Status)) { + return Status; + } + + // Erasing the keys need to reset the Sovereign Boot state + // as we will no longer have the trusted keys in db + if (FixedPcdGetBool (PcdSovereignBootEnabled)) { + Status = ResetSovereignBootState (Private); + } + // // Update secure boot strings after key reset // @@ -5342,6 +5582,38 @@ SecureBootCallback ( SecureBootExtractConfigFromVariable (Private, IfrNvData); } break; + } + case KEY_SOVEREIGN_BOOT_ENABLE: + { + Status = SaveSovereignBootVariable (Value->b); + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; + // If disabling, we need to restore Secure Boot keys + if (!Value->b) { + Status = KeyEnrollReset (); + if (EFI_ERROR (Status)) { + break; + } + // Reset the Sovereign Boot provisioning state + Status = ResetSovereignBootState (Private); + if (EFI_ERROR (Status)) { + break; + } + // + // Update secure boot strings after key reset + // + Status = UpdateSecureBootString (Private); + if (GetBrowserDataResult) { + SecureBootExtractConfigFromVariable (Private, IfrNvData); + } + } + + break; + } + case KEY_LAUNCH_SOVEREIGN_BOOT_WIZARD: + { + SetupResetReminder (); + Status = EfiBootManagerLaunchSovereignBootWizard (SV_BOOT_LAUNCH_VIA_SETUP); + break; } default: break; @@ -5372,6 +5644,25 @@ SecureBootCallback ( } break; } + case KEY_SOVEREIGN_BOOT_ENABLE: { + Value->u8 = FixedPcdGetBool (PcdSovereignBootDefaultState); + if (EFI_ERROR (SaveSovereignBootVariable(Value->u8))) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Could not restore Sovereign Boot to default state!", + NULL + ); + } + break; + } + case KEY_SOVEREIGN_BOOT_PROVISIONED: + { + Status = EFI_SUCCESS; + Value->b = FALSE; + mResetSvBootState = TRUE; + break; + } default: break; } diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h index ff6e7301af..3480a8a108 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h @@ -19,6 +19,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include +#include #include #include @@ -35,6 +37,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include @@ -42,6 +45,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include "SecureBootConfigNvData.h" diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h index a5ed76b6f8..fe7fb2dea0 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h @@ -75,6 +75,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define KEY_SECURE_BOOT_DELETE_ALL_DATA 0x1110 #define KEY_SECURE_BOOT_DELETE_CHECK_DATA 0x1111 +#define KEY_SOVEREIGN_BOOT_ENABLE 0x1120 +#define KEY_LAUNCH_SOVEREIGN_BOOT_WIZARD 0x1121 +#define KEY_SOVEREIGN_BOOT_PROVISIONED 0x1122 + #define LABEL_KEK_DELETE 0x1200 #define LABEL_DB_DELETE 0x1201 #define LABEL_SIGNATURE_LIST_START 0x1202 @@ -138,6 +142,9 @@ typedef struct { UINT8 FileEnrollType; // File type of signature enroll UINT32 ListCount; // The count of signature list. UINT32 CheckedDataCount; // The count of checked signature data. + BOOLEAN SvBootAvailable; // If Sovereign Boot is enabled in the build and should be displayed + BOOLEAN SvBootEnable; // If Sovereign Boot flow should be enforced + BOOLEAN SvBootProvisioned; // If Sovereign Boot was already provisioned } SECUREBOOT_CONFIGURATION; #endif diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni index 17afa9e33b..8e5f308b7c 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigStrings.uni @@ -27,6 +27,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #string STR_SECURE_RESET_TO_DEFAULTS #language en-US "> Reset to default Secure Boot Keys" #string STR_RESET_TO_DEFAULTS_POPUP #language en-US "Secure Boot Keys & databases will be initialized from defaults.\n Are you sure?" +#string STR_SV_RESET_TO_DEFAULTS_POPUP #language en-US "Disabling Sovereign Boot will restore default Secure Boot Keys & databases.\n Are you sure?" #string STR_SECURE_ERASE_ALL_KEYS_HELP #language en-US "Erases all Secure Boot keys and leaves the related variables empty.\nYou will need to provision the keys to use Secure Boot again or reset the Secure Boot keys to defaults." #string STR_SECURE_ERASE_ALL_KEYS #language en-US "> Erase all Secure Boot Keys" @@ -151,3 +152,26 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #string STR_SIGNATURE_DATA_HELP_FORMAT_TIME #language en-US "Revocation Time:\n%s" #string STR_SIGNATURE_DELETE_ALL_CONFIRM #language en-US "Press 'Y' to delete all signature List." + +/* Sovereign Boot strings */ + +#string STR_SOVEREIGN_BOOT_OPTIONS #language en-US "*** Sovereign Boot Options ***" +#string STR_ENABLE_SOVEREIGN_BOOT_PROMPT #language en-US "Enable Sovereign Boot" +#string STR_ENABLE_SOVEREIGN_BOOT_HELP #language en-US "Enables/disables Sovereign Boot in the firmware boot flow. " + "When enabled, the firmware will invoke Sovereign Boot Wizard on the first boot, " + "or when defautl settings are restored (if Sovereign Boot is configured to be " + "enabled by default) or when UEFI Secure Boto fails to verify a boot image.\n\n" + "Sovereign Boot Wizard assist in configuring Secure Boot in an easy and " + "comprehensible way for less technical users.\n\n" + "If unsure, disable it, to use the default firmware keys and be able to boot " + "Windows and most common Linux distributions when Secure Boot is enabled." + +#string STR_LAUNCH_SOVEREIGN_BOOT_WIZARD_HELP #language en-US "Manually invoke Sovereign Boot Wizard to modify/augment the Sovereign Boot settings." +#string STR_LAUNCH_SOVEREIGN_BOOT_WIZARD_PROMPT #language en-US "> Launch Sovereign Boot Wizard" + +#string STR_SOVEREIGN_BOOT_PRIVISIONED_HELP #language en-US "Sovereign Boot provisioning state" +#string STR_SOVEREIGN_BOOT_PRIVISIONED_PROMPT #language en-US "Sovereign Boot Provisioned" + +#string STR_SOVEREIGN_BOOT_STATE_HELP #language en-US "Sovereign Boot provisioning state" +#string STR_SOVEREIGN_BOOT_STATE_PROMPT #language en-US "Sovereign Boot Provisioned" +#string STR_SOVEREIGN_BOOT_STATE_CONTENT #language en-US "Unknown"