From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web10.14650.1596185716899366598 for ; Fri, 31 Jul 2020 01:55:17 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.31, mailfrom: qi1.zhang@intel.com) IronPort-SDR: /cwq2d+tOsHA4npLoiABTTh0AVAcmRvfAh/qhVOOpyHnUulZ3QR+LbXWNZ2uSRrO3632bnPpbD wlGDnlyaSh0A== X-IronPort-AV: E=McAfee;i="6000,8403,9698"; a="213281385" X-IronPort-AV: E=Sophos;i="5.75,417,1589266800"; d="scan'208";a="213281385" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Jul 2020 01:54:54 -0700 IronPort-SDR: xqo7SNMDoaMOToHV0MFlekqJppsE8HyrD81YPClgFmycI0aiaLwblhSAAbQDhbbjHz5J1ZNA9p 4NqdEenkXYXA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,417,1589266800"; d="scan'208";a="490953563" Received: from shwdesssddpdqi.ccr.corp.intel.com ([10.239.9.10]) by fmsmga006.fm.intel.com with ESMTP; 31 Jul 2020 01:54:52 -0700 From: "Qi Zhang" To: devel@edk2.groups.io Cc: Jiewen Yao , Jian J Wang , Qi Zhang Subject: [PATCH 4/9] SecurityPkg/PeiTpmMeasurementLib: Add new API. Date: Fri, 31 Jul 2020 16:54:32 +0800 Message-Id: <20200731085437.16070-5-qi1.zhang@intel.com> X-Mailer: git-send-email 2.26.2.windows.1 In-Reply-To: <20200731085437.16070-1-qi1.zhang@intel.com> References: <20200731085437.16070-1-qi1.zhang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Jiewen Yao REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2376 Cc: Jiewen Yao Cc: Jian J Wang Cc: Qi Zhang Signed-off-by: Jiewen Yao --- .../PeiTpmMeasurementLib/EventLogRecord.c | 409 ++++++++++++++++++ .../PeiTpmMeasurementLib.inf | 5 + 2 files changed, 414 insertions(+) create mode 100644 SecurityPkg/Library/PeiTpmMeasurementLib/EventLogRecord= .c diff --git a/SecurityPkg/Library/PeiTpmMeasurementLib/EventLogRecord.c b/Se= curityPkg/Library/PeiTpmMeasurementLib/EventLogRecord.c new file mode 100644 index 0000000000..bd3d7000a1 --- /dev/null +++ b/SecurityPkg/Library/PeiTpmMeasurementLib/EventLogRecord.c @@ -0,0 +1,409 @@ +/** @file=0D + This library is used by other modules to measure data to TPM.=0D +=0D +Copyright (c) 2020, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#include =0D +#include =0D +=0D +#pragma pack (1)=0D +=0D +#define PLATFORM_FIRMWARE_BLOB_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX= XX)"=0D +typedef struct {=0D + UINT8 BlobDescriptionSize;=0D + UINT8 BlobDescription[sizeof(PLATFORM_FIRMWA= RE_BLOB_DESC)];=0D + EFI_PHYSICAL_ADDRESS BlobBase;=0D + UINT64 BlobLength;=0D +} PLATFORM_FIRMWARE_BLOB2_STRUCT;=0D +=0D +#define HANDOFF_TABLE_POINTER_DESC "1234567890ABCDEF"=0D +typedef struct {=0D + UINT8 TableDescriptionSize;=0D + UINT8 TableDescription[sizeof(HANDOFF_TABLE_= POINTER_DESC)];=0D + UINT64 NumberOfTables;=0D + EFI_CONFIGURATION_TABLE TableEntry[1];=0D +} HANDOFF_TABLE_POINTERS2_STRUCT;=0D +=0D +#pragma pack ()=0D +=0D +/**=0D + Tpm measure and log data, and extend the measurement result into a speci= fic PCR.=0D +=0D + @param[in] PcrIndex PCR Index.=0D + @param[in] EventType Event type.=0D + @param[in] EventLog Measurement event log.=0D + @param[in] LogLen Event log length in bytes.=0D + @param[in] HashData The start of the data buffer to be hashed, = extended.=0D + @param[in] HashDataLen The length, in bytes, of the buffer referen= ced by HashData=0D + @param[in] Flags Bitmap providing additional information.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_UNSUPPORTED TPM device not available.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +TpmMeasureAndLogDataWithFlags (=0D + IN UINT32 PcrIndex,=0D + IN UINT32 EventType,=0D + IN VOID *EventLog,=0D + IN UINT32 LogLen,=0D + IN VOID *HashData,=0D + IN UINT64 HashDataLen,=0D + IN UINT64 Flags=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EDKII_TCG_PPI *TcgPpi;=0D + TCG_PCR_EVENT_HDR TcgEventHdr;=0D +=0D + Status =3D PeiServicesLocatePpi(=0D + &gEdkiiTcgPpiGuid,=0D + 0,=0D + NULL,=0D + (VOID**)&TcgPpi=0D + );=0D + if (EFI_ERROR(Status)) {=0D + return Status;=0D + }=0D +=0D + TcgEventHdr.PCRIndex =3D PcrIndex;=0D + TcgEventHdr.EventType =3D EventType;=0D + TcgEventHdr.EventSize =3D LogLen;=0D +=0D + Status =3D TcgPpi->HashLogExtendEvent (=0D + TcgPpi,=0D + Flags,=0D + HashData,=0D + (UINTN)HashDataLen,=0D + &TcgEventHdr,=0D + EventLog=0D + );=0D + return Status;=0D +}=0D +=0D +/**=0D + Get the FvName from the FV header.=0D +=0D + Causion: The FV is untrusted input.=0D +=0D + @param[in] FvBase Base address of FV image.=0D + @param[in] FvLength Length of FV image.=0D +=0D + @return FvName pointer=0D + @retval NULL FvName is NOT found=0D +**/=0D +VOID *=0D +TpmMeasurementGetFvName (=0D + IN EFI_PHYSICAL_ADDRESS FvBase,=0D + IN UINT64 FvLength=0D + )=0D +{=0D + EFI_FIRMWARE_VOLUME_HEADER *FvHeader;=0D + EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;=0D +=0D + if (FvBase >=3D MAX_ADDRESS) {=0D + return NULL;=0D + }=0D + if (FvLength >=3D MAX_ADDRESS - FvBase) {=0D + return NULL;=0D + }=0D + if (FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {=0D + return NULL;=0D + }=0D +=0D + FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;=0D + if (FvHeader->Signature !=3D EFI_FVH_SIGNATURE) {=0D + return NULL;=0D + }=0D + if (FvHeader->ExtHeaderOffset < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {=0D + return NULL;=0D + }=0D + if (FvHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER) >= FvLength) {=0D + return NULL;=0D + }=0D + FvExtHeader =3D (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHea= der->ExtHeaderOffset);=0D +=0D + return &FvExtHeader->FvName;=0D +}=0D +=0D +/**=0D + Mesure a FirmwareBlob.=0D +=0D + @param[in] PcrIndex PcrIndex of the measurment.=0D + @param[in] Descrption Description for this FirmwareBlob.=0D + @param[in] FirmwareBlobBase Base address of this FirmwareBlob.=0D + @param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.= =0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_UNSUPPORTED TPM device not available.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +*/=0D +EFI_STATUS=0D +EFIAPI=0D +MeasureFirmwareBlob (=0D + IN UINT32 PcrIndex,=0D + IN CHAR8 *Description OPTIONAL,=0D + IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,=0D + IN UINT64 FirmwareBlobLength=0D + )=0D +{=0D + EFI_PLATFORM_FIRMWARE_BLOB FvBlob;=0D + PLATFORM_FIRMWARE_BLOB2_STRUCT FvBlob2;=0D + VOID *FvName;=0D + UINT32 EventType;=0D + VOID *EventLog;=0D + UINT32 EventLogSize;=0D + EFI_STATUS Status;=0D +=0D + FvName =3D TpmMeasurementGetFvName (FirmwareBlobBase, FirmwareBlobLength= );=0D +=0D + if (((Description !=3D NULL) || (FvName !=3D NULL)) &&=0D + (PcdGet32(PcdTcgPfpMeasurementRevision) >=3D TCG_EfiSpecIDEventStruc= t_SPEC_ERRATA_TPM2_REV_105)) {=0D + ZeroMem (&FvBlob2, sizeof(FvBlob2));=0D + if (Description !=3D NULL) {=0D + AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDesc= ription), "%a", Description);=0D + } else {=0D + AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDesc= ription), "Fv(%g)", FvName);=0D + }=0D +=0D + FvBlob2.BlobDescriptionSize =3D sizeof(FvBlob2.BlobDescription);=0D + FvBlob2.BlobBase =3D FirmwareBlobBase;=0D + FvBlob2.BlobLength =3D FirmwareBlobLength;=0D +=0D + EventType =3D EV_EFI_PLATFORM_FIRMWARE_BLOB2;=0D + EventLog =3D &FvBlob2;=0D + EventLogSize =3D sizeof(FvBlob2);=0D + } else {=0D + FvBlob.BlobBase =3D FirmwareBlobBase;=0D + FvBlob.BlobLength =3D FirmwareBlobLength;=0D +=0D + EventType =3D EV_EFI_PLATFORM_FIRMWARE_BLOB;=0D + EventLog =3D &FvBlob;=0D + EventLogSize =3D sizeof(FvBlob);=0D + }=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + PcrIndex,=0D + EventType,=0D + EventLog,=0D + EventLogSize,=0D + (VOID*)(UINTN)FirmwareBlobBase,=0D + FirmwareBlobLength=0D + );=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Mesure a FirmwareBlob in separation mode of FV binary and configuration.= =0D +=0D + @param[in] Descrption Description for this FirmwareBlob.=0D + @param[in] FirmwareBlobBase Base address of this FirmwareBlob.=0D + @param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.= =0D + @param[in] CfgRegionOffset Configuration region offset in bytes= .=0D + @param[in] CfgRegionSize Configuration region in bytes.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_UNSUPPORTED TPM device not available.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +*/=0D +EFI_STATUS=0D +EFIAPI=0D +MeasureFirmwareBlobWithCfg (=0D + IN CHAR8 *Description OPTIONAL,=0D + IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,=0D + IN UINT64 FirmwareBlobLength,=0D + IN UINT32 CfgRegionOffset,=0D + IN UINT32 CfgRegionSize=0D + )=0D +{=0D + EFI_PLATFORM_FIRMWARE_BLOB FvBlob, UPDBlob;=0D + PLATFORM_FIRMWARE_BLOB2_STRUCT FvBlob2, UPDBlob2;=0D + VOID *FvName;=0D + UINT32 FvEventType;=0D + VOID *FvEventLog, *UPDEventLog;=0D + UINT32 FvEventLogSize, UPDEventLogSize;=0D + EFI_STATUS Status;=0D + HASH_HANDLE HashHandle;=0D + UINT8 *HashBase;=0D + UINTN HashSize;=0D + TPML_DIGEST_VALUES DigestList;=0D +=0D + FvName =3D TpmMeasurementGetFvName (FirmwareBlobBase, FirmwareBlobLength= );=0D +=0D + if (((Description !=3D NULL) || (FvName !=3D NULL)) &&=0D + (PcdGet32(PcdTcgPfpMeasurementRevision) >=3D TCG_EfiSpecIDEventStruc= t_SPEC_ERRATA_TPM2_REV_105)) {=0D + ZeroMem (&FvBlob2, sizeof(FvBlob2));=0D + ZeroMem (&UPDBlob2, sizeof(UPDBlob2));=0D + if (Description !=3D NULL) {=0D + AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDesc= ription), "%a", Description);=0D + AsciiSPrint((CHAR8*)UPDBlob2.BlobDescription, sizeof(UPDBlob2.BlobDe= scription), "%aUDP", Description);=0D + } else {=0D + AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDesc= ription), "Fv(%g)", FvName);=0D + AsciiSPrint((CHAR8*)UPDBlob2.BlobDescription, sizeof(UPDBlob2.BlobDe= scription), "(%g)UDP", FvName);=0D + }=0D +=0D + FvBlob2.BlobDescriptionSize =3D sizeof(FvBlob2.BlobDescription);=0D + FvBlob2.BlobBase =3D FirmwareBlobBase;=0D + FvBlob2.BlobLength =3D FirmwareBlobLength;=0D + FvEventType =3D EV_EFI_PLATFORM_FIRMWARE_BLOB2;=0D + FvEventLog =3D &FvBlob2;=0D + FvEventLogSize =3D sizeof(FvBlob2);=0D +=0D + UPDBlob2.BlobDescriptionSize =3D sizeof(UPDBlob2.BlobDescription);=0D + UPDBlob2.BlobBase =3D CfgRegionOffset;=0D + UPDBlob2.BlobLength =3D CfgRegionSize;=0D + UPDEventLog =3D &UPDBlob2;=0D + UPDEventLogSize =3D sizeof(UPDBlob2);=0D + } else {=0D + FvBlob.BlobBase =3D FirmwareBlobBase;=0D + FvBlob.BlobLength =3D FirmwareBlobLength;=0D + FvEventType =3D EV_EFI_PLATFORM_FIRMWARE_BLOB;=0D + FvEventLog =3D &FvBlob;=0D + FvEventLogSize =3D sizeof(FvBlob);=0D +=0D + UPDBlob.BlobBase =3D CfgRegionOffset;=0D + UPDBlob.BlobLength =3D CfgRegionSize;=0D + UPDEventLog =3D &UPDBlob;=0D + UPDEventLogSize =3D sizeof(UPDBlob);=0D + }=0D +=0D + // Initialize a SHA hash context.=0D + Status =3D HashStart (&HashHandle);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "HashStart failed - %r\n", Status));=0D + return Status;=0D + }=0D +=0D + // Hash FSP binary before UDP=0D + HashBase =3D (UINT8 *) (UINTN) FirmwareBlobBase;=0D + HashSize =3D (UINTN) CfgRegionOffset;=0D + Status =3D HashUpdate (HashHandle, HashBase, HashSize);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));=0D + return Status;=0D + }=0D +=0D + // Hash FSP binary after UDP=0D + HashBase =3D (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset + CfgR= egionSize;=0D + HashSize =3D (UINTN)(FirmwareBlobLength - CfgRegionOffset - CfgRegionSiz= e);=0D + Status =3D HashUpdate (HashHandle, HashBase, HashSize);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));=0D + return Status;=0D + }=0D +=0D + // Finalize the SHA hash.=0D + Status =3D HashFinal(HashHandle, &DigestList);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "HashFinal failed - %r\n", Status));=0D + return Status;=0D + }=0D +=0D + Status =3D TpmMeasureAndLogDataWithFlags (=0D + 0,=0D + FvEventType,=0D + FvEventLog,=0D + FvEventLogSize,=0D + (UINT8 *) &DigestList,=0D + (UINTN) sizeof(DigestList),=0D + EDKII_TCG_PRE_HASH=0D + );=0D + DEBUG ((DEBUG_ERROR, "TpmMeasureAndLogDataWithFlags - %r\n", Status));=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + 1,=0D + EV_PLATFORM_CONFIG_FLAGS,=0D + UPDEventLog,=0D + UPDEventLogSize,=0D + (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset,=0D + CfgRegionSize=0D + );=0D + DEBUG ((DEBUG_ERROR, "TpmMeasureAndLogData - %r\n", Status));=0D +=0D + return Status;=0D +}=0D +/**=0D + Mesure a HandoffTable.=0D +=0D + @param[in] PcrIndex PcrIndex of the measurment.=0D + @param[in] Descrption Description for this HandoffTable.=0D + @param[in] TableGuid GUID of this HandoffTable.=0D + @param[in] TableAddress Base address of this HandoffTable.=0D + @param[in] TableLength Size in bytes of this HandoffTable.= =0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_UNSUPPORTED TPM device not available.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +*/=0D +EFI_STATUS=0D +EFIAPI=0D +MeasureHandoffTable (=0D + IN UINT32 PcrIndex,=0D + IN CHAR8 *Description OPTIONAL,=0D + IN EFI_GUID *TableGuid,=0D + IN VOID *TableAddress,=0D + IN UINTN TableLength=0D + )=0D +{=0D + EFI_HANDOFF_TABLE_POINTERS HandoffTables;=0D + HANDOFF_TABLE_POINTERS2_STRUCT HandoffTables2;=0D + UINT32 EventType;=0D + VOID *EventLog;=0D + UINT32 EventLogSize;=0D + EFI_STATUS Status;=0D +=0D + if ((Description !=3D NULL) &&=0D + (PcdGet32(PcdTcgPfpMeasurementRevision) >=3D TCG_EfiSpecIDEventStruc= t_SPEC_ERRATA_TPM2_REV_105)) {=0D + ZeroMem (&HandoffTables2, sizeof(HandoffTables2));=0D + AsciiSPrint((CHAR8*)HandoffTables2.TableDescription, sizeof(HandoffTab= les2.TableDescription), "%a", Description);=0D +=0D + HandoffTables2.TableDescriptionSize =3D sizeof(HandoffTables2.TableDes= cription);=0D + HandoffTables2.NumberOfTables =3D 1;=0D + CopyGuid (&(HandoffTables2.TableEntry[0].VendorGuid), TableGuid);=0D + HandoffTables2.TableEntry[0].VendorTable =3D TableAddress;=0D +=0D + EventType =3D EV_EFI_HANDOFF_TABLES2;=0D + EventLog =3D &HandoffTables2;=0D + EventLogSize =3D sizeof(HandoffTables2);=0D + } else {=0D + HandoffTables.NumberOfTables =3D 1;=0D + CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), TableGuid);=0D + HandoffTables.TableEntry[0].VendorTable =3D TableAddress;=0D +=0D + EventType =3D EV_EFI_HANDOFF_TABLES;=0D + EventLog =3D &HandoffTables;=0D + EventLogSize =3D sizeof(HandoffTables);=0D + }=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + PcrIndex,=0D + EventType,=0D + EventLog,=0D + EventLogSize,=0D + TableAddress,=0D + TableLength=0D + );=0D + return Status;=0D +}=0D diff --git a/SecurityPkg/Library/PeiTpmMeasurementLib/PeiTpmMeasurementLib.= inf b/SecurityPkg/Library/PeiTpmMeasurementLib/PeiTpmMeasurementLib.inf index 6625d0fd01..6ff32a2bdc 100644 --- a/SecurityPkg/Library/PeiTpmMeasurementLib/PeiTpmMeasurementLib.inf +++ b/SecurityPkg/Library/PeiTpmMeasurementLib/PeiTpmMeasurementLib.inf @@ -26,6 +26,7 @@ =0D [Sources]=0D PeiTpmMeasurementLib.c=0D + EventLogRecord.c=0D =0D [Packages]=0D MdePkg/MdePkg.dec=0D @@ -41,10 +42,14 @@ PrintLib=0D PeiServicesLib=0D PeiServicesTablePointerLib=0D + HashLib=0D =0D [Ppis]=0D gEdkiiTcgPpiGuid ## = CONSUMES=0D =0D +[Pcd]=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## = CONSUMES=0D +=0D [Depex]=0D gEfiPeiMasterBootModePpiGuid AND=0D gEfiTpmDeviceSelectedGuid=0D --=20 2.26.2.windows.1