diff --git a/DasharoModulePkg/Application/SovereignBootWizard/BootOptionParsing.c b/DasharoModulePkg/Application/SovereignBootWizard/BootOptionParsing.c
index 9aed6bbbaa..996ae7eb4d 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/BootOptionParsing.c
+++ b/DasharoModulePkg/Application/SovereignBootWizard/BootOptionParsing.c
@@ -11,7 +11,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
///
/// Boot Option from variable Menu
///
-SV_MENU_OPTION BootOptionMenu = {
+SV_MENU_OPTION mBootOptionMenu = {
SOVEREIGN_BOOT_MENU_OPTION_SIGNATURE,
{ NULL },
0
@@ -489,15 +489,14 @@ CheckIfEntryIsDuplicate (
}
Index = 0;
- while (Index < BootOptionMenu.MenuNumber) {
- BootloaderEntry = GetMenuEntry (&BootOptionMenu, Index++);
+ while (Index < mBootOptionMenu.MenuNumber) {
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, Index++);
if (BootloaderEntry == NULL) {
DEBUG ((DEBUG_WARN, "Bootloader entry is NULL\n"));
continue;
}
if (MenuPathsAreEqual (MenuEntry, BootloaderEntry)) {
- DEBUG ((DEBUG_WARN, "Found duplicate entry\n"));
return TRUE;
}
}
@@ -640,7 +639,7 @@ FillMenuEntryFromDevicePath (
/**
- Build the BootOptionMenu according to BootOrder Variable.
+ Build the mBootOptionMenu according to BootOrder Variable.
This Routine will access the Boot#### to get EFI_LOAD_OPTION.
@param CallbackData The BMM context data.
@@ -666,7 +665,7 @@ GetBootOptions (
MenuCount = 0;
BootOrderListSize = 0;
BootOrderList = NULL;
- InitializeListHead (&BootOptionMenu.Head);
+ InitializeListHead (&mBootOptionMenu.Head);
DEBUG ((DEBUG_INFO, "Locating boot options\n"));
@@ -679,8 +678,8 @@ GetBootOptions (
return Status;
}
- InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
- BootOptionMenu.MenuNumber = 1;
+ InsertTailList (&mBootOptionMenu.Head, &NewMenuEntry->Link);
+ mBootOptionMenu.MenuNumber = 1;
return EFI_SUCCESS;
}
@@ -712,7 +711,7 @@ GetBootOptions (
return Status;
}
- InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
+ InsertTailList (&mBootOptionMenu.Head, &NewMenuEntry->Link);
MenuCount++;
}
@@ -720,16 +719,16 @@ GetBootOptions (
FREE_NON_NULL (BootOrderList);
- BootOptionMenu.MenuNumber = MenuCount;
+ mBootOptionMenu.MenuNumber = MenuCount;
- Status = ScanFileSystemsForBootOptions (Private, &BootOptionMenu);
+ Status = ScanFileSystemsForBootOptions (Private, &mBootOptionMenu);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Scanning of filesystems failed with %r\n", Status));
}
- DEBUG ((DEBUG_INFO, "Found %d boot options \n", BootOptionMenu.MenuNumber));
+ DEBUG ((DEBUG_INFO, "Found %d boot options \n", mBootOptionMenu.MenuNumber));
- if (BootOptionMenu.MenuNumber == 0) {
+ if (mBootOptionMenu.MenuNumber == 0) {
return EFI_NOT_FOUND;
}
@@ -777,12 +776,13 @@ UpdateBootloaderPage (
IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private
)
{
- SV_MENU_ENTRY *BootloaderEntry;
- EFI_STRING NewString;
- EFI_STATUS Status;
+ SV_MENU_ENTRY *BootloaderEntry;
+ SV_SECURITY_CONTEXT *SecurityContext;
+ EFI_STRING NewString;
+ EFI_STATUS Status;
- while (mBootloaderIndex < BootOptionMenu.MenuNumber) {
- BootloaderEntry = GetMenuEntry (&BootOptionMenu, mBootloaderIndex);
+ while (mBootloaderIndex < mBootOptionMenu.MenuNumber) {
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, mBootloaderIndex);
if (BootloaderEntry == NULL) {
return EFI_NO_MEDIA;
}
@@ -794,6 +794,7 @@ UpdateBootloaderPage (
if (BootloaderEntry->SecurityContext == NULL) {
Status = FillSecurityContext(BootloaderEntry);
if (EFI_ERROR (Status)) {
+ Private->FormData.ImageUnsigned = TRUE;
DEBUG ((DEBUG_ERROR, "Failed to fill security context for bootloader %u\n", mBootloaderIndex));
return EFI_NO_MEDIA;
}
@@ -803,15 +804,17 @@ UpdateBootloaderPage (
if (Status == EFI_NO_MEDIA) {
DEBUG ((DEBUG_INFO, "No more keys/certificates for bootloader %u\n", mBootloaderIndex));
// No more keys/certs to show for this bootloader, proceed to the next one
- mCertIndex = 0;
- mBootloaderIndex++;
- continue;
+ if (!mAltAccessMode) {
+ mCertIndex = 0;
+ mBootloaderIndex++;
+ continue;
+ }
}
break;
}
- if (mBootloaderIndex >= BootOptionMenu.MenuNumber) {
+ if (mBootloaderIndex >= mBootOptionMenu.MenuNumber) {
DEBUG ((DEBUG_INFO, "No more keys/certificates/bootloaders to show\n"));
return EFI_NO_MEDIA;
}
@@ -838,6 +841,43 @@ UpdateBootloaderPage (
HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_BOOTOPT_DESCRIPTION), L"Not Found!", NULL);
}
+ if (mAltAccessMode && (BootloaderEntry->SecurityContext != NULL)) {
+ NewString = NULL;
+ SecurityContext = (SV_SECURITY_CONTEXT *)BootloaderEntry->SecurityContext;
+ Status = ParseHashValue (SecurityContext->ImageDigest,
+ SecurityContext->ImageDigestSize,
+ &NewString);
+ if (!EFI_ERROR (Status)) {
+ HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_BOOTLOADER_HASH_HEX), NewString, NULL);
+ FREE_NON_NULL (NewString);
+ } else {
+ HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_BOOTLOADER_HASH_HEX), L"Image hash could not be obtained.", NULL);
+ }
+
+ Private->FormData.ImageUnsigned = (!SecurityContext->ImageIsSigned ||
+ (SecurityContext->NumCertificates == 0));
+
+ if (SecurityContext->ImageIsInDbx) {
+ Private->FormData.ImageTrusted = IMAGE_STATE_UNTRUSTED;
+ } else if (SecurityContext->ImageIsInDb) {
+ Private->FormData.ImageTrusted = IMAGE_STATE_TRUSTED;
+ } else {
+ Private->FormData.ImageTrusted = IMAGE_STATE_UNDECIDED;
+ }
+
+ DEBUG ((DEBUG_INFO, "UpdateBootloaderPage:\n"
+ " ImageIsSigned: %u\n"
+ " ImageIsVerified: %u\n"
+ " ImageIsInDb: %u\n"
+ " ImageIsInDbx: %u\n"
+ " ImageTrusted: %u\n",
+ SecurityContext->ImageIsSigned,
+ SecurityContext->ImageIsVerified,
+ SecurityContext->ImageIsInDb,
+ SecurityContext->ImageIsInDbx,
+ Private->FormData.ImageTrusted));
+ }
+
return Status;
}
@@ -882,13 +922,13 @@ FreeBootMenuEntries (
{
SV_MENU_ENTRY *BootloaderEntry;
- if (BootOptionMenu.MenuNumber == 0) {
+ if (mBootOptionMenu.MenuNumber == 0) {
return;
}
- while (!IsListEmpty (&BootOptionMenu.Head)) {
+ while (!IsListEmpty (&mBootOptionMenu.Head)) {
BootloaderEntry = CR (
- BootOptionMenu.Head.ForwardLink,
+ mBootOptionMenu.Head.ForwardLink,
SV_MENU_ENTRY,
Link,
SOVEREIGN_BOOT_MENU_ENTRY_SIGNATURE);
@@ -896,5 +936,5 @@ FreeBootMenuEntries (
FreeBootMenuEntry (BootloaderEntry);
}
- BootOptionMenu.MenuNumber = 0;
+ mBootOptionMenu.MenuNumber = 0;
}
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/InteractiveModeImpl.c b/DasharoModulePkg/Application/SovereignBootWizard/InteractiveModeImpl.c
new file mode 100644
index 0000000000..121a07dc03
--- /dev/null
+++ b/DasharoModulePkg/Application/SovereignBootWizard/InteractiveModeImpl.c
@@ -0,0 +1,3982 @@
+/** @file
+Sovereign Boot Wizard Interactive Mode implementation.
+
+Copyright (c) 2025, 3mdeb Sp z o.o. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SovereignBootWizard.h"
+#include "InteractiveModeImpl.h"
+
+EFI_STATUS
+FormatHelpInfo (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN EFI_SIGNATURE_DATA *DataEntry,
+ OUT EFI_STRING_ID *StringId
+ );
+
+EFI_STATUS
+GetCommonNameFromX509 (
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN EFI_SIGNATURE_DATA *DataEntry,
+ OUT CHAR16 **BufferToReturn
+ );
+
+UINT8
+GetSignatureFormat (
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN OUT EFI_STRING_ID *ListFormat OPTIONAL,
+ IN OUT EFI_STRING_ID *EntryFormat OPTIONAL,
+ IN OUT EFI_STRING_ID *ListType OPTIONAL
+ );
+
+//
+// Variable Definitions
+//
+WIN_CERTIFICATE *mCertificate = NULL;
+EFI_IMAGE_SECURITY_DATA_DIRECTORY *mSecDataDir = NULL;
+UINT8 *mImageBase = NULL;
+UINTN mImageSize = 0;
+//
+// Possible DER-encoded certificate file suffixes, end with NULL pointer.
+//
+CHAR16 *mDerEncodedSuffix[] = {
+ L".cer",
+ L".der",
+ L".crt",
+ NULL
+};
+
+CHAR16 *mSupportX509Suffix = L"*.cer/der/crt";
+
+//
+// Prompt strings during certificate enrollment.
+//
+CHAR16 *mX509EnrollPromptTitle[] = {
+ L"",
+ L"ERROR: Unsupported file type!",
+ L"ERROR: Unsupported certificate!",
+ NULL
+};
+CHAR16 *mX509EnrollPromptString[] = {
+ L"",
+ L"Only DER encoded certificate file (*.cer/der/crt) is supported.",
+ L"Public key length should be equal to or greater than 2048 bits.",
+ NULL
+};
+
+#define EFI_SB_MICROSOFT_OWNER_GUID \
+ { 0x77FA9ABD, 0x0359, 0x4D32, {0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B} }
+
+EFI_GUID gEfiSbMicrosoftOwnerGuid = EFI_SB_MICROSOFT_OWNER_GUID;
+
+/**
+ Read file content into BufferPtr, the size of the allocate buffer
+ is *FileSize plus AdditionAllocateSize.
+
+ @param[in] FileHandle The file to be read.
+ @param[in, out] BufferPtr Pointers to the pointer of allocated buffer.
+ @param[out] FileSize Size of input file
+ @param[in] AdditionAllocateSize Addition size the buffer need to be allocated.
+ In case the buffer need to contain others besides the file content.
+
+ @retval EFI_SUCCESS The file was read into the buffer.
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval others Unexpected error.
+
+**/
+EFI_STATUS
+ReadFile (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN OUT VOID **BufferPtr,
+ OUT UINTN *FileSize,
+ IN UINTN AdditionAllocateSize
+ )
+
+{
+ UINTN BufferSize;
+ UINT64 SourceFileSize;
+ VOID *Buffer;
+ EFI_STATUS Status;
+
+ if ((FileHandle == NULL) || (FileSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Buffer = NULL;
+
+ //
+ // Get the file size
+ //
+ Status = FileHandle->SetPosition (FileHandle, (UINT64)-1);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = FileHandle->SetPosition (FileHandle, 0);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ BufferSize = (UINTN)SourceFileSize + AdditionAllocateSize;
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BufferSize = (UINTN)SourceFileSize;
+ *FileSize = BufferSize;
+
+ Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);
+ if (EFI_ERROR (Status) || (BufferSize != *FileSize)) {
+ FREE_NON_NULL (Buffer);
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ *BufferPtr = Buffer;
+ return Status;
+}
+
+/**
+ Close an open file handle.
+
+ @param[in] FileHandle The file handle to close.
+
+**/
+VOID
+CloseFile (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ if (FileHandle != NULL) {
+ FileHandle->Close (FileHandle);
+ }
+}
+
+/**
+ Convert a nonnegative integer to an octet string of a specified length.
+
+ @param[in] Integer Pointer to the nonnegative integer to be converted
+ @param[in] IntSizeInWords Length of integer buffer in words
+ @param[out] OctetString Converted octet string of the specified length
+ @param[in] OSSizeInBytes Intended length of resulting octet string in bytes
+
+Returns:
+
+ @retval EFI_SUCCESS Data conversion successfully
+ @retval EFI_BUFFER_TOOL_SMALL Buffer is too small for output string
+
+**/
+EFI_STATUS
+EFIAPI
+Int2OctStr (
+ IN CONST UINTN *Integer,
+ IN UINTN IntSizeInWords,
+ OUT UINT8 *OctetString,
+ IN UINTN OSSizeInBytes
+ )
+{
+ CONST UINT8 *Ptr1;
+ UINT8 *Ptr2;
+
+ for (Ptr1 = (CONST UINT8 *)Integer, Ptr2 = OctetString + OSSizeInBytes - 1;
+ Ptr1 < (UINT8 *)(Integer + IntSizeInWords) && Ptr2 >= OctetString;
+ Ptr1++, Ptr2--)
+ {
+ *Ptr2 = *Ptr1;
+ }
+
+ for ( ; Ptr1 < (CONST UINT8 *)(Integer + IntSizeInWords) && *Ptr1 == 0; Ptr1++) {
+ }
+
+ if (Ptr1 < (CONST UINT8 *)(Integer + IntSizeInWords)) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (Ptr2 >= OctetString) {
+ ZeroMem (OctetString, Ptr2 - OctetString + 1);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Worker function that prints an EFI_GUID into specified Buffer.
+
+ @param[in] Guid Pointer to GUID to print.
+ @param[in] Buffer Buffer to print Guid into.
+ @param[in] BufferSize Size of Buffer.
+
+ @retval Number of characters printed.
+
+**/
+UINTN
+GuidToString (
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ UINTN Size;
+
+ Size = UnicodeSPrint (
+ Buffer,
+ BufferSize,
+ L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (UINTN)Guid->Data1,
+ (UINTN)Guid->Data2,
+ (UINTN)Guid->Data3,
+ (UINTN)Guid->Data4[0],
+ (UINTN)Guid->Data4[1],
+ (UINTN)Guid->Data4[2],
+ (UINTN)Guid->Data4[3],
+ (UINTN)Guid->Data4[4],
+ (UINTN)Guid->Data4[5],
+ (UINTN)Guid->Data4[6],
+ (UINTN)Guid->Data4[7]
+ );
+
+ //
+ // SPrint will null terminate the string. The -1 skips the null
+ //
+ return Size - 1;
+}
+
+
+VOID *mStartOpCodeHandle = NULL;
+VOID *mEndOpCodeHandle = NULL;
+EFI_IFR_GUID_LABEL *mStartLabel = NULL;
+EFI_IFR_GUID_LABEL *mEndLabel = NULL;
+UINT8 *mSignatureTypes = NULL;
+
+/**
+ Refresh the global UpdateData structure.
+
+**/
+VOID
+RefreshUpdateData (
+ VOID
+ )
+{
+ //
+ // Free current updated date
+ //
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ //
+ // Create new OpCode Handle
+ //
+ mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ mStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ mStartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+}
+
+/**
+ Clean up the dynamic opcode at label and form specified by both LabelId.
+
+ @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
+ @param[in] PrivateData Module private data.
+
+**/
+VOID
+CleanUpPage (
+ IN UINT16 FormId,
+ IN UINT16 LabelId,
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ RefreshUpdateData ();
+
+ // Remove all op-codes from dynamic page
+ mStartLabel->Number = LabelId;
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSovereignBootWizardFormSetGuid,
+ FormId,
+ mStartOpCodeHandle, // Label LabelId
+ mEndOpCodeHandle // LABEL_END
+ );
+}
+
+/**
+ Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
+ The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL
+ means not enough memory resource.
+
+ @param DevicePath Device path.
+
+ @retval NULL Not enough memory resource for AllocateCopyPool.
+ @retval Other A new allocated string that represents the file name.
+
+**/
+CHAR16 *
+ExtractFileNameFromDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CHAR16 *String;
+ CHAR16 *MatchString;
+ CHAR16 *LastMatch;
+ CHAR16 *FileName;
+ UINTN Length;
+
+ ASSERT (DevicePath != NULL);
+
+ String = UiDevicePathToStr (gPrivateData->DevPathToText, DevicePath);
+ MatchString = String;
+ LastMatch = String;
+ FileName = NULL;
+
+ while (MatchString != NULL) {
+ LastMatch = MatchString + 1;
+ MatchString = StrStr (LastMatch, L"\\");
+ }
+
+ Length = StrLen (LastMatch);
+ FileName = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), LastMatch);
+ if (FileName != NULL) {
+ *(FileName + Length) = 0;
+ }
+
+ FREE_NON_NULL (String);
+
+ return FileName;
+}
+
+/**
+ Update the form base on the selected file.
+
+ @param FilePath Point to the file path.
+ @param FormId The form need to display.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+
+**/
+BOOLEAN
+UpdatePage (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN EFI_FORM_ID FormId,
+ IN UINT16 Label
+ )
+{
+ CHAR16 *FileName;
+ EFI_STRING_ID StringToken;
+
+ FileName = NULL;
+
+ if (FilePath != NULL) {
+ FileName = ExtractFileNameFromDevicePath (FilePath);
+ }
+
+ if (FileName == NULL) {
+ //
+ // FileName = NULL has two case:
+ // 1. FilePath == NULL, not select file.
+ // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.
+ // In these two case, no need to update the form, and exit the caller function.
+ //
+ return TRUE;
+ }
+
+ StringToken = HiiSetString (gPrivateData->HiiHandle, 0, FileName, NULL);
+
+ gPrivateData->FileContext->FileName = FileName;
+
+ EfiOpenFileByDevicePath (
+ &FilePath,
+ &gPrivateData->FileContext->FHandle,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ //
+ // Create Subtitle op-code for the display string of the option.
+ //
+ RefreshUpdateData ();
+ mStartLabel->Number = Label;
+
+ HiiCreateSubTitleOpCode (
+ mStartOpCodeHandle,
+ StringToken,
+ 0,
+ 0,
+ 0
+ );
+
+ HiiUpdateForm (
+ gPrivateData->HiiHandle,
+ &gSovereignBootWizardFormSetGuid,
+ FormId,
+ mStartOpCodeHandle, // Label FormId
+ mEndOpCodeHandle // LABEL_END
+ );
+
+ return TRUE;
+}
+
+/**
+ Update the DB form base on the input file path info.
+
+ @param FilePath Point to the file path.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+**/
+BOOLEAN
+EFIAPI
+UpdateDBFromFile (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ )
+{
+ return UpdatePage (
+ FilePath,
+ SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB,
+ LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB);
+}
+
+/**
+ Update the DBX form base on the input file path info.
+
+ @param FilePath Point to the file path.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+**/
+BOOLEAN
+EFIAPI
+UpdateDBXFromFile (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ )
+{
+ return UpdatePage (
+ FilePath,
+ SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX,
+ LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX);
+}
+
+/**
+ This code cleans up enrolled file by closing file & free related resources attached to
+ enrolled file.
+
+ @param[in] FileContext FileContext cached in Sovereign Boot Wizard driver
+
+**/
+VOID
+CloseEnrolledFile (
+ IN SOVEREIGNBOOT_FILE_CONTEXT *FileContext
+ )
+{
+ if (FileContext->FHandle != NULL) {
+ CloseFile (FileContext->FHandle);
+ FileContext->FHandle = NULL;
+ }
+
+ if (FileContext->FileName != NULL) {
+ FreePool (FileContext->FileName);
+ FileContext->FileName = NULL;
+ }
+
+ FileContext->FileType = UNKNOWN_FILE_TYPE;
+}
+
+/**
+ This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix.
+
+ @param[in] FileSuffix The suffix of the input certificate file
+
+ @retval TRUE It's a DER-encoded certificate.
+ @retval FALSE It's NOT a DER-encoded certificate.
+
+**/
+BOOLEAN
+IsDerEncodeCertificate (
+ IN CONST CHAR16 *FileSuffix
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; mDerEncodedSuffix[Index] != NULL; Index++) {
+ if (StrCmp (FileSuffix, mDerEncodedSuffix[Index]) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ This code checks if the file content complies with EFI_VARIABLE_AUTHENTICATION_2 format
+The function reads file content but won't open/close given FileHandle.
+
+ @param[in] FileHandle The FileHandle to be checked
+
+ @retval TRUE The content is EFI_VARIABLE_AUTHENTICATION_2 format.
+ @retval FALSE The content is NOT a EFI_VARIABLE_AUTHENTICATION_2 format.
+
+**/
+BOOLEAN
+IsAuthentication2Format (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_VARIABLE_AUTHENTICATION_2 *Auth2;
+ BOOLEAN IsAuth2Format;
+
+ IsAuth2Format = FALSE;
+
+ //
+ // Read the whole file content
+ //
+ Status = ReadFile (
+ FileHandle,
+ (VOID **)&mImageBase,
+ &mImageSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Auth2 = (EFI_VARIABLE_AUTHENTICATION_2 *)mImageBase;
+ if (Auth2->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) {
+ goto ON_EXIT;
+ }
+
+ if (CompareGuid (&gEfiCertPkcs7Guid, &Auth2->AuthInfo.CertType)) {
+ IsAuth2Format = TRUE;
+ }
+
+ON_EXIT:
+ //
+ // Do not close File. simply check file content
+ //
+ FREE_NON_NULL (mImageBase);
+
+ return IsAuth2Format;
+}
+
+/**
+ This code checks if the encode type and key strength of X.509
+ certificate is qualified.
+
+ @param[in] X509FileContext FileContext of X.509 certificate storing
+ file.
+ @param[out] Error Error type checked in the certificate.
+
+ @return EFI_SUCCESS The certificate checked successfully.
+ @return EFI_INVALID_PARAMETER The parameter is invalid.
+ @return EFI_OUT_OF_RESOURCES Memory allocation failed.
+
+**/
+EFI_STATUS
+CheckX509Certificate (
+ IN SOVEREIGNBOOT_FILE_CONTEXT *X509FileContext,
+ OUT ENROLL_KEY_ERROR *Error
+ )
+{
+ EFI_STATUS Status;
+ UINT16 *FilePostFix;
+ UINTN NameLength;
+ UINT8 *X509Data;
+ UINTN X509DataSize;
+ void *X509PubKey;
+ UINTN PubKeyModSize;
+
+ if (X509FileContext->FileName == NULL) {
+ *Error = Unsupported_Type;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ X509Data = NULL;
+ X509DataSize = 0;
+ X509PubKey = NULL;
+ PubKeyModSize = 0;
+
+ //
+ // Parse the file's postfix. Only support DER encoded X.509 certificate files.
+ //
+ NameLength = StrLen (X509FileContext->FileName);
+ if (NameLength <= 4) {
+ DEBUG ((DEBUG_ERROR, "Wrong X509 NameLength\n"));
+ *Error = Unsupported_Type;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FilePostFix = X509FileContext->FileName + NameLength - 4;
+ if (!IsDerEncodeCertificate (FilePostFix)) {
+ DEBUG ((DEBUG_ERROR, "Unsupported file type, only DER encoded certificate (%s) is supported.\n", mSupportX509Suffix));
+ *Error = Unsupported_Type;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_INFO, "FileName= %s\n", X509FileContext->FileName));
+ DEBUG ((DEBUG_INFO, "FilePostFix = %s\n", FilePostFix));
+
+ //
+ // Read the certificate file content
+ //
+ Status = ReadFile (X509FileContext->FHandle, (VOID **)&X509Data, &X509DataSize, 0);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error occurred while reading the file.\n"));
+ goto ON_EXIT;
+ }
+
+ //
+ // Parse the public key context.
+ //
+ if (RsaGetPublicKeyFromX509 (X509Data, X509DataSize, &X509PubKey) == FALSE) {
+ DEBUG ((DEBUG_ERROR, "Error occurred while parsing the pubkey from certificate.\n"));
+ Status = EFI_INVALID_PARAMETER;
+ *Error = Unsupported_Type;
+ goto ON_EXIT;
+ }
+
+ //
+ // Parse Module size of public key using interface provided by CryptoPkg, which is
+ // actually the size of public key.
+ //
+ if (X509PubKey != NULL) {
+ RsaGetKey (X509PubKey, RsaKeyN, NULL, &PubKeyModSize);
+ if (PubKeyModSize < CER_PUBKEY_MIN_SIZE) {
+ DEBUG ((DEBUG_ERROR, "Unqualified PK size, key size should be equal to or greater than 2048 bits.\n"));
+ Status = EFI_INVALID_PARAMETER;
+ *Error = Unqualified_Key;
+ }
+
+ RsaFree (X509PubKey);
+ }
+
+ON_EXIT:
+ FREE_NON_NULL (X509Data);
+
+ return Status;
+}
+
+/**
+ Enroll a new X509 certificate into Signature Database (DB or DBX or DBT) without
+ KEK's authentication.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollX509toSigDB (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ UINTN X509DataSize;
+ VOID *X509Data;
+ EFI_SIGNATURE_LIST *SigDBCert;
+ EFI_SIGNATURE_DATA *SigDBCertData;
+ VOID *Data;
+ UINTN DataSize;
+ UINTN SigDBSize;
+ UINT32 Attr;
+ EFI_TIME Time;
+
+ X509DataSize = 0;
+ SigDBSize = 0;
+ DataSize = 0;
+ X509Data = NULL;
+ SigDBCert = NULL;
+ SigDBCertData = NULL;
+ Data = NULL;
+
+ Status = ReadFile (
+ Private->FileContext->FHandle,
+ &X509Data,
+ &X509DataSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ ASSERT (X509Data != NULL);
+
+ SigDBSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+
+ Data = AllocateZeroPool (SigDBSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ SigDBCert = (EFI_SIGNATURE_LIST *)Data;
+ SigDBCert->SignatureListSize = (UINT32)SigDBSize;
+ SigDBCert->SignatureHeaderSize = 0;
+ SigDBCert->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&SigDBCert->SignatureType, &gEfiCertX509Guid);
+
+ SigDBCertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigDBCert + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&SigDBCertData->SignatureOwner, &gSovereignBootWizardFormSetGuid);
+ CopyMem ((UINT8 *)(SigDBCertData->SignatureData), X509Data, X509DataSize);
+
+ //
+ // Check if signature database entry has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+ Status = GetCurrentTime (&Time);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **)&Data, &Time);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ Attr,
+ SigDBSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ CloseEnrolledFile (Private->FileContext);
+
+ FREE_NON_NULL (Data);
+ FREE_NON_NULL (X509Data);
+
+ return Status;
+}
+
+/**
+ Check whether the signature list exists in given variable data.
+
+ It searches the signature list for the certificate hash by CertType.
+ If the signature list is found, get the offset of Database for the
+ next hash of a certificate.
+
+ @param[in] Database Variable data to save signature list.
+ @param[in] DatabaseSize Variable size.
+ @param[in] SignatureType The type of the signature.
+ @param[out] Offset The offset to save a new hash of certificate.
+
+ @return TRUE The signature list is found in the forbidden database.
+ @return FALSE The signature list is not found in the forbidden database.
+**/
+BOOLEAN
+GetSignaturelistOffset (
+ IN EFI_SIGNATURE_LIST *Database,
+ IN UINTN DatabaseSize,
+ IN EFI_GUID *SignatureType,
+ OUT UINTN *Offset
+ )
+{
+ EFI_SIGNATURE_LIST *SigList;
+ UINTN SiglistSize;
+
+ if ((Database == NULL) || (DatabaseSize == 0)) {
+ *Offset = 0;
+ return FALSE;
+ }
+
+ SigList = Database;
+ SiglistSize = DatabaseSize;
+ while ((SiglistSize > 0) && (SiglistSize >= SigList->SignatureListSize)) {
+ if (CompareGuid (&SigList->SignatureType, SignatureType)) {
+ *Offset = DatabaseSize - SiglistSize;
+ return TRUE;
+ }
+
+ SiglistSize -= SigList->SignatureListSize;
+ SigList = (EFI_SIGNATURE_LIST *)((UINT8 *)SigList + SigList->SignatureListSize);
+ }
+
+ *Offset = 0;
+ return FALSE;
+}
+
+/**
+ Enroll a new X509 certificate hash into Signature Database (dbx) without
+ KEK's authentication.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] HashAlg The hash algorithm to enroll the certificate.
+ @param[in] RevocationDate The revocation date of the certificate.
+ @param[in] RevocationTime The revocation time of the certificate.
+ @param[in] AlwaysRevocation Indicate whether the certificate is always revoked.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollX509HashtoSigDB (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN UINT32 HashAlg,
+ IN EFI_HII_DATE *RevocationDate,
+ IN EFI_HII_TIME *RevocationTime,
+ IN BOOLEAN AlwaysRevocation
+ )
+{
+ EFI_STATUS Status;
+ UINTN X509DataSize;
+ VOID *X509Data;
+ EFI_SIGNATURE_LIST *SignatureList;
+ UINTN SignatureListSize;
+ UINT8 *Data;
+ UINT8 *NewData;
+ UINTN DataSize;
+ UINTN DbSize;
+ UINT32 Attr;
+ EFI_SIGNATURE_DATA *SignatureData;
+ UINTN SignatureSize;
+ EFI_GUID SignatureType;
+ UINTN Offset;
+ UINT8 CertHash[MAX_DIGEST_SIZE];
+ UINT16 *FilePostFix;
+ UINTN NameLength;
+ EFI_TIME *Time;
+ EFI_TIME NewTime;
+
+ X509DataSize = 0;
+ DbSize = 0;
+ X509Data = NULL;
+ SignatureData = NULL;
+ SignatureList = NULL;
+ Data = NULL;
+ NewData = NULL;
+
+ if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Parse the file's postfix.
+ //
+ NameLength = StrLen (Private->FileContext->FileName);
+ if (NameLength <= 4) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FilePostFix = Private->FileContext->FileName + NameLength - 4;
+ if (!IsDerEncodeCertificate (FilePostFix)) {
+ //
+ // Only supports DER-encoded X509 certificate.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Get the certificate from file and calculate its hash.
+ //
+ Status = ReadFile (
+ Private->FileContext->FHandle,
+ &X509Data,
+ &X509DataSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ ASSERT (X509Data != NULL);
+
+ if (!CalculateCertHash (X509Data, X509DataSize, HashAlg, CertHash)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Get the variable for enrollment.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Data = (UINT8 *)AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ }
+
+ //
+ // Allocate memory for Signature and fill the Signature
+ //
+ SignatureSize = sizeof (EFI_SIGNATURE_DATA) - 1 + sizeof (EFI_TIME) + GetDigestLength(HashAlg);
+ SignatureData = (EFI_SIGNATURE_DATA *)AllocateZeroPool (SignatureSize);
+ if (SignatureData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyGuid (&SignatureData->SignatureOwner, &gSovereignBootWizardFormSetGuid);
+ CopyMem (SignatureData->SignatureData, CertHash, GetDigestLength(HashAlg));
+
+ //
+ // Fill the time.
+ //
+ if (!AlwaysRevocation) {
+ Time = (EFI_TIME *)(&SignatureData->SignatureData + GetDigestLength(HashAlg));
+ Time->Year = RevocationDate->Year;
+ Time->Month = RevocationDate->Month;
+ Time->Day = RevocationDate->Day;
+ Time->Hour = RevocationTime->Hour;
+ Time->Minute = RevocationTime->Minute;
+ Time->Second = RevocationTime->Second;
+ }
+
+ //
+ // Determine the GUID for certificate hash.
+ //
+ switch (HashAlg) {
+ case HASHALG_SHA256:
+ SignatureType = gEfiCertX509Sha256Guid;
+ break;
+ case HASHALG_SHA384:
+ SignatureType = gEfiCertX509Sha384Guid;
+ break;
+ case HASHALG_SHA512:
+ SignatureType = gEfiCertX509Sha512Guid;
+ break;
+ default:
+ return FALSE;
+ }
+
+ //
+ // Add signature into the new variable data buffer
+ //
+ if (GetSignaturelistOffset ((EFI_SIGNATURE_LIST *)Data, DataSize, &SignatureType, &Offset)) {
+ //
+ // Add the signature to the found signaturelist.
+ //
+ DbSize = DataSize + SignatureSize;
+ NewData = AllocateZeroPool (DbSize);
+ if (NewData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ SignatureList = (EFI_SIGNATURE_LIST *)(Data + Offset);
+ SignatureListSize = (UINTN)ReadUnaligned32 ((UINT32 *)&SignatureList->SignatureListSize);
+ CopyMem (NewData, Data, Offset + SignatureListSize);
+
+ SignatureList = (EFI_SIGNATURE_LIST *)(NewData + Offset);
+ WriteUnaligned32 ((UINT32 *)&SignatureList->SignatureListSize, (UINT32)(SignatureListSize + SignatureSize));
+
+ Offset += SignatureListSize;
+ CopyMem (NewData + Offset, SignatureData, SignatureSize);
+ CopyMem (NewData + Offset + SignatureSize, Data + Offset, DataSize - Offset);
+
+ FREE_NON_NULL (Data);
+ Data = NewData;
+ DataSize = DbSize;
+ } else {
+ //
+ // Create a new signaturelist, and add the signature into the signaturelist.
+ //
+ DbSize = DataSize + sizeof (EFI_SIGNATURE_LIST) + SignatureSize;
+ NewData = AllocateZeroPool (DbSize);
+ if (NewData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ SignatureList = (EFI_SIGNATURE_LIST *)(NewData + DataSize);
+ SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + SignatureSize;
+ WriteUnaligned32 ((UINT32 *)&SignatureList->SignatureListSize, (UINT32)SignatureListSize);
+ WriteUnaligned32 ((UINT32 *)&SignatureList->SignatureSize, (UINT32)SignatureSize);
+ CopyGuid (&SignatureList->SignatureType, &SignatureType);
+ CopyMem ((UINT8 *)SignatureList + sizeof (EFI_SIGNATURE_LIST), SignatureData, SignatureSize);
+ if ((DataSize != 0) && (Data != NULL)) {
+ CopyMem (NewData, Data, DataSize);
+ FreePool (Data);
+ }
+
+ Data = NewData;
+ DataSize = DbSize;
+ }
+
+ Status = GetCurrentTime (&NewTime);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = CreateTimeBasedPayload (&DataSize, (UINT8 **)&Data, &NewTime);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+ Status = gRT->SetVariable (
+ EFI_IMAGE_SECURITY_DATABASE1,
+ &gEfiImageSecurityDatabaseGuid,
+ Attr,
+ DataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ CloseEnrolledFile (Private->FileContext);
+
+ FREE_NON_NULL (Data);
+ FREE_NON_NULL (SignatureData);
+ FREE_NON_NULL (X509Data);
+
+ return Status;
+}
+
+/**
+ Check whether a certificate from a file exists in dbx.
+
+ @param[in] PrivateData The module's private data.
+
+ @retval TRUE The X509 certificate is found in dbx successfully.
+ @retval FALSE The X509 certificate is not found in dbx.
+**/
+BOOLEAN
+IsX509CertInDbx (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ UINTN X509DataSize;
+ VOID *X509Data;
+ BOOLEAN IsFound;
+
+ //
+ // Read the certificate from file
+ //
+ X509DataSize = 0;
+ X509Data = NULL;
+ Status = ReadFile (
+ Private->FileContext->FHandle,
+ &X509Data,
+ &X509DataSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ //
+ // Check the raw certificate.
+ //
+ IsFound = FALSE;
+ Status = IsSignatureFoundInDatabase (
+ EFI_IMAGE_SECURITY_DATABASE1,
+ X509Data,
+ &gEfiCertX509Guid,
+ X509DataSize,
+ &IsFound);
+ if (EFI_ERROR (Status)) {
+ IsFound = FALSE;
+ goto ON_EXIT;
+ }
+
+ if (IsFound) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Check the hash of certificate.
+ //
+ IsFound = FALSE;
+ Status = IsCertHashFoundInDbx (
+ X509Data,
+ X509DataSize,
+ NULL,
+ 0,
+ NULL,
+ &IsFound);
+ if (EFI_ERROR (Status)) {
+ IsFound = FALSE;
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ FREE_NON_NULL (X509Data);
+
+ return IsFound;
+}
+
+/**
+ Enroll a new signature of executable into Signature Database.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1
+ or EFI_IMAGE_SECURITY_DATABASE2.
+
+ @retval EFI_SUCCESS New signature is enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported command.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollAuthentication2Descriptor (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINTN DataSize;
+ UINT32 Attr;
+
+ Data = NULL;
+
+ //
+ // DBT only support DER-X509 Cert Enrollment
+ //
+ if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Read the whole file content
+ //
+ Status = ReadFile (
+ Private->FileContext->FHandle,
+ (VOID **)&mImageBase,
+ &mImageSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ ASSERT (mImageBase != NULL);
+
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+
+ //
+ // Check if SigDB variable has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Directly set AUTHENTICATION_2 data to SetVariable
+ //
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ Attr,
+ mImageSize,
+ mImageBase
+ );
+
+ DEBUG ((DEBUG_INFO, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName, Status));
+
+ON_EXIT:
+
+ CloseEnrolledFile (Private->FileContext);
+
+ FREE_NON_NULL (Data);
+ FREE_NON_NULL (mImageBase);
+
+ return Status;
+}
+
+/**
+ Enroll a new signature of executable into Signature Database.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1
+ or EFI_IMAGE_SECURITY_DATABASE2.
+
+ @retval EFI_SUCCESS New signature is enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported command.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollImageSignatureToSigDB (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *SigDBCert;
+ EFI_SIGNATURE_DATA *SigDBCertData;
+ VOID *Data;
+ UINTN DataSize;
+ UINTN SigDBSize;
+ UINT32 Attr;
+ WIN_CERTIFICATE_UEFI_GUID *GuidCertData;
+ WIN_CERTIFICATE_EFI_PKCS *PkcsCertData;
+ EFI_TIME Time;
+ UINT32 HashAlg;
+ EFI_GUID CertType;
+ UINTN ImageDigestSize;
+ UINT8 ImageDigest[MAX_DIGEST_SIZE];
+
+ Data = NULL;
+ GuidCertData = NULL;
+
+ if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE2) == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Form the SigDB certificate list.
+ // Format the data item into EFI_SIGNATURE_LIST type.
+ //
+ // We need to parse signature data of executable from specified signed executable file.
+ // In current implementation, we simply trust the pass-in signed executable file.
+ // In reality, it's OS's responsibility to verify the signed executable file.
+ //
+
+ //
+ // Read the whole file content
+ //
+ Status = ReadFile (
+ Private->FileContext->FHandle,
+ (VOID **)&mImageBase,
+ &mImageSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ ASSERT (mImageBase != NULL);
+
+ Status = GetImageSecDataDir (mImageBase, mImageSize, (EFI_IMAGE_DATA_DIRECTORY **)&mSecDataDir);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ if (mSecDataDir->SizeOfCert == 0) {
+ Status = EFI_SECURITY_VIOLATION;
+ HashAlg = HASHALG_MAX;
+ while (HashAlg > 0) {
+ HashAlg--;
+
+ if (HashPeImage (mImageBase, mImageSize, HashAlg, ImageDigest, &ImageDigestSize, &CertType)) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to get hash digest: %r", Status));
+ goto ON_EXIT;
+ }
+ } else {
+ //
+ // Read the certificate data
+ //
+ mCertificate = (WIN_CERTIFICATE *)(mImageBase + mSecDataDir->Offset);
+
+ if (mCertificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) {
+ GuidCertData = (WIN_CERTIFICATE_UEFI_GUID *)mCertificate;
+ if (CompareMem (&GuidCertData->CertType, &gEfiCertTypeRsa2048Sha256Guid, sizeof (EFI_GUID)) != 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ if (!HashPeImage (mImageBase, mImageSize, HASHALG_SHA256, ImageDigest, &ImageDigestSize, &CertType)) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ } else if (mCertificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
+ PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *)mCertificate;
+ if (PkcsCertData->Hdr.dwLength <= sizeof (PkcsCertData->Hdr)) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ Status = HashPeImageByType (
+ mImageBase,
+ mImageSize,
+ PkcsCertData->CertData,
+ PkcsCertData->Hdr.dwLength - sizeof (PkcsCertData->Hdr),
+ ImageDigest,
+ &ImageDigestSize,
+ &CertType);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ } else {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ }
+
+ //
+ // Create a new SigDB entry.
+ //
+ SigDBSize = sizeof (EFI_SIGNATURE_LIST)
+ + sizeof (EFI_SIGNATURE_DATA) - 1
+ + (UINT32)ImageDigestSize;
+
+ Data = (UINT8 *)AllocateZeroPool (SigDBSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Adjust the Certificate Database parameters.
+ //
+ SigDBCert = (EFI_SIGNATURE_LIST *)Data;
+ SigDBCert->SignatureListSize = (UINT32)SigDBSize;
+ SigDBCert->SignatureHeaderSize = 0;
+ SigDBCert->SignatureSize = sizeof (EFI_SIGNATURE_DATA) - 1 + (UINT32)ImageDigestSize;
+ CopyGuid (&SigDBCert->SignatureType, &CertType);
+
+ SigDBCertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigDBCert + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&SigDBCertData->SignatureOwner, &gSovereignBootWizardFormSetGuid);
+ CopyMem (SigDBCertData->SignatureData, ImageDigest, ImageDigestSize);
+
+ Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+ Status = GetCurrentTime (&Time);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **)&Data, &Time);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
+ goto ON_EXIT;
+ }
+
+ //
+ // Check if SigDB variable has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Enroll the variable.
+ //
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ Attr,
+ SigDBSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ CloseEnrolledFile (Private->FileContext);
+
+ FREE_NON_NULL (Data);
+ FREE_NON_NULL (mImageBase);
+
+ return Status;
+}
+
+/**
+ Enroll signature into DB/DBX/DBT without KEK's authentication.
+ The SignatureOwner GUID will be SovereignBootWizardFormsetGuid.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
+
+ @retval EFI_SUCCESS New signature enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval others Fail to enroll signature data.
+
+**/
+EFI_STATUS
+EnrollSignatureDatabase (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ UINT16 *FilePostFix;
+ EFI_STATUS Status;
+ UINTN NameLength;
+
+ if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Parse the file's postfix.
+ //
+ NameLength = StrLen (Private->FileContext->FileName);
+ if (NameLength <= 4) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FilePostFix = Private->FileContext->FileName + NameLength - 4;
+ if (IsDerEncodeCertificate (FilePostFix)) {
+ //
+ // Supports DER-encoded X509 certificate.
+ //
+ return EnrollX509toSigDB (Private, VariableName);
+ } else if (IsAuthentication2Format (Private->FileContext->FHandle)) {
+ return EnrollAuthentication2Descriptor (Private, VariableName);
+ } else {
+ return EnrollImageSignatureToSigDB (Private, VariableName);
+ }
+}
+
+/**
+ List all signatures in specified signature database (e.g. KEK/DB/DBX/DBT)
+ by GUID in the page for user to select and delete as needed.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the vendor's signature database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+
+**/
+EFI_STATUS
+UpdateDeletePage (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINTN GuidIndex;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ UINTN DataSize;
+ UINT8 *Data;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *DataWalker;
+ UINT32 ItemDataSize;
+ EFI_STRING_ID HelpStringId;
+ EFI_STRING_ID FormatStringId;
+ EFI_STRING_ID EntryTypeStringId;
+ EFI_STRING EntryTypeString;
+ EFI_STRING FormatNameString;
+ UINT8 SignatureType;
+ CHAR16 *CertCN;
+ CHAR16 NameBuffer[BUFFER_MAX_SIZE];
+
+ Data = NULL;
+ CertList = NULL;
+ DataWalker = NULL;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+ FormatNameString = NULL;
+ EntryTypeString = NULL;
+ //
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LabelNumber;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ //
+ // Read Variable.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ goto ON_EXIT;
+ }
+
+ Data = (UINT8 *)AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Enumerate all DB data.
+ //
+ ItemDataSize = (UINT32)DataSize;
+ CertList = (EFI_SIGNATURE_LIST *)Data;
+ GuidIndex = 0;
+
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ SignatureType = GetSignatureFormat(CertList, NULL, &FormatStringId, &EntryTypeStringId);
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+
+ FormatNameString = HiiGetString (PrivateData->HiiHandle, FormatStringId, NULL);
+ EntryTypeString = HiiGetString (PrivateData->HiiHandle, EntryTypeStringId, NULL);
+ if ((FormatNameString == NULL) || (EntryTypeString == NULL)) {
+ goto ON_EXIT;
+ }
+
+ for (Index = 0; Index < SIGNATURE_DATA_COUNTS (CertList); Index = Index + 1) {
+ //
+ // Format name buffer.
+ //
+ ZeroMem (NameBuffer, sizeof (NameBuffer));
+ if (SignatureType == SIGNATURE_TYPE_X509) {
+ CertCN = NULL;
+ if (!EFI_ERROR (GetCommonNameFromX509 (CertList, DataWalker, &CertCN)) && (StrLen(CertCN) > 0)) {
+ UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, GuidIndex + 1, CertCN);
+ } else {
+ UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, GuidIndex + 1, EntryTypeString);
+ }
+ FREE_NON_NULL (CertCN);
+ } else {
+ UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, GuidIndex + 1, EntryTypeString);
+ }
+
+ //
+ // Format help info buffer.
+ //
+ Status = FormatHelpInfo (PrivateData, CertList, DataWalker, &HelpStringId);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle,
+ (EFI_QUESTION_ID)(QuestionIdBase + GuidIndex++),
+ 0,
+ 0,
+ HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
+ HelpStringId,
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ ZeroMem (NameBuffer, BUFFER_MAX_SIZE);
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + CertList->SignatureSize);
+ }
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
+ }
+
+ON_EXIT:
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSovereignBootWizardFormSetGuid,
+ FormId,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ FREE_NON_OPCODE (StartOpCodeHandle);
+ FREE_NON_OPCODE (EndOpCodeHandle);
+
+ FREE_NON_NULL (Data);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Delete a signature entry from signature database.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the vendor's signature database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+ @param[in] DeleteIndex Signature index to delete.
+
+ @retval EFI_SUCCESS Delete signature successfully.
+ @retval EFI_NOT_FOUND Can't find the signature item,
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+**/
+EFI_STATUS
+DeleteSignature (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase,
+ IN UINTN DeleteIndex
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT8 *Data;
+ UINT8 *OldData;
+ UINT32 Attr;
+ UINT32 Index;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_LIST *NewCertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINTN CertCount;
+ UINT32 Offset;
+ BOOLEAN IsItemFound;
+ UINT32 ItemDataSize;
+ UINTN GuidIndex;
+ EFI_TIME Time;
+
+ Data = NULL;
+ OldData = NULL;
+ CertList = NULL;
+ Cert = NULL;
+ Attr = 0;
+
+ Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get original signature list data.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ goto ON_EXIT;
+ }
+
+ OldData = (UINT8 *)AllocateZeroPool (DataSize);
+ if (OldData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Allocate space for new variable.
+ //
+ Data = (UINT8 *)AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Enumerate all signature data and erasing the target item.
+ //
+ IsItemFound = FALSE;
+ ItemDataSize = (UINT32)DataSize;
+ CertList = (EFI_SIGNATURE_LIST *)OldData;
+ Offset = 0;
+ GuidIndex = 0;
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertRsa2048Sha256Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertSha1Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertSha224Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertSha384Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertSha256Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertSha512Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertSm3Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha256Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha384Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertX509Sha512Guid) ||
+ CompareGuid (&CertList->SignatureType, &gEfiCertX509Sm3Guid)
+ )
+ {
+ //
+ // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
+ //
+ CopyMem (Data + Offset, CertList, (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
+ NewCertList = (EFI_SIGNATURE_LIST *)(Data + Offset);
+ Offset += (sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ if (GuidIndex == DeleteIndex) {
+ //
+ // Find it! Skip it!
+ //
+ NewCertList->SignatureListSize -= CertList->SignatureSize;
+ IsItemFound = TRUE;
+ } else {
+ //
+ // This item doesn't match. Copy it to the Data buffer.
+ //
+ CopyMem (Data + Offset, (UINT8 *)(Cert), CertList->SignatureSize);
+ Offset += CertList->SignatureSize;
+ }
+
+ GuidIndex++;
+ Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
+ }
+ } else {
+ //
+ // This List doesn't match. Just copy it to the Data buffer.
+ //
+ CopyMem (Data + Offset, (UINT8 *)(CertList), CertList->SignatureListSize);
+ Offset += CertList->SignatureListSize;
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
+ }
+
+ if (!IsItemFound) {
+ //
+ // Doesn't find the signature Item!
+ //
+ Status = EFI_NOT_FOUND;
+ goto ON_EXIT;
+ }
+
+ //
+ // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
+ //
+ ItemDataSize = Offset;
+ CertList = (EFI_SIGNATURE_LIST *)Data;
+ Offset = 0;
+ ZeroMem (OldData, ItemDataSize);
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));
+ if (CertCount != 0) {
+ CopyMem (OldData + Offset, (UINT8 *)(CertList), CertList->SignatureListSize);
+ Offset += CertList->SignatureListSize;
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
+ }
+
+ DataSize = Offset;
+ if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
+ Status = GetCurrentTime (&Time);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = CreateTimeBasedPayload (&DataSize, &OldData, &Time);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
+ goto ON_EXIT;
+ }
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ Attr,
+ DataSize,
+ OldData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ FREE_NON_NULL (Data);
+ FREE_NON_NULL (OldData);
+
+ return UpdateDeletePage (
+ PrivateData,
+ VariableName,
+ VendorGuid,
+ LabelNumber,
+ FormId,
+ QuestionIdBase
+ );
+}
+
+/**
+ This function to delete signature list or data, according by DelType.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] DelType Indicate delete signature list or data.
+ @param[in] CheckedCount Indicate how many signature data have
+ been checked in current signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+DeleteSignatureEx (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN SIGNATURE_DELETE_TYPE DelType,
+ IN UINT32 CheckedCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_SIGNATURE_LIST *NewCertList;
+ EFI_SIGNATURE_DATA *DataWalker;
+ CHAR16 VariableName[BUFFER_MAX_SIZE];
+ UINT32 VariableAttr;
+ UINTN VariableDataSize;
+ UINTN RemainingSize;
+ UINTN ListIndex;
+ UINTN Index;
+ UINTN Offset;
+ UINT8 *VariableData;
+ UINT8 *NewVariableData;
+ EFI_TIME Time;
+
+ Status = EFI_SUCCESS;
+ VariableAttr = 0;
+ VariableDataSize = 0;
+ ListIndex = 0;
+ Offset = 0;
+ VariableData = NULL;
+ NewVariableData = NULL;
+
+ if (PrivateData->VariableName == Variable_DB) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
+ } else {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ &VariableAttr,
+ &VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ goto ON_EXIT;
+ }
+
+ VariableData = AllocateZeroPool (VariableDataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ &VariableAttr,
+ &VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = SetSecureBootMode (CUSTOM_SECURE_BOOT_MODE);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ NewVariableData = AllocateZeroPool (VariableDataSize);
+ if (NewVariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ RemainingSize = VariableDataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)(VariableData);
+ if (DelType == Delete_Signature_List_All) {
+ VariableDataSize = 0;
+ } else {
+ //
+ // Traverse to target EFI_SIGNATURE_LIST but others will be skipped.
+ //
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex < PrivateData->ListIndex) {
+ CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, ListWalker->SignatureListSize);
+ Offset += ListWalker->SignatureListSize;
+
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ ListIndex++;
+ }
+
+ //
+ // Handle the target EFI_SIGNATURE_LIST.
+ // If CheckedCount == SIGNATURE_DATA_COUNTS (ListWalker) or DelType == Delete_Signature_List_One
+ // it means delete the whole EFI_SIGNATURE_LIST, So we just skip this EFI_SIGNATURE_LIST.
+ //
+ if ((CheckedCount < SIGNATURE_DATA_COUNTS (ListWalker)) && (DelType == Delete_Signature_Data)) {
+ NewCertList = (EFI_SIGNATURE_LIST *)(NewVariableData + Offset);
+ //
+ // Copy header.
+ //
+ CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ Offset += sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize;
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ for (Index = 0; Index < SIGNATURE_DATA_COUNTS (ListWalker); Index = Index + 1) {
+ if (PrivateData->CheckArray[Index]) {
+ //
+ // Delete checked signature data, and update the size of whole signature list.
+ //
+ NewCertList->SignatureListSize -= NewCertList->SignatureSize;
+ } else {
+ //
+ // Remain the unchecked signature data.
+ //
+ CopyMem ((UINT8 *)NewVariableData + Offset, DataWalker, ListWalker->SignatureSize);
+ Offset += ListWalker->SignatureSize;
+ }
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
+ }
+ }
+
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+
+ //
+ // Copy remaining data, maybe 0.
+ //
+ CopyMem ((UINT8 *)NewVariableData + Offset, ListWalker, RemainingSize);
+ Offset += RemainingSize;
+
+ VariableDataSize = Offset;
+ }
+
+ if ((VariableAttr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
+ Status = GetCurrentTime (&Time);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+ goto ON_EXIT;
+ }
+
+ Status = CreateTimeBasedPayload (&VariableDataSize, &NewVariableData, &Time);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
+ goto ON_EXIT;
+ }
+ }
+
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ VariableAttr,
+ VariableDataSize,
+ NewVariableData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r", Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ FREE_NON_NULL (VariableData);
+ FREE_NON_NULL (NewVariableData);
+
+ return Status;
+}
+
+/**
+ This function extracts configuration from variable.
+
+ @param[in] Private Point to Sovereign Boot configuration driver private data.
+ @param[in, out] FormData Point to Sovereign Boot form private data.
+
+**/
+VOID
+InteractiveModeExtractConfig (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN OUT SOVEREIGN_BOOT_WIZARD_FORM_DATA *FormData
+ )
+{
+ EFI_TIME CurrTime;
+
+ //
+ // Initialize the Date and Time using system time.
+ //
+ FormData->CertificateFormat = HASHALG_RAW;
+ FormData->AlwaysRevocation = TRUE;
+ gRT->GetTime (&CurrTime, NULL);
+ FormData->RevocationDate.Year = CurrTime.Year;
+ FormData->RevocationDate.Month = CurrTime.Month;
+ FormData->RevocationDate.Day = CurrTime.Day;
+ FormData->RevocationTime.Hour = CurrTime.Hour;
+ FormData->RevocationTime.Minute = CurrTime.Minute;
+ FormData->RevocationTime.Second = 0;
+ if (Private->FileContext->FHandle != NULL) {
+ FormData->FileEnrollType = Private->FileContext->FileType;
+ } else {
+ FormData->FileEnrollType = UNKNOWN_FILE_TYPE;
+ }
+
+ FormData->ListCount = Private->ListCount;
+}
+
+UINT8
+GetSignatureFormat (
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN OUT EFI_STRING_ID *ListFormat OPTIONAL,
+ IN OUT EFI_STRING_ID *EntryFormat OPTIONAL,
+ IN OUT EFI_STRING_ID *ListType OPTIONAL
+ )
+{
+ EFI_STRING_ID ListTypeId;
+ EFI_STRING_ID ListFormatId;
+ EFI_STRING_ID EntryFormatId;
+ UINT8 SignatureType;
+
+ if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa2048Guid)) {
+ SignatureType = SIGNATURE_TYPE_RSA2048;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_RSA2048);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_RSA_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_RSA_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa2048Sha256Guid)) {
+ SignatureType = SIGNATURE_TYPE_RSA2048_SHA256;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_RSA2048_SHA256);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_RSA_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_RSA_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Guid)) {
+ SignatureType = SIGNATURE_TYPE_X509;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_CERT_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_CERT_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha1Guid)) {
+ SignatureType = SIGNATURE_TYPE_SHA1;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA1);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha224Guid)) {
+ SignatureType = SIGNATURE_TYPE_SHA224;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA224);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
+ SignatureType = SIGNATURE_TYPE_SHA256;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA256);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid)) {
+ SignatureType = SIGNATURE_TYPE_SHA384;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA384);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid)) {
+ SignatureType = SIGNATURE_TYPE_SHA512;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SHA512);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSm3Guid)) {
+ SignatureType = SIGNATURE_TYPE_SM3;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_SM3);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) {
+ SignatureType = SIGNATURE_TYPE_X509_SHA256;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA256);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_CERT_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_CERT_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha384Guid)) {
+ SignatureType = SIGNATURE_TYPE_X509_SHA384;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA384);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_CERT_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_CERT_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha512Guid)) {
+ SignatureType = SIGNATURE_TYPE_X509_SHA512;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SHA512);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_CERT_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_CERT_HASH_NAME_FORMAT);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sm3Guid)) {
+ SignatureType = SIGNATURE_TYPE_X509_SM3;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_X509_SM3);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_CERT_HASH_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_CERT_HASH_NAME_FORMAT);
+ } else {
+ SignatureType = SIGNATURE_TYPE_UNKNOWN;
+ ListTypeId = STRING_TOKEN(STR_LIST_TYPE_UNKNOWN);
+ EntryFormatId = STRING_TOKEN(STR_SIGNATURE_DATA_UNKNOWN_NAME_FORMAT);
+ ListFormatId = STRING_TOKEN(STR_SIGNATURE_LIST_UNKNOWN_NAME_FORMAT);
+ }
+
+ if (ListFormat != NULL) {
+ *ListFormat = ListFormatId;
+ }
+
+ if (EntryFormat != NULL) {
+ *EntryFormat = EntryFormatId;
+ }
+
+ if (ListType != NULL) {
+ *ListType = ListTypeId;
+ }
+
+ return SignatureType;
+}
+
+/**
+ This function to load signature list, the update the menu page.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] LabelId Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadSignatureList (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN UINT16 LabelId,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_STRING_ID ListType;
+ EFI_STRING_ID FormatNameStringId;
+ EFI_STRING FormatNameString;
+ EFI_STRING FormatHelpString;
+ EFI_STRING FormatTypeString;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ EFI_IFR_GUID_LABEL *StartGoto;
+ EFI_IFR_GUID_LABEL *EndGoto;
+ EFI_FORM_ID DstFormId;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ VOID *StartGotoHandle;
+ VOID *EndGotoHandle;
+ UINTN DataSize;
+ UINTN RemainingSize;
+ UINT16 Index;
+ UINT8 *VariableData;
+ CHAR16 VariableName[BUFFER_MAX_SIZE];
+ CHAR16 NameBuffer[BUFFER_MAX_SIZE];
+ CHAR16 HelpBuffer[BUFFER_MAX_SIZE];
+ BOOLEAN GotoList;
+
+ Status = EFI_SUCCESS;
+ FormatNameString = NULL;
+ FormatHelpString = NULL;
+ FormatTypeString = NULL;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+ StartGotoHandle = NULL;
+ EndGotoHandle = NULL;
+ Index = 0;
+ VariableData = NULL;
+
+ GotoList = (LabelId == LABEL_DB_CERTS_DATA_START) ||
+ (LabelId == LABEL_DBX_CERTS_DATA_START);
+
+ //
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ if (!GotoList) {
+ StartGotoHandle = HiiAllocateOpCodeHandle ();
+ if (StartGotoHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndGotoHandle = HiiAllocateOpCodeHandle ();
+ if (EndGotoHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+ }
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LabelId;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ if (!GotoList) {
+ StartGoto = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartGotoHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartGoto->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartGoto->Number = LABEL_DELETE_ALL_LIST_BUTTON;
+
+ EndGoto = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndGotoHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndGoto->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndGoto->Number = LABEL_END;
+ }
+
+ if (PrivateData->VariableName == Variable_DB) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
+ DstFormId = FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM;
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
+ DstFormId = FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM;
+ } else {
+ goto ON_EXIT;
+ }
+ //
+ // Read Variable, the variable name save in the PrivateData->VariableName.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ goto ON_EXIT;
+ }
+
+ VariableData = AllocateZeroPool (DataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ if (!GotoList) {
+ HiiCreateGotoOpCode (
+ StartGotoHandle,
+ DstFormId,
+ STRING_TOKEN (STR_SOVEREIGN_BOOT_DELETE_ALL_LIST),
+ STRING_TOKEN (STR_SOVEREIGN_BOOT_DELETE_ALL_LIST),
+ EFI_IFR_FLAG_CALLBACK,
+ KEY_SOVEREIGN_BOOT_DELETE_ALL_LIST
+ );
+ }
+
+ RemainingSize = DataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)VariableData;
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) {
+
+ GetSignatureFormat (ListWalker, &FormatNameStringId, NULL, &ListType);
+
+ ZeroMem (NameBuffer, sizeof (NameBuffer));
+ FormatNameString = HiiGetString(PrivateData->HiiHandle, FormatNameStringId, NULL);
+ FormatTypeString = HiiGetString(PrivateData->HiiHandle, ListType, NULL);
+ if (FormatNameString == NULL || FormatTypeString == NULL) {
+ goto ON_EXIT;
+ }
+
+ UnicodeSPrint (
+ NameBuffer,
+ sizeof (NameBuffer),
+ FormatNameString,
+ Index + 1,
+ FormatTypeString
+ );
+
+ if (!GotoList) {
+ FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_LIST_HELP_FORMAT), NULL);
+ if (FormatHelpString == NULL) {
+ goto ON_EXIT;
+ }
+
+ ZeroMem (HelpBuffer, sizeof (HelpBuffer));
+ UnicodeSPrint (
+ HelpBuffer,
+ sizeof (HelpBuffer),
+ FormatHelpString,
+ FormatTypeString,
+ SIGNATURE_DATA_COUNTS (ListWalker)
+ );
+
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM,
+ HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
+ HiiSetString (PrivateData->HiiHandle, 0, HelpBuffer, NULL),
+ EFI_IFR_FLAG_CALLBACK,
+ QuestionIdBase + Index++
+ );
+ } else {
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM,
+ HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
+ STRING_TOKEN (STR_EMPTY_STRING),
+ EFI_IFR_FLAG_CALLBACK,
+ QuestionIdBase + Index++
+ );
+ }
+
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ }
+
+ON_EXIT:
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSovereignBootWizardFormSetGuid,
+ FormId,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ if (!GotoList) {
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSovereignBootWizardFormSetGuid,
+ FormId,
+ StartGotoHandle,
+ EndGotoHandle
+ );
+ }
+
+ FREE_NON_OPCODE (StartOpCodeHandle);
+ FREE_NON_OPCODE (EndOpCodeHandle);
+ FREE_NON_OPCODE (StartGotoHandle);
+ FREE_NON_OPCODE (EndGotoHandle);
+
+ FREE_NON_NULL (VariableData);
+
+ PrivateData->ListCount = Index;
+
+ return Status;
+}
+
+/**
+ Parse hash value from EFI_SIGNATURE_DATA, and save in the CHAR16 type array.
+ The buffer is callee allocated and should be freed by the caller.
+
+ @param[in] ListEntry The pointer point to the signature list.
+ @param[in] DataEntry The signature data we are processing.
+ @param[out] BufferToReturn Buffer to save the hash value.
+
+ @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval EFI_SUCCESS Operation success.
+**/
+EFI_STATUS
+ParseHelpHashValue (
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN EFI_SIGNATURE_DATA *DataEntry,
+ OUT CHAR16 **BufferToReturn
+ )
+{
+ UINTN Index;
+ UINTN BufferIndex;
+ UINTN TotalSize;
+ UINTN DataSize;
+ UINTN Line;
+ UINTN OneLineBytes;
+
+ //
+ // Assume that, display 8 bytes in one line.
+ //
+ OneLineBytes = 8;
+
+ if ((ListEntry == NULL) || (DataEntry == NULL) || (BufferToReturn == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DataSize = ListEntry->SignatureSize - sizeof (EFI_GUID);
+ Line = (DataSize + OneLineBytes - 1) / OneLineBytes;
+
+ //
+ // Each byte will split two Hex-number, and each line need additional memory to save '\r\n'.
+ //
+ TotalSize = ((DataSize + Line) * 2 * sizeof (CHAR16));
+
+ *BufferToReturn = AllocateZeroPool (TotalSize);
+ if (*BufferToReturn == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (Index = 0, BufferIndex = 0; Index < DataSize; Index = Index + 1) {
+ if ((Index > 0) && (Index % OneLineBytes == 0)) {
+ BufferIndex += UnicodeSPrint (&(*BufferToReturn)[BufferIndex], TotalSize - sizeof (CHAR16) * BufferIndex, L"\n");
+ }
+
+ BufferIndex += UnicodeSPrint (&(*BufferToReturn)[BufferIndex], TotalSize - sizeof (CHAR16) * BufferIndex, L"%02x", DataEntry->SignatureData[Index]);
+ }
+
+ BufferIndex += UnicodeSPrint (&(*BufferToReturn)[BufferIndex], TotalSize - sizeof (CHAR16) * BufferIndex, L"\n");
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to get the common name from the X509 format certificate.
+ The buffer is callee allocated and should be freed by the caller.
+
+ @param[in] ListEntry The pointer point to the signature list.
+ @param[in] DataEntry The signature data we are processing.
+ @param[out] BufferToReturn Buffer to save the CN of X509 certificate.
+
+ @retval EFI_INVALID_PARAMETER Invalid List or Data or Buffer.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval EFI_SUCCESS Operation success.
+ @retval EFI_NOT_FOUND Not found CN field in the X509 certificate.
+**/
+EFI_STATUS
+GetCommonNameFromX509 (
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN EFI_SIGNATURE_DATA *DataEntry,
+ OUT CHAR16 **BufferToReturn
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 *CNBuffer;
+ UINTN CNBufferSize;
+
+ Status = EFI_SUCCESS;
+ CNBuffer = NULL;
+
+ CNBuffer = AllocateZeroPool (256);
+ if (CNBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ CNBufferSize = 256;
+ X509GetCommonName (
+ (UINT8 *)DataEntry + sizeof (EFI_GUID),
+ ListEntry->SignatureSize - sizeof (EFI_GUID),
+ CNBuffer,
+ &CNBufferSize
+ );
+
+ *BufferToReturn = AllocateZeroPool (256 * sizeof (CHAR16));
+ if (*BufferToReturn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ AsciiStrToUnicodeStrS (CNBuffer, *BufferToReturn, 256);
+
+ON_EXIT:
+ FREE_NON_NULL (CNBuffer);
+
+ return Status;
+}
+
+/**
+ Format the help info for the signature data, each help info contain 3 parts.
+ 1. Owner Guid.
+ 2. Content, depends on the type of the signature list.
+ 3. Revocation time.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] ListEntry Point to the signature list.
+ @param[in] DataEntry Point to the signature data we are processing.
+ @param[out] StringId Save the string id of help info.
+
+ @retval EFI_SUCCESS Operation success.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+FormatHelpInfo (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN EFI_SIGNATURE_LIST *ListEntry,
+ IN EFI_SIGNATURE_DATA *DataEntry,
+ OUT EFI_STRING_ID *StringId
+ )
+{
+ EFI_STATUS Status;
+ EFI_TIME *Time;
+ EFI_STRING_ID ListTypeId;
+ EFI_STRING FormatHelpString;
+ EFI_STRING FormatTypeString;
+ UINTN DataSize;
+ UINTN HelpInfoIndex;
+ UINTN TotalSize;
+ CHAR16 GuidString[BUFFER_MAX_SIZE];
+ CHAR16 TimeString[BUFFER_MAX_SIZE];
+ CHAR16 *DataString;
+ CHAR16 *HelpInfoString;
+
+ Status = EFI_SUCCESS;
+ Time = NULL;
+ FormatTypeString = NULL;
+ HelpInfoIndex = 0;
+ DataString = NULL;
+ HelpInfoString = NULL;
+
+ if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa2048Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048);
+ DataSize = ListEntry->SignatureSize - sizeof (EFI_GUID);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertRsa2048Sha256Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_RSA2048_SHA256);
+ DataSize = ListEntry->SignatureSize - sizeof (EFI_GUID);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509);
+ DataSize = ListEntry->SignatureSize - sizeof (EFI_GUID);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha1Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA1);
+ DataSize = 20;
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha224Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA224);
+ DataSize = 28;
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha256Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA256);
+ DataSize = 32;
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha384Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA384);
+ DataSize = 48;
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSha512Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SHA512);
+ DataSize = 64;
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertSm3Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_SM3);
+ DataSize = 32;
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha256Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA256);
+ DataSize = 32;
+ Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha384Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA384);
+ DataSize = 48;
+ Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sha512Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SHA512);
+ DataSize = 64;
+ Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
+ } else if (CompareGuid (&ListEntry->SignatureType, &gEfiCertX509Sm3Guid)) {
+ ListTypeId = STRING_TOKEN (STR_LIST_TYPE_X509_SM3);
+ DataSize = 32;
+ Time = (EFI_TIME *)(DataEntry->SignatureData + DataSize);
+ } else {
+ Status = EFI_UNSUPPORTED;
+ goto ON_EXIT;
+ }
+
+ FormatTypeString = HiiGetString (PrivateData->HiiHandle, ListTypeId, NULL);
+ if (FormatTypeString == NULL) {
+ goto ON_EXIT;
+ }
+
+ TotalSize = 1024;
+ HelpInfoString = AllocateZeroPool (TotalSize);
+ if (HelpInfoString == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Format GUID part.
+ //
+ ZeroMem (GuidString, sizeof (GuidString));
+ GuidToString (&DataEntry->SignatureOwner, GuidString, BUFFER_MAX_SIZE);
+ FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_GUID), NULL);
+ if (FormatHelpString == NULL) {
+ goto ON_EXIT;
+ }
+
+ HelpInfoIndex += UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof (CHAR16) * HelpInfoIndex,
+ FormatHelpString,
+ GuidString
+ );
+ FREE_NON_NULL (FormatHelpString);
+ FormatHelpString = NULL;
+
+ if (CompareGuid (&DataEntry->SignatureOwner, &gSovereignBootWizardFormSetGuid)) {
+ HelpInfoIndex += UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof (CHAR16) * HelpInfoIndex,
+ L"%s",
+ HiiGetString(PrivateData->HiiHandle, STRING_TOKEN(STR_SIGNATURE_DATA_HELP_GUID_SVBOOT), NULL)
+ );
+ } else if (CompareGuid (&DataEntry->SignatureOwner, &gEfiSbMicrosoftOwnerGuid)) {
+ HelpInfoIndex += UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof (CHAR16) * HelpInfoIndex,
+ L"%s",
+ HiiGetString(PrivateData->HiiHandle, STRING_TOKEN(STR_SIGNATURE_DATA_HELP_GUID_MS), NULL)
+ );
+ } else if (CompareGuid (&DataEntry->SignatureOwner, &gEfiGlobalVariableGuid)) {
+ HelpInfoIndex += UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof (CHAR16) * HelpInfoIndex,
+ L"%s",
+ HiiGetString(PrivateData->HiiHandle, STRING_TOKEN(STR_SIGNATURE_DATA_HELP_GUID_FW), NULL)
+ );
+ }
+
+ //
+ // Format hash value for each signature data entry.
+ //
+ ParseHelpHashValue (ListEntry, DataEntry, &DataString);
+ FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_HASH), NULL);
+ if (FormatHelpString == NULL) {
+ goto ON_EXIT;
+ }
+
+ HelpInfoIndex += UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof (CHAR16) * HelpInfoIndex,
+ FormatHelpString,
+ FormatTypeString,
+ DataSize,
+ DataString
+ );
+ FREE_NON_NULL (FormatHelpString);
+ FormatHelpString = NULL;
+
+ //
+ // Format revocation time part.
+ //
+ if (Time != NULL) {
+ ZeroMem (TimeString, sizeof (TimeString));
+ UnicodeSPrint (
+ TimeString,
+ sizeof (TimeString),
+ L"%02d-%02d-%04d %02d:%02d:%02d",
+ Time->Day,
+ Time->Month,
+ Time->Year,
+ Time->Hour,
+ Time->Minute,
+ Time->Second
+ );
+ FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_HELP_FORMAT_TIME), NULL);
+ if (FormatHelpString == NULL) {
+ goto ON_EXIT;
+ }
+
+ UnicodeSPrint (
+ &HelpInfoString[HelpInfoIndex],
+ TotalSize - sizeof (CHAR16) * HelpInfoIndex,
+ FormatHelpString,
+ TimeString
+ );
+ FREE_NON_NULL (FormatHelpString);
+ FormatHelpString = NULL;
+ }
+
+ *StringId = HiiSetString (PrivateData->HiiHandle, 0, HelpInfoString, NULL);
+ON_EXIT:
+ FREE_NON_NULL (DataString);
+ FREE_NON_NULL (HelpInfoString);
+
+ FREE_NON_NULL (FormatTypeString);
+
+ return Status;
+}
+
+/**
+ This function to load signature data under the signature list.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] LabelId Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+ @param[in] ListIndex Indicate to load which signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadSignatureData (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN UINT16 LabelId,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase,
+ IN UINT16 ListIndex
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_SIGNATURE_DATA *DataWalker;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ EFI_STRING_ID HelpStringId;
+ EFI_STRING_ID FormatStringId;
+ EFI_STRING_ID EntryTypeStringId;
+ EFI_STRING EntryTypeString;
+ EFI_STRING FormatNameString;
+ EFI_FORM_ID GotoFormId;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ UINTN DataSize;
+ UINTN RemainingSize;
+ UINT16 Index;
+ UINT8 *VariableData;
+ CHAR16 VariableName[BUFFER_MAX_SIZE];
+ CHAR16 NameBuffer[BUFFER_MAX_SIZE];
+ BOOLEAN GotoList;
+ UINT8 SignatureType;
+ CHAR16 *CertCN;
+
+ Status = EFI_SUCCESS;
+ FormatNameString = NULL;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+ Index = 0;
+ VariableData = NULL;
+
+ GotoList = (QuestionIdBase == OPTION_DB_ENTRIES_QUESTION_ID) ||
+ (QuestionIdBase == OPTION_DBX_ENTRIES_QUESTION_ID);
+ //
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LabelId;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ if (PrivateData->VariableName == Variable_DB) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
+ } else {
+ goto ON_EXIT;
+ }
+
+ //
+ // Read Variable, the variable name save in the PrivateData->VariableName.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ goto ON_EXIT;
+ }
+
+ VariableData = AllocateZeroPool (DataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ RemainingSize = DataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)VariableData;
+
+ //
+ // Skip signature list.
+ //
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex-- > 0) {
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ }
+
+ SignatureType = GetSignatureFormat(ListWalker, NULL, &FormatStringId, &EntryTypeStringId);
+
+ FormatNameString = HiiGetString (PrivateData->HiiHandle, FormatStringId, NULL);
+ EntryTypeString = HiiGetString (PrivateData->HiiHandle, EntryTypeStringId, NULL);
+ if ((FormatNameString == NULL) || (EntryTypeString == NULL)) {
+ goto ON_EXIT;
+ }
+
+ PrivateData->DataCount = SIGNATURE_DATA_COUNTS (ListWalker);
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ for (Index = 0; Index < SIGNATURE_DATA_COUNTS (ListWalker); Index = Index + 1) {
+ //
+ // Format name buffer.
+ //
+ ZeroMem (NameBuffer, sizeof (NameBuffer));
+ if (SignatureType == SIGNATURE_TYPE_X509) {
+ CertCN = NULL;
+ if (!EFI_ERROR (GetCommonNameFromX509 (ListWalker, DataWalker, &CertCN)) && (StrLen(CertCN) > 0)) {
+ UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, Index + 1, CertCN);
+ } else {
+ UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, Index + 1, EntryTypeString);
+ }
+ FREE_NON_NULL (CertCN);
+ GotoFormId = SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID;
+ } else {
+ UnicodeSPrint (NameBuffer, sizeof (NameBuffer), FormatNameString, Index + 1, EntryTypeString);
+ GotoFormId = SOVEREIGN_BOOT_WIZARD_HASH_DETAILS_FORM_ID;
+ }
+
+ //
+ // Format help info buffer.
+ //
+ Status = FormatHelpInfo (PrivateData, ListWalker, DataWalker, &HelpStringId);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ if (GotoList) {
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle,
+ GotoFormId,
+ HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
+ HelpStringId,
+ EFI_IFR_FLAG_CALLBACK,
+ QuestionIdBase + Index
+ );
+ } else {
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle,
+ (EFI_QUESTION_ID)(QuestionIdBase + Index),
+ 0,
+ 0,
+ HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
+ HelpStringId,
+ EFI_IFR_FLAG_CALLBACK,
+ 0,
+ NULL
+ );
+ }
+
+ ZeroMem (NameBuffer, BUFFER_MAX_SIZE);
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
+ }
+
+ if (GotoList) {
+ PrivateData->FormData.SignatureType = SignatureType;
+ PrivateData->FormData.SignatureRemove = TRUE;
+ } else {
+ PrivateData->FormData.SignatureRemove = FALSE;
+ }
+
+ //
+ // Allocate a buffer to record which signature data will be checked.
+ // This memory buffer will be freed when exit from the SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM form.
+ //
+ PrivateData->CheckArray = AllocateZeroPool (SIGNATURE_DATA_COUNTS (ListWalker) * sizeof (BOOLEAN));
+ON_EXIT:
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSovereignBootWizardFormSetGuid,
+ FormId,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ FREE_NON_OPCODE (StartOpCodeHandle);
+ FREE_NON_OPCODE (EndOpCodeHandle);
+
+ FREE_NON_NULL (VariableData);
+ FREE_NON_NULL (FormatNameString);
+
+ return Status;
+}
+
+
+/**
+ This function to load signature data strings under the signature data.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] DataIndex Indicate to load which signature data.
+ @param[in] ListIndex Indicate to load which signature list.
+
+ @retval EFI_SUCCESS Success to update the signature data page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadSignatureDataStrings (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN UINT16 DataIndex,
+ IN UINT16 ListIndex
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_SIGNATURE_DATA *DataWalker;
+ UINTN DataSize;
+ UINTN RemainingSize;
+ UINT16 Index;
+ UINT8 *VariableData;
+ CHAR16 VariableName[BUFFER_MAX_SIZE];
+ UINT8 SignatureType;
+ SV_CERT_ENTRY CertEntry;
+
+ Status = EFI_SUCCESS;
+ Index = 0;
+ VariableData = NULL;
+
+ if (PrivateData->VariableName == Variable_DB) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
+ } else {
+ goto ON_EXIT;
+ }
+
+ //
+ // Read Variable, the variable name save in the PrivateData->VariableName.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ goto ON_EXIT;
+ }
+
+ VariableData = AllocateZeroPool (DataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, VariableData);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ RemainingSize = DataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)VariableData;
+
+ //
+ // Skip signature list.
+ //
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize) && ListIndex-- > 0) {
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ }
+
+ SignatureType = GetSignatureFormat(ListWalker, NULL, NULL, NULL);
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ for (Index = 0; Index < SIGNATURE_DATA_COUNTS (ListWalker); Index = Index + 1) {
+
+ if (Index != DataIndex) {
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
+ continue;
+ }
+
+ if (SignatureType == SIGNATURE_TYPE_X509) {
+ CertEntry.CertDataSize = ListWalker->SignatureSize - sizeof (EFI_GUID);
+ CertEntry.CertData = DataWalker->SignatureData;
+ FillCertStrings(PrivateData, &CertEntry);
+ } else {
+ PrivateData->FormData.SignatureType = SignatureType;
+ FillKeyHashStrings (PrivateData, ListWalker, DataWalker);
+ }
+
+ break;
+ }
+
+ON_EXIT:
+
+ FREE_NON_NULL (VariableData);
+
+ return Status;
+}
+
+
+/**
+ Format the help info for the bootloader data, each help info contain 3 parts.
+ 1. Description.
+ 2. Disk HW path.
+ 3. File apth.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] BootloaderEntry Point to the bootloader data.
+ @param[out] StringId Save the string id of help info.
+
+ @retval EFI_SUCCESS Operation success.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+FormatBlHelpInfo (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN SV_MENU_ENTRY *BootloaderEntry,
+ OUT EFI_STRING_ID *StringId
+ )
+{
+ EFI_STATUS Status;
+ EFI_STRING FormatHelpString;
+ UINTN TotalSize;
+ CHAR16 *HelpInfoString;
+
+ Status = EFI_SUCCESS;
+ HelpInfoString = NULL;
+
+ TotalSize = 1024;
+ HelpInfoString = AllocateZeroPool (TotalSize);
+ if (HelpInfoString == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ FormatHelpString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_BOOTLOADER_HELP_FORMAT), NULL);
+ if (FormatHelpString == NULL) {
+ goto ON_EXIT;
+ }
+
+ UnicodeSPrint (
+ HelpInfoString,
+ TotalSize,
+ FormatHelpString,
+ BootloaderEntry->DisplayString,
+ BootloaderEntry->DevicePathString,
+ BootloaderEntry->FilePathString
+ );
+ FREE_NON_NULL (FormatHelpString);
+
+ *StringId = HiiSetString (PrivateData->HiiHandle, 0, HelpInfoString, NULL);
+ON_EXIT:
+ FREE_NON_NULL (HelpInfoString);
+
+ return Status;
+}
+
+/**
+ This function to loads bootloader data strings under the bootloader form.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the bootloader list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadBootloaders (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ EFI_STATUS Status;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ EFI_STRING_ID HelpStringId;
+ EFI_STRING FormatNameString;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ UINT16 Index;
+ CHAR16 NameBuffer[BUFFER_MAX_SIZE];
+ SV_MENU_ENTRY *BootloaderEntry;
+
+ Status = EFI_SUCCESS;
+ FormatNameString = NULL;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+ Index = 0;
+
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_BOOTLOADER_LIST_START;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ FormatNameString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN (STR_BOOTLOADER_NAME_FORMAT), NULL);
+ if (FormatNameString == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto ON_EXIT;
+ }
+
+ for (Index = 0; Index < mBootOptionMenu.MenuNumber; Index = Index + 1) {
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, Index);
+ if (BootloaderEntry == NULL) {
+ Status = EFI_NO_MEDIA;
+ goto ON_EXIT;
+ }
+
+ //
+ // Format name buffer.
+ //
+ ZeroMem (NameBuffer, sizeof (NameBuffer));
+ UnicodeSPrint (
+ NameBuffer,
+ sizeof (NameBuffer),
+ FormatNameString,
+ &BootloaderEntry->FilePathString[StrLen(L"File Path: ")],
+ &BootloaderEntry->DisplayString[StrLen(L"Description: ")]);
+
+ //
+ // Format help info buffer.
+ //
+ Status = FormatBlHelpInfo (PrivateData, BootloaderEntry, &HelpStringId);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle,
+ SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID,
+ HiiSetString (PrivateData->HiiHandle, 0, NameBuffer, NULL),
+ HelpStringId,
+ EFI_IFR_FLAG_CALLBACK,
+ OPTION_BL_QUESTION_ID + Index
+ );
+ }
+
+ON_EXIT:
+ PrivateData->FormData.BootloaderCount = Index;
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSovereignBootWizardFormSetGuid,
+ FORMID_SOVEREIGN_BOOT_BL_OPTION_FORM,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ FREE_NON_OPCODE (StartOpCodeHandle);
+ FREE_NON_OPCODE (EndOpCodeHandle);
+
+ return Status;
+}
+
+
+/**
+ This function to loads bootloader data strings under the bootloader form.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the bootloader list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadBootloaderCertificates (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ EFI_STATUS Status;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ EFI_STRING_ID NameStringId;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ UINT16 Index;
+ CHAR8 NameBuffer[BUFFER_MAX_SIZE];
+ UINTN NameBufferSize;
+ CHAR16 *NewString;
+ SV_MENU_ENTRY *BootloaderEntry;
+ SV_SECURITY_CONTEXT *SecurityContext;
+ SV_CERT_ENTRY *CertificateEntry;
+ BOOLEAN MsCertFound;
+ BOOLEAN NonMsCertFound;
+ BOOLEAN FoundInDb;
+ BOOLEAN FoundInDbx;
+ BOOLEAN InvalidSigFound;
+
+ Status = EFI_SUCCESS;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+ Index = 0;
+ MsCertFound = FALSE;
+ NonMsCertFound = FALSE;
+ FoundInDb = FALSE;
+ FoundInDbx = FALSE;
+ InvalidSigFound = FALSE;
+
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_BOOTLOADER_CERT_LIST_START;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, mBootloaderIndex);
+ if ((BootloaderEntry == NULL) || (BootloaderEntry->SecurityContext == NULL)) {
+ Status = EFI_NO_MEDIA;
+ goto ON_EXIT;
+ }
+
+ SecurityContext = (SV_SECURITY_CONTEXT *)BootloaderEntry->SecurityContext;
+ for (Index = 0; Index < SecurityContext->NumCertificates; Index = Index + 1) {
+ CertificateEntry = GetCertEntry(BootloaderEntry, Index);
+ if (CertificateEntry == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ NameStringId = STRING_TOKEN(STR_CERT_NO_COMMON_NAME);
+ NameBufferSize = sizeof (NameBuffer);
+ SetMem (NameBuffer, NameBufferSize, 0);
+ if (!RETURN_ERROR (X509GetCommonName (CertificateEntry->CertData,
+ CertificateEntry->CertDataSize,
+ NameBuffer,
+ &NameBufferSize))) {
+ NewString = (CHAR16 *)AllocateZeroPool ((NameBufferSize + 1) * sizeof(CHAR16));
+ if (NewString != NULL) {
+ if (!RETURN_ERROR (AsciiStrToUnicodeStrS (NameBuffer, NewString, NameBufferSize + 1))) {
+ NameStringId = HiiSetString (PrivateData->HiiHandle, 0, NewString, NULL);
+ }
+ FreePool (NewString);
+ }
+ }
+
+ if (CertificateEntry->CertIsMicrosoft) {
+ MsCertFound = TRUE;
+ } else {
+ NonMsCertFound = TRUE;
+ }
+
+ if (CertificateEntry->CertIsInDb) {
+ FoundInDb = TRUE;
+ }
+
+ if (CertificateEntry->CertIsInDbx) {
+ FoundInDbx = TRUE;
+ }
+
+ if (!CertificateEntry->SignatureValid || !CertificateEntry->CertIsValid) {
+ InvalidSigFound = TRUE;
+ }
+
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle,
+ SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID,
+ NameStringId,
+ STRING_TOKEN(STR_EMPTY_STRING),
+ EFI_IFR_FLAG_CALLBACK,
+ OPTION_BL_CERT_QUESTION_ID + Index
+ );
+ }
+
+ PrivateData->FormData.SignedByMs = MsCertFound;
+ PrivateData->FormData.SignedByMsOnly = (!NonMsCertFound && MsCertFound);
+ PrivateData->FormData.HasInvalidSignature = InvalidSigFound;
+ PrivateData->FormData.ImageHashIsInDb = SecurityContext->ImageIsInDb;
+ PrivateData->FormData.ImageHashIsInDbx = SecurityContext->ImageIsInDbx;
+
+ if (SecurityContext->ImageIsSigned) {
+ if (!SecurityContext->ImageIsVerified || FoundInDbx || SecurityContext->ImageIsInDbx) {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_UNTRUSTED;
+ } else if (FoundInDb || SecurityContext->ImageIsInDb) {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_TRUSTED;
+ } else {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_UNDECIDED;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "LoadBootloaderCertificates:\n"
+ " MsCertFound: %u\n"
+ " NonMsCertFound: %u\n"
+ " InvalidSigFound: %u\n"
+ " ImageIsSigned: %u\n"
+ " ImageIsVerified: %u\n"
+ " FoundInDbx: %u\n"
+ " FoundInDb: %u\n"
+ " ImageIsInDb: %u\n"
+ " ImageIsInDbx: %u\n"
+ " ImageTrusted: %u\n",
+ MsCertFound,
+ NonMsCertFound,
+ InvalidSigFound,
+ SecurityContext->ImageIsSigned,
+ SecurityContext->ImageIsVerified,
+ FoundInDbx,
+ FoundInDb,
+ SecurityContext->ImageIsInDb,
+ SecurityContext->ImageIsInDbx,
+ PrivateData->FormData.ImageTrusted));
+
+ON_EXIT:
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle,
+ &gSovereignBootWizardFormSetGuid,
+ SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ FREE_NON_OPCODE (StartOpCodeHandle);
+ FREE_NON_OPCODE (EndOpCodeHandle);
+
+ return Status;
+}
+
+/**
+ This function publish the Sovereign Boot Wizrd Interactive Mode form.
+
+ @param[in, out] PrivateData Points to Sovereign Boot private data.
+
+ @retval EFI_SUCCESS HII Form is installed successfully.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+InstallInteractiveModeForm (
+ IN OUT SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ PrivateData->FileContext = AllocateZeroPool (sizeof (SOVEREIGNBOOT_FILE_CONTEXT));
+
+ if (PrivateData->FileContext == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Init OpCode Handle and Allocate space for creation of Buffer
+ //
+ mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (mStartOpCodeHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (mEndOpCodeHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ mStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ mStartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ mEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ mEndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ mEndLabel->Number = LABEL_END;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function removes Sovereign Boot Wizrd Interactive Mode form.
+
+ @param[in, out] PrivateData Points to Sovereign Boot configuration private data.
+
+**/
+VOID
+UninstallInteractiveModeForm (
+ IN OUT SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ FREE_NON_NULL (PrivateData->FileContext);
+
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ if (mEndOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mEndOpCodeHandle);
+ }
+}
+
+/**
+ This function removes the image hash from database.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the signature database
+ @retval EFI_NO_MEDIA If given bootloader was not found.
+ @retval EFI_NOT_FOUND If hash of the image could not be found in
+ database.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+RemoveImageHashFromDatabase (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_SIGNATURE_DATA *DataWalker;
+ CHAR16 VariableName[BUFFER_MAX_SIZE];
+ UINTN VariableDataSize;
+ UINT32 VariableAttr;
+ UINTN RemainingSize;
+ UINTN ListIndex;
+ UINTN Index;
+ UINT8 *VariableData;
+ UINT8 *HashData;
+ UINTN DigestLen;
+ SV_MENU_ENTRY *BootloaderEntry;
+ SV_SECURITY_CONTEXT *SecurityContext;
+
+ Status = EFI_NO_MEDIA;
+ VariableDataSize = 0;
+ ListIndex = 0;
+ VariableData = NULL;
+
+ if (PrivateData->VariableName == Variable_DB) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
+ } else {
+ goto Done;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ &VariableAttr,
+ &VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ goto Done;
+ }
+
+ VariableData = AllocateZeroPool (VariableDataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ &VariableAttr,
+ &VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, mBootloaderIndex);
+ if (BootloaderEntry == NULL || BootloaderEntry->SecurityContext == NULL) {
+ DEBUG ((DEBUG_ERROR, "Bootloader %u not found\n", mBootloaderIndex));
+ return EFI_NO_MEDIA;
+ }
+
+ SecurityContext = (SV_SECURITY_CONTEXT *)BootloaderEntry->SecurityContext;
+
+ RemainingSize = VariableDataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)(VariableData);
+
+ Status = EFI_NOT_FOUND;
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) {
+ HashData = NULL;
+ if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha256Guid)) {
+ HashData = SecurityContext->ImageDigest;
+ DigestLen = SHA256_DIGEST_SIZE;
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha384Guid)) {
+ HashData = SecurityContext->ImageSha384Digest;
+ DigestLen = SHA384_DIGEST_SIZE;
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertSha512Guid)) {
+ HashData = SecurityContext->ImageSha512Digest;
+ DigestLen = SHA512_DIGEST_SIZE;
+ } else {
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ ListIndex++;
+ continue;
+ }
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ for (Index = 0; Index < SIGNATURE_DATA_COUNTS (ListWalker); Index = Index + 1) {
+ // Remove raw certificate or certificate hash if data matches
+ if ((HashData != NULL) &&
+ (CompareMem (DataWalker->SignatureData, HashData, DigestLen) == 0)) {
+ PrivateData->ListIndex = ListIndex;
+
+ if (SIGNATURE_DATA_COUNTS (ListWalker) == 1) {
+ Status = DeleteSignatureEx (PrivateData, Delete_Signature_List_One, 1);
+ } else {
+ PrivateData->CheckArray = AllocateZeroPool (SIGNATURE_DATA_COUNTS (ListWalker));
+ if (PrivateData->CheckArray == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ PrivateData->CheckArray[Index] = TRUE;
+ Status = DeleteSignatureEx (PrivateData, Delete_Signature_Data, 1);
+ FreePool (PrivateData->CheckArray);
+ PrivateData->CheckArray = NULL;
+ }
+
+ goto Done;
+ }
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
+ }
+
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ ListIndex++;
+ }
+
+Done:
+
+ FREE_NON_NULL (VariableData);
+
+ return Status;
+}
+
+/**
+ This function removes a certificate from database.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the signature database
+ @retval EFI_NO_MEDIA If given bootloader or certificate was not
+ found or certificate hash could not be
+ calculated.
+ @retval EFI_NOT_FOUND If the certificate or its hash was not
+ found in database.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+RemoveCertificateFromDatabase (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *ListWalker;
+ EFI_SIGNATURE_DATA *DataWalker;
+ CHAR16 VariableName[BUFFER_MAX_SIZE];
+ UINTN VariableDataSize;
+ UINT32 VariableAttr;
+ UINTN RemainingSize;
+ UINTN ListIndex;
+ UINTN Index;
+ UINT8 *VariableData;
+ UINT8 HashAlg;
+ UINT8 CertDigest[MAX_DIGEST_SIZE];
+ UINTN DigestLen;
+ SV_MENU_ENTRY *BootloaderEntry;
+ SV_CERT_ENTRY *CertificateEntry;
+
+ Status = EFI_NO_MEDIA;
+ VariableDataSize = 0;
+ ListIndex = 0;
+ VariableData = NULL;
+
+ if (PrivateData->VariableName == Variable_DB) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE);
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), EFI_IMAGE_SECURITY_DATABASE1);
+ } else {
+ goto Done;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ &VariableAttr,
+ &VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ goto Done;
+ }
+
+ VariableData = AllocateZeroPool (VariableDataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiImageSecurityDatabaseGuid,
+ &VariableAttr,
+ &VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, mBootloaderIndex);
+ if (BootloaderEntry == NULL) {
+ DEBUG ((DEBUG_ERROR, "Bootloader %u not found\n", mBootloaderIndex));
+ return EFI_NO_MEDIA;
+ }
+
+ CertificateEntry = GetCertEntry(BootloaderEntry, mCertIndex);
+ if (CertificateEntry == NULL) {
+ DEBUG ((DEBUG_ERROR, "Certificate %u not found\n", mCertIndex));
+ return EFI_NO_MEDIA;
+ }
+
+ RemainingSize = VariableDataSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)(VariableData);
+
+ Status = EFI_NOT_FOUND;
+ while ((RemainingSize > 0) && (RemainingSize >= ListWalker->SignatureListSize)) {
+ HashAlg = HASHALG_MAX;
+ if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha256Guid)) {
+ HashAlg = HASHALG_SHA256;
+ DigestLen = SHA256_DIGEST_SIZE;
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha384Guid)) {
+ HashAlg = HASHALG_SHA384;
+ DigestLen = SHA384_DIGEST_SIZE;
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Sha512Guid)) {
+ HashAlg = HASHALG_SHA512;
+ DigestLen = SHA512_DIGEST_SIZE;
+ } else if (CompareGuid (&ListWalker->SignatureType, &gEfiCertX509Guid)) {
+ HashAlg = HASHALG_RAW;
+ } else {
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ ListIndex++;
+ continue;
+ }
+
+ if (HashAlg < HASHALG_MAX) {
+ ZeroMem (CertDigest, MAX_DIGEST_SIZE);
+ if (!CalculateCertHash (CertificateEntry->CertData, CertificateEntry->CertDataSize, HashAlg, CertDigest)) {
+ Status = EFI_NO_MEDIA;
+ goto Done;
+ }
+ }
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)ListWalker + sizeof (EFI_SIGNATURE_LIST) + ListWalker->SignatureHeaderSize);
+ for (Index = 0; Index < SIGNATURE_DATA_COUNTS (ListWalker); Index = Index + 1) {
+ // Remove raw certificate or certificate hash if data matches
+ if (((HashAlg < HASHALG_MAX) && (CompareMem (DataWalker->SignatureData,
+ CertDigest,
+ DigestLen) == 0)) ||
+ ((HashAlg == HASHALG_RAW) && (CompareMem (DataWalker->SignatureData,
+ CertificateEntry->CertData,
+ CertificateEntry->CertDataSize) == 0)))
+ {
+ PrivateData->ListIndex = ListIndex;
+
+ if (SIGNATURE_DATA_COUNTS (ListWalker) == 1) {
+ Status = DeleteSignatureEx (PrivateData, Delete_Signature_List_One, 1);
+ } else {
+ PrivateData->CheckArray = AllocateZeroPool (SIGNATURE_DATA_COUNTS (ListWalker));
+ if (PrivateData->CheckArray == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ PrivateData->CheckArray[Index] = TRUE;
+ Status = DeleteSignatureEx (PrivateData, Delete_Signature_Data, 1);
+ FreePool (PrivateData->CheckArray);
+ PrivateData->CheckArray = NULL;
+ }
+
+ goto Done;
+ }
+
+ DataWalker = (EFI_SIGNATURE_DATA *)((UINT8 *)DataWalker + ListWalker->SignatureSize);
+ }
+
+ RemainingSize -= ListWalker->SignatureListSize;
+ ListWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)ListWalker + ListWalker->SignatureListSize);
+ ListIndex++;
+ }
+
+Done:
+
+ FREE_NON_NULL (VariableData);
+
+ return Status;
+}
+
+EFI_STATUS
+RemoveImageDataFromDatabase (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ SV_MENU_ENTRY *BootloaderEntry;
+ SV_SECURITY_CONTEXT *SecurityContext;
+ UINTN CertIndex;
+ UINTN Index;
+
+ while (!EFI_ERROR (Status)) {
+ Status = RemoveImageHashFromDatabase (PrivateData);
+ }
+
+ // No more entries with given image, continue with certs
+ if (Status == EFI_NOT_FOUND) {
+ Status = EFI_SUCCESS;
+ } else {
+ DEBUG ((DEBUG_INFO, "RemoveImageHashFromDatabase failed with %r\n", Status));
+ return Status;
+ }
+
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, mBootloaderIndex);
+ if (BootloaderEntry == NULL || BootloaderEntry->SecurityContext == NULL) {
+ DEBUG ((DEBUG_INFO, "RemoveImageDataFromDatabase: No bootloader entry or security context\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ SecurityContext = (SV_SECURITY_CONTEXT *)BootloaderEntry->SecurityContext;
+
+ // Backup currently browsed certificate index
+ CertIndex = mCertIndex;
+
+ for (Index = 0; Index < SecurityContext->NumCertificates; Index++) {
+
+ mCertIndex = Index;
+ while (!EFI_ERROR (Status)) {
+ Status = RemoveCertificateFromDatabase (PrivateData);
+ }
+
+ // No more entries with given, proceed with next cert
+ if (Status == EFI_NOT_FOUND) {
+ Status = EFI_SUCCESS;
+ continue;
+ } else {
+ DEBUG ((DEBUG_INFO, "RemoveCertificateFromDatabase %u failed with %r\n", Index, Status));
+ mCertIndex = CertIndex;
+ return Status;
+ }
+ }
+
+ mCertIndex = CertIndex;
+
+ if (Status == EFI_NOT_FOUND) {
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+RemoveImageDataFromDbx (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ PrivateData->VariableName = Variable_DBX;
+
+ return RemoveImageDataFromDatabase(PrivateData);
+}
+
+EFI_STATUS
+RemoveImageDataFromDb (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ PrivateData->VariableName = Variable_DB;
+
+ return RemoveImageDataFromDatabase(PrivateData);
+}
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/InteractiveModeImpl.h b/DasharoModulePkg/Application/SovereignBootWizard/InteractiveModeImpl.h
new file mode 100644
index 0000000000..dbfee7c68b
--- /dev/null
+++ b/DasharoModulePkg/Application/SovereignBootWizard/InteractiveModeImpl.h
@@ -0,0 +1,495 @@
+/** @file
+The header file of Interactive Mode implementation of Sovereign Boot
+Provisioning Wizard.
+
+Copyright (c) 2025, 3mdeb Sp z o.o. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __SOVEREIGNBOOT_INTERACTIVE_MODE_IMPL_H__
+#define __SOVEREIGNBOOT_INTERACTIVE_MODE_IMPL_H__
+
+//
+// Shared IFR form update data
+//
+extern VOID *mStartOpCodeHandle;
+extern VOID *mEndOpCodeHandle;
+extern EFI_IFR_GUID_LABEL *mStartLabel;
+extern EFI_IFR_GUID_LABEL *mEndLabel;
+
+#define MAX_CHAR 480
+#define TWO_BYTE_ENCODE 0x82
+
+#define UNKNOWN_FILE_TYPE 0
+#define X509_CERT_FILE_TYPE 1
+#define PE_IMAGE_FILE_TYPE 2
+#define AUTHENTICATION_2_FILE_TYPE 3
+
+//
+// Certificate public key minimum size (bytes)
+//
+#define CER_PUBKEY_MIN_SIZE 256
+
+//
+// Define KeyType for public key storing file
+//
+#define KEY_TYPE_RSASSA 0
+
+//
+// Types of errors may occur during certificate enrollment.
+//
+typedef enum {
+ None_Error = 0,
+ //
+ // Unsupported_type indicates the certificate type is not supported.
+ //
+ Unsupported_Type,
+ //
+ // Unqualified_key indicates the key strength of certificate is not
+ // strong enough.
+ //
+ Unqualified_Key,
+ Enroll_Error_Max
+} ENROLL_KEY_ERROR;
+
+typedef enum {
+ Delete_Signature_List_All,
+ Delete_Signature_List_One,
+ Delete_Signature_Data
+} SIGNATURE_DELETE_TYPE;
+
+
+typedef enum {
+ Signature_Type_X509_Cert,
+ Signature_Type_X509_Cert_Hash,
+ Signature_Type_RSA_Key,
+ Signature_Type_RSA_Key_Hash,
+ Signature_Type_Hash,
+ Signature_Type_Unknown
+} SIGNATURE_TYPE;
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Head;
+ UINTN MenuNumber;
+} SOVEREIGNBOOT_MENU_OPTION;
+
+
+#define SIGNATURE_DATA_COUNTS(List) \
+ (((List)->SignatureListSize - sizeof(EFI_SIGNATURE_LIST) - (List)->SignatureHeaderSize) / (List)->SignatureSize)
+
+//
+// We define another format of 5th directory entry: security directory
+//
+typedef struct {
+ UINT32 Offset; // Offset of certificate
+ UINT32 SizeOfCert; // size of certificate appended
+} EFI_IMAGE_SECURITY_DATA_DIRECTORY;
+
+typedef enum {
+ ImageType_IA32,
+ ImageType_X64
+} IMAGE_TYPE;
+
+//
+// Cryptographic Key Information
+//
+#pragma pack(1)
+typedef struct _CPL_KEY_INFO {
+ UINT32 KeyLengthInBits; // Key Length In Bits
+ UINT32 BlockSize; // Operation Block Size in Bytes
+ UINT32 CipherBlockSize; // Output Cipher Block Size in Bytes
+ UINT32 KeyType; // Key Type
+ UINT32 CipherMode; // Cipher Mode for Symmetric Algorithm
+ UINT32 Flags; // Additional Key Property Flags
+} CPL_KEY_INFO;
+#pragma pack()
+
+/**
+ This function extracts configuration from variable.
+
+ @param[in] Private Point to Sovereign Boot configuration driver private data.
+ @param[in, out] FormData Point to Sovereign Boot form private data.
+
+**/
+VOID
+InteractiveModeExtractConfig (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN OUT SOVEREIGN_BOOT_WIZARD_FORM_DATA *FormData
+ );
+
+EFI_STATUS
+InstallInteractiveModeForm (
+ IN OUT SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+VOID
+UninstallInteractiveModeForm (
+ IN OUT SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+/**
+ Update the DB form base on the input file path info.
+
+ @param FilePath Point to the file path.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+**/
+BOOLEAN
+EFIAPI
+UpdateDBFromFile (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ );
+
+/**
+ Update the DBX form base on the input file path info.
+
+ @param FilePath Point to the file path.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+**/
+BOOLEAN
+EFIAPI
+UpdateDBXFromFile (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ );
+
+/**
+ This code cleans up enrolled file by closing file & free related resources attached to
+ enrolled file.
+
+ @param[in] FileContext FileContext cached in Sovereign Boot Wizard driver
+
+**/
+VOID
+CloseEnrolledFile (
+ IN SOVEREIGNBOOT_FILE_CONTEXT *FileContext
+ );
+
+/**
+ Delete a signature entry from signature database.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the vendor's signature database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+ @param[in] DeleteIndex Signature index to delete.
+
+ @retval EFI_SUCCESS Delete signature successfully.
+ @retval EFI_NOT_FOUND Can't find the signature item,
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+**/
+EFI_STATUS
+DeleteSignature (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase,
+ IN UINTN DeleteIndex
+ );
+
+/**
+ This function to delete signature list or data, according by DelType.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] DelType Indicate delete signature list or data.
+ @param[in] CheckedCount Indicate how many signature data have
+ been checked in current signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+DeleteSignatureEx (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN SIGNATURE_DELETE_TYPE DelType,
+ IN UINT32 CheckedCount
+ );
+
+/**
+ This function to load signature data under the signature list.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] LabelId Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+ @param[in] ListIndex Indicate to load which signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadSignatureData (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN UINT16 LabelId,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase,
+ IN UINT16 ListIndex
+ );
+
+/**
+ This function to load signature list, the update the menu page.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] LabelId Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadSignatureList (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN UINT16 LabelId,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase
+ );
+
+/**
+ This function to load signature data strings under the signature data.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] DataIndex Indicate to load which signature data.
+ @param[in] ListIndex Indicate to load which signature list.
+
+ @retval EFI_SUCCESS Success to update the signature data page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadSignatureDataStrings (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN UINT16 DataIndex,
+ IN UINT16 ListIndex
+ );
+
+/**
+ Enroll a new X509 certificate hash into Signature Database (dbx) without
+ KEK's authentication.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] HashAlg The hash algorithm to enroll the certificate.
+ @param[in] RevocationDate The revocation date of the certificate.
+ @param[in] RevocationTime The revocation time of the certificate.
+ @param[in] AlwaysRevocation Indicate whether the certificate is always revoked.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollX509HashtoSigDB (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN UINT32 HashAlg,
+ IN EFI_HII_DATE *RevocationDate,
+ IN EFI_HII_TIME *RevocationTime,
+ IN BOOLEAN AlwaysRevocation
+ );
+
+/**
+ Enroll signature into DB/DBX/DBT without KEK's authentication.
+ The SignatureOwner GUID will be SovereignBootWizardFormsetGuid.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_IMAGE_SECURITY_DATABASE or EFI_IMAGE_SECURITY_DATABASE1.
+
+ @retval EFI_SUCCESS New signature enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval others Fail to enroll signature data.
+
+**/
+EFI_STATUS
+EnrollSignatureDatabase (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ );
+
+/**
+ Check whether a certificate from a file exists in dbx.
+
+ @param[in] PrivateData The module's private data.
+
+ @retval TRUE The X509 certificate is found in dbx successfully.
+ @retval FALSE The X509 certificate is not found in dbx.
+**/
+BOOLEAN
+IsX509CertInDbx (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private
+ );
+
+
+ /**
+ List all signatures in specified signature database (e.g. KEK/DB/DBX/DBT)
+ by GUID in the page for user to select and delete as needed.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the vendor's signature database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+
+**/
+EFI_STATUS
+UpdateDeletePage (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase
+ );
+
+/**
+ This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix.
+
+ @param[in] FileSuffix The suffix of the input certificate file
+
+ @retval TRUE It's a DER-encoded certificate.
+ @retval FALSE It's NOT a DER-encoded certificate.
+
+**/
+BOOLEAN
+IsDerEncodeCertificate (
+ IN CONST CHAR16 *FileSuffix
+ );
+
+/**
+ This code checks if the file content complies with EFI_VARIABLE_AUTHENTICATION_2 format
+The function reads file content but won't open/close given FileHandle.
+
+ @param[in] FileHandle The FileHandle to be checked
+
+ @retval TRUE The content is EFI_VARIABLE_AUTHENTICATION_2 format.
+ @retval FALSE The content is NOT a EFI_VARIABLE_AUTHENTICATION_2 format.
+
+**/
+BOOLEAN
+IsAuthentication2Format (
+ IN EFI_FILE_HANDLE FileHandle
+ );
+
+/**
+ Clean up the dynamic opcode at label and form specified by both LabelId.
+
+ @param[in] FormId It is the Form ID for opcode deletion.
+ @param[in] LabelId It is the Label ID for opcode deletion.
+ @param[in] PrivateData Module private data.
+
+**/
+VOID
+CleanUpPage (
+ IN UINT16 FormId,
+ IN UINT16 LabelId,
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+/**
+ This function to loads bootloader data strings under the bootloader form.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the bootloader list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadBootloaders (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+/**
+ This function to loads certificate list under the bootloader data.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the bootloader page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+LoadBootloaderCertificates (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+/**
+ This function removes the image hash from database.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the signature database
+ @retval EFI_NO_MEDIA If given bootloader was not found.
+ @retval EFI_NOT_FOUND If hash of the image could not be found in
+ database.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+RemoveImageHashFromDatabase (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+/**
+ This function removes a certificate from database.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the signature database
+ @retval EFI_NO_MEDIA If given bootloader or certificate was not
+ found or certificate hash could not be
+ calculated.
+ @retval EFI_NOT_FOUND If the certificate or its hash was not
+ found in database.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+RemoveCertificateFromDatabase (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+/**
+ This function removes all data elated to an image from untrusted database.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the signature database
+ @retval EFI_NO_MEDIA If given bootloader or certificate was not
+ found or certificate hash could not be
+ calculated.
+ @retval EFI_NOT_FOUND If the certificate or its hash was not
+ found in database.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+RemoveImageDataFromDbx (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+/**
+ This function removes all data elated to an image from trusted database.
+
+ @param[in] PrivateData Module's private data.
+
+ @retval EFI_SUCCESS Success to update the signature database
+ @retval EFI_NO_MEDIA If given bootloader or certificate was not
+ found or certificate hash could not be
+ calculated.
+ @retval EFI_NOT_FOUND If the certificate or its hash was not
+ found in database.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+**/
+EFI_STATUS
+RemoveImageDataFromDb (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
+#endif
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/KeyManagement.c b/DasharoModulePkg/Application/SovereignBootWizard/KeyManagement.c
index c0872deec9..b877943307 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/KeyManagement.c
+++ b/DasharoModulePkg/Application/SovereignBootWizard/KeyManagement.c
@@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SovereignBootWizard.h"
+#include "InteractiveModeImpl.h"
STATIC EFI_STATUS
DeleteAllSecureBootVariables (
@@ -203,7 +204,8 @@ CreateSigList (
STATIC EFI_STATUS
EnrollHashToSigDB (
IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
- IN CHAR16 *VariableName
+ IN CHAR16 *VariableName,
+ IN BOOLEAN EnrollImageHash
)
{
EFI_SIGNATURE_LIST *SigDBHash;
@@ -219,7 +221,7 @@ EnrollHashToSigDB (
BOOLEAN Trust;
EFI_INPUT_KEY Key;
- BootloaderEntry = GetMenuEntry (&BootOptionMenu, mBootloaderIndex);
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, mBootloaderIndex);
if (BootloaderEntry == NULL) {
return EFI_NO_MEDIA;
}
@@ -229,13 +231,6 @@ EnrollHashToSigDB (
return EFI_NO_MEDIA;
}
- if (SecurityContext->ImageIsSigned) {
- CertificateEntry = GetCertEntry (BootloaderEntry, mCertIndex);
- if (CertificateEntry == NULL) {
- return EFI_NO_MEDIA;
- }
- }
-
DataSize = 0;
SigDBSize = 0;
SigDBHash = NULL;
@@ -243,7 +238,19 @@ EnrollHashToSigDB (
SigDBSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1;
- if (SecurityContext->ImageIsSigned) {
+ if (EnrollImageHash || !SecurityContext->ImageIsSigned) {
+ SigDBSize += SHA256_DIGEST_SIZE;
+ Status = CreateSigList (
+ SecurityContext->ImageDigest,
+ SecurityContext->ImageDigestSize,
+ &SecurityContext->HashType,
+ &SigDBHash
+ );
+ } else {
+ CertificateEntry = GetCertEntry (BootloaderEntry, mCertIndex);
+ if (CertificateEntry == NULL) {
+ return EFI_NO_MEDIA;
+ }
// EDK2 only checks X509 certificates in DB and DBX, so enroll whole cert to DB.
// For DBX only non-CA (signer's) certificate can be checked.
// Otherwise enroll SHA256 to DBX to save space.
@@ -267,14 +274,6 @@ EnrollHashToSigDB (
&SigDBHash
);
}
- } else {
- SigDBSize += SHA256_DIGEST_SIZE;
- Status = CreateSigList (
- SecurityContext->ImageDigest,
- SecurityContext->ImageDigestSize,
- &SecurityContext->HashType,
- &SigDBHash
- );
}
if (SigDBHash == NULL) {
@@ -318,7 +317,7 @@ EnrollHashToSigDB (
goto ON_EXIT;
}
- if (SecurityContext->ImageIsSigned && Trust) {
+ if (!EnrollImageHash && SecurityContext->ImageIsSigned && Trust) {
if (!CertificateEntry->CertIsValid) {
do {
CreatePopUp (
@@ -354,23 +353,25 @@ EnrollHashToSigDB (
goto ON_EXIT;
}
if (PrivateData->ConfigData.AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED) {
- if (CertificateEntry->CertIsInDbx) {
- do {
- CreatePopUp (
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
- &Key,
- L"",
- L"This certificate is currently untrusted.",
- L"Removing certificates from DBX is not yet supported.",
- L"Can not add the certificate as trusted."
- L"",
- L"Press ENTER to abort the process...",
- L"",
- NULL
- );
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- Status = EFI_ABORTED;
- goto ON_EXIT;
+ if (CertificateEntry->CertIsInDbx || !SecurityContext->ImageIsVerified) {
+ Status = RemoveImageDataFromDbx (PrivateData);
+ if (EFI_ERROR (Status)) {
+ do {
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"",
+ L"Failed to remove all bootloader entries from DBX.",
+ L"Can not add the certificate as trusted."
+ L"",
+ L"Press ENTER to abort the process...",
+ L"",
+ NULL
+ );
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
}
}
}
@@ -394,17 +395,19 @@ EnrollHashToSigDB (
if (Trust && (mFirstTrustedBootloader == -1)) {
mFirstTrustedBootloader = (INTN)mBootloaderIndex;
}
- // If image is unsigned or added as untrusted we have to increment the
- // bootloader index to show next one. No point in displaying other
- // signatures if one of them is already in DBX, as the image will not
- // pass Secure Boot verification. Otherwise move to next certificate.
- if (!SecurityContext->ImageIsSigned || !Trust) {
- mBootloaderIndex++;
- mCertIndex = 0;
- DEBUG ((DEBUG_INFO, "Moving to next bootloader %u\n", mBootloaderIndex));
- } else {
- mCertIndex++;
- DEBUG ((DEBUG_INFO, "Moving to next certificate %u for bootloader %u\n", mCertIndex, mBootloaderIndex));
+ if (!mAltAccessMode) {
+ // If image is unsigned or added as untrusted we have to increment the
+ // bootloader index to show next one. No point in displaying other
+ // signatures if one of them is already in DBX, as the image will not
+ // pass Secure Boot verification. Otherwise move to next certificate.
+ if (!SecurityContext->ImageIsSigned || !Trust) {
+ mBootloaderIndex++;
+ mCertIndex = 0;
+ DEBUG ((DEBUG_INFO, "Moving to next bootloader %u\n", mBootloaderIndex));
+ } else {
+ mCertIndex++;
+ DEBUG ((DEBUG_INFO, "Moving to next certificate %u for bootloader %u\n", mCertIndex, mBootloaderIndex));
+ }
}
}
@@ -419,8 +422,9 @@ EnrollHashToSigDB (
EFI_STATUS
AddKeyOrHashAsTrustedOrUntrusted (
- SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
- BOOLEAN Trust
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN BOOLEAN Trust,
+ IN BOOLEAN EnrollImageHash
)
{
EFI_STRING Message;
@@ -433,38 +437,51 @@ AddKeyOrHashAsTrustedOrUntrusted (
CHAR16 ErrorMessage[MAXIMUM_VALUE_CHARACTERS + 8];
EFI_INPUT_KEY Key;
- Message = HiiGetString (
- PrivateData->HiiHandle,
- Trust ? STRING_TOKEN(STR_SV_TRUST_KEY_QUESTION) : STRING_TOKEN(STR_SV_UNTRUST_KEY_QUESTION),
- NULL);
- HeaderString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN(STR_KEY_FINGERPRINT), NULL);
- HashString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN(STR_KEY_FINGERPRINT_HASH), NULL);
+ PopupMessage = NULL;
- // Size of the whole message plus couple new lines
- PopupMessageSize = StrSize(Message) + StrSize(HeaderString) + StrSize(HashString) + 6;
- PopupMessage = (CHAR16 *) AllocateZeroPool(PopupMessageSize);
+ if (!mAltAccessMode) {
+ Message = HiiGetString (
+ PrivateData->HiiHandle,
+ Trust ? STRING_TOKEN(STR_SV_TRUST_KEY_QUESTION) : STRING_TOKEN(STR_SV_UNTRUST_KEY_QUESTION),
+ NULL);
- if (PopupMessage == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
+ if (PrivateData->FormData.ImageUnsigned) {
+ HeaderString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN(STR_BOOTLOADER_HASH), NULL);
+ } else {
+ HeaderString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN(STR_KEY_FINGERPRINT), NULL);
+ }
+ HashString = HiiGetString (PrivateData->HiiHandle, STRING_TOKEN(STR_KEY_FINGERPRINT_HASH), NULL);
+
+ // Size of the whole message plus couple new lines
+ PopupMessageSize = StrSize(Message) + StrSize(HeaderString) + StrSize(HashString) + 6;
+ PopupMessage = (CHAR16 *) AllocateZeroPool(PopupMessageSize);
+
+ if (PopupMessage == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UnicodeSPrint (PopupMessage, PopupMessageSize, L"%s\n%s\n%s", Message, HeaderString, HashString);
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SV_TRUST_KEY_POPUP), PopupMessage, NULL) ;
- UnicodeSPrint (PopupMessage, PopupMessageSize, L"%s\n%s\n%s", Message, HeaderString, HashString);
- HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SV_TRUST_KEY_POPUP), PopupMessage, NULL) ;
+ Status = PrivateData->HiiPopup->CreatePopup (
+ PrivateData->HiiPopup,
+ EfiHiiPopupStyleInfo,
+ EfiHiiPopupTypeYesNo,
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_SV_TRUST_KEY_POPUP),
+ &UserSelection
+ );
+ } else {
+ UserSelection = EfiHiiPopupSelectionYes;
+ }
- Status = PrivateData->HiiPopup->CreatePopup (
- PrivateData->HiiPopup,
- EfiHiiPopupStyleInfo,
- EfiHiiPopupTypeYesNo,
- PrivateData->HiiHandle,
- STRING_TOKEN (STR_SV_TRUST_KEY_POPUP),
- &UserSelection
- );
if (UserSelection == EfiHiiPopupSelectionYes) {
// Add key or hash to DB or DBX
Status = EnrollHashToSigDB (
PrivateData,
- Trust ? EFI_IMAGE_SECURITY_DATABASE : EFI_IMAGE_SECURITY_DATABASE1
+ Trust ? EFI_IMAGE_SECURITY_DATABASE : EFI_IMAGE_SECURITY_DATABASE1,
+ EnrollImageHash
);
if (EFI_ERROR (Status) && Status != EFI_ABORTED) {
@@ -478,8 +495,8 @@ AddKeyOrHashAsTrustedOrUntrusted (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
L"",
- Trust ? L"Could not add the certificate/image as trusted" :
- L"Could not add the certificate/image as untrusted",
+ Trust ? L"Could not add the certificate/image hash as trusted" :
+ L"Could not add the certificate/image hash as untrusted",
L"",
ErrorMessage,
L"",
@@ -492,7 +509,7 @@ AddKeyOrHashAsTrustedOrUntrusted (
Status = EFI_ABORTED;
}
- FreePool (PopupMessage);
+ FREE_NON_NULL (PopupMessage);
return Status;
}
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SignatureParsing.c b/DasharoModulePkg/Application/SovereignBootWizard/SignatureParsing.c
index e99fd7d54e..9ba29ed1cf 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/SignatureParsing.c
+++ b/DasharoModulePkg/Application/SovereignBootWizard/SignatureParsing.c
@@ -293,7 +293,7 @@ CreateNewCert (
if ((SecCtx == NULL) || (CertData == NULL) || (FileBuffer == NULL) ||
(AuthData == NULL) || (CertEntry == NULL) || (CertDataSize == 0) ||
(FileSize == 0) || (AuthDataSize == 0)) {
- DEBUG ((DEBUG_ERROR, "%a, Invalid parameter\n", __FUNCTION__));
+ DEBUG ((DEBUG_ERROR, "CreateNewCert, Invalid parameter\n"));
return EFI_INVALID_PARAMETER;
}
@@ -353,15 +353,39 @@ CreateNewCert (
);
if (!EFI_ERROR (Status) && IsFound) {
NewCertEntry->CertIsInDb = TRUE;
- } else {
- NewCertEntry->CertIsInDb = FALSE;
}
- NewCertEntry->CertIsInDbx = IsForbiddenByDbx (AuthData, AuthDataSize, ImageDigest, ImageDigestSize);
+ // Check if certificate is in DBX
+ IsFound = FALSE;
+ Status = IsSignatureFoundInDatabase (
+ EFI_IMAGE_SECURITY_DATABASE1,
+ NewCertEntry->CertData,
+ &gEfiCertX509Guid,
+ NewCertEntry->CertDataSize,
+ &IsFound
+ );
+ if (!EFI_ERROR (Status) && IsFound) {
+ NewCertEntry->CertIsInDbx = TRUE;
+ }
+
+ // Check if certificate hash is in DBX
+ IsFound = FALSE;
+ Status = IsCertHashFoundInDbx (
+ NewCertEntry->CertData,
+ NewCertEntry->CertDataSize,
+ NULL,
+ 0,
+ NULL,
+ &IsFound
+ );
+ if (!EFI_ERROR (Status) && IsFound) {
+ NewCertEntry->CertIsInDbx = TRUE;
+ }
+
NewCertEntry->SignatureValid = AuthenticodeVerify (
- AuthData, AuthDataSize,
- NewCertEntry->CertData, NewCertEntry->CertDataSize,
- ImageDigest, ImageDigestSize);
+ AuthData, AuthDataSize,
+ NewCertEntry->CertData, NewCertEntry->CertDataSize,
+ ImageDigest, ImageDigestSize);
NewCertEntry->CertIsCA = CertIsCA (NewCertEntry);
@@ -389,7 +413,7 @@ CreateNewCert (
}
// Mark the image as unverified if it is in DBX.
- if (NewCertEntry->CertIsInDbx) {
+ if (IsForbiddenByDbx (AuthData, AuthDataSize, ImageDigest, ImageDigestSize)) {
SecCtx->ImageIsVerified = FALSE;
}
@@ -632,6 +656,7 @@ FillSecurityContext (
UINTN ImageSize;
UINT32 AuthStatus;
EFI_STATUS Status;
+ EFI_GUID HashType;
FullFilePath = NULL;
LoadCtx = (SV_LOAD_CONTEXT *)Entry->VariableContext;
@@ -684,6 +709,21 @@ FillSecurityContext (
&SecCtx->ImageDigestSize,
&SecCtx->HashType);
+ // Additional hashes for checks in interactive mode.
+ HashPeImage (ImageBase,
+ ImageSize,
+ HASHALG_SHA384,
+ SecCtx->ImageSha384Digest,
+ &SecCtx->ImageSha384DigestSize,
+ &HashType);
+
+ HashPeImage (ImageBase,
+ ImageSize,
+ HASHALG_SHA512,
+ SecCtx->ImageSha512Digest,
+ &SecCtx->ImageSha512DigestSize,
+ &HashType);
+
//
// Start Image Validation.
//
@@ -727,6 +767,121 @@ FillSecurityContext (
return Status;
}
+VOID
+RefreshImageSecurityInfo (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ )
+{
+ SV_MENU_ENTRY *BootloaderEntry;
+ SV_SECURITY_CONTEXT *SecurityContext;
+ SV_CERT_ENTRY *CertificateEntry;
+ UINTN Index;
+ BOOLEAN MsCertFound;
+ BOOLEAN NonMsCertFound;
+ BOOLEAN FoundInDbx;
+ BOOLEAN FoundInDb;
+ BOOLEAN InvalidSigFound;
+
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, mBootloaderIndex);
+ if (BootloaderEntry == NULL) {
+ return;
+ }
+
+ FreeSecurityContext (BootloaderEntry->SecurityContext);
+ FREE_NON_NULL (BootloaderEntry->SecurityContext);
+
+ FillSecurityContext (BootloaderEntry);
+
+ MsCertFound = FALSE;
+ NonMsCertFound = FALSE;
+ FoundInDbx = FALSE;
+ FoundInDb = FALSE;
+ InvalidSigFound = FALSE;
+
+ if (BootloaderEntry->SecurityContext == NULL) {
+ return;
+ }
+
+ SecurityContext = (SV_SECURITY_CONTEXT *)BootloaderEntry->SecurityContext;
+ for (Index = 0; Index < SecurityContext->NumCertificates; Index = Index + 1) {
+ CertificateEntry = GetCertEntry(BootloaderEntry, Index);
+ if (CertificateEntry == NULL) {
+ continue;
+ }
+
+ if (CertificateEntry->CertIsMicrosoft) {
+ MsCertFound = TRUE;
+ } else {
+ NonMsCertFound = TRUE;
+ }
+
+ if (CertificateEntry->CertIsInDbx) {
+ FoundInDbx = TRUE;
+ }
+
+ if (CertificateEntry->CertIsInDb) {
+ FoundInDb = TRUE;
+ }
+
+ if (!CertificateEntry->SignatureValid || !CertificateEntry->CertIsValid) {
+ InvalidSigFound = TRUE;
+ }
+
+ if (Index == mCertIndex) {
+ PrivateData->FormData.CertInDb = CertificateEntry->CertIsInDb;
+ PrivateData->FormData.CertInDbx = CertificateEntry->CertIsInDbx;
+ PrivateData->FormData.CertIsValid = CertificateEntry->CertIsValid;
+ PrivateData->FormData.CertIsMicrosoft = CertificateEntry->CertIsMicrosoft;
+ }
+ }
+
+ PrivateData->FormData.SignedByMs = MsCertFound;
+ PrivateData->FormData.SignedByMsOnly = (!NonMsCertFound && MsCertFound);
+ PrivateData->FormData.HasInvalidSignature = InvalidSigFound;
+ PrivateData->FormData.ImageHashIsInDb = SecurityContext->ImageIsInDb;
+ PrivateData->FormData.ImageHashIsInDbx = SecurityContext->ImageIsInDbx;
+
+ if (SecurityContext->ImageIsSigned) {
+ if (!SecurityContext->ImageIsVerified || FoundInDbx || SecurityContext->ImageIsInDbx) {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_UNTRUSTED;
+ } else if (FoundInDb || SecurityContext->ImageIsInDb) {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_TRUSTED;
+ } else {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_UNDECIDED;
+ }
+ } else {
+ if (SecurityContext->ImageIsInDbx) {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_UNTRUSTED;
+ } else if (SecurityContext->ImageIsInDb) {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_TRUSTED;
+ } else {
+ PrivateData->FormData.ImageTrusted = IMAGE_STATE_UNDECIDED;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "RefreshImageSecurityInfo:\n"
+ " MsCertFound: %u\n"
+ " NonMsCertFound: %u\n"
+ " InvalidSigFound: %u\n"
+ " ImageIsSigned: %u\n"
+ " ImageIsVerified: %u\n"
+ " FoundInDbx: %u\n"
+ " FoundInDb: %u\n"
+ " ImageIsInDb: %u\n"
+ " ImageIsInDbx: %u\n"
+ " ImageTrusted: %u\n",
+ MsCertFound,
+ NonMsCertFound,
+ InvalidSigFound,
+ SecurityContext->ImageIsSigned,
+ SecurityContext->ImageIsVerified,
+ FoundInDbx,
+ FoundInDb,
+ SecurityContext->ImageIsInDb,
+ SecurityContext->ImageIsInDbx,
+ PrivateData->FormData.ImageTrusted));
+}
+
/**
Get the Cert Entry from the list in Menu Entry.
@@ -817,7 +972,7 @@ ParseHashValue (
}
/**
- Parse key modulus from buffer, and save in the CHAR16 type array.
+ Format raw hex buffer, and save in the CHAR16 type array.
The buffer is callee allocated and should be freed by the caller.
@param[in] Digest The pointer to the hash value.
@@ -829,7 +984,7 @@ ParseHashValue (
@retval EFI_SUCCESS Operation success.
**/
EFI_STATUS
-ParseKeyModulus (
+FormatHexBuffer (
IN UINT8 *Digest,
IN UINTN DigestSize,
OUT CHAR16 **BufferToReturn
@@ -898,7 +1053,7 @@ UpdateCertInfo (
EFI_STRING NewString;
EFI_STATUS Status;
- BootloaderEntry = GetMenuEntry (&BootOptionMenu, OptionNumber);
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, OptionNumber);
if (BootloaderEntry == NULL) {
return EFI_NO_MEDIA;
}
@@ -912,17 +1067,16 @@ UpdateCertInfo (
(SecurityContext->NumCertificates == 0));
if (Private->ConfigData.AppLaunchCause != SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED) {
- if (SecurityContext->ImageIsInDb || SecurityContext->ImageIsInDbx) {
- DEBUG ((DEBUG_INFO, "Bootloader %u already (un)trusted\n", OptionNumber));
- return EFI_NO_MEDIA;
+ if (!mAltAccessMode) {
+ if (SecurityContext->ImageIsInDb || SecurityContext->ImageIsInDbx) {
+ DEBUG ((DEBUG_INFO, "Bootloader %u already (un)trusted\n", OptionNumber));
+ return EFI_NO_MEDIA;
+ }
}
}
// Image is unsigned? Show its hash instead of certificates
if (Private->FormData.ImageUnsigned) {
-
- HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_KEY_FINGERPRINT), L"Image hash (SHA-256):\n!!! Image is unsigned !!!", NULL);
-
Status = ParseHashValue (SecurityContext->ImageDigest, SecurityContext->ImageDigestSize, &NewString);
if (!EFI_ERROR (Status)) {
HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_KEY_FINGERPRINT_HASH), NewString, NULL);
@@ -938,7 +1092,7 @@ UpdateCertInfo (
// Do not show images that are not verified (one of the certs in the
// signatures is unstrusted/in DBX), because we won't be able to boot it
// anyways.
- if (!SecurityContext->ImageIsVerified) {
+ if (!SecurityContext->ImageIsVerified && !mAltAccessMode) {
DEBUG ((DEBUG_INFO, "Image %u already untrusted\n", mBootloaderIndex));
mCertIndex = 0;
return EFI_NO_MEDIA;
@@ -955,17 +1109,19 @@ UpdateCertInfo (
// Do not show already trusted/utrusted, invalid or microsoft certificates
if (Private->ConfigData.AppLaunchCause != SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED) {
- if (CertificateEntry->CertIsMicrosoft) {
- DEBUG ((DEBUG_INFO, "Certificate %u belongs to Microsoft\n",
- mCertIndex));
- mCertIndex++;
- continue;
- }
- if (CertificateEntry->CertIsInDb) {
- DEBUG ((DEBUG_INFO, "Certificate %u already trusted\n",
- mCertIndex));
- mCertIndex++;
- continue;
+ if (!mAltAccessMode) {
+ if (CertificateEntry->CertIsMicrosoft) {
+ DEBUG ((DEBUG_INFO, "Certificate %u belongs to Microsoft\n",
+ mCertIndex));
+ mCertIndex++;
+ continue;
+ }
+ if (CertificateEntry->CertIsInDb) {
+ DEBUG ((DEBUG_INFO, "Certificate %u already trusted\n",
+ mCertIndex));
+ mCertIndex++;
+ continue;
+ }
}
}
@@ -978,33 +1134,16 @@ UpdateCertInfo (
return EFI_NO_MEDIA;
}
- if (CertificateEntry->SignatureValid) {
- HiiSetString (
- Private->HiiHandle,
- STRING_TOKEN (STR_KEY_FINGERPRINT),
- L"Certificate fingerprint (SHA-256):",
- NULL
- );
+ if (!CertificateEntry->SignatureValid || !CertificateEntry->CertIsValid) {
+ Private->FormData.HasInvalidSignature = TRUE;
} else {
- HiiSetString (
- Private->HiiHandle,
- STRING_TOKEN (STR_KEY_FINGERPRINT),
- L"Certificate fingerprint (SHA-256):\n!!! Signature is invalid !!!",
- NULL
- );
+ Private->FormData.HasInvalidSignature = FALSE;
}
// Special case if AppLaunchCause is SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED
// We still want to show what the system attempted to boot and failed, even
// if it is signed by MS certificate.
- if (CertificateEntry->CertIsMicrosoft) {
- HiiSetString (
- Private->HiiHandle,
- STRING_TOKEN (STR_KEY_FINGERPRINT),
- L"Certificate fingerprint (SHA-256):\n!!! Certificate belongs to Microsoft !!!",
- NULL
- );
- }
+ Private->FormData.SignedByMs = CertificateEntry->CertIsMicrosoft;
Status = ParseHashValue (CertificateEntry->CertDigest, CertificateEntry->CertDigestSize, &NewString);
if (!EFI_ERROR (Status)) {
@@ -1062,7 +1201,7 @@ UpdateCertIssuerAndSubjectStrings (
IN SV_CERT_ENTRY *CertificateEntry
)
{
- CHAR8 StringBuffer[500];
+ CHAR8 StringBuffer[BUFFER_MAX_SIZE];
UINTN StringBufferSize;
CHAR16 *NewString;
@@ -1190,7 +1329,7 @@ UpdateCertKeyStrings (
}
NewString = NULL;
- if (!EFI_ERROR (ParseKeyModulus (ModulusBuffer, PubKeyModSize, &NewString))) {
+ if (!EFI_ERROR (FormatHexBuffer (ModulusBuffer, PubKeyModSize, &NewString))) {
HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CERT_KEY_MODULUS_HEX), NewString, NULL);
}
FREE_NON_NULL (NewString);
@@ -1205,6 +1344,139 @@ UpdateCertKeyStrings (
FREE_NON_NULL (ModulusBuffer);
}
+VOID
+UpdateKeyStringsFromSigList (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN EFI_SIGNATURE_DATA *Data
+ )
+{
+ UINT8 *ModulusBuffer;
+ CHAR16 *NewString;
+ UINT16 ExponentString[20];
+
+ HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CERT_KEY_MODULUS_HEX), L"Unknown", NULL);
+ HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CERT_KEY_EXPONENT2), L"Unknown", NULL);
+
+ ModulusBuffer = (UINT8 *)Data->SignatureData;
+
+ NewString = NULL;
+ if (!EFI_ERROR (FormatHexBuffer (ModulusBuffer, WIN_CERT_UEFI_RSA2048_SIZE, &NewString))) {
+ HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CERT_KEY_MODULUS_HEX), NewString, NULL);
+ }
+ FREE_NON_NULL (NewString);
+
+ SetMem(ExponentString, sizeof (ExponentString), 0);
+ HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_CERT_KEY_EXPONENT2), L"0x10001", NULL);
+}
+
+VOID
+UpdateTimeString (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN EFI_TIME *Time
+ )
+{
+ CHAR16 TimeString[BUFFER_MAX_SIZE];
+
+ ZeroMem (TimeString, sizeof (TimeString));
+ UnicodeSPrint (
+ TimeString,
+ sizeof (TimeString),
+ L"%02d-%02d-%04d %02d:%02d:%02d",
+ Time->Day,
+ Time->Month,
+ Time->Year,
+ Time->Hour,
+ Time->Minute,
+ Time->Second
+ );
+
+ HiiSetString(Private->HiiHandle, STRING_TOKEN(STR_SIGNATURE_DATA_REVOCATION_TIME2), TimeString, NULL);
+}
+
+VOID
+UpdateHashStringsFromSigData (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN EFI_SIGNATURE_DATA *Data,
+ IN UINT32 DataSize
+ )
+{
+ CHAR16 *HexString;
+
+ HexString = NULL;
+ if (!EFI_ERROR (FormatHexBuffer (Data->SignatureData, DataSize, &HexString))) {
+ HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_SIGNATURE_DATA_RAW_HEX), HexString, NULL);
+ }
+ FREE_NON_NULL (HexString);
+}
+
+VOID
+FillKeyHashStrings (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN EFI_SIGNATURE_LIST *List,
+ IN EFI_SIGNATURE_DATA *Data
+ )
+{
+ UINT32 DataSize;
+ EFI_TIME *Time;
+
+ Private->FormData.IsCertHash = FALSE;
+
+ switch (Private->FormData.SignatureType) {
+ case SIGNATURE_TYPE_RSA2048:
+ UpdateKeyStringsFromSigList (Private, Data);
+ return;
+ case SIGNATURE_TYPE_RSA2048_SHA256:
+ DataSize = List->SignatureSize - sizeof (EFI_GUID);
+ break;
+ case SIGNATURE_TYPE_SHA1:
+ DataSize = 20;
+ break;
+ case SIGNATURE_TYPE_SHA224:
+ DataSize = 28;
+ break;
+ case SIGNATURE_TYPE_X509_SHA256:
+ case SIGNATURE_TYPE_X509_SM3:
+ Private->FormData.IsCertHash = TRUE;
+ case SIGNATURE_TYPE_SHA256:
+ case SIGNATURE_TYPE_SM3:
+ DataSize = 32;
+ break;
+ case SIGNATURE_TYPE_X509_SHA384:
+ Private->FormData.IsCertHash = TRUE;
+ case SIGNATURE_TYPE_SHA384:
+ DataSize = 48;
+ break;
+ case SIGNATURE_TYPE_X509_SHA512:
+ Private->FormData.IsCertHash = TRUE;
+ case SIGNATURE_TYPE_SHA512:
+ DataSize = 64;
+ break;
+ case SIGNATURE_TYPE_UNKNOWN:
+ default:
+ UpdateHashStringsFromSigData (Private, Data, List->SignatureSize);
+ return;
+ }
+
+ if (Private->FormData.IsCertHash) {
+ Time = (EFI_TIME *)(Data->SignatureData + DataSize);
+ UpdateTimeString (Private, Time);
+ }
+
+ UpdateHashStringsFromSigData (Private, Data, DataSize);
+}
+
+VOID
+FillCertStrings (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN SV_CERT_ENTRY *CertificateEntry
+ )
+{
+ UpdateCertValidityStrings (Private, CertificateEntry);
+ UpdateCertIssuerAndSubjectStrings (Private, CertificateEntry);
+ UpdateCertSerialNumberString (Private, CertificateEntry);
+ UpdateCertKeyStrings (Private, CertificateEntry);
+}
+
EFI_STATUS
UpdateCertDetails (
IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private
@@ -1213,7 +1485,7 @@ UpdateCertDetails (
SV_MENU_ENTRY *BootloaderEntry;
SV_CERT_ENTRY *CertificateEntry;
- BootloaderEntry = GetMenuEntry (&BootOptionMenu, mBootloaderIndex);
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, mBootloaderIndex);
if (BootloaderEntry == NULL) {
return EFI_NO_MEDIA;
}
@@ -1223,10 +1495,12 @@ UpdateCertDetails (
return EFI_NO_MEDIA;
}
- UpdateCertValidityStrings (Private, CertificateEntry);
- UpdateCertIssuerAndSubjectStrings (Private, CertificateEntry);
- UpdateCertSerialNumberString (Private, CertificateEntry);
- UpdateCertKeyStrings (Private, CertificateEntry);
+ FillCertStrings (Private, CertificateEntry);
+
+ Private->FormData.CertInDb = CertificateEntry->CertIsInDb;
+ Private->FormData.CertInDbx = CertificateEntry->CertIsInDbx;
+ Private->FormData.CertIsValid = CertificateEntry->CertIsValid;
+ Private->FormData.CertIsMicrosoft = CertificateEntry->CertIsMicrosoft;
return EFI_SUCCESS;
}
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.c b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.c
index 8132746694..ebfd0db62f 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.c
+++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.c
@@ -7,12 +7,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SovereignBootWizard.h"
+#include "InteractiveModeImpl.h"
-SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *mPrivateData = NULL;
+SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *mPrivateData = NULL;
+SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *gPrivateData = NULL;
BOOLEAN mBootloadersInitted;
+BOOLEAN mAltAccessMode;
STATIC CHAR16 mSvBootDataVarName[] = SV_BOOT_DATA_VAR;
-STATIC CHAR16 mVarStoreName[] = L"SvBootFormData";
+STATIC CHAR16 mVarStoreName[] = SV_BOOT_VARSTORE_NAME;
STATIC CHAR16 mSvBootConfigVarName[] = SV_BOOT_CONFIG_VAR;
STATIC BOOLEAN mBootloadersShown;
@@ -82,23 +85,25 @@ ExtractConfig (
)
{
EFI_STATUS Status;
- SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private;
+ SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData;
UINTN BufferSize;
EFI_STRING ConfigRequestHdr;
EFI_STRING ConfigRequest;
UINTN Size;
- if (Progress == NULL || Results == NULL) {
+ if ((Progress == NULL) || (Results == NULL)) {
return EFI_INVALID_PARAMETER;
}
*Progress = Request;
- if (Request != NULL &&
+ if ((Request != NULL) &&
!HiiIsConfigHdrMatch (Request, &gSovereignBootWizardFormSetGuid, mVarStoreName)) {
return EFI_NOT_FOUND;
}
- Private = SOVEREIGN_BOOT_WIZARD_PRIVATE_FROM_THIS (This);
+ PrivateData = SOVEREIGN_BOOT_WIZARD_PRIVATE_FROM_THIS (This);
+
+ InteractiveModeExtractConfig (PrivateData, &PrivateData->FormData);
BufferSize = sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA);
ConfigRequest = Request;
@@ -109,7 +114,7 @@ ExtractConfig (
ConfigRequestHdr = HiiConstructConfigHdr (
&gSovereignBootWizardFormSetGuid,
mVarStoreName,
- Private->AppHandle
+ PrivateData->AppHandle
);
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
ConfigRequest = AllocateZeroPool (Size);
@@ -125,10 +130,10 @@ ExtractConfig (
}
// Convert fields of binary structure to string representation.
- Status = Private->HiiConfigRouting->BlockToConfig (
- Private->HiiConfigRouting,
+ Status = PrivateData->HiiConfigRouting->BlockToConfig (
+ PrivateData->HiiConfigRouting,
ConfigRequest,
- (CONST UINT8 *) &Private->FormData,
+ (CONST UINT8 *) &PrivateData->FormData,
BufferSize,
Results,
Progress
@@ -140,7 +145,9 @@ ExtractConfig (
FreePool (ConfigRequest);
}
- if (Request != NULL && StrStr (Request, L"OFFSET") == NULL) {
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
*Progress = Request + StrLen (Request);
}
@@ -176,7 +183,7 @@ RouteConfig (
{
EFI_STATUS Status;
UINTN BufferSize;
- SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData;
+ SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData;
if ((Configuration == NULL) || (Progress == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -189,13 +196,11 @@ RouteConfig (
return EFI_NOT_FOUND;
}
- if (HiiIsConfigHdrMatch (Configuration, &gSovereignBootWizardFormSetGuid, mSvBootDataVarName)) {
+ if (!HiiIsConfigHdrMatch (Configuration, &gSovereignBootWizardFormSetGuid, mVarStoreName)) {
return EFI_UNSUPPORTED;
}
- if (!HiiIsConfigHdrMatch (Configuration, &gSovereignBootWizardFormSetGuid, mSvBootConfigVarName)) {
- return EFI_UNSUPPORTED;
- }
+ InteractiveModeExtractConfig (PrivateData, &PrivateData->FormData);
BufferSize = sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA);
Status = PrivateData->HiiConfigRouting->ConfigToBlock (
@@ -209,13 +214,16 @@ RouteConfig (
return Status;
}
+ *Progress = Configuration + StrLen (Configuration);
+
return EFI_SUCCESS;
}
EFI_STATUS
BootTheBootloader (
SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
- UINTN BootloaderIndex
+ UINTN BootloaderIndex,
+ BOOLEAN SetFirstPriority
)
{
SV_MENU_ENTRY *BootloaderEntry;
@@ -226,7 +234,7 @@ BootTheBootloader (
INTN OptionIndex;
EFI_STATUS Status;
- BootloaderEntry = GetMenuEntry (&BootOptionMenu, BootloaderIndex);
+ BootloaderEntry = GetMenuEntry (&mBootOptionMenu, BootloaderIndex);
if (BootloaderEntry == NULL) {
DEBUG ((DEBUG_INFO, "Bootloader %u entry not found\n", BootloaderIndex));
return EFI_NO_MEDIA;
@@ -269,19 +277,31 @@ BootTheBootloader (
gST->ConOut->ClearScreen (gST->ConOut);
}
- // TODO: Make this bootloader the first boot priority
if (OptionIndex == -1) {
- Status = EfiBootManagerAddLoadOptionVariable (&BootOption, MAX_UINTN);
+ Status = EfiBootManagerAddLoadOptionVariable (&BootOption, SetFirstPriority ? 0 : MAX_UINTN);
if (EFI_ERROR (Status)) {
EfiBootManagerFreeLoadOption (&BootOption);
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
DEBUG ((DEBUG_ERROR, "Failed to add load option variable: %r\n", Status));
return Status;
}
- DEBUG ((DEBUG_INFO, "Booting %s\n", BootloaderContext->Description));
+ DEBUG ((DEBUG_INFO, "Booting new option: %s\n", BootloaderContext->Description));
EfiBootManagerBoot (&BootOption);
} else {
- DEBUG ((DEBUG_INFO, "Booting %s\n", BootloaderContext->Description));
+ if (SetFirstPriority) {
+ // Remove the Boot#### variable associated with the bootloader and its
+ // entry in Bootorder variable
+ EfiBootManagerDeleteLoadOptionVariable (BootOption.OptionNumber, BootOption.OptionType);
+ // Create the Boot#### option again with the top priority
+ Status = EfiBootManagerAddLoadOptionVariable (&BootOption, 0);
+ if (EFI_ERROR (Status)) {
+ EfiBootManagerFreeLoadOption (&BootOption);
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+ DEBUG ((DEBUG_ERROR, "Failed to add load option variable: %r\n", Status));
+ return Status;
+ }
+ }
+ DEBUG ((DEBUG_INFO, "Booting option %d: %s\n", OptionIndex, BootloaderContext->Description));
EfiBootManagerBoot (&BootOptions[OptionIndex]);
}
@@ -308,6 +328,7 @@ PrepareBootloaders (
if (!EFI_ERROR (Status)) {
mBootloadersInitted = TRUE;
if (!mBootloadersShown) {
+ mAltAccessMode = FALSE;
Status = UpdateBootloaderPage (PrivateData);
mBootloadersShown = !EFI_ERROR (Status);
}
@@ -377,6 +398,12 @@ Callback (
SOVEREIGN_BOOT_WIZARD_NV_CONFIG SvConfig;
BROWSER_SETTING_SCOPE Scope;
UINTN BootloaderToBoot;
+ EFI_DEVICE_PATH_PROTOCOL *File;
+ UINTN NameLength;
+ UINT16 *FilePostFix;
+ BOOLEAN GetBrowserDataResult;
+
+ File = NULL;
if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) ||
(ActionRequest == NULL))
@@ -387,6 +414,14 @@ Callback (
Status = EFI_SUCCESS;
PrivateData = SOVEREIGN_BOOT_WIZARD_PRIVATE_FROM_THIS (This);
+ gPrivateData = PrivateData;
+
+ GetBrowserDataResult = HiiGetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData);
+
switch (Action) {
case EFI_BROWSER_ACTION_CHANGING:
switch (QuestionId) {
@@ -405,13 +440,13 @@ Callback (
&SvConfig
);
if (EFI_ERROR (Status)) {
- return Status;
+ goto EXIT;
}
// 3. Restore default keys if necessary. Maybe use NV VendorKeys to
// indicate if key restoration is required.
Status = RestoreSecureBootDefaults ();
if (EFI_ERROR (Status)) {
- return Status;
+ goto EXIT;
}
// 4. Reset the system to boot in a fresh state. Can't really avoid
// the reset as we cannot exit the form in any other action than
@@ -461,71 +496,40 @@ Callback (
}
Status = PrivateData->FormBrowserEx2->ExecuteAction(BROWSER_ACTION_EXIT, 0);
- return Status;
+ goto EXIT;
}
PrepareBootloaders(PrivateData);
break;
}
- case DO_NOT_TRUST_KEY_FORM2_QUESTION_ID:
- {
- // Add cert or image hash to DBX
- Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, FALSE);
- break;
- }
- case TRUST_KEY_FORM2_QUESTION_ID:
- {
- // Add cert or image hash to DB
- Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, TRUE);
- break;
- }
- case SHOW_KEY_DETAILS_FORM2_QUESTION_ID:
- {
- // Update the strings when opening certificate details form
- Status = UpdateCertDetails (PrivateData);
- break;
- }
- default:
- break;
- }
-
- break;
- case EFI_BROWSER_ACTION_CHANGED:
- {
- switch (QuestionId) {
- case EXIT_FORM1_QUESTION_ID:
- case EXIT_FORM2_QUESTION_ID:
- case EXIT_FORM3_QUESTION_ID:
- case EXIT_FORM9_QUESTION_ID:
- if (PrivateData->ConfigData.AppLaunchCause == SV_BOOT_LAUNCH_VIA_SETUP) {
- Scope = FormSetLevel;
- } else {
- Scope = SystemLevel;
- }
- PrivateData->FormBrowserEx2->SetScope (Scope);
- Status = PrivateData->FormBrowserEx2->ExecuteAction(BROWSER_ACTION_EXIT, 0);
-
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- break;
- case SKIP_KEY_FORM2_QUESTION_ID:
+ case KEY_SKIP_KEY_FORM2:
if (PrivateData->FormData.ImageUnsigned) {
mBootloaderIndex++;
} else {
mCertIndex++;
}
// fallthrough
- case DO_NOT_TRUST_KEY_FORM2_QUESTION_ID:
- case TRUST_KEY_FORM2_QUESTION_ID:
+ case KEY_DO_NOT_TRUST_KEY_FORM2:
+ case KEY_TRUST_KEY_FORM2:
+ if (QuestionId == KEY_DO_NOT_TRUST_KEY_FORM2) {
+ // Add cert or image hash to DBX
+ mAltAccessMode = FALSE;
+ Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, FALSE, FALSE);
+ } else if (QuestionId == KEY_TRUST_KEY_FORM2) {
+ // Add cert or image hash to DB
+ mAltAccessMode = FALSE;
+ Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, TRUE, FALSE);
+ }
if (mBootloadersInitted) {
Status = UpdateBootloaderPage (PrivateData);
if (Status == EFI_NO_MEDIA) {
// If we failed image verification and do not trust the image, simply exit
- if (QuestionId == DO_NOT_TRUST_KEY_FORM2_QUESTION_ID &&
+ if (QuestionId == KEY_DO_NOT_TRUST_KEY_FORM2 &&
PrivateData->ConfigData.AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED) {
PrivateData->FormBrowserEx2->SetScope (SystemLevel);
Status = PrivateData->FormBrowserEx2->ExecuteAction(BROWSER_ACTION_EXIT, 0);
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- return Status;
+ goto EXIT;
}
do {
CreatePopUp (
@@ -562,7 +566,7 @@ Callback (
);
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
// 4. Boot the first trusted bootloader.
- BootTheBootloader(PrivateData, (UINTN)mFirstTrustedBootloader);
+ BootTheBootloader(PrivateData, (UINTN)mFirstTrustedBootloader, TRUE);
// If we return from the bootloader, exit the form completely.
mBootloaderIndex = 0;
if (PrivateData->ConfigData.AppLaunchCause == SV_BOOT_LAUNCH_VIA_SETUP) {
@@ -635,10 +639,10 @@ Callback (
}
}
break;
- case TRUST_KEY_AND_BOOT_FORM2_QUESTION_ID:
+ case KEY_TRUST_KEY_AND_BOOT_FORM2:
BootloaderToBoot = mBootloaderIndex;
// Add cert or image hash to DB
- Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, TRUE);
+ Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, TRUE, FALSE);
if (EFI_ERROR (Status)) {
// If we are already provisioned and fail, simply exit the wizard.
// If the image verification fails, a string will be shown on the
@@ -652,14 +656,14 @@ Callback (
PrivateData->FormBrowserEx2->SetScope (Scope);
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
}
- return Status;
+ goto EXIT;
}
// If we failed image verification and decided to trust the image, simply boot it
if (PrivateData->ConfigData.AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED) {
- Status = BootTheBootloader (PrivateData, BootloaderToBoot);
+ Status = BootTheBootloader (PrivateData, BootloaderToBoot, FALSE);
PrivateData->FormBrowserEx2->SetScope (SystemLevel);
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
- return Status;
+ goto EXIT;
}
// All is left here is to enroll PK to enable Secure Boot, set
@@ -676,7 +680,7 @@ Callback (
NULL
);
gBS->Stall (2 * 1000 * 1000);
- Status = BootTheBootloader (PrivateData, BootloaderToBoot);
+ Status = BootTheBootloader (PrivateData, BootloaderToBoot, TRUE);
// Do not go back to wizard after booting
if (PrivateData->ConfigData.AppLaunchCause == SV_BOOT_LAUNCH_VIA_SETUP) {
Scope = FormSetLevel;
@@ -702,6 +706,682 @@ Callback (
);
}
break;
+ case KEY_SHOW_KEY_DETAILS_FORM2:
+ {
+ PrivateData->FormData.BlCertView = FALSE;
+ // Update the strings when opening certificate details form
+ Status = UpdateCertDetails (PrivateData);
+ break;
+ }
+ case KEY_ADD_CERT_TO_DBX:
+ {
+ // Add cert or image hash to DBX
+ mAltAccessMode = TRUE;
+ Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, FALSE, FALSE);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_ADD_CERT_TO_DB:
+ {
+ // Add cert or image hash to DB
+ mAltAccessMode = TRUE;
+ Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, TRUE, FALSE);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_REMOVE_CERT_FROM_DB:
+ {
+ PrivateData->VariableName = Variable_DB;
+ Status = RemoveCertificateFromDatabase (PrivateData);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_REMOVE_CERT_FROM_DBX:
+ {
+ PrivateData->VariableName = Variable_DBX;
+ Status = RemoveCertificateFromDatabase (PrivateData);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_ADD_HASH_TO_DBX:
+ {
+ // Add cert or image hash to DBX
+ mAltAccessMode = TRUE;
+ Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, FALSE, TRUE);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_ADD_HASH_TO_DB:
+ {
+ // Add cert or image hash to DB
+ mAltAccessMode = TRUE;
+ Status = AddKeyOrHashAsTrustedOrUntrusted(PrivateData, TRUE, TRUE);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_REMOVE_HASH_FROM_DB:
+ {
+ PrivateData->VariableName = Variable_DB;
+ Status = RemoveImageHashFromDatabase (PrivateData);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_REMOVE_HASH_FROM_DBX:
+ {
+ PrivateData->VariableName = Variable_DBX;
+ Status = RemoveImageHashFromDatabase (PrivateData);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_REMOVE_ALL_IMAGE_DATA:
+ {
+ Status = RemoveImageDataFromDbx (PrivateData);
+ Status |= RemoveImageDataFromDb (PrivateData);
+ RefreshImageSecurityInfo (PrivateData);
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ GetBrowserDataResult = FALSE;
+ break;
+ }
+ case KEY_SOVEREIGN_BOOT_BL_OPTION:
+ if (!mBootloadersInitted) {
+ Status = GetBootOptions (PrivateData);
+ if (!EFI_ERROR (Status)) {
+ mBootloadersInitted = TRUE;
+ } else {
+ if (Status != EFI_NOT_FOUND) {
+ PrivateData->FormData.BootloaderCount = 0;
+ break;
+ }
+ }
+ }
+ PrivateData->FormData.BlCertView = TRUE;
+ LoadBootloaders (PrivateData);
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_SOVEREIGN_BOOT_DB_OPTION:
+ PrivateData->VariableName = Variable_DB;
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DB_CERTS_DATA_START,
+ FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM,
+ OPTION_DB_LIST_QUESTION_ID
+ );
+
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_SOVEREIGN_BOOT_DBX_OPTION:
+ PrivateData->VariableName = Variable_DBX;
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DBX_CERTS_DATA_START,
+ FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM,
+ OPTION_DBX_LIST_QUESTION_ID
+ );
+
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_ENROLL_SIGNATURE_TO_DB:
+ // Refresh selected file.
+ PrivateData->FormData.FileEnrollType = UNKNOWN_FILE_TYPE;
+ PrivateData->FormData.CertificateFormat = HASHALG_SHA256;
+ CloseEnrolledFile (PrivateData->FileContext);
+ CleanUpPage (
+ SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB,
+ LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB,
+ PrivateData);
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_ENROLL_SIGNATURE_TO_DBX:
+ // Refresh selected file.
+ PrivateData->FormData.FileEnrollType = UNKNOWN_FILE_TYPE;
+ PrivateData->FormData.CertificateFormat = HASHALG_SHA256;
+ CloseEnrolledFile (PrivateData->FileContext);
+ CleanUpPage (
+ SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX,
+ LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX,
+ PrivateData);
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB:
+ mAltAccessMode = FALSE;
+ ChooseFile (NULL, NULL, UpdateDBFromFile, &File);
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX:
+ mAltAccessMode = FALSE;
+ ChooseFile (NULL, NULL, UpdateDBXFromFile, &File);
+
+ if (PrivateData->FileContext->FHandle != NULL) {
+ //
+ // Parse the file's postfix.
+ //
+ NameLength = StrLen (PrivateData->FileContext->FileName);
+ if (NameLength <= 4) {
+ return FALSE;
+ }
+
+ FilePostFix = PrivateData->FileContext->FileName + NameLength - 4;
+
+ if (IsDerEncodeCertificate (FilePostFix)) {
+ //
+ // Supports DER-encoded X509 certificate.
+ //
+ PrivateData->FormData.FileEnrollType = X509_CERT_FILE_TYPE;
+ PrivateData->FormData.CertificateFormat = HASHALG_RAW;
+ } else if (IsAuthentication2Format (PrivateData->FileContext->FHandle)) {
+ PrivateData->FormData.FileEnrollType = AUTHENTICATION_2_FILE_TYPE;
+ PrivateData->FormData.CertificateFormat = HASHALG_RAW;
+ } else {
+ PrivateData->FormData.FileEnrollType = PE_IMAGE_FILE_TYPE;
+ PrivateData->FormData.CertificateFormat = HASHALG_SHA256;
+ }
+
+ PrivateData->FileContext->FileType = PrivateData->FormData.FileEnrollType;
+ }
+
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_SOVEREIGN_BOOT_DELETE_SIGNATURE_FROM_DB:
+ mAltAccessMode = FALSE;
+ UpdateDeletePage (
+ PrivateData,
+ EFI_IMAGE_SECURITY_DATABASE,
+ &gEfiImageSecurityDatabaseGuid,
+ LABEL_DB_DELETE,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_FROM_DB,
+ OPTION_DEL_DB_QUESTION_ID
+ );
+ Status = EFI_SUCCESS;
+ break;
+
+ //
+ // From DBX option to the level-1 form, display signature list.
+ //
+ case KEY_VALUE_FROM_DBX_TO_LIST_FORM:
+ mAltAccessMode = FALSE;
+ PrivateData->VariableName = Variable_DBX;
+ LoadSignatureList (
+ PrivateData,
+ LABEL_SIGNATURE_LIST_START,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_LIST_FORM,
+ OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ Status = EFI_SUCCESS;
+ break;
+
+ //
+ // Delete all signature list and reload.
+ //
+ case KEY_SOVEREIGN_BOOT_DELETE_ALL_LIST:
+ mAltAccessMode = FALSE;
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Press 'Y' to delete signature list.",
+ L"Press other key to cancel and exit.",
+ NULL
+ );
+
+ if ((Key.UnicodeChar == L'Y') || (Key.UnicodeChar == L'y')) {
+ DeleteSignatureEx (PrivateData, Delete_Signature_List_All, PrivateData->FormData.CheckedDataCount);
+ }
+
+ LoadSignatureList (
+ PrivateData,
+ LABEL_SIGNATURE_LIST_START,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_LIST_FORM,
+ OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ PrivateData->FormData.ListCount = PrivateData->ListCount;
+ Status = EFI_SUCCESS;
+ break;
+
+ //
+ // Delete one signature list and reload.
+ //
+ case KEY_SOVEREIGN_BOOT_DELETE_ALL_DATA:
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Press 'Y' to delete signature data.",
+ L"Press other key to cancel and exit.",
+ NULL
+ );
+
+ if ((Key.UnicodeChar == L'Y') || (Key.UnicodeChar == L'y')) {
+ DeleteSignatureEx (
+ PrivateData,
+ Delete_Signature_List_One,
+ mAltAccessMode ? 1 : PrivateData->FormData.CheckedDataCount);
+ }
+
+ if (!mAltAccessMode) {
+ Value->ref.FormId = SOVEREIGN_BOOT_DELETE_SIGNATURE_LIST_FORM;
+ CleanUpPage (Value->ref.FormId, LABEL_SIGNATURE_LIST_START, PrivateData);
+ LoadSignatureList (
+ PrivateData,
+ LABEL_SIGNATURE_LIST_START,
+ Value->ref.FormId,
+ OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ } else {
+ if (PrivateData->VariableName == Variable_DB) {
+ Value->ref.FormId = FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM;
+ CleanUpPage (Value->ref.FormId, LABEL_DB_CERTS_DATA_START, PrivateData);
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DB_CERTS_DATA_START,
+ Value->ref.FormId,
+ OPTION_DB_LIST_QUESTION_ID
+ );
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ Value->ref.FormId = FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM;
+ CleanUpPage (Value->ref.FormId, LABEL_DBX_CERTS_DATA_START, PrivateData);
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DBX_CERTS_DATA_START,
+ Value->ref.FormId,
+ OPTION_DBX_LIST_QUESTION_ID
+ );
+ } else {
+ Value->ref.FormId = SOVEREIGN_BOOT_WIZARD_INTERACTIVE_MODE_FORM_ID;
+ }
+ }
+ PrivateData->FormData.ListCount = PrivateData->ListCount;
+ Status = EFI_SUCCESS;
+ break;
+
+ //
+ // Delete checked signature data and reload.
+ //
+ case KEY_SOVEREIGN_BOOT_DELETE_CHECK_DATA:
+ mAltAccessMode = FALSE;
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Press 'Y' to delete signature data.",
+ L"Press other key to cancel and exit.",
+ NULL
+ );
+
+ if ((Key.UnicodeChar == L'Y') || (Key.UnicodeChar == L'y')) {
+ DeleteSignatureEx (PrivateData, Delete_Signature_Data, PrivateData->FormData.CheckedDataCount);
+ }
+
+ LoadSignatureList (
+ PrivateData,
+ LABEL_SIGNATURE_LIST_START,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_LIST_FORM,
+ OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ PrivateData->FormData.ListCount = PrivateData->ListCount;
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_REMOVE_HASH_FROM_DATABASE:
+ case KEY_REMOVE_KEY_FROM_DATABASE:
+ case KEY_REMOVE_CERT_FROM_DATABASE:
+ mAltAccessMode = TRUE;
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Press 'Y' to delete signature data.",
+ L"Press other key to cancel and exit.",
+ NULL
+ );
+
+ if ((Key.UnicodeChar == L'Y') || (Key.UnicodeChar == L'y')) {
+ DeleteSignatureEx (PrivateData, Delete_Signature_Data, 1);
+ }
+
+ if (PrivateData->DataCount == 1) {
+ if (PrivateData->VariableName == Variable_DB) {
+ Value->ref.FormId = FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM;
+ CleanUpPage (Value->ref.FormId, LABEL_DB_CERTS_DATA_START, PrivateData);
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DB_CERTS_DATA_START,
+ Value->ref.FormId,
+ OPTION_DB_LIST_QUESTION_ID
+ );
+ PrivateData->FormData.ListCount = PrivateData->ListCount;
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ Value->ref.FormId = FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM;
+ CleanUpPage (Value->ref.FormId, LABEL_DBX_CERTS_DATA_START, PrivateData);
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DBX_CERTS_DATA_START,
+ Value->ref.FormId,
+ OPTION_DBX_LIST_QUESTION_ID
+ );
+ PrivateData->FormData.ListCount = PrivateData->ListCount;
+ } else {
+ Value->ref.FormId = SOVEREIGN_BOOT_WIZARD_INTERACTIVE_MODE_FORM_ID;
+ }
+ } else {
+ Value->ref.FormId = SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM;
+ CleanUpPage (Value->ref.FormId, LABEL_SIGNATURE_DATA_START, PrivateData);
+ if (PrivateData->VariableName == Variable_DB) {
+ LoadSignatureData (
+ PrivateData,
+ LABEL_SIGNATURE_DATA_START,
+ Value->ref.FormId,
+ OPTION_DB_ENTRIES_QUESTION_ID,
+ PrivateData->ListIndex
+ );
+ } else if (PrivateData->VariableName == Variable_DBX) {
+ LoadSignatureData (
+ PrivateData,
+ LABEL_SIGNATURE_DATA_START,
+ Value->ref.FormId,
+ OPTION_DBX_ENTRIES_QUESTION_ID,
+ PrivateData->ListIndex
+ );
+ }
+ }
+
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_VALUE_SAVE_AND_EXIT_DB:
+ Status = EnrollSignatureDatabase (PrivateData, EFI_IMAGE_SECURITY_DATABASE);
+ if (EFI_ERROR (Status)) {
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"ERROR: Unsupported file type!",
+ L"Only supports DER-encoded X509 certificate and executable EFI image",
+ NULL
+ );
+ } else {
+ CleanUpPage (
+ FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM,
+ LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB,
+ PrivateData);
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DB_CERTS_DATA_START,
+ FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM,
+ OPTION_DB_LIST_QUESTION_ID
+ );
+ PrivateData->FormData.ListCount = PrivateData->ListCount;
+ }
+ Status = EFI_SUCCESS;
+ break;
+
+ case KEY_VALUE_SAVE_AND_EXIT_DBX:
+ if (IsX509CertInDbx (PrivateData)) {
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Enrollment failed! Same certificate had already been in the dbx!",
+ NULL
+ );
+
+ //
+ // Cert already exists in DBX. Close opened file before exit.
+ //
+ CloseEnrolledFile (PrivateData->FileContext);
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ if (PrivateData->FormData.CertificateFormat < HASHALG_MAX) {
+ Status = EnrollX509HashtoSigDB (
+ PrivateData,
+ PrivateData->FormData.CertificateFormat,
+ &PrivateData->FormData.RevocationDate,
+ &PrivateData->FormData.RevocationTime,
+ PrivateData->FormData.AlwaysRevocation
+ );
+ PrivateData->FormData.CertificateFormat = HASHALG_RAW;
+ } else {
+ Status = EnrollSignatureDatabase (PrivateData, EFI_IMAGE_SECURITY_DATABASE1);
+ }
+
+ if (EFI_ERROR (Status)) {
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"ERROR: Unsupported file type!",
+ L"Only supports DER-encoded X509 certificate, AUTH_2 format data & executable EFI image",
+ NULL
+ );
+ } else {
+ CleanUpPage (
+ FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM,
+ LABEL_DBX_CERTS_DATA_START,
+ PrivateData);
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DBX_CERTS_DATA_START,
+ FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM,
+ OPTION_DBX_LIST_QUESTION_ID
+ );
+ PrivateData->FormData.ListCount = PrivateData->ListCount;
+ }
+
+ break;
+
+ case KEY_VALUE_NO_SAVE_AND_EXIT_DB:
+ case KEY_VALUE_NO_SAVE_AND_EXIT_DBX:
+ CloseEnrolledFile (PrivateData->FileContext);
+ Status = EFI_SUCCESS;
+ break;
+
+ default:
+ if ((QuestionId >= OPTION_DEL_DB_QUESTION_ID) &&
+ (QuestionId < (OPTION_DEL_DB_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = FALSE;
+ DeleteSignature (
+ PrivateData,
+ EFI_IMAGE_SECURITY_DATABASE,
+ &gEfiImageSecurityDatabaseGuid,
+ LABEL_DB_DELETE,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_FROM_DB,
+ OPTION_DEL_DB_QUESTION_ID,
+ QuestionId - OPTION_DEL_DB_QUESTION_ID
+ );
+ // Refresh DB entries in the DB option form
+ LoadSignatureList (
+ PrivateData,
+ LABEL_DB_CERTS_DATA_START,
+ FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM,
+ OPTION_DB_LIST_QUESTION_ID
+ );
+ PrivateData->FormData.ListCount = PrivateData->ListCount;
+ Status = EFI_SUCCESS;
+ } else if ((QuestionId >= OPTION_SIGNATURE_LIST_QUESTION_ID) &&
+ (QuestionId < (OPTION_SIGNATURE_LIST_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = FALSE;
+ LoadSignatureData (
+ PrivateData,
+ LABEL_SIGNATURE_DATA_START,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM,
+ OPTION_SIGNATURE_DATA_QUESTION_ID,
+ QuestionId - OPTION_SIGNATURE_LIST_QUESTION_ID
+ );
+ PrivateData->ListIndex = QuestionId - OPTION_SIGNATURE_LIST_QUESTION_ID;
+ Status = EFI_SUCCESS;
+ } else if ((QuestionId >= OPTION_SIGNATURE_DATA_QUESTION_ID) &&
+ (QuestionId < (OPTION_SIGNATURE_DATA_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = FALSE;
+ if (PrivateData->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID]) {
+ PrivateData->FormData.CheckedDataCount--;
+ PrivateData->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID] = FALSE;
+ } else {
+ PrivateData->FormData.CheckedDataCount++;
+ PrivateData->CheckArray[QuestionId - OPTION_SIGNATURE_DATA_QUESTION_ID] = TRUE;
+ }
+ Status = EFI_SUCCESS;
+ } else if ((QuestionId >= OPTION_DB_LIST_QUESTION_ID) &&
+ (QuestionId < (OPTION_DB_LIST_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = TRUE;
+ PrivateData->FormData.BlCertView = FALSE;
+ LoadSignatureData (
+ PrivateData,
+ LABEL_SIGNATURE_DATA_START,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM,
+ OPTION_DB_ENTRIES_QUESTION_ID,
+ QuestionId - OPTION_DB_LIST_QUESTION_ID
+ );
+ PrivateData->ListIndex = QuestionId - OPTION_DB_LIST_QUESTION_ID;
+ Status = EFI_SUCCESS;
+ } else if ((QuestionId >= OPTION_DBX_LIST_QUESTION_ID) &&
+ (QuestionId < (OPTION_DBX_LIST_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = TRUE;
+ PrivateData->FormData.BlCertView = FALSE;
+ LoadSignatureData (
+ PrivateData,
+ LABEL_SIGNATURE_DATA_START,
+ SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM,
+ OPTION_DBX_ENTRIES_QUESTION_ID,
+ QuestionId - OPTION_DBX_LIST_QUESTION_ID
+ );
+ PrivateData->ListIndex = QuestionId - OPTION_DBX_LIST_QUESTION_ID;
+ Status = EFI_SUCCESS;
+ } else if ((QuestionId >= OPTION_DB_ENTRIES_QUESTION_ID) &&
+ (QuestionId < (OPTION_DB_ENTRIES_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = TRUE;
+ PrivateData->FormData.BlCertView = FALSE;
+ LoadSignatureDataStrings (
+ PrivateData,
+ QuestionId - OPTION_DB_ENTRIES_QUESTION_ID,
+ PrivateData->ListIndex
+ );
+ PrivateData->DataIndex = QuestionId - OPTION_DB_ENTRIES_QUESTION_ID;
+ PrivateData->CheckArray[PrivateData->DataIndex] = TRUE;
+ Status = EFI_SUCCESS;
+ } else if ((QuestionId >= OPTION_DBX_ENTRIES_QUESTION_ID) &&
+ (QuestionId < (OPTION_DBX_ENTRIES_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = TRUE;
+ PrivateData->FormData.BlCertView = FALSE;
+ LoadSignatureDataStrings (
+ PrivateData,
+ QuestionId - OPTION_DBX_ENTRIES_QUESTION_ID,
+ PrivateData->ListIndex
+ );
+ PrivateData->DataIndex = QuestionId - OPTION_DBX_ENTRIES_QUESTION_ID;
+ PrivateData->CheckArray[PrivateData->DataIndex] = TRUE;
+ Status = EFI_SUCCESS;
+ } else if ((QuestionId >= OPTION_BL_QUESTION_ID) &&
+ (QuestionId < (OPTION_BL_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = TRUE;
+ PrivateData->FormData.BlCertView = TRUE;
+ mBootloaderIndex = QuestionId - OPTION_BL_QUESTION_ID;
+ Status = UpdateBootloaderPage (PrivateData);
+ if (!EFI_ERROR (Status)) {
+ Status = LoadBootloaderCertificates (PrivateData);
+ } else {
+ DEBUG ((DEBUG_ERROR, "Failed to update bootloader page: %r", Status));
+ }
+ } else if ((QuestionId >= OPTION_BL_CERT_QUESTION_ID) &&
+ (QuestionId < (OPTION_BL_CERT_QUESTION_ID + OPTION_CONFIG_RANGE)))
+ {
+ mAltAccessMode = TRUE;
+ PrivateData->FormData.BlCertView = TRUE;
+ mCertIndex = QuestionId - OPTION_BL_CERT_QUESTION_ID;
+ Status = UpdateCertDetails (PrivateData);
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+ break;
+ }
+
+ break;
+ case EFI_BROWSER_ACTION_CHANGED:
+ {
+ switch (QuestionId) {
+ case KEY_EXIT_FORM1:
+ case KEY_EXIT_FORM2:
+ case KEY_EXIT_FORM3:
+ case KEY_EXIT_FORM5:
+ if (PrivateData->ConfigData.AppLaunchCause == SV_BOOT_LAUNCH_VIA_SETUP) {
+ Scope = FormSetLevel;
+ } else {
+ Scope = SystemLevel;
+ }
+ PrivateData->FormBrowserEx2->SetScope (Scope);
+ Status = PrivateData->FormBrowserEx2->ExecuteAction(BROWSER_ACTION_EXIT, 0);
+
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
+ break;
default:
break;
}
@@ -711,30 +1391,67 @@ Callback (
case EFI_BROWSER_ACTION_FORM_OPEN:
{
switch (QuestionId) {
- case DO_NOT_TRUST_KEY_FORM2_QUESTION_ID:
+ case KEY_DO_NOT_TRUST_KEY_FORM2:
// When the trust form opens during image authentication failure
// the PrepareBootloaders is not called, because Sovereign Boot
// welcome form is skipped and SV Boto option never selected.
PrepareBootloaders (PrivateData);
Status = EFI_SUCCESS;
break;
+ case KEY_SOVEREIGN_BOOT_DB_OPTION:
+ case KEY_SOVEREIGN_BOOT_DBX_OPTION:
+ CloseEnrolledFile (PrivateData->FileContext);
+ Status = EFI_SUCCESS;
+ break;
default:
+ Status = EFI_UNSUPPORTED;
break;
}
break;
}
+ case EFI_BROWSER_ACTION_FORM_CLOSE:
+ {
+ switch (QuestionId) {
+ case KEY_SOVEREIGN_BOOT_DELETE_ALL_DATA:
+ //
+ // Free memory when exit from the SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM form.
+ //
+ if (!mAltAccessMode) {
+ FREE_NON_NULL (PrivateData->CheckArray);
+ PrivateData->FormData.CheckedDataCount = 0;
+ }
+ Status = EFI_SUCCESS;
+ break;
+ case KEY_REMOVE_HASH_FROM_DATABASE:
+ case KEY_REMOVE_KEY_FROM_DATABASE:
+ case KEY_REMOVE_CERT_FROM_DATABASE:
+ FREE_NON_NULL (PrivateData->CheckArray);
+ PrivateData->FormData.CheckedDataCount = 0;
+ Status = EFI_SUCCESS;
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+ }
default:
Status = EFI_UNSUPPORTED;
break;
}
- HiiSetBrowserData (
- &gSovereignBootWizardFormSetGuid,
- mVarStoreName,
- sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
- (CONST UINT8 *)&PrivateData->FormData,
- NULL);
+ if (!EFI_ERROR (Status) && GetBrowserDataResult) {
+ HiiSetBrowserData (
+ &gSovereignBootWizardFormSetGuid,
+ mVarStoreName,
+ sizeof (SOVEREIGN_BOOT_WIZARD_FORM_DATA),
+ (UINT8 *)&PrivateData->FormData,
+ NULL);
+ }
+
+EXIT:
+
+ FREE_NON_NULL (File);
return Status;
}
@@ -916,6 +1633,12 @@ SovereignBootWizardInit (
mPrivateData->HiiHandle = HiiHandle;
+ Status = InstallInteractiveModeForm (mPrivateData);
+ if (EFI_ERROR (Status)) {
+ SovereignBootWizardUnload (ImageHandle);
+ return Status;
+ }
+
SvConfig = &mPrivateData->NvConfig;
ZeroMem (SvConfig, sizeof (SOVEREIGN_BOOT_WIZARD_NV_CONFIG));
@@ -1102,8 +1825,6 @@ SovereignBootWizardUnload (
IN EFI_HANDLE ImageHandle
)
{
- UINTN Index;
-
ASSERT (mPrivateData != NULL);
if (mPrivateData->HiiHandle != NULL) {
@@ -1122,12 +1843,9 @@ SovereignBootWizardUnload (
mPrivateData->AppHandle = NULL;
}
- for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {
- FREE_NON_NULL (mPrivateData->NameValueName[Index]);
- }
-
// Free all pools from certificate, bootloader contexts and entries
FreeBootMenuEntries ();
+ UninstallInteractiveModeForm (mPrivateData);
FREE_NON_NULL (mPrivateData);
mPrivateData = NULL;
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.h b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.h
index e9d036db1e..0b9f10059d 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.h
+++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.h
@@ -24,6 +24,7 @@ Revision History
#include
#include
+#include
#include
#include
#include
@@ -46,6 +47,7 @@ Revision History
#include
#include
#include
+#include
#include
#include
#include
@@ -75,7 +77,7 @@ typedef struct {
extern CONST UINTN MicrosoftCertificatesArraySize;
extern CONST CERT_PTR MicrosoftCertificates[];
-#define NAME_VALUE_NAME_NUMBER 3
+#define SV_BOOT_VARSTORE_NAME L"SvBootFormData"
#define DEFAULT_CLASS_MANUFACTURING_VALUE 0xFF
#define DEFAULT_CLASS_STANDARD_VALUE 0x0
@@ -96,17 +98,39 @@ extern CONST CERT_PTR MicrosoftCertificates[];
} \
} while(FALSE)
+#define FREE_NON_OPCODE(Handle) \
+ do{ \
+ if ((Handle) != NULL) { \
+ HiiFreeOpCodeHandle((Handle)); \
+ } \
+ } while (FALSE)
+
+#define BUFFER_MAX_SIZE 100
+
+#define WIN_CERT_UEFI_RSA2048_SIZE 256
+#define WIN_CERT_UEFI_RSA3072_SIZE 384
+#define WIN_CERT_UEFI_RSA4096_SIZE 512
+
+typedef enum {
+ Variable_NONE,
+ Variable_DB,
+ Variable_DBX,
+ Variable_MAX
+} CURRENT_VARIABLE_NAME;
+
+typedef struct {
+ EFI_FILE_HANDLE FHandle;
+ UINT16 *FileName;
+ UINT8 FileType;
+} SOVEREIGNBOOT_FILE_CONTEXT;
+
typedef struct {
UINT32 Signature;
EFI_HANDLE AppHandle;
EFI_HII_HANDLE HiiHandle;
- SOVEREIGN_BOOT_WIZARD_CONFIG_DATA ConfigData;
- SOVEREIGN_BOOT_WIZARD_NV_CONFIG NvConfig;
- SOVEREIGN_BOOT_WIZARD_FORM_DATA FormData;
- EFI_STRING_ID NameStringId[NAME_VALUE_NAME_NUMBER];
- EFI_STRING NameValueName[NAME_VALUE_NAME_NUMBER];
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
EFI_HII_STRING_PROTOCOL *HiiString;
@@ -114,16 +138,29 @@ typedef struct {
EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
EFI_HII_POPUP_PROTOCOL *HiiPopup;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
+
EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
- EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+ SOVEREIGN_BOOT_WIZARD_CONFIG_DATA ConfigData;
+ SOVEREIGN_BOOT_WIZARD_NV_CONFIG NvConfig;
+ SOVEREIGN_BOOT_WIZARD_FORM_DATA FormData;
- EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
+ SOVEREIGNBOOT_FILE_CONTEXT *FileContext;
+
+ CURRENT_VARIABLE_NAME VariableName; // The variable name we are processing.
+ UINT32 ListCount; // Record current variable has how many signature list.
+ UINTN ListIndex; // Record which signature list is processing.
+ UINT32 DataCount; // Record current list has how many signature data.
+ UINTN DataIndex; // Record which signature data is processing.
+ BOOLEAN *CheckArray; // Record which signature data checked.
} SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA;
#define SOVEREIGN_BOOT_WIZARD_PRIVATE_FROM_THIS(a) CR (a, SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA, ConfigAccess, SOVEREIGN_BOOT_PRIVATE_SIGNATURE)
+extern SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *gPrivateData;
+
#pragma pack(1)
typedef struct {
@@ -224,6 +261,7 @@ typedef struct {
BOOLEAN CertIsValid;
BOOLEAN CertIsMicrosoft;
BOOLEAN CertIsCA;
+ BOOLEAN CertIsForbidden;
UINT8 CertDigest[MAX_DIGEST_SIZE];
UINTN CertDigestSize;
@@ -237,8 +275,12 @@ typedef struct {
} SV_CERT_ENTRY;
typedef struct {
- UINT8 ImageDigest[MAX_DIGEST_SIZE];
+ UINT8 ImageDigest[SHA256_DIGEST_SIZE];
UINTN ImageDigestSize;
+ UINT8 ImageSha384Digest[SHA384_DIGEST_SIZE];
+ UINTN ImageSha384DigestSize;
+ UINT8 ImageSha512Digest[SHA512_DIGEST_SIZE];
+ UINTN ImageSha512DigestSize;
BOOLEAN ImageIsInDbx;
BOOLEAN ImageIsInDb;
@@ -253,10 +295,11 @@ typedef struct {
LIST_ENTRY Certs;
} SV_SECURITY_CONTEXT;
-extern SV_MENU_OPTION BootOptionMenu;
+extern SV_MENU_OPTION mBootOptionMenu;
extern UINTN mBootloaderIndex;
extern UINTN mCertIndex;
extern INTN mFirstTrustedBootloader;
+extern BOOLEAN mAltAccessMode;
EFI_STATUS
GetBootOptions (
@@ -293,6 +336,13 @@ GetMenuEntry (
UINTN MenuNumber
);
+EFI_STATUS
+ParseHashValue (
+ IN UINT8 *Digest,
+ IN UINTN DigestSize,
+ OUT CHAR16 **BufferToReturn
+ );
+
VOID
FreeBootMenuEntry (
SV_MENU_ENTRY *BootloaderEntry
@@ -325,6 +375,19 @@ UpdateCertDetails (
IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private
);
+VOID
+FillCertStrings (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN SV_CERT_ENTRY *CertificateEntry
+ );
+
+VOID
+FillKeyHashStrings (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *Private,
+ IN EFI_SIGNATURE_LIST *List,
+ IN EFI_SIGNATURE_DATA *Data
+ );
+
EFI_STATUS
RestoreSecureBootDefaults (
VOID
@@ -337,8 +400,9 @@ PrepareSbVariablesForSvBoot (
EFI_STATUS
AddKeyOrHashAsTrustedOrUntrusted (
- SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
- BOOLEAN Trust
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData,
+ IN BOOLEAN Trust,
+ IN BOOLEAN EnrollImageHash
);
EFI_STATUS
@@ -346,6 +410,12 @@ FinalizeSvBootProvisioning (
VOID
);
+CHAR16 *
+UiDevicePathToStr (
+ IN EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ );
+
BOOLEAN
Asn1TimeToEfiTime (
IN OPENSSL_ASN1_TIME *Asn1Time,
@@ -379,4 +449,9 @@ FreeSecurityContext (
SV_SECURITY_CONTEXT *SecCtx
);
+VOID
+RefreshImageSecurityInfo (
+ IN SOVEREIGN_BOOT_WIZARD_PRIVATE_DATA *PrivateData
+ );
+
#endif
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf
index da617ce5a2..eba4c8e6fa 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf
+++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf
@@ -29,6 +29,7 @@
Asn1Time.c
BootOptionParsing.c
BootOptionScanning.c
+ InteractiveModeImpl.c
KeyManagement.c
MicrosoftCerts.c
SignatureParsing.c
@@ -65,15 +66,30 @@
SecureBootVariableLib
SecureBootVariableProvisionLib
DxeImageVerificationLib
+ FileExplorerLib
[Guids]
- gSovereignBootWizardFormSetGuid
gEfiCertRsa2048Guid
+ gEfiCertRsa2048Sha256Guid
+ gEfiCertX509Guid
+ gEfiCertSha1Guid
+ gEfiCertSha224Guid
+ gEfiCertSha256Guid
+ gEfiCertSha384Guid
+ gEfiCertSha512Guid
+ gEfiCertSm3Guid
gEfiCertPkcs7Guid
+ gEfiCertTypeRsa2048Sha256Guid
+ gEfiFileSystemVolumeLabelInfoIdGuid
gEfiCertX509Sha256Guid
+ gEfiCertX509Sha384Guid
+ gEfiCertX509Sha512Guid
+ gEfiCertX509Sm3Guid
+ gSovereignBootWizardFormSetGuid
gEfiImageSecurityDatabaseGuid
gEfiGlobalVariableGuid
gEfiPartTypeSystemPartGuid
+ gEfiIfrTianoGuid
[Protocols]
## PRODUCES # SovereignBootWizardFormSet
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardHii.h b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardHii.h
index be5f426788..68a0e53380 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardHii.h
+++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardHii.h
@@ -24,42 +24,184 @@ Revision History:
#include
#include
-#define SOVEREIGN_BOOT_WIZARD_FORM_DATA_VARSTORE_ID 0x0001
-
-#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
-#define SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID 4
-#define SOVEREIGN_BOOT_WIZARD_INTERACTIVE_MODE_FORM_ID 9
+#define SOVEREIGN_BOOT_WIZARD_FORM_DATA_VARSTORE_ID 0x0001
+
+#define SOVEREIGN_BOOT_WIZARD_WELCOME_FORM_ID 0x1
+#define SOVEREIGN_BOOT_WIZARD_CONFIG_FORM_ID 0x2
+#define SOVEREIGN_BOOT_WIZARD_MS_SECURE_BOOT_FORM_ID 0x3
+#define SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID 0x4
+#define SOVEREIGN_BOOT_WIZARD_INTERACTIVE_MODE_FORM_ID 0x5
+#define FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM 0x6
+#define FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM 0x7
+#define SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB 0x8
+#define SOVEREIGN_BOOT_DELETE_SIGNATURE_FROM_DB 0x9
+#define SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX 0xa
+#define SOVEREIGN_BOOT_DELETE_SIGNATURE_LIST_FORM 0xb
+#define SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM 0xc
+#define SOVEREIGN_BOOT_WIZARD_HASH_DETAILS_FORM_ID 0xd
+#define FORMID_SOVEREIGN_BOOT_BL_OPTION_FORM 0xe
+#define SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID 0xf
// Question IDs
// Each form will reserve 0x100 IDs
-#define SOVEREIGN_BOOT_WIZARD_FORM_QUESTION_ID_BASE 0x1000
+#define SOVEREIGN_BOOT_WIZARD_FORM_QUESTION_ID_BASE 0x1000
+
// Welcome form
#define WELCOME_FORM_QUESTION_ID_BASE 0x1100
#define SELECT_SOVEREIGN_BOOT_QUESTION_ID 0x1101
#define SELECT_DEFAULT_SECURE_BOOT_QUESTION_ID 0x1102
-// Configuration form
-#define CONFIG_FORM_QUESTION_ID_BASE 0x1200
-#define DO_NOT_TRUST_KEY_FORM2_QUESTION_ID 0x1201
-#define TRUST_KEY_AND_BOOT_FORM2_QUESTION_ID 0x1202
-#define TRUST_KEY_FORM2_QUESTION_ID 0x1203
-#define SHOW_KEY_DETAILS_FORM2_QUESTION_ID 0x1204
-#define SKIP_KEY_FORM2_QUESTION_ID 0x1205
-
#define EXIT_FORM_QUESTION_ID_BASE 0x1F00
-#define EXIT_FORM1_QUESTION_ID 0x1F01
-#define EXIT_FORM2_QUESTION_ID 0x1F02
-#define EXIT_FORM3_QUESTION_ID 0x1F03
-#define EXIT_FORM9_QUESTION_ID 0x1F09
-
+#define KEY_EXIT_FORM1 0x1F01
+#define KEY_EXIT_FORM2 0x1F02
+#define KEY_EXIT_FORM3 0x1F03
+#define KEY_EXIT_FORM5 0x1F05
+// Configuration form
+#define CONFIG_FORM_QUESTION_ID_BASE 0x1200
+#define KEY_DO_NOT_TRUST_KEY_FORM2 0x1201
+#define KEY_TRUST_KEY_AND_BOOT_FORM2 0x1202
+#define KEY_TRUST_KEY_FORM2 0x1203
+#define KEY_SHOW_KEY_DETAILS_FORM2 0x1204
+#define KEY_SKIP_KEY_FORM2 0x1205
+
+
+// Interactive form
+
+#define KEY_REMOVE_KEY_FROM_DATABASE 0x1D01
+#define KEY_REMOVE_HASH_FROM_DATABASE 0x1D02
+#define KEY_REMOVE_CERT_FROM_DATABASE 0x1D03
+
+#define KEY_SOVEREIGN_BOOT_DELETE_SIGNATURE_FROM_DB 0x1D04
+#define KEY_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB 0x1D05
+#define KEY_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX 0x1D06
+
+#define SIGNATURE_TYPE_QUESTION_ID 0x1D10
+
+#define KEY_VALUE_SAVE_AND_EXIT_DB 0x1F0A
+#define KEY_VALUE_NO_SAVE_AND_EXIT_DB 0x1F0B
+#define KEY_VALUE_SAVE_AND_EXIT_DBX 0x1F0C
+#define KEY_VALUE_NO_SAVE_AND_EXIT_DBX 0x1F0D
+#define KEY_VALUE_FROM_DBX_TO_LIST_FORM 0x1F0E
+
+#define KEY_SOVEREIGN_BOOT_DB_OPTION 0x1306
+#define KEY_SOVEREIGN_BOOT_DBX_OPTION 0x1307
+#define KEY_SOVEREIGN_BOOT_SIGNATURE_GUID_DB 0x1308
+#define KEY_SOVEREIGN_BOOT_SIGNATURE_GUID_DBX 0x1309
+#define KEY_SOVEREIGN_BOOT_DELETE_ALL_LIST 0x130a
+#define KEY_SOVEREIGN_BOOT_DELETE_ALL_DATA 0x130b
+#define KEY_SOVEREIGN_BOOT_DELETE_CHECK_DATA 0x130c
+#define KEY_ENROLL_SIGNATURE_TO_DB 0x130d
+#define KEY_ENROLL_SIGNATURE_TO_DBX 0x130e
+#define KEY_SOVEREIGN_BOOT_BL_OPTION 0x130f
+#define KEY_REMOVE_CERT_FROM_DB 0x1310
+#define KEY_REMOVE_CERT_FROM_DBX 0x1311
+#define KEY_ADD_CERT_TO_DB 0x1312
+#define KEY_ADD_CERT_TO_DBX 0x1313
+#define KEY_REMOVE_HASH_FROM_DB 0x1314
+#define KEY_REMOVE_HASH_FROM_DBX 0x1315
+#define KEY_ADD_HASH_TO_DB 0x1316
+#define KEY_ADD_HASH_TO_DBX 0x1317
+#define KEY_REMOVE_ALL_IMAGE_DATA 0x1318
+
+#define LABEL_DB_DELETE 0x1400
+#define LABEL_SIGNATURE_LIST_START 0x1410
+#define LABEL_SIGNATURE_DATA_START 0x1420
+#define LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB 0x1430
+#define LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX 0x1440
+#define LABEL_DELETE_ALL_LIST_BUTTON 0x1500
+#define LABEL_DB_CERTS_DATA_START 0x1600
+#define LABEL_DBX_CERTS_DATA_START 0x1700
+#define LABEL_BOOTLOADER_LIST_START 0x1800
+#define LABEL_BOOTLOADER_CERT_LIST_START 0x1900
+#define LABEL_END 0xffff
+
+#define OPTION_CONFIG_RANGE 0x1000
+
+//
+// Question ID 0x2000 ~ 0x2FFF is for bootloaders
+//
+#define OPTION_BL_QUESTION_ID 0x2000
+//
+// Question ID 0x3000 ~ 0x3FFF is for bootloader certificates
+//
+#define OPTION_BL_CERT_QUESTION_ID 0x3000
+//
+// Question ID 0x4000 ~ 0x4FFF is for DB
+//
+#define OPTION_DEL_DB_QUESTION_ID 0x4000
+//
+// Question ID 0x5000 ~ 0x5FFF is for signature list.
+//
+#define OPTION_SIGNATURE_LIST_QUESTION_ID 0x5000
+//
+// Question ID 0x6000 ~ 0x6FFF is for signature data.
+//
+#define OPTION_SIGNATURE_DATA_QUESTION_ID 0x6000
+//
+// Question ID 0x7000 ~ 0x7FFF is for DB list
+//
+#define OPTION_DB_LIST_QUESTION_ID 0x7000
+//
+// Question ID 0x8000 ~ 0x8FFF is for DBX list
+//
+#define OPTION_DBX_LIST_QUESTION_ID 0x8000
+//
+// Question ID 0x7000 ~ 0x7FFF is for DB list entries
+//
+#define OPTION_DB_ENTRIES_QUESTION_ID 0x9000
+//
+// Question ID 0x8000 ~ 0x8FFF is for DBX list entries
+//
+#define OPTION_DBX_ENTRIES_QUESTION_ID 0xA000
+
+#define SIGNATURE_TYPE_RSA2048_SHA256 0
+#define SIGNATURE_TYPE_RSA2048 1
+#define SIGNATURE_TYPE_X509 2
+#define SIGNATURE_TYPE_SHA1 3
+#define SIGNATURE_TYPE_SHA224 4
+#define SIGNATURE_TYPE_SHA256 5
+#define SIGNATURE_TYPE_SHA384 6
+#define SIGNATURE_TYPE_SHA512 7
+#define SIGNATURE_TYPE_SM3 8
+#define SIGNATURE_TYPE_X509_SHA256 9
+#define SIGNATURE_TYPE_X509_SHA384 10
+#define SIGNATURE_TYPE_X509_SHA512 11
+#define SIGNATURE_TYPE_X509_SM3 12
+#define SIGNATURE_TYPE_UNKNOWN 13
+
+#define IMAGE_STATE_UNDECIDED 0
+#define IMAGE_STATE_UNTRUSTED 1
+#define IMAGE_STATE_TRUSTED 2
+
+// Keep the form data packed to workaround the storage size calculation
+// difference in C and IFR for EFI_HII_TIME
#pragma pack(1)
-
// Form Data
typedef struct {
- BOOLEAN ImageUnsigned;
+ UINT8 ImageUnsigned; // If the image is unsigned.
+ BOOLEAN AlwaysRevocation; // If the certificate is always revoked. Revocation time is hidden
+ UINT8 CertificateFormat; // The type of the certificate
+ EFI_HII_DATE RevocationDate; // The revocation date of the certificate
+ EFI_HII_TIME RevocationTime; // The revocation time of the certificate
+ UINT8 FileEnrollType; // File type of signature enroll
+ UINT32 ListCount; // The count of signature list.
+ UINT32 CheckedDataCount; // The count of checked signature data.
+ UINT8 SignatureType; // Type of signature to be displayed
+ BOOLEAN IsCertHash; // If the signature data is certificate hash
+ UINT8 SignatureRemove; // If the signature data should be modified
+ UINT32 BootloaderCount; // The count of bootloaders.
+ UINT8 BlCertView; // Controls data displayed in the certificate details
+ UINT8 SignedByMs; // If current bootloader is signed by MS certs.
+ UINT8 SignedByMsOnly; // If current bootloader is signed by MS certs only.
+ UINT8 ImageHashIsInDb; // If current bootloader hash is present in DB.
+ UINT8 ImageHashIsInDbx; // If current bootloader hash is present in DBX.
+ UINT8 ImageTrusted; // If current bootloader is trusted.
+ UINT8 HasInvalidSignature; // If current bootloader contains invalid signature.
+ UINT8 CertInDb; // If current certificate or its hash is present in DB.
+ UINT8 CertInDbx; // If current certificate or its hash is present in DBX.
+ UINT8 CertIsValid; // If current certificate is valid.
+ UINT8 CertIsMicrosoft; // If current certificate is Microsoft.
} SOVEREIGN_BOOT_WIZARD_FORM_DATA;
#pragma pack()
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfr.vfr b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfr.vfr
index 6a1bba1b7f..424ed1526b 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfr.vfr
+++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfr.vfr
@@ -85,7 +85,7 @@ formset
help = STRING_TOKEN(STR_EMPTY_STRING),
text = STRING_TOKEN(STR_EXIT_TEXT),
flags = INTERACTIVE,
- key = EXIT_FORM1_QUESTION_ID;
+ key = KEY_EXIT_FORM1;
endform;
@@ -95,50 +95,66 @@ 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;
+ 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);
subtitle text = STRING_TOKEN(STR_FILE_PATH);
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
- subtitle text = STRING_TOKEN(STR_KEY_FINGERPRINT);
+ suppressif ideqval SvBootFormData.ImageUnsigned == 0;
+ subtitle text = STRING_TOKEN(STR_BOOTLOADER_HASH);
+ endif;
+ suppressif ideqval SvBootFormData.ImageUnsigned == 1;
+ subtitle text = STRING_TOKEN(STR_KEY_FINGERPRINT);
+ endif;
subtitle text = STRING_TOKEN(STR_KEY_FINGERPRINT_HASH);
+
+ suppressif ideqval SvBootFormData.ImageUnsigned == 0;
+ subtitle text = STRING_TOKEN(STR_IMAGE_UNSIGNED);
+ endif;
+ suppressif ideqval SvBootFormData.SignedByMs == 0;
+ subtitle text = STRING_TOKEN(STR_CERT_BELONGS_TO_MICROSOFT);
+ endif;
+ suppressif ideqval SvBootFormData.HasInvalidSignature == 0;
+ subtitle text = STRING_TOKEN(STR_SIGNATURE_INVALID);
+ endif;
+
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
subtitle text = STRING_TOKEN(STR_TRUST_QUESTION);
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
- text
+ goto SOVEREIGN_BOOT_WIZARD_CONFIG_FORM_ID,
+ prompt = STRING_TOKEN(STR_DO_NOT_TRUST_KEY),
help = STRING_TOKEN(STR_EMPTY_STRING),
- text = STRING_TOKEN(STR_DO_NOT_TRUST_KEY),
flags = INTERACTIVE,
- key = DO_NOT_TRUST_KEY_FORM2_QUESTION_ID;
+ key = KEY_DO_NOT_TRUST_KEY_FORM2;
- text
+ goto SOVEREIGN_BOOT_WIZARD_CONFIG_FORM_ID,
+ prompt = STRING_TOKEN(STR_TRUST_KEY_AND_BOOT),
help = STRING_TOKEN(STR_EMPTY_STRING),
- text = STRING_TOKEN(STR_TRUST_KEY_AND_BOOT),
flags = INTERACTIVE,
- key = TRUST_KEY_AND_BOOT_FORM2_QUESTION_ID;
+ key = KEY_TRUST_KEY_AND_BOOT_FORM2;
disableif ideqval SvBootData.AppLaunchCause == SV_BOOT_LAUNCH_IMAGE_VERIFICATION_FAILED;
- text
+ goto SOVEREIGN_BOOT_WIZARD_CONFIG_FORM_ID,
+ prompt = STRING_TOKEN(STR_TRUST_KEY),
help = STRING_TOKEN(STR_EMPTY_STRING),
- text = STRING_TOKEN(STR_TRUST_KEY),
flags = INTERACTIVE,
- key = TRUST_KEY_FORM2_QUESTION_ID;
+ key = KEY_TRUST_KEY_FORM2;
- text
+ goto SOVEREIGN_BOOT_WIZARD_CONFIG_FORM_ID,
+ prompt = STRING_TOKEN(STR_SKIP_KEY),
help = STRING_TOKEN(STR_EMPTY_STRING),
- text = STRING_TOKEN(STR_SKIP_KEY),
flags = INTERACTIVE,
- key = SKIP_KEY_FORM2_QUESTION_ID;
+ key = KEY_SKIP_KEY_FORM2;
endif;
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
@@ -148,7 +164,7 @@ formset
prompt = STRING_TOKEN(STR_SHOW_KEY_DETAILS),
help = STRING_TOKEN(STR_EMPTY_STRING),
flags = INTERACTIVE,
- key = SHOW_KEY_DETAILS_FORM2_QUESTION_ID;
+ key = KEY_SHOW_KEY_DETAILS_FORM2;
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
endif;
@@ -157,7 +173,7 @@ formset
help = STRING_TOKEN(STR_EMPTY_STRING),
text = STRING_TOKEN(STR_EXIT_TEXT),
flags = INTERACTIVE,
- key = EXIT_FORM2_QUESTION_ID;
+ key = KEY_EXIT_FORM2;
endform;
@@ -171,7 +187,7 @@ formset
form formid = SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID,
- title = STRING_TOKEN(STR_FORM4_TITLE);
+ title = STRING_TOKEN(STR_FORM_CERT_DETAILS_TITLE);
grayoutif TRUE;
text
@@ -213,24 +229,647 @@ formset
text = STRING_TOKEN(STR_CERT_KEY_EXPONENT2);
endif;
+
+ disableif ideqval SvBootFormData.BlCertView == 1;
+ disableif ideqval SvBootFormData.SignatureRemove == 0;
+
+ grayoutif TRUE;
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_KEY_FINGERPRINT);
+
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_KEY_FINGERPRINT_HASH);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ endif;
+
+ // Empty text field so that none of the options are
+ // highlighted/selected by default.
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ // No form ID here, will be updated dynamically
+ goto
+ prompt = STRING_TOKEN(STR_REMOVE_CERT),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_REMOVE_CERT_FROM_DATABASE;
+ endif;
+ endif;
+
+ disableif ideqval SvBootFormData.BlCertView == 0;
+ grayoutif TRUE;
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_KEY_FINGERPRINT);
+
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_KEY_FINGERPRINT_HASH);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ oneof varid = SvBootFormData.CertIsValid,
+ prompt = STRING_TOKEN(STR_CERT_VALID),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+
+ oneof varid = SvBootFormData.CertIsMicrosoft,
+ prompt = STRING_TOKEN(STR_CERT_IS_MICROSOFT),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+
+ oneof varid = SvBootFormData.CertInDb,
+ prompt = STRING_TOKEN(STR_CERT_IN_DB),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = 0;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+
+ oneof varid = SvBootFormData.CertInDbx,
+ prompt = STRING_TOKEN(STR_CERT_IN_DBX),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+ endif;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ // Empty text field so that none of the options are
+ // highlighted/selected by default.
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ suppressif ideqval SvBootFormData.CertInDb == 0;
+ goto SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_REMOVE_CERT_FROM_TRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_REMOVE_CERT_FROM_DB;
+ endif;
+
+ suppressif ideqval SvBootFormData.CertInDbx == 0;
+ goto SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_REMOVE_CERT_FROM_UNTRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_REMOVE_CERT_FROM_DBX;
+ endif;
+
+ suppressif ideqval SvBootFormData.CertInDb == 1;
+ goto SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_ADD_CERT_TO_TRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_ADD_CERT_TO_DB;
+ endif;
+
+ suppressif ideqval SvBootFormData.CertInDbx == 1;
+ goto SOVEREIGN_BOOT_WIZARD_KEY_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_ADD_CERT_TO_UNTRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_ADD_CERT_TO_DBX;
+ endif;
+
+ endif;
+
endform;
+ form formid = SOVEREIGN_BOOT_WIZARD_HASH_DETAILS_FORM_ID,
+ title = STRING_TOKEN(STR_FORM_HASH_DETAILS_TITLE);
+
+ grayoutif TRUE;
+ oneof varid = SvBootFormData.SignatureType,
+ questionid = SIGNATURE_TYPE_QUESTION_ID,
+ prompt = STRING_TOKEN(STR_SIGNATURE_TYPE),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+
+ option text = STRING_TOKEN(STR_LIST_TYPE_RSA2048_SHA256), value = SIGNATURE_TYPE_RSA2048_SHA256, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_RSA2048), value = SIGNATURE_TYPE_RSA2048, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_X509), value = SIGNATURE_TYPE_X509, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_SHA1), value = SIGNATURE_TYPE_SHA1, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_SHA224), value = SIGNATURE_TYPE_SHA224, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_SHA256), value = SIGNATURE_TYPE_SHA256, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_SHA384), value = SIGNATURE_TYPE_SHA384, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_SHA512), value = SIGNATURE_TYPE_SHA512, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_SM3), value = SIGNATURE_TYPE_SM3, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_X509_SHA256), value = SIGNATURE_TYPE_X509_SHA256, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_X509_SHA384), value = SIGNATURE_TYPE_X509_SHA384, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_X509_SHA512), value = SIGNATURE_TYPE_X509_SHA512, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_X509_SM3), value = SIGNATURE_TYPE_X509_SM3, flags = 0;
+ option text = STRING_TOKEN(STR_LIST_TYPE_UNKNOWN), value = SIGNATURE_TYPE_UNKNOWN, flags = 0;
+ endoneof;
+ endif;
+
+ suppressif ideqval SvBootFormData.SignatureType == SIGNATURE_TYPE_RSA2048;
+ grayoutif TRUE;
+ suppressif ideqval SvBootFormData.IsCertHash == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_SIGNATURE_DATA_REVOCATION_TIME),
+ text = STRING_TOKEN(STR_SIGNATURE_DATA_REVOCATION_TIME2);
+ endif;
+
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_SIGNATURE_DATA_RAW);
+
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_SIGNATURE_DATA_RAW_HEX);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ endif;
+
+ // Empty text field so that none of the options are
+ // highlighted/selected by default.
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ // No form ID here, will be updated dynamically
+ goto
+ prompt = STRING_TOKEN(STR_REMOVE_HASH),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_REMOVE_HASH_FROM_DATABASE;
+
+ endif;
+
+ suppressif NOT ideqval SvBootFormData.SignatureType == SIGNATURE_TYPE_RSA2048;
+
+ grayoutif TRUE;
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_CERT_KEY_MODULUS);
+
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_CERT_KEY_MODULUS_HEX);
+
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_CERT_KEY_EXPONENT),
+ text = STRING_TOKEN(STR_CERT_KEY_EXPONENT2);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ endif;
+
+ // Empty text field so that none of the options are
+ // highlighted/selected by default.
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto
+ prompt = STRING_TOKEN(STR_REMOVE_KEY),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_REMOVE_KEY_FROM_DATABASE;
+
+ endif;
+
+ endform;
//
- // Advanced mode window
+ // Interactive mode window
//
form formid = SOVEREIGN_BOOT_WIZARD_INTERACTIVE_MODE_FORM_ID,
- title = STRING_TOKEN(STR_FORM9_TITLE);
+ title = STRING_TOKEN(STR_FORM5_TITLE);
subtitle text = STRING_TOKEN(STR_INTERACTIVE_MODE_SUBTITLE);
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
subtitle text = STRING_TOKEN(STR_LAUNCH_REASON);
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto FORMID_SOVEREIGN_BOOT_BL_OPTION_FORM,
+ prompt = STRING_TOKEN(STR_SOVEREIGN_BOOT_BL_OPTION),
+ help = STRING_TOKEN(STR_SOVEREIGN_BOOT_BL_OPTION_HELP),
+ flags = INTERACTIVE,
+ key = KEY_SOVEREIGN_BOOT_BL_OPTION;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM,
+ prompt = STRING_TOKEN(STR_SOVEREIGN_BOOT_DB_OPTION),
+ help = STRING_TOKEN(STR_SOVEREIGN_BOOT_DB_OPTION_HELP),
+ flags = INTERACTIVE,
+ key = KEY_SOVEREIGN_BOOT_DB_OPTION;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM,
+ prompt = STRING_TOKEN(STR_SOVEREIGN_BOOT_DBX_OPTION),
+ help = STRING_TOKEN(STR_SOVEREIGN_BOOT_DBX_OPTION_HELP),
+ flags = INTERACTIVE,
+ key = KEY_SOVEREIGN_BOOT_DBX_OPTION;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
text
help = STRING_TOKEN(STR_EMPTY_STRING),
text = STRING_TOKEN(STR_EXIT_TEXT),
flags = INTERACTIVE,
- key = EXIT_FORM9_QUESTION_ID;
+ key = KEY_EXIT_FORM5;
+
+ endform;
+
+ form formid = FORMID_SOVEREIGN_BOOT_BL_OPTION_FORM,
+ title = STRING_TOKEN(STR_BOOTLOADER_LIST_FORM);
+
+ disableif NOT ideqval SvBootFormData.BootloaderCount == 0;
+ grayoutif TRUE;
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_NO_BOOTLOADERS_FOUND);
+ endif;
+ endif;
+
+ label LABEL_BOOTLOADER_LIST_START;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ endform;
+
+ form formid = SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID,
+ title = STRING_TOKEN(STR_BOOTLOADER_DETAILS_FORM);
+
+ subtitle text = STRING_TOKEN(STR_BOOTOPT_DESCRIPTION);
+ subtitle text = STRING_TOKEN(STR_HW_PATH);
+ subtitle text = STRING_TOKEN(STR_FILE_PATH);
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ subtitle text = STRING_TOKEN(STR_BOOTLOADER_HASH);
+ subtitle text = STRING_TOKEN(STR_BOOTLOADER_HASH_HEX);
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ grayoutif TRUE;
+ oneof varid = SvBootFormData.ImageUnsigned,
+ prompt = STRING_TOKEN(STR_IMAGE_IS_SIGNED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_YES), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_NO), value = 0x1, flags = 0;
+ endoneof;
+
+ suppressif ideqval SvBootFormData.ImageUnsigned == 1;
+ oneof varid = SvBootFormData.HasInvalidSignature,
+ prompt = STRING_TOKEN(STR_IMAGE_CONTAINS_INVALID_SIGNATURE),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+
+ oneof varid = SvBootFormData.SignedByMs,
+ prompt = STRING_TOKEN(STR_IMAGE_IS_SIGNED_BY_MS),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+
+ oneof varid = SvBootFormData.SignedByMsOnly,
+ prompt = STRING_TOKEN(STR_IMAGE_IS_SIGNED_BY_MS_ONLY),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+ endif;
+
+ oneof varid = SvBootFormData.ImageHashIsInDb,
+ prompt = STRING_TOKEN(STR_IMAGE_HASH_IN_DB),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+
+ oneof varid = SvBootFormData.ImageHashIsInDbx,
+ prompt = STRING_TOKEN(STR_IMAGE_HASH_IN_DBX),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_NO), value = 0x0, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_YES), value = 0x1, flags = 0;
+ endoneof;
+
+ oneof varid = SvBootFormData.ImageTrusted,
+ prompt = STRING_TOKEN(STR_IMAGE_IS_TRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ option text = STRING_TOKEN(STR_UNDECIDED), value = IMAGE_STATE_UNDECIDED, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_NO), value = IMAGE_STATE_UNTRUSTED, flags = 0;
+ option text = STRING_TOKEN(STR_YES), value = IMAGE_STATE_TRUSTED, flags = 0;
+ endoneof;
+ endif;
+
+ // Empty text field so that none of the options are
+ // highlighted/selected by default.
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ suppressif ideqval SvBootFormData.ImageHashIsInDb == 0;
+ goto SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_REMOVE_HASH_FROM_TRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_REMOVE_HASH_FROM_DB;
+ endif;
+
+ suppressif ideqval SvBootFormData.ImageHashIsInDbx == 0;
+ goto SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_REMOVE_HASH_FROM_UNTRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_REMOVE_HASH_FROM_DBX;
+ endif;
+
+ suppressif ideqval SvBootFormData.ImageHashIsInDb == 1;
+ goto SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_ADD_HASH_TO_TRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_ADD_HASH_TO_DB;
+ endif;
+
+ suppressif ideqval SvBootFormData.ImageHashIsInDbx == 1;
+ goto SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_ADD_HASH_TO_UNTRUSTED),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_ADD_HASH_TO_DBX;
+ endif;
+
+ goto SOVEREIGN_BOOT_WIZARD_BL_DETAILS_FORM_ID,
+ prompt = STRING_TOKEN(STR_REMOVE_ALL_IMAGE_DATA),
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ flags = INTERACTIVE,
+ key = KEY_REMOVE_ALL_IMAGE_DATA;
+
+ disableif ideqval SvBootFormData.ImageUnsigned == 1;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ subtitle text = STRING_TOKEN(STR_BL_CERTIFICATE_LSIT);
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ endif;
+
+ label LABEL_BOOTLOADER_CERT_LIST_START;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ endform;
+
+ form formid = FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM,
+ title = STRING_TOKEN(STR_SOVEREIGN_BOOT_DB_OPTION);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB,
+ prompt = STRING_TOKEN (STR_SOVEREIGN_BOOT_ENROLL_SIGNATURE),
+ help = STRING_TOKEN (STR_SOVEREIGN_BOOT_ENROLL_SIGNATURE),
+ flags = INTERACTIVE,
+ key = KEY_ENROLL_SIGNATURE_TO_DB;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto SOVEREIGN_BOOT_DELETE_SIGNATURE_FROM_DB,
+ prompt = STRING_TOKEN (STR_SOVEREIGN_BOOT_DELETE_SIGNATURE),
+ help = STRING_TOKEN (STR_SOVEREIGN_BOOT_DELETE_SIGNATURE),
+ flags = INTERACTIVE,
+ key = KEY_SOVEREIGN_BOOT_DELETE_SIGNATURE_FROM_DB;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ subtitle text = STRING_TOKEN(STR_SV_BOOT_DB_INFO);
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ label LABEL_DB_CERTS_DATA_START;
+ // goto opcodes will be generated dynamically for each cert
+ // enrolled in DB to point to key details form
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ disableif NOT ideqval SvBootFormData.ListCount == 0;
+ grayoutif TRUE;
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_DATABASE_EMPTY);
+ endif;
+ endif;
+
+ endform;
+
+ form formid = FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM,
+ title = STRING_TOKEN(STR_SOVEREIGN_BOOT_DBX_OPTION);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX,
+ prompt = STRING_TOKEN (STR_SOVEREIGN_BOOT_ENROLL_SIGNATURE),
+ help = STRING_TOKEN (STR_SOVEREIGN_BOOT_ENROLL_SIGNATURE),
+ flags = INTERACTIVE,
+ key = KEY_ENROLL_SIGNATURE_TO_DBX;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto SOVEREIGN_BOOT_DELETE_SIGNATURE_LIST_FORM,
+ prompt = STRING_TOKEN (STR_SOVEREIGN_BOOT_DELETE_SIGNATURE),
+ help = STRING_TOKEN (STR_SOVEREIGN_BOOT_DELETE_SIGNATURE),
+ flags = INTERACTIVE,
+ key = KEY_VALUE_FROM_DBX_TO_LIST_FORM;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ subtitle text = STRING_TOKEN(STR_SV_BOOT_DBX_INFO);
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ label LABEL_DBX_CERTS_DATA_START;
+ // goto opcodes will be generated dynamically for each cert
+ // enrolled in DBX to point to key details form
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ disableif NOT ideqval SvBootFormData.ListCount == 0;
+ grayoutif TRUE;
+ text
+ help = STRING_TOKEN(STR_EMPTY_STRING),
+ text = STRING_TOKEN(STR_DATABASE_EMPTY);
+ endif;
+ endif;
+
+ endform;
+
+ form formid = SOVEREIGN_BOOT_DELETE_SIGNATURE_FROM_DB,
+ title = STRING_TOKEN(STR_SOVEREIGN_BOOT_DELETE_SIGNATURE);
+
+ label LABEL_DB_DELETE;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ endform;
+
+ form formid = SOVEREIGN_BOOT_DELETE_SIGNATURE_LIST_FORM,
+ title = STRING_TOKEN(STR_SOVEREIGN_BOOT_DELETE_LIST_FORM);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ disableif ideqval SvBootFormData.SignatureRemove == 1;
+ grayoutif ideqval SvBootFormData.ListCount == 0;
+ label LABEL_DELETE_ALL_LIST_BUTTON;
+ label LABEL_END;
+ endif;
+ endif;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ label LABEL_SIGNATURE_LIST_START;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ endform;
+
+ form formid = SOVEREIGN_BOOT_DELETE_SIGNATURE_DATA_FORM,
+ title = STRING_TOKEN(STR_SOVEREIGN_BOOT_DELETE_DATA_FORM);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto
+ prompt = STRING_TOKEN(STR_SOVEREIGN_BOOT_DELETE_ALL_DATA),
+ help = STRING_TOKEN(STR_SOVEREIGN_BOOT_DELETE_ALL_DATA_HELP),
+ flags = INTERACTIVE,
+ key = KEY_SOVEREIGN_BOOT_DELETE_ALL_DATA;
+
+ disableif ideqval SvBootFormData.SignatureRemove == 1;
+ grayoutif ideqval SvBootFormData.CheckedDataCount == 0;
+ goto SOVEREIGN_BOOT_DELETE_SIGNATURE_LIST_FORM,
+ prompt = STRING_TOKEN(STR_SOVEREIGN_BOOT_DELETE_CHECK_DATA),
+ help = STRING_TOKEN(STR_SOVEREIGN_BOOT_DELETE_CHECK_DATA_HELP),
+ flags = INTERACTIVE,
+ key = KEY_SOVEREIGN_BOOT_DELETE_CHECK_DATA;
+ endif;
+ endif;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ label LABEL_SIGNATURE_DATA_START;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ endform;
+
+ form formid = SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB,
+ title = STRING_TOKEN(STR_SOVEREIGN_BOOT_ENROLL_SIGNATURE);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB,
+ prompt = STRING_TOKEN(STR_SOVEREIGN_BOOT_ADD_SIGNATURE_FILE),
+ help = STRING_TOKEN(STR_SOVEREIGN_BOOT_ADD_SIGNATURE_FILE),
+ flags = INTERACTIVE,
+ key = KEY_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ label LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DB;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM,
+ prompt = STRING_TOKEN(STR_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_SAVE_AND_EXIT),
+ flags = INTERACTIVE | RESET_REQUIRED,
+ key = KEY_VALUE_SAVE_AND_EXIT_DB;
+
+ goto FORMID_SOVEREIGN_BOOT_DB_OPTION_FORM,
+ prompt = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
+ flags = INTERACTIVE,
+ key = KEY_VALUE_NO_SAVE_AND_EXIT_DB;
+
+ endform;
+
+ form formid = SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX,
+ title = STRING_TOKEN(STR_SOVEREIGN_BOOT_ENROLL_SIGNATURE);
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX,
+ prompt = STRING_TOKEN(STR_SOVEREIGN_BOOT_ADD_SIGNATURE_FILE),
+ help = STRING_TOKEN(STR_SOVEREIGN_BOOT_ADD_SIGNATURE_FILE),
+ flags = INTERACTIVE,
+ key = KEY_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX;
+
+ label LABEL_SOVEREIGN_BOOT_ENROLL_SIGNATURE_TO_DBX;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ disableif NOT ideqval SvBootFormData.FileEnrollType == 1;
+ oneof name = X509SignatureFormatInDbx,
+ varid = SvBootFormData.CertificateFormat,
+ prompt = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_PROMPT),
+ help = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_HELP),
+ disableif TRUE; // Make it depend on DISABLE_SHA1_DEPRECATED_INTERFACES?
+ option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_SHA1), value = 0x0, flags = 0;
+ endif;
+ suppressif TRUE; // SHA224 not implemented
+ option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_SHA224), value = 0x1, flags = 0;
+ endif;
+ option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_SHA256), value = 0x2, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_SHA384), value = 0x3, flags = 0;
+ option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_SHA512), value = 0x4, flags = 0;
+ option text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_RAW), value = 0x6, flags = 0;
+ endoneof;
+ endif;
+
+ disableif NOT ideqval SvBootFormData.FileEnrollType == 2;
+ text
+ help = STRING_TOKEN(STR_DBX_PE_IMAGE_FORMAT_HELP), // Help string
+ text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_PROMPT), // Prompt string
+ text = STRING_TOKEN(STR_DBX_PE_FORMAT_SHA256); // PE image type
+ endif;
+
+ disableif NOT ideqval SvBootFormData.FileEnrollType == 3;
+ text
+ help = STRING_TOKEN(STR_DBX_AUTH_2_FORMAT_HELP), // Help string
+ text = STRING_TOKEN(STR_DBX_CERTIFICATE_FORMAT_PROMPT), // Prompt string
+ text = STRING_TOKEN(STR_DBX_AUTH_2_FORMAT); // AUTH_2 image type
+ endif;
+
+ suppressif ideqval SvBootFormData.CertificateFormat == 4;
+ checkbox varid = SvBootFormData.AlwaysRevocation,
+ prompt = STRING_TOKEN(STR_ALWAYS_CERTIFICATE_REVOCATION_PROMPT),
+ help = STRING_TOKEN(STR_ALWAYS_CERTIFICATE_REVOCATION_HELP),
+ flags = INTERACTIVE,
+ endcheckbox;
+
+ suppressif ideqval SvBootFormData.AlwaysRevocation == 1;
+ date varid = SvBootFormData.RevocationDate,
+ prompt = STRING_TOKEN(STR_CERTIFICATE_REVOCATION_DATE_PROMPT),
+ help = STRING_TOKEN(STR_CERTIFICATE_REVOCATION_DATE_HELP),
+ flags = STORAGE_NORMAL,
+ enddate;
+
+ time varid = SvBootFormData.RevocationTime,
+ prompt = STRING_TOKEN(STR_CERTIFICATE_REVOCATION_TIME_PROMPT),
+ help = STRING_TOKEN(STR_CERTIFICATE_REVOCATION_TIME_HELP),
+ flags = STORAGE_NORMAL,
+ endtime;
+ endif;
+ endif;
+
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+ subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+
+ goto FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM,
+ prompt = STRING_TOKEN(STR_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_SAVE_AND_EXIT),
+ flags = INTERACTIVE | RESET_REQUIRED,
+ key = KEY_VALUE_SAVE_AND_EXIT_DBX;
+
+ goto FORMID_SOVEREIGN_BOOT_DBX_OPTION_FORM,
+ prompt = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
+ flags = INTERACTIVE,
+ key = KEY_VALUE_NO_SAVE_AND_EXIT_DBX;
endform;
diff --git a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfrStrings.uni b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfrStrings.uni
index 15d3546355..5a8453adc7 100644
--- a/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfrStrings.uni
+++ b/DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizardVfrStrings.uni
@@ -15,88 +15,255 @@
//
// --*/
-
-/=#
-
#langdef en-US "English"
-#string STR_FORM_SET_TITLE #language en-US "Sovereign Boot Provisioning Wizard"
-#string STR_FORM_SET_TITLE_HELP #language en-US " "
-#string STR_EMPTY_STRING #language en-US " "
-#string STR_EXIT_TEXT #language en-US "[ Exit ]"
+#string STR_FORM_SET_TITLE #language en-US "Sovereign Boot Provisioning Wizard"
+#string STR_FORM_SET_TITLE_HELP #language en-US " "
+#string STR_EMPTY_STRING #language en-US " "
+#string STR_EXIT_TEXT #language en-US "[ Exit ]"
-#string FUNCTION_NINE_STRING #language en-US "F9=Reset to Defaults"
-#string FUNCTION_TEN_STRING #language en-US "F10=Save"
+#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"
+#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"
-#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 ""
-#string STR_SOVEREIGN_BOOT_FEATURES #language en-US "* You decide which keys to trust\n"
- "* No keys are initially trusted by default\n"
- "* Requires a Sovereign Boot compatible operating system"
-#string STR_SELECT_DEFAULT_SECURE_BOOT #language en-US "Standard Secure Boot with Microsoft certificates"
-#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"
- "* Enrolls firmware's default Secure Boot keys"
+#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"
+#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 ""
+#string STR_SOVEREIGN_BOOT_FEATURES #language en-US "* You decide which keys to trust\n"
+ "* No keys are initially trusted by default\n"
+ "* Requires a Sovereign Boot compatible operating system"
+#string STR_SELECT_DEFAULT_SECURE_BOOT #language en-US "Standard Secure Boot with Microsoft certificates"
+#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"
+ "* Enrolls firmware's default Secure Boot keys"
// Configuration page strings
-#string STR_FORM2_TITLE #language en-US "Sovereign Boot Provisioning Wizard"
+#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: "
-#string STR_FILE_PATH #language en-US "File path: "
-#string STR_KEY_FINGERPRINT #language en-US "Certificate fingerprint (SHA-256):"
-#string STR_KEY_FINGERPRINT_HASH #language en-US ""
+#string STR_BOOTOPT_DESCRIPTION #language en-US "Description: "
+#string STR_HW_PATH #language en-US "Hardware path: "
+#string STR_FILE_PATH #language en-US "File path: "
+#string STR_KEY_FINGERPRINT #language en-US "Certificate fingerprint (SHA-256):"
+#string STR_KEY_FINGERPRINT_HASH #language en-US ""
+#string STR_BOOTLOADER_HASH #language en-US "Image hash (SHA-256):"
-#string STR_TRUST_QUESTION #language en-US "Do you want to trust this key/image and continue booting?"
-#string STR_SV_TRUST_KEY_POPUP #language en-US ""
-#string STR_SV_TRUST_KEY_QUESTION #language en-US "Are you sure you want to trust the following"
-#string STR_SV_UNTRUST_KEY_QUESTION #language en-US "Are you sure you do NOT want to trust the following"
+#string STR_IMAGE_UNSIGNED #language en-US "!!! Image is unsigned !!!"
+#string STR_SIGNATURE_INVALID #language en-US "!!! Signature or certificate is invalid !!!"
+#string STR_CERT_BELONGS_TO_MICROSOFT #language en-US "!!! Certificate belongs to Microsoft !!!"
-#string STR_DO_NOT_TRUST_KEY #language en-US "[ Do NOT trust, next 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_SKIP_KEY #language en-US "[ Skip this key/image, next key/bootloader ]"
-#string STR_SHOW_KEY_DETAILS #language en-US "Show key/certificate details"
+#string STR_TRUST_QUESTION #language en-US "Do you want to trust this key/image and continue booting?"
+#string STR_SV_TRUST_KEY_POPUP #language en-US ""
+#string STR_SV_TRUST_KEY_QUESTION #language en-US "Are you sure you want to trust the following"
+#string STR_SV_UNTRUST_KEY_QUESTION #language en-US "Are you sure you do NOT want to trust the following"
+
+#string STR_DO_NOT_TRUST_KEY #language en-US "Do NOT trust, next 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_SKIP_KEY #language en-US "Skip this key/image, next key/bootloader"
+#string STR_SHOW_KEY_DETAILS #language en-US "Show key/certificate details"
// Configuration page strings
-#string STR_FORM4_TITLE #language en-US "Certificate Details"
+#string STR_FORM_CERT_DETAILS_TITLE #language en-US "Certificate Details"
-#string STR_VALIDITY_BEFORE #language en-US "Valid Not Before:"
-#string STR_VALIDITY_AFTER #language en-US "Valid Not After:"
-#string STR_VALIDITY_BEFORE_DATE #language en-US ""
-#string STR_VALIDITY_AFTER_DATE #language en-US ""
+#string STR_VALIDITY_BEFORE #language en-US "Valid Not Before:"
+#string STR_VALIDITY_AFTER #language en-US "Valid Not After:"
+#string STR_VALIDITY_BEFORE_DATE #language en-US ""
+#string STR_VALIDITY_AFTER_DATE #language en-US ""
-#string STR_CERT_ISSUER #language en-US "Issuer Common Name (CN):"
-#string STR_CERT_ISSUER2 #language en-US ""
-#string STR_CERT_SUBJECT #language en-US "Subject Common Name (CN):"
-#string STR_CERT_SUBJECT2 #language en-US ""
+#string STR_CERT_ISSUER #language en-US "Issuer Common Name (CN):"
+#string STR_CERT_ISSUER2 #language en-US ""
+#string STR_CERT_SUBJECT #language en-US "Subject Common Name (CN):"
+#string STR_CERT_SUBJECT2 #language en-US ""
-#string STR_CERT_SERIAL_NUMBER #language en-US "Serial Number (HEX):"
-#string STR_CERT_SERIAL_NUMBER2 #language en-US ""
+#string STR_CERT_SERIAL_NUMBER #language en-US "Serial Number (HEX):"
+#string STR_CERT_SERIAL_NUMBER2 #language en-US ""
-#string STR_CERT_KEY_MODULUS #language en-US "Key Modulus:"
-#string STR_CERT_KEY_MODULUS_HEX #language en-US ""
-#string STR_CERT_KEY_EXPONENT #language en-US "Key Exponent:"
-#string STR_CERT_KEY_EXPONENT2 #language en-US ""
+#string STR_CERT_KEY_MODULUS #language en-US "Key Modulus:"
+#string STR_CERT_KEY_MODULUS_HEX #language en-US ""
+#string STR_CERT_KEY_EXPONENT #language en-US "Key Exponent:"
+#string STR_CERT_KEY_EXPONENT2 #language en-US ""
// Interactive mode strings
-#string STR_FORM9_TITLE #language en-US "Sovereign Boot Provisioning Wizard"
-#string STR_INTERACTIVE_MODE_SUBTITLE #language en-US "Sovereign Boot is already provisioned. You can use below options to modify/augment current configuration\n"
+#string STR_FORM5_TITLE #language en-US "Sovereign Boot Provisioning Wizard"
+#string STR_INTERACTIVE_MODE_SUBTITLE #language en-US "Sovereign Boot is already provisioned. You can use below options to modify/augment current configuration\n"
+
+#string STR_SOVEREIGN_BOOT_ENROLL_SIGNATURE #language en-US "Enroll Signature"
+#string STR_SOVEREIGN_BOOT_DELETE_SIGNATURE #language en-US "Delete Signature"
+#string STR_SOVEREIGN_BOOT_DELETE_LIST_FORM #language en-US "Delete Signature List Form"
+#string STR_SOVEREIGN_BOOT_DELETE_DATA_FORM #language en-US "Delete Signature Data Form"
+#string STR_SOVEREIGN_BOOT_DELETE_ALL_LIST #language en-US "Delete All Signature List"
+#string STR_SOVEREIGN_BOOT_DELETE_ALL_DATA #language en-US "Delete All Signature Data"
+#string STR_SOVEREIGN_BOOT_DELETE_CHECK_DATA #language en-US "Delete Checked Signature Data"
+#string STR_SOVEREIGN_BOOT_DELETE_ALL_DATA_HELP #language en-US "All signature data will be deleted, no matter how many signature data have you checked."
+#string STR_SOVEREIGN_BOOT_DELETE_CHECK_DATA_HELP #language en-US "All checked signature data will be deleted."
+#string STR_SOVEREIGN_BOOT_ADD_SIGNATURE_FILE #language en-US "Enroll Signature Using File"
+
+#string STR_DBX_CERTIFICATE_FORMAT_PROMPT #language en-US "Signature Format"
+#string STR_DBX_CERTIFICATE_FORMAT_HELP #language en-US "X509 DER-Cert enrolled. Select different option to enroll it into DBX."
+#string STR_DBX_CERTIFICATE_FORMAT_SHA1 #language en-US "X509 CERT SHA1"
+#string STR_DBX_CERTIFICATE_FORMAT_SHA224 #language en-US "X509 CERT SHA224"
+#string STR_DBX_CERTIFICATE_FORMAT_SHA256 #language en-US "X509 CERT SHA256"
+#string STR_DBX_CERTIFICATE_FORMAT_SHA384 #language en-US "X509 CERT SHA384"
+#string STR_DBX_CERTIFICATE_FORMAT_SHA512 #language en-US "X509 CERT SHA512"
+#string STR_DBX_CERTIFICATE_FORMAT_RAW #language en-US "X509 CERT"
+
+#string STR_DBX_PE_IMAGE_FORMAT_HELP #language en-US "PE image enrolled. Use SHA256 hash to enroll it into DBX"
+#string STR_DBX_PE_FORMAT_SHA256 #language en-US "PE Image SHA256"
+
+#string STR_DBX_AUTH_2_FORMAT_HELP #language en-US "VARIABLE_AUTHENTICATION_2 binary enrolled. Use raw binary to enroll it into DBX"
+#string STR_DBX_AUTH_2_FORMAT #language en-US "VARIABLE_AUTHENTICATION_2"
+
+#string STR_CERTIFICATE_REVOCATION_TIME_PROMPT #language en-US " Revocation Time"
+#string STR_CERTIFICATE_REVOCATION_TIME_HELP #language en-US "Input the revocation time of the certificate"
+#string STR_CERTIFICATE_REVOCATION_DATE_PROMPT #language en-US " Revocation Date"
+#string STR_CERTIFICATE_REVOCATION_DATE_HELP #language en-US "Input the revocation date of the certificate"
+
+#string STR_ALWAYS_CERTIFICATE_REVOCATION_PROMPT #language en-US "Always Revoked"
+#string STR_ALWAYS_CERTIFICATE_REVOCATION_HELP #language en-US "Indicate whether the certificate is always revoked."
+
+#string STR_SAVE_SIGNATURE_FILE #language en-US "Save Signature File"
+
+#string STR_SAVE_AND_EXIT #language en-US "Commit Changes and Exit"
+#string STR_NO_SAVE_AND_EXIT #language en-US "Discard Changes and Exit"
+
+#string STR_FILE_EXPLORER_TITLE #language en-US "File Explorer"
+
+#string STR_SOVEREIGN_BOOT_BL_OPTION #language en-US "Show or modify Bootloaders"
+#string STR_SOVEREIGN_BOOT_BL_OPTION_HELP #language en-US ""
+#string STR_SOVEREIGN_BOOT_DB_OPTION #language en-US "Show or modify Trusted Key/Image Database"
+#string STR_SOVEREIGN_BOOT_DB_OPTION_HELP #language en-US ""
+#string STR_SOVEREIGN_BOOT_DBX_OPTION #language en-US "Show or modify Untrusted Key/Image Database"
+#string STR_SOVEREIGN_BOOT_DBX_OPTION_HELP #language en-US ""
+
+#string STR_CERT_TYPE_RSA2048_SHA256_GUID #language en-US "RSA2048_SHA256_GUID"
+#string STR_CERT_TYPE_PCKS7_GUID #language en-US "PKCS7_GUID"
+#string STR_CERT_TYPE_SHA1_GUID #language en-US "SHA1_GUID"
+#string STR_CERT_TYPE_SHA256_GUID #language en-US "SHA256_GUID"
+#string STR_CERT_TYPE_X509_SHA256_GUID #language en-US "X509_SHA256_GUID"
+#string STR_CERT_TYPE_X509_SHA384_GUID #language en-US "X509_SHA384_GUID"
+#string STR_CERT_TYPE_X509_SHA512_GUID #language en-US "X509_SHA512_GUID"
+
+#string STR_LIST_TYPE_RSA2048_SHA256 #language en-US "RSA2048 signature of SHA256 hash"
+#string STR_LIST_TYPE_RSA2048 #language en-US "RSA2048"
+#string STR_LIST_TYPE_X509 #language en-US "X.509 Certificate"
+#string STR_LIST_TYPE_SHA1 #language en-US "SHA1 hash"
+#string STR_LIST_TYPE_SHA224 #language en-US "SHA224 hash"
+#string STR_LIST_TYPE_SHA256 #language en-US "SHA256 hash"
+#string STR_LIST_TYPE_SHA384 #language en-US "SHA384 hash"
+#string STR_LIST_TYPE_SHA512 #language en-US "SHA512 hash"
+#string STR_LIST_TYPE_SM3 #language en-US "SM3 hash"
+#string STR_LIST_TYPE_X509_SHA256 #language en-US "X.509 Certificate SHA256 hash"
+#string STR_LIST_TYPE_X509_SHA384 #language en-US "X.509 Certificate SHA384 hash"
+#string STR_LIST_TYPE_X509_SHA512 #language en-US "X.509 Certificate SHA512 hash"
+#string STR_LIST_TYPE_X509_SM3 #language en-US "X.509 Certificate SM3 hash"
+#string STR_LIST_TYPE_UNKNOWN #language en-US "Unknown"
+
+#string STR_SIGNATURE_LIST_NAME_FORMAT #language en-US "Signature List, Entry-%d"
+#string STR_SIGNATURE_DATA_NAME_FORMAT #language en-US "Signature Data, Entry-%d"
+#string STR_SIGNATURE_LIST_HELP_FORMAT #language en-US "List Type:\n %s\n\nEntry Number:\n %d"
+#string STR_SIGNATURE_DATA_HELP_FORMAT_GUID #language en-US "Owner GUID:\n%s\n"
+#string STR_SIGNATURE_DATA_HELP_GUID_SVBOOT #language en-US "(Enrolled by Sovereign Boot Wizard)\n"
+#string STR_SIGNATURE_DATA_HELP_GUID_FW #language en-US "(Enrolled by firmware)\n"
+#string STR_SIGNATURE_DATA_HELP_GUID_MS #language en-US "(Microsoft owned)\n"
+
+#string STR_SIGNATURE_DATA_HELP_FORMAT_CN #language en-US "\n%s(%d bytes):\nCN = %s\n"
+#string STR_SIGNATURE_DATA_HELP_FORMAT_HASH #language en-US "\n%s(%d bytes):\n%s\n"
+#string STR_SIGNATURE_DATA_HELP_FORMAT_TIME #language en-US "\nRevocation Time:\n%s"
+
+#string STR_SIGNATURE_DATA_HASH_NAME_FORMAT #language en-US "Entry %d: Image %s"
+#string STR_SIGNATURE_DATA_CERT_HASH_NAME_FORMAT #language en-US "Entry %d: %s"
+#string STR_SIGNATURE_DATA_CERT_NAME_FORMAT #language en-US "Entry %d: %s"
+#string STR_SIGNATURE_DATA_RSA_NAME_FORMAT #language en-US "Entry %d: %s key"
+#string STR_SIGNATURE_DATA_RSA_HASH_NAME_FORMAT #language en-US "Entry %d: %s"
+#string STR_SIGNATURE_DATA_UNKNOWN_NAME_FORMAT #language en-US "Entry %d: %s type"
+
+#string STR_SIGNATURE_LIST_HASH_NAME_FORMAT #language en-US "List %d: Image %s list"
+#string STR_SIGNATURE_LIST_CERT_HASH_NAME_FORMAT #language en-US "List %d: %s list"
+#string STR_SIGNATURE_LIST_CERT_NAME_FORMAT #language en-US "List %d: %s list"
+#string STR_SIGNATURE_LIST_RSA_NAME_FORMAT #language en-US "List %d: %s key list"
+#string STR_SIGNATURE_LIST_RSA_HASH_NAME_FORMAT #language en-US "List %d: %s list"
+#string STR_SIGNATURE_LIST_UNKNOWN_NAME_FORMAT #language en-US "List %d: %s type list"
+
+#string STR_SIGNATURE_DELETE_ALL_CONFIRM #language en-US "Press 'Y' to delete all signature List."
+
+#string STR_FORM_HASH_DETAILS_TITLE #language en-US "Key and hash details"
+#string STR_SV_BOOT_DB_INFO #language en-US "Below is the list of certificates and image hashes enrolled "
+ "to the Trusted Image and Key Database.\n\n"
+ "Use below options to delete entries by one with more detailed view.\n\n"
+ "To delete multiple entries please use Delete Signatures option above."
+#string STR_SV_BOOT_DBX_INFO #language en-US "Below is the list of certificates and image hashes enrolled "
+ "to the Unrusted Image and Key Database.\n\n"
+ "Use below options to delete entries by one with more detailed view.\n\n"
+ "To delete multiple entries please use Delete Signatures option above."
+
+#string STR_DATABASE_EMPTY #language en-US "The database is empty"
+
+#string STR_SV_BOOT_SIG_LIST_HELP #language en-US "This signature was not added by Sovereing Boot Provisioning Wizard."
+
+#string STR_SV_BOOT_SIG_LIST_DEFAULT_HELP #language en-US "This signature was not added by Sovereing Boot."
+
+#string STR_SIGNATURE_TYPE #language en-US "Signature type:"
+#string STR_SIGNATURE_DATA_RAW #language en-US "Signature data:"
+#string STR_SIGNATURE_DATA_RAW_HEX #language en-US ""
+
+#string STR_SIGNATURE_DATA_REVOCATION_TIME #language en-US "Revocation time:"
+#string STR_SIGNATURE_DATA_REVOCATION_TIME2 #language en-US ""
+
+#string STR_REMOVE_KEY #language en-US "Remove this key from database"
+#string STR_REMOVE_HASH #language en-US "Remove this hash from database"
+#string STR_REMOVE_CERT #language en-US "Remove this certificate from database"
+
+#string STR_BOOTLOADER_LIST_FORM #language en-US "Bootloaders"
+#string STR_BOOTLOADER_NAME_FORMAT #language en-US "%s (%s)"
+#string STR_BOOTLOADER_HELP_FORMAT #language en-US "%s\n\n%s\n\n%s"
+#string STR_NO_BOOTLOADERS_FOUND #language en-US "No bootloaders found"
+
+#string STR_BOOTLOADER_DETAILS_FORM #language en-US "Bootloader details"
+#string STR_BOOTLOADER_HASH_HEX #language en-US ""
+#string STR_BL_CERTIFICATE_LSIT #language en-US "Certificate list:"
+#string STR_CERT_NO_COMMON_NAME #language en-US "Certificate without common name"
+
+#string STR_IMAGE_IS_SIGNED #language en-US "Image is signed:"
+#string STR_IMAGE_CONTAINS_INVALID_SIGNATURE #language en-US "Image contains invalid signature:"
+#string STR_IMAGE_IS_SIGNED_BY_MS #language en-US "Image contains Microsoft signatures:"
+#string STR_IMAGE_IS_SIGNED_BY_MS_ONLY #language en-US "Image is signed only by Microsoft certificates:"
+#string STR_IMAGE_HASH_IN_DB #language en-US "Image hash present in Trusted Database:"
+#string STR_IMAGE_HASH_IN_DBX #language en-US "Image hash present in Untrusted Database:"
+#string STR_IMAGE_IS_TRUSTED #language en-US "Image is trusted:"
+
+#string STR_YES #language en-US "Yes"
+#string STR_NO #language en-US "No"
+#string STR_UNDECIDED #language en-US "Undecided"
+
+#string STR_CERT_VALID #language en-US "Certificate is valid:"
+#string STR_CERT_IS_MICROSOFT #language en-US "Certificate belongs to Microsoft:"
+#string STR_CERT_IN_DB #language en-US "Certificate present in Trusted Database:"
+#string STR_CERT_IN_DBX #language en-US "Certificate present in Untrusted Database:"
+
+#string STR_REMOVE_CERT_FROM_TRUSTED #language en-US "Remove certificate from Trusted Database"
+#string STR_REMOVE_CERT_FROM_UNTRUSTED #language en-US "Remove certificate from Untrusted Database"
+#string STR_ADD_CERT_TO_TRUSTED #language en-US "Add certificate to Trusted Database"
+#string STR_ADD_CERT_TO_UNTRUSTED #language en-US "Add certificate to Untrusted Database"
+
+#string STR_REMOVE_HASH_FROM_TRUSTED #language en-US "Remove image hash from Trusted Database"
+#string STR_REMOVE_HASH_FROM_UNTRUSTED #language en-US "Remove image hash from Untrusted Database"
+#string STR_ADD_HASH_TO_TRUSTED #language en-US "Add image hash to Trusted Database"
+#string STR_ADD_HASH_TO_UNTRUSTED #language en-US "Add image hash to Untrusted Database"
+
+#string STR_REMOVE_ALL_IMAGE_DATA #language en-US "Remove all hashes and certificates of this image from all databases"
diff --git a/DasharoPayloadPkg/DasharoPayloadPkg.dsc b/DasharoPayloadPkg/DasharoPayloadPkg.dsc
index bfcf60bc88..a2004db81a 100644
--- a/DasharoPayloadPkg/DasharoPayloadPkg.dsc
+++ b/DasharoPayloadPkg/DasharoPayloadPkg.dsc
@@ -803,9 +803,11 @@ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrd
!if $(SOVEREIGN_BOOT_ENABLE) == TRUE
DasharoModulePkg/Application/SovereignBootWizard/SovereignBootWizard.inf {
- # For Secure Boot use OpenSSL, because MBED TLS may fail AuthenticodeVerify
+ # For Secure Boot use OpenSSL, because MBED TLS may fail AuthenticodeVerify
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+ # Using FileExplorerLib directly causes form browsing problems.^M
+ FileExplorerLib|MdeModulePkg/Library/DxeFileExplorerProtocol/DxeFileExplorerProtocol.inf
}
!endif
!endif
@@ -894,6 +896,7 @@ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrd
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/FileExplorerDxe/FileExplorerDxe.inf
DasharoPayloadPkg/BlSupportDxe/BlSupportDxe.inf
CrScreenshotDxe/CrScreenshotDxe.inf {
diff --git a/DasharoPayloadPkg/DasharoPayloadPkg.fdf b/DasharoPayloadPkg/DasharoPayloadPkg.fdf
index e85a6b66cc..d49aa33944 100644
--- a/DasharoPayloadPkg/DasharoPayloadPkg.fdf
+++ b/DasharoPayloadPkg/DasharoPayloadPkg.fdf
@@ -152,6 +152,7 @@ INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF MdeModulePkg/Universal/FileExplorerDxe/FileExplorerDxe.inf
INF DasharoPayloadPkg/BlSupportDxe/BlSupportDxe.inf
INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 2c9e0c04df..cda50a0099 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -1017,6 +1017,7 @@
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/FileExplorerDxe/FileExplorerDxe.inf
OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
@@ -1105,6 +1106,8 @@
# For Secure Boot use OpenSSL, because MBED TLS may fail AuthenticodeVerify
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+ # Using FileExplorerLib directly causes form browsing problems.
+ FileExplorerLib|MdeModulePkg/Library/DxeFileExplorerProtocol/DxeFileExplorerProtocol.inf
}
!endif
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 390747c290..7fd674e61c 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -348,6 +348,7 @@ INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF MdeModulePkg/Universal/FileExplorerDxe/FileExplorerDxe.inf
INF OvmfPkg/SioBusDxe/SioBusDxe.inf
!if $(SOURCE_DEBUG_ENABLE) == FALSE
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
index 903020ea80..59ceaae6ff 100644
--- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
+++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
@@ -781,6 +781,7 @@ IsCertHashFoundInDbx (
{
EFI_STATUS Status;
EFI_SIGNATURE_LIST *DbxList;
+ EFI_SIGNATURE_LIST *DbxWalker;
UINTN DbxSize;
EFI_SIGNATURE_DATA *CertHash;
UINTN CertHashCount;
@@ -821,19 +822,20 @@ IsCertHashFoundInDbx (
}
}
- while ((DbxSize > 0) && (SignatureListSize >= DbxList->SignatureListSize)) {
+ DbxWalker = DbxList;
+ while ((DbxSize > 0) && (SignatureListSize >= DbxWalker->SignatureListSize)) {
//
// Determine Hash Algorithm of Certificate in the forbidden database.
//
- if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha256Guid)) {
+ if (CompareGuid (&DbxWalker->SignatureType, &gEfiCertX509Sha256Guid)) {
HashAlg = HASHALG_SHA256;
- } else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha384Guid)) {
+ } else if (CompareGuid (&DbxWalker->SignatureType, &gEfiCertX509Sha384Guid)) {
HashAlg = HASHALG_SHA384;
- } else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha512Guid)) {
+ } else if (CompareGuid (&DbxWalker->SignatureType, &gEfiCertX509Sha512Guid)) {
HashAlg = HASHALG_SHA512;
} else {
- DbxSize -= DbxList->SignatureListSize;
- DbxList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxList + DbxList->SignatureListSize);
+ DbxSize -= DbxWalker->SignatureListSize;
+ DbxWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxWalker + DbxWalker->SignatureListSize);
continue;
}
//
@@ -843,9 +845,9 @@ IsCertHashFoundInDbx (
goto Done;
}
- SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxList->SignatureHeaderSize;
- CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)DbxList + SiglistHeaderSize);
- CertHashCount = (DbxList->SignatureListSize - SiglistHeaderSize) / DbxList->SignatureSize;
+ SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxWalker->SignatureHeaderSize;
+ CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)DbxWalker + SiglistHeaderSize);
+ CertHashCount = (DbxWalker->SignatureListSize - SiglistHeaderSize) / DbxWalker->SignatureSize;
for (Index = 0; Index < CertHashCount; Index++) {
//
// Iterate each Signature Data Node within this CertList for verify.
@@ -867,11 +869,11 @@ IsCertHashFoundInDbx (
goto Done;
}
- CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)CertHash + DbxList->SignatureSize);
+ CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)CertHash + DbxWalker->SignatureSize);
}
- DbxSize -= DbxList->SignatureListSize;
- DbxList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxList + DbxList->SignatureListSize);
+ DbxSize -= DbxWalker->SignatureListSize;
+ DbxWalker = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxWalker + DbxWalker->SignatureListSize);
}
Status = EFI_SUCCESS;