From: "Yao, Jiewen" <jiewen.yao@intel.com>
To: Kun Qin <kun.q@outlook.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Wang, Jian J" <jian.j.wang@intel.com>,
"Zhang, Qi1" <qi1.zhang@intel.com>,
"Kumar, Rahul1" <rahul1.kumar@intel.com>
Subject: Re: [PATCH v2 4/6] SecurityPkg: Tcg2Smm: Separate Tcg2Smm into 2 modules
Date: Wed, 24 Feb 2021 01:20:54 +0000 [thread overview]
Message-ID: <BY5PR11MB41663E001A35B8384542AB108C9F9@BY5PR11MB4166.namprd11.prod.outlook.com> (raw)
In-Reply-To: <MWHPR06MB31025B3684F96A769E918C79F38D9@MWHPR06MB3102.namprd06.prod.outlook.com>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
> -----Original Message-----
> From: Kun Qin <kun.q@outlook.com>
> Sent: Wednesday, February 10, 2021 9:25 AM
> To: devel@edk2.groups.io
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>;
> Zhang, Qi1 <qi1.zhang@intel.com>; Kumar, Rahul1 <rahul1.kumar@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.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Qi Zhang <qi1.zhang@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
>
> Signed-off-by: Kun Qin <kun.q@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
next prev parent reply other threads:[~2021-02-24 1:22 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20210210012457.315-1-kun.q@outlook.com>
2021-02-10 1:24 ` [PATCH v2 1/6] MdeModulePkg: DxeMmUnblockMemoryLib: Added definition and null instance Kun Qin
2021-02-22 22:15 ` Kun Qin
2021-02-23 1:42 ` Wu, Hao A
2021-02-23 19:29 ` [edk2-devel] " Kun Qin
2021-02-24 1:27 ` Wu, Hao A
2021-02-24 1:33 ` Yao, Jiewen
2021-02-24 1:48 ` Kun Qin
2021-02-25 14:03 ` 回复: " gaoliming
2021-02-25 18:57 ` Kun Qin
[not found] ` <16668BE524C457EA.19172@groups.io>
2021-02-25 1:53 ` Kun Qin
2021-02-25 2:06 ` Yao, Jiewen
2021-02-25 2:20 ` Kun Qin
2021-02-10 1:24 ` [PATCH v2 2/6] MdeModulePkg: VariableSmmRuntimeDxe: Added request unblock memory interface Kun Qin
2021-02-10 1:24 ` [PATCH v2 3/6] SecurityPkg: Tcg2Smm: Switching from gSmst to gMmst Kun Qin
2021-02-24 1:20 ` Yao, Jiewen
2021-02-10 1:24 ` [PATCH v2 4/6] SecurityPkg: Tcg2Smm: Separate Tcg2Smm into 2 modules Kun Qin
2021-02-22 22:33 ` Kun Qin
2021-02-24 1:20 ` Yao, Jiewen [this message]
2021-02-10 1:24 ` [PATCH v2 5/6] SecurityPkg: Tcg2Smm: Added support for Standalone Mm Kun Qin
2021-02-24 1:26 ` Yao, Jiewen
2021-02-24 1:40 ` [edk2-devel] " Kun Qin
[not found] ` <16668B740798D6CC.26818@groups.io>
2021-02-25 2:26 ` Kun Qin
2021-03-01 8:28 ` Yao, Jiewen
2021-03-01 8:57 ` Kun Qin
2021-03-01 9:27 ` Yao, Jiewen
2021-03-01 9:45 ` Kun Qin
2021-02-10 1:24 ` [PATCH v2 6/6] SecurityPkg: Tcg2Acpi: Added unblock memory interface for NVS region Kun Qin
2021-02-24 1:24 ` Yao, Jiewen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BY5PR11MB41663E001A35B8384542AB108C9F9@BY5PR11MB4166.namprd11.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox