| /** @file | |
| This library is used by other modules to measure data to TPM. | |
| Copyright (c) 2020, Intel Corporation. All rights reserved. <BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include <Uefi/UefiBaseType.h> | |
| #include <Pi/PiFirmwareVolume.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/ReportStatusCodeLib.h> | |
| #include <Library/PcdLib.h> | |
| #include <Library/PrintLib.h> | |
| #include <Library/TcgEventLogRecordLib.h> | |
| #include <Library/TpmMeasurementLib.h> | |
| #include <IndustryStandard/UefiTcgPlatform.h> | |
| /** | |
| 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 * | |
| 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; | |
| } | |
| /** | |
| Measure a FirmwareBlob. | |
| @param[in] PcrIndex PcrIndex of the measurement. | |
| @param[in] Description 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 | |
| MeasureFirmwareBlob ( | |
| IN UINT32 PcrIndex, | |
| IN CHAR8 *Description OPTIONAL, | |
| IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase, | |
| IN UINT64 FirmwareBlobLength | |
| ) | |
| { | |
| EFI_PLATFORM_FIRMWARE_BLOB FvBlob; | |
| PLATFORM_FIRMWARE_BLOB2_STRUCT FvBlob2; | |
| VOID *FvName; | |
| UINT32 EventType; | |
| VOID *EventLog; | |
| UINT32 EventLogSize; | |
| EFI_STATUS Status; | |
| FvName = TpmMeasurementGetFvName (FirmwareBlobBase, FirmwareBlobLength); | |
| if (((Description != NULL) || (FvName != NULL)) && | |
| (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) { | |
| if (Description != NULL) { | |
| AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "%a", Description); | |
| } else { | |
| AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName); | |
| } | |
| FvBlob2.BlobDescriptionSize = sizeof(FvBlob2.BlobDescription); | |
| FvBlob2.BlobBase = FirmwareBlobBase; | |
| FvBlob2.BlobLength = FirmwareBlobLength; | |
| EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2; | |
| EventLog = &FvBlob2; | |
| EventLogSize = sizeof(FvBlob2); | |
| } else { | |
| FvBlob.BlobBase = FirmwareBlobBase; | |
| FvBlob.BlobLength = FirmwareBlobLength; | |
| EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB; | |
| EventLog = &FvBlob; | |
| EventLogSize = sizeof(FvBlob); | |
| } | |
| Status = TpmMeasureAndLogData ( | |
| PcrIndex, | |
| EventType, | |
| EventLog, | |
| EventLogSize, | |
| (VOID*)(UINTN)FirmwareBlobBase, | |
| FirmwareBlobLength | |
| ); | |
| return Status; | |
| } | |
| /** | |
| Measure a HandoffTable. | |
| @param[in] PcrIndex PcrIndex of the measurement. | |
| @param[in] Description Description for this HandoffTable. | |
| @param[in] TableGuid GUID of this HandoffTable. | |
| @param[in] TableAddress Base address of this HandoffTable. | |
| @param[in] TableLength Size in bytes of this HandoffTable. | |
| @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 | |
| MeasureHandoffTable ( | |
| IN UINT32 PcrIndex, | |
| IN CHAR8 *Description OPTIONAL, | |
| IN EFI_GUID *TableGuid, | |
| IN VOID *TableAddress, | |
| IN UINTN TableLength | |
| ) | |
| { | |
| EFI_HANDOFF_TABLE_POINTERS HandoffTables; | |
| HANDOFF_TABLE_POINTERS2_STRUCT HandoffTables2; | |
| UINT32 EventType; | |
| VOID *EventLog; | |
| UINT32 EventLogSize; | |
| EFI_STATUS Status; | |
| if ((Description != NULL) && | |
| (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) { | |
| AsciiSPrint((CHAR8*)HandoffTables2.TableDescription, sizeof(HandoffTables2.TableDescription), "%a", Description); | |
| HandoffTables2.TableDescriptionSize = sizeof(HandoffTables2.TableDescription); | |
| HandoffTables2.NumberOfTables = 1; | |
| CopyGuid (&(HandoffTables2.TableEntry[0].VendorGuid), TableGuid); | |
| HandoffTables2.TableEntry[0].VendorTable = TableAddress; | |
| EventType = EV_EFI_HANDOFF_TABLES2; | |
| EventLog = &HandoffTables2; | |
| EventLogSize = sizeof(HandoffTables2); | |
| } else { | |
| HandoffTables.NumberOfTables = 1; | |
| CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), TableGuid); | |
| HandoffTables.TableEntry[0].VendorTable = TableAddress; | |
| EventType = EV_EFI_HANDOFF_TABLES; | |
| EventLog = &HandoffTables; | |
| EventLogSize = sizeof(HandoffTables); | |
| } | |
| Status = TpmMeasureAndLogData ( | |
| PcrIndex, | |
| EventType, | |
| EventLog, | |
| EventLogSize, | |
| TableAddress, | |
| TableLength | |
| ); | |
| return Status; | |
| } |