/** @file This library is used by other modules to measure data to TPM. Copyright (c) 2020, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include /** 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; }