/** Initialize and publish TPM items in ACPI table. @retval EFI_SUCCESS The TCG ACPI table is published successfully. @retval Others The TCG ACPI table is not published. **/ EFI_STATUS PublishAcpiTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; EFI_ACPI_DESCRIPTION_HEADER *Table; UINTN TableSize; Status = GetSectionFromFv ( &gEfiCallerIdGuid, EFI_SECTION_RAW, 0, (VOID **) &Table, &TableSize ); ASSERT_EFI_ERROR (Status); // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, Table, TableSize ); ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l')); CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) ); mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS)); ASSERT (mTcgNvs != NULL); // // Publish the TPM ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); TableKey = 0; Status = AcpiTable->InstallAcpiTable ( AcpiTable, Table, TableSize, &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
/** Measure and log an EFI variable, and extend the measurement result into a specific PCR. @param[in] VarName A Null-terminated string that is the name of the vendor's variable. @param[in] VendorGuid A unique identifier for the vendor. @param[in] VarData The content of the variable data. @param[in] VarSize The size of the variable data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES Out of memory. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI MeasureVariable ( IN CHAR16 *VarName, IN EFI_GUID *VendorGuid, IN VOID *VarData, IN UINTN VarSize ) { EFI_STATUS Status; UINTN VarNameLength; EFI_VARIABLE_DATA_TREE *VarLog; UINT32 VarLogSize; // // The EFI_VARIABLE_DATA_TREE.VariableData value shall be the EFI_SIGNATURE_DATA value // from the EFI_SIGNATURE_LIST that contained the authority that was used to validate the image // VarNameLength = StrLen (VarName); VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData)); VarLog = (EFI_VARIABLE_DATA_TREE *) AllocateZeroPool (VarLogSize); if (VarLog == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (&VarLog->VariableName, VendorGuid, sizeof(VarLog->VariableName)); VarLog->UnicodeNameLength = VarNameLength; VarLog->VariableDataLength = VarSize; CopyMem ( VarLog->UnicodeName, VarName, VarNameLength * sizeof (*VarName) ); CopyMem ( (CHAR16 *)VarLog->UnicodeName + VarNameLength, VarData, VarSize ); DEBUG ((EFI_D_INFO, "DxeImageVerification: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY)); DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid)); Status = TpmMeasureAndLogData ( 7, EV_EFI_VARIABLE_AUTHORITY, VarLog, VarLogSize, VarLog, VarLogSize ); FreePool (VarLog); return Status; }
/** Measure and log an EFI variable, and extend the measurement result into a specific PCR. @param[in] VarName A Null-terminated string that is the name of the vendor's variable. @param[in] VendorGuid A unique identifier for the vendor. @param[in] VarData The content of the variable data. @param[in] VarSize The size of the variable data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES Out of memory. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI MeasureVariable ( IN CHAR16 *VarName, IN EFI_GUID *VendorGuid, IN VOID *VarData, IN UINTN VarSize ) { EFI_STATUS Status; UINTN VarNameLength; UEFI_VARIABLE_DATA *VarLog; UINT32 VarLogSize; ASSERT ((VarSize == 0 && VarData == NULL) || (VarSize != 0 && VarData != NULL)); VarNameLength = StrLen (VarName); VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData)); VarLog = (UEFI_VARIABLE_DATA *) AllocateZeroPool (VarLogSize); if (VarLog == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (&VarLog->VariableName, VendorGuid, sizeof(VarLog->VariableName)); VarLog->UnicodeNameLength = VarNameLength; VarLog->VariableDataLength = VarSize; CopyMem ( VarLog->UnicodeName, VarName, VarNameLength * sizeof (*VarName) ); if (VarSize != 0) { CopyMem ( (CHAR16 *)VarLog->UnicodeName + VarNameLength, VarData, VarSize ); } DEBUG ((EFI_D_INFO, "VariableDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_DRIVER_CONFIG)); DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid)); Status = TpmMeasureAndLogData ( 7, EV_EFI_VARIABLE_DRIVER_CONFIG, VarLog, VarLogSize, VarLog, VarLogSize ); FreePool (VarLog); return Status; }
/** Publish TPM2 ACPI table @retval EFI_SUCCESS The TPM2 ACPI table is published successfully. @retval Others The TPM2 ACPI table is not published. **/ EFI_STATUS PublishTpm2 ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; UINT64 OemTableId; // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate) ); CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTpm2AcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTpm2AcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // Construct ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate), &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }
/** Publish TPM2 ACPI table @retval EFI_SUCCESS The TPM2 ACPI table is published successfully. @retval Others The TPM2 ACPI table is not published. **/ EFI_STATUS PublishTpm2 ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; UINTN TableKey; UINT64 OemTableId; EFI_TPM2_ACPI_CONTROL_AREA *ControlArea; PTP_INTERFACE_TYPE InterfaceType; // // Measure to PCR[0] with event EV_POST_CODE ACPI DATA // TpmMeasureAndLogData( 0, EV_POST_CODE, EV_POSTCODE_INFO_ACPI_DATA, ACPI_DATA_LEN, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate) ); InterfaceType = GetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress)); switch (InterfaceType) { case PtpInterfaceCrb: mTpm2AcpiTemplate.StartMethod = EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE; mTpm2AcpiTemplate.AddressOfControlArea = PcdGet64 (PcdTpmBaseAddress) + 0x40; ControlArea = (EFI_TPM2_ACPI_CONTROL_AREA *)(UINTN)mTpm2AcpiTemplate.AddressOfControlArea; ControlArea->CommandSize = 0xF80; ControlArea->ResponseSize = 0xF80; ControlArea->Command = PcdGet64 (PcdTpmBaseAddress) + 0x80; ControlArea->Response = PcdGet64 (PcdTpmBaseAddress) + 0x80; break; case PtpInterfaceFifo: case PtpInterfaceTis: break; default: DEBUG((EFI_D_ERROR, "TPM2 InterfaceType get error! %d\n", InterfaceType)); break; } CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId)); OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); mTpm2AcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); mTpm2AcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); // // Construct ACPI table // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); ASSERT_EFI_ERROR (Status); Status = AcpiTable->InstallAcpiTable ( AcpiTable, &mTpm2AcpiTemplate, sizeof(mTpm2AcpiTemplate), &TableKey ); ASSERT_EFI_ERROR (Status); return Status; }