Re: [PATCH v2 6/9] IntelFsp2WrapperPkg/FspMeasurementLib: Add BaseFspMeasurementLib.


Wang, Jian J
 

Qi,

Comments below.

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Qi Zhang
Sent: Thursday, August 06, 2020 8:34 AM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@...>; Chiu, Chasel <chasel.chiu@...>;
Desimone, Nathaniel L <@natedesimone>; Zeng, Star
<star.zeng@...>; Zhang, Qi1 <qi1.zhang@...>
Subject: [edk2-devel] [PATCH v2 6/9] IntelFsp2WrapperPkg/FspMeasurementLib:
Add BaseFspMeasurementLib.

From: Jiewen Yao <jiewen.yao@...>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2376

Cc: Jiewen Yao <jiewen.yao@...>
Cc: Chasel Chiu <chasel.chiu@...>
Cc: Nate DeSimone <@natedesimone>
Cc: Star Zeng <star.zeng@...>
Cc: Qi Zhang <qi1.zhang@...>
Signed-off-by: Jiewen Yao <jiewen.yao@...>
---
.../BaseFspMeasurementLib.inf | 54 +++
.../BaseFspMeasurementLib/FspMeasurementLib.c | 349 ++++++++++++++++++
2 files changed, 403 insertions(+)
create mode 100644
IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLi
b.inf
create mode 100644
IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c

diff --git
a/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurement
Lib.inf
b/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurement
Lib.inf
new file mode 100644
index 0000000000..d30168117d
--- /dev/null
+++
b/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurement
Lib.inf
@@ -0,0 +1,54 @@
+## @file

+# Provides FSP measurement functions.

+#

+# This library provides MeasureFspFirmwareBlob() to measure FSP binary.

+#

+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+[Defines]

+ INF_VERSION = 0x00010005

+ BASE_NAME = FspMeasurementLib

+ FILE_GUID = 9A62C49D-C45A-4322-9F3C-45958DF0056B

+ MODULE_TYPE = BASE

+ VERSION_STRING = 1.0

+ LIBRARY_CLASS = FspMeasurementLib

+

+#

+# The following information is for reference only and not required by the build
tools.

+#

+# VALID_ARCHITECTURES = IA32 X64

+#

+

+[Sources]

+ FspMeasurementLib.c

+

+[Packages]

+ MdePkg/MdePkg.dec

+ MdeModulePkg/MdeModulePkg.dec

+ SecurityPkg/SecurityPkg.dec

+ IntelFsp2Pkg/IntelFsp2Pkg.dec

+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec

+

+[LibraryClasses]

+ BaseLib

+ BaseMemoryLib

+ DebugLib

+ PrintLib

+ PcdLib

+ PeiServicesLib

+ PeiServicesTablePointerLib

+ FspWrapperApiLib

+ TpmMeasurementLib

+ HashLib

+

+[Ppis]

+ gEdkiiTcgPpiGuid ## CONSUMES

+

+[Pcd]

+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig ##
CONSUMES

+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ##
CONSUMES

+ gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ##
CONSUMES

+

diff --git
a/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c
b/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c
new file mode 100644
index 0000000000..316570cd2c
--- /dev/null
+++
b/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c
@@ -0,0 +1,349 @@
+/** @file

+ This library is used by FSP modules to measure data to TPM.

+

+Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>

+SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+#include <PiPei.h>

+#include <Uefi.h>

+

+#include <Library/BaseMemoryLib.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/PcdLib.h>

+#include <Library/PrintLib.h>

+#include <Library/DebugLib.h>

+#include <Library/FspWrapperApiLib.h>

+#include <Library/TpmMeasurementLib.h>

+#include <Library/FspMeasurementLib.h>

+#include <Library/HashLib.h>

+

+#include <Ppi/Tcg.h>

+#include <IndustryStandard/UefiTcgPlatform.h>

+

+#pragma pack (1)

+

+#define PLATFORM_FIRMWARE_BLOB_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-
XXXXXXXXXXXX)"

+typedef struct {

+ UINT8 BlobDescriptionSize;

+ UINT8
BlobDescription[sizeof(PLATFORM_FIRMWARE_BLOB_DESC)];

+ EFI_PHYSICAL_ADDRESS BlobBase;

+ UINT64 BlobLength;

+} PLATFORM_FIRMWARE_BLOB2_STRUCT;

+

+#define HANDOFF_TABLE_POINTER_DESC "1234567890ABCDEF"

+typedef struct {

+ UINT8 TableDescriptionSize;

+ UINT8
TableDescription[sizeof(HANDOFF_TABLE_POINTER_DESC)];

+ UINT64 NumberOfTables;

+ EFI_CONFIGURATION_TABLE TableEntry[1];

+} HANDOFF_TABLE_POINTERS2_STRUCT;

+

+#pragma pack ()
Above definitions have been defined the same in EventLogRecord.c in patch3&4.
Suggest put them in a common header file.

+

+/**

+ 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

+ @param[in] Flags Bitmap providing additional information.

+

+ @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

+TpmMeasureAndLogDataWithFlags (

+ IN UINT32 PcrIndex,

+ IN UINT32 EventType,

+ IN VOID *EventLog,

+ IN UINT32 LogLen,

+ IN VOID *HashData,

+ IN UINT64 HashDataLen,

+ IN UINT64 Flags

+ )

+{

+ EFI_STATUS Status;

+ EDKII_TCG_PPI *TcgPpi;

+ TCG_PCR_EVENT_HDR TcgEventHdr;

+

+ Status = PeiServicesLocatePpi(

+ &gEdkiiTcgPpiGuid,

+ 0,

+ NULL,

+ (VOID**)&TcgPpi

+ );

+ if (EFI_ERROR(Status)) {

+ return Status;

+ }

+

+ TcgEventHdr.PCRIndex = PcrIndex;

+ TcgEventHdr.EventType = EventType;

+ TcgEventHdr.EventSize = LogLen;

+

+ Status = TcgPpi->HashLogExtendEvent (

+ TcgPpi,

+ Flags,

+ HashData,

+ (UINTN)HashDataLen,

+ &TcgEventHdr,

+ EventLog

+ );

+ 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

+**/

+STATIC

+VOID *

+TpmMeasurementGetFvName (

+ 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->Signature != EFI_FVH_SIGNATURE) {

+ return NULL;

+ }

+ 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;

+}

+

+/**

+ Mesure a FSP FirmwareBlob.
'Mesure' -> 'Measure'


+

+ @param[in] Descrption Description for this FirmwareBlob.
'Descrption' -> 'Description'


+ @param[in] FirmwareBlobBase Base address of this FirmwareBlob.

+ @param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.

+ @param[in] CfgRegionOffset Configuration region offset in bytes.

+ @param[in] CfgRegionSize Configuration region in bytes.

+

+ @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.

+*/

+STATIC

+EFI_STATUS

+EFIAPI

+MeasureFspFirmwareBlobWithCfg (

+ IN CHAR8 *Description OPTIONAL,

+ IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,

+ IN UINT64 FirmwareBlobLength,

+ IN UINT32 CfgRegionOffset,

+ IN UINT32 CfgRegionSize

+ )

+{

+ EFI_PLATFORM_FIRMWARE_BLOB FvBlob, UPDBlob;

+ PLATFORM_FIRMWARE_BLOB2_STRUCT FvBlob2, UPDBlob2;

+ VOID *FvName;

+ UINT32 FvEventType;

+ VOID *FvEventLog, *UPDEventLog;

+ UINT32 FvEventLogSize, UPDEventLogSize;

+ EFI_STATUS Status;

+ HASH_HANDLE HashHandle;

+ UINT8 *HashBase;

+ UINTN HashSize;

+ TPML_DIGEST_VALUES DigestList;

+

+ FvName = TpmMeasurementGetFvName (FirmwareBlobBase,
FirmwareBlobLength);

+

+ if (((Description != NULL) || (FvName != NULL)) &&

+ (PcdGet32(PcdTcgPfpMeasurementRevision) >=
TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) {

+ ZeroMem (&FvBlob2, sizeof(FvBlob2));

+ ZeroMem (&UPDBlob2, sizeof(UPDBlob2));
The same as patch3&4, I think it's not necessary to clear the data
in advance.

+ if (Description != NULL) {

+ AsciiSPrint((CHAR8*)FvBlob2.BlobDescription,
sizeof(FvBlob2.BlobDescription), "%a", Description);

+ AsciiSPrint((CHAR8*)UPDBlob2.BlobDescription,
sizeof(UPDBlob2.BlobDescription), "%aUDP", Description);

+ } else {

+ AsciiSPrint((CHAR8*)FvBlob2.BlobDescription,
sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);

+ AsciiSPrint((CHAR8*)UPDBlob2.BlobDescription,
sizeof(UPDBlob2.BlobDescription), "(%g)UDP", FvName);

+ }

+

+ FvBlob2.BlobDescriptionSize = sizeof(FvBlob2.BlobDescription);

+ FvBlob2.BlobBase = FirmwareBlobBase;

+ FvBlob2.BlobLength = FirmwareBlobLength;

+ FvEventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;

+ FvEventLog = &FvBlob2;

+ FvEventLogSize = sizeof(FvBlob2);

+

+ UPDBlob2.BlobDescriptionSize = sizeof(UPDBlob2.BlobDescription);

+ UPDBlob2.BlobBase = CfgRegionOffset;

+ UPDBlob2.BlobLength = CfgRegionSize;

+ UPDEventLog = &UPDBlob2;

+ UPDEventLogSize = sizeof(UPDBlob2);

+ } else {

+ FvBlob.BlobBase = FirmwareBlobBase;

+ FvBlob.BlobLength = FirmwareBlobLength;

+ FvEventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;

+ FvEventLog = &FvBlob;

+ FvEventLogSize = sizeof(FvBlob);

+

+ UPDBlob.BlobBase = CfgRegionOffset;

+ UPDBlob.BlobLength = CfgRegionSize;

+ UPDEventLog = &UPDBlob;

+ UPDEventLogSize = sizeof(UPDBlob);

+ }

+

+ // Initialize a SHA hash context.

+ Status = HashStart (&HashHandle);

+ if (EFI_ERROR (Status)) {

+ DEBUG ((DEBUG_ERROR, "HashStart failed - %r\n", Status));

+ return Status;

+ }

+

+ // Hash FSP binary before UDP

+ HashBase = (UINT8 *) (UINTN) FirmwareBlobBase;

+ HashSize = (UINTN) CfgRegionOffset;

+ Status = HashUpdate (HashHandle, HashBase, HashSize);

+ if (EFI_ERROR (Status)) {

+ DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));

+ return Status;

+ }

+

+ // Hash FSP binary after UDP

+ HashBase = (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset +
CfgRegionSize;

+ HashSize = (UINTN)(FirmwareBlobLength - CfgRegionOffset - CfgRegionSize);

+ Status = HashUpdate (HashHandle, HashBase, HashSize);

+ if (EFI_ERROR (Status)) {

+ DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));

+ return Status;

+ }

+

+ // Finalize the SHA hash.

+ Status = HashCompleteAndExtend (HashHandle, 0, NULL, 0, &DigestList);

+ if (EFI_ERROR (Status)) {

+ DEBUG ((DEBUG_ERROR, "HashCompleteAndExtend failed - %r\n", Status));

+ return Status;

+ }

+

+ Status = TpmMeasureAndLogDataWithFlags (

+ 0,

+ FvEventType,

+ FvEventLog,

+ FvEventLogSize,

+ (UINT8 *) &DigestList,

+ (UINTN) sizeof(DigestList),

+ EDKII_TCG_PRE_HASH_LOG_ONLY

+ );

+

+ Status = TpmMeasureAndLogData (

+ 1,

+ EV_PLATFORM_CONFIG_FLAGS,

+ UPDEventLog,

+ UPDEventLogSize,

+ (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset,

+ CfgRegionSize

+ );

+

+ return Status;

+}

+

+FSP_INFO_HEADER *

+EFIAPI

+mFspFindFspHeader (

+ IN EFI_PHYSICAL_ADDRESS FlashFvFspBase

+ )

+{

+ UINT8 *CheckPointer;

+

+ CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase;

+

+ if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature !=
EFI_FVH_SIGNATURE) {

+ return NULL;

+ }

+

+ if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset !=
0) {

+ CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER
*)CheckPointer)->ExtHeaderOffset;

+ CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER
*)CheckPointer)->ExtHeaderSize;

+ CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8);

+ } else {

+ CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER
*)CheckPointer)->HeaderLength;

+ }

+

+

+ CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER);

+

+ if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) {

+ return NULL;

+ }

+

+ CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION);

+

+ return (FSP_INFO_HEADER *)CheckPointer;

+}

+/**

+ Mesure a FSP FirmwareBlob.
'Mesure' -> ' Measure'


+

+ @param[in] PcrIndex PCR Index.

+ @param[in] Descrption Description for this FirmwareBlob.

+ @param[in] FirmwareBlobBase Base address of this FirmwareBlob.

+ @param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.

+

+ @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

+MeasureFspFirmwareBlob (

+ IN UINT32 PcrIndex,

+ IN CHAR8 *Description OPTIONAL,

+ IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,

+ IN UINT64 FirmwareBlobLength

+ )

+{

+ UINT32 FspMeasureMask;

+ FSP_INFO_HEADER *FspHeaderPtr;

+

+ FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);

+ if (FspMeasureMask & FSP_MEASURE_FSPUPD) {

+ FspHeaderPtr = (FSP_INFO_HEADER *) mFspFindFspHeader
(FirmwareBlobBase);

+ if (FspHeaderPtr == NULL) {

+ return MeasureFirmwareBlob (PcrIndex, Description, FirmwareBlobBase,
FirmwareBlobLength);;

+ }

+ return MeasureFspFirmwareBlobWithCfg(Description, FirmwareBlobBase,
FirmwareBlobLength,

+ FspHeaderPtr->CfgRegionOffset, FspHeaderPtr-
CfgRegionSize);
+ } else {

+ return MeasureFirmwareBlob (PcrIndex, Description, FirmwareBlobBase,
FirmwareBlobLength);

+ }

+}

+

--
2.26.2.windows.1


-=-=-=-=-=-=
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#63757): https://edk2.groups.io/g/devel/message/63757
Mute This Topic: https://groups.io/mt/76019588/1768734
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [jian.j.wang@...]
-=-=-=-=-=-=

Join devel@edk2.groups.io to automatically receive all group messages.