summaryrefslogtreecommitdiffstats
path: root/SecurityPkg/Tcg/TcgPei
diff options
context:
space:
mode:
authorgdong1 <gdong1@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-02 07:49:32 +0000
committergdong1 <gdong1@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-02 07:49:32 +0000
commit0c18794ea4289f03fefc7117b56740414cc0536c (patch)
tree4e51c5cc23c69a67cead8c58464da870daa4c029 /SecurityPkg/Tcg/TcgPei
parent986d1dfb0813d6a7623531e85c2e2a7e1f956cf8 (diff)
downloadedk2-0c18794ea4289f03fefc7117b56740414cc0536c.tar.gz
edk2-0c18794ea4289f03fefc7117b56740414cc0536c.tar.bz2
edk2-0c18794ea4289f03fefc7117b56740414cc0536c.zip
Add security package to repository.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12261 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'SecurityPkg/Tcg/TcgPei')
-rw-r--r--SecurityPkg/Tcg/TcgPei/TcgPei.c593
-rw-r--r--SecurityPkg/Tcg/TcgPei/TcgPei.inf67
-rw-r--r--SecurityPkg/Tcg/TcgPei/TisPei.c160
-rw-r--r--SecurityPkg/Tcg/TcgPei/TpmComm.c272
-rw-r--r--SecurityPkg/Tcg/TcgPei/TpmComm.h163
5 files changed, 1255 insertions, 0 deletions
diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.c b/SecurityPkg/Tcg/TcgPei/TcgPei.c
new file mode 100644
index 0000000000..63caddec8c
--- /dev/null
+++ b/SecurityPkg/Tcg/TcgPei/TcgPei.c
@@ -0,0 +1,593 @@
+/** @file
+ Initialize TPM device and measure FVs before handing off control to DXE.
+
+Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+
+#include <IndustryStandard/Tpm12.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Ppi/LockPhysicalPresence.h>
+#include <Ppi/TpmInitialized.h>
+#include <Ppi/FirmwareVolume.h>
+#include <Guid/TcgEventHob.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/TpmCommLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+
+#include "TpmComm.h"
+
+BOOLEAN mImageInMemory = FALSE;
+
+EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTpmInitializedPpiGuid,
+ NULL
+};
+
+/**
+ Lock physical presence if needed.
+
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PhysicalPresencePpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ Measure and record the Firmware Volum Information once FvInfoPPI install.
+
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
+ @return Others Fail to measure FV.
+
+**/
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ &gPeiLockPhysicalPresencePpiGuid,
+ PhysicalPresencePpiNotifyCallback
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiFirmwareVolumeInfoPpiGuid,
+ FirmwareVolmeInfoPpiNotifyCallback
+ }
+};
+
+CHAR8 mSCrtmVersion[] = "{D20BC7C6-A1A5-415c-AE85-38290AB6BE04}";
+
+EFI_PLATFORM_FIRMWARE_BLOB mMeasuredFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
+UINT32 mMeasuredFvIndex = 0;
+
+/**
+ Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
+ and build a GUIDed HOB recording the event which will be passed to the DXE phase and
+ added into the Event Log.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] HashData Physical address of the start of the data buffer
+ to be hashed, extended, and logged.
+ @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
+ @param[in] TpmHandle TPM handle.
+ @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
+ @param[in] NewEventData Pointer to the new event data.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+
+**/
+EFI_STATUS
+HashLogExtendEvent (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINTN HashDataLen,
+ IN TIS_TPM_HANDLE TpmHandle,
+ IN TCG_PCR_EVENT_HDR *NewEventHdr,
+ IN UINT8 *NewEventData
+ )
+{
+ EFI_STATUS Status;
+ VOID *HobData;
+
+ HobData = NULL;
+ if (HashDataLen != 0) {
+ Status = TpmCommHashAll (
+ HashData,
+ HashDataLen,
+ &NewEventHdr->Digest
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = TpmCommExtend (
+ PeiServices,
+ TpmHandle,
+ &NewEventHdr->Digest,
+ NewEventHdr->PCRIndex,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ HobData = BuildGuidHob (
+ &gTcgEventEntryHobGuid,
+ sizeof (*NewEventHdr) + NewEventHdr->EventSize
+ );
+ if (HobData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));
+ HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));
+ CopyMem (HobData, NewEventData, NewEventHdr->EventSize);
+ return EFI_SUCCESS;
+}
+
+/**
+ Measure CRTM version.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+
+**/
+EFI_STATUS
+EFIAPI
+MeasureCRTMVersion (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle
+ )
+{
+ TCG_PCR_EVENT_HDR TcgEventHdr;
+
+ //
+ // Here, only a static GUID is measured instead of real CRTM version.
+ // OEMs should get real CRTM version string and measure it.
+ //
+
+ TcgEventHdr.PCRIndex = 0;
+ TcgEventHdr.EventType = EV_S_CRTM_VERSION;
+ TcgEventHdr.EventSize = sizeof (mSCrtmVersion);
+ return HashLogExtendEvent (
+ PeiServices,
+ (UINT8*)&mSCrtmVersion,
+ TcgEventHdr.EventSize,
+ TpmHandle,
+ &TcgEventHdr,
+ (UINT8*)&mSCrtmVersion
+ );
+}
+
+/**
+ Measure FV image.
+ Add it into the measured FV list after the FV is measured successfully.
+
+ @param[in] FvBase Base address of FV image.
+ @param[in] FvLength Length of FV image.
+
+ @retval EFI_SUCCESS Fv image is measured successfully
+ or it has been already measured.
+ @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+
+**/
+EFI_STATUS
+EFIAPI
+MeasureFvImage (
+ IN EFI_PHYSICAL_ADDRESS FvBase,
+ IN UINT64 FvLength
+ )
+{
+ UINT32 Index;
+ EFI_STATUS Status;
+ EFI_PLATFORM_FIRMWARE_BLOB FvBlob;
+ TCG_PCR_EVENT_HDR TcgEventHdr;
+ TIS_TPM_HANDLE TpmHandle;
+
+ TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;
+
+ //
+ // Check whether FV is in the measured FV list.
+ //
+ for (Index = 0; Index < mMeasuredFvIndex; Index ++) {
+ if (mMeasuredFvInfo[Index].BlobBase == FvBase) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Measure and record the FV to the TPM
+ //
+ FvBlob.BlobBase = FvBase;
+ FvBlob.BlobLength = FvLength;
+
+ DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob.BlobBase));
+ DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob.BlobLength));
+
+ TcgEventHdr.PCRIndex = 0;
+ TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
+ TcgEventHdr.EventSize = sizeof (FvBlob);
+
+ Status = HashLogExtendEvent (
+ (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),
+ (UINT8*) (UINTN) FvBlob.BlobBase,
+ (UINTN) FvBlob.BlobLength,
+ TpmHandle,
+ &TcgEventHdr,
+ (UINT8*) &FvBlob
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Add new FV into the measured FV list.
+ //
+ ASSERT (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
+ if (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
+ mMeasuredFvInfo[mMeasuredFvIndex].BlobBase = FvBase;
+ mMeasuredFvInfo[mMeasuredFvIndex++].BlobLength = FvLength;
+ }
+
+ return Status;
+}
+
+/**
+ Measure main BIOS.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+
+**/
+EFI_STATUS
+EFIAPI
+MeasureMainBios (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle
+ )
+{
+ EFI_STATUS Status;
+ UINT32 FvInstances;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_FV_INFO VolumeInfo;
+ EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
+
+ FvInstances = 0;
+ while (TRUE) {
+ //
+ // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
+ // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
+ // platform for special CRTM TPM measuring.
+ //
+ Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // Measure and record the firmware volume that is dispatched by PeiCore
+ //
+ Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Locate the corresponding FV_PPI according to founded FV's format guid
+ //
+ Status = PeiServicesLocatePpi (
+ &VolumeInfo.FvFormat,
+ 0,
+ NULL,
+ (VOID**)&FvPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);
+ }
+
+ FvInstances++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Measure and record the Firmware Volum Information once FvInfoPPI install.
+
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
+ @return Others Fail to measure FV.
+
+**/
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
+ EFI_STATUS Status;
+ EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
+
+ Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;
+
+ //
+ // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
+ //
+ Status = PeiServicesLocatePpi (
+ &Fv->FvFormat,
+ 0,
+ NULL,
+ (VOID**)&FvPpi
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // This is an FV from an FFS file, and the parent FV must have already been measured,
+ // No need to measure twice, so just returns
+ //
+ if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {
+ return EFI_SUCCESS;
+ }
+
+ return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);
+}
+
+/**
+ Lock physical presence if needed.
+
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_ABORTED physicalPresenceCMDEnable is locked.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+
+**/
+EFI_STATUS
+EFIAPI
+PhysicalPresencePpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ PEI_LOCK_PHYSICAL_PRESENCE_PPI *LockPhysicalPresencePpi;
+ BOOLEAN LifetimeLock;
+ BOOLEAN CmdEnable;
+ TIS_TPM_HANDLE TpmHandle;
+
+ TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;
+ LockPhysicalPresencePpi = (PEI_LOCK_PHYSICAL_PRESENCE_PPI *) Ppi;
+
+ if (!LockPhysicalPresencePpi->LockPhysicalPresence ((CONST EFI_PEI_SERVICES**) PeiServices)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Lock TPM physical presence.
+ //
+
+ Status = TpmCommGetCapability (PeiServices, TpmHandle, NULL, &LifetimeLock, &CmdEnable);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (!CmdEnable) {
+ if (LifetimeLock) {
+ //
+ // physicalPresenceCMDEnable is locked, can't change.
+ //
+ return EFI_ABORTED;
+ }
+
+ //
+ // Enable physical presence command
+ // It is necessary in order to lock physical presence
+ //
+ Status = TpmCommPhysicalPresence (
+ PeiServices,
+ TpmHandle,
+ TPM_PHYSICAL_PRESENCE_CMD_ENABLE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Lock physical presence
+ //
+ Status = TpmCommPhysicalPresence (
+ PeiServices,
+ TpmHandle,
+ TPM_PHYSICAL_PRESENCE_LOCK
+ );
+ return Status;
+}
+
+/**
+ Check if TPM chip is activeated or not.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+
+ @retval TRUE TPM is activated.
+ @retval FALSE TPM is deactivated.
+
+**/
+BOOLEAN
+EFIAPI
+IsTpmUsable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN Deactivated;
+
+ Status = TpmCommGetCapability (PeiServices, TpmHandle, &Deactivated, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return (BOOLEAN)(!Deactivated);
+}
+
+/**
+ Do measurement after memory is ready.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+
+**/
+EFI_STATUS
+EFIAPI
+PeimEntryMP (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ TIS_TPM_HANDLE TpmHandle;
+
+ TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
+ Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (IsTpmUsable (PeiServices, TpmHandle)) {
+ Status = MeasureCRTMVersion (PeiServices, TpmHandle);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = MeasureMainBios (PeiServices, TpmHandle);
+ }
+
+ //
+ // Post callbacks:
+ // 1). for the FvInfoPpi services to measure and record
+ // the additional Fvs to TPM
+ // 2). for the OperatorPresencePpi service to determine whether to
+ // lock the TPM
+ //
+ Status = PeiServicesNotifyPpi (&mNotifyList[0]);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Entry point of this module.
+
+ @param[in] FileHandle Handle of the file being invoked.
+ @param[in] PeiServices Describes the list of possible PEI Services.
+
+ @return Status.
+
+**/
+EFI_STATUS
+EFIAPI
+PeimEntryMA (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ TIS_TPM_HANDLE TpmHandle;
+
+ if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = (**PeiServices).RegisterForShadow(FileHandle);
+ if (Status == EFI_ALREADY_STARTED) {
+ mImageInMemory = TRUE;
+ } else if (Status == EFI_NOT_FOUND) {
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (!mImageInMemory) {
+ //
+ // Initialize TPM device
+ //
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
+ Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
+ return Status;
+ }
+
+ Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
+ if (EFI_ERROR (Status) ) {
+ return Status;
+ }
+ Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (mImageInMemory) {
+ Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return Status;
+}
diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.inf b/SecurityPkg/Tcg/TcgPei/TcgPei.inf
new file mode 100644
index 0000000000..60a3bfa5f1
--- /dev/null
+++ b/SecurityPkg/Tcg/TcgPei/TcgPei.inf
@@ -0,0 +1,67 @@
+## @file
+# This module will initialize TPM device and measure FVs in PEI phase.
+#
+# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TcgPei
+ FILE_GUID = 2BE1E4A6-6505-43b3-9FFC-A3C8330E0432
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PeimEntryMA
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ TcgPei.c
+ TisPei.c
+ TpmComm.c
+ TpmComm.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ HobLib
+ PeimEntryPoint
+ PeiServicesLib
+ BaseMemoryLib
+ DebugLib
+ TpmCommLib
+ TimerLib
+ IoLib
+ PeiServicesTablePointerLib
+
+[Guids]
+ gTcgEventEntryHobGuid
+
+[Ppis]
+ gPeiLockPhysicalPresencePpiGuid
+ gEfiPeiFirmwareVolumeInfoPpiGuid
+ gPeiTpmInitializedPpiGuid
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
+
+[FixedPcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported ## CONSUMES
+
+[Depex]
+ gEfiPeiMasterBootModePpiGuid AND
+ gEfiPeiReadOnlyVariable2PpiGuid
diff --git a/SecurityPkg/Tcg/TcgPei/TisPei.c b/SecurityPkg/Tcg/TcgPei/TisPei.c
new file mode 100644
index 0000000000..97d9628bda
--- /dev/null
+++ b/SecurityPkg/Tcg/TcgPei/TisPei.c
@@ -0,0 +1,160 @@
+/** @file
+ TIS (TPM Interface Specification) functions used by TPM PEI driver.
+
+Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <IndustryStandard/Tpm12.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/TpmCommLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+
+/**
+ Send a command to TPM for execution and return response data.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TisReg TPM register space base address.
+ @param[in] BufferIn Buffer for command data.
+ @param[in] SizeIn Size of command data.
+ @param[in, out] BufferOut Buffer for response data.
+ @param[in, out] SizeOut Size of response data.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TisTpmCommand (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_PC_REGISTERS_PTR TisReg,
+ IN UINT8 *BufferIn,
+ IN UINT32 SizeIn,
+ IN OUT UINT8 *BufferOut,
+ IN OUT UINT32 *SizeOut
+ )
+{
+ EFI_STATUS Status;
+ UINT16 BurstCount;
+ UINT32 Index;
+ UINT32 TpmOutSize;
+ UINT16 Data16;
+ UINT32 Data32;
+
+ Status = TisPcPrepareCommand (TisReg);
+ if (EFI_ERROR (Status)){
+ DEBUG ((DEBUG_ERROR, "Tpm is not ready for command!\n"));
+ return Status;
+ }
+ //
+ // Send the command data to Tpm
+ //
+ Index = 0;
+ while (Index < SizeIn) {
+ Status = TisPcReadBurstCount (TisReg, &BurstCount);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_TIMEOUT;
+ goto Exit;
+ }
+ for (; BurstCount > 0 && Index < SizeIn; BurstCount--) {
+ MmioWrite8((UINTN)&TisReg->DataFifo, *(BufferIn + Index));
+ Index++;
+ }
+ }
+ //
+ // Check the Tpm status STS_EXPECT change from 1 to 0
+ //
+ Status = TisPcWaitRegisterBits (
+ &TisReg->Status,
+ (UINT8) TIS_PC_VALID,
+ TIS_PC_STS_EXPECT,
+ TIS_TIMEOUT_C
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "The send buffer too small!\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ }
+ //
+ // Executed the TPM command and waiting for the response data ready
+ //
+ MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_GO);
+ Status = TisPcWaitRegisterBits (
+ &TisReg->Status,
+ (UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),
+ 0,
+ TIS_TIMEOUT_B
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Wait for Tpm response data time out!!\n"));
+ Status = EFI_TIMEOUT;
+ goto Exit;
+ }
+ //
+ // Get response data header
+ //
+ Index = 0;
+ BurstCount = 0;
+ while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {
+ Status = TisPcReadBurstCount (TisReg, &BurstCount);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_TIMEOUT;
+ goto Exit;
+ }
+ for (; BurstCount > 0; BurstCount--) {
+ *(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
+ Index++;
+ if (Index == sizeof (TPM_RSP_COMMAND_HDR)) break;
+ }
+ }
+ //
+ // Check the reponse data header (tag,parasize and returncode )
+ //
+ CopyMem (&Data16, BufferOut, sizeof (UINT16));
+ if (SwapBytes16 (Data16) != TPM_TAG_RSP_COMMAND ) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));
+ TpmOutSize = SwapBytes32 (Data32);
+ if (*SizeOut < TpmOutSize) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ }
+ *SizeOut = TpmOutSize;
+ //
+ // Continue reading the remaining data
+ //
+ while ( Index < TpmOutSize ) {
+ for (; BurstCount > 0; BurstCount--) {
+ *(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
+ Index++;
+ if (Index == TpmOutSize) {
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ }
+ Status = TisPcReadBurstCount (TisReg, &BurstCount);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_TIMEOUT;
+ goto Exit;
+ }
+ }
+Exit:
+ MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
+ return Status;
+}
+
diff --git a/SecurityPkg/Tcg/TcgPei/TpmComm.c b/SecurityPkg/Tcg/TcgPei/TpmComm.c
new file mode 100644
index 0000000000..fb5011ee9d
--- /dev/null
+++ b/SecurityPkg/Tcg/TcgPei/TpmComm.c
@@ -0,0 +1,272 @@
+/** @file
+ Utility functions used by TPM PEI driver.
+
+Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TpmComm.h"
+
+/**
+ Send a command to TPM for execution and return response data.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TisReg TPM register space base address.
+ @param[in] BufferIn Buffer for command data.
+ @param[in] SizeIn Size of command data.
+ @param[in, out] BufferOut Buffer for response data.
+ @param[in, out] SizeOut size of response data.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TisTpmCommand (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_PC_REGISTERS_PTR TisReg,
+ IN UINT8 *BufferIn,
+ IN UINT32 SizeIn,
+ IN OUT UINT8 *BufferOut,
+ IN OUT UINT32 *SizeOut
+ );
+
+/**
+ Send TPM_Startup command to TPM.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+ @param[in] BootMode Boot mode.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommStartup (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle,
+ IN EFI_BOOT_MODE BootMode
+ )
+{
+ EFI_STATUS Status;
+ TPM_STARTUP_TYPE TpmSt;
+ UINT32 TpmRecvSize;
+ UINT32 TpmSendSize;
+ TPM_CMD_START_UP SendBuffer;
+ UINT8 RecvBuffer[20];
+
+ TpmSt = TPM_ST_CLEAR;
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ TpmSt = TPM_ST_STATE;
+ }
+ //
+ // send Tpm command TPM_ORD_Startup
+ //
+ TpmRecvSize = 20;
+ TpmSendSize = sizeof (TPM_CMD_START_UP);
+ SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
+ SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Startup);
+ SendBuffer.TpmSt = SwapBytes16 (TpmSt);
+ Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
+ return Status;
+}
+
+/**
+ Send TPM_ContinueSelfTest command to TPM.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommContinueSelfTest (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TpmRecvSize;
+ UINT32 TpmSendSize;
+ TPM_CMD_SELF_TEST SendBuffer;
+ UINT8 RecvBuffer[20];
+
+ //
+ // send Tpm command TPM_ORD_ContinueSelfTest
+ //
+ TpmRecvSize = 20;
+ TpmSendSize = sizeof (TPM_CMD_SELF_TEST);
+ SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
+ SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_ContinueSelfTest);
+ Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
+ return Status;
+}
+
+/**
+ Get TPM capability flags.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+ @param[out] Deactivated Returns deactivated flag.
+ @param[out] LifetimeLock Returns physicalPresenceLifetimeLock permanent flag.
+ @param[out] CmdEnable Returns physicalPresenceCMDEnable permanent flag.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommGetCapability (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle,
+ OUT BOOLEAN *Deactivated, OPTIONAL
+ OUT BOOLEAN *LifetimeLock, OPTIONAL
+ OUT BOOLEAN *CmdEnable OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TpmRecvSize;
+ UINT32 TpmSendSize;
+ TPM_CMD_GET_CAPABILITY SendBuffer;
+ UINT8 RecvBuffer[40];
+ TPM_PERMANENT_FLAGS *TpmPermanentFlags;
+
+ //
+ // send Tpm command TPM_ORD_GetCapability
+ //
+ TpmRecvSize = 40;
+ TpmSendSize = sizeof (TPM_CMD_GET_CAPABILITY);
+ SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
+ SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_GetCapability);
+ SendBuffer.Capability = SwapBytes32 (TPM_CAP_FLAG);
+ SendBuffer.CapabilityFlagSize = SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT));
+ SendBuffer.CapabilityFlag = SwapBytes32 (TPM_CAP_FLAG_PERMANENT);
+ Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];
+ if (Deactivated != NULL) {
+ *Deactivated = TpmPermanentFlags->deactivated;
+ }
+
+ if (LifetimeLock != NULL) {
+ *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock;
+ }
+
+ if (CmdEnable != NULL) {
+ *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable;
+ }
+ return Status;
+}
+
+/**
+ Extend a TPM PCR.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+ @param[in] DigestToExtend The 160 bit value representing the event to be recorded.
+ @param[in] PcrIndex The PCR to be updated.
+ @param[out] NewPcrValue New PCR value after extend.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommExtend (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle,
+ IN TPM_DIGEST *DigestToExtend,
+ IN TPM_PCRINDEX PcrIndex,
+ OUT TPM_DIGEST *NewPcrValue
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TpmSendSize;
+ UINT32 TpmRecvSize;
+ TPM_CMD_EXTEND SendBuffer;
+ UINT8 RecvBuffer[10 + sizeof(TPM_DIGEST)];
+
+ //
+ // send Tpm command TPM_ORD_Extend
+ //
+ TpmRecvSize = sizeof (TPM_RSP_COMMAND_HDR) + sizeof (TPM_DIGEST);
+ TpmSendSize = sizeof (TPM_CMD_EXTEND);
+ SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
+ SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Extend);
+ SendBuffer.PcrIndex = SwapBytes32 (PcrIndex);
+ CopyMem (&SendBuffer.TpmDigest, (UINT8 *)DigestToExtend, sizeof (TPM_DIGEST));
+ Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
+ ASSERT_EFI_ERROR (Status);
+
+ if(NewPcrValue != NULL) {
+ CopyMem ((UINT8*)NewPcrValue, &RecvBuffer[10], sizeof (TPM_DIGEST));
+ }
+
+ return Status;
+}
+
+
+/**
+ Send TSC_PhysicalPresence command to TPM.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+ @param[in] PhysicalPresence The state to set the TPMs Physical Presence flags.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommPhysicalPresence (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle,
+ IN TPM_PHYSICAL_PRESENCE PhysicalPresence
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TpmSendSize;
+ UINT32 TpmRecvSize;
+ TPM_CMD_PHYSICAL_PRESENCE SendBuffer;
+ UINT8 RecvBuffer[10];
+
+ //
+ // send Tpm command TSC_ORD_PhysicalPresence
+ //
+ TpmRecvSize = 10;
+ TpmSendSize = sizeof (TPM_CMD_PHYSICAL_PRESENCE);
+ SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
+ SendBuffer.Hdr.ordinal = SwapBytes32 (TSC_ORD_PhysicalPresence);
+ SendBuffer.PhysicalPresence = SwapBytes16 (PhysicalPresence);
+ Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
+ return Status;
+}
diff --git a/SecurityPkg/Tcg/TcgPei/TpmComm.h b/SecurityPkg/Tcg/TcgPei/TpmComm.h
new file mode 100644
index 0000000000..52d7f2e20d
--- /dev/null
+++ b/SecurityPkg/Tcg/TcgPei/TpmComm.h
@@ -0,0 +1,163 @@
+/** @file
+ The header file for TPM PEI driver.
+
+Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _TPM_COMM_H_
+#define _TPM_COMM_H_
+
+#include <IndustryStandard/Tpm12.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/TpmCommLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#pragma pack(1)
+
+typedef struct {
+ TPM_RQU_COMMAND_HDR Hdr;
+ TPM_STARTUP_TYPE TpmSt;
+} TPM_CMD_START_UP;
+
+typedef struct {
+ TPM_RQU_COMMAND_HDR Hdr;
+} TPM_CMD_SELF_TEST;
+
+typedef struct {
+ TPM_RQU_COMMAND_HDR Hdr;
+ UINT32 Capability;
+ UINT32 CapabilityFlagSize;
+ UINT32 CapabilityFlag;
+} TPM_CMD_GET_CAPABILITY;
+
+typedef struct {
+ TPM_RQU_COMMAND_HDR Hdr;
+ TPM_PCRINDEX PcrIndex;
+ TPM_DIGEST TpmDigest;
+} TPM_CMD_EXTEND;
+
+typedef struct {
+ TPM_RQU_COMMAND_HDR Hdr;
+ TPM_PHYSICAL_PRESENCE PhysicalPresence;
+} TPM_CMD_PHYSICAL_PRESENCE;
+
+#pragma pack()
+
+/**
+ Send TPM_Startup command to TPM.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+ @param[in] BootMode Boot mode.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommStartup (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle,
+ IN EFI_BOOT_MODE BootMode
+ );
+
+/**
+ Send TPM_ContinueSelfTest command to TPM.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommContinueSelfTest (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle
+ );
+
+/**
+ Get TPM capability flags.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+ @param[out] Deactivated Returns deactivated flag.
+ @param[out] LifetimeLock Returns physicalPresenceLifetimeLock permanent flag.
+ @param[out] CmdEnable Returns physicalPresenceCMDEnable permanent flag.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommGetCapability (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle,
+ OUT BOOLEAN *Deactivated, OPTIONAL
+ OUT BOOLEAN *LifetimeLock, OPTIONAL
+ OUT BOOLEAN *CmdEnable OPTIONAL
+ );
+
+/**
+ Extend a TPM PCR.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+ @param[in] DigestToExtend The 160 bit value representing the event to be recorded.
+ @param[in] PcrIndex The PCR to be updated.
+ @param[out] NewPcrValue New PCR value after extend.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommExtend (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle,
+ IN TPM_DIGEST *DigestToExtend,
+ IN TPM_PCRINDEX PcrIndex,
+ OUT TPM_DIGEST *NewPcrValue
+ );
+
+
+/**
+ Send TSC_PhysicalPresence command to TPM.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in] TpmHandle TPM handle.
+ @param[in] PhysicalPresence The state to set the TPMs Physical Presence flags.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+TpmCommPhysicalPresence (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TIS_TPM_HANDLE TpmHandle,
+ IN TPM_PHYSICAL_PRESENCE PhysicalPresence
+ );
+
+#endif // _TPM_COMM_H_