From 7d5abcd01607c7c2d56804b130f21ee7090f8719 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 5 Oct 2020 16:29:25 +0200 Subject: [PATCH] UefiPayloadPkg: Parse coreboot's TPM PPI handoff buffer Read the coreboot table containing the TPM PPI handoff buffer and place it in gEfiTcgPhysicalPresenceInfoHob. coreboot uses the same PPI interface as QEMU does and installs the corresponding ACPI code to provide a full PPI interface to the OS. The OS must reboot in order to execute the requests. The corresponding coreboot patch can be found here: https://review.coreboot.org/c/coreboot/+/45568 In a follow up commit the OvmfPkg PhysicalPresence library will be used to confirm TPM PPI request. This is necessary as coreboot doesn't have input drivers or a graphical UI that could be used. Signed-off-by: Patrick Rudolph --- UefiPayloadPkg/Include/Coreboot.h | 25 ++++++++++ .../Include/Guid/TcgPhysicalPresenceGuid.h | 30 +++++++++++ UefiPayloadPkg/Include/Library/BlParseLib.h | 17 +++++++ .../Library/CbParseLib/CbParseLib.c | 50 +++++++++++++++++++ .../Library/SblParseLib/SblParseLib.c | 18 +++++++ .../UefiPayloadEntry/UefiPayloadEntry.c | 13 +++++ .../UefiPayloadEntry/UefiPayloadEntry.h | 1 + .../UefiPayloadEntry/UefiPayloadEntry.inf | 1 + UefiPayloadPkg/UefiPayloadPkg.dec | 1 + 9 files changed, 156 insertions(+) create mode 100644 UefiPayloadPkg/Include/Guid/TcgPhysicalPresenceGuid.h diff --git a/UefiPayloadPkg/Include/Coreboot.h b/UefiPayloadPkg/Include/Coreboot.h index 340465177c..a3e90227c9 100644 --- a/UefiPayloadPkg/Include/Coreboot.h +++ b/UefiPayloadPkg/Include/Coreboot.h @@ -258,5 +258,30 @@ struct cb_smmstorev2 { (void *)(((UINT8 *) (_rec)) + sizeof(*(_rec)) \ + (sizeof((_rec)->map[0]) * (_idx))) +#define CB_TAG_TPM_PPI_HANDOFF 0x003a + +enum lb_tmp_ppi_tpm_version { + LB_TPM_VERSION_UNSPEC = 0, + LB_TPM_VERSION_TPM_VERSION_1_2, + LB_TPM_VERSION_TPM_VERSION_2, +}; + +/* + * Handoff buffer for TPM Physical Presence Interface. + * * ppi_address Pointer to PPI buffer shared with ACPI + * The layout of the buffer matches the QEMU virtual memory device + * that is generated by QEMU. + * See files 'hw/i386/acpi-build.c' and 'include/hw/acpi/tpm.h' + * for details. + * * tpm_version TPM version: 1 for TPM1.2, 2 for TPM2.0 + * * ppi_version BCD encoded version of TPM PPI interface + */ +struct cb_tpm_physical_presence { + UINT32 tag; + UINT32 size; + UINT32 ppi_address; /* Address of ACPI PPI communication buffer */ + UINT8 tpm_version; /* 1: TPM1.2, 2: TPM2.0 */ + UINT8 ppi_version; /* BCD encoded */ +} __packed; #endif // _COREBOOT_PEI_H_INCLUDED_ diff --git a/UefiPayloadPkg/Include/Guid/TcgPhysicalPresenceGuid.h b/UefiPayloadPkg/Include/Guid/TcgPhysicalPresenceGuid.h new file mode 100644 index 0000000000..1f8ca6e3ab --- /dev/null +++ b/UefiPayloadPkg/Include/Guid/TcgPhysicalPresenceGuid.h @@ -0,0 +1,30 @@ +/** @file + This file defines the hob structure for Tcg Physical Presence Interface. + + Copyright (c) 2020, 9elements Agency GmbH
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __TCG_PHYSICAL_PRESENCE_GUID_H__ +#define __TCG_PHYSICAL_PRESENCE_GUID_H__ + +/// +/// TCG Physical Presence Information GUID +/// +extern EFI_GUID gEfiTcgPhysicalPresenceInfoHobGuid; + +typedef struct { + UINT32 PpiAddress; + UINT8 TpmVersion; + UINT8 PpiVersion; +} TCG_PHYSICAL_PRESENCE_INFO; + +#define UEFIPAYLOAD_TPM_VERSION_UNSPEC 0 +#define UEFIPAYLOAD_TPM_VERSION_1_2 1 +#define UEFIPAYLOAD_TPM_VERSION_2 2 + +#define UEFIPAYLOAD_TPM_PPI_VERSION_NONE 0 +#define UEFIPAYLOAD_TPM_PPI_VERSION_1_30 1 + +#endif diff --git a/UefiPayloadPkg/Include/Library/BlParseLib.h b/UefiPayloadPkg/Include/Library/BlParseLib.h index f9439e30a7..834197555a 100644 --- a/UefiPayloadPkg/Include/Library/BlParseLib.h +++ b/UefiPayloadPkg/Include/Library/BlParseLib.h @@ -13,6 +13,7 @@ #include #include #include +#include #ifndef __BOOTLOADER_PARSE_LIB__ #define __BOOTLOADER_PARSE_LIB__ @@ -133,4 +134,20 @@ ParseSMMSTOREInfo ( OUT SMMSTORE_INFO *SMMSTOREInfo ); + +/** + Find the Tcg Physical Presence store information + + @param PPIInfo Pointer to the TCG_PHYSICAL_PRESENCE_INFO structure + + @retval RETURN_SUCCESS Successfully find the SMM store buffer information. + @retval RETURN_NOT_FOUND Failed to find the SMM store buffer information . + +**/ +RETURN_STATUS +EFIAPI +ParseTPMPPIInfo ( + OUT TCG_PHYSICAL_PRESENCE_INFO *PPIInfo + ); + #endif diff --git a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c index 2b449f05eb..10fc3bcdc8 100644 --- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -600,3 +600,53 @@ ParseSMMSTOREInfo ( return RETURN_SUCCESS; } + + +/** + Find the Tcg Physical Presence store information + + @param PPIInfo Pointer to the TCG_PHYSICAL_PRESENCE_INFO structure + + @retval RETURN_SUCCESS Successfully find the SMM store buffer information. + @retval RETURN_NOT_FOUND Failed to find the SMM store buffer information . + +**/ +RETURN_STATUS +EFIAPI +ParseTPMPPIInfo ( + OUT TCG_PHYSICAL_PRESENCE_INFO *PPIInfo + ) +{ + struct cb_tpm_physical_presence *CbTPPRec; + UINT8 VersionMajor; + UINT8 VersionMinor; + + if (PPIInfo == NULL) { + return RETURN_INVALID_PARAMETER; + } + + CbTPPRec = FindCbTag (CB_TAG_TPM_PPI_HANDOFF); + if (CbTPPRec == NULL) { + return RETURN_NOT_FOUND; + } + + VersionMajor = CbTPPRec->ppi_version >> 4; + VersionMinor = CbTPPRec->ppi_version & 0xF; + + DEBUG ((DEBUG_INFO, "Found Tcg Physical Presence information\n")); + DEBUG ((DEBUG_INFO, "PpiAddress: 0x%x\n", CbTPPRec->ppi_address)); + DEBUG ((DEBUG_INFO, "TpmVersion: 0x%x\n", CbTPPRec->tpm_version)); + DEBUG ((DEBUG_INFO, "PpiVersion: %x.%x\n", VersionMajor, VersionMinor)); + + PPIInfo->PpiAddress = CbTPPRec->ppi_address; + if (CbTPPRec->tpm_version == LB_TPM_VERSION_TPM_VERSION_1_2) { + PPIInfo->TpmVersion = UEFIPAYLOAD_TPM_VERSION_1_2; + } else if (CbTPPRec->tpm_version == LB_TPM_VERSION_TPM_VERSION_2) { + PPIInfo->TpmVersion = UEFIPAYLOAD_TPM_VERSION_2; + } + if (VersionMajor == 1 && VersionMinor >= 3) { + PPIInfo->PpiVersion = UEFIPAYLOAD_TPM_PPI_VERSION_1_30; + } + + return RETURN_SUCCESS; +} diff --git a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c index 87e7605a2b..5c6a405daf 100644 --- a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c +++ b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c @@ -238,3 +238,21 @@ ParseSMMSTOREInfo ( { return RETURN_NOT_FOUND; } + +/** + Find the Tcg Physical Presence store information + + @param PPIInfo Pointer to the TCG_PHYSICAL_PRESENCE_INFO structure + + @retval RETURN_SUCCESS Successfully find the SMM store buffer information. + @retval RETURN_NOT_FOUND Failed to find the SMM store buffer information . + +**/ +RETURN_STATUS +EFIAPI +ParseTPMPPIInfo ( + OUT TCG_PHYSICAL_PRESENCE_INFO *PPIInfo + ) +{ + return RETURN_NOT_FOUND; +} diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c index bc6a8a2004..d90c2ae79f 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c @@ -407,6 +407,8 @@ BuildHobFromBl ( ACPI_BOARD_INFO *NewAcpiBoardInfo; SMMSTORE_INFO SMMSTOREInfo; SMMSTORE_INFO *NewSMMSTOREInfo; + TCG_PHYSICAL_PRESENCE_INFO PhysicalPresenceInfo; + TCG_PHYSICAL_PRESENCE_INFO *NewPhysicalPresenceInfo; EFI_PEI_GRAPHICS_INFO_HOB GfxInfo; EFI_PEI_GRAPHICS_INFO_HOB *NewGfxInfo; EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo; @@ -464,6 +466,17 @@ BuildHobFromBl ( DEBUG ((DEBUG_INFO, "Created SMMSTORE info hob\n")); } + // + // Create guid hob for Tcg Physical Presence Interface + // + Status = ParseTPMPPIInfo (&PhysicalPresenceInfo); + if (!EFI_ERROR (Status)) { + NewPhysicalPresenceInfo = BuildGuidHob (&gEfiTcgPhysicalPresenceInfoHobGuid, sizeof (TCG_PHYSICAL_PRESENCE_INFO)); + ASSERT (NewPhysicalPresenceInfo != NULL); + CopyMem (NewPhysicalPresenceInfo, &PhysicalPresenceInfo, sizeof (TCG_PHYSICAL_PRESENCE_INFO)); + DEBUG ((DEBUG_INFO, "Created Tcg Physical Presence info hob\n")); + } + // // Create guid hob for system tables like acpi table and smbios table // diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h index 54d8e9e960..9ad057455e 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h @@ -37,6 +37,7 @@ #include #include #include +#include #define LEGACY_8259_MASK_REGISTER_MASTER 0x21 #define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1 diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf index 88c661b09f..91312c06d4 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf @@ -68,6 +68,7 @@ gUniversalPayloadSmbiosTableGuid gUniversalPayloadAcpiTableGuid gEfiSMMSTOREInfoHobGuid + gEfiTcgPhysicalPresenceInfoHobGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index 18f7607ec7..2eda2ce246 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -37,6 +37,7 @@ gUefiSerialPortInfoGuid = { 0x6c6872fe, 0x56a9, 0x4403, { 0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1 } } gLoaderMemoryMapInfoGuid = { 0xa1ff7424, 0x7a1a, 0x478e, { 0xa9, 0xe4, 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32 } } gEfiSMMSTOREInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 } } + gEfiTcgPhysicalPresenceInfoHobGuid = { 0xf367be59, 0x5891, 0x40eb, { 0x21, 0x44, 0xed, 0x2e, 0xac, 0x57, 0xfd, 0x14 }} [Guids.common] #