diff options
67 files changed, 3484 insertions, 128 deletions
diff --git a/ArmPkg/Include/IndustryStandard/ArmTransferList.h b/ArmPkg/Include/IndustryStandard/ArmTransferList.h index 303384622f..2bc0d80177 100644 --- a/ArmPkg/Include/IndustryStandard/ArmTransferList.h +++ b/ArmPkg/Include/IndustryStandard/ArmTransferList.h @@ -74,6 +74,12 @@ #define TRANSFER_LIST_FL_HAS_CHECKSUM BIT0
/*
+ * Flag values for TPM event log table entry layout XFERLIST_EVLOG->Flags,
+ * see https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfer_list.rst#tpm-event-log-table-entry-layout-xferlist_evlog
+ */
+#define TRANSFER_LIST_EVENTLOG_FL_NEED_TO_REPLAY BIT0 /* Need to replay */
+
+/*
* Operation codes indicating the validity of the Transfer List.
*/
typedef enum {
@@ -137,4 +143,18 @@ typedef struct TransferEntryHeader { UINT32 DataSize;
} TRANSFER_ENTRY_HEADER;
+/*
+ * TPM event log information entry,
+ * see Section 'TPM event log table entry layout (XFERLIST_EVLOG)' in
+ * the Firmware Handoff specification.
+ */
+typedef struct TransferListEventLog {
+ /// See the TRANSFER_LIST_EVENT_LOG_FL_*
+ UINT32 Flags;
+
+ /// TPM event log as much as
+ /// TRNASFER_ENTRY_HEADER->DataSize - sizeof (TRANSFER_LIST_EVENTLOG)->Flags
+ UINT8 EventLog[];
+} TRANSFER_LIST_EVENTLOG;
+
#endif // ARM_TRANSFER_LIST_
diff --git a/ArmPkg/Include/Library/ArmTransferListLib.h b/ArmPkg/Include/Library/ArmTransferListLib.h index fb0c69972e..09ade9f4a1 100644 --- a/ArmPkg/Include/Library/ArmTransferListLib.h +++ b/ArmPkg/Include/Library/ArmTransferListLib.h @@ -19,6 +19,21 @@ #include <Pi/PiHob.h>
/**
+ Get the TransferList from HOB list.
+
+ @param[out] TransferList TransferList
+
+ @retval EFI_SUCCESS TransferList is found.
+ @retval EFI_NOT_FOUND TransferList is not found.
+
+**/
+EFI_STATUS
+EFIAPI
+TransferListGetFromHobList (
+ OUT TRANSFER_LIST_HEADER **TransferList
+ );
+
+/**
Return the first Transfer Entry Node in the Transfer List.
@param [in] TransferListHeader Pointer to the Transfer List Header.
@@ -157,4 +172,26 @@ TransferListFindEntry ( IN UINT16 TagId
);
+/**
+ Get TPM event log from TransferList
+
+ @param [in] TransferListHeader Pointer to the Transfer List Header
+ @param [out] EventLog Pointer to Eventlog in TransferList
+ @param [out] EventLogSize Size of Event log
+ @param [out] EventLogFlags Flags for Event log
+
+ @return EFI_SUCCESS
+ @return EFI_NOT_FOUND No Event log in TransferListHeader
+ @return EFI_INVALID_PARAMETER Invalid parameters
+
+**/
+EFI_STATUS
+EFIAPI
+TransferListGetEventLog (
+ IN TRANSFER_LIST_HEADER *TransferListHeader,
+ OUT VOID **EventLog,
+ OUT UINTN *EventLogSize,
+ OUT UINT32 *EventLogFlags OPTIONAL
+ );
+
#endif // ARM_TRANSFER_LIST_LIB_
diff --git a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c index af8170e67f..06d66292b4 100644 --- a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c +++ b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c @@ -13,6 +13,45 @@ #include <Library/ArmTransferListLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+
+/**
+ Get the TransferList from HOB list.
+
+ @param[out] TransferList TransferList
+
+ @retval EFI_SUCCESS TransferList is found.
+ @retval EFI_NOT_FOUND TransferList is not found.
+
+**/
+EFI_STATUS
+EFIAPI
+TransferListGetFromHobList (
+ OUT TRANSFER_LIST_HEADER **TransferList
+ )
+{
+ VOID *HobList;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UINTN *GuidHobData;
+
+ *TransferList = NULL;
+
+ HobList = GetHobList ();
+ if (HobList == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidHob = GetNextGuidHob (&gArmTransferListHobGuid, HobList);
+ if (GuidHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidHobData = GET_GUID_HOB_DATA (GuidHob);
+
+ *TransferList = (TRANSFER_LIST_HEADER *)(*GuidHobData);
+
+ return EFI_SUCCESS;
+}
/**
This function verifies the checksum of the Transfer List.
@@ -275,6 +314,56 @@ TransferListFindEntry ( }
/**
+ Get TPM event log from TransferList
+
+ @param [in] TransferListHeader Pointer to the Transfer List Header
+ @param [out] EventLog Pointer to Eventlog in TransferList
+ @param [out] EventLogSize Size of Event log
+ @param [out] EventLogFlags Flags for Event log
+
+ @return EFI_SUCCESS
+ @return EFI_NOT_FOUND No Event log in TransferListHeader
+ @return EFI_INVALID_PARAMETER Invalid parameters
+
+**/
+EFI_STATUS
+EFIAPI
+TransferListGetEventLog (
+ IN TRANSFER_LIST_HEADER *TransferListHeader,
+ OUT VOID **EventLog,
+ OUT UINTN *EventLogSize,
+ OUT UINT32 *EventLogFlags OPTIONAL
+ )
+{
+ TRANSFER_ENTRY_HEADER *Entry;
+ TRANSFER_LIST_EVENTLOG *EntryData;
+
+ if ((TransferListHeader == NULL) || (EventLog == NULL) || (EventLogSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *EventLog = NULL;
+ *EventLogSize = 0;
+
+ Entry = TransferListFindFirstEntry (TransferListHeader, TRANSFER_ENTRY_TAG_ID_TPM_EVENT_LOG);
+ if ((Entry == NULL) || (Entry->DataSize == 0) ||
+ ((Entry->DataSize - OFFSET_OF (TRANSFER_LIST_EVENTLOG, EventLog)) == 0))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ EntryData = TransferListGetEntryData (Entry);
+ if (EventLogFlags != NULL) {
+ *EventLogFlags = EntryData->Flags;
+ }
+
+ *EventLogSize = Entry->DataSize - OFFSET_OF (TRANSFER_LIST_EVENTLOG, EventLog);
+ *EventLog = (VOID *)&EntryData->EventLog;
+
+ return EFI_SUCCESS;
+}
+
+/**
Dump the transfer list to the debug output.
@param [in] TransferListHeader Pointer to the Transfer List Header
diff --git a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf index b1eeb8a1f7..5ffb1a4d9c 100644 --- a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf +++ b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf @@ -25,3 +25,6 @@ [LibraryClasses]
BaseLib
+
+[Guids]
+ gArmTransferListHobGuid
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index d791351f6b..2dc36d69d6 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -72,6 +72,7 @@ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
!include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 1e239bbbf7..c8e8ab2b05 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -103,6 +103,11 @@ !endif
ArmMonitorLib|ArmVirtPkg/Library/ArmVirtMonitorLib/ArmVirtMonitorLib.inf
+!if $(DEBUG_TO_MEM)
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogDxeLib.inf
+!else
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+!endif
[LibraryClasses.AARCH64]
ArmPlatformLib|ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf
@@ -115,6 +120,12 @@ ArmMonitorLib|ArmVirtPkg/Library/ArmVirtMonitorPeiLib/ArmVirtMonitorPeiLib.inf
FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
+ QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioPeiLib.inf
+!if $(DEBUG_TO_MEM)
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf
+!else
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+!endif
[LibraryClasses.AARCH64.PEIM]
ArmMmuLib|UefiCpuPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
@@ -335,6 +346,23 @@ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
!endif
+[LibraryClasses.common.SEC]
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+
+[LibraryClasses.common.PEI_CORE]
+!if $(DEBUG_TO_MEM)
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCoreLib.inf
+!else
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+!endif
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+!if $(DEBUG_TO_MEM)
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogRtLib.inf
+!else
+ MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
+!endif
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
@@ -350,6 +378,10 @@ ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf
ArmPkg/Drivers/CpuPei/CpuPei.inf
+!if $(DEBUG_TO_MEM)
+ OvmfPkg/MemDebugLogPei/MemDebugLogPei.inf
+!endif
+
!if $(TPM2_ENABLE) == TRUE
MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
<LibraryClasses>
diff --git a/ArmVirtPkg/ArmVirtQemu.fdf b/ArmVirtPkg/ArmVirtQemu.fdf index ac2040acff..1e45d51729 100644 --- a/ArmVirtPkg/ArmVirtQemu.fdf +++ b/ArmVirtPkg/ArmVirtQemu.fdf @@ -111,6 +111,10 @@ READ_LOCK_STATUS = TRUE INF ArmPkg/Drivers/CpuPei/CpuPei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+!if $(DEBUG_TO_MEM)
+ INF OvmfPkg/MemDebugLogPei/MemDebugLogPei.inf
+!endif
+
!if $(TPM2_ENABLE) == TRUE
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c index 83d52e98f5..18222aaebc 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c @@ -24,6 +24,7 @@ #include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugPrintErrorLevelLib.h>
+#include <Library/MemDebugLogLib.h>
#include "Write.h"
@@ -117,6 +118,13 @@ DebugPrintMarker ( }
//
+ // Send string to Memory Debug Log if enabled
+ //
+ if (MemDebugLogEnabled ()) {
+ MemDebugLogWrite ((CHAR8 *)Buffer, AsciiStrLen (Buffer));
+ }
+
+ //
// Send the print string to a Serial Port
//
DebugLibFdtPL011UartWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
@@ -213,6 +221,13 @@ DebugAssert ( AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT [%a] %a(%d): %a\n", gEfiCallerBaseName, FileName, LineNumber, Description);
//
+ // Send string to Memory Debug Log if enabled
+ //
+ if (MemDebugLogEnabled ()) {
+ MemDebugLogWrite ((CHAR8 *)Buffer, AsciiStrLen (Buffer));
+ }
+
+ //
// Send the print string to the Console Output device
//
DebugLibFdtPL011UartWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf index f35a0913f0..6b3b3316a2 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf @@ -40,6 +40,7 @@ PL011UartLib
PcdLib
PrintLib
+ MemDebugLogLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress # Flash.c
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf index a5f4c2d80a..568fc3e6b2 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf @@ -34,6 +34,7 @@ ArmPlatformPkg/ArmPlatformPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
@@ -43,6 +44,7 @@ PL011UartLib
PcdLib
PrintLib
+ MemDebugLogLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DxeRuntimeDebugLibFdtPL011Uart.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DxeRuntimeDebugLibFdtPL011Uart.inf index 84e9dbae22..1ae3f9993a 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DxeRuntimeDebugLibFdtPL011Uart.inf +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DxeRuntimeDebugLibFdtPL011Uart.inf @@ -35,6 +35,7 @@ ArmPlatformPkg/ArmPlatformPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
@@ -44,6 +45,7 @@ PL011UartLib
PcdLib
PrintLib
+ MemDebugLogLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py index ed1ccb1cf1..5d2a44481d 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -1407,7 +1407,11 @@ class DscParser(MetaFileParser): if self._ContentIndex >= len(self._Content):
break
Record = self._Content[self._ContentIndex]
- if LineStart == Record[10] and LineEnd == Record[12]:
+ #
+ # Avoid merging includes with different owners to make sure an
+ # include is correctly processed per arch.
+ #
+ if Owner == Record[8] and LineStart == Record[10] and LineEnd == Record[12]:
if [Record[5], Record[6], Record[7]] not in self._Scope:
self._Scope.append([Record[5], Record[6], Record[7]])
self._ContentIndex += 1
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pem/CryptPem.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pem/CryptPem.c index 56411174dd..ddcf8f4e73 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pem/CryptPem.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pem/CryptPem.c @@ -57,7 +57,7 @@ RsaGetPrivateKeyFromPem ( return FALSE;
}
- CopyMem (NewPemData, PemData, PemSize + 1);
+ CopyMem (NewPemData, PemData, PemSize);
NewPemData[PemSize] = 0;
PemData = NewPemData;
PemSize += 1;
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/UnitTestHostBaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/UnitTestHostBaseCryptLib.inf new file mode 100644 index 0000000000..ae1f0b3d6f --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/UnitTestHostBaseCryptLib.inf @@ -0,0 +1,86 @@ +## @file
+# Cryptographic Library Instance for Unit Test Host.
+#
+# Caution: This module requires additional review when modified.
+# This library will have external input - signature.
+# This external input must be validated carefully to avoid security issues such as
+# buffer overflow or integer overflow.
+#
+# Copyright (c) 2025, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseCryptLib
+ FILE_GUID = 5C14CE62-000E-4CC6-803C-683018EA5F97
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BaseCryptLib|HOST_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ InternalCryptLib.h
+ Hash/CryptMd5.c
+ Hash/CryptSha1.c
+ Hash/CryptSha256.c
+ Hash/CryptSha512.c
+ Hash/CryptParallelHashNull.c
+ Hash/CryptSm3.c
+ Hmac/CryptHmac.c
+ Kdf/CryptHkdf.c
+ Cipher/CryptAes.c
+ Cipher/CryptAeadAesGcm.c
+ Pk/CryptRsaBasic.c
+ Pk/CryptRsaExt.c
+ Pk/CryptPkcs1Oaep.c
+ Pk/CryptPkcs5Pbkdf2.c
+ Pk/CryptPkcs7Sign.c
+ Pk/CryptPkcs7VerifyCommon.c
+ Pk/CryptPkcs7VerifyBase.c
+ Pk/CryptPkcs7VerifyEku.c
+ Pk/CryptDhNull.c
+ Pk/CryptX509.c
+ Pk/CryptAuthenticode.c
+ Pk/CryptTs.c
+ Pk/CryptRsaPss.c
+ Pk/CryptRsaPssSign.c
+ Pk/CryptEcNull.c
+ Pem/CryptPem.c
+ Bn/CryptBnNull.c
+ Rand/CryptRand.c
+
+ SysCall/CrtWrapper.c
+ SysCall/UnitTestHostCrtWrapper.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ DebugLib
+ MbedTlsLib
+ OpensslLib
+ PrintLib
+ RngLib
+
+#
+# Remove these [BuildOptions] after this library is cleaned up
+#
+[BuildOptions]
+ #
+ # suppress the following warnings so we do not break the build with warnings-as-errors:
+ #
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types
+ GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types
+
+ XCODE:*_*_*_CC_FLAGS = -std=c99
diff --git a/CryptoPkg/Test/CryptoPkgHostUnitTest.dsc b/CryptoPkg/Test/CryptoPkgHostUnitTest.dsc index e22363a110..d4d9bf0084 100644 --- a/CryptoPkg/Test/CryptoPkgHostUnitTest.dsc +++ b/CryptoPkg/Test/CryptoPkgHostUnitTest.dsc @@ -17,6 +17,15 @@ BUILD_TARGETS = NOOPT
SKUID_IDENTIFIER = DEFAULT
+!ifndef CRYPTO_TEST_TYPE
+ DEFINE CRYPTO_TEST_TYPE = OPENSSL
+!endif
+
+!if $(CRYPTO_TEST_TYPE) IN "OPENSSL MBEDTLS"
+!else
+ !error CRYPTO_TEST_TYPE must be set to one of OPENSSL MBEDTLS.
+!endif
+
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
!include CryptoPkg/CryptoPkgFeatureFlagPcds.dsc.inc
@@ -34,6 +43,7 @@ #
# Build HOST_APPLICATION that tests the SampleUnitTest
#
+!if $(CRYPTO_TEST_TYPE) IN "OPENSSL"
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf {
<LibraryClasses>
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
@@ -44,6 +54,16 @@ <LibraryClasses>
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf
}
+!endif
+
+!if $(CRYPTO_TEST_TYPE) IN "MBEDTLS"
+ CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf {
+ <LibraryClasses>
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLibMbedTls/UnitTestHostBaseCryptLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibSm3.inf
+ MbedTlsLib|CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
+ }
+!endif
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPkcs7Tests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPkcs7Tests.c index aba049f0dd..dcb93236d4 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPkcs7Tests.c +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaPkcs7Tests.c @@ -228,6 +228,164 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TestCert[] = { };
//
+// TestCase2: Non self issued CA (partial certificate chains)
+//
+//
+// Password-protected PEM Key data for RSA Private Key Retrieving (encryption key is "non-self-issued").
+// (Generated by OpenSSL utility).
+// $ openssl genrsa -aes256 -out TestKeyCert2Pem -passout pass:non-self-issued 1024
+// password should match TestKeyCert2PemPass in this file
+// $ xxd --include TestKeyCert2Pem
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TestKeyCert2Pem[] = {
+ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52,
+ 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b,
+ 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0d, 0x0a, 0x50, 0x72, 0x6f,
+ 0x63, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x34, 0x2c, 0x45, 0x4e,
+ 0x43, 0x52, 0x59, 0x50, 0x54, 0x45, 0x44, 0x0d, 0x0a, 0x44, 0x45, 0x4b,
+ 0x2d, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x41, 0x45, 0x53, 0x2d, 0x32,
+ 0x35, 0x36, 0x2d, 0x43, 0x42, 0x43, 0x2c, 0x39, 0x43, 0x39, 0x38, 0x32,
+ 0x33, 0x31, 0x38, 0x42, 0x46, 0x37, 0x38, 0x33, 0x38, 0x46, 0x34, 0x32,
+ 0x45, 0x34, 0x33, 0x31, 0x32, 0x42, 0x42, 0x30, 0x43, 0x39, 0x31, 0x33,
+ 0x36, 0x43, 0x44, 0x0d, 0x0a, 0x0d, 0x0a, 0x62, 0x32, 0x77, 0x62, 0x64,
+ 0x75, 0x49, 0x30, 0x76, 0x6b, 0x48, 0x41, 0x6c, 0x45, 0x4a, 0x78, 0x30,
+ 0x6d, 0x69, 0x64, 0x57, 0x6f, 0x77, 0x6d, 0x71, 0x32, 0x62, 0x64, 0x75,
+ 0x65, 0x4f, 0x7a, 0x49, 0x71, 0x44, 0x59, 0x46, 0x6e, 0x4d, 0x41, 0x76,
+ 0x79, 0x58, 0x5a, 0x45, 0x74, 0x45, 0x4c, 0x79, 0x42, 0x41, 0x72, 0x7a,
+ 0x4c, 0x6c, 0x55, 0x72, 0x54, 0x73, 0x78, 0x41, 0x49, 0x62, 0x73, 0x0d,
+ 0x0a, 0x47, 0x4d, 0x46, 0x45, 0x47, 0x44, 0x59, 0x46, 0x69, 0x72, 0x7a,
+ 0x6c, 0x55, 0x77, 0x2f, 0x54, 0x6a, 0x36, 0x43, 0x2f, 0x78, 0x71, 0x45,
+ 0x67, 0x76, 0x79, 0x2b, 0x6c, 0x47, 0x57, 0x42, 0x46, 0x6b, 0x6c, 0x64,
+ 0x34, 0x7a, 0x49, 0x2b, 0x68, 0x73, 0x62, 0x77, 0x45, 0x70, 0x53, 0x6d,
+ 0x36, 0x4a, 0x61, 0x6a, 0x4e, 0x73, 0x69, 0x61, 0x79, 0x35, 0x6f, 0x6f,
+ 0x37, 0x6b, 0x41, 0x54, 0x68, 0x0d, 0x0a, 0x69, 0x6e, 0x51, 0x54, 0x33,
+ 0x43, 0x71, 0x76, 0x6e, 0x64, 0x41, 0x44, 0x50, 0x44, 0x5a, 0x72, 0x6f,
+ 0x38, 0x7a, 0x44, 0x52, 0x64, 0x4d, 0x2b, 0x58, 0x67, 0x65, 0x53, 0x42,
+ 0x37, 0x69, 0x65, 0x78, 0x6a, 0x55, 0x32, 0x55, 0x69, 0x42, 0x48, 0x4e,
+ 0x6b, 0x73, 0x76, 0x52, 0x77, 0x49, 0x4f, 0x75, 0x52, 0x50, 0x57, 0x41,
+ 0x75, 0x56, 0x4c, 0x41, 0x77, 0x6e, 0x6a, 0x57, 0x79, 0x66, 0x51, 0x0d,
+ 0x0a, 0x6e, 0x39, 0x52, 0x59, 0x4e, 0x78, 0x44, 0x37, 0x63, 0x73, 0x2f,
+ 0x56, 0x54, 0x38, 0x50, 0x50, 0x55, 0x75, 0x35, 0x69, 0x4d, 0x70, 0x65,
+ 0x4e, 0x49, 0x6a, 0x44, 0x44, 0x6a, 0x48, 0x5a, 0x2b, 0x78, 0x2f, 0x75,
+ 0x37, 0x77, 0x6e, 0x75, 0x46, 0x65, 0x76, 0x56, 0x73, 0x62, 0x67, 0x4e,
+ 0x50, 0x76, 0x4e, 0x78, 0x74, 0x6a, 0x74, 0x6a, 0x33, 0x66, 0x73, 0x6c,
+ 0x49, 0x75, 0x6d, 0x6c, 0x59, 0x0d, 0x0a, 0x53, 0x36, 0x35, 0x6b, 0x41,
+ 0x59, 0x6f, 0x36, 0x2f, 0x69, 0x51, 0x69, 0x50, 0x2b, 0x48, 0x52, 0x2b,
+ 0x59, 0x71, 0x57, 0x55, 0x53, 0x73, 0x4e, 0x7a, 0x55, 0x6f, 0x35, 0x52,
+ 0x72, 0x49, 0x51, 0x6d, 0x41, 0x52, 0x2f, 0x74, 0x66, 0x66, 0x55, 0x5a,
+ 0x66, 0x69, 0x4f, 0x37, 0x76, 0x53, 0x67, 0x4b, 0x49, 0x32, 0x47, 0x72,
+ 0x4e, 0x66, 0x69, 0x5a, 0x55, 0x6c, 0x49, 0x4f, 0x49, 0x7a, 0x39, 0x0d,
+ 0x0a, 0x67, 0x78, 0x56, 0x58, 0x73, 0x56, 0x69, 0x56, 0x2b, 0x47, 0x6b,
+ 0x70, 0x52, 0x49, 0x5a, 0x71, 0x7a, 0x46, 0x38, 0x53, 0x76, 0x4d, 0x72,
+ 0x35, 0x57, 0x4b, 0x63, 0x51, 0x49, 0x4b, 0x79, 0x61, 0x44, 0x52, 0x66,
+ 0x72, 0x57, 0x54, 0x75, 0x55, 0x4b, 0x4a, 0x67, 0x50, 0x57, 0x77, 0x30,
+ 0x42, 0x70, 0x45, 0x43, 0x65, 0x62, 0x6c, 0x77, 0x58, 0x79, 0x42, 0x56,
+ 0x70, 0x4b, 0x55, 0x72, 0x71, 0x0d, 0x0a, 0x77, 0x67, 0x56, 0x6c, 0x55,
+ 0x37, 0x42, 0x55, 0x55, 0x4b, 0x57, 0x6c, 0x36, 0x52, 0x66, 0x38, 0x32,
+ 0x42, 0x4d, 0x59, 0x63, 0x75, 0x47, 0x39, 0x2f, 0x36, 0x6a, 0x37, 0x61,
+ 0x4b, 0x6c, 0x6b, 0x42, 0x67, 0x42, 0x41, 0x33, 0x58, 0x75, 0x32, 0x33,
+ 0x68, 0x42, 0x64, 0x45, 0x33, 0x63, 0x55, 0x30, 0x47, 0x5a, 0x74, 0x50,
+ 0x66, 0x78, 0x33, 0x65, 0x4d, 0x64, 0x69, 0x2f, 0x6e, 0x4b, 0x4b, 0x0d,
+ 0x0a, 0x32, 0x66, 0x74, 0x33, 0x71, 0x79, 0x71, 0x2b, 0x32, 0x47, 0x56,
+ 0x73, 0x63, 0x74, 0x48, 0x65, 0x30, 0x75, 0x68, 0x37, 0x44, 0x4a, 0x6a,
+ 0x55, 0x30, 0x78, 0x37, 0x59, 0x48, 0x4f, 0x4f, 0x52, 0x51, 0x6b, 0x4f,
+ 0x79, 0x77, 0x79, 0x72, 0x6b, 0x34, 0x45, 0x61, 0x44, 0x42, 0x73, 0x72,
+ 0x71, 0x44, 0x6e, 0x51, 0x7a, 0x76, 0x2b, 0x4c, 0x34, 0x61, 0x70, 0x4a,
+ 0x71, 0x44, 0x31, 0x39, 0x72, 0x0d, 0x0a, 0x72, 0x64, 0x2b, 0x6e, 0x47,
+ 0x38, 0x75, 0x4d, 0x4b, 0x2f, 0x32, 0x4c, 0x38, 0x62, 0x73, 0x53, 0x71,
+ 0x4e, 0x7a, 0x46, 0x52, 0x2f, 0x46, 0x64, 0x51, 0x77, 0x6f, 0x39, 0x32,
+ 0x5a, 0x33, 0x6b, 0x4c, 0x63, 0x6a, 0x36, 0x61, 0x31, 0x36, 0x50, 0x6b,
+ 0x2f, 0x78, 0x38, 0x6e, 0x64, 0x70, 0x67, 0x54, 0x58, 0x35, 0x6a, 0x71,
+ 0x44, 0x41, 0x72, 0x4b, 0x36, 0x79, 0x38, 0x43, 0x65, 0x48, 0x70, 0x0d,
+ 0x0a, 0x33, 0x75, 0x48, 0x4b, 0x67, 0x77, 0x45, 0x52, 0x30, 0x52, 0x30,
+ 0x43, 0x34, 0x33, 0x6f, 0x37, 0x61, 0x41, 0x76, 0x6f, 0x79, 0x76, 0x5a,
+ 0x36, 0x44, 0x4e, 0x75, 0x5a, 0x46, 0x77, 0x65, 0x7a, 0x7a, 0x4c, 0x50,
+ 0x31, 0x35, 0x33, 0x78, 0x36, 0x35, 0x78, 0x75, 0x4b, 0x47, 0x57, 0x33,
+ 0x5a, 0x2b, 0x38, 0x68, 0x63, 0x5a, 0x53, 0x42, 0x32, 0x2b, 0x79, 0x76,
+ 0x33, 0x74, 0x36, 0x56, 0x69, 0x0d, 0x0a, 0x39, 0x45, 0x4b, 0x51, 0x65,
+ 0x58, 0x65, 0x36, 0x7a, 0x4f, 0x5a, 0x57, 0x36, 0x74, 0x42, 0x6d, 0x4a,
+ 0x51, 0x2f, 0x51, 0x65, 0x66, 0x51, 0x37, 0x45, 0x34, 0x70, 0x62, 0x78,
+ 0x65, 0x54, 0x46, 0x43, 0x4e, 0x33, 0x56, 0x4c, 0x51, 0x41, 0x75, 0x31,
+ 0x4d, 0x47, 0x75, 0x4b, 0x48, 0x70, 0x30, 0x5a, 0x59, 0x39, 0x42, 0x58,
+ 0x4f, 0x62, 0x77, 0x44, 0x48, 0x53, 0x39, 0x57, 0x51, 0x67, 0x6d, 0x0d,
+ 0x0a, 0x79, 0x31, 0x66, 0x37, 0x78, 0x70, 0x77, 0x30, 0x34, 0x38, 0x69,
+ 0x68, 0x67, 0x6c, 0x70, 0x32, 0x6e, 0x44, 0x32, 0x63, 0x72, 0x4b, 0x4b,
+ 0x57, 0x57, 0x38, 0x68, 0x6d, 0x41, 0x59, 0x6d, 0x6f, 0x51, 0x63, 0x42,
+ 0x36, 0x4f, 0x73, 0x58, 0x4f, 0x36, 0x45, 0x35, 0x77, 0x73, 0x4b, 0x65,
+ 0x75, 0x59, 0x41, 0x30, 0x6f, 0x79, 0x65, 0x61, 0x33, 0x6a, 0x6e, 0x55,
+ 0x4b, 0x71, 0x6a, 0x41, 0x58, 0x0d, 0x0a, 0x49, 0x56, 0x73, 0x43, 0x79,
+ 0x75, 0x68, 0x50, 0x48, 0x78, 0x65, 0x2b, 0x58, 0x38, 0x6e, 0x67, 0x38,
+ 0x52, 0x30, 0x72, 0x70, 0x78, 0x41, 0x30, 0x4d, 0x6f, 0x78, 0x71, 0x71,
+ 0x72, 0x67, 0x71, 0x78, 0x46, 0x32, 0x61, 0x4c, 0x33, 0x39, 0x38, 0x6d,
+ 0x51, 0x54, 0x46, 0x4f, 0x68, 0x4b, 0x46, 0x62, 0x2b, 0x73, 0x41, 0x69,
+ 0x6e, 0x7a, 0x34, 0x48, 0x59, 0x52, 0x59, 0x65, 0x4b, 0x72, 0x48, 0x0d,
+ 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, 0x53,
+ 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45,
+ 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0d, 0x0a
+};
+//
+// Password for private key retrieving from encrypted PEM ("TestKeyCert2PemPass").
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *TestKeyCert2PemPass = "non-self-issued";
+//
+// X509 Cert Data for RSA Public Key Retrieving and X509 Verification (Generated by OpenSSL utility).
+// $ openssl req -new -key TestKeyCert2Pem -out TestCertCsr2 -subj "/C=US/ST=WA/L=Seattle/O=Tianocore/OU=EDK2CHILD/CN=UEFINOSELFISSUED"
+// $ openssl x509 -days 10000 -CA TestCACert.pem -CAkey TestKeyPem -req -out TestCert2 -set_serial 3432 --outform DER -in TestCertCsr2
+// password should be in the PemPass variable
+// $ xxd --include TestCert2
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TestCert2[] = {
+ 0x30, 0x82, 0x02, 0x3f, 0x30, 0x82, 0x01, 0xa8, 0x02, 0x02, 0x0d, 0x68,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x08, 0x0c, 0x02, 0x57, 0x41, 0x31, 0x10, 0x30, 0x0e, 0x06,
+ 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c,
+ 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09,
+ 0x54, 0x69, 0x61, 0x6e, 0x6f, 0x63, 0x6f, 0x72, 0x65, 0x31, 0x0d, 0x30,
+ 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x45, 0x44, 0x4b, 0x32,
+ 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x04, 0x55,
+ 0x45, 0x46, 0x49, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x38, 0x32,
+ 0x31, 0x30, 0x33, 0x34, 0x36, 0x35, 0x34, 0x5a, 0x18, 0x0f, 0x32, 0x30,
+ 0x35, 0x33, 0x30, 0x31, 0x30, 0x36, 0x30, 0x33, 0x34, 0x36, 0x35, 0x34,
+ 0x5a, 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+ 0x08, 0x0c, 0x02, 0x57, 0x41, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
+ 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31,
+ 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x54, 0x69,
+ 0x61, 0x6e, 0x6f, 0x63, 0x6f, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06,
+ 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x09, 0x45, 0x44, 0x4b, 0x32, 0x43, 0x48,
+ 0x49, 0x4c, 0x44, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0c, 0x10, 0x55, 0x45, 0x46, 0x49, 0x4e, 0x4f, 0x53, 0x45, 0x4c, 0x46,
+ 0x49, 0x53, 0x53, 0x55, 0x45, 0x44, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+ 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa3,
+ 0x08, 0x50, 0xc5, 0x20, 0xea, 0x2c, 0xf6, 0xfe, 0xa9, 0xa0, 0xee, 0x9b,
+ 0xa1, 0xd7, 0x5a, 0x24, 0x99, 0x8f, 0xe3, 0x27, 0xd9, 0xbf, 0x59, 0x73,
+ 0x5d, 0x88, 0x1a, 0x0d, 0x98, 0x0e, 0xaf, 0xe8, 0x98, 0x77, 0x67, 0x04,
+ 0xdc, 0x6d, 0x2d, 0xea, 0x3d, 0x94, 0x35, 0x56, 0x85, 0x4b, 0xad, 0xd3,
+ 0xb5, 0x19, 0xcb, 0x6e, 0x3f, 0xeb, 0x4c, 0x31, 0x85, 0xb5, 0xf5, 0x6c,
+ 0x5c, 0xd1, 0x71, 0x05, 0xef, 0x39, 0xf5, 0x0a, 0xca, 0x73, 0x0d, 0x4e,
+ 0xdc, 0x76, 0x29, 0xa3, 0xc7, 0x0d, 0xb7, 0x96, 0x83, 0x38, 0xaa, 0x49,
+ 0x93, 0xc9, 0x17, 0xe7, 0x13, 0xb6, 0xd3, 0xb5, 0xc0, 0xe4, 0x27, 0xd0,
+ 0x4f, 0x4a, 0x82, 0xe4, 0x79, 0x7e, 0xcc, 0xf5, 0x25, 0xb9, 0x2c, 0xe3,
+ 0xcd, 0xf1, 0x8b, 0xc3, 0x5a, 0x37, 0x5d, 0xe7, 0x34, 0xef, 0x9e, 0xd0,
+ 0xb9, 0x5a, 0x0c, 0xdc, 0x30, 0x13, 0xdf, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x87, 0x53, 0xea, 0x99, 0xbc,
+ 0x6d, 0xc4, 0xd3, 0x7f, 0xb2, 0xca, 0xe7, 0x19, 0x44, 0xc5, 0xcf, 0xdf,
+ 0xcb, 0x41, 0xee, 0x3b, 0xf6, 0x4f, 0x2a, 0x48, 0x5f, 0x32, 0xca, 0x11,
+ 0xae, 0x21, 0x46, 0x5d, 0xb4, 0xb0, 0x8a, 0x6b, 0x43, 0x4a, 0xc1, 0x49,
+ 0xc9, 0x83, 0x61, 0xce, 0x3f, 0x90, 0x7d, 0xc5, 0x0b, 0x5c, 0x93, 0xb7,
+ 0x76, 0x2b, 0xe5, 0x2f, 0xac, 0xb2, 0xc6, 0x3d, 0x82, 0xee, 0x70, 0x4a,
+ 0x0a, 0x62, 0x5e, 0xb2, 0x33, 0xe0, 0xed, 0xcc, 0x83, 0xbd, 0x45, 0x27,
+ 0x94, 0xc1, 0x98, 0x84, 0x9e, 0x22, 0x00, 0xa8, 0xfe, 0x18, 0x0a, 0xe7,
+ 0xaa, 0x23, 0xaf, 0x6e, 0xaa, 0xe5, 0x03, 0x55, 0x37, 0x5a, 0x98, 0x08,
+ 0x7b, 0xab, 0x4c, 0xba, 0x46, 0x27, 0xf1, 0xd3, 0x63, 0x16, 0x20, 0x2f,
+ 0xe8, 0x58, 0xd6, 0x34, 0x3f, 0x83, 0xe5, 0x33, 0x5b, 0xf5, 0x6e, 0x6a,
+ 0x25, 0x9f, 0x16
+};
+
+//
// Message Hash for Signing & Verification Validation.
//
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 MsgHash[] = {
@@ -426,6 +584,72 @@ TestVerifyPkcs7SignVerify ( return UNIT_TEST_PASSED;
}
+//
+// TestCase2: Non self issued CA (partial certificate chains)
+// This case uses a non-self-issued certificate as the signing certificate and CA.
+// BaseCryptLib can pass this case (with X509_V_FLAG_PARTIAL_CHAIN enabled).
+// BaseCryptLibMbedTls cannot, because Mbedtls certificate chain validation lacks support for partial certificate chains currently .
+//
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyPkcs7SignVerifyNonSelfIssued (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ BOOLEAN Status;
+ UINT8 *P7SignedData;
+ UINTN P7SignedDataSize;
+ UINT8 *SignCert;
+
+ P7SignedData = NULL;
+ SignCert = NULL;
+
+ //
+ // Construct Signer Certificate from RAW data.
+ //
+ Status = X509ConstructCertificate (TestCert2, sizeof (TestCert2), (UINT8 **)&SignCert);
+ UT_ASSERT_TRUE (Status);
+ UT_ASSERT_NOT_NULL (SignCert);
+
+ //
+ // Create PKCS#7 signedData on Payload.
+ // Note: Caller should release P7SignedData manually.
+ //
+ Status = Pkcs7Sign (
+ TestKeyCert2Pem,
+ sizeof (TestKeyCert2Pem),
+ (CONST UINT8 *)TestKeyCert2PemPass,
+ (UINT8 *)Payload,
+ AsciiStrLen (Payload),
+ SignCert,
+ NULL,
+ &P7SignedData,
+ &P7SignedDataSize
+ );
+ UT_ASSERT_TRUE (Status);
+ UT_ASSERT_NOT_EQUAL (P7SignedDataSize, 0);
+
+ Status = Pkcs7Verify (
+ P7SignedData,
+ P7SignedDataSize,
+ TestCert2,
+ sizeof (TestCert2),
+ (UINT8 *)Payload,
+ AsciiStrLen (Payload)
+ );
+ UT_ASSERT_TRUE (Status);
+
+ if (P7SignedData != NULL) {
+ FreePool (P7SignedData);
+ }
+
+ if (SignCert != NULL) {
+ X509Free (SignCert);
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
TEST_DESC mRsaCertTest[] = {
//
// -----Description--------------------------------------Class----------------------Function-----------------Pre---Post--Context
@@ -439,7 +663,8 @@ TEST_DESC mPkcs7Test[] = { //
// -----Description--------------------------------------Class----------------------Function-----------------Pre---Post--Context
//
- { "TestVerifyPkcs7SignVerify()", "CryptoPkg.BaseCryptLib.Pkcs7", TestVerifyPkcs7SignVerify, NULL, NULL, NULL },
+ { "TestVerifyPkcs7SignVerify()", "CryptoPkg.BaseCryptLib.Pkcs7", TestVerifyPkcs7SignVerify, NULL, NULL, NULL },
+ { "TestVerifyPkcs7SignVerifyNonSelfIssued()", "CryptoPkg.BaseCryptLib.Pkcs7", TestVerifyPkcs7SignVerifyNonSelfIssued, NULL, NULL, NULL },
};
UINTN mPkcs7TestNum = ARRAY_SIZE (mPkcs7Test);
diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.c b/MdeModulePkg/Core/Pei/FwVol/FwVol.c index 04bec986e4..1c0aa9d121 100644 --- a/MdeModulePkg/Core/Pei/FwVol/FwVol.c +++ b/MdeModulePkg/Core/Pei/FwVol/FwVol.c @@ -2,7 +2,7 @@ Pei Core Firmware File System service routines.
Copyright (c) 2015 HP Development Company, L.P.
-Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2025, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -456,6 +456,29 @@ FindFileEx ( }
/**
+ Return the pointer to the Firmware Volume GUID name in the FV header.
+
+ @param[in] FvHeader Pointer to the header of the Firmware Volume.
+
+ @retval Pointer to the Firmware Volume GUID name in the FV header.
+ NULL if the FV is anonymous without an extended header.
+**/
+EFI_GUID *
+GetFvName (
+ IN CONST EFI_FIRMWARE_VOLUME_HEADER *FvHeader
+ )
+{
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
+
+ if (FvHeader->ExtHeaderOffset == 0) {
+ return NULL;
+ }
+
+ FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FvHeader + FvHeader->ExtHeaderOffset);
+ return &FvExtHeader->FvName;
+}
+
+/**
Initialize PeiCore FV List.
@param PrivateData - Pointer to PEI_CORE_INSTANCE.
@@ -519,8 +542,9 @@ PeiInitializeFv ( PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = 0;
DEBUG ((
DEBUG_INFO,
- "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
+ "The %dth FV[%g] start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
(UINT32)PrivateData->FvCount,
+ GetFvName (BfvHeader),
(VOID *)BfvHeader,
(UINT32)BfvHeader->FvLength,
FvHandle
@@ -661,8 +685,9 @@ FirmwareVolumeInfoPpiNotifyCallback ( CurFvCount = PrivateData->FvCount;
DEBUG ((
DEBUG_INFO,
- "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
+ "The %dth FV[%g] start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
(UINT32)CurFvCount,
+ GetFvName ((EFI_FIRMWARE_VOLUME_HEADER *)FvInfo2Ppi.FvInfo),
(VOID *)FvInfo2Ppi.FvInfo,
FvInfo2Ppi.FvInfoSize,
FvHandle
@@ -696,7 +721,7 @@ FirmwareVolumeInfoPpiNotifyCallback ( }
}
- DEBUG ((DEBUG_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, CurFvCount, FvHandle));
+ DEBUG ((DEBUG_INFO, "Found firmware volume Image File[%g] %p in FV[%d] %p\n", FileHandle, FileHandle, CurFvCount, FvHandle));
ProcessFvFile (PrivateData, &PrivateData->Fv[CurFvCount], FileHandle);
}
} while (FileHandle != NULL);
@@ -2434,8 +2459,9 @@ ThirdPartyFvPpiNotifyCallback ( CurFvCount = PrivateData->FvCount;
DEBUG ((
DEBUG_INFO,
- "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
+ "The %dth FV[%g] start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
(UINT32)CurFvCount,
+ GetFvName ((EFI_FIRMWARE_VOLUME_HEADER *)FvInfo),
(VOID *)FvInfo,
FvInfoSize,
FvHandle
@@ -2469,7 +2495,7 @@ ThirdPartyFvPpiNotifyCallback ( }
}
- DEBUG ((DEBUG_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, CurFvCount, FvHandle));
+ DEBUG ((DEBUG_INFO, "Found firmware volume Image File[%g] %p in FV[%d] %p\n", FileHandle, FileHandle, CurFvCount, FvHandle));
ProcessFvFile (PrivateData, &PrivateData->Fv[CurFvCount], FileHandle);
}
} while (FileHandle != NULL);
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 24cc64f6b4..8820059e7c 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1674,6 +1674,14 @@ # @Prompt Maximum Number of PEI Reset Filters, Reset Notifications or Reset Handlers.
gEfiMdeModulePkgTokenSpaceGuid.PcdMaximumPeiResetNotifies|0x10|UINT32|0x0000010A
+ ## Whether to report support of FMP capsules in OsIndicationSupport.<BR><BR>
+ # This PCD indicates if support of FMP capsules should be advertised.<BR>
+ # TRUE - support of FMP capsules is advertised.<BR>
+ # FALSE - support of FMP capsules is not advertised.<BR>
+ # If platform does not use this feature, this PCD should be set to FALSE.<BR><BR>
+ # @Prompt Enable advertising support of FMP capsules.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleFmpSupport|FALSE|BOOLEAN|0x00000028
+
## Capsule On Disk is to deliver capsules via files on Mass Storage device.<BR><BR>
# This PCD indicates if the Capsule On Disk is supported.<BR>
# TRUE - Capsule On Disk is supported.<BR>
diff --git a/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf b/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf index 5bac635def..95d2607b8d 100644 --- a/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf +++ b/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf @@ -97,6 +97,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleOnDiskSupport ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleFmpSupport ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformRecoverySupport ## CONSUMES
[Depex]
diff --git a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c index 72de8d3211..78564919f3 100644 --- a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c +++ b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c @@ -580,6 +580,10 @@ BdsFormalizeOSIndicationVariable ( OsIndicationSupport |= EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
}
+ if (PcdGetBool (PcdCapsuleFmpSupport)) {
+ OsIndicationSupport |= EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED;
+ }
+
Status = gRT->SetVariable (
EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
&gEfiGlobalVariableGuid,
diff --git a/MdePkg/Library/BaseFdtLib/LibFdtSupport.h b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h index 05f758a93d..be7043bd27 100644 --- a/MdePkg/Library/BaseFdtLib/LibFdtSupport.h +++ b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h @@ -3,6 +3,7 @@ libfdt library.
Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -54,12 +55,6 @@ memcmp ( size_t
);
-int
-strcmp (
- const char *,
- const char *
- );
-
char *
strchr (
const char *,
@@ -88,19 +83,15 @@ strcpy ( //
// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions
//
-#define memcpy(dest, source, count) CopyMem(dest,source, (UINTN)(count))
-#define memset(dest, ch, count) SetMem(dest, (UINTN)(count),(UINT8)(ch))
-#define memchr(buf, ch, count) ScanMem8(buf, (UINTN)(count),(UINT8)ch)
-#define memcmp(buf1, buf2, count) (int)(CompareMem(buf1, buf2, (UINTN)(count)))
-#define memmove(dest, source, count) CopyMem(dest, source, (UINTN)(count))
-#define strlen(str) (size_t)(AsciiStrLen(str))
-#define strnlen(str, count) (size_t)(AsciiStrnLenS(str, count))
-#define strncpy(strDest, strSource, count) AsciiStrnCpyS(strDest, MAX_STRING_SIZE, strSource, (UINTN)count)
-#define strcat(strDest, strSource) AsciiStrCatS(strDest, MAX_STRING_SIZE, strSource)
-#define strchr(str, ch) ScanMem8(str, AsciiStrSize (str), (UINT8)ch)
-#define strcmp(string1, string2, count) (int)(AsciiStrCmp(string1, string2))
-#define strncmp(string1, string2, count) (int)(AsciiStrnCmp(string1, string2, (UINTN)(count)))
-#define strrchr(str, ch) fdt_strrchr(str, ch)
-#define strtoul(ptr, end_ptr, base) fdt_strtoul(ptr, end_ptr, base)
+#define memcpy(dest, source, count) CopyMem(dest,source, (UINTN)(count))
+#define memset(dest, ch, count) SetMem(dest, (UINTN)(count),(UINT8)(ch))
+#define memchr(buf, ch, count) ScanMem8(buf, (UINTN)(count),(UINT8)ch)
+#define memcmp(buf1, buf2, count) (int)(CompareMem(buf1, buf2, (UINTN)(count)))
+#define memmove(dest, source, count) CopyMem(dest, source, (UINTN)(count))
+#define strlen(str) (size_t)(AsciiStrLen(str))
+#define strnlen(str, count) (size_t)(AsciiStrnLenS(str, count))
+#define strchr(str, ch) ScanMem8(str, AsciiStrSize (str), (UINT8)ch)
+#define strrchr(str, ch) fdt_strrchr(str, ch)
+#define strtoul(ptr, end_ptr, base) fdt_strtoul(ptr, end_ptr, base)
#endif /* FDT_LIB_SUPPORT_H_ */
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c index 3b2ac0d887..072707faee 100644 --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c @@ -1490,7 +1490,7 @@ WifiMgrOnTimerTick ( }
Nic = (WIFI_MGR_DEVICE_DATA *)Context;
- if (Nic->ConnectPendingNetwork == NULL) {
+ if ((Nic->ConnectPendingNetwork == NULL) && !Nic->HasDisconnectPendingNetwork) {
DEBUG ((DEBUG_VERBOSE, "[WiFi Connection Manager] No profile for connection, no scan triggered!\n"));
gBS->SetTimer (Nic->TickTimer, TimerCancel, 0);
return;
diff --git a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPei.c b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPei.c index cbdab6c22f..05e32daf1c 100644 --- a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPei.c +++ b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPei.c @@ -12,9 +12,6 @@ #include <Library/QemuFwCfgSimpleParserLib.h>
#include <Library/MemDebugLogLib.h>
-EFI_PHYSICAL_ADDRESS mMemDebugLogBufAddr;
-BOOLEAN mMemDebugLogBufAddrInit;
-
EFI_STATUS
EFIAPI
MemDebugLogWrite (
@@ -22,23 +19,21 @@ MemDebugLogWrite ( IN UINTN Length
)
{
- EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemDebugLogBufAddr;
+ EFI_STATUS Status;
- if (!mMemDebugLogBufAddrInit) {
- //
- // Obtain the Memory Debug Log buffer addr from HOB
- // NOTE: This is expected to fail until the HOB is created.
- //
- Status = MemDebugLogAddrFromHOB (&mMemDebugLogBufAddr);
- if (EFI_ERROR (Status)) {
- mMemDebugLogBufAddr = 0;
- } else {
- mMemDebugLogBufAddrInit = TRUE;
- }
+ //
+ // Obtain the Memory Debug Log buffer addr from HOB
+ // NOTE: This is expected to fail until the HOB is created.
+ //
+ Status = MemDebugLogAddrFromHOB (&MemDebugLogBufAddr);
+
+ if (EFI_ERROR (Status)) {
+ MemDebugLogBufAddr = 0;
}
- if (mMemDebugLogBufAddr) {
- Status = MemDebugLogWriteBuffer (mMemDebugLogBufAddr, Buffer, Length);
+ if (MemDebugLogBufAddr != 0) {
+ Status = MemDebugLogWriteBuffer (MemDebugLogBufAddr, Buffer, Length);
} else {
//
// HOB has not yet been created, so
diff --git a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCore.c b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCore.c index 1e95d65aaa..c8de40d5c1 100644 --- a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCore.c +++ b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiCore.c @@ -11,9 +11,6 @@ #include <Library/PeiServicesLib.h>
#include <Library/MemDebugLogLib.h>
-EFI_PHYSICAL_ADDRESS mMemDebugLogBufAddr;
-BOOLEAN mMemDebugLogBufAddrInit;
-
EFI_STATUS
EFIAPI
MemDebugLogWrite (
@@ -21,23 +18,20 @@ MemDebugLogWrite ( IN UINTN Length
)
{
- EFI_STATUS Status;
-
- if (!mMemDebugLogBufAddrInit) {
- //
- // Obtain the Memory Debug Log buffer addr from HOB
- // NOTE: This is expected to fail until the HOB is created.
- //
- Status = MemDebugLogAddrFromHOB (&mMemDebugLogBufAddr);
- if (EFI_ERROR (Status)) {
- mMemDebugLogBufAddr = 0;
- } else {
- mMemDebugLogBufAddrInit = TRUE;
- }
+ EFI_PHYSICAL_ADDRESS MemDebugLogBufAddr;
+ EFI_STATUS Status;
+
+ //
+ // Obtain the Memory Debug Log buffer addr from HOB
+ // NOTE: This is expected to fail until the HOB is created.
+ //
+ Status = MemDebugLogAddrFromHOB (&MemDebugLogBufAddr);
+ if (EFI_ERROR (Status)) {
+ MemDebugLogBufAddr = 0;
}
- if (mMemDebugLogBufAddr) {
- Status = MemDebugLogWriteBuffer (mMemDebugLogBufAddr, Buffer, Length);
+ if (MemDebugLogBufAddr != 0) {
+ Status = MemDebugLogWriteBuffer (MemDebugLogBufAddr, Buffer, Length);
} else {
//
// HOB has not yet been created, so
diff --git a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf index 18f06e45b3..b6b407c891 100644 --- a/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf +++ b/OvmfPkg/Library/MemDebugLogLib/MemDebugLogPeiLib.inf @@ -29,11 +29,6 @@ [LibraryClasses]
SynchronizationLib
PcdLib
-
-[LibraryClasses.Ia32]
- QemuFwCfgSimpleParserLib
-
-[LibraryClasses.X64]
QemuFwCfgSimpleParserLib
[Guids]
diff --git a/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.c b/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.c new file mode 100644 index 0000000000..037174dc6a --- /dev/null +++ b/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.c @@ -0,0 +1,643 @@ +/** @file
+ This driver init default Secure Boot variables
+
+ Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
+ Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2021, Semihalf All rights reserved.<BR>
+ Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+ Copyright (C) 2023-2025 Advanced Micro Devices, Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <UefiSecureBoot.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/AuthenticatedVariableFormat.h>
+#include <Guid/ImageAuthentication.h>
+#include <Library/SecureBootVariableLib.h>
+#include <Library/SecureBootVariableProvisionLib.h>
+
+/**
+ Set PKDefault Variable.
+
+ @param[in] X509Data X509 Certificate data.
+ @param[in] X509DataSize X509 Certificate data size.
+
+ @retval EFI_SUCCESS PKDefault is set successfully.
+
+**/
+EFI_STATUS
+SetPkDefault (
+ IN UINT8 *X509Data,
+ IN UINTN X509DataSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Attr;
+ UINTN DataSize;
+ EFI_SIGNATURE_LIST *PkCert;
+ EFI_SIGNATURE_DATA *PkCertData;
+
+ PkCert = NULL;
+
+ //
+ // Allocate space for PK certificate list and initialize it.
+ // Create PK database entry with SignatureHeaderSize equals 0.
+ //
+ PkCert = (EFI_SIGNATURE_LIST *)AllocateZeroPool (
+ sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1
+ + X509DataSize
+ );
+ if (PkCert == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize PKDefault: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ PkCert->SignatureListSize = (UINT32)(sizeof (EFI_SIGNATURE_LIST)
+ + sizeof (EFI_SIGNATURE_DATA) - 1
+ + X509DataSize);
+ PkCert->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ PkCert->SignatureHeaderSize = 0;
+ CopyGuid (&PkCert->SignatureType, &gEfiCertX509Guid);
+ PkCertData = (EFI_SIGNATURE_DATA *)((UINTN)PkCert
+ + sizeof (EFI_SIGNATURE_LIST)
+ + PkCert->SignatureHeaderSize);
+ CopyGuid (&PkCertData->SignatureOwner, &gEfiGlobalVariableGuid);
+ //
+ // Fill the PK database with PKpub data from X509 certificate file.
+ //
+ CopyMem (&(PkCertData->SignatureData[0]), X509Data, X509DataSize);
+
+ Attr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ DataSize = PkCert->SignatureListSize;
+
+ Status = gRT->SetVariable (
+ EFI_PK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ DataSize,
+ PkCert
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize PKDefault: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (PkCert != NULL) {
+ FreePool (PkCert);
+ }
+
+ return Status;
+}
+
+/**
+ Set KDKDefault Variable.
+
+ @param[in] X509Data X509 Certificate data.
+ @param[in] X509DataSize X509 Certificate data size.
+
+ @retval EFI_SUCCESS KEKDefault is set successfully.
+
+**/
+EFI_STATUS
+SetKekDefault (
+ IN UINT8 *X509Data,
+ IN UINTN X509DataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_DATA *KEKSigData;
+ EFI_SIGNATURE_LIST *KekSigList;
+ UINTN DataSize;
+ UINTN KekSigListSize;
+ UINT32 Attr;
+
+ KekSigList = NULL;
+ KekSigListSize = 0;
+ DataSize = 0;
+ KEKSigData = NULL;
+
+ KekSigListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+ KekSigList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (KekSigListSize);
+ if (KekSigList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize KEKDefault: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ KekSigList->SignatureListSize = (UINT32)KekSigListSize;
+ KekSigList->SignatureHeaderSize = 0;
+ KekSigList->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&KekSigList->SignatureType, &gEfiCertX509Guid);
+
+ KEKSigData = (EFI_SIGNATURE_DATA *)((UINT8 *)KekSigList + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&KEKSigData->SignatureOwner, &gEfiGlobalVariableGuid);
+ CopyMem (KEKSigData->SignatureData, X509Data, X509DataSize);
+
+ //
+ // Check if KEK been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new kek to original variable
+ //
+ Attr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ Status = gRT->GetVariable (
+ EFI_KEK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot get the value of KEK: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable (
+ EFI_KEK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ KekSigListSize,
+ KekSigList
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize KEKDefault: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (KekSigList != NULL) {
+ FreePool (KekSigList);
+ }
+
+ return Status;
+}
+
+/**
+ Checks if the file content complies with EFI_VARIABLE_AUTHENTICATION_2 format
+
+ @param[in] Data Data.
+ @param[in] DataSize Data size.
+
+ @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 UINT8 *Data,
+ IN UINTN DataSize
+ )
+{
+ EFI_VARIABLE_AUTHENTICATION_2 *Auth2;
+ BOOLEAN IsAuth2Format;
+
+ IsAuth2Format = FALSE;
+
+ Auth2 = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;
+ if (Auth2->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) {
+ goto ON_EXIT;
+ }
+
+ if (CompareGuid (&gEfiCertPkcs7Guid, &Auth2->AuthInfo.CertType)) {
+ IsAuth2Format = TRUE;
+ }
+
+ON_EXIT:
+
+ return IsAuth2Format;
+}
+
+/**
+ Set signature database with the data of EFI_VARIABLE_AUTHENTICATION_2 format.
+
+ @param[in] AuthData AUTHENTICATION_2 data.
+ @param[in] AuthDataSize AUTHENTICATION_2 data size.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_DB_DEFAULT_VARIABLE_NAME or EFI_DBX_DEFAULT_VARIABLE_NAME or EFI_DBT_DEFAULT_VARIABLE_NAME.
+
+ @retval EFI_SUCCESS New signature is set 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
+SetAuthentication2ToSigDb (
+ IN UINT8 *AuthData,
+ IN UINTN AuthDataSize,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT32 Attr;
+ UINT8 *Data;
+
+ Attr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_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,
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot get the value of signature database: %r\n", __func__, Status));
+ return Status;
+ }
+
+ //
+ // Ignore AUTHENTICATION_2 region. Only the actual certificate is needed.
+ //
+ DataSize = AuthDataSize - ((EFI_VARIABLE_AUTHENTICATION_2 *)AuthData)->AuthInfo.Hdr.dwLength - sizeof (EFI_TIME);
+ Data = AuthData + (AuthDataSize - DataSize);
+
+ Status = gRT->SetVariable (
+ VariableName,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ DataSize,
+ Data
+ );
+
+ return Status;
+}
+
+/**
+
+ Set signature database with the data of X509 format.
+
+ @param[in] X509Data X509 Certificate data.
+ @param[in] X509DataSize X509 Certificate data size.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_DB_DEFAULT_VARIABLE_NAME or EFI_DBX_DEFAULT_VARIABLE_NAME or EFI_DBT_DEFAULT_VARIABLE_NAME.
+ @param[in] SignatureOwnerGuid Guid of the signature owner.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+SetX509ToSigDb (
+ IN UINT8 *X509Data,
+ IN UINTN X509DataSize,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *SignatureOwnerGuid
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *SigDBCert;
+ EFI_SIGNATURE_DATA *SigDBCertData;
+ VOID *Data;
+ UINTN DataSize;
+ UINTN SigDBSize;
+ UINT32 Attr;
+
+ SigDBSize = 0;
+ DataSize = 0;
+ SigDBCert = NULL;
+ SigDBCertData = NULL;
+ Data = NULL;
+
+ SigDBSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+ Data = AllocateZeroPool (SigDBSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a: Cannot allocate memory: %r\n", __func__, Status));
+ 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, SignatureOwnerGuid);
+ 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_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ Status = gRT->GetVariable (
+ VariableName,
+ &gEfiGlobalVariableGuid,
+ 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,
+ &gEfiGlobalVariableGuid,
+ Attr,
+ SigDBSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot set signature database: %r\n", __func__, Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ return Status;
+}
+
+/**
+
+ Set signature database.
+
+ @param[in] Data Data.
+ @param[in] DataSize Data size.
+ @param[in] VariableName Variable name of signature database, must be
+ EFI_DB_DEFAULT_VARIABLE_NAME or EFI_DBX_DEFAULT_VARIABLE_NAME or EFI_DBT_DEFAULT_VARIABLE_NAME.
+ @param[in] SignatureOwnerGuid Guid of the signature owner.
+
+ @retval EFI_SUCCESS Signature is set successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+SetSignatureDatabase (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *SignatureOwnerGuid
+ )
+{
+ if (IsAuthentication2Format (Data, DataSize)) {
+ return SetAuthentication2ToSigDb (Data, DataSize, VariableName);
+ } else {
+ return SetX509ToSigDb (Data, DataSize, VariableName, SignatureOwnerGuid);
+ }
+}
+
+/** Initializes PKDefault variable with data from FFS section.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+**/
+EFI_STATUS
+InitPkDefault (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_PK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_PK_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Variable does not exist, can be initialized
+ //
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_PK_DEFAULT_VARIABLE_NAME));
+
+ //
+ // Enroll default PK.
+ //
+ Status = GetSectionFromFv (
+ &gDefaultPKFileGuid,
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (!EFI_ERROR (Status)) {
+ SetPkDefault (Data, DataSize);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Initializes KEKDefault variable with data from FFS section.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+**/
+EFI_STATUS
+InitKekDefault (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_KEK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ Index = 0;
+ do {
+ Status = GetSectionFromFv (
+ &gDefaultKEKFileGuid,
+ EFI_SECTION_RAW,
+ Index,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (!EFI_ERROR (Status)) {
+ SetKekDefault (Data, DataSize);
+ Index++;
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_SUCCESS;
+}
+
+/** Initializes dbDefault variable with data from FFS section.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+**/
+EFI_STATUS
+InitDbDefault (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ Status = GetVariable2 (EFI_DB_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DB_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DB_DEFAULT_VARIABLE_NAME));
+
+ Index = 0;
+ do {
+ Status = GetSectionFromFv (
+ &gDefaultdbFileGuid,
+ EFI_SECTION_RAW,
+ Index,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (!EFI_ERROR (Status)) {
+ SetSignatureDatabase (Data, DataSize, EFI_DB_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid);
+ Index++;
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_SUCCESS;
+}
+
+/** Initializes dbxDefault variable with data from FFS section.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+**/
+EFI_STATUS
+InitDbxDefault (
+ IN VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_DBX_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Variable does not exist, can be initialized
+ //
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
+
+ Index = 0;
+ do {
+ Status = GetSectionFromFv (
+ &gDefaultdbxFileGuid,
+ EFI_SECTION_RAW,
+ Index,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (!EFI_ERROR (Status)) {
+ SetSignatureDatabase (Data, DataSize, EFI_DBX_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid);
+ Index++;
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes default SecureBoot certificates with data from FFS section.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+**/
+EFI_STATUS
+EFIAPI
+SecureBootDefaultKeysInitEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = InitPkDefault ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize PKDefault: %r\n", __func__, Status));
+ return Status;
+ }
+
+ Status = InitKekDefault ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize KEKDefault: %r\n", __func__, Status));
+ return Status;
+ }
+
+ Status = InitDbDefault ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize dbDefault: %r\n", __func__, Status));
+ return Status;
+ }
+
+ Status = InitDbxDefault ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Cannot initialize dbxDefault: %r\n", __func__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf b/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf new file mode 100644 index 0000000000..0127841733 --- /dev/null +++ b/OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf @@ -0,0 +1,49 @@ +## @file
+# Initializes Secure Boot default keys
+#
+# Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2021, Semihalf All rights reserved.<BR>
+# Copyright (C) 2023-2025 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = SecureBootDefaultKeysInit
+ FILE_GUID = 384D1860-7306-11F0-B8B4-F53A5CB787AC
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SecureBootDefaultKeysInitEntry
+
+[Sources]
+ SecureBootDefaultKeysInit.c
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ DxeServicesLib
+ SecureBootVariableLib
+ SecureBootVariableProvisionLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Guids]
+ gDefaultdbFileGuid
+ gDefaultdbxFileGuid
+ gDefaultKEKFileGuid
+ gDefaultPKFileGuid
+ gEfiCertPkcs7Guid
+ gEfiCertX509Guid
+ gEfiCustomModeEnableGuid
+ gEfiImageSecurityDatabaseGuid
+ gEfiSecureBootEnableDisableGuid
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c index 54b5d33613..3da71aa51b 100644 --- a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c +++ b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.c @@ -1,6 +1,7 @@ /** @file
- Copyright (c) 2011, ARM Limited. All rights reserved.<BR>
+ Copyright (c) 2011-2014, ARM Limited. All rights reserved.<BR>
+ Copyright (c) 2014-2020, Linaro Limited. All rights reserved.<BR>
Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -45,6 +46,12 @@ CONST EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = { NULL
};
+CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gOvmfTpmDiscoveredPpiGuid,
+ NULL
+};
+
/*
Install PEI memory.
@@ -89,6 +96,126 @@ FindInstallPeiMemory ( ASSERT_EFI_ERROR (PeiServicesInstallPeiMemory (PeiMemoryBase, PEI_MEMORY_SIZE));
}
+/**
+ Set up TPM resources from FDT.
+
+ @param FdtBase Fdt base address
+
+**/
+STATIC
+VOID
+SetupTPMResources (
+ VOID *FdtBase
+ )
+{
+ INT32 Node, Prev;
+ INT32 Parent, Depth;
+ CONST CHAR8 *Compatible;
+ CONST CHAR8 *CompItem;
+ INT32 Len;
+ INT32 RangesLen;
+ CONST UINT8 *RegProp;
+ CONST UINT32 *RangesProp;
+ UINT64 TpmBase;
+ UINT64 TpmBaseSize;
+
+ //
+ // Set Parent to suppress incorrect compiler/analyzer warnings.
+ //
+ Parent = 0;
+
+ for (Prev = Depth = 0; ; Prev = Node) {
+ Node = FdtNextNode (FdtBase, Prev, &Depth);
+ if (Node < 0) {
+ break;
+ }
+
+ if (Depth == 1) {
+ Parent = Node;
+ }
+
+ Compatible = FdtGetProp (FdtBase, Node, "compatible", &Len);
+
+ //
+ // Iterate over the NULL-separated items in the compatible string
+ //
+ for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
+ CompItem += 1 + AsciiStrLen (CompItem))
+ {
+ if (AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0) {
+ RegProp = FdtGetProp (FdtBase, Node, "reg", &Len);
+ ASSERT (Len == 8 || Len == 16);
+ if (Len == 8) {
+ TpmBase = Fdt32ToCpu (*(UINT32 *)RegProp);
+ TpmBaseSize = Fdt32ToCpu (*(UINT32 *)((UINT8 *)RegProp + 4));
+ } else if (Len == 16) {
+ TpmBase = Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RegProp));
+ TpmBaseSize = Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)((UINT8 *)RegProp + 8)));
+ }
+
+ if (Depth > 1) {
+ //
+ // QEMU/mach-virt may put the TPM on the platform bus, in which case
+ // we have to take its 'ranges' property into account to translate the
+ // MMIO address. This consists of a <child base, parent base, size>
+ // tuple, where the child base and the size use the same number of
+ // cells as the 'reg' property above, and the parent base uses 2 cells
+ //
+ RangesProp = FdtGetProp (FdtBase, Parent, "ranges", &RangesLen);
+ ASSERT (RangesProp != NULL);
+
+ //
+ // a plain 'ranges' attribute without a value implies a 1:1 mapping
+ //
+ if (RangesLen != 0) {
+ //
+ // assume a single translated range with 2 cells for the parent base
+ //
+ if (RangesLen != Len + 2 * sizeof (UINT32)) {
+ DEBUG ((
+ DEBUG_WARN,
+ "%a: 'ranges' property has unexpected size %d\n",
+ __func__,
+ RangesLen
+ ));
+ break;
+ }
+
+ if (Len == 8) {
+ TpmBase -= Fdt32ToCpu (RangesProp[0]);
+ } else {
+ TpmBase -= Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RangesProp));
+ }
+
+ //
+ // advance RangesProp to the parent bus address
+ //
+ RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2);
+ TpmBase += Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RangesProp));
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (TpmBase) {
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ TpmBase,
+ ALIGN_VALUE (TpmBaseSize, EFI_PAGE_SIZE)
+ );
+
+ ASSERT_EFI_ERROR ((EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase));
+ PeiServicesInstallPpi (&mTpm2DiscoveredPpi);
+ }
+}
+
/*
Entry point of this module.
@@ -125,6 +252,7 @@ InitializePlatformPeim ( MemoryInitialization (SecData->FdtPointer);
CpuInitialization (SecData->FdtPointer);
PlatformInitialization (SecData->FdtPointer);
+ SetupTPMResources (SecData->FdtPointer);
//
// Install PEI memory
diff --git a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf index 9be96dd3de..6ca005bec9 100644 --- a/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf +++ b/OvmfPkg/RiscVVirt/PlatformPei/PlatformPeim.inf @@ -25,17 +25,24 @@ MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
OvmfPkg/OvmfPkg.dec
+ SecurityPkg/SecurityPkg.dec
[LibraryClasses]
PeimEntryPoint
DebugLib
+ FdtLib
HobLib
+ PcdLib
PeiServicesLib
PlatformSecLib
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
+
[Ppis]
gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED
gEfiSecHobDataPpiGuid # ALWAYS_CONSUMED
+ gOvmfTpmDiscoveredPpiGuid # SOMETIMES_PRODUCES
[Depex]
TRUE
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc index bc4935ec2b..c23130a72d 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc +++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc @@ -193,13 +193,14 @@ [PcdsFixedAtBuild.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
-!if $(NETWORK_TLS_ENABLE) == TRUE
+!if $(NETWORK_TLS_ENABLE) == TRUE || $(SECURE_BOOT_ENABLE) == TRUE
#
# The cumulative and individual VOLATILE variable size limits should be set
# high enough for accommodating several and/or large CA certificates.
#
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"2.7"
@@ -290,6 +291,8 @@ [LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
!if $(TPM2_ENABLE) == TRUE
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
!else
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
!endif
@@ -317,6 +320,24 @@ <LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
}
+!if $(TPM2_ENABLE) == TRUE
+ OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
+ SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
+ <LibraryClasses>
+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.inf
+ NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
+ HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
+ NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
+ }
+ SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf {
+ <LibraryClasses>
+ TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf
+ }
+!endif
!else
UefiCpuPkg/SecCore/SecCoreNative.inf {
<LibraryClasses>
@@ -370,7 +391,7 @@ !endif
}
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
- OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
+ OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf
!else
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
!endif
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf index 3470b18a2e..1f37eb6894 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf +++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.fdf @@ -89,6 +89,24 @@ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf !endif
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+ INF OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootDefaultKeysInit/SecureBootDefaultKeysInit.inf
+
+ FILE FREEFORM = 85254ea7-4759-4fc4-82d4-5eed5fb0a4a0 {
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/PK/PK.cer
+ }
+
+ FILE FREEFORM = 6f64916e-9f7a-4c35-b952-cd041efb05a3 {
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/KEK/MicCorKEKCA2011_2011-06-24.crt
+ }
+
+ FILE FREEFORM = c491d352-7623-4843-accc-2791a7574421 {
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/db/MicWinProPCA2011_2011-10-19.crt
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/db/MicCorUEFCA2011_2011-06-27.crt
+ }
+
+ FILE FREEFORM = 5740766a-718e-4dc0-9935-c36f7d3f884f {
+ SECTION RAW = OvmfPkg/RiscVVirt/Feature/SecureBoot/SecureBootKeys/dbx/dbxupdate_x64.bin
+ }
!endif
INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
@@ -212,6 +230,16 @@ INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
#
+# TPM2 support
+#
+!if $(TPM2_ENABLE) == TRUE
+ INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+!if $(TPM2_CONFIG_ENABLE) == TRUE
+ INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
+!endif
+!endif
+
+#
# TianoCore logo (splash screen)
#
INF MdeModulePkg/Logo/LogoDxe.inf
diff --git a/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf index 51078c9813..0355df9609 100644 --- a/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf +++ b/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf @@ -52,3 +52,6 @@ [Depex.ARM, Depex.AARCH64]
gOvmfTpmDiscoveredPpiGuid
+
+[Depex.RISCV64]
+ gOvmfTpmDiscoveredPpiGuid
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c index f759df900b..c6a9804834 100644 --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c @@ -542,8 +542,19 @@ OneOfStatementToAttributeValues ( }
if (Option->Text != 0) {
- Values->ValueArray[Index].ValueName = HiiGetRedfishAsciiString (HiiHandle, SchemaName, Option->Text);
Values->ValueArray[Index].ValueDisplayName = HiiGetEnglishAsciiString (HiiHandle, Option->Text);
+ Values->ValueArray[Index].ValueName = HiiGetRedfishAsciiString (HiiHandle, SchemaName, Option->Text);
+ if (Values->ValueArray[Index].ValueName == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Redfish x-UEFI string is not found.\n", __func__));
+ //
+ // No x-UEFI-redfish string defined. Try to get string in English.
+ //
+ Values->ValueArray[Index].ValueName =
+ AllocateCopyPool (AsciiStrSize (Values->ValueArray[Index].ValueDisplayName), (VOID *)Values->ValueArray[Index].ValueDisplayName);
+ if (Values->ValueArray[Index].ValueName == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Both Redfish and English string are not found.\n", __func__));
+ }
+ }
}
Index += 1;
@@ -1309,8 +1320,16 @@ HiiValueToRedfishValue ( RedfishValue->Value.Buffer = HiiGetRedfishAsciiString (HiiHandle, FullSchema, StringId);
if (RedfishValue->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- break;
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Redfish x-UEFI string is not found.\n", __func__));
+ //
+ // No x-UEFI-redfish string defined. Try to get string in English.
+ //
+ RedfishValue->Value.Buffer = HiiGetEnglishAsciiString (HiiHandle, StringId);
+ if (RedfishValue->Value.Buffer == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Both Redfish and English string are not found.\n", __func__));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
}
RedfishValue->Type = RedfishValueTypeString;
@@ -1399,6 +1418,18 @@ HiiValueToRedfishValue ( }
RedfishValue->Value.StringArray[Index] = HiiGetRedfishAsciiString (HiiHandle, FullSchema, StringIdArray[Index]);
+ if (RedfishValue->Value.StringArray[Index] == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Redfish x-UEFI string is not found.\n", __func__));
+ //
+ // No x-UEFI-redfish string defined. Try to get string in English.
+ //
+ RedfishValue->Value.StringArray[Index] = HiiGetEnglishAsciiString (HiiHandle, StringIdArray[Index]);
+ if (RedfishValue->Value.StringArray[Index] == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Both Redfish and English string are not found.\n", __func__));
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+
ASSERT (RedfishValue->Value.StringArray[Index] != NULL);
}
@@ -1418,6 +1449,7 @@ HiiValueToRedfishValue ( RedfishValue->Value.Buffer = HiiGetRedfishAsciiString (HiiHandle, FullSchema, HiiStatement->ExtraData.TextTwo);
if (RedfishValue->Value.Buffer == NULL) {
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Redfish x-UEFI string is not found.\n", __func__));
//
// No x-UEFI-redfish string defined. Try to get string in English.
//
@@ -1666,7 +1698,7 @@ RedfishPlatformConfigProtocolGetValue ( goto RELEASE_RESOURCE;
}
- if (TargetStatement->Suppressed) {
+ if (TargetStatement->Suppressed && !RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED)) {
Status = EFI_ACCESS_DENIED;
goto RELEASE_RESOURCE;
}
@@ -2289,7 +2321,7 @@ RedfishPlatformConfigProtocolGetDefaultValue ( goto RELEASE_RESOURCE;
}
- if (TargetStatement->Suppressed) {
+ if (TargetStatement->Suppressed && !RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED)) {
Status = EFI_ACCESS_DENIED;
goto RELEASE_RESOURCE;
}
diff --git a/SecurityPkg/FvReportPei/FvReportPei.c b/SecurityPkg/FvReportPei/FvReportPei.c index 50773db056..6c92e7379d 100644 --- a/SecurityPkg/FvReportPei/FvReportPei.c +++ b/SecurityPkg/FvReportPei/FvReportPei.c @@ -343,17 +343,38 @@ GetHashInfo ( }
/**
- Verify and report pre-hashed FVs.
+ Verifies and reports pre-hashed Firmware Volumes (FVs).
- Doing this must be at post-memory to make sure there's enough memory to hold
- all FVs to be verified. This is necessary for mitigating TOCTOU issue.
+ This function should be called after memory initialization (post-memory phase)
+ to ensure sufficient memory is available to hold all FVs for verification.
- This function will never return if the verification is failed.
+ Verifying FVs at this stage is critical to mitigate Time-of-Check to Time-of-Use (TOCTOU) vulnerabilities.
+
+ FV Verification Step:
+
+ This function relies upon an instance of gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid being installed. If
+ an instance of the PPI is not found, EFI_NOT_FOUND is returned.
+
+ If the gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid PPI instance does not have valid hash information for the
+ current boot mode (hash info is NULL), verification is treated as successful.
+
+ FV Reporting Step:
+
+ If FV verification is successful, the function reports the FVs to PEI and/or DXE core for further processing by:
+
+ 1. Installing a FV HOB.
+ 2. Installing a FV Info PPI.
+ 3. Reporting a status code with the value from PcdStatusCodeFvVerificationPass to indicate that FV verification
+ passed.
+
+ If FV verification fails, the function reports a status code with the value from PcdStatusCodeFvVerificationFail
+ and returns a failure status code.
@param[in] PeiServices General purpose services available to every PEIM.
@param[in] BootMode Current boot mode.
@retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND No valid gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid PPI instance found.
**/
STATIC
EFI_STATUS
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c index f11f7696b1..7ca892735b 100644 --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c @@ -229,6 +229,7 @@ Tpm2NvReadPublic ( case TPM_RC_SUCCESS:
// return data
break;
+ case TPM_RC_HANDLE:
case TPM_RC_HANDLE + RC_NV_ReadPublic_nvIndex: // TPM_RC_NV_DEFINED:
return EFI_NOT_FOUND;
case TPM_RC_VALUE + RC_NV_ReadPublic_nvIndex:
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c index 080e229c40..bb07200754 100644 --- a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c +++ b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c @@ -8,6 +8,7 @@ **/
#include <Uefi.h>
+#include <Guid/RiscVSecHobData.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
@@ -16,9 +17,12 @@ #include <Pi/PiHob.h>
#include <Library/HobLib.h>
#include <Library/FdtLib.h>
+#include <Library/TimerLib.h>
STATIC UINT64 mTimeBase;
+#define GET_TIME_BASE() (mTimeBase ?: GetPerformanceCounterProperties(NULL, NULL))
+
/**
Stalls the CPU for at least the given number of ticks.
@@ -63,7 +67,7 @@ MicroSecondDelay ( DivU64x32 (
MultU64x32 (
MicroSeconds,
- mTimeBase
+ GET_TIME_BASE ()
),
1000000u
)
@@ -91,7 +95,7 @@ NanoSecondDelay ( DivU64x32 (
MultU64x32 (
NanoSeconds,
- mTimeBase
+ GET_TIME_BASE ()
),
1000000000u
)
@@ -150,6 +154,12 @@ GetPerformanceCounterProperties ( OUT UINT64 *EndValue OPTIONAL
)
{
+ VOID *Hob;
+ RISCV_SEC_HANDOFF_DATA *SecData;
+ CONST EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID;
+ UINT64 TimeBase;
+ CONST VOID *FdtBase;
+
if (StartValue != NULL) {
*StartValue = 0;
}
@@ -165,20 +175,27 @@ GetPerformanceCounterProperties ( //
// Locate the FDT HOB and validate header
//
- CONST EFI_HOB_GUID_TYPE *Hob = GetFirstGuidHob (&gFdtHobGuid);
-
- ASSERT (Hob != NULL);
-
- CONST VOID *DeviceTreeBase =
- (CONST VOID *)(UINTN)*(CONST UINT64 *)GET_GUID_HOB_DATA (Hob);
+ Hob = GetFirstGuidHob (&gFdtHobGuid);
+ if (Hob) {
+ FdtBase = (CONST VOID *)(UINTN)*(CONST UINT64 *)GET_GUID_HOB_DATA (Hob);
+ } else {
+ //
+ // Get the FDT address from the SEC HOB
+ //
+ Hob = GetFirstGuidHob (&SecHobDataGuid);
+ ASSERT (Hob != NULL);
+ SecData = (RISCV_SEC_HANDOFF_DATA *)GET_GUID_HOB_DATA (Hob);
+ FdtBase = (CONST VOID *)SecData->FdtPointer;
+ }
- ASSERT (FdtCheckHeader (DeviceTreeBase) == 0);
+ ASSERT (FdtBase != NULL);
+ ASSERT (FdtCheckHeader ((VOID *)(UINTN)FdtBase) == 0);
//
// /cpus node
//
INT32 Node = FdtSubnodeOffsetNameLen (
- DeviceTreeBase,
+ FdtBase,
0,
"cpus",
sizeof ("cpus") - 1
@@ -191,15 +208,23 @@ GetPerformanceCounterProperties ( //
INT32 Len;
CONST FDT_PROPERTY *Prop =
- FdtGetProperty (DeviceTreeBase, Node, "timebase-frequency", &Len);
+ FdtGetProperty (FdtBase, Node, "timebase-frequency", &Len);
ASSERT (Prop != NULL && Len == sizeof (UINT32));
//
// Device-tree cells are big-endian
//
- mTimeBase = SwapBytes32 (*(CONST UINT32 *)Prop->Data);
- return mTimeBase;
+ TimeBase = SwapBytes32 (*(CONST UINT32 *)Prop->Data);
+ ASSERT (TimeBase != 0);
+
+ //
+ // Save the time base for later use. Note that the mTimeBase maybe zero if
+ // this library is stored in read-only memory.
+ //
+ mTimeBase = TimeBase;
+
+ return TimeBase;
}
/**
@@ -227,13 +252,13 @@ GetTimeInNanoSecond ( // Time = --------- x 1,000,000,000
// Frequency
//
- NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, mTimeBase, &Remainder), 1000000000u);
+ NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, GET_TIME_BASE (), &Remainder), 1000000000u);
//
// Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
// will not overflow 64-bit.
//
- NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), mTimeBase);
+ NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), GET_TIME_BASE ());
return NanoSeconds;
}
diff --git a/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.c b/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.c index 215bc60f77..866ca70394 100644 --- a/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.c +++ b/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.c @@ -29,6 +29,9 @@ BlDxeEntryPoint ( EFI_HOB_GUID_TYPE *GuidHob;
EFI_PEI_GRAPHICS_INFO_HOB *GfxInfo;
ACPI_BOARD_INFO *AcpiBoardInfo;
+ FIRMWARE_INFO *FirmwareInfo;
+ EFI_SYSTEM_RESOURCE_TABLE *Esrt;
+ EFI_SYSTEM_RESOURCE_ENTRY *Esre;
//
// Find the frame buffer information and update PCDs
@@ -61,5 +64,30 @@ BlDxeEntryPoint ( Status = BlArchAdditionalOps (ImageHandle, SystemTable);
ASSERT_EFI_ERROR (Status);
+ //
+ // Build and publish a single-entry ESRT if a bootloader provided us with
+ // details about currently running firmware
+ //
+ GuidHob = GetFirstGuidHob (&gEfiFirmwareInfoHobGuid);
+ if (GuidHob != NULL) {
+ FirmwareInfo = (FIRMWARE_INFO *)GET_GUID_HOB_DATA (GuidHob);
+
+ Esrt = AllocateZeroPool (sizeof (EFI_SYSTEM_RESOURCE_TABLE) + sizeof (EFI_SYSTEM_RESOURCE_ENTRY));
+ ASSERT (Esrt != NULL);
+
+ Esrt->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;
+ Esrt->FwResourceCount = 1;
+ Esrt->FwResourceCountMax = 1;
+
+ Esre = (EFI_SYSTEM_RESOURCE_ENTRY *)&Esrt[1];
+ CopyMem (&Esre->FwClass, &FirmwareInfo->Type, sizeof (EFI_GUID));
+ Esre->FwType = ESRT_FW_TYPE_SYSTEMFIRMWARE;
+ Esre->FwVersion = FirmwareInfo->Version;
+ Esre->LowestSupportedFwVersion = FirmwareInfo->LowestSupportedVersion;
+
+ Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, Esrt);
+ ASSERT_EFI_ERROR (Status);
+ }
+
return EFI_SUCCESS;
}
diff --git a/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.h b/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.h index 5f611c3713..2a235475f2 100644 --- a/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.h +++ b/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.h @@ -16,8 +16,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include <Library/BaseMemoryLib.h>
#include <Library/IoLib.h>
#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Guid/SystemResourceTable.h>
#include <Guid/AcpiBoardInfoGuid.h>
+#include <Guid/FirmwareInfoGuid.h>
#include <Guid/GraphicsInfoHob.h>
EFI_STATUS
diff --git a/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf b/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf index 401b99f9b6..c1fe073634 100644 --- a/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf +++ b/UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf @@ -45,13 +45,16 @@ DebugLib
BaseMemoryLib
HobLib
+ MemoryAllocationLib
[LibraryClasses.AARCH64]
ArmMmuLib
[Guids]
gUefiAcpiBoardInfoGuid
+ gEfiFirmwareInfoHobGuid
gEfiGraphicsInfoHobGuid
+ gEfiSystemResourceTableGuid
[Protocols]
gEfiCpuArchProtocolGuid
diff --git a/UefiPayloadPkg/Include/Coreboot.h b/UefiPayloadPkg/Include/Coreboot.h index 1b05f15fe5..4d0d2cc1e4 100644 --- a/UefiPayloadPkg/Include/Coreboot.h +++ b/UefiPayloadPkg/Include/Coreboot.h @@ -263,6 +263,34 @@ struct cb_smmstorev2 { UINT8 unused[3]; /* Set to zero */
} __attribute__ ((packed));
+/*
+ * Machine-friendly version of a system firmware component. A component is
+ * identified by a GUID. coreboot is an obvious main component but there could
+ * be others (like EC) which should get their own instances of the tag.
+ *
+ * The main consumer of this information is UEFI firmware but something else
+ * could reuse it too.
+ *
+ * Larger number in a version field corresponds to a more recent version.
+ */
+#define CB_TAG_FW_INFO 0x0045
+struct lb_efi_fw_info {
+ UINT32 tag;
+ UINT32 size;
+ UINT8 guid[16]; /* Called "firmware class" in UEFI */
+ UINT32 version; /* Current version */
+ UINT32 lowest_supported_version; /* Lowest allowed version */
+ UINT32 fw_size; /* Size of firmware in bytes */
+} __attribute__ ((packed));
+
+#define CB_TAG_CAPSULE 0x0046
+struct cb_range {
+ UINT32 tag;
+ UINT32 size;
+ UINT64 range_start;
+ UINT32 range_size;
+} __attribute__ ((packed));
+
/* Helpful macros */
#define MEM_RANGE_COUNT(_rec) \
diff --git a/UefiPayloadPkg/Include/Guid/FirmwareInfoGuid.h b/UefiPayloadPkg/Include/Guid/FirmwareInfoGuid.h new file mode 100644 index 0000000000..fa1d0649e2 --- /dev/null +++ b/UefiPayloadPkg/Include/Guid/FirmwareInfoGuid.h @@ -0,0 +1,26 @@ +/** @file
+ This file defines the hob structure for firmware related information from a
+ bootloader
+
+ Copyright (c) 2025, 3mdeb Sp. z o.o.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FIRMWARE_INFO_GUID_H_
+#define FIRMWARE_INFO_GUID_H_
+
+///
+/// Firmware information GUID
+///
+extern EFI_GUID gEfiFirmwareInfoHobGuid;
+
+typedef struct {
+ EFI_GUID Type;
+ CHAR8 VersionStr[64];
+ UINT32 Version;
+ UINT32 LowestSupportedVersion;
+ UINT32 ImageSize;
+} FIRMWARE_INFO;
+
+#endif // FIRMWARE_INFO_GUID_H_
diff --git a/UefiPayloadPkg/Include/Library/BlParseLib.h b/UefiPayloadPkg/Include/Library/BlParseLib.h index 82be5a9eb8..e86f03f2b6 100644 --- a/UefiPayloadPkg/Include/Library/BlParseLib.h +++ b/UefiPayloadPkg/Include/Library/BlParseLib.h @@ -15,6 +15,7 @@ #include <Guid/MemoryMapInfoGuid.h>
#include <Guid/SerialPortInfoGuid.h>
#include <Guid/AcpiBoardInfoGuid.h>
+#include <Guid/FirmwareInfoGuid.h>
#include <UniversalPayload/AcpiTable.h>
#include <UniversalPayload/SmbiosTable.h>
@@ -26,6 +27,12 @@ typedef RETURN_STATUS \ VOID *Param
);
+typedef VOID \
+(*BL_CAPSULE_CALLBACK) (
+ EFI_PHYSICAL_ADDRESS BaseAddress,
+ UINT64 Length
+ );
+
/**
This function retrieves the parameter base address from boot loader.
@@ -148,4 +155,33 @@ ParseMiscInfo ( VOID
);
+/**
+ Parse firmware information passed in by bootloader
+
+ @param FwInfo Information about current firmware.
+
+ @retval RETURN_INVALID_PARAMETER The parameter is NULL.
+ @retval RETURN_SUCCESS Successfully parsed information.
+ @retval RETURN_NOT_FOUND The information is missing.
+**/
+RETURN_STATUS
+EFIAPI
+ParseFirmwareInfo (
+ OUT FIRMWARE_INFO *FwInfo
+ );
+
+/**
+ Parse update capsules passed in by bootloader
+
+ @param CapsuleCallback The callback routine invoked for each capsule.
+
+ @retval RETURN_SUCCESS Successfully parsed capsules.
+ @retval RETURN_NOT_FOUND Failed to look up the information.
+**/
+RETURN_STATUS
+EFIAPI
+ParseCapsules (
+ IN BL_CAPSULE_CALLBACK CapsuleCallback
+ );
+
#endif
diff --git a/UefiPayloadPkg/Include/Library/SmmStoreLib.h b/UefiPayloadPkg/Include/Library/SmmStoreLib.h index bf0b8a01b8..13b51ee63c 100644 --- a/UefiPayloadPkg/Include/Library/SmmStoreLib.h +++ b/UefiPayloadPkg/Include/Library/SmmStoreLib.h @@ -1,6 +1,7 @@ /** @file SmmStoreLib.h
Copyright (c) 2022, 9elements GmbH<BR>
+ Copyright (c) 2025, 3mdeb Sp. z o.o.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -67,6 +68,25 @@ SmmStoreLibRead ( );
/**
+ Read from an arbitrary flash location. The whole flash is represented as a
+ sequence of blocks.
+
+ @param[in] Lba The starting logical block index to read from.
+ @param[in] Offset Offset into the block at which to begin reading.
+ @param[in] NumBytes On input, indicates the requested read size. On
+ output, indicates the actual number of bytes read
+ @param[in] Buffer Pointer to the buffer to read into.
+
+**/
+EFI_STATUS
+SmmStoreLibReadAnyBlock (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+/**
Write to SmmStore
@param[in] Lba The starting logical block index to write to.
@@ -85,6 +105,25 @@ SmmStoreLibWrite ( );
/**
+ Write to an arbitrary flash location. The whole flash is represented as a
+ sequence of blocks.
+
+ @param[in] Lba The starting logical block index to write to.
+ @param[in] Offset Offset into the block at which to begin writing.
+ @param[in] NumBytes On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written
+ @param[in] Buffer Pointer to the data to write.
+
+**/
+EFI_STATUS
+SmmStoreLibWriteAnyBlock (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+/**
Erase a block using the SmmStore
@param Lba The logical block index to erase.
@@ -96,6 +135,18 @@ SmmStoreLibEraseBlock ( );
/**
+ Erase an arbitrary block of the flash. The whole flash is represented as a
+ sequence of blocks.
+
+ @param Lba The logical block index to erase.
+
+**/
+EFI_STATUS
+SmmStoreLibEraseAnyBlock (
+ IN EFI_LBA Lba
+ );
+
+/**
Function to update a pointer on virtual address change. Matches the signature
and operation of EfiConvertPointer.
diff --git a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c index d7282e07b0..0f6d1d506f 100644 --- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -14,6 +14,7 @@ #include <Library/PcdLib.h>
#include <Library/IoLib.h>
#include <Library/BlParseLib.h>
+#include <Library/PrintLib.h>
#include <Library/SmmStoreParseLib.h>
#include <IndustryStandard/Acpi.h>
#include <Coreboot.h>
@@ -638,3 +639,114 @@ ParseSmmStoreInfo ( return RETURN_SUCCESS;
}
+
+/**
+ Parse information in a string form identified by a number
+
+ @param Id String identifier.
+
+ @retval NULL The requested information wasn't found.
+ @retval Otherwise A pointer to a static string.
+**/
+STATIC
+CONST CHAR8 *
+EFIAPI
+ParseInfoString (
+ IN UINTN Id
+ )
+{
+ struct cb_string *CbString;
+
+ CbString = FindCbTag (Id);
+ if (CbString == NULL) {
+ return NULL;
+ }
+
+ return (CONST CHAR8 *)CbString->string;
+}
+
+/**
+ Parse firmware information passed in by bootloader
+
+ @param FwInfo Information about current firmware.
+
+ @retval RETURN_INVALID_PARAMETER The parameter is NULL.
+ @retval RETURN_SUCCESS Successfully parsed information.
+ @retval RETURN_NOT_FOUND The information is missing.
+**/
+RETURN_STATUS
+EFIAPI
+ParseFirmwareInfo (
+ OUT FIRMWARE_INFO *FwInfo
+ )
+{
+ CONST CHAR8 *Version;
+ CONST CHAR8 *ExtraVersion;
+ struct lb_efi_fw_info *Info;
+
+ if (FwInfo == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ Info = FindCbTag (CB_TAG_FW_INFO);
+ if (Info == NULL) {
+ return RETURN_NOT_FOUND;
+ }
+
+ Version = ParseInfoString (CB_TAG_VERSION);
+ ExtraVersion = ParseInfoString (CB_TAG_EXTRA_VERSION);
+
+ /* No big deal if these aren't available. */
+ if ((Version == NULL) && (ExtraVersion == NULL)) {
+ Version = "coreboot+EDK2 (unknown version)";
+ ExtraVersion = "";
+ } else if (Version == NULL) {
+ Version = "";
+ } else if (ExtraVersion == NULL) {
+ ExtraVersion = "";
+ }
+
+ CopyMem (&FwInfo->Type, &Info->guid, sizeof (FwInfo->Type));
+ FwInfo->Version = Info->version;
+ FwInfo->LowestSupportedVersion = Info->lowest_supported_version;
+ FwInfo->ImageSize = Info->fw_size;
+ AsciiSPrint (FwInfo->VersionStr, sizeof (FwInfo->VersionStr), "%a%a", Version, ExtraVersion);
+ return RETURN_SUCCESS;
+}
+
+/**
+ Parse update capsules passed in by bootloader
+
+ @param CapsuleCallback The callback routine invoked for each capsule.
+
+ @retval RETURN_SUCCESS Successfully parsed capsules.
+ @retval RETURN_NOT_FOUND Failed to look up the information.
+**/
+RETURN_STATUS
+EFIAPI
+ParseCapsules (
+ IN BL_CAPSULE_CALLBACK CapsuleCallback
+ )
+{
+ struct cb_header *Header;
+ struct cb_range *Range;
+ UINT8 *TmpPtr;
+ UINTN Idx;
+
+ Header = GetParameterBase ();
+ if (Header == NULL) {
+ return RETURN_NOT_FOUND;
+ }
+
+ TmpPtr = (UINT8 *)Header + Header->header_bytes;
+ for (Idx = 0; Idx < Header->table_entries; Idx++) {
+ Range = (struct cb_range *)TmpPtr;
+ if (Range->tag == CB_TAG_CAPSULE) {
+ CapsuleCallback (Range->range_start, Range->range_size);
+ }
+
+ TmpPtr += Range->size;
+ }
+
+ return RETURN_SUCCESS;
+}
diff --git a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf index cf81697703..7be238c850 100644 --- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf +++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf @@ -34,6 +34,7 @@ IoLib
DebugLib
PcdLib
+ PrintLib
[Pcd]
gUefiPayloadPkgTokenSpaceGuid.PcdBootloaderParameter
diff --git a/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.c b/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.c new file mode 100644 index 0000000000..ff85401ef0 --- /dev/null +++ b/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.c @@ -0,0 +1,1143 @@ +/** @file
+ Provides firmware device specific services to support updates of a firmware
+ image stored in a firmware device.
+
+ This implementation uses SmmStoreLib to update the whole flash chip. For
+ this to work correctly Intel ME or an equivalent need to be disabled and all
+ flash chip protections need to be lifted (rather, not applied) if coreboot
+ finds any capsules during initialization. It is done to allow updating ME or
+ changing chip's layout in a new firmware (e.g., to allocate more space for
+ the BIOS region). In the future, this can be made more flexible, say, by
+ parsing coreboot's FMAP and only updating some regions. Such functionality
+ probably need embedding more knowledge about specific firmware image via a
+ new library to be customized for specific use-cases.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2025, 3mdeb Sp. z o.o. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <Guid/FirmwareInfoGuid.h>
+#include <Guid/SystemResourceTable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FmpDeviceLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SmmStoreLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Coreboot.h>
+
+/**
+ This function requests firmware information on the first call, caches it and
+ returns on all calls afterwards.
+
+ @param[out] Info Place to store a pointer to firmware information.
+
+ @retval EFI_SUCCESS Info points to firmware information.
+ @retval EFI_INVALID_PARAMETER Info is NULL.
+**/
+STATIC
+EFI_STATUS
+GetFwInfo (
+ OUT FIRMWARE_INFO **Info
+ )
+{
+ STATIC FIRMWARE_INFO Storage;
+ STATIC BOOLEAN Initialized;
+
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ if (Info == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!Initialized) {
+ GuidHob = GetFirstGuidHob (&gEfiFirmwareInfoHobGuid);
+ if (GuidHob == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a(): failed to query firmware information\n", __func__));
+ return EFI_UNSUPPORTED;
+ }
+
+ Storage = *(FIRMWARE_INFO *)GET_GUID_HOB_DATA (GuidHob);
+ Initialized = TRUE;
+ }
+
+ *Info = &Storage;
+ return EFI_SUCCESS;
+}
+
+/**
+ Provide a function to install the Firmware Management Protocol instance onto a
+ device handle when the device is managed by a driver that follows the UEFI
+ Driver Model. If the device is not managed by a driver that follows the UEFI
+ Driver Model, then EFI_UNSUPPORTED is returned.
+
+ @param[in] FmpInstaller Function that installs the Firmware Management
+ Protocol.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model. FmpInstaller must be called on
+ each Driver Binding Start().
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+**/
+EFI_STATUS
+EFIAPI
+RegisterFmpInstaller (
+ IN FMP_DEVICE_LIB_REGISTER_FMP_INSTALLER Function
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Provide a function to uninstall the Firmware Management Protocol instance from a
+ device handle when the device is managed by a driver that follows the UEFI
+ Driver Model. If the device is not managed by a driver that follows the UEFI
+ Driver Model, then EFI_UNSUPPORTED is returned.
+
+ @param[in] FmpUninstaller Function that installs the Firmware Management
+ Protocol.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model. FmpUninstaller must be called on
+ each Driver Binding Stop().
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+**/
+EFI_STATUS
+EFIAPI
+RegisterFmpUninstaller (
+ IN FMP_DEVICE_LIB_REGISTER_FMP_UNINSTALLER Function
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Set the device context for the FmpDeviceLib services when the device is
+ managed by a driver that follows the UEFI Driver Model. If the device is not
+ managed by a driver that follows the UEFI Driver Model, then EFI_UNSUPPORTED
+ is returned. Once a device context is set, the FmpDeviceLib services
+ operate on the currently set device context.
+
+ @param[in] Handle Device handle for the FmpDeviceLib services.
+ If Handle is NULL, then Context is freed.
+ @param[in, out] Context Device context for the FmpDeviceLib services.
+ If Context is NULL, then a new context is allocated
+ for Handle and the current device context is set and
+ returned in Context. If Context is not NULL, then
+ the current device context is set.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model.
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceSetContext (
+ IN EFI_HANDLE Handle,
+ IN OUT VOID **Context
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns the size, in bytes, of the firmware image currently stored in the
+ firmware device. This function is used to by the GetImage() and
+ GetImageInfo() services of the Firmware Management Protocol. If the image
+ size can not be determined from the firmware device, then 0 must be returned.
+
+ @param[out] Size Pointer to the size, in bytes, of the firmware image
+ currently stored in the firmware device.
+
+ @retval EFI_SUCCESS The size of the firmware image currently
+ stored in the firmware device was returned.
+ @retval EFI_INVALID_PARAMETER Size is NULL.
+ @retval EFI_UNSUPPORTED The firmware device does not support reporting
+ the size of the currently stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to determine the
+ size of the firmware image currently stored in
+ in the firmware device.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetSize (
+ OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_INFO *FwInfo;
+
+ if (Size == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetFwInfo (&FwInfo);
+ if (!EFI_ERROR (Status)) {
+ *Size = FwInfo->ImageSize;
+ }
+
+ return Status;
+}
+
+/**
+ Returns the GUID value used to fill in the ImageTypeId field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_UNSUPPORTED is returned,
+ then the ImageTypeId field is set to gEfiCallerIdGuid. If EFI_SUCCESS is
+ returned, then ImageTypeId is set to the Guid returned from this function.
+
+ @param[out] Guid Double pointer to a GUID value that is updated to point to
+ to a GUID value. The GUID value is not allocated and must
+ not be modified or freed by the caller.
+
+ @retval EFI_SUCCESS EFI_FIRMWARE_IMAGE_DESCRIPTOR ImageTypeId GUID is set
+ to the returned Guid value.
+ @retval EFI_UNSUPPORTED EFI_FIRMWARE_IMAGE_DESCRIPTOR ImageTypeId GUID is set
+ to gEfiCallerIdGuid.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImageTypeIdGuidPtr (
+ OUT EFI_GUID **Guid
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_INFO *FwInfo;
+
+ if (Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetFwInfo (&FwInfo);
+ if (!EFI_ERROR (Status)) {
+ *Guid = &FwInfo->Type;
+ }
+
+ return Status;
+}
+
+/**
+ Returns values used to fill in the AttributesSupported and AttributesSettings
+ fields of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the
+ GetImageInfo() service of the Firmware Management Protocol. The following
+ bit values from the Firmware Management Protocol may be combined:
+ IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
+ IMAGE_ATTRIBUTE_RESET_REQUIRED
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
+ IMAGE_ATTRIBUTE_IN_USE
+ IMAGE_ATTRIBUTE_UEFI_IMAGE
+
+ @param[out] Supported Attributes supported by this firmware device.
+ @param[out] Setting Attributes settings for this firmware device.
+
+ @retval EFI_SUCCESS The attributes supported by the firmware
+ device were returned.
+ @retval EFI_INVALID_PARAMETER Supported is NULL.
+ @retval EFI_INVALID_PARAMETER Setting is NULL.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetAttributes (
+ OUT UINT64 *Supported,
+ OUT UINT64 *Setting
+ )
+{
+ if ((Supported == NULL) || (Setting == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Supported = IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
+ IMAGE_ATTRIBUTE_RESET_REQUIRED |
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED |
+ IMAGE_ATTRIBUTE_IN_USE;
+ *Setting = *Supported;
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns the value used to fill in the LowestSupportedVersion field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the LowestSupportedVersion
+ value from the currently stored firmware image. If the value can not be
+ reported for the firmware image currently stored in the firmware device, then
+ EFI_UNSUPPORTED must be returned. EFI_DEVICE_ERROR is returned if an error
+ occurs attempting to retrieve the LowestSupportedVersion value for the
+ currently stored firmware image.
+
+ @note It is recommended that all firmware devices support a method to report
+ the LowestSupportedVersion value from the currently stored firmware
+ image.
+
+ @param[out] LowestSupportedVersion LowestSupportedVersion value retrieved
+ from the currently stored firmware image.
+
+ @retval EFI_SUCCESS The lowest supported version of currently stored
+ firmware image was returned in LowestSupportedVersion.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the lowest supported version of the currently
+ stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the lowest
+ supported version of the currently stored firmware
+ image.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetLowestSupportedVersion (
+ OUT UINT32 *LowestSupportedVersion
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_INFO *FwInfo;
+
+ if (LowestSupportedVersion == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetFwInfo (&FwInfo);
+ if (!EFI_ERROR (Status)) {
+ *LowestSupportedVersion = FwInfo->LowestSupportedVersion;
+ }
+
+ return Status;
+}
+
+/**
+ Returns the Null-terminated Unicode string that is used to fill in the
+ VersionName field of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is
+ returned by the GetImageInfo() service of the Firmware Management Protocol.
+ The returned string must be allocated using EFI_BOOT_SERVICES.AllocatePool().
+
+ @note It is recommended that all firmware devices support a method to report
+ the VersionName string from the currently stored firmware image.
+
+ @param[out] VersionString The version string retrieved from the currently
+ stored firmware image.
+
+ @retval EFI_SUCCESS The version string of currently stored
+ firmware image was returned in Version.
+ @retval EFI_INVALID_PARAMETER VersionString is NULL.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method
+ to report the version string of the currently
+ stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the
+ version string of the currently stored
+ firmware image.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the
+ buffer for the version string of the currently
+ stored firmware image.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersionString (
+ OUT CHAR16 **VersionString
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_INFO *FwInfo;
+
+ if (VersionString == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetFwInfo (&FwInfo);
+ if (!EFI_ERROR (Status)) {
+ *VersionString = (CHAR16 *)AllocateCopyPool (
+ sizeof (FwInfo->VersionStr),
+ FwInfo->VersionStr
+ );
+ if (*VersionString == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Returns the value used to fill in the Version field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the Version value from the
+ currently stored firmware image. If the value can not be reported for the
+ firmware image currently stored in the firmware device, then EFI_UNSUPPORTED
+ must be returned. EFI_DEVICE_ERROR is returned if an error occurs attempting
+ to retrieve the LowestSupportedVersion value for the currently stored firmware
+ image.
+
+ @note It is recommended that all firmware devices support a method to report
+ the Version value from the currently stored firmware image.
+
+ @param[out] Version The version value retrieved from the currently stored
+ firmware image.
+
+ @retval EFI_SUCCESS The version of currently stored firmware image was
+ returned in Version.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the version of the currently stored firmware
+ image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the version
+ of the currently stored firmware image.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersion (
+ OUT UINT32 *Version
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_INFO *FwInfo;
+
+ if (Version == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetFwInfo (&FwInfo);
+ if (!EFI_ERROR (Status)) {
+ *Version = FwInfo->Version;
+ }
+
+ return Status;
+}
+
+/**
+ Returns the value used to fill in the HardwareInstance field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the HardwareInstance value.
+ If the value can not be reported for the firmware device, then EFI_UNSUPPORTED
+ must be returned. EFI_DEVICE_ERROR is returned if an error occurs attempting
+ to retrieve the HardwareInstance value for the firmware device.
+
+ @param[out] HardwareInstance The hardware instance value for the firmware
+ device.
+
+ @retval EFI_SUCCESS The hardware instance for the current firmware
+ device is returned in HardwareInstance.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the hardware instance value.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the hardware
+ instance value.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetHardwareInstance (
+ OUT UINT64 *HardwareInstance
+ )
+{
+ if (HardwareInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *HardwareInstance = 0;
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns a copy of the firmware image currently stored in the firmware device.
+
+ @note It is recommended that all firmware devices support a method to retrieve
+ a copy currently stored firmware image. This can be used to support
+ features such as recovery and rollback.
+
+ @param[out] Image Pointer to a caller allocated buffer where the
+ currently stored firmware image is copied to.
+ @param[in, out] ImageSize Pointer the size, in bytes, of the Image buffer.
+ On return, points to the size, in bytes, of firmware
+ image currently stored in the firmware device.
+
+ @retval EFI_SUCCESS Image contains a copy of the firmware image
+ currently stored in the firmware device, and
+ ImageSize contains the size, in bytes, of the
+ firmware image currently stored in the
+ firmware device.
+ @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small
+ to hold the firmware image currently stored in
+ the firmware device. The buffer size required
+ is returned in ImageSize.
+ @retval EFI_INVALID_PARAMETER The Image is NULL.
+ @retval EFI_INVALID_PARAMETER The ImageSize is NULL.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the
+ firmware image currently stored in the firmware
+ device.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImage (
+ OUT VOID *Image,
+ IN OUT UINTN *ImageSize
+ )
+{
+ //
+ // This seems useful only if FMP device is part of the running firmware.
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Checks if a new firmware image is valid for the firmware device. This
+ function allows firmware update operation to validate the firmware image
+ before FmpDeviceSetImage() is called.
+
+ @param[in] Image Points to a new firmware image.
+ @param[in] ImageSize Size, in bytes, of a new firmware image.
+ @param[out] ImageUpdatable Indicates if a new firmware image is valid for
+ a firmware update to the firmware device. The
+ following values from the Firmware Management
+ Protocol are supported:
+ IMAGE_UPDATABLE_VALID
+ IMAGE_UPDATABLE_INVALID
+ IMAGE_UPDATABLE_INVALID_TYPE
+ IMAGE_UPDATABLE_INVALID_OLD
+ IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE
+
+ @retval EFI_SUCCESS The image was successfully checked. Additional
+ status information is returned in
+ ImageUpdatable.
+ @retval EFI_INVALID_PARAMETER Image is NULL.
+ @retval EFI_INVALID_PARAMETER ImageUpdatable is NULL.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceCheckImage (
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *ImageUpdatable
+ )
+{
+ UINT32 LastAttemptStatus;
+
+ return FmpDeviceCheckImageWithStatus (Image, ImageSize, ImageUpdatable, &LastAttemptStatus);
+}
+
+/**
+ Checks if a new firmware image is valid for the firmware device. This
+ function allows firmware update operation to validate the firmware image
+ before FmpDeviceSetImage() is called.
+
+ @param[in] Image Points to a new firmware image.
+ @param[in] ImageSize Size, in bytes, of a new firmware image.
+ @param[out] ImageUpdatable Indicates if a new firmware image is valid for
+ a firmware update to the firmware device. The
+ following values from the Firmware Management
+ Protocol are supported:
+ IMAGE_UPDATABLE_VALID
+ IMAGE_UPDATABLE_INVALID
+ IMAGE_UPDATABLE_INVALID_TYPE
+ IMAGE_UPDATABLE_INVALID_OLD
+ IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE
+ @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last attempt
+ status to report back to the ESRT table in case
+ of error.
+
+ The return status code must fall in the range of
+ LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to
+ LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE.
+
+ If the value falls outside this range, it will be converted
+ to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL.
+
+ @retval EFI_SUCCESS The image was successfully checked. Additional
+ status information is returned in
+ ImageUpdatable.
+ @retval EFI_INVALID_PARAMETER Image is NULL.
+ @retval EFI_INVALID_PARAMETER ImageUpdatable is NULL.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceCheckImageWithStatus (
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *ImageUpdatable,
+ OUT UINT32 *LastAttemptStatus
+ )
+{
+ EFI_STATUS Status;
+ UINTN FwSize;
+ UINTN BlockSize;
+
+ if ((Image == NULL) || (ImageUpdatable == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
+ *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
+
+ Status = FmpDeviceGetSize (&FwSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a(): FmpDeviceGetSize() failed with: %r\n", __func__, Status));
+ return Status;
+ }
+
+ if (ImageSize != FwSize) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a(): image size (0x%x) doesn't match firmware size (0x%x)\n",
+ __func__,
+ ImageSize,
+ FwSize
+ ));
+ return EFI_ABORTED;
+ }
+
+ Status = SmmStoreLibGetBlockSize (&BlockSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a(): SmmStoreLibGetBlockSize() failed with: %r\n", __func__, Status));
+ return Status;
+ }
+
+ if (FwSize % BlockSize != 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a(): firmware size (0x%x) is not a multiple of block size (0x%x)\n",
+ __func__,
+ FwSize,
+ BlockSize
+ ));
+ return EFI_ABORTED;
+ }
+
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
+ *ImageUpdatable = IMAGE_UPDATABLE_VALID;
+ return EFI_SUCCESS;
+}
+
+/**
+ Updates a firmware device with a new firmware image. This function returns
+ EFI_UNSUPPORTED if the firmware image is not updatable. If the firmware image
+ is updatable, the function should perform the following minimal validations
+ before proceeding to do the firmware image update.
+ - Validate that the image is a supported image for this firmware device.
+ Return EFI_ABORTED if the image is not supported. Additional details
+ on why the image is not a supported image may be returned in AbortReason.
+ - Validate the data from VendorCode if is not NULL. Firmware image
+ validation must be performed before VendorCode data validation.
+ VendorCode data is ignored or considered invalid if image validation
+ fails. Return EFI_ABORTED if the VendorCode data is invalid.
+
+ VendorCode enables vendor to implement vendor-specific firmware image update
+ policy. Null if the caller did not specify the policy or use the default
+ policy. As an example, vendor can implement a policy to allow an option to
+ force a firmware image update when the abort reason is due to the new firmware
+ image version is older than the current firmware image version or bad image
+ checksum. Sensitive operations such as those wiping the entire firmware image
+ and render the device to be non-functional should be encoded in the image
+ itself rather than passed with the VendorCode. AbortReason enables vendor to
+ have the option to provide a more detailed description of the abort reason to
+ the caller.
+
+ @param[in] Image Points to the new firmware image.
+ @param[in] ImageSize Size, in bytes, of the new firmware image.
+ @param[in] VendorCode This enables vendor to implement vendor-specific
+ firmware image update policy. NULL indicates
+ the caller did not specify the policy or use the
+ default policy.
+ @param[in] Progress A function used to report the progress of
+ updating the firmware device with the new
+ firmware image.
+ @param[in] CapsuleFwVersion The version of the new firmware image from the
+ update capsule that provided the new firmware
+ image.
+ @param[out] AbortReason A pointer to a pointer to a Null-terminated
+ Unicode string providing more details on an
+ aborted operation. The buffer is allocated by
+ this function with
+ EFI_BOOT_SERVICES.AllocatePool(). It is the
+ caller's responsibility to free this buffer with
+ EFI_BOOT_SERVICES.FreePool().
+
+ @retval EFI_SUCCESS The firmware device was successfully updated
+ with the new firmware image.
+ @retval EFI_ABORTED The operation is aborted. Additional details
+ are provided in AbortReason.
+ @retval EFI_INVALID_PARAMETER The Image was NULL.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceSetImage (
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ IN CONST VOID *VendorCode OPTIONAL,
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress OPTIONAL,
+ IN UINT32 CapsuleFwVersion,
+ OUT CHAR16 **AbortReason
+ )
+{
+ UINT32 LastAttemptStatus;
+
+ return FmpDeviceSetImageWithStatus (
+ Image,
+ ImageSize,
+ VendorCode,
+ Progress,
+ CapsuleFwVersion,
+ AbortReason,
+ &LastAttemptStatus
+ );
+}
+
+/**
+ Advances progress of the operation by a single step, converts the steps to
+ percents and invokes a callback if there is one.
+
+ @param[in] Callback External callback for progress reporting
+ or NULL if there is none.
+ @param[in] TotalSteps Total number of flashing steps.
+ @param[in, out] Step Current step number.
+ @param[in, out] ShouldReportProgress A flag indicating whether progress needs
+ to be reported.
+**/
+STATIC
+VOID
+IncrementProgress (
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Callback OPTIONAL,
+ IN UINTN TotalSteps,
+ IN OUT UINTN *Step,
+ IN OUT BOOLEAN *ShouldReportProgress
+ )
+{
+ EFI_STATUS Status;
+ UINTN Progress;
+
+ if (!*ShouldReportProgress) {
+ return;
+ }
+
+ if (Callback == NULL) {
+ *ShouldReportProgress = FALSE;
+ return;
+ }
+
+ ++*Step;
+ Progress = (*Step * 100) / TotalSteps;
+
+ //
+ // Value of 0 means "progress reporting is not supported", so avoid using it.
+ //
+ if (Progress == 0) {
+ Progress = 1;
+ }
+
+ Status = Callback (Progress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a(): progress callback failed with: %r\n", __func__, Status));
+ *ShouldReportProgress = FALSE;
+ }
+}
+
+/**
+ This code finds variable in storage blocks (Volatile or Non-Volatile).
+
+ @param[in] VariableName Name of Variable to be found.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[out] Attributes Attribute value of the variable found.
+ @param[in, out] DataSize Size of Data found. If size is less than the
+ data, this value contains the required size.
+ @param[out] Data Data pointer.
+
+ @return EFI_INVALID_PARAMETER Invalid parameter.
+ @return EFI_SUCCESS Find the specified variable.
+ @return EFI_NOT_FOUND Not found.
+ @return EFI_BUFFER_TO_SMALL DataSize is too small for the result.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetVariableHook (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data
+ )
+{
+ DEBUG ((DEBUG_INFO, "%a(): %g:%S\n", __func__, VendorGuid, VariableName));
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ This code Finds the Next available variable.
+
+ @param[in, out] VariableNameSize Size of the variable name.
+ @param[in, out] VariableName Pointer to variable name.
+ @param[in, out] VendorGuid Variable Vendor Guid.
+
+ @return EFI_INVALID_PARAMETER Invalid parameter.
+ @return EFI_SUCCESS Find the specified variable.
+ @return EFI_NOT_FOUND Not found.
+ @return EFI_BUFFER_TO_SMALL DataSize is too small for the result.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetNextVariableNameHook (
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName,
+ IN OUT EFI_GUID *VendorGuid
+ )
+{
+ DEBUG ((DEBUG_INFO, "%a(): %g:%S\n", __func__, VendorGuid, VariableName));
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ This code sets variable in storage blocks (Volatile or Non-Volatile).
+
+ @param[in] VariableName Name of Variable to be found.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable found
+ @param[in] DataSize Size of Data found. If size is less than the
+ data, this value contains the required size.
+ @param[in] Data Data pointer.
+
+ @return EFI_INVALID_PARAMETER Invalid parameter.
+ @return EFI_SUCCESS Set successfully.
+ @return EFI_OUT_OF_RESOURCES Resource not enough to set variable.
+ @return EFI_NOT_FOUND Not found.
+ @return EFI_WRITE_PROTECTED Variable is read-only.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SetVariableHook (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ DEBUG ((
+ DEBUG_INFO,
+ "%a(): %g:%S, 0x%x bytes, 0x%x\n",
+ __func__,
+ VendorGuid,
+ VariableName,
+ DataSize,
+ Attributes
+ ));
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ This code returns information about the EFI variables.
+
+ @param[in] Attributes Attributes bitmask to specify the type of variables
+ on which to return information.
+ @param[out] MaximumVariableStorageSize Pointer to the maximum size of the storage space available
+ for the EFI variables associated with the attributes specified.
+ @param[out] RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param[out] MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
+ @return EFI_SUCCESS Query successfully.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+QueryVariableInfoHook (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ )
+{
+ DEBUG ((DEBUG_INFO, "%a(): 0x%x\n", __func__, Attributes));
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Updates a firmware device with a new firmware image. This function returns
+ EFI_UNSUPPORTED if the firmware image is not updatable. If the firmware image
+ is updatable, the function should perform the following minimal validations
+ before proceeding to do the firmware image update.
+ - Validate that the image is a supported image for this firmware device.
+ Return EFI_ABORTED if the image is not supported. Additional details
+ on why the image is not a supported image may be returned in AbortReason.
+ - Validate the data from VendorCode if is not NULL. Firmware image
+ validation must be performed before VendorCode data validation.
+ VendorCode data is ignored or considered invalid if image validation
+ fails. Return EFI_ABORTED if the VendorCode data is invalid.
+
+ VendorCode enables vendor to implement vendor-specific firmware image update
+ policy. Null if the caller did not specify the policy or use the default
+ policy. As an example, vendor can implement a policy to allow an option to
+ force a firmware image update when the abort reason is due to the new firmware
+ image version is older than the current firmware image version or bad image
+ checksum. Sensitive operations such as those wiping the entire firmware image
+ and render the device to be non-functional should be encoded in the image
+ itself rather than passed with the VendorCode. AbortReason enables vendor to
+ have the option to provide a more detailed description of the abort reason to
+ the caller.
+
+ @param[in] Image Points to the new firmware image.
+ @param[in] ImageSize Size, in bytes, of the new firmware image.
+ @param[in] VendorCode This enables vendor to implement vendor-specific
+ firmware image update policy. NULL indicates
+ the caller did not specify the policy or use the
+ default policy.
+ @param[in] Progress A function used to report the progress of
+ updating the firmware device with the new
+ firmware image.
+ @param[in] CapsuleFwVersion The version of the new firmware image from the
+ update capsule that provided the new firmware
+ image.
+ @param[out] AbortReason A pointer to a pointer to a Null-terminated
+ Unicode string providing more details on an
+ aborted operation. The buffer is allocated by
+ this function with
+ EFI_BOOT_SERVICES.AllocatePool(). It is the
+ caller's responsibility to free this buffer with
+ EFI_BOOT_SERVICES.FreePool().
+ @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last attempt
+ status to report back to the ESRT table in case
+ of error. This value will only be checked when this
+ function returns an error.
+
+ The return status code must fall in the range of
+ LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to
+ LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE.
+
+ If the value falls outside this range, it will be converted
+ to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL.
+
+ @retval EFI_SUCCESS The firmware device was successfully updated
+ with the new firmware image.
+ @retval EFI_ABORTED The operation is aborted. Additional details
+ are provided in AbortReason.
+ @retval EFI_INVALID_PARAMETER The Image was NULL.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceSetImageWithStatus (
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ IN CONST VOID *VendorCode OPTIONAL,
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress OPTIONAL,
+ IN UINT32 CapsuleFwVersion,
+ OUT CHAR16 **AbortReason,
+ OUT UINT32 *LastAttemptStatus
+ )
+{
+ EFI_STATUS Status;
+ UINTN BlockSize;
+ UINTN BlockCount;
+ UINTN Block;
+ UINTN NumBytes;
+ UINTN TotalSteps;
+ UINTN Step;
+ BOOLEAN ShouldReportProgress;
+ VOID *ReadBuffer;
+ CONST UINT8 *WriteNext;
+
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
+
+ //
+ // FmpDeviceCheckImageWithStatus() has already validated the image, so not
+ // repeating the checks. However, could move the checks here to be able to
+ // report abort reason which can't be done in FmpDeviceCheckImageWithStatus().
+ //
+
+ Status = SmmStoreLibGetBlockSize (&BlockSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a(): SmmStoreLibGetBlockSize() failed with: %r\n",
+ __func__,
+ Status
+ ));
+ return Status;
+ }
+
+ ReadBuffer = AllocatePool (BlockSize);
+ if (ReadBuffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a(): failed to allocate read buffer\n", __func__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BlockCount = ImageSize / BlockSize;
+ DEBUG ((
+ DEBUG_INFO,
+ "%a(): 0x%x blocks of 0x%x bytes\n",
+ __func__,
+ BlockCount,
+ BlockSize
+ ));
+
+ ShouldReportProgress = TRUE;
+ TotalSteps = BlockCount * 2; // Erase and write of each block.
+ Step = 0;
+ WriteNext = Image;
+
+ for (Block = 0; Block < BlockCount; Block++, WriteNext += BlockSize) {
+ //
+ // Save the flash and time by only writing a block if new contents differs
+ // from the old one.
+ //
+ // This is an optimization, so ignore read errors (if they are indicative of
+ // a serious problem, erasing or writing will fail as well).
+ //
+ NumBytes = BlockSize;
+ Status = SmmStoreLibReadAnyBlock (Block, 0, &NumBytes, ReadBuffer);
+ if (!EFI_ERROR (Status) && (NumBytes == BlockSize)) {
+ if (CompareMem (ReadBuffer, WriteNext, BlockSize) == 0) {
+ // Erase step.
+ IncrementProgress (Progress, TotalSteps, &Step, &ShouldReportProgress);
+ // Write step.
+ IncrementProgress (Progress, TotalSteps, &Step, &ShouldReportProgress);
+ continue;
+ }
+ }
+
+ Status = SmmStoreLibEraseAnyBlock (Block);
+ if (EFI_ERROR (Status)) {
+ goto IoError;
+ }
+
+ IncrementProgress (Progress, TotalSteps, &Step, &ShouldReportProgress);
+
+ NumBytes = BlockSize;
+ Status = SmmStoreLibWriteAnyBlock (Block, 0, &NumBytes, (VOID *)WriteNext);
+ if (EFI_ERROR (Status) || (NumBytes != BlockSize)) {
+ goto IoError;
+ }
+
+ IncrementProgress (Progress, TotalSteps, &Step, &ShouldReportProgress);
+ }
+
+ FreePool (ReadBuffer);
+
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
+
+ //
+ // Updating the firmware on system flash overwrites SMMSTORE region which
+ // backs up EFI variables of the running firmware. At this point both SMI
+ // handler from coreboot and variable services of EDK can be mistaken in
+ // their assumptions about the location, size and contents of the region.
+ // Accessing flash where SMMSTORE used to be can lead to unexpected results
+ // including corruption of the new image outside of its SMMSTORE. Switch to
+ // the use of stubs for dealing with EFI variables that do nothing.
+ //
+ // New firmware will not report result of flashing in any way unless some
+ // kind of communication mechanism is implemented for this purpose.
+ //
+ // If there was an error, it's unclear whether these stubs would be of any
+ // help, so they are employed only on successful flashing.
+ //
+
+ gRT->GetVariable = GetVariableHook;
+ gRT->GetNextVariableName = GetNextVariableNameHook;
+ gRT->SetVariable = SetVariableHook;
+ gRT->QueryVariableInfo = QueryVariableInfoHook;
+
+ gRT->Hdr.CRC32 = 0;
+ gBS->CalculateCrc32 (
+ (UINT8 *)&gRT->Hdr,
+ gRT->Hdr.HeaderSize,
+ &gRT->Hdr.CRC32
+ );
+
+ return EFI_SUCCESS;
+
+IoError:
+ //
+ // There are several reasons why we might end up in here:
+ // - an actual issue with the flash chip which is unlikely to allow any
+ // recovery via software
+ // - a bug in SMMSTORE SMI handler of coreboot
+ // - any bug of the firmware or its configuration which has resulted in the
+ // system not being ready for a full flash update
+ //
+ // The last case can be caused at least by:
+ // - coreboot not lifting flash protections
+ // - Intel ME not being disabled
+ //
+ // This situation is atypical and can leave the flash chip in an
+ // unpredictable state which can be fully functional, unbootable or something
+ // in between.
+ //
+ // Being optimistic that the firmware is still functional, we're leaving
+ // variable services available under assumption that SMMSTORE region hasn't
+ // been moved withing the firmware image (most updates don't modify layout).
+ // Note that the store can even be recreated on the next boot depending on
+ // the damage that it has sustained. It's also possible that we hit
+ // protected range and nothing of any worth has been modified.
+ //
+ // If the firmware ends up unbootable, then, in general, external flashing
+ // via a programmer needs to be employed to recover the device.
+ //
+ FreePool (ReadBuffer);
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a(): flashing has failed at block 0x%x/0x%x: %r\n",
+ __func__,
+ Block,
+ BlockCount,
+ EFI_DEVICE_ERROR
+ ));
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Lock the firmware device that contains a firmware image. Once a firmware
+ device is locked, any attempts to modify the firmware image contents in the
+ firmware device must fail.
+
+ @note It is recommended that all firmware devices support a lock method to
+ prevent modifications to a stored firmware image.
+
+ @note A firmware device lock mechanism is typically only cleared by a full
+ system reset (not just sleep state/low power mode).
+
+ @retval EFI_SUCCESS The firmware device was locked.
+ @retval EFI_UNSUPPORTED The firmware device does not support locking
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceLock (
+ VOID
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Constructor that performs required initialization.
+
+ @param ImageHandle The image handle of the process.
+ @param SystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS Initialization was successful.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceSmmLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ SmmStoreLibInitialize ();
+ return EFI_SUCCESS;
+}
diff --git a/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.inf b/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.inf new file mode 100644 index 0000000000..893e36170e --- /dev/null +++ b/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.inf @@ -0,0 +1,47 @@ +## @file
+# Provides firmware device specific services to support updates of a firmware
+# image stored in a firmware device.
+#
+# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2025, 3mdeb Sp. z o.o. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDeviceSmmLib
+ MODULE_UNI_FILE = FmpDeviceSmmLib.uni
+ FILE_GUID = 979CF0F8-7214-4D12-89CE-F32112ED71C6
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpDeviceLib|DXE_DRIVER UEFI_DRIVER
+ CONSTRUCTOR = FmpDeviceSmmLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDeviceSmmLib.c
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+ SmmStoreLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
+[Packages]
+ UefiPayloadPkg/UefiPayloadPkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[Guids]
+ gEfiFirmwareInfoHobGuid
diff --git a/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.uni b/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.uni new file mode 100644 index 0000000000..37efb8c9ec --- /dev/null +++ b/UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.uni @@ -0,0 +1,13 @@ +// /** @file
+// Provides firmware device specific services to support updates of a firmware
+// image stored in a firmware device.
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides firmware device specific services to support updates of a firmware image stored in a firmware device."
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides firmware device specific services to support updates of a firmware image stored in a firmware device."
diff --git a/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c b/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c index c2d4437dd2..0e3bf29c82 100644 --- a/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c +++ b/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c @@ -558,6 +558,39 @@ BuildFv3Hob ( }
/**
+ Builds a Capsule Volume HOB.
+
+ This function builds a Capsule Volume HOB.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+
+ If the platform does not support Capsule Volume HOBs, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Capsule Volume.
+ @param Length The size of the Capsule Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildCvHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ EFI_HOB_UEFI_CAPSULE *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_UEFI_CAPSULE, sizeof (EFI_HOB_UEFI_CAPSULE));
+ ASSERT (Hob != NULL);
+ if (Hob == NULL) {
+ return;
+ }
+
+ Hob->BaseAddress = BaseAddress;
+ Hob->Length = Length;
+}
+
+/**
Builds a HOB for the CPU.
This function builds a HOB for the CPU.
diff --git a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c index a4a49da0e9..0788d850ab 100644 --- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c +++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c @@ -226,6 +226,7 @@ PlatformBootManagerBeforeConsole ( VOID
)
{
+ EFI_STATUS Status;
EFI_INPUT_KEY Enter;
EFI_INPUT_KEY CustomKey;
EFI_INPUT_KEY Down;
@@ -264,6 +265,17 @@ PlatformBootManagerBeforeConsole ( EfiBootManagerAddKeyOptionVariable (NULL, (UINT16)BootOption.OptionNumber, 0, &Down, NULL);
//
+ // Process update capsules that don't contain embedded drivers.
+ //
+ if (GetBootModeHob () == BOOT_ON_FLASH_UPDATE) {
+ // TODO: when enabling capsule support for laptops, add a battery check here
+ Status = ProcessCapsules ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a(): ProcessCapsule() failed with: %r\n", __func__, Status));
+ }
+ }
+
+ //
// Install ready to lock.
// This needs to be done before option rom dispatched.
//
@@ -312,6 +324,33 @@ PlatformBootManagerAfterConsole ( EfiBootManagerRefreshAllBootOption ();
//
+ // Active BOOT_ON_FLASH_UPDATE mode means that at least one capsule has been
+ // discovered by a bootloader and passed for further processing into EDK which
+ // created EFI_HOB_TYPE_UEFI_CAPSULE HOB(s).
+ //
+ // Process update capsules that weren't processed on the first call to
+ // ProcessCapsules() in PlatformBootManagerBeforeConsole().
+ //
+ if (GetBootModeHob () == BOOT_ON_FLASH_UPDATE) {
+ // TODO: when enabling capsule support for laptops, add a battery check here
+ Status = ProcessCapsules ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a(): ProcessCapsule() failed with: %r\n", __func__, Status));
+ }
+
+ //
+ // Reset the system to disable SMI handler in order to exclude the
+ // possibility of it being used outside of the firmware.
+ //
+ // In practice, this will rarely execute because even the first
+ // ProcessCapsules() invocation might do a reset if all capsules were
+ // processed and at least one of them needed a reset. This is just to catch
+ // a case when this doesn't happen which is possible on error.
+ //
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+
+ //
// Register UEFI Shell
//
PlatformRegisterFvBootOption (&gUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE);
diff --git a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h index 2110997d9b..88a83af047 100644 --- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h +++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h @@ -26,6 +26,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include <Library/PrintLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/BootLogoLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/HobLib.h>
#include <Protocol/SmmAccess2.h>
typedef struct {
diff --git a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf index 987c73040e..e803cc80c5 100644 --- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf +++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -47,6 +47,8 @@ HiiLib
PrintLib
PlatformHookLib
+ CapsuleLib
+ HobLib
[Guids]
gEfiEndOfDxeEventGroupGuid
diff --git a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c index de139a5305..7cc615a35e 100644 --- a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c +++ b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c @@ -307,3 +307,41 @@ ParseSmmStoreInfo ( {
return RETURN_NOT_FOUND;
}
+
+/**
+ Parse firmware information passed in by bootloader
+
+ @param FwInfo Information about current firmware.
+
+ @retval RETURN_INVALID_PARAMETER The parameter is NULL.
+ @retval RETURN_SUCCESS Successfully parsed information.
+ @retval RETURN_NOT_FOUND The information is missing.
+**/
+RETURN_STATUS
+EFIAPI
+ParseFirmwareInfo (
+ OUT FIRMWARE_INFO *FwInfo
+ )
+{
+ return RETURN_NOT_FOUND;
+}
+
+/**
+ Parse update capsules passed in by bootloader
+
+ @param CapsuleCallback The callback routine invoked for each capsule.
+
+ @retval RETURN_SUCCESS Successfully parsed capsules.
+ @retval RETURN_NOT_FOUND Failed to look up the information.
+**/
+RETURN_STATUS
+EFIAPI
+ParseCapsules (
+ IN BL_CAPSULE_CALLBACK CapsuleCallback
+ )
+{
+ //
+ // Treat not supporting this function like reporting zero capsules.
+ //
+ return RETURN_SUCCESS;
+}
diff --git a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf index f83a10ccd8..15fd1ca873 100644 --- a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf +++ b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf @@ -41,6 +41,8 @@ gEfiGraphicsInfoHobGuid
gEfiGraphicsDeviceInfoHobGuid
gUniversalPayloadPciRootBridgeInfoGuid
+ gUniversalPayloadSmbiosTableGuid
+ gUniversalPayloadAcpiTableGuid
[Pcd]
gUefiPayloadPkgTokenSpaceGuid.PcdBootloaderParameter
diff --git a/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.c b/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.c index 690bae0f1c..f232b12e8a 100644 --- a/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.c +++ b/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.c @@ -1,6 +1,7 @@ /** @file SmmStore.c
Copyright (c) 2022, 9elements GmbH<BR>
+ Copyright (c) 2025, 3mdeb Sp. z o.o.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -139,33 +140,31 @@ SmmStoreLibGetMmioAddress ( }
/**
- Read from SmmStore
+ Read a flash block. The whole flash is represented as a
+ sequence of blocks.
@param[in] Lba The starting logical block index to read from.
@param[in] Offset Offset into the block at which to begin reading.
@param[in] NumBytes On input, indicates the requested read size. On
- output, indicates the actual number of bytes read.
+ output, indicates the actual number of bytes read
@param[in] Buffer Pointer to the buffer to read into.
+ @param[in] ReadCmd Read command to use.
+
+ @note Validation of mSmmStoreInfo and Lba must be done by the calling code.
**/
+STATIC
EFI_STATUS
-SmmStoreLibRead (
+ReadBlock (
IN EFI_LBA Lba,
IN UINTN Offset,
IN UINTN *NumBytes,
- IN UINT8 *Buffer
+ IN UINT8 *Buffer,
+ IN UINT8 ReadCmd
)
{
EFI_STATUS Status;
- if (mSmmStoreInfo == NULL) {
- return EFI_NO_MEDIA;
- }
-
- if (Lba >= mSmmStoreInfo->NumBlocks) {
- return EFI_INVALID_PARAMETER;
- }
-
if (((*NumBytes + Offset) > mSmmStoreInfo->BlockSize) ||
((*NumBytes + Offset) > mSmmStoreInfo->ComBufferSize))
{
@@ -176,7 +175,7 @@ SmmStoreLibRead ( mArgComBuf->Read.BufOffset = Offset;
mArgComBuf->Read.BlockId = Lba;
- Status = CallSmm (mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_READ, mArgComBufPhys);
+ Status = CallSmm (mSmmStoreInfo->ApmCmd, ReadCmd, mArgComBufPhys);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -187,17 +186,17 @@ SmmStoreLibRead ( }
/**
- Write to SmmStore
+ Read from SmmStore
- @param[in] Lba The starting logical block index to write to.
- @param[in] Offset Offset into the block at which to begin writing.
- @param[in] NumBytes On input, indicates the requested write size. On
- output, indicates the actual number of bytes written.
- @param[in] Buffer Pointer to the data to write.
+ @param[in] Lba The starting logical block index to read from.
+ @param[in] Offset Offset into the block at which to begin reading.
+ @param[in] NumBytes On input, indicates the requested read size. On
+ output, indicates the actual number of bytes read.
+ @param[in] Buffer Pointer to the buffer to read into.
**/
EFI_STATUS
-SmmStoreLibWrite (
+SmmStoreLibRead (
IN EFI_LBA Lba,
IN UINTN Offset,
IN UINTN *NumBytes,
@@ -212,6 +211,59 @@ SmmStoreLibWrite ( return EFI_INVALID_PARAMETER;
}
+ return ReadBlock (Lba, Offset, NumBytes, Buffer, SMMSTORE_CMD_RAW_READ);
+}
+
+/**
+ Read from an arbitrary flash location. The whole flash is represented as a
+ sequence of blocks.
+
+ @param[in] Lba The starting logical block index to read from.
+ @param[in] Offset Offset into the block at which to begin reading.
+ @param[in] NumBytes On input, indicates the requested read size. On
+ output, indicates the actual number of bytes read
+ @param[in] Buffer Pointer to the buffer to read into.
+
+**/
+EFI_STATUS
+SmmStoreLibReadAnyBlock (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ return ReadBlock (Lba, Offset, NumBytes, Buffer, SMMSTORE_CMD_USE_FULL_FLASH | SMMSTORE_CMD_RAW_READ);
+}
+
+/**
+ Write a flash block. The whole flash is represented as a
+ sequence of blocks.
+
+ @param[in] Lba The starting logical block index to write to.
+ @param[in] Offset Offset into the block at which to begin writing.
+ @param[in] NumBytes On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written
+ @param[in] Buffer Pointer to the data to write.
+ @param[in] WriteCmd Write command to use.
+
+ @note Validation of mSmmStoreInfo and Lba must be done by the calling code.
+
+**/
+STATIC
+EFI_STATUS
+WriteBlock (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN UINT8 WriteCmd
+ )
+{
if (((*NumBytes + Offset) > mSmmStoreInfo->BlockSize) ||
((*NumBytes + Offset) > mSmmStoreInfo->ComBufferSize))
{
@@ -224,7 +276,62 @@ SmmStoreLibWrite ( CopyMem ((VOID *)(UINTN)(mSmmStoreInfo->ComBuffer + Offset), Buffer, *NumBytes);
- return CallSmm (mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_WRITE, mArgComBufPhys);
+ return CallSmm (mSmmStoreInfo->ApmCmd, WriteCmd, mArgComBufPhys);
+}
+
+/**
+ Write to SmmStore
+
+ @param[in] Lba The starting logical block index to write to.
+ @param[in] Offset Offset into the block at which to begin writing.
+ @param[in] NumBytes On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written.
+ @param[in] Buffer Pointer to the data to write.
+
+**/
+EFI_STATUS
+SmmStoreLibWrite (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ if (Lba >= mSmmStoreInfo->NumBlocks) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return WriteBlock (Lba, Offset, NumBytes, Buffer, SMMSTORE_CMD_RAW_WRITE);
+}
+
+/**
+ Write to an arbitrary flash location. The whole flash is represented as a
+ sequence of blocks.
+
+ @param[in] Lba The starting logical block index to write to.
+ @param[in] Offset Offset into the block at which to begin writing.
+ @param[in] NumBytes On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written
+ @param[in] Buffer Pointer to the data to write.
+
+**/
+EFI_STATUS
+SmmStoreLibWriteAnyBlock (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ return WriteBlock (Lba, Offset, NumBytes, Buffer, SMMSTORE_CMD_USE_FULL_FLASH | SMMSTORE_CMD_RAW_WRITE);
}
/**
@@ -252,6 +359,31 @@ SmmStoreLibEraseBlock ( }
/**
+ Erase an arbitrary block of the flash. The whole flash is represented as a
+ sequence of blocks.
+
+ @param Lba The logical block index to erase.
+
+**/
+EFI_STATUS
+SmmStoreLibEraseAnyBlock (
+ IN EFI_LBA Lba
+ )
+{
+ if (mSmmStoreInfo == NULL) {
+ return EFI_NO_MEDIA;
+ }
+
+ mArgComBuf->Clear.BlockId = Lba;
+
+ return CallSmm (
+ mSmmStoreInfo->ApmCmd,
+ SMMSTORE_CMD_USE_FULL_FLASH | SMMSTORE_CMD_RAW_CLEAR,
+ mArgComBufPhys
+ );
+}
+
+/**
Fixup internal data so that EFI can be called in virtual mode.
Converts any pointers in lib to virtual mode. This function is meant to
be invoked on gEfiEventVirtualAddressChangeGuid event when the library is
diff --git a/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.h b/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.h index d91b8e13c6..11a42a7289 100644 --- a/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.h +++ b/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.h @@ -1,6 +1,7 @@ /** @file SmmStore.h
Copyright (c) 2022, 9elements GmbH<BR>
+ Copyright (c) 2025, 3mdeb Sp. z o.o.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -19,6 +20,9 @@ #define SMMSTORE_CMD_RAW_WRITE 6
#define SMMSTORE_CMD_RAW_CLEAR 7
+/* Used by capsule updates as a standalone command or modifier to v2 commands */
+#define SMMSTORE_CMD_USE_FULL_FLASH 0x80
+
/*
* This allows the payload to store raw data in the flash regions.
* This can be used by a FaultTolerantWrite implementation, that uses at least
diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c index 3391da8446..9840368f2f 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c @@ -358,7 +358,7 @@ HandOffToDxeCore ( DEBUG ((
DEBUG_INFO,
- "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n",
+ "%a() Stack Base: 0x%llx, Stack Size: 0x%x\n",
__func__,
BaseOfStack,
STACK_SIZE
diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c index d0f3143004..867765f6ef 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c @@ -356,7 +356,7 @@ HandOffToDxeCore ( DEBUG ((
DEBUG_INFO,
- "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n",
+ "%a() Stack Base: 0x%llx, Stack Size: 0x%x\n",
__func__,
BaseOfStack,
STACK_SIZE
diff --git a/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFunc.c index ecd2493371..ff4841bf85 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFunc.c +++ b/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFunc.c @@ -60,7 +60,7 @@ HandOffToDxeCore ( //
UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack, STACK_SIZE);
- DEBUG ((DEBUG_INFO, "DXE Core new stack at %x, stack pointer at %x\n", BaseOfStack, TopOfStack));
+ DEBUG ((DEBUG_INFO, "DXE Core new stack at %llx, stack pointer at %llx\n", BaseOfStack, TopOfStack));
//
// Transfer the control to the entry point of DxeCore.
diff --git a/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFuncFit.c b/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFuncFit.c index e74c4fae4c..e92c4c34f9 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFuncFit.c +++ b/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFuncFit.c @@ -1,8 +1,8 @@ /** @file
- x64-specifc functionality for DxeLoad.
+ RISC-V specific functionality for DxeLoad.
-Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
+ Copyright (C) 2023, Rivos Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c index 468c36625c..343676d892 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c @@ -342,6 +342,8 @@ BuildHobFromBl ( ACPI_BOARD_INFO *AcpiBoardInfo;
SMMSTORE_INFO SmmStoreInfo;
SMMSTORE_INFO *NewSmmStoreInfo;
+ FIRMWARE_INFO FirmwareInfo;
+ FIRMWARE_INFO *NewFirmwareInfo;
EFI_PEI_GRAPHICS_INFO_HOB GfxInfo;
EFI_PEI_GRAPHICS_INFO_HOB *NewGfxInfo;
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo;
@@ -400,6 +402,17 @@ BuildHobFromBl ( }
//
+ // Create guid hob for firmware information
+ //
+ Status = ParseFirmwareInfo (&FirmwareInfo);
+ if (!EFI_ERROR (Status)) {
+ NewFirmwareInfo = BuildGuidHob (&gEfiFirmwareInfoHobGuid, sizeof (FirmwareInfo));
+ ASSERT (NewFirmwareInfo != NULL);
+ CopyMem (NewFirmwareInfo, &FirmwareInfo, sizeof (FirmwareInfo));
+ DEBUG ((DEBUG_INFO, "Created firmware info hob\n"));
+ }
+
+ //
// Create SmBios table Hob
//
SmBiosTableHob = BuildGuidHob (&gUniversalPayloadSmbiosTableGuid, sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE));
@@ -457,6 +470,15 @@ BuildHobFromBl ( return Status;
}
+ //
+ // Import update capsules, if there are any.
+ //
+ Status = ParseCapsules (BuildCvHob);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Error when importing update capsules, Status = %r\n", Status));
+ return Status;
+ }
+
return EFI_SUCCESS;
}
@@ -512,6 +534,7 @@ _ModuleEntryPoint ( EFI_PEI_HOB_POINTERS Hob;
SERIAL_PORT_INFO SerialPortInfo;
UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *UniversalSerialPort;
+ EFI_HOB_HANDOFF_INFO_TABLE *HobInfo;
Status = PcdSet64S (PcdBootloaderParameter, BootloaderParameter);
ASSERT_EFI_ERROR (Status);
@@ -535,7 +558,7 @@ _ModuleEntryPoint ( HobMemTop = HobMemBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
- HobConstructor ((VOID *)MemBase, (VOID *)HobMemTop, (VOID *)HobMemBase, (VOID *)HobMemTop);
+ HobInfo = HobConstructor ((VOID *)MemBase, (VOID *)HobMemTop, (VOID *)HobMemBase, (VOID *)HobMemTop);
//
// Build serial port info
@@ -592,6 +615,13 @@ _ModuleEntryPoint ( DEBUG ((DEBUG_INFO, "DxeCoreEntryPoint = 0x%lx\n", DxeCoreEntryPoint));
//
+ // Switch to update mode if there is at least one capsule.
+ //
+ if (GetFirstHob (EFI_HOB_TYPE_UEFI_CAPSULE) != NULL) {
+ HobInfo->BootMode = BOOT_ON_FLASH_UPDATE;
+ }
+
+ //
// Mask off all legacy 8259 interrupt sources
//
IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h index b6fe5ef738..87e1564798 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h @@ -38,6 +38,7 @@ #include <UniversalPayload/SerialPortInfo.h>
#include <UniversalPayload/DeviceTree.h>
#include <Guid/PcdDataBaseSignatureGuid.h>
+#include <Guid/FirmwareInfoGuid.h>
#include <Guid/SmmStoreInfoGuid.h>
#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf index 702be0d7a0..8795f1b17d 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf @@ -71,6 +71,7 @@ gUniversalPayloadSmbiosTableGuid
gUniversalPayloadAcpiTableGuid
gUniversalPayloadSerialPortInfoGuid
+ gEfiFirmwareInfoHobGuid
gEfiSmmStoreInfoHobGuid
[FeaturePcd.IA32]
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index 491e5428b9..51ddcc58e9 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -46,6 +46,7 @@ gUplPciSegmentInfoHobGuid = {0x37e0e3a9, 0xb3fc, 0x4e85, { 0x97, 0x2b, 0x40, 0x82, 0xfc, 0x79, 0x40, 0x54 } }
gEfiSmmStoreInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 } }
+ gEfiFirmwareInfoHobGuid = { 0xe0653829, 0x274e, 0x4b1e, { 0x87, 0x2d, 0xa2, 0x20, 0xf5, 0xaf, 0x8f, 0x3d } }
[Ppis]
gEfiPayLoadHobBasePpiGuid = { 0xdbe23aa1, 0xa342, 0x4b97, {0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89} }
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 76e4e58f50..db4875e7c4 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -43,11 +43,19 @@ DEFINE USE_CBMEM_FOR_CONSOLE = FALSE
DEFINE BOOTSPLASH_IMAGE = FALSE
DEFINE NVME_ENABLE = TRUE
- DEFINE CAPSULE_SUPPORT = FALSE
DEFINE LOCKBOX_SUPPORT = FALSE
DEFINE LOAD_OPTION_ROMS = FALSE
#
+ # Capsule updates
+ #
+ # CAPSULE_MAIN_FW_GUID specifies GUID to be used by FmpDxe when
+ # CAPSULE_SUPPORT is set to TRUE
+ #
+ DEFINE CAPSULE_SUPPORT = FALSE
+ DEFINE CAPSULE_MAIN_FW_GUID =
+
+ #
# Crypto Support
#
DEFINE CRYPTO_PROTOCOL_SUPPORT = FALSE
@@ -278,8 +286,23 @@ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
!if $(CAPSULE_SUPPORT) == TRUE
- CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+ !if $(BOOTSPLASH_IMAGE)
+ # Note, however, that DisplayUpdateProgressLibGraphics aborts firmware
+ # update if GOP is missing, so text progress works in more environments.
+ DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf
+ !else
+ DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibText/DisplayUpdateProgressLibText.inf
+ !endif
+ # If there are no specific checks to do, null-library suffices
+ CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+ FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+ FmpDependencyCheckLib|FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
+ # No need to save/restore FMP dependencies unless they are utilized
+ FmpDependencyDeviceLib|FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf
+ FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
+ FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
!else
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
!endif
@@ -346,7 +369,6 @@ !if $(VARIABLE_SUPPORT) == "EMU"
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
!elseif $(VARIABLE_SUPPORT) == "SMMSTORE"
- SmmStoreLib|UefiPayloadPkg/Library/SmmStoreLib/SmmStoreLib.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
!elseif $(VARIABLE_SUPPORT) == "SPI"
PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
@@ -354,6 +376,9 @@ S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf
MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
!endif
+!if $(VARIABLE_SUPPORT) == "SMMSTORE" || ($(CAPSULE_SUPPORT) && $(BOOTLOADER) == "COREBOOT")
+ SmmStoreLib|UefiPayloadPkg/Library/SmmStoreLib/SmmStoreLib.inf
+!endif
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
@@ -496,6 +521,9 @@ !if $(PERFORMANCE_MEASUREMENT_ENABLE)
PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
!endif
+!if $(CAPSULE_SUPPORT) == TRUE
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
+!endif
[LibraryClasses.common.UEFI_DRIVER,LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -554,6 +582,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDegradeResourceForOptionRom|FALSE
+ ## Whether capsules are allowed to persist across reset.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|$(CAPSULE_SUPPORT)
[PcdsFeatureFlag.X64]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
@@ -592,6 +622,9 @@ gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1800000
+ ## Whether FMP capsules are enabled.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleFmpSupport|$(CAPSULE_SUPPORT)
+
!if $(CRYPTO_PROTOCOL_SUPPORT) == TRUE
!if $(CRYPTO_DRIVER_EXTERNAL_SUPPORT) == FALSE
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.HmacSha256.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
@@ -944,6 +977,31 @@ NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
}
MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
+!if $(CAPSULE_SUPPORT) == TRUE
+ # Build FmpDxe meant for the inclusion into an update capsule as an embedded driver.
+ FmpDevicePkg/FmpDxe/FmpDxe.inf {
+ <Defines>
+ # FmpDxe interprets its FILE_GUID as firmware GUID. This allows including
+ # multiple FmpDxe instances along each other targeting different
+ # components.
+ FILE_GUID = $(CAPSULE_MAIN_FW_GUID)
+ <PcdsFixedAtBuild>
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"System Firmware"
+ # Public certificate used for validation of UEFI capsules
+ #
+ # See BaseTools/Source/Python/Pkcs7Sign/Readme.md for more details on such
+ # PCDs and include files.
+ !include BaseTools/Source/Python/Pkcs7Sign/TestRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
+ <LibraryClasses>
+!if $(BOOTLOADER) == "COREBOOT"
+ FmpDeviceLib|UefiPayloadPkg/Library/FmpDeviceSmmLib/FmpDeviceSmmLib.inf
+!else
+ # TODO: provide platform-specific implementation of firmware flashing
+ FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf
+!endif
+ }
+ MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf
+!endif
MdeModulePkg/Universal/Metronome/Metronome.inf
diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 06ca20761a..28afae75dd 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -369,6 +369,13 @@ INF ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf INF ShellPkg/Application/Shell/Shell.inf
!endif
+#
+# Capsules
+#
+!if $(CAPSULE_SUPPORT) == TRUE
+INF MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf
+!endif
+
!if $(UNIVERSAL_PAYLOAD) == TRUE
!if $(SECURE_BOOT_ENABLE) == TRUE
diff --git a/pip-requirements.txt b/pip-requirements.txt index d2365e7590..ec5502ecc2 100644 --- a/pip-requirements.txt +++ b/pip-requirements.txt @@ -17,3 +17,5 @@ edk2-pytool-extensions~=0.29.11 antlr4-python3-runtime==4.9
lcov-cobertura==2.1.1
regex==2024.11.6
+pylibfdt==1.7.2.post1
+pefile
|