diff --git a/OvmfPkg/Include/Library/QemuFwCfgLib.h b/OvmfPkg/Include/Library/QemuFwCfgLib.h index 2ad96c02979d..b83c632ebbd4 100644 --- a/OvmfPkg/Include/Library/QemuFwCfgLib.h +++ b/OvmfPkg/Include/Library/QemuFwCfgLib.h @@ -164,4 +164,23 @@ QemuFwCfgFindFile ( OUT UINTN *Size ); +/** + OVMF reads configuration data from QEMU via fw_cfg. + For Td-Guest VMM is out of TCB and the configuration data is untrusted. + From the security perpective the configuration data shall be measured + before it is consumed. + This function reads the fw_cfg items and cached them. In the meanwhile these + fw_cfg items are measured as well. This is to avoid changing the order when + reading the fw_cfg process, which depends on multiple factors(depex, order in + the Firmware volume). + + @retval RETURN_SUCCESS - Successfully cache with measurement + @retval Others - As the error code indicates + */ +RETURN_STATUS +EFIAPI +QemuFwCfgInitCache ( + VOID + ); + #endif diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 6d3e0a5f1c6e..a4824dde52ca 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -240,7 +240,7 @@ PeilessStartupLib|OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf TdxMeasurementLib|OvmfPkg/IntelTdx/TdxMeasurementLib/SecPeiTdxMeasurementLib.inf - + TpmMeasurementLib|SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.inf [LibraryClasses.common.DXE_CORE] HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c index 42db1a61cb50..ed87d9244705 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c @@ -7,6 +7,8 @@ **/ #include +#include +#include #include #include #include @@ -47,6 +49,10 @@ InitializePlatform ( DEBUG ((DEBUG_INFO, "InitializePlatform in Pei-less boot\n")); PlatformDebugDumpCmos (); + if (RETURN_ERROR (QemuFwCfgInitCache ())) { + DEBUG ((DEBUG_ERROR, "QemuFwCfgInitCache failed !\n")); + } + PlatformInfoHob->DefaultMaxCpuNumber = 64; PlatformInfoHob->PcdPciMmio64Size = 0x800000000; diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCache.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCache.c new file mode 100644 index 000000000000..b80c9f1323bb --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCache.c @@ -0,0 +1,242 @@ +/** @file + QemuFwCfg cached feature related functions. + Copyright (c) 2025, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include "QemuFwCfgLibInternal.h" + +/** + Get the pointer to the cached fw_cfg item. + @param[in] Item The fw_cfg item to be retrieved. + @retval FW_CFG_CACHED_ITEM Pointer to the cached fw_cfg item. + @retval NULL The fw_cfg item is not cached. +**/ +FW_CFG_CACHED_ITEM * +InternalQemuFwCfgItemCached ( + IN FIRMWARE_CONFIG_ITEM Item + ) +{ + UINT16 HobSize; + UINT16 Offset; + BOOLEAN Cached; + FW_CFG_CACHED_ITEM *CachedItem; + EFI_HOB_GUID_TYPE *GuidHob; + UINTN CachedItemSize; + UINT16 SelectItem; + + if (!InternalQemuFwCfgCacheEnable ()) { + return NULL; + } + + SelectItem = (UINT16)Item; + GuidHob = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid); + + HobSize = GET_GUID_HOB_DATA_SIZE (GuidHob); + Offset = sizeof (EFI_HOB_GUID_TYPE) + sizeof (FW_CFG_CACHE_WORK_AREA); + if (Offset > HobSize) { + return NULL; + } + + CachedItem = InternalQemuFwCfgCacheFirstItem (); + + Cached = FALSE; + while (Offset < HobSize) { + if (CachedItem->FwCfgItem == SelectItem) { + Cached = TRUE; + break; + } + + CachedItemSize = CachedItem->DataSize + sizeof (FW_CFG_CACHED_ITEM); + Offset += (UINT16)CachedItemSize; + CachedItem = (FW_CFG_CACHED_ITEM *)((UINT8 *)CachedItem + CachedItemSize); + } + + return Cached ? CachedItem : NULL; +} + +/** + Clear the FW_CFG_CACHE_WORK_AREA. +**/ +VOID +InternalQemuFwCfgCacheResetWorkArea ( + VOID + ) +{ + FW_CFG_CACHE_WORK_AREA *FwCfgCacheWorkArea; + + FwCfgCacheWorkArea = InternalQemuFwCfgCacheGetWorkArea (); + if (FwCfgCacheWorkArea != NULL) { + FwCfgCacheWorkArea->FwCfgItem = 0; + FwCfgCacheWorkArea->Offset = 0; + FwCfgCacheWorkArea->Reading = FALSE; + } +} + +/** + Check if reading from FwCfgCache is ongoing. + @retval TRUE Reading from FwCfgCache is ongoing. + @retval FALSE Reading from FwCfgCache is not ongoing. +**/ +BOOLEAN +InternalQemuFwCfgCacheReading ( + VOID + ) +{ + BOOLEAN Reading; + FW_CFG_CACHE_WORK_AREA *FwCfgCacheWorkArea; + + Reading = FALSE; + FwCfgCacheWorkArea = InternalQemuFwCfgCacheGetWorkArea (); + if (FwCfgCacheWorkArea != NULL) { + Reading = FwCfgCacheWorkArea->Reading; + } + + return Reading; +} + +BOOLEAN +InternalQemuFwCfgCacheSelectItem ( + IN FIRMWARE_CONFIG_ITEM Item + ) +{ + FW_CFG_CACHE_WORK_AREA *FwCfgCacheWorkArea; + + // Walk thru cached fw_items to see if Item is cached. + if (InternalQemuFwCfgItemCached (Item) == NULL) { + return FALSE; + } + + FwCfgCacheWorkArea = InternalQemuFwCfgCacheGetWorkArea (); + if (FwCfgCacheWorkArea == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Invalid FwCfg Cache Work Area\n", __func__)); + return FALSE; + } + + FwCfgCacheWorkArea->FwCfgItem = (UINT16)Item; + FwCfgCacheWorkArea->Offset = 0; + FwCfgCacheWorkArea->Reading = TRUE; + + return TRUE; +} + +/** + Get the first cached item. + @retval FW_CFG_CACHED_ITEM The first cached item. + @retval NULL There is no cached item. +**/ +FW_CFG_CACHED_ITEM * +InternalQemuFwCfgCacheFirstItem ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + UINT16 Offset; + + if (!InternalQemuFwCfgCacheEnable ()) { + return NULL; + } + + GuidHob = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid); + + Offset = sizeof (FW_CFG_CACHE_WORK_AREA); + + return (FW_CFG_CACHED_ITEM *)((UINT8 *)GET_GUID_HOB_DATA (GuidHob) + Offset); +} + +/** + Read the fw_cfg data from Cache. + @param[in] Size Data size to be read + @param[in] Buffer Pointer to the buffer to which data is written + @retval EFI_SUCCESS - Successfully + @retval Others - As the error code indicates +**/ +EFI_STATUS +InternalQemuFwCfgCacheReadBytes ( + IN UINTN Size, + IN OUT VOID *Buffer + ) +{ + FW_CFG_CACHE_WORK_AREA *FwCfgCacheWorkArea; + FW_CFG_CACHED_ITEM *CachedItem; + UINTN ReadSize; + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + FwCfgCacheWorkArea = InternalQemuFwCfgCacheGetWorkArea (); + if (FwCfgCacheWorkArea == NULL) { + return RETURN_NOT_FOUND; + } + + if (!FwCfgCacheWorkArea->Reading) { + return RETURN_NOT_READY; + } + + CachedItem = InternalQemuFwCfgItemCached (FwCfgCacheWorkArea->FwCfgItem); + if (CachedItem == NULL) { + return RETURN_NOT_FOUND; + } + + if (CachedItem->DataSize - FwCfgCacheWorkArea->Offset > Size) { + ReadSize = Size; + } else { + ReadSize = CachedItem->DataSize - FwCfgCacheWorkArea->Offset; + } + + CopyMem (Buffer, (UINT8 *)CachedItem + sizeof (FW_CFG_CACHED_ITEM) + FwCfgCacheWorkArea->Offset, ReadSize); + FwCfgCacheWorkArea->Offset += (UINT32)ReadSize; + + DEBUG ((DEBUG_INFO, "%a: found Item 0x%x in FwCfg Cache\n", __func__, FwCfgCacheWorkArea->FwCfgItem)); + return RETURN_SUCCESS; +} + +RETURN_STATUS +InternalQemuFwCfgItemInCacheList ( + IN CONST CHAR8 *Name, + OUT FIRMWARE_CONFIG_ITEM *Item, + OUT UINTN *Size + ) +{ + UINT16 HobSize; + UINT16 Offset; + FW_CFG_CACHED_ITEM *CachedItem; + EFI_HOB_GUID_TYPE *GuidHob; + UINTN CachedItemSize; + + CachedItem = InternalQemuFwCfgCacheFirstItem (); + if (CachedItem == NULL) { + return RETURN_NOT_FOUND; + } + + GuidHob = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid); + if (GuidHob == NULL) { + return RETURN_NOT_FOUND; + } + + HobSize = GET_GUID_HOB_DATA_SIZE (GuidHob); + Offset = sizeof (EFI_HOB_GUID_TYPE) + sizeof (FW_CFG_CACHE_WORK_AREA); + if (Offset > HobSize) { + return RETURN_NOT_FOUND; + } + + while (Offset < HobSize) { + if (AsciiStrCmp (Name, CachedItem->FileName) == 0) { + *Item = CachedItem->FwCfgItem; + *Size = CachedItem->DataSize; + return RETURN_SUCCESS; + } + + CachedItemSize = CachedItem->DataSize + sizeof (FW_CFG_CACHED_ITEM); + Offset += (UINT16)CachedItemSize; + CachedItem = (FW_CFG_CACHED_ITEM *)((UINT8 *)CachedItem + CachedItemSize); + } + + return RETURN_NOT_FOUND; +} diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCacheInit.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCacheInit.c new file mode 100644 index 000000000000..b37058bcc77e --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgCacheInit.c @@ -0,0 +1,198 @@ +/** @file + QemuFwCfg cached feature related functions. + Copyright (c) 2025, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include "QemuFwCfgLibInternal.h" +#include +#include +#include +#include + +#define EV_POSTCODE_INFO_QEMU_FW_CFG_DATA "QEMU FW CFG" +#define QEMU_FW_CFG_SIZE sizeof (EV_POSTCODE_INFO_QEMU_FW_CFG_DATA) + +#pragma pack(1) +typedef struct { + CHAR8 FileName[QEMU_FW_CFG_FNAME_SIZE]; + BOOLEAN NeedMeasure; + UINT16 FwCfgItem; + UINT32 FwCfgSize; +} CACHE_FW_CFG_STRCUT; + +typedef struct { + UINT8 FwCfg[QEMU_FW_CFG_SIZE]; + UINT8 FwCfgFileName[QEMU_FW_CFG_FNAME_SIZE]; +} FW_CFG_EVENT; + +#pragma pack() + +#define E820_FWCFG_FILE \ + "etc/e820" + +#define SYSTEM_STATES_FWCFG_FILE \ + "etc/system-states" + +#define EXTRA_PCI_ROOTS_FWCFG_FILE \ + "etc/extra-pci-roots" + +#define EXTRA_PCI_ROOTS_FWCFG_SIZE sizeof (UINT64) + +#define BOOT_MENU_FWCFG_NAME "BootMenu" + +#define BOOT_MENU_FWCFG_SIZE sizeof (UINT16) + +#define BOOT_MENU_WAIT_TIME_FWCFG_FILE \ + "etc/boot-menu-wait" + +#define BOOT_MENU_WAIT_TIME_FWCFG_SIZE sizeof (UINT16) + +#define RESERVED_MEMORY_END_FWCFG_FILE \ + "etc/reserved-memory-end" + +#define RESERVED_MEMORY_END_FWCFG_SIZE sizeof (UINT64) + +#define PCI_MMIO64_FWCFG_FILE \ + "opt/ovmf/X-PciMmio64Mb" + +#define BOOTORDER_FWCFG_FILE \ + "bootorder" + +#define INVALID_FW_CFG_ITEM 0xFFFF + +STATIC CONST CACHE_FW_CFG_STRCUT mCacheFwCfgList[] = { + { E820_FWCFG_FILE, FALSE, INVALID_FW_CFG_ITEM, 0 }, + { SYSTEM_STATES_FWCFG_FILE, FALSE, INVALID_FW_CFG_ITEM, 0 }, + { EXTRA_PCI_ROOTS_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, EXTRA_PCI_ROOTS_FWCFG_SIZE }, + { BOOT_MENU_FWCFG_NAME, TRUE, QemuFwCfgItemBootMenu, BOOT_MENU_FWCFG_SIZE }, + { BOOT_MENU_WAIT_TIME_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, BOOT_MENU_WAIT_TIME_FWCFG_SIZE }, + { RESERVED_MEMORY_END_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, RESERVED_MEMORY_END_FWCFG_SIZE }, + { PCI_MMIO64_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, 0 }, + { BOOTORDER_FWCFG_FILE, TRUE, INVALID_FW_CFG_ITEM, 0 }, +}; + +#define CACHE_FW_CFG_COUNT sizeof (mCacheFwCfgList)/sizeof (mCacheFwCfgList[0]) + +EFI_STATUS +InternalQemuFwCfgInitCache ( + VOID + ) +{ + UINTN TotalSize; + UINT32 Index; + UINT32 Count; + UINTN FwCfgSize; + FIRMWARE_CONFIG_ITEM FwCfgItem; + CACHE_FW_CFG_STRCUT CacheFwCfgList[CACHE_FW_CFG_COUNT]; + FW_CFG_CACHED_ITEM *CachedItem; + UINT8 *ItemData; + UINT8 *FwCfhHobData; + + CopyMem (CacheFwCfgList, mCacheFwCfgList, sizeof (mCacheFwCfgList)); + Count = CACHE_FW_CFG_COUNT; + TotalSize = sizeof (FW_CFG_CACHE_WORK_AREA); + + for (Index = 0; Index < Count; Index++) { + if (CacheFwCfgList[Index].FwCfgItem != INVALID_FW_CFG_ITEM) { + TotalSize += (CacheFwCfgList[Index].FwCfgSize + sizeof (FW_CFG_CACHED_ITEM)); + continue; + } + + if (EFI_ERROR (QemuFwCfgFindFile (CacheFwCfgList[Index].FileName, &FwCfgItem, &FwCfgSize))) { + continue; + } + + if (FwCfgSize == 0) { + continue; + } + + if ((CacheFwCfgList[Index].FwCfgSize != 0) && (FwCfgSize != CacheFwCfgList[Index].FwCfgSize)) { + continue; + } + + CacheFwCfgList[Index].FwCfgItem = (UINT16)FwCfgItem; + CacheFwCfgList[Index].FwCfgSize = (UINT32)FwCfgSize; + TotalSize += (FwCfgSize + sizeof (FW_CFG_CACHED_ITEM)); + } + + DEBUG ((DEBUG_INFO, "%a: FW_CFG TotalSize is %d (Bytes)\n", __func__, TotalSize)); + + if (TotalSize < (sizeof (FW_CFG_CACHED_ITEM) + sizeof (FW_CFG_CACHE_WORK_AREA))) { + return EFI_ABORTED; + } + + FwCfhHobData = BuildGuidHob (&gOvmfFwCfgInfoHobGuid, TotalSize); + if (FwCfhHobData == NULL) { + DEBUG ((DEBUG_ERROR, "%a: BuildGuidHob Failed with TotalSize(0x%x)\n", __func__, TotalSize)); + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (FwCfhHobData, TotalSize); + + FW_CFG_CACHE_WORK_AREA *FwCfgCacheWorkArea; + + FwCfgCacheWorkArea = (FW_CFG_CACHE_WORK_AREA *)FwCfhHobData; + FwCfgCacheWorkArea->CacheReady = FALSE; + + CachedItem = (FW_CFG_CACHED_ITEM *)(FwCfhHobData + sizeof (FW_CFG_CACHE_WORK_AREA)); + + for (Index = 0; Index < Count; Index++) { + if (CacheFwCfgList[Index].FwCfgItem == INVALID_FW_CFG_ITEM) { + continue; + } + + DEBUG (( + DEBUG_INFO, + "%a: Name: %a Item:0x%x Size: 0x%x \n", + __func__, + CacheFwCfgList[Index].FileName, + CacheFwCfgList[Index].FwCfgItem, + CacheFwCfgList[Index].FwCfgSize + )); + CachedItem->FwCfgItem = CacheFwCfgList[Index].FwCfgItem; + CachedItem->DataSize = CacheFwCfgList[Index].FwCfgSize; + CopyMem (CachedItem->FileName, CacheFwCfgList[Index].FileName, QEMU_FW_CFG_FNAME_SIZE); + + ItemData = (UINT8 *)CachedItem + sizeof (FW_CFG_CACHED_ITEM); + + QemuFwCfgSelectItem (CacheFwCfgList[Index].FwCfgItem); + QemuFwCfgReadBytes (CacheFwCfgList[Index].FwCfgSize, ItemData); + + if (CacheFwCfgList[Index].NeedMeasure == FALSE) { + CachedItem = (FW_CFG_CACHED_ITEM *)((UINT8 *)CachedItem + sizeof (FW_CFG_CACHED_ITEM) + CachedItem->DataSize); + continue; + } + + if (TdIsEnabled ()) { + FW_CFG_EVENT FwCfgEvent; + EFI_STATUS Status; + + ZeroMem (&FwCfgEvent, sizeof (FW_CFG_EVENT)); + CopyMem (&FwCfgEvent.FwCfg, EV_POSTCODE_INFO_QEMU_FW_CFG_DATA, sizeof (EV_POSTCODE_INFO_QEMU_FW_CFG_DATA)); + CopyMem (&FwCfgEvent.FwCfgFileName, CacheFwCfgList[Index].FileName, QEMU_FW_CFG_FNAME_SIZE); + + Status = TpmMeasureAndLogData ( + 1, + EV_PLATFORM_CONFIG_FLAGS, + (VOID *)&FwCfgEvent, + sizeof (FwCfgEvent), + (VOID *)ItemData, + CacheFwCfgList[Index].FwCfgSize + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "TpmMeasureAndLogData failed with %r\n", Status)); + } + } + + CachedItem = (FW_CFG_CACHED_ITEM *)((UINT8 *)CachedItem + sizeof (FW_CFG_CACHED_ITEM) + CachedItem->DataSize); + } + + FwCfgCacheWorkArea->CacheReady = TRUE; + return EFI_SUCCESS; +} diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c index c86f5914c72c..c8d1e1c87689 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c @@ -29,6 +29,8 @@ STATIC BOOLEAN mQemuFwCfgDmaSupported; STATIC EDKII_IOMMU_PROTOCOL *mIoMmuProtocol; +STATIC FW_CFG_CACHE_WORK_AREA mFwCfgCacheWorkArea = { 0 }; + /** Returns a boolean indicating if the firmware configuration interface is available or not. @@ -496,3 +498,54 @@ InternalQemuFwCfgDmaBytes ( UnmapFwCfgDmaDataBuffer (DataMapping); } } + +/** + Check if fw_cfg cache is ready. + + @retval TRUE Cache is ready + @retval FALSE Cache is not ready +**/ +BOOLEAN +InternalQemuFwCfgCacheEnable ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + FW_CFG_CACHE_WORK_AREA *FwCfgCacheWrokArea; + + GuidHob = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid); + if (GuidHob == NULL) { + return FALSE; + } + + FwCfgCacheWrokArea = (FW_CFG_CACHE_WORK_AREA *)GET_GUID_HOB_DATA (GuidHob); + return FwCfgCacheWrokArea->CacheReady; +} + +/** + Get the pointer to the FW_CFG_CACHE_WORK_AREA. This data is used as the + workarea to record the onging fw_cfg item and offset. + + @retval FW_CFG_CACHE_WORK_AREA Pointer to the FW_CFG_CACHE_WORK_AREA + @retval NULL FW_CFG_CACHE_WORK_AREA doesn't exist +**/ +FW_CFG_CACHE_WORK_AREA * +InternalQemuFwCfgCacheGetWorkArea ( + VOID + ) +{ + if (!InternalQemuFwCfgCacheEnable ()) { + return NULL; + } + + return &mFwCfgCacheWorkArea; +} + +RETURN_STATUS +EFIAPI +QemuFwCfgInitCache ( + VOID + ) +{ + return RETURN_UNSUPPORTED; +} diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf index 11fbcdab983a..51326807ef3e 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf @@ -30,6 +30,7 @@ QemuFwCfgLibInternal.h QemuFwCfgLib.c QemuFwCfgDxe.c + QemuFwCfgCache.c [Packages] MdePkg/MdePkg.dec @@ -42,6 +43,7 @@ DebugLib IoLib MemoryAllocationLib + HobLib [Protocols] gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES @@ -49,5 +51,8 @@ [Pcd] gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr +[Guids] + gOvmfFwCfgInfoHobGuid + [Depex] gEdkiiIoMmuProtocolGuid OR gIoMmuAbsentProtocolGuid diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c index 8e8f54ba3fac..30e2e6382d95 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c @@ -35,6 +35,13 @@ QemuFwCfgSelectItem ( ) { DEBUG ((DEBUG_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN)QemuFwCfgItem)); + + if (InternalQemuFwCfgCacheSelectItem (QemuFwCfgItem)) { + return; + } else { + InternalQemuFwCfgCacheResetWorkArea (); + } + IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)(UINTN)QemuFwCfgItem); } @@ -52,6 +59,11 @@ InternalQemuFwCfgReadBytes ( IN VOID *Buffer OPTIONAL ) { + if (InternalQemuFwCfgCacheEnable () && InternalQemuFwCfgCacheReading ()) { + InternalQemuFwCfgCacheReadBytes (Size, Buffer); + return; + } + if (InternalQemuFwCfgDmaIsAvailable () && (Size <= MAX_UINT32)) { InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ); return; @@ -260,6 +272,10 @@ QemuFwCfgFindFile ( return RETURN_UNSUPPORTED; } + if (!EFI_ERROR (InternalQemuFwCfgItemInCacheList (Name, Item, Size))) { + return RETURN_SUCCESS; + } + QemuFwCfgSelectItem (QemuFwCfgItemFileDir); Count = SwapBytes32 (QemuFwCfgRead32 ()); diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h index 6f7beb6ac1c7..d285df5ff03d 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibInternal.h @@ -11,6 +11,30 @@ #ifndef __QEMU_FW_CFG_LIB_INTERNAL_H__ #define __QEMU_FW_CFG_LIB_INTERNAL_H__ +#include +#include +#include +#include +#include +#include +#include + +#pragma pack(1) +typedef struct { + CHAR8 FileName[QEMU_FW_CFG_FNAME_SIZE]; + UINT16 FwCfgItem; + UINT32 DataSize; + // UINT8 *data +} FW_CFG_CACHED_ITEM; + +typedef struct { + BOOLEAN CacheReady; + UINT16 FwCfgItem; + UINT32 Offset; + BOOLEAN Reading; +} FW_CFG_CACHE_WORK_AREA; +#pragma pack() + /** Returns a boolean indicating if the firmware configuration interface is available for library-internal purposes. @@ -70,4 +94,107 @@ QemuFwCfgIsTdxGuest ( VOID ); +/** + Read the fw_cfg data from Cache. + @retval EFI_SUCCESS - Successfully + @retval Others - As the error code indicates +**/ +EFI_STATUS +InternalQemuFwCfgCacheReadBytes ( + IN UINTN Size, + IN OUT VOID *Buffer + ); + +/** + Select the fw_cfg item for reading from cache. If the fw_cfg item + is not cached, then it returns FALSE. + @param[in] Item The fw_cfg item to be selected + @retval TRUE The fw_cfg item is selected. + @retval FALSE The fw_cfg item is not selected. +**/ +BOOLEAN +InternalQemuFwCfgCacheSelectItem ( + IN FIRMWARE_CONFIG_ITEM Item + ); + +/** + Get the pointer to the FW_CFG_CACHE_WORK_AREA. This data is used as the + workarea to record the onging fw_cfg item and offset. + @retval FW_CFG_CACHE_WORK_AREA Pointer to the FW_CFG_CACHE_WORK_AREA + @retval NULL FW_CFG_CACHE_WORK_AREA doesn't exist +**/ +FW_CFG_CACHE_WORK_AREA * +InternalQemuFwCfgCacheGetWorkArea ( + VOID + ); + +/** + Clear the FW_CFG_CACHE_WORK_AREA. +**/ +VOID +InternalQemuFwCfgCacheResetWorkArea ( + VOID + ); + +/** + Check if fw_cfg cache is ready. + @retval TRUE Cache is ready + @retval FALSE Cache is not ready +**/ +BOOLEAN +InternalQemuFwCfgCacheEnable ( + VOID + ); + +/** + Get the pointer to the cached fw_cfg item. + @param[in] Item The fw_cfg item to be retrieved. + @retval FW_CFG_CACHED_ITEM Pointer to the cached fw_cfg item. + @retval NULL The fw_cfg item is not cached. +**/ +FW_CFG_CACHED_ITEM * +InternalQemuFwCfgItemCached ( + IN FIRMWARE_CONFIG_ITEM Item + ); + +/** + Check if reading from FwCfgCache is ongoing. + @retval TRUE Reading from FwCfgCache is ongoing. + @retval FALSE Reading from FwCfgCache is not ongoing. +**/ +BOOLEAN +InternalQemuFwCfgCacheReading ( + VOID + ); + +/** + Get the first cached item. + @retval FW_CFG_CACHED_ITEM The first cached item. + @retval NULL There is no cached item. +**/ +FW_CFG_CACHED_ITEM * +InternalQemuFwCfgCacheFirstItem ( + VOID + ); + +/** + Check if the fw_cfg file name is in cache. + @retval TRUE The item in cache. + @retval FALSE The item not in cache. +**/ +RETURN_STATUS +InternalQemuFwCfgItemInCacheList ( + IN CONST CHAR8 *Name, + OUT FIRMWARE_CONFIG_ITEM *Item, + OUT UINTN *Size + ); + +/** + init the fw_cfg info hob with optional measurement +**/ +EFI_STATUS +InternalQemuFwCfgInitCache ( + VOID + ); + #endif diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgNull.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgNull.c index 6a85ed65a024..3d070dd228a0 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgNull.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgNull.c @@ -197,3 +197,12 @@ QemuFwCfgFindFile ( { return RETURN_UNSUPPORTED; } + +RETURN_STATUS +EFIAPI +QemuFwCfgInitCache ( + VOID + ) +{ + return RETURN_UNSUPPORTED; +} diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c index da86a3c84c02..12ee2fc2724a 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c @@ -242,3 +242,75 @@ InternalQemuFwCfgDmaBytes ( // MemoryFence (); } + +/** + Get the pointer to the FW_CFG_CACHE_WORK_AREA. This data is used as the + workarea to record the onging fw_cfg item and offset. + + @retval FW_CFG_CACHE_WORK_AREA Pointer to the FW_CFG_CACHE_WORK_AREA + @retval NULL FW_CFG_CACHE_WORK_AREA doesn't exist +**/ +FW_CFG_CACHE_WORK_AREA * +InternalQemuFwCfgCacheGetWorkArea ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + if (!InternalQemuFwCfgCacheEnable ()) { + return NULL; + } + + GuidHob = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid); + + return (FW_CFG_CACHE_WORK_AREA *)(VOID *)GET_GUID_HOB_DATA (GuidHob); +} + +/** + Check if fw_cfg cache is ready. + + @retval TRUE Cache is ready + @retval FALSE Cache is not ready +**/ +BOOLEAN +InternalQemuFwCfgCacheEnable ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + FW_CFG_CACHE_WORK_AREA *FwCfgCacheWorkArea; + + GuidHob = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid); + if (GuidHob == NULL) { + return FALSE; + } + + FwCfgCacheWorkArea = (FW_CFG_CACHE_WORK_AREA *)GET_GUID_HOB_DATA (GuidHob); + return FwCfgCacheWorkArea->CacheReady; +} + +/** + OVMF reads configuration data from QEMU via fw_cfg. + For Td-Guest VMM is out of TCB and the configuration data is untrusted. + From the security perpective the configuration data shall be measured + before it is consumed. + This function reads the fw_cfg items and cached them. In the meanwhile these + fw_cfg items are measured as well. This is to avoid changing the order when + reading the fw_cfg process, which depends on multiple factors(depex, order in + the Firmware volume). + @retval RETURN_SUCCESS - Successfully cache with measurement + @retval Others - As the error code indicates + */ +RETURN_STATUS +EFIAPI +QemuFwCfgInitCache ( + VOID + ) +{ + if (EFI_ERROR (InternalQemuFwCfgInitCache ())) { + return RETURN_ABORTED; + } + + DEBUG ((DEBUG_INFO, "QemuFwCfgInitCache Pass!!!\n")); + return RETURN_SUCCESS; +} diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf index b1f548febcf7..7ecfa489e56a 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf @@ -30,10 +30,14 @@ QemuFwCfgLibInternal.h QemuFwCfgLib.c QemuFwCfgPei.c + QemuFwCfgCache.c + QemuFwCfgCacheInit.c [Packages] MdePkg/MdePkg.dec OvmfPkg/OvmfPkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec [LibraryClasses] BaseLib @@ -42,9 +46,11 @@ HobLib IoLib MemoryAllocationLib + TpmMeasurementLib [Guids] gUefiOvmfPkgPlatformInfoGuid + gOvmfFwCfgInfoHobGuid [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c index 63cfee934795..c3e41bf44816 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSec.c @@ -13,7 +13,10 @@ #include #include +#include #include +#include +#include #include "QemuFwCfgLibInternal.h" @@ -119,3 +122,107 @@ InternalQemuFwCfgDmaBytes ( ASSERT (FALSE); CpuDeadLoop (); } + +/** + Get the pointer to the FW_CFG_CACHE_WORK_AREA. This data is used as the + workarea to record the onging fw_cfg item and offset. + + @retval FW_CFG_CACHE_WORK_AREA Pointer to the FW_CFG_CACHE_WORK_AREA + @retval NULL FW_CFG_CACHE_WORK_AREA doesn't exist +**/ +FW_CFG_CACHE_WORK_AREA * +InternalQemuFwCfgCacheGetWorkArea ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + if (!InternalQemuFwCfgCacheEnable ()) { + return NULL; + } + + GuidHob = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid); + + return (FW_CFG_CACHE_WORK_AREA *)(VOID *)GET_GUID_HOB_DATA (GuidHob); +} + +/** + Check if fw_cfg cache is ready. + + @retval TRUE Cache is ready + @retval FALSE Cache is not ready +**/ +BOOLEAN +InternalQemuFwCfgCacheEnable ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + FW_CFG_CACHE_WORK_AREA *FwCfgCacheWorkArea; + TDX_WORK_AREA *TdxWorkArea; + + // InternalQemuFwCfgCacheEnable in QemuFwCfgSecLib might be called in a very early + // stage (at that moment HobList may not be set). So an additional check + // to the HobList is needed. + TdxWorkArea = (TDX_WORK_AREA *)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase); + if (TdxWorkArea == NULL) { + return FALSE; + } + + if (TdxWorkArea->SecTdxWorkArea.HobList == 0) { + return FALSE; + } + + GuidHob = GetFirstGuidHob (&gOvmfFwCfgInfoHobGuid); + if (GuidHob == NULL) { + return FALSE; + } + + FwCfgCacheWorkArea = (FW_CFG_CACHE_WORK_AREA *)GET_GUID_HOB_DATA (GuidHob); + return FwCfgCacheWorkArea->CacheReady; +} + +/** + OVMF reads configuration data from QEMU via fw_cfg. + For Td-Guest VMM is out of TCB and the configuration data is untrusted. + From the security perpective the configuration data shall be measured + before it is consumed. + This function reads the fw_cfg items and cached them. In the meanwhile these + fw_cfg items are measured as well. This is to avoid changing the order when + reading the fw_cfg process, which depends on multiple factors(depex, order in + the Firmware volume). + + @retval RETURN_SUCCESS - Successfully cache with measurement + @retval Others - As the error code indicates + */ +RETURN_STATUS +EFIAPI +QemuFwCfgInitCache ( + VOID + ) +{ + #ifdef TDX_PEI_LESS_BOOT + + if (!QemuFwCfgIsAvailable ()) { + DEBUG ((DEBUG_ERROR, "%a: Qemu Fw_Cfg is not Available! \n", __func__)); + return RETURN_UNSUPPORTED; + } + + TDX_WORK_AREA *TdxWorkArea; + + // InternalQemuFwCfgCacheEnable in QemuFwCfgSecLib might be called in a very early + // stage (at that moment HobList may not be set). So an additional check + // to the HobList is needed. + TdxWorkArea = (TDX_WORK_AREA *)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase); + if ((TdxWorkArea == NULL) || (TdxWorkArea->SecTdxWorkArea.HobList == 0)) { + return RETURN_UNSUPPORTED; + } + + if (EFI_ERROR (InternalQemuFwCfgInitCache ())) { + return RETURN_ABORTED; + } + + DEBUG ((DEBUG_INFO, "QemuFwCfgInitCache Pass!!!\n")); + return RETURN_SUCCESS; + #endif +} diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf index d34edd6e68df..ca50145c990d 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf @@ -28,10 +28,14 @@ QemuFwCfgLibInternal.h QemuFwCfgLib.c QemuFwCfgSec.c + QemuFwCfgCache.c + QemuFwCfgCacheInit.c [Packages] MdePkg/MdePkg.dec OvmfPkg/OvmfPkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec [LibraryClasses] BaseLib @@ -39,4 +43,12 @@ DebugLib IoLib MemoryAllocationLib + HobLib + TpmMeasurementLib + +[Guids] + gOvmfFwCfgInfoHobGuid + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 7e13d313e61b..e88a70739d12 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -173,6 +173,7 @@ gOvmfVariableGuid = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}} gQemuFirmwareResourceHobGuid = {0x3cc47b04, 0x0d3e, 0xaa64, {0x06, 0xa6, 0x4b, 0xdc, 0x9a, 0x2c, 0x61, 0x19}} gRtcRegisterBaseAddressHobGuid = {0x40435d97, 0xeb37, 0x4a4b, {0x7f, 0xad, 0xb7, 0xed, 0x72, 0xa1, 0x43, 0xc5}} + gOvmfFwCfgInfoHobGuid = {0xa291ce0e, 0xdc09, 0x11ee, {0x9e, 0xdb, 0x73, 0x49, 0xd7, 0x92, 0xaf, 0x51}} [Ppis] # PPI whose presence in the PPI database signals that the TPM base address diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c index 7b4ea1b82730..6a07a322e471 100644 --- a/OvmfPkg/PlatformPei/Platform.c +++ b/OvmfPkg/PlatformPei/Platform.c @@ -316,6 +316,10 @@ InitializePlatform ( TdxHelperBuildGuidHobForTdxMeasurement (); } + if (RETURN_ERROR (QemuFwCfgInitCache ())) { + DEBUG ((DEBUG_ERROR, "QemuFwCfgInitCache failed !\n")); + } + PlatformInfoHob->SmmSmramRequire = FeaturePcdGet (PcdSmmSmramRequire); PlatformInfoHob->SevEsIsEnabled = MemEncryptSevEsIsEnabled (); PlatformInfoHob->PcdPciMmio64Size = PcdGet64 (PcdPciMmio64Size); diff --git a/SecurityPkg/Library/SecTpmMeasurementLib/IntelTdx.c b/SecurityPkg/Library/SecTpmMeasurementLib/IntelTdx.c new file mode 100644 index 000000000000..95d69eddc502 --- /dev/null +++ b/SecurityPkg/Library/SecTpmMeasurementLib/IntelTdx.c @@ -0,0 +1,92 @@ +/** @file + Extend to RTMR and Build GuidHob for tdx measurement. + + Copyright (c) 2025, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Do a hash operation on a data buffer, extend a specific RTMR with the hash result, + and add an entry to the Event Log. + + @param[in] PcrIndex PCRIndex Index of the TPM PCR + @param[in] EventType Type of the Event. + @param[in] EventLog Physical address of the start of the data buffer. + @param[in] EventSize The length, in bytes, of the buffer referenced by EventLog. + @param[in] HashData Physical address of the start of the data buffer + to be hashed, extended, and logged. + @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData + + @retval EFI_SUCCESS The measurement is successful + @retval Others Other errors as indicated +**/ +EFI_STATUS +EFIAPI +TdxHashLogExtendEvent ( + IN UINT32 PcrIndex, + IN UINT32 EventType, + IN VOID *EventLog, + IN UINT32 LogLen, + IN VOID *HashData, + IN UINT64 HashDataLen + ) +{ + EFI_STATUS Status; + UINT8 Digest[SHA384_DIGEST_SIZE]; + UINT32 MrIndex; + + if ((EventLog == NULL) || (HashData == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (!TdIsEnabled ()) { + return EFI_UNSUPPORTED; + } + + MrIndex = TdxMeasurementMapPcrToMrIndex (PcrIndex); + if (MrIndex == CC_MR_INDEX_INVALID) { + return EFI_INVALID_PARAMETER; + } + + Status = TdxMeasurementHashAndExtendToRtmr ( + MrIndex - 1, + (UINT8 *)HashData, + (UINTN)HashDataLen, + Digest, + SHA384_DIGEST_SIZE + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: TdxMeasurementHashAndExtendToRtmr failed with %r\n", __func__, Status)); + return Status; + } + + Status = TdxMeasurementBuildGuidHob ( + MrIndex - 1, + EventType, + EventLog, + LogLen, + Digest, + SHA384_DIGEST_SIZE + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: TdxMeasurementBuildGuidHob failed with %r\n", __func__, Status)); + } + + return Status; +} diff --git a/SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.c b/SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.c new file mode 100644 index 000000000000..1ee5dc4bc731 --- /dev/null +++ b/SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.c @@ -0,0 +1,75 @@ +/** @file + TpmMeasurementLib SEC implementation. + + Copyright (c) 2025, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +/** + Do a hash operation on a data buffer, extend a specific RTMR with the hash result, + and add an entry to the Event Log. + + @param[in] PcrIndex PCRIndex Index of the TPM PCR + @param[in] EventType Type of the Event. + @param[in] EventLog Physical address of the start of the data buffer. + @param[in] EventSize The length, in bytes, of the buffer referenced by EventLog. + @param[in] HashData Physical address of the start of the data buffer + to be hashed, extended, and logged. + @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData + + @retval EFI_SUCCESS The measurement is successful + @retval Others Other errors as indicated +**/ +EFI_STATUS +EFIAPI +TdxHashLogExtendEvent ( + IN UINT32 PcrIndex, + IN UINT32 EventType, + IN VOID *EventLog, + IN UINT32 LogLen, + IN VOID *HashData, + IN UINT64 HashDataLen + ); + +/** + Tpm measure and log data, and extend the measurement result into a specific PCR. + + @param[in] PcrIndex PCR Index. + @param[in] EventType Event type. + @param[in] EventLog Measurement event log. + @param[in] LogLen Event log length in bytes. + @param[in] HashData The start of the data buffer to be hashed, extended. + @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_UNSUPPORTED TPM device not available. + @retval EFI_OUT_OF_RESOURCES Out of memory. + @retval EFI_DEVICE_ERROR The operation was unsuccessful. +**/ +EFI_STATUS +EFIAPI +TpmMeasureAndLogData ( + IN UINT32 PcrIndex, + IN UINT32 EventType, + IN VOID *EventLog, + IN UINT32 LogLen, + IN VOID *HashData, + IN UINT64 HashDataLen + ) +{ + if (CcProbe () == CcGuestTypeIntelTdx) { + return TdxHashLogExtendEvent (PcrIndex, EventType, EventLog, LogLen, HashData, HashDataLen); + } + + return EFI_UNSUPPORTED; +} diff --git a/SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.inf b/SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.inf new file mode 100644 index 000000000000..4728234f7d84 --- /dev/null +++ b/SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.inf @@ -0,0 +1,46 @@ +## @file +# TpmMeasurementLib SEC instance +# +# Copyright (c) 2025, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecTpmMeasurementLib + FILE_GUID = a608aadb-3809-4b7c-9ab9-c42ef79c508e + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TpmMeasurementLib | SEC + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = X64 +# + +[Sources] + IntelTdx.c + SecTpmMeasurementLib.c + +[Packages] + MdePkg/MdePkg.dec + CryptoPkg/CryptoPkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + HobLib + PcdLib + TdxLib + CcProbeLib + TdxMeasurementLib + BaseCryptLib + +[Guids] + gCcEventEntryHobGuid diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml index 26fedd179c23..1b389cc30631 100644 --- a/SecurityPkg/SecurityPkg.ci.yaml +++ b/SecurityPkg/SecurityPkg.ci.yaml @@ -51,6 +51,7 @@ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec", "SecurityPkg/SecurityPkg.dec", "StandaloneMmPkg/StandaloneMmPkg.dec", + "UefiCpuPkg/UefiCpuPkg.dec", "CryptoPkg/CryptoPkg.dec" ], # For host based unit tests diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 0b167032eacf..5ca1220da2c8 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -98,6 +98,9 @@ [LibraryClasses.RISCV64] RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf +[LibraryClasses.common.SEC] + TpmMeasurementLib|SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.inf + [LibraryClasses.common.PEIM] PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf @@ -267,7 +270,7 @@ SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf SecurityPkg/Library/FmpAuthenticationLibRsa2048Sha256/FmpAuthenticationLibRsa2048Sha256.inf - + SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLib.inf SecurityPkg/Library/PeiTpmMeasurementLib/PeiTpmMeasurementLib.inf SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf