From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web11.16251.1654390982054574984 for ; Sat, 04 Jun 2022 18:03:08 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=Vc6tcf54; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: min.m.xu@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1654390988; x=1685926988; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=K/+Dsxe0eom1stss54N0EozaGuBXMmbf+ZU3pzb7p0M=; b=Vc6tcf54G9FfOvAuJFm3ISWfWo/Z99s64XAkbroDbVY9rUR8XcLON/6b IptGsTQ4uChJYD8RSoHPcZ9zveXdMWkpuunkWSiH87I1JuDSI6bL78as5 wSf8hNQssrZlkYgG+BV0taINTpvee5nM7oQ6pYwfAL6zt4LhWf6tTrVZT P3QwblectDKxaHranLPxJTRCJ6L3uPItzhU/Caug70oOZzdUfkRzlmU/7 Ysw3seyWQpBD+X7/oNMEb8/QSvajSdpGyayVyz8lupb/7+sn1qVlAmRNT gYm7kYQE2ndsxkC+a3ybPcG/LLjohEyxiMz6hQ3KULxEoxjuXByEy9UB7 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10368"; a="276257319" X-IronPort-AV: E=Sophos;i="5.91,278,1647327600"; d="scan'208";a="276257319" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jun 2022 18:03:07 -0700 X-IronPort-AV: E=Sophos;i="5.91,278,1647327600"; d="scan'208";a="608039368" Received: from mxu9-mobl1.ccr.corp.intel.com ([10.249.171.120]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jun 2022 18:03:04 -0700 From: "Min Xu" To: devel@edk2.groups.io Cc: Min M Xu , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky , Gerd Hoffmann Subject: [PATCH 2/3] OvmfPkg: Implement MeasureHobList/MeasureFvImage Date: Sun, 5 Jun 2022 09:02:47 +0800 Message-Id: X-Mailer: git-send-email 2.29.2.windows.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Min M Xu MeasureHobList and MeasureFvImage once were implemented in SecMeasurementTdxLib. The intention of this patch-set is to refactor SecMeasurementTdxLib to be an instance of TpmMeasurementLib. So these 2 functions (MeasureHobList/MeasureFvImage) are moved to PeilessStartupLib. This is because: 1. RTMR based trusted boot is implemented in Config-B (See below link) 2. PeilessStartupLib is designed for PEI-less boot and it is the right place to do the measurement for Hoblist and Config-FV. Config-B: https://edk2.groups.io/g/devel/message/76367 Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Cc: Gerd Hoffmann Signed-off-by: Min Xu --- OvmfPkg/IntelTdx/IntelTdxX64.dsc | 2 +- OvmfPkg/Library/PeilessStartupLib/IntelTdx.c | 186 ++++++++++++++++++ .../PeilessStartupLib/PeilessStartup.c | 1 - .../PeilessStartupInternal.h | 36 ++++ .../PeilessStartupLib/PeilessStartupLib.inf | 2 +- 5 files changed, 224 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 43ab8bd089d9..a40f7228b98e 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -527,7 +527,7 @@ OvmfPkg/IntelTdx/Sec/SecMain.inf { NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf - SecMeasurementLib|OvmfPkg/Library/SecMeasurementLib/SecMeasurementLibTdx.inf + TpmMeasurementLib|SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf HashLib|SecurityPkg/Library/HashLibTdx/HashLibTdx.inf NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf diff --git a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c index d240d3b7719f..484fd21057c8 100644 --- a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c +++ b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c @@ -9,8 +9,34 @@ #include #include #include +#include +#include +#include +#include +#include + #include "PeilessStartupInternal.h" +#pragma pack(1) + +#define HANDOFF_TABLE_DESC "TdxTable" +typedef struct { + UINT8 TableDescriptionSize; + UINT8 TableDescription[sizeof (HANDOFF_TABLE_DESC)]; + UINT64 NumberOfTables; + EFI_CONFIGURATION_TABLE TableEntry[1]; +} TDX_HANDOFF_TABLE_POINTERS2; + +#define FV_HANDOFF_TABLE_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)" +typedef struct { + UINT8 BlobDescriptionSize; + UINT8 BlobDescription[sizeof (FV_HANDOFF_TABLE_DESC)]; + EFI_PHYSICAL_ADDRESS BlobBase; + UINT64 BlobLength; +} FV_HANDOFF_TABLE_POINTERS2; + +#pragma pack() + /** Check padding data all bit should be 1. @@ -161,3 +187,163 @@ TdxValidateCfv ( return TRUE; } + +/** + Measure the Hoblist passed from the VMM. + + @param[in] VmmHobList The Hoblist pass the firmware + + @retval EFI_SUCCESS Fv image is measured successfully + or it has been already measured. + @retval Others Other errors as indicated +**/ +EFI_STATUS +EFIAPI +MeasureHobList ( + IN CONST VOID *VmmHobList + ) +{ + EFI_PEI_HOB_POINTERS Hob; + TDX_HANDOFF_TABLE_POINTERS2 HandoffTables; + EFI_STATUS Status; + + if (!TdIsEnabled ()) { + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + + Hob.Raw = (UINT8 *)VmmHobList; + + // + // Parse the HOB list until end of list. + // + while (!END_OF_HOB_LIST (Hob)) { + Hob.Raw = GET_NEXT_HOB (Hob); + } + + // + // Init the log event for HOB measurement + // + + HandoffTables.TableDescriptionSize = sizeof (HandoffTables.TableDescription); + CopyMem (HandoffTables.TableDescription, HANDOFF_TABLE_DESC, sizeof (HandoffTables.TableDescription)); + HandoffTables.NumberOfTables = 1; + CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gUefiOvmfPkgTokenSpaceGuid); + HandoffTables.TableEntry[0].VendorTable = (VOID *)VmmHobList; + + Status = TpmMeasureAndLogData ( + 1, // PCRIndex + EV_EFI_HANDOFF_TABLES2, // EventType + (VOID *)&HandoffTables, // EventData + sizeof (HandoffTables), // EventSize + (UINT8 *)(UINTN)VmmHobList, // HashData + (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)VmmHobList) // HashDataLen + ); + + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + } + + return Status; +} + +/** + Get the FvName from the FV header. + + Causion: The FV is untrusted input. + + @param[in] FvBase Base address of FV image. + @param[in] FvLength Length of FV image. + + @return FvName pointer + @retval NULL FvName is NOT found +**/ +VOID * +GetFvName ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader; + + if (FvBase >= MAX_ADDRESS) { + return NULL; + } + + if (FvLength >= MAX_ADDRESS - FvBase) { + return NULL; + } + + if (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) { + return NULL; + } + + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase; + if (FvHeader->ExtHeaderOffset < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) { + return NULL; + } + + if (FvHeader->ExtHeaderOffset + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) { + return NULL; + } + + FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset); + + return &FvExtHeader->FvName; +} + +/** + Measure FV image. + + @param[in] FvBase Base address of FV image. + @param[in] FvLength Length of FV image. + @param[in] PcrIndex Index of PCR + + @retval EFI_SUCCESS Fv image is measured successfully + or it has been already measured. + @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. + @retval EFI_DEVICE_ERROR The command was unsuccessful. + +**/ +EFI_STATUS +EFIAPI +MeasureFvImage ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength, + IN UINT8 PcrIndex + ) +{ + EFI_STATUS Status; + FV_HANDOFF_TABLE_POINTERS2 FvBlob2; + VOID *FvName; + + // + // Init the log event for FV measurement + // + FvBlob2.BlobDescriptionSize = sizeof (FvBlob2.BlobDescription); + CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof (FvBlob2.BlobDescription)); + FvName = GetFvName (FvBase, FvLength); + if (FvName != NULL) { + AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof (FvBlob2.BlobDescription), "Fv(%g)", FvName); + } + + FvBlob2.BlobBase = FvBase; + FvBlob2.BlobLength = FvLength; + + Status = TpmMeasureAndLogData ( + 1, // PCRIndex + EV_EFI_PLATFORM_FIRMWARE_BLOB2, // EventType + (VOID *)&FvBlob2, // EventData + sizeof (FvBlob2), // EventSize + (UINT8 *)(UINTN)FvBase, // HashData + (UINTN)(FvLength) // HashDataLen + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "The FV which failed to be measured starts at: 0x%x\n", FvBase)); + ASSERT (FALSE); + } + + return Status; +} diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c index 54236b956c52..fdfefd00d732 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "PeilessStartupInternal.h" #define GET_GPAW_INIT_STATE(INFO) ((UINT8) ((INFO) & 0x3f)) diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h index dd79b8a06b44..74b5f46552c2 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h @@ -69,4 +69,40 @@ TdxValidateCfv ( IN UINT32 TdxCfvSize ); +/** + Measure the Hoblist passed from the VMM. + + @param[in] VmmHobList The Hoblist pass the firmware + + @retval EFI_SUCCESS Fv image is measured successfully + or it has been already measured. + @retval Others Other errors as indicated +**/ +EFI_STATUS +EFIAPI +MeasureHobList ( + IN CONST VOID *VmmHobList + ); + +/** + Measure FV image. + + @param[in] FvBase Base address of FV image. + @param[in] FvLength Length of FV image. + @param[in] PcrIndex Index of PCR + + @retval EFI_SUCCESS Fv image is measured successfully + or it has been already measured. + @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. + @retval EFI_DEVICE_ERROR The command was unsuccessful. + +**/ +EFI_STATUS +EFIAPI +MeasureFvImage ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength, + IN UINT8 PcrIndex + ); + #endif diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf index c5d291f02bcd..def50b4b019e 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf @@ -58,7 +58,7 @@ QemuFwCfgLib PlatformInitLib HashLib - SecMeasurementLib + TpmMeasurementLib [Guids] gEfiHobMemoryAllocModuleGuid -- 2.29.2.windows.2