Reviewed-by: Jiewen Yao <jiewen....@intel.com> > -----Original Message----- > From: Kun Qin <ku...@outlook.com> > Sent: Wednesday, February 10, 2021 9:25 AM > To: devel@edk2.groups.io > Cc: Yao, Jiewen <jiewen....@intel.com>; Wang, Jian J <jian.j.w...@intel.com>; > Zhang, Qi1 <qi1.zh...@intel.com>; Kumar, Rahul1 <rahul1.ku...@intel.com> > Subject: [PATCH v2 4/6] SecurityPkg: Tcg2Smm: Separate Tcg2Smm into 2 > modules > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3169 > > This change separated the original Tcg2Smm module into 2 drivers: the > SMM driver that registers callback for physical presence and memory > clear; the Tcg2Acpi driver that patches and publishes ACPI table for > runtime use. > > Tcg2Smm introduced an SMI root handler to allow Tcg2Acpi to communicate > the NVS region used by Tpm.asl and exchange the registered SwSmiValue. > > Lastly, Tcg2Smm driver will publish gTcg2MmSwSmiRegisteredGuid at the end > of entrypoint to ensure Tcg2Acpi to load after Tcg2Smm is ready to > communicate. > > Cc: Jiewen Yao <jiewen....@intel.com> > Cc: Jian J Wang <jian.j.w...@intel.com> > Cc: Qi Zhang <qi1.zh...@intel.com> > Cc: Rahul Kumar <rahul1.ku...@intel.com> > > Signed-off-by: Kun Qin <ku...@outlook.com> > --- > > Notes: > v2: > - Newly added in v2. > > v2: > - Newly added. > > SecurityPkg/Tcg/{Tcg2Smm/Tcg2Smm.c => Tcg2Acpi/Tcg2Acpi.c} | 350 ++++- > --- > SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c | 850 > ++++---------------- > SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c | 82 ++ > SecurityPkg/Include/Guid/TpmNvsMm.h | 68 ++ > SecurityPkg/SecurityPkg.dec | 7 + > SecurityPkg/SecurityPkg.dsc | 1 + > SecurityPkg/Tcg/{Tcg2Smm/Tcg2Smm.inf => Tcg2Acpi/Tcg2Acpi.inf} | 32 +- > SecurityPkg/Tcg/{Tcg2Smm => Tcg2Acpi}/Tpm.asl | 0 > SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h | 119 +-- > SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf | 25 +- > 10 files changed, 542 insertions(+), 992 deletions(-) > > diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c > b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c > similarity index 72% > copy from SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c > copy to SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c > index 08105c3692ba..7080df81efe7 100644 > --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c > +++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c > @@ -1,20 +1,74 @@ > /** @file > - It updates TPM2 items in ACPI table and registers SMI2 callback > - functions for Tcg2 physical presence, ClearMemory, and sample > - for dTPM StartMethod. > + This driver implements TPM 2.0 definition block in ACPI table and > + populates registered SMI callback functions for Tcg2 physical presence > + and MemoryClear to handle the requests for ACPI method. > > Caution: This module requires additional review when modified. > This driver will have external input - variable and ACPINvs data in SMM > mode. > This external input must be validated carefully to avoid security issue. > > - PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted > input and do some check. > - > Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> > +Copyright (c) Microsoft Corporation. > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > > -#include "Tcg2Smm.h" > +#include <PiDxe.h> > + > +#include <IndustryStandard/Tpm2Acpi.h> > + > +#include <Guid/TpmInstance.h> > +#include <Guid/TpmNvsMm.h> > +#include <Guid/PiSmmCommunicationRegionTable.h> > + > +#include <Protocol/AcpiTable.h> > +#include <Protocol/Tcg2Protocol.h> > +#include <Protocol/MmCommunication.h> > + > +#include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/DxeServicesLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/DebugLib.h> > +#include <Library/PcdLib.h> > +#include <Library/PrintLib.h> > +#include <Library/TpmMeasurementLib.h> > +#include <Library/Tpm2DeviceLib.h> > +#include <Library/Tpm2CommandLib.h> > +#include <Library/UefiLib.h> > + > +// > +// Physical Presence Interface Version supported by Platform > +// > +#define PHYSICAL_PRESENCE_VERSION_TAG "$PV" > +#define PHYSICAL_PRESENCE_VERSION_SIZE 4 > + > +// > +// PNP _HID for TPM2 device > +// > +#define TPM_HID_TAG "NNNN0000" > +#define TPM_HID_PNP_SIZE 8 > +#define TPM_HID_ACPI_SIZE 9 > + > +#define TPM_PRS_RESL "RESL" > +#define TPM_PRS_RESS "RESS" > +#define TPM_PRS_RES_NAME_SIZE 4 > +// > +// Minimum PRS resource template size > +// 1 byte for BufferOp > +// 1 byte for PkgLength > +// 2 bytes for BufferSize > +// 12 bytes for Memory32Fixed descriptor > +// 5 bytes for Interrupt descriptor > +// 2 bytes for END Tag > +// > +#define TPM_POS_RES_TEMPLATE_MIN_SIZE (1 + 1 + > 2 + 12 + > 5 + 2) > + > +// > +// Max Interrupt buffer size for PRS interrupt resource > +// Now support 15 interrupts in maxmum > +// > +#define MAX_PRS_INT_BUF_SIZE (15*4) > > #pragma pack(1) > > @@ -49,142 +103,8 @@ EFI_TPM2_ACPI_TABLE_V4 mTpm2AcpiTemplate = { > EFI_TPM2_ACPI_TABLE_START_METHOD_TIS, // StartMethod > }; > > -EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable; > TCG_NVS *mTcgNvs; > > -/** > - Software SMI callback for TPM physical presence which is called from ACPI > method. > - > - Caution: This function may receive untrusted input. > - Variable and ACPINvs are external input, so this function will validate > - its data structure to be valid value. > - > - @param[in] DispatchHandle The unique handle assigned to this handler > by > SmiHandlerRegister(). > - @param[in] Context Points to an optional handler context > which was > specified when the > - handler was registered. > - @param[in, out] CommBuffer A pointer to a collection of data in memory > that will > - be conveyed from a non-SMM environment > into an SMM > environment. > - @param[in, out] CommBufferSize The size of the CommBuffer. > - > - @retval EFI_SUCCESS The interrupt was handled successfully. > - > -**/ > -EFI_STATUS > -EFIAPI > -PhysicalPresenceCallback ( > - IN EFI_HANDLE DispatchHandle, > - IN CONST VOID *Context, > - IN OUT VOID *CommBuffer, > - IN OUT UINTN *CommBufferSize > - ) > -{ > - UINT32 MostRecentRequest; > - UINT32 Response; > - UINT32 OperationRequest; > - UINT32 RequestParameter; > - > - > - if (mTcgNvs->PhysicalPresence.Parameter == > TCG_ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) { > - mTcgNvs->PhysicalPresence.ReturnCode = > Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction ( > - &MostRecentRequest, > - &Response > - ); > - mTcgNvs->PhysicalPresence.LastRequest = MostRecentRequest; > - mTcgNvs->PhysicalPresence.Response = Response; > - return EFI_SUCCESS; > - } else if ((mTcgNvs->PhysicalPresence.Parameter == > TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS) > - || (mTcgNvs->PhysicalPresence.Parameter == > TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2)) { > - > - OperationRequest = mTcgNvs->PhysicalPresence.Request; > - RequestParameter = mTcgNvs->PhysicalPresence.RequestParameter; > - mTcgNvs->PhysicalPresence.ReturnCode = > Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx ( > - &OperationRequest, > - &RequestParameter > - ); > - mTcgNvs->PhysicalPresence.Request = OperationRequest; > - mTcgNvs->PhysicalPresence.RequestParameter = RequestParameter; > - } else if (mTcgNvs->PhysicalPresence.Parameter == > TCG_ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) { > - mTcgNvs->PhysicalPresence.ReturnCode = > Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (mTcgNvs- > >PPRequestUserConfirm); > - } > - > - return EFI_SUCCESS; > -} > - > - > -/** > - Software SMI callback for MemoryClear which is called from ACPI method. > - > - Caution: This function may receive untrusted input. > - Variable and ACPINvs are external input, so this function will validate > - its data structure to be valid value. > - > - @param[in] DispatchHandle The unique handle assigned to this handler > by > SmiHandlerRegister(). > - @param[in] Context Points to an optional handler context > which was > specified when the > - handler was registered. > - @param[in, out] CommBuffer A pointer to a collection of data in memory > that will > - be conveyed from a non-SMM environment > into an SMM > environment. > - @param[in, out] CommBufferSize The size of the CommBuffer. > - > - @retval EFI_SUCCESS The interrupt was handled successfully. > - > -**/ > -EFI_STATUS > -EFIAPI > -MemoryClearCallback ( > - IN EFI_HANDLE DispatchHandle, > - IN CONST VOID *Context, > - IN OUT VOID *CommBuffer, > - IN OUT UINTN *CommBufferSize > - ) > -{ > - EFI_STATUS Status; > - UINTN DataSize; > - UINT8 MorControl; > - > - mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS; > - if (mTcgNvs->MemoryClear.Parameter == > ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) { > - MorControl = (UINT8) mTcgNvs->MemoryClear.Request; > - } else if (mTcgNvs->MemoryClear.Parameter == > ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) { > - DataSize = sizeof (UINT8); > - Status = mSmmVariable->SmmGetVariable ( > - MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, > - &gEfiMemoryOverwriteControlDataGuid, > - NULL, > - &DataSize, > - &MorControl > - ); > - if (EFI_ERROR (Status)) { > - mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE; > - DEBUG ((EFI_D_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", > Status)); > - return EFI_SUCCESS; > - } > - > - if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) { > - return EFI_SUCCESS; > - } > - MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK; > - } else { > - mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE; > - DEBUG ((EFI_D_ERROR, "[TPM] MOR Parameter error! Parameter = %x\n", > mTcgNvs->MemoryClear.Parameter)); > - return EFI_SUCCESS; > - } > - > - DataSize = sizeof (UINT8); > - Status = mSmmVariable->SmmSetVariable ( > - MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, > - &gEfiMemoryOverwriteControlDataGuid, > - EFI_VARIABLE_NON_VOLATILE | > EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > - DataSize, > - &MorControl > - ); > - if (EFI_ERROR (Status)) { > - mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE; > - DEBUG ((EFI_D_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", > Status)); > - } > - > - return EFI_SUCCESS; > -} > - > /** > Find the operation region in TCG ACPI table by given Name and Size, > and initialize it if the region is found. > @@ -232,6 +152,103 @@ AssignOpRegion ( > return (VOID *) (UINTN) MemoryAddress; > } > > +/** > + Locate the MM communication buffer and protocol, then use it to exchange > information with > + Tcg2StandaloneMmm on NVS address and SMI value. > + > + @param[in, out] TcgNvs The NVS subject to send to MM environment. > + > + @return The status for locating MM common buffer, > communicate to MM, etc. > + > +**/ > +EFI_STATUS > +EFIAPI > +ExchangeCommonBuffer ( > + IN OUT TCG_NVS *TcgNvs > +) > +{ > + EFI_STATUS Status; > + EFI_MM_COMMUNICATION_PROTOCOL *MmCommunication; > + EDKII_PI_SMM_COMMUNICATION_REGION_TABLE > *PiSmmCommunicationRegionTable; > + EFI_MEMORY_DESCRIPTOR *MmCommMemRegion; > + EFI_MM_COMMUNICATE_HEADER *CommHeader; > + TPM_NVS_MM_COMM_BUFFER *CommBuffer; > + UINTN CommBufferSize; > + UINTN Index; > + > + // Step 0: Sanity check for input argument > + if (TcgNvs == NULL) { > + DEBUG ((DEBUG_ERROR, "%a - Input argument is NULL!\n", > __FUNCTION__)); > + return EFI_INVALID_PARAMETER; > + } > + > + // Step 1: Grab the common buffer header > + Status = EfiGetSystemConfigurationTable > (&gEdkiiPiSmmCommunicationRegionTableGuid, (VOID**) > &PiSmmCommunicationRegionTable); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a - Failed to locate SMM communciation > common buffer - %r!\n", __FUNCTION__, Status)); > + return Status; > + } > + > + // Step 2: Grab one that is large enough to hold > TPM_NVS_MM_COMM_BUFFER, the IPL one should be sufficient > + CommBufferSize = 0; > + MmCommMemRegion = (EFI_MEMORY_DESCRIPTOR*) > (PiSmmCommunicationRegionTable + 1); > + for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; > Index++) { > + if (MmCommMemRegion->Type == EfiConventionalMemory) { > + CommBufferSize = EFI_PAGES_TO_SIZE ((UINTN)MmCommMemRegion- > >NumberOfPages); > + if (CommBufferSize >= (sizeof (TPM_NVS_MM_COMM_BUFFER) + > OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data))) { > + break; > + } > + } > + MmCommMemRegion = > (EFI_MEMORY_DESCRIPTOR*)((UINT8*)MmCommMemRegion + > PiSmmCommunicationRegionTable->DescriptorSize); > + } > + > + if (Index >= PiSmmCommunicationRegionTable->NumberOfEntries) { > + // Could not find one that meets our goal... > + DEBUG ((DEBUG_ERROR, "%a - Could not find a common buffer that is big > enough for NVS!\n", __FUNCTION__)); > + return EFI_OUT_OF_RESOURCES; > + } > + > + // Step 3: Start to populate contents > + // Step 3.1: MM Communication common header > + CommHeader = (EFI_MM_COMMUNICATE_HEADER *) (UINTN) > MmCommMemRegion->PhysicalStart; > + CommBufferSize = sizeof (TPM_NVS_MM_COMM_BUFFER) + OFFSET_OF > (EFI_MM_COMMUNICATE_HEADER, Data); > + ZeroMem (CommHeader, CommBufferSize); > + CopyGuid (&CommHeader->HeaderGuid, &gTpmNvsMmGuid); > + CommHeader->MessageLength = sizeof (TPM_NVS_MM_COMM_BUFFER); > + > + // Step 3.2: TPM_NVS_MM_COMM_BUFFER content per our needs > + CommBuffer = (TPM_NVS_MM_COMM_BUFFER *) (CommHeader->Data); > + CommBuffer->Function = TpmNvsMmExchangeInfo; > + CommBuffer->TargetAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TcgNvs; > + > + // Step 4: Locate the protocol and signal Mmi. > + Status = gBS->LocateProtocol (&gEfiMmCommunicationProtocolGuid, NULL, > (VOID**) &MmCommunication); > + if (!EFI_ERROR (Status)) { > + Status = MmCommunication->Communicate (MmCommunication, > CommHeader, &CommBufferSize); > + DEBUG ((DEBUG_INFO, "%a - Communicate() = %r\n", __FUNCTION__, > Status)); > + } > + else { > + DEBUG ((DEBUG_ERROR, "%a - Failed to locate MmCommunication protocol > - %r\n", __FUNCTION__, Status)); > + return Status; > + } > + > + // Step 5: If everything goes well, populate the channel number > + if (!EFI_ERROR (CommBuffer->ReturnStatus)) { > + // Need to demote to UINT8 according to SMI value definition > + TcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) CommBuffer- > >RegisteredPpSwiValue; > + TcgNvs->MemoryClear.SoftwareSmi = (UINT8) CommBuffer- > >RegisteredMcSwiValue; > + DEBUG (( > + DEBUG_INFO, > + "%a Communication returned software SMI value. PP: 0x%x; MC: 0x%x.\n", > + __FUNCTION__, > + TcgNvs->PhysicalPresence.SoftwareSmi, > + TcgNvs->MemoryClear.SoftwareSmi > + )); > + } > + > + return (EFI_STATUS) CommBuffer->ReturnStatus; > +} > + > /** > Patch version string of Physical Presence interface supported by platform. > The > initial string tag in TPM > ACPI table is "$PV". > @@ -259,7 +276,7 @@ UpdatePPVersion ( > DataPtr += 1) { > if (AsciiStrCmp((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_TAG) == 0) > { > Status = AsciiStrCpyS((CHAR8 *)DataPtr, > PHYSICAL_PRESENCE_VERSION_SIZE, PPVer); > - DEBUG((EFI_D_INFO, "TPM2 Physical Presence Interface Version update > status 0x%x\n", Status)); > + DEBUG((DEBUG_INFO, "TPM2 Physical Presence Interface Version update > status 0x%x\n", Status)); > return Status; > } > } > @@ -548,7 +565,7 @@ UpdateHID ( > // > Status = Tpm2GetCapabilityManufactureID(&ManufacturerID); > if (!EFI_ERROR(Status)) { > - DEBUG((EFI_D_INFO, "TPM_PT_MANUFACTURER 0x%08x\n", > ManufacturerID)); > + DEBUG((DEBUG_INFO, "TPM_PT_MANUFACTURER 0x%08x\n", > ManufacturerID)); > // > // ManufacturerID defined in TCG Vendor ID Registry > // may tailed with 0x00 or 0x20 > @@ -568,15 +585,15 @@ UpdateHID ( > PnpHID = FALSE; > } > } else { > - DEBUG ((EFI_D_ERROR, "Get TPM_PT_MANUFACTURER failed %x!\n", > Status)); > + DEBUG ((DEBUG_ERROR, "Get TPM_PT_MANUFACTURER failed %x!\n", > Status)); > ASSERT(FALSE); > return Status; > } > > Status = Tpm2GetCapabilityFirmwareVersion(&FirmwareVersion1, > &FirmwareVersion2); > if (!EFI_ERROR(Status)) { > - DEBUG((EFI_D_INFO, "TPM_PT_FIRMWARE_VERSION_1 0x%x\n", > FirmwareVersion1)); > - DEBUG((EFI_D_INFO, "TPM_PT_FIRMWARE_VERSION_2 0x%x\n", > FirmwareVersion2)); > + DEBUG((DEBUG_INFO, "TPM_PT_FIRMWARE_VERSION_1 0x%x\n", > FirmwareVersion1)); > + DEBUG((DEBUG_INFO, "TPM_PT_FIRMWARE_VERSION_2 0x%x\n", > FirmwareVersion2)); > // > // #### is Firmware Version 1 > // > @@ -587,7 +604,7 @@ UpdateHID ( > } > > } else { > - DEBUG ((EFI_D_ERROR, "Get TPM_PT_FIRMWARE_VERSION_X failed %x!\n", > Status)); > + DEBUG ((DEBUG_ERROR, "Get TPM_PT_FIRMWARE_VERSION_X > failed %x!\n", Status)); > ASSERT(FALSE); > return Status; > } > @@ -615,7 +632,7 @@ UpdateHID ( > } > } > > - DEBUG((EFI_D_ERROR, "TPM2 ACPI HID TAG for patch not found!\n")); > + DEBUG((DEBUG_ERROR, "TPM2 ACPI HID TAG for patch not found!\n")); > return EFI_NOT_FOUND; > } > > @@ -716,6 +733,8 @@ PublishAcpiTable ( > mTcgNvs->TpmIrqNum = PcdGet32(PcdTpm2CurrentIrqNum); > mTcgNvs->IsShortFormPkgLength = IsShortFormPkgLength; > > + Status = ExchangeCommonBuffer (mTcgNvs); > + > // > // Publish the TPM ACPI table. Table is re-checksummed. > // > @@ -806,7 +825,7 @@ PublishTpm2 ( > case Tpm2PtpInterfaceTis: > break; > default: > - DEBUG((EFI_D_ERROR, "TPM2 InterfaceType get error! %d\n", > InterfaceType)); > + DEBUG((DEBUG_ERROR, "TPM2 InterfaceType get error! %d\n", > InterfaceType)); > break; > } > > @@ -849,58 +868,27 @@ PublishTpm2 ( > **/ > EFI_STATUS > EFIAPI > -InitializeTcgSmm ( > +InitializeTcgAcpi ( > IN EFI_HANDLE ImageHandle, > IN EFI_SYSTEM_TABLE *SystemTable > ) > { > EFI_STATUS Status; > - EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch; > - EFI_SMM_SW_REGISTER_CONTEXT SwContext; > - EFI_HANDLE SwHandle; > > if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), > &gEfiTpmDeviceInstanceTpm20DtpmGuid)){ > - DEBUG ((EFI_D_ERROR, "No TPM2 DTPM instance required!\n")); > + DEBUG ((DEBUG_ERROR, "No TPM2 DTPM instance required!\n")); > return EFI_UNSUPPORTED; > } > > Status = PublishAcpiTable (); > ASSERT_EFI_ERROR (Status); > > - // > - // Get the Sw dispatch protocol and register SMI callback functions. > - // > - Status = gMmst->MmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, > NULL, (VOID**)&SwDispatch); > - ASSERT_EFI_ERROR (Status); > - SwContext.SwSmiInputValue = (UINTN) -1; > - Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, > &SwContext, &SwHandle); > - ASSERT_EFI_ERROR (Status); > - if (EFI_ERROR (Status)) { > - return Status; > - } > - mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) > SwContext.SwSmiInputValue; > - > - SwContext.SwSmiInputValue = (UINTN) -1; > - Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, > &SwContext, &SwHandle); > - ASSERT_EFI_ERROR (Status); > - if (EFI_ERROR (Status)) { > - return Status; > - } > - mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue; > - > - // > - // Locate SmmVariableProtocol. > - // > - Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, > (VOID**)&mSmmVariable); > - ASSERT_EFI_ERROR (Status); > - > // > // Set TPM2 ACPI table > // > Status = PublishTpm2 (); > ASSERT_EFI_ERROR (Status); > > - > return EFI_SUCCESS; > } > > diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c > b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c > index 08105c3692ba..977ea3b1dfd2 100644 > --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c > +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c > @@ -10,47 +10,95 @@ > PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted > input and do some check. > > Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> > +Copyright (c) Microsoft Corporation. > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > > #include "Tcg2Smm.h" > > -#pragma pack(1) > - > -typedef struct { > - EFI_ACPI_DESCRIPTION_HEADER Header; > - // Flags field is replaced in version 4 and above > - // BIT0~15: PlatformClass This field is only valid for version 4 > and above > - // BIT16~31: Reserved > - UINT32 Flags; > - UINT64 AddressOfControlArea; > - UINT32 StartMethod; > - UINT8 PlatformSpecificParameters[12]; // size up to > 12 > - UINT32 Laml; // Optional > - UINT64 Lasa; // Optional > -} EFI_TPM2_ACPI_TABLE_V4; > - > -#pragma pack() > - > -EFI_TPM2_ACPI_TABLE_V4 mTpm2AcpiTemplate = { > - { > - EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE, > - sizeof (mTpm2AcpiTemplate), > - EFI_TPM2_ACPI_TABLE_REVISION, > - // > - // Compiler initializes the remaining bytes to 0 > - // These fields should be filled in in production > - // > - }, > - 0, // BIT0~15: PlatformClass > - // BIT16~31: Reserved > - 0, // Control Area > - EFI_TPM2_ACPI_TABLE_START_METHOD_TIS, // StartMethod > -}; > - > -EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable; > -TCG_NVS *mTcgNvs; > +EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL; > +TCG_NVS *mTcgNvs = NULL; > +UINTN mPpSoftwareSmi; > +UINTN mMcSoftwareSmi; > +EFI_HANDLE mReadyToLockHandle; > + > +/** > + Communication service SMI Handler entry. > + > + This handler takes requests to exchange Mmi channel and Nvs address > between MM and DXE. > + > + Caution: This function may receive untrusted input. > + Communicate buffer and buffer size are external input, so this function > will do > basic validation. > + > + @param[in] DispatchHandle The unique handle assigned to this > handler > by SmiHandlerRegister(). > + @param[in] RegisterContext Points to an optional handler context > which > was specified when the > + handler was registered. > + @param[in, out] CommBuffer A pointer to a collection of data in > memory > that will > + be conveyed from a non-SMM environment > into an SMM > environment. > + @param[in, out] CommBufferSize The size of the CommBuffer. > + > + @retval EFI_SUCCESS The interrupt was handled and quiesced. > No > other handlers > + should still be called. > + @retval EFI_UNSUPPORTED An unknown test function was requested. > + @retval EFI_ACCESS_DENIED Part of the communication buffer lies in > an > invalid region. > + > +**/ > +EFI_STATUS > +EFIAPI > +TpmNvsCommunciate ( > + IN EFI_HANDLE DispatchHandle, > + IN CONST VOID *RegisterContext, > + IN OUT VOID *CommBuffer, > + IN OUT UINTN *CommBufferSize > + ) > +{ > + EFI_STATUS Status; > + UINTN TempCommBufferSize; > + TPM_NVS_MM_COMM_BUFFER *CommParams; > + > + DEBUG ((DEBUG_VERBOSE, "%a()\n", __FUNCTION__)); > + > + // > + // If input is invalid, stop processing this SMI > + // > + if (CommBuffer == NULL || CommBufferSize == NULL) { > + return EFI_SUCCESS; > + } > + > + TempCommBufferSize = *CommBufferSize; > + > + if(TempCommBufferSize != sizeof (TPM_NVS_MM_COMM_BUFFER)) { > + DEBUG ((DEBUG_ERROR, "[%a] MM Communication buffer size is invalid for > this handler!\n", __FUNCTION__)); > + return EFI_ACCESS_DENIED; > + } > + if (!IsBufferOutsideMmValid ((UINTN) CommBuffer, TempCommBufferSize)) { > + DEBUG ((DEBUG_ERROR, "[%a] - MM Communication buffer in invalid > location!\n", __FUNCTION__)); > + return EFI_ACCESS_DENIED; > + } > + > + // > + // Farm out the job to individual functions based on what was requested. > + // > + CommParams = (TPM_NVS_MM_COMM_BUFFER*) CommBuffer; > + Status = EFI_SUCCESS; > + switch (CommParams->Function) { > + case TpmNvsMmExchangeInfo: > + DEBUG ((DEBUG_VERBOSE, "[%a] - Function requested: > MM_EXCHANGE_NVS_INFO\n", __FUNCTION__)); > + CommParams->RegisteredPpSwiValue = mPpSoftwareSmi; > + CommParams->RegisteredMcSwiValue = mMcSoftwareSmi; > + mTcgNvs = (TCG_NVS*) (UINTN) CommParams->TargetAddress; > + break; > + > + default: > + DEBUG ((DEBUG_INFO, "[%a] - Unknown function %d!\n", __FUNCTION__, > CommParams->Function)); > + Status = EFI_UNSUPPORTED; > + break; > + } > + > + CommParams->ReturnStatus = (UINT64) Status; > + return EFI_SUCCESS; > +} > > /** > Software SMI callback for TPM physical presence which is called from ACPI > method. > @@ -186,721 +234,137 @@ MemoryClearCallback ( > } > > /** > - Find the operation region in TCG ACPI table by given Name and Size, > - and initialize it if the region is found. > + Notification for SMM ReadyToLock protocol. > > - @param[in, out] Table The TPM item in ACPI table. > - @param[in] Name The name string to find in TPM table. > - @param[in] Size The size of the region to find. > + @param[in] Protocol Points to the protocol's unique identifier. > + @param[in] Interface Points to the interface instance. > + @param[in] Handle The handle on which the interface was installed. > > - @return The allocated address for the found region. > - > -**/ > -VOID * > -AssignOpRegion ( > - EFI_ACPI_DESCRIPTION_HEADER *Table, > - UINT32 Name, > - UINT16 Size > - ) > -{ > - EFI_STATUS Status; > - AML_OP_REGION_32_8 *OpRegion; > - EFI_PHYSICAL_ADDRESS MemoryAddress; > - > - MemoryAddress = SIZE_4GB - 1; > - > - // > - // Patch some pointers for the ASL code before loading the SSDT. > - // > - for (OpRegion = (AML_OP_REGION_32_8 *) (Table + 1); > - OpRegion <= (AML_OP_REGION_32_8 *) ((UINT8 *) Table + Table->Length); > - OpRegion = (AML_OP_REGION_32_8 *) ((UINT8 *) OpRegion + 1)) { > - if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) && > - (OpRegion->NameString == Name) && > - (OpRegion->DWordPrefix == AML_DWORD_PREFIX) && > - (OpRegion->BytePrefix == AML_BYTE_PREFIX)) { > - > - Status = gBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, > EFI_SIZE_TO_PAGES (Size), &MemoryAddress); > - ASSERT_EFI_ERROR (Status); > - ZeroMem ((VOID *)(UINTN)MemoryAddress, Size); > - OpRegion->RegionOffset = (UINT32) (UINTN) MemoryAddress; > - OpRegion->RegionLen = (UINT8) Size; > - break; > - } > - } > - > - return (VOID *) (UINTN) MemoryAddress; > -} > - > -/** > - Patch version string of Physical Presence interface supported by platform. > The > initial string tag in TPM > -ACPI table is "$PV". > - > - @param[in, out] Table The TPM item in ACPI table. > - @param[in] PPVer Version string of Physical Presence > interface > supported by platform. > - > - @return The allocated address for the found region. > - > -**/ > -EFI_STATUS > -UpdatePPVersion ( > - EFI_ACPI_DESCRIPTION_HEADER *Table, > - CHAR8 *PPVer > - ) > -{ > - EFI_STATUS Status; > - UINT8 *DataPtr; > - > - // > - // Patch some pointers for the ASL code before loading the SSDT. > - // > - for (DataPtr = (UINT8 *)(Table + 1); > - DataPtr <= (UINT8 *) ((UINT8 *) Table + Table->Length - > PHYSICAL_PRESENCE_VERSION_SIZE); > - DataPtr += 1) { > - if (AsciiStrCmp((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_TAG) == 0) > { > - Status = AsciiStrCpyS((CHAR8 *)DataPtr, > PHYSICAL_PRESENCE_VERSION_SIZE, PPVer); > - DEBUG((EFI_D_INFO, "TPM2 Physical Presence Interface Version update > status 0x%x\n", Status)); > - return Status; > - } > - } > - > - return EFI_NOT_FOUND; > -} > - > -/** > - Patch interrupt resources returned by TPM _PRS. ResourceTemplate to patch > is determined by input > - interrupt buffer size. BufferSize, PkgLength and interrupt descriptor in > ByteList > need to be patched > - > - @param[in, out] Table The TPM item in ACPI table. > - @param[in] IrqBuffer Input new IRQ buffer. > - @param[in] IrqBuffserSize Input new IRQ buffer size. > - @param[out] IsShortFormPkgLength If _PRS returns Short length > Package(ACPI spec 20.2.4). > - > - @return patch status. > - > -**/ > -EFI_STATUS > -UpdatePossibleResource ( > - IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table, > - IN UINT32 *IrqBuffer, > - IN UINT32 IrqBuffserSize, > - OUT BOOLEAN *IsShortFormPkgLength > - ) > -{ > - UINT8 *DataPtr; > - UINT8 *DataEndPtr; > - UINT32 NewPkgLength; > - UINT32 OrignalPkgLength; > - > - NewPkgLength = 0; > - OrignalPkgLength = 0; > - DataEndPtr = NULL; > - > - // > - // Follow ACPI spec > - // 6.4.3 Extend Interrupt Descriptor. > - // 19.3.3 ASL Resource Template > - // 20 AML specification > - // to patch TPM ACPI object _PRS returned ResourceTemplate() containing 2 > resource descriptors and an auto appended End Tag > - // > - // AML data is organized by following rule. > - // Code need to patch BufferSize and PkgLength and interrupt descriptor in > ByteList > - // > - // ============= Buffer ==================== > - // DefBuffer := BufferOp PkgLength BufferSize ByteList > - // BufferOp := 0x11 > - // > - // ==============PkgLength================== > - // PkgLength := PkgLeadByte | > - // <PkgLeadByte ByteData> | > - // <PkgLeadByte ByteData ByteData> | > - // <PkgLeadByte ByteData ByteData ByteData> > - // > - // PkgLeadByte := <bit 7-6: ByteData count that follows (0-3)> > - // <bit 5-4: Only used if PkgLength <= 63 > > - // <bit 3-0: Least significant package > length nybble> > - // > - //==============BufferSize================== > - // BufferSize := Integer > - // Integer := ByteConst|WordConst|DwordConst.... > - // > - // ByteConst := BytePrefix ByteData > - // > - //==============ByteList=================== > - // ByteList := ByteData ByteList > - // > - //========================================= > - > - // > - // 1. Check TPM_PRS_RESS with PkgLength <=63 can hold the input interrupt > number buffer for patching > - // > - for (DataPtr = (UINT8 *)(Table + 1); > - DataPtr < (UINT8 *) ((UINT8 *) Table + Table->Length - > (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE)); > - DataPtr += 1) { > - if (CompareMem(DataPtr, TPM_PRS_RESS, TPM_PRS_RES_NAME_SIZE) == 0) > { > - // > - // Jump over object name & BufferOp > - // > - DataPtr += TPM_PRS_RES_NAME_SIZE + 1; > - > - if ((*DataPtr & (BIT7|BIT6)) == 0) { > - OrignalPkgLength = (UINT32)*DataPtr; > - DataEndPtr = DataPtr + OrignalPkgLength; > - > - // > - // Jump over PkgLength = PkgLeadByte only > - // > - NewPkgLength++; > - > - // > - // Jump over BufferSize > - // > - if (*(DataPtr + 1) == AML_BYTE_PREFIX) { > - NewPkgLength += 2; > - } else if (*(DataPtr + 1) == AML_WORD_PREFIX) { > - NewPkgLength += 3; > - } else if (*(DataPtr + 1) == AML_DWORD_PREFIX) { > - NewPkgLength += 5; > - } else { > - ASSERT(FALSE); > - return EFI_UNSUPPORTED; > - } > - } else { > - ASSERT(FALSE); > - return EFI_UNSUPPORTED; > - } > - > - // > - // Include Memory32Fixed Descriptor (12 Bytes) + Interrupt Descriptor > header(5 Bytes) + End Tag(2 Bytes) > - // > - NewPkgLength += 19 + IrqBuffserSize; > - if (NewPkgLength > 63) { > - break; > - } > - > - if (NewPkgLength > OrignalPkgLength) { > - ASSERT(FALSE); > - return EFI_INVALID_PARAMETER; > - } > - > - // > - // 1.1 Patch PkgLength > - // > - *DataPtr = (UINT8)NewPkgLength; > - > - // > - // 1.2 Patch BufferSize = sizeof(Memory32Fixed Descriptor + Interrupt > Descriptor + End Tag). > - // It is Little endian. So only patch lowest byte of BufferSize > due to > current interrupt number limit. > - // > - *(DataPtr + 2) = (UINT8)(IrqBuffserSize + 19); > - > - // > - // Notify _PRS to report short formed ResourceTemplate > - // > - *IsShortFormPkgLength = TRUE; > - > - break; > - } > - } > - > - // > - // 2. Use TPM_PRS_RESL with PkgLength > 63 to hold longer input interrupt > number buffer for patching > - // > - if (NewPkgLength > 63) { > - NewPkgLength = 0; > - OrignalPkgLength = 0; > - for (DataPtr = (UINT8 *)(Table + 1); > - DataPtr < (UINT8 *) ((UINT8 *) Table + Table->Length - > (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE)); > - DataPtr += 1) { > - if (CompareMem(DataPtr, TPM_PRS_RESL, TPM_PRS_RES_NAME_SIZE) == 0) > { > - // > - // Jump over object name & BufferOp > - // > - DataPtr += TPM_PRS_RES_NAME_SIZE + 1; > - > - if ((*DataPtr & (BIT7|BIT6)) != 0) { > - OrignalPkgLength = (UINT32)(*(DataPtr + 1) << 4) + (*DataPtr & > 0x0F); > - DataEndPtr = DataPtr + OrignalPkgLength; > - // > - // Jump over PkgLength = PkgLeadByte + ByteData length > - // > - NewPkgLength += 1 + ((*DataPtr & (BIT7|BIT6)) >> 6); > - > - // > - // Jump over BufferSize > - // > - if (*(DataPtr + NewPkgLength) == AML_BYTE_PREFIX) { > - NewPkgLength += 2; > - } else if (*(DataPtr + NewPkgLength) == AML_WORD_PREFIX) { > - NewPkgLength += 3; > - } else if (*(DataPtr + NewPkgLength) == AML_DWORD_PREFIX) { > - NewPkgLength += 5; > - } else { > - ASSERT(FALSE); > - return EFI_UNSUPPORTED; > - } > - } else { > - ASSERT(FALSE); > - return EFI_UNSUPPORTED; > - } > - > - // > - // Include Memory32Fixed Descriptor (12 Bytes) + Interrupt Descriptor > header(5 Bytes) + End Tag(2 Bytes) > - // > - NewPkgLength += 19 + IrqBuffserSize; > - > - if (NewPkgLength > OrignalPkgLength) { > - ASSERT(FALSE); > - return EFI_INVALID_PARAMETER; > - } > - > - // > - // 2.1 Patch PkgLength. Only patch PkgLeadByte and first ByteData > - // > - *DataPtr = (UINT8)((*DataPtr) & 0xF0) | (NewPkgLength & 0x0F); > - *(DataPtr + 1) = (UINT8)((NewPkgLength & 0xFF0) >> 4); > - > - // > - // 2.2 Patch BufferSize = sizeof(Memory32Fixed Descriptor + Interrupt > Descriptor + End Tag). > - // It is Little endian. Only patch lowest byte of BufferSize due > to current > interrupt number limit. > - // > - *(DataPtr + 2 + ((*DataPtr & (BIT7|BIT6)) >> 6)) = > (UINT8)(IrqBuffserSize + > 19); > - > - // > - // Notify _PRS to report long formed ResourceTemplate > - // > - *IsShortFormPkgLength = FALSE; > - break; > - } > - } > - } > - > - if (DataPtr >= (UINT8 *) ((UINT8 *) Table + Table->Length - > (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE))) { > - return EFI_NOT_FOUND; > - } > - > - // > - // 3. Move DataPtr to Interrupt descriptor header and patch interrupt > descriptor. > - // 5 bytes for interrupt descriptor header, 2 bytes for End Tag > - // > - DataPtr += NewPkgLength - (5 + IrqBuffserSize + 2); > - // > - // 3.1 Patch Length bit[7:0] of Interrupt descriptor patch interrupt > descriptor > - // > - *(DataPtr + 1) = (UINT8)(2 + IrqBuffserSize); > - // > - // 3.2 Patch Interrupt Table Length > - // > - *(DataPtr + 4) = (UINT8)(IrqBuffserSize / sizeof(UINT32)); > - // > - // 3.3 Copy patched InterruptNumBuffer > - // > - CopyMem(DataPtr + 5, IrqBuffer, IrqBuffserSize); > - > - // > - // 4. Jump over Interrupt descriptor and Patch END Tag, set Checksum field > to > 0 > - // > - DataPtr += 5 + IrqBuffserSize; > - *DataPtr = ACPI_END_TAG_DESCRIPTOR; > - *(DataPtr + 1) = 0; > - > - // > - // 5. Jump over new ResourceTemplate. Stuff rest bytes to NOOP > - // > - DataPtr += 2; > - if (DataPtr < DataEndPtr) { > - SetMem(DataPtr, (UINTN)DataEndPtr - (UINTN)DataPtr, AML_NOOP_OP); > - } > - > - return EFI_SUCCESS; > -} > - > -/** > - Patch TPM2 device HID string. The initial string tag in TPM2 ACPI table is > "NNN0000". > - > - @param[in, out] Table The TPM2 SSDT ACPI table. > - > - @return HID Update status. > - > -**/ > -EFI_STATUS > -UpdateHID ( > - EFI_ACPI_DESCRIPTION_HEADER *Table > - ) > -{ > - EFI_STATUS Status; > - UINT8 *DataPtr; > - CHAR8 Hid[TPM_HID_ACPI_SIZE]; > - UINT32 ManufacturerID; > - UINT32 FirmwareVersion1; > - UINT32 FirmwareVersion2; > - BOOLEAN PnpHID; > - > - PnpHID = TRUE; > - > - // > - // Initialize HID with Default PNP string > - // > - ZeroMem(Hid, TPM_HID_ACPI_SIZE); > - > - // > - // Get Manufacturer ID > - // > - Status = Tpm2GetCapabilityManufactureID(&ManufacturerID); > - if (!EFI_ERROR(Status)) { > - DEBUG((EFI_D_INFO, "TPM_PT_MANUFACTURER 0x%08x\n", > ManufacturerID)); > - // > - // ManufacturerID defined in TCG Vendor ID Registry > - // may tailed with 0x00 or 0x20 > - // > - if ((ManufacturerID >> 24) == 0x00 || ((ManufacturerID >> 24) == 0x20)) { > - // > - // HID containing PNP ID "NNN####" > - // NNN is uppercase letter for Vendor ID specified by manufacturer > - // > - CopyMem(Hid, &ManufacturerID, 3); > - } else { > - // > - // HID containing ACP ID "NNNN####" > - // NNNN is uppercase letter for Vendor ID specified by manufacturer > - // > - CopyMem(Hid, &ManufacturerID, 4); > - PnpHID = FALSE; > - } > - } else { > - DEBUG ((EFI_D_ERROR, "Get TPM_PT_MANUFACTURER failed %x!\n", > Status)); > - ASSERT(FALSE); > - return Status; > - } > - > - Status = Tpm2GetCapabilityFirmwareVersion(&FirmwareVersion1, > &FirmwareVersion2); > - if (!EFI_ERROR(Status)) { > - DEBUG((EFI_D_INFO, "TPM_PT_FIRMWARE_VERSION_1 0x%x\n", > FirmwareVersion1)); > - DEBUG((EFI_D_INFO, "TPM_PT_FIRMWARE_VERSION_2 0x%x\n", > FirmwareVersion2)); > - // > - // #### is Firmware Version 1 > - // > - if (PnpHID) { > - AsciiSPrint(Hid + 3, TPM_HID_PNP_SIZE - 3, "%02d%02d", > ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 & 0x0000FFFF)); > - } else { > - AsciiSPrint(Hid + 4, TPM_HID_ACPI_SIZE - 4, "%02d%02d", > ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 & 0x0000FFFF)); > - } > - > - } else { > - DEBUG ((EFI_D_ERROR, "Get TPM_PT_FIRMWARE_VERSION_X failed %x!\n", > Status)); > - ASSERT(FALSE); > - return Status; > - } > - > - // > - // Patch HID in ASL code before loading the SSDT. > - // > - for (DataPtr = (UINT8 *)(Table + 1); > - DataPtr <= (UINT8 *) ((UINT8 *) Table + Table->Length - > TPM_HID_PNP_SIZE); > - DataPtr += 1) { > - if (AsciiStrCmp((CHAR8 *)DataPtr, TPM_HID_TAG) == 0) { > - if (PnpHID) { > - CopyMem(DataPtr, Hid, TPM_HID_PNP_SIZE); > - // > - // if HID is PNP ID, patch the last byte in HID TAG to Noop > - // > - *(DataPtr + TPM_HID_PNP_SIZE) = AML_NOOP_OP; > - } else { > - > - CopyMem(DataPtr, Hid, TPM_HID_ACPI_SIZE); > - } > - DEBUG((DEBUG_INFO, "TPM2 ACPI _HID is patched to %a\n", DataPtr)); > - > - return Status; > - } > - } > - > - DEBUG((EFI_D_ERROR, "TPM2 ACPI HID TAG for patch not found!\n")); > - return EFI_NOT_FOUND; > -} > - > -/** > - 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; > - UINT32 *PossibleIrqNumBuf; > - UINT32 PossibleIrqNumBufSize; > - BOOLEAN IsShortFormPkgLength; > - > - IsShortFormPkgLength = FALSE; > - > - 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. > - // The measurement has to be done before any update. > - // Otherwise, the PCR record would be different after TPM FW update > - // or the PCD configuration change. > - // > - TpmMeasureAndLogData( > - 0, > - EV_POST_CODE, > - EV_POSTCODE_INFO_ACPI_DATA, > - ACPI_DATA_LEN, > - Table, > - TableSize > - ); > - > - // > - // Update Table version before measuring it to PCR > - // > - Status = UpdatePPVersion(Table, (CHAR8 > *)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer)); > - ASSERT_EFI_ERROR (Status); > - > - DEBUG (( > - DEBUG_INFO, > - "Current physical presence interface version - %a\n", > - (CHAR8 *) PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer) > - )); > - > - // > - // Update TPM2 HID after measuring it to PCR > - // > - Status = UpdateHID(Table); > - if (EFI_ERROR(Status)) { > - return Status; > - } > - > - if (PcdGet32(PcdTpm2CurrentIrqNum) != 0) { > - // > - // Patch _PRS interrupt resource only when TPM interrupt is supported > - // > - PossibleIrqNumBuf = (UINT32 *)PcdGetPtr(PcdTpm2PossibleIrqNumBuf); > - PossibleIrqNumBufSize = (UINT32)PcdGetSize(PcdTpm2PossibleIrqNumBuf); > - > - if (PossibleIrqNumBufSize <= MAX_PRS_INT_BUF_SIZE && > (PossibleIrqNumBufSize % sizeof(UINT32)) == 0) { > - Status = UpdatePossibleResource(Table, PossibleIrqNumBuf, > PossibleIrqNumBufSize, &IsShortFormPkgLength); > - DEBUG (( > - DEBUG_INFO, > - "UpdatePossibleResource status - %x. TPM2 service may not ready in > OS.\n", > - Status > - )); > - } else { > - DEBUG (( > - DEBUG_INFO, > - "PcdTpm2PossibleIrqNumBuf size %x is not correct. TPM2 service may > not > ready in OS.\n", > - PossibleIrqNumBufSize > - )); > - } > - } > - > - 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); > - mTcgNvs->TpmIrqNum = PcdGet32(PcdTpm2CurrentIrqNum); > - mTcgNvs->IsShortFormPkgLength = IsShortFormPkgLength; > - > - // > - // Publish the TPM ACPI table. Table is re-checksummed. > - // > - 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; > -} > - > -/** > - Publish TPM2 ACPI table > - > - @retval EFI_SUCCESS The TPM2 ACPI table is published successfully. > - @retval Others The TPM2 ACPI table is not published. > + @retval EFI_SUCCESS Notification runs successfully. > > **/ > EFI_STATUS > -PublishTpm2 ( > - VOID > - ) > +EFIAPI > +TcgMmReadyToLock ( > + IN CONST EFI_GUID *Protocol, > + IN VOID *Interface, > + IN EFI_HANDLE Handle > +) > { > - EFI_STATUS Status; > - EFI_ACPI_TABLE_PROTOCOL *AcpiTable; > - UINTN TableKey; > - UINT64 OemTableId; > - EFI_TPM2_ACPI_CONTROL_AREA *ControlArea; > - TPM2_PTP_INTERFACE_TYPE InterfaceType; > - > - // > - // Measure to PCR[0] with event EV_POST_CODE ACPI DATA. > - // The measurement has to be done before any update. > - // Otherwise, the PCR record would be different after event log update > - // or the PCD configuration change. > - // > - TpmMeasureAndLogData( > - 0, > - EV_POST_CODE, > - EV_POSTCODE_INFO_ACPI_DATA, > - ACPI_DATA_LEN, > - &mTpm2AcpiTemplate, > - mTpm2AcpiTemplate.Header.Length > - ); > - > - mTpm2AcpiTemplate.Header.Revision = PcdGet8(PcdTpm2AcpiTableRev); > - DEBUG((DEBUG_INFO, "Tpm2 ACPI table revision is %d\n", > mTpm2AcpiTemplate.Header.Revision)); > - > - // > - // PlatformClass is only valid for version 4 and above > - // BIT0~15: PlatformClass > - // BIT16~31: Reserved > - // > - if (mTpm2AcpiTemplate.Header.Revision >= > EFI_TPM2_ACPI_TABLE_REVISION_4) { > - mTpm2AcpiTemplate.Flags = (mTpm2AcpiTemplate.Flags & 0xFFFF0000) | > PcdGet8(PcdTpmPlatformClass); > - DEBUG((DEBUG_INFO, "Tpm2 ACPI table PlatformClass is %d\n", > (mTpm2AcpiTemplate.Flags & 0x0000FFFF))); > - } > - > - mTpm2AcpiTemplate.Laml = PcdGet32(PcdTpm2AcpiTableLaml); > - mTpm2AcpiTemplate.Lasa = PcdGet64(PcdTpm2AcpiTableLasa); > - if ((mTpm2AcpiTemplate.Header.Revision < > EFI_TPM2_ACPI_TABLE_REVISION_4) || > - (mTpm2AcpiTemplate.Laml == 0) || (mTpm2AcpiTemplate.Lasa == 0)) { > - // > - // If version is smaller than 4 or Laml/Lasa is not valid, rollback to > original > Length. > - // > - mTpm2AcpiTemplate.Header.Length = sizeof(EFI_TPM2_ACPI_TABLE); > - } > + EFI_STATUS Status; > > - InterfaceType = PcdGet8(PcdActiveTpmInterfaceType); > - switch (InterfaceType) { > - case Tpm2PtpInterfaceCrb: > - mTpm2AcpiTemplate.StartMethod = > EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INT > ERFACE; > - 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 Tpm2PtpInterfaceFifo: > - case Tpm2PtpInterfaceTis: > - break; > - default: > - DEBUG((EFI_D_ERROR, "TPM2 InterfaceType get error! %d\n", > InterfaceType)); > - break; > + if (mReadyToLockHandle != NULL) { > + Status = gMmst->MmiHandlerUnRegister (mReadyToLockHandle); > + mReadyToLockHandle = NULL; > } > - > - 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, > - mTpm2AcpiTemplate.Header.Length, > - &TableKey > - ); > - ASSERT_EFI_ERROR (Status); > - > return Status; > } > > /** > - The driver's entry point. > + The driver's common initialization routine. > > It install callbacks for TPM physical presence and MemoryClear, and locate > SMM variable to be used in the callback function. > > - @param[in] ImageHandle The firmware allocated handle for the EFI image. > - @param[in] SystemTable A pointer to the EFI System Table. > - > @retval EFI_SUCCESS The entry point is executed successfully. > @retval Others Some error occurs when executing this entry point. > > **/ > EFI_STATUS > -EFIAPI > -InitializeTcgSmm ( > - IN EFI_HANDLE ImageHandle, > - IN EFI_SYSTEM_TABLE *SystemTable > +InitializeTcgCommon ( > + VOID > ) > { > EFI_STATUS Status; > EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch; > EFI_SMM_SW_REGISTER_CONTEXT SwContext; > - EFI_HANDLE SwHandle; > + EFI_HANDLE PpSwHandle; > + EFI_HANDLE McSwHandle; > + EFI_HANDLE NotifyHandle; > > if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), > &gEfiTpmDeviceInstanceTpm20DtpmGuid)){ > DEBUG ((EFI_D_ERROR, "No TPM2 DTPM instance required!\n")); > return EFI_UNSUPPORTED; > } > > - Status = PublishAcpiTable (); > + // Register a root handler to communicate the NVS region and SMI channel > between MM and DXE > + mReadyToLockHandle = NULL; > + Status = gMmst->MmiHandlerRegister (TpmNvsCommunciate, > &gTpmNvsMmGuid, &mReadyToLockHandle); > ASSERT_EFI_ERROR (Status); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "[%a] Failed to register NVS communicate as root > MM handler - %r!\n", __FUNCTION__, Status)); > + goto Cleanup; > + } > > // > // Get the Sw dispatch protocol and register SMI callback functions. > // > Status = gMmst->MmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, > NULL, (VOID**)&SwDispatch); > ASSERT_EFI_ERROR (Status); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "[%a] Failed to locate Sw dispatch protocol - > %r!\n", __FUNCTION__, Status)); > + goto Cleanup; > + } > + > + PpSwHandle = NULL; > SwContext.SwSmiInputValue = (UINTN) -1; > - Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, > &SwContext, &SwHandle); > + Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, > &SwContext, &PpSwHandle); > ASSERT_EFI_ERROR (Status); > if (EFI_ERROR (Status)) { > - return Status; > + DEBUG ((DEBUG_ERROR, "[%a] Failed to register PP callback as SW MM > handler - %r!\n", __FUNCTION__, Status)); > + goto Cleanup; > } > - mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) > SwContext.SwSmiInputValue; > + mPpSoftwareSmi = SwContext.SwSmiInputValue; > > + McSwHandle = NULL; > SwContext.SwSmiInputValue = (UINTN) -1; > - Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, > &SwContext, &SwHandle); > + Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, > &SwContext, &McSwHandle); > ASSERT_EFI_ERROR (Status); > if (EFI_ERROR (Status)) { > - return Status; > + DEBUG ((DEBUG_ERROR, "[%a] Failed to register MC callback as SW MM > handler - %r!\n", __FUNCTION__, Status)); > + goto Cleanup; > } > - mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue; > + mMcSoftwareSmi = SwContext.SwSmiInputValue; > > // > // Locate SmmVariableProtocol. > // > Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, > (VOID**)&mSmmVariable); > ASSERT_EFI_ERROR (Status); > + if (EFI_ERROR (Status)) { > + // Should not happen > + DEBUG ((DEBUG_ERROR, "[%a] Failed to locate SMM variable protocol - > %r!\n", __FUNCTION__, Status)); > + goto Cleanup; > + } > > - // > - // Set TPM2 ACPI table > - // > - Status = PublishTpm2 (); > + // Turn off the light before leaving the room... at least, take a remote... > + NotifyHandle = NULL; > + Status = gMmst->MmRegisterProtocolNotify > (&gEfiMmReadyToLockProtocolGuid, TcgMmReadyToLock, &NotifyHandle); > ASSERT_EFI_ERROR (Status); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "[%a] Failed to register ready to lock notification > - > %r!\n", __FUNCTION__, Status)); > + goto Cleanup; > + } > > + Tcg2NotifyMmReady (); > > - return EFI_SUCCESS; > +Cleanup: > + if (EFI_ERROR (Status)) { > + // Something is whacked, clean up the mess... > + if (NotifyHandle != NULL) { > + gMmst->MmRegisterProtocolNotify (&gEfiMmReadyToLockProtocolGuid, > NULL, &NotifyHandle); > + } > + if (McSwHandle != NULL && SwDispatch != NULL) { > + SwDispatch->UnRegister (SwDispatch, McSwHandle); > + } > + if (PpSwHandle != NULL && SwDispatch != NULL) { > + SwDispatch->UnRegister (SwDispatch, PpSwHandle); > + } > + if (mReadyToLockHandle != NULL) { > + gMmst->MmiHandlerUnRegister (mReadyToLockHandle); > + } > + } > + > + return Status; > } > > diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c > b/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c > new file mode 100644 > index 000000000000..5930090b4e46 > --- /dev/null > +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c > @@ -0,0 +1,82 @@ > +/** @file > + TCG2 SMM driver that updates TPM2 items in ACPI table and registers > + SMI2 callback functions for Tcg2 physical presence, ClearMemory, and > + sample for dTPM StartMethod. > + > + Caution: This module requires additional review when modified. > + This driver will have external input - variable and ACPINvs data in SMM > mode. > + This external input must be validated carefully to avoid security issue. > + > + PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted > input and do some check. > + > +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> > +Copyright (c) Microsoft Corporation. > +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "Tcg2Smm.h" > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/SmmMemLib.h> > + > +/** > + Notify the system that the SMM variable driver is ready. > +**/ > +VOID > +Tcg2NotifyMmReady ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + EFI_HANDLE Handle; > + > + Handle = NULL; > + Status = gBS->InstallProtocolInterface ( > + &Handle, > + &gTcg2MmSwSmiRegisteredGuid, > + EFI_NATIVE_INTERFACE, > + NULL > + ); > + ASSERT_EFI_ERROR (Status); > +} > + > +/** > + This function is an abstraction layer for implementation specific Mm buffer > validation routine. > + > + @param Buffer The buffer start address to be checked. > + @param Length The buffer length to be checked. > + > + @retval TRUE This buffer is valid per processor architecture and not > overlap > with SMRAM. > + @retval FALSE This buffer is not valid per processor architecture or > overlap > with SMRAM. > +**/ > +BOOLEAN > +IsBufferOutsideMmValid ( > + IN EFI_PHYSICAL_ADDRESS Buffer, > + IN UINT64 Length > + ) > +{ > + return SmmIsBufferOutsideSmmValid (Buffer, Length); > +} > + > +/** > + The driver's entry point. > + > + It install callbacks for TPM physical presence and MemoryClear, and locate > + SMM variable to be used in the callback function. > + > + @param[in] ImageHandle The firmware allocated handle for the EFI image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The entry point is executed successfully. > + @retval Others Some error occurs when executing this entry point. > + > +**/ > +EFI_STATUS > +EFIAPI > +InitializeTcgSmm ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + return InitializeTcgCommon (); > +} > diff --git a/SecurityPkg/Include/Guid/TpmNvsMm.h > b/SecurityPkg/Include/Guid/TpmNvsMm.h > new file mode 100644 > index 000000000000..a6e8e1f30f95 > --- /dev/null > +++ b/SecurityPkg/Include/Guid/TpmNvsMm.h > @@ -0,0 +1,68 @@ > +/** @file > + TPM NVS MM guid, used for exchanging information, including SWI value and > NVS region > + information, for patching TPM ACPI table. > + > +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> > +Copyright (c) Microsoft Corporation. > +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef __TCG2_NVS_MM_H__ > +#define __TCG2_NVS_MM_H__ > + > +#define MM_TPM_NVS_HOB_GUID \ > + { 0xc96c76eb, 0xbc78, 0x429c, { 0x9f, 0x4b, 0xda, 0x51, 0x78, 0xc2, 0x84, > 0x57 }} > + > +extern EFI_GUID gTpmNvsMmGuid; > + > +#pragma pack(1) > +typedef struct { > + UINT8 SoftwareSmi; > + UINT32 Parameter; > + UINT32 Response; > + UINT32 Request; > + UINT32 RequestParameter; > + UINT32 LastRequest; > + UINT32 ReturnCode; > +} PHYSICAL_PRESENCE_NVS; > + > +typedef struct { > + UINT8 SoftwareSmi; > + UINT32 Parameter; > + UINT32 Request; > + UINT32 ReturnCode; > +} MEMORY_CLEAR_NVS; > + > +typedef struct { > + PHYSICAL_PRESENCE_NVS PhysicalPresence; > + MEMORY_CLEAR_NVS MemoryClear; > + UINT32 PPRequestUserConfirm; > + UINT32 TpmIrqNum; > + BOOLEAN IsShortFormPkgLength; > +} TCG_NVS; > + > +typedef struct { > + UINT8 OpRegionOp; > + UINT32 NameString; > + UINT8 RegionSpace; > + UINT8 DWordPrefix; > + UINT32 RegionOffset; > + UINT8 BytePrefix; > + UINT8 RegionLen; > +} AML_OP_REGION_32_8; > + > +typedef struct { > + UINT64 Function; > + UINT64 ReturnStatus; > + EFI_PHYSICAL_ADDRESS TargetAddress; > + UINT64 RegisteredPpSwiValue; > + UINT64 RegisteredMcSwiValue; > +} TPM_NVS_MM_COMM_BUFFER; > +#pragma pack() > + > +typedef enum { > + TpmNvsMmExchangeInfo, > +} TPM_NVS_MM_FUNCTION; > + > +#endif // __TCG_SMM_H__ > diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec > index 1b7d62e802b3..0970cae5c75e 100644 > --- a/SecurityPkg/SecurityPkg.dec > +++ b/SecurityPkg/SecurityPkg.dec > @@ -183,6 +183,13 @@ [Guids] > ## Include/OpalPasswordExtraInfoVariable.h > gOpalExtraInfoVariableGuid = {0x44a2ad5d, 0x612c, 0x47b3, {0xb0, 0x6e, > 0xc8, 0xf5, 0x0b, 0xfb, 0xf0, 0x7d}} > > + ## GUID used to exchange registered SWI value and NVS region between > Tcg2Acpi and Tcg2Smm. > + ## Include/Guid/TpmNvsMm.h > + gTpmNvsMmGuid = { 0xc96c76eb, 0xbc78, 0x429c, { 0x9f, > 0x4b, > 0xda, 0x51, 0x78, 0xc2, 0x84, 0x57 }} > + > + ## GUID used to enforce loading order between Tcg2Acpi and Tcg2Smm > + gTcg2MmSwSmiRegisteredGuid = { 0x9d4548b9, 0xa48d, 0x4db4, { 0x9a, > 0x68, 0x32, 0xc5, 0x13, 0x9e, 0x20, 0x18 } } > + > > [Ppis] > ## The PPI GUID for that TPM physical presence should be locked. > diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc > index 618420a56c33..928bff72baa3 100644 > --- a/SecurityPkg/SecurityPkg.dsc > +++ b/SecurityPkg/SecurityPkg.dsc > @@ -317,6 +317,7 @@ [Components.IA32, Components.X64] > SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf > SecurityPkg/Tcg/TcgSmm/TcgSmm.inf > SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf > + SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf > > SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib > .inf > > SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalP > resenceLib.inf > > diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf > b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf > similarity index 76% > copy from SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf > copy to SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf > index 872ed27cbe71..d8e06881c01d 100644 > --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf > +++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf > @@ -13,8 +13,8 @@ > # "Errata for PC Client Specific Platform Firmware Profile Specification > Version 1.0 Revision 1.03" > # > # This driver implements TPM 2.0 definition block in ACPI table and > -# registers SMI callback functions for Tcg2 physical presence and > -# MemoryClear to handle the requests from ACPI method. > +# populates registered SMI callback functions for Tcg2 physical presence > +# and MemoryClear to handle the requests for ACPI method. > # > # Caution: This module requires additional review when modified. > # This driver will have external input - variable and ACPINvs data in SMM > mode. > @@ -28,17 +28,15 @@ > > [Defines] > INF_VERSION = 0x00010005 > - BASE_NAME = Tcg2Smm > - MODULE_UNI_FILE = Tcg2Smm.uni > - FILE_GUID = 44A20657-10B8-4049-A148-ACD8812AF257 > - MODULE_TYPE = DXE_SMM_DRIVER > + BASE_NAME = Tcg2Acpi > + FILE_GUID = 0D4BBF18-C2CC-4C23-BD63-BFDAD4C710D0 > + MODULE_TYPE = DXE_DRIVER > PI_SPECIFICATION_VERSION = 0x0001000A > VERSION_STRING = 1.0 > - ENTRY_POINT = InitializeTcgSmm > + ENTRY_POINT = InitializeTcgAcpi > > [Sources] > - Tcg2Smm.h > - Tcg2Smm.c > + Tcg2Acpi.c > Tpm.asl > > [Packages] > @@ -50,7 +48,6 @@ [LibraryClasses] > BaseLib > BaseMemoryLib > UefiDriverEntryPoint > - MmServicesTableLib > UefiBootServicesTableLib > DebugLib > DxeServicesLib > @@ -60,16 +57,13 @@ [LibraryClasses] > PcdLib > > [Guids] > - ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControl" > - ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl" > - gEfiMemoryOverwriteControlDataGuid > - > gEfiTpmDeviceInstanceTpm20DtpmGuid ## PRODUCES > ## > GUID # TPM device identifier > + gTpmNvsMmGuid ## CONSUMES > + gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES > > [Protocols] > - gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES > - gEfiSmmVariableProtocolGuid ## CONSUMES > gEfiAcpiTableProtocolGuid ## CONSUMES > + gEfiMmCommunicationProtocolGuid ## CONSUMES > > [FixedPcd] > gEfiSecurityPkgTokenSpaceGuid.PcdSmiCommandIoPort ## CONSUMES > @@ -93,9 +87,5 @@ [Pcd] > > [Depex] > gEfiAcpiTableProtocolGuid AND > - gEfiSmmSwDispatch2ProtocolGuid AND > - gEfiSmmVariableProtocolGuid AND > + gTcg2MmSwSmiRegisteredGuid AND > gEfiTcg2ProtocolGuid > - > -[UserExtensions.TianoCore."ExtraFiles"] > - Tcg2SmmExtra.uni > diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl > b/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl > similarity index 100% > rename from SecurityPkg/Tcg/Tcg2Smm/Tpm.asl > rename to SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl > diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h > b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h > index d7328c8f2ac9..d7f78aa43275 100644 > --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h > +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h > @@ -2,6 +2,7 @@ > The header file for Tcg2 SMM driver. > > Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> > +Copyright (c) Microsoft Corporation. > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > @@ -9,13 +10,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #ifndef __TCG2_SMM_H__ > #define __TCG2_SMM_H__ > > -#include <PiDxe.h> > -#include <IndustryStandard/Acpi.h> > -#include <IndustryStandard/Tpm2Acpi.h> > +#include <PiMm.h> > > #include <Guid/MemoryOverwriteControl.h> > #include <Guid/TpmInstance.h> > +#include <Guid/TpmNvsMm.h> > > +#include <Protocol/MmReadyToLock.h> > #include <Protocol/SmmSwDispatch2.h> > #include <Protocol/AcpiTable.h> > #include <Protocol/SmmVariable.h> > @@ -25,56 +26,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #include <Library/BaseMemoryLib.h> > #include <Library/DebugLib.h> > #include <Library/MmServicesTableLib.h> > -#include <Library/UefiDriverEntryPoint.h> > -#include <Library/UefiBootServicesTableLib.h> > -#include <Library/DxeServicesLib.h> > -#include <Library/TpmMeasurementLib.h> > #include <Library/Tpm2CommandLib.h> > #include <Library/Tcg2PhysicalPresenceLib.h> > #include <Library/IoLib.h> > -#include <Library/PrintLib.h> > #include <Library/PcdLib.h> > #include <Library/Tpm2DeviceLib.h> > > #include <IndustryStandard/TpmPtp.h> > > -#pragma pack(1) > -typedef struct { > - UINT8 SoftwareSmi; > - UINT32 Parameter; > - UINT32 Response; > - UINT32 Request; > - UINT32 RequestParameter; > - UINT32 LastRequest; > - UINT32 ReturnCode; > -} PHYSICAL_PRESENCE_NVS; > - > -typedef struct { > - UINT8 SoftwareSmi; > - UINT32 Parameter; > - UINT32 Request; > - UINT32 ReturnCode; > -} MEMORY_CLEAR_NVS; > - > -typedef struct { > - PHYSICAL_PRESENCE_NVS PhysicalPresence; > - MEMORY_CLEAR_NVS MemoryClear; > - UINT32 PPRequestUserConfirm; > - UINT32 TpmIrqNum; > - BOOLEAN IsShortFormPkgLength; > -} TCG_NVS; > - > -typedef struct { > - UINT8 OpRegionOp; > - UINT32 NameString; > - UINT8 RegionSpace; > - UINT8 DWordPrefix; > - UINT32 RegionOffset; > - UINT8 BytePrefix; > - UINT8 RegionLen; > -} AML_OP_REGION_32_8; > -#pragma pack() > - > // > // The definition for TCG MOR > // > @@ -87,36 +46,42 @@ typedef struct { > #define MOR_REQUEST_SUCCESS 0 > #define MOR_REQUEST_GENERAL_FAILURE 1 > > -// > -// Physical Presence Interface Version supported by Platform > -// > -#define PHYSICAL_PRESENCE_VERSION_TAG "$PV" > -#define PHYSICAL_PRESENCE_VERSION_SIZE 4 > - > -// > -// PNP _HID for TPM2 device > -// > -#define TPM_HID_TAG "NNNN0000" > -#define TPM_HID_PNP_SIZE 8 > -#define TPM_HID_ACPI_SIZE 9 > - > -#define TPM_PRS_RESL "RESL" > -#define TPM_PRS_RESS "RESS" > -#define TPM_PRS_RES_NAME_SIZE 4 > -// > -// Minimum PRS resource template size > -// 1 byte for BufferOp > -// 1 byte for PkgLength > -// 2 bytes for BufferSize > -// 12 bytes for Memory32Fixed descriptor > -// 5 bytes for Interrupt descriptor > -// 2 bytes for END Tag > -// > -#define TPM_POS_RES_TEMPLATE_MIN_SIZE (1 + 1 + > 2 + 12 + 5 > + 2) > - > -// > -// Max Interrupt buffer size for PRS interrupt resource > -// Now support 15 interrupts in maxmum > -// > -#define MAX_PRS_INT_BUF_SIZE (15*4) > +/** > + Notify the system that the SMM variable driver is ready. > +**/ > +VOID > +Tcg2NotifyMmReady ( > + VOID > + ); > + > +/** > + This function is an abstraction layer for implementation specific Mm buffer > validation routine. > + > + @param Buffer The buffer start address to be checked. > + @param Length The buffer length to be checked. > + > + @retval TRUE This buffer is valid per processor architecture and not > overlap > with SMRAM. > + @retval FALSE This buffer is not valid per processor architecture or > overlap > with SMRAM. > +**/ > +BOOLEAN > +IsBufferOutsideMmValid ( > + IN EFI_PHYSICAL_ADDRESS Buffer, > + IN UINT64 Length > + ); > + > +/** > + The driver's common initialization routine. > + > + It install callbacks for TPM physical presence and MemoryClear, and locate > + SMM variable to be used in the callback function. > + > + @retval EFI_SUCCESS The entry point is executed successfully. > + @retval Others Some error occurs when executing this entry point. > + > +**/ > +EFI_STATUS > +InitializeTcgCommon ( > + VOID > + ); > + > #endif // __TCG_SMM_H__ > diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf > b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf > index 872ed27cbe71..096338d0ef47 100644 > --- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf > +++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf > @@ -39,7 +39,7 @@ [Defines] > [Sources] > Tcg2Smm.h > Tcg2Smm.c > - Tpm.asl > + Tcg2TraditionalMm.c > > [Packages] > MdePkg/MdePkg.dec > @@ -58,6 +58,7 @@ [LibraryClasses] > Tpm2CommandLib > Tcg2PhysicalPresenceLib > PcdLib > + SmmMemLib > > [Guids] > ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControl" > @@ -65,34 +66,18 @@ [Guids] > gEfiMemoryOverwriteControlDataGuid > > gEfiTpmDeviceInstanceTpm20DtpmGuid ## PRODUCES > ## > GUID # TPM device identifier > + gTcg2MmSwSmiRegisteredGuid ## PRODUCES > + gTpmNvsMmGuid ## CONSUMES > > [Protocols] > gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES > gEfiSmmVariableProtocolGuid ## CONSUMES > - gEfiAcpiTableProtocolGuid ## CONSUMES > - > -[FixedPcd] > - gEfiSecurityPkgTokenSpaceGuid.PcdSmiCommandIoPort ## CONSUMES > + gEfiMmReadyToLockProtocolGuid ## CONSUMES > > [Pcd] > gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES > - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## > SOMETIMES_CONSUMES > - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## > SOMETIMES_CONSUMES > - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## > SOMETIMES_CONSUMES > - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## > SOMETIMES_CONSUMES > - gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## > SOMETIMES_CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer ## > CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev ## > CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass ## > SOMETIMES_CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum ## CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2PossibleIrqNumBuf ## > CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdActiveTpmInterfaceType ## > CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLaml ## CONSUMES > - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLasa ## CONSUMES > > [Depex] > - gEfiAcpiTableProtocolGuid AND > gEfiSmmSwDispatch2ProtocolGuid AND > gEfiSmmVariableProtocolGuid AND > gEfiTcg2ProtocolGuid > -- > 2.30.0.windows.1
-=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#72124): https://edk2.groups.io/g/devel/message/72124 Mute This Topic: https://groups.io/mt/80522087/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-