X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=SecurityPkg%2FTcg%2FTcgPei%2FTcgPei.c;h=0adfcc50c5098f783415556c2c39cd92a6332eb3;hp=37302fd0ecf5ba382929389d30497930350e45ed;hb=289b714b77008aa4200c0be25c4b4e25df04955a;hpb=055c829c4212f12614ad80dcd161a2b4f5cf6713
diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.c b/SecurityPkg/Tcg/TcgPei/TcgPei.c
index 37302fd0ec..0adfcc50c5 100644
--- a/SecurityPkg/Tcg/TcgPei/TcgPei.c
+++ b/SecurityPkg/Tcg/TcgPei/TcgPei.c
@@ -1,14 +1,8 @@
/** @file
Initialize TPM device and measure FVs before handing off control to DXE.
-Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
-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.
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -17,21 +11,31 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include
#include
#include
+#include
#include
#include
#include
+#include
+#include
+
#include
+#include
+#include
+
#include
#include
#include
#include
-#include
#include
#include
#include
#include
-
-#include "TpmComm.h"
+#include
+#include
+#include
+#include
+#include
+#include
BOOLEAN mImageInMemory = FALSE;
@@ -41,6 +45,27 @@ EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {
NULL
};
+EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTpmInitializationDonePpiGuid,
+ NULL
+};
+
+//
+// Number of firmware blobs to grow by each time we run out of room
+//
+#define FIRMWARE_BLOB_GROWTH_STEP 4
+
+EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredBaseFvInfo;
+UINT32 mMeasuredMaxBaseFvIndex = 0;
+UINT32 mMeasuredBaseFvIndex = 0;
+
+EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;
+UINT32 mMeasuredMaxChildFvIndex = 0;
+UINT32 mMeasuredChildFvIndex = 0;
+
+EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;
+
/**
Lock physical presence if needed.
@@ -78,6 +103,25 @@ FirmwareVolmeInfoPpiNotifyCallback (
IN VOID *Ppi
);
+/**
+ Record all measured Firmware Volum Information into a Guid Hob
+
+ @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
+EndofPeiSignalNotifyCallBack (
+ 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,
@@ -85,14 +129,114 @@ EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
PhysicalPresencePpiNotifyCallback
},
{
- (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
&gEfiPeiFirmwareVolumeInfoPpiGuid,
- FirmwareVolmeInfoPpiNotifyCallback
+ FirmwareVolmeInfoPpiNotifyCallback
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ &gEfiPeiFirmwareVolumeInfo2PpiGuid,
+ FirmwareVolmeInfoPpiNotifyCallback
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ EndofPeiSignalNotifyCallBack
}
};
-EFI_PLATFORM_FIRMWARE_BLOB mMeasuredFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
-UINT32 mMeasuredFvIndex = 0;
+/**
+ Record all measured Firmware Volum Information into a Guid Hob
+ Guid Hob payload layout is
+
+ UINT32 *************************** FIRMWARE_BLOB number
+ EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
+
+ @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
+EndofPeiSignalNotifyCallBack (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ MEASURED_HOB_DATA *MeasuredHobData;
+
+ MeasuredHobData = NULL;
+
+ PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid);
+
+ //
+ // Create a Guid hob to save all measured Fv
+ //
+ MeasuredHobData = BuildGuidHob(
+ &gMeasuredFvHobGuid,
+ sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)
+ );
+
+ if (MeasuredHobData != NULL){
+ //
+ // Save measured FV info enty number
+ //
+ MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;
+
+ //
+ // Save measured base Fv info
+ //
+ CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));
+
+ //
+ // Save measured child Fv info
+ //
+ CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));
+ }
+
+ PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid);
+
+ return EFI_SUCCESS;
+}
+
+/**
+Single function calculates SHA1 digest value for all raw data. It
+combines Sha1Init(), Sha1Update() and Sha1Final().
+
+@param[in] Data Raw data to be digested.
+@param[in] DataLen Size of the raw data.
+@param[out] Digest Pointer to a buffer that stores the final digest.
+
+@retval EFI_SUCCESS Always successfully calculate the final digest.
+**/
+EFI_STATUS
+EFIAPI
+TpmCommHashAll (
+ IN CONST UINT8 *Data,
+ IN UINTN DataLen,
+ OUT TPM_DIGEST *Digest
+ )
+{
+ VOID *Sha1Ctx;
+ UINTN CtxSize;
+
+ CtxSize = Sha1GetContextSize ();
+ Sha1Ctx = AllocatePool (CtxSize);
+ ASSERT (Sha1Ctx != NULL);
+
+ Sha1Init (Sha1Ctx);
+ Sha1Update (Sha1Ctx, Data, DataLen);
+ Sha1Final (Sha1Ctx, (UINT8 *)Digest);
+
+ FreePool (Sha1Ctx);
+
+ return EFI_SUCCESS;
+}
/**
Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
@@ -100,12 +244,11 @@ UINT32 mMeasuredFvIndex = 0;
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
+ @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.
+ @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.
@@ -117,7 +260,6 @@ 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
)
@@ -125,6 +267,10 @@ HashLogExtendEvent (
EFI_STATUS Status;
VOID *HobData;
+ if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
HobData = NULL;
if (HashDataLen != 0) {
Status = TpmCommHashAll (
@@ -132,37 +278,50 @@ HashLogExtendEvent (
HashDataLen,
&NewEventHdr->Digest
);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
}
- Status = TpmCommExtend (
- PeiServices,
- TpmHandle,
+ Status = Tpm12Extend (
&NewEventHdr->Digest,
NewEventHdr->PCRIndex,
NULL
);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
HobData = BuildGuidHob (
&gTcgEventEntryHobGuid,
sizeof (*NewEventHdr) + NewEventHdr->EventSize
);
if (HobData == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
}
CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));
HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));
CopyMem (HobData, NewEventData, NewEventHdr->EventSize);
- return EFI_SUCCESS;
+
+Done:
+ if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) {
+ DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
+ BuildGuidHob (&gTpmErrorHobGuid,0);
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
+ );
+ Status = EFI_DEVICE_ERROR;
+ }
+ return Status;
}
/**
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.
@@ -172,8 +331,7 @@ HashLogExtendEvent (
EFI_STATUS
EFIAPI
MeasureCRTMVersion (
- IN EFI_PEI_SERVICES **PeiServices,
- IN TIS_TPM_HANDLE TpmHandle
+ IN EFI_PEI_SERVICES **PeiServices
)
{
TCG_PCR_EVENT_HDR TcgEventHdr;
@@ -185,26 +343,25 @@ MeasureCRTMVersion (
TcgEventHdr.PCRIndex = 0;
TcgEventHdr.EventType = EV_S_CRTM_VERSION;
- TcgEventHdr.EventSize = StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));
+ TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));
return HashLogExtendEvent (
PeiServices,
(UINT8*)PcdGetPtr (PcdFirmwareVersionString),
TcgEventHdr.EventSize,
- TpmHandle,
&TcgEventHdr,
(UINT8*)PcdGetPtr (PcdFirmwareVersionString)
);
}
/**
- Measure FV image.
- Add it into the measured FV list after the FV is measured successfully.
+ 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
+ @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.
@@ -221,19 +378,29 @@ MeasureFvImage (
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 if it is in Excluded FV list
+ //
+ if (mMeasurementExcludedFvPpi != NULL) {
+ for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {
+ if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {
+ DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase));
+ DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength));
+ return EFI_SUCCESS;
+ }
+ }
+ }
//
// Check whether FV is in the measured FV list.
//
- for (Index = 0; Index < mMeasuredFvIndex; Index ++) {
- if (mMeasuredFvInfo[Index].BlobBase == FvBase) {
+ for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {
+ if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {
return EFI_SUCCESS;
}
}
-
+
//
// Measure and record the FV to the TPM
//
@@ -251,21 +418,27 @@ MeasureFvImage (
(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;
+ if (mMeasuredBaseFvIndex >= mMeasuredMaxBaseFvIndex) {
+ mMeasuredBaseFvInfo = ReallocatePool (
+ sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * mMeasuredMaxBaseFvIndex,
+ sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredMaxBaseFvIndex + FIRMWARE_BLOB_GROWTH_STEP),
+ mMeasuredBaseFvInfo
+ );
+ ASSERT (mMeasuredBaseFvInfo != NULL);
+ mMeasuredMaxBaseFvIndex = mMeasuredMaxBaseFvIndex + FIRMWARE_BLOB_GROWTH_STEP;
}
+ mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;
+ mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;
+ mMeasuredBaseFvIndex++;
+
return Status;
}
@@ -273,7 +446,6 @@ MeasureFvImage (
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.
@@ -283,8 +455,7 @@ MeasureFvImage (
EFI_STATUS
EFIAPI
MeasureMainBios (
- IN EFI_PEI_SERVICES **PeiServices,
- IN TIS_TPM_HANDLE TpmHandle
+ IN EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
@@ -292,7 +463,7 @@ MeasureMainBios (
EFI_PEI_FV_HANDLE VolumeHandle;
EFI_FV_INFO VolumeInfo;
EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
-
+
FvInstances = 0;
while (TRUE) {
//
@@ -304,7 +475,7 @@ MeasureMainBios (
if (EFI_ERROR (Status)) {
break;
}
-
+
//
// Measure and record the firmware volume that is dispatched by PeiCore
//
@@ -314,8 +485,8 @@ MeasureMainBios (
// Locate the corresponding FV_PPI according to founded FV's format guid
//
Status = PeiServicesLocatePpi (
- &VolumeInfo.FvFormat,
- 0,
+ &VolumeInfo.FvFormat,
+ 0,
NULL,
(VOID**)&FvPpi
);
@@ -351,6 +522,7 @@ FirmwareVolmeInfoPpiNotifyCallback (
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
EFI_STATUS Status;
EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
+ UINTN Index;
Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;
@@ -358,20 +530,41 @@ FirmwareVolmeInfoPpiNotifyCallback (
// The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
//
Status = PeiServicesLocatePpi (
- &Fv->FvFormat,
- 0,
+ &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
+ // No need to measure twice, so just record the FV and return
//
if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {
+
+ if (mMeasuredChildFvIndex >= mMeasuredMaxChildFvIndex) {
+ mMeasuredChildFvInfo = ReallocatePool (
+ sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * mMeasuredMaxChildFvIndex,
+ sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredMaxChildFvIndex + FIRMWARE_BLOB_GROWTH_STEP),
+ mMeasuredChildFvInfo
+ );
+ ASSERT (mMeasuredChildFvInfo != NULL);
+ mMeasuredMaxChildFvIndex = mMeasuredMaxChildFvIndex + FIRMWARE_BLOB_GROWTH_STEP;
+ }
+ //
+ // Check whether FV is in the measured child FV list.
+ //
+ for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {
+ if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) {
+ return EFI_SUCCESS;
+ }
+ }
+ mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;
+ mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;
+ mMeasuredChildFvIndex++;
return EFI_SUCCESS;
}
@@ -400,15 +593,11 @@ PhysicalPresencePpiNotifyCallback (
)
{
EFI_STATUS Status;
+ TPM_PERMANENT_FLAGS TpmPermanentFlags;
PEI_LOCK_PHYSICAL_PRESENCE_PPI *LockPhysicalPresencePpi;
- BOOLEAN LifetimeLock;
- BOOLEAN CmdEnable;
- TIS_TPM_HANDLE TpmHandle;
TPM_PHYSICAL_PRESENCE PhysicalPresenceValue;
- TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;
-
- Status = TpmCommGetCapability (PeiServices, TpmHandle, NULL, &LifetimeLock, &CmdEnable);
+ Status = Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -416,36 +605,35 @@ PhysicalPresencePpiNotifyCallback (
//
// 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
//
- if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !LifetimeLock) {
+ if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !TpmPermanentFlags.physicalPresenceLifetimeLock) {
//
- // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
+ // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
//
PhysicalPresenceValue = TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK;
+ TpmPermanentFlags.physicalPresenceLifetimeLock = TRUE;
if (PcdGetBool (PcdPhysicalPresenceCmdEnable)) {
PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_ENABLE;
- CmdEnable = TRUE;
+ TpmPermanentFlags.physicalPresenceCMDEnable = TRUE;
} else {
PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_DISABLE;
- CmdEnable = FALSE;
+ TpmPermanentFlags.physicalPresenceCMDEnable = FALSE;
}
if (PcdGetBool (PcdPhysicalPresenceHwEnable)) {
PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_ENABLE;
} else {
PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_DISABLE;
- }
-
- Status = TpmCommPhysicalPresence (
- PeiServices,
- TpmHandle,
+ }
+
+ Status = Tpm12PhysicalPresence (
PhysicalPresenceValue
);
if (EFI_ERROR (Status)) {
return Status;
}
}
-
+
//
// 2. Lock physical presence if it is required.
//
@@ -454,8 +642,8 @@ PhysicalPresencePpiNotifyCallback (
return EFI_SUCCESS;
}
- if (!CmdEnable) {
- if (LifetimeLock) {
+ if (!TpmPermanentFlags.physicalPresenceCMDEnable) {
+ if (TpmPermanentFlags.physicalPresenceLifetimeLock) {
//
// physicalPresenceCMDEnable is locked, can't change.
//
@@ -466,9 +654,7 @@ PhysicalPresencePpiNotifyCallback (
// Enable physical presence command
// It is necessary in order to lock physical presence
//
- Status = TpmCommPhysicalPresence (
- PeiServices,
- TpmHandle,
+ Status = Tpm12PhysicalPresence (
TPM_PHYSICAL_PRESENCE_CMD_ENABLE
);
if (EFI_ERROR (Status)) {
@@ -478,10 +664,8 @@ PhysicalPresencePpiNotifyCallback (
//
// Lock physical presence
- //
- Status = TpmCommPhysicalPresence (
- PeiServices,
- TpmHandle,
+ //
+ Status = Tpm12PhysicalPresence (
TPM_PHYSICAL_PRESENCE_LOCK
);
return Status;
@@ -491,27 +675,24 @@ PhysicalPresencePpiNotifyCallback (
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
+ VOID
)
{
- EFI_STATUS Status;
- BOOLEAN Deactivated;
+ EFI_STATUS Status;
+ TPM_PERMANENT_FLAGS TpmPermanentFlags;
- Status = TpmCommGetCapability (PeiServices, TpmHandle, &Deactivated, NULL, NULL);
+ Status = Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags);
if (EFI_ERROR (Status)) {
return FALSE;
}
- return (BOOLEAN)(!Deactivated);
+ return (BOOLEAN)(!TpmPermanentFlags.deactivated);
}
/**
@@ -531,26 +712,33 @@ PeimEntryMP (
)
{
EFI_STATUS Status;
- TIS_TPM_HANDLE TpmHandle;
- TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
- Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid,
+ 0,
+ NULL,
+ (VOID**)&mMeasurementExcludedFvPpi
+ );
+ // Do not check status, because it is optional
+
+ Status = Tpm12RequestUseTpm ();
if (EFI_ERROR (Status)) {
return Status;
}
- if (IsTpmUsable (PeiServices, TpmHandle)) {
- Status = MeasureCRTMVersion (PeiServices, TpmHandle);
- ASSERT_EFI_ERROR (Status);
+ if (IsTpmUsable ()) {
+ if (PcdGet8 (PcdTpmScrtmPolicy) == 1) {
+ Status = MeasureCRTMVersion (PeiServices);
+ }
- Status = MeasureMainBios (PeiServices, TpmHandle);
- }
+ Status = MeasureMainBios (PeiServices);
+ }
//
// 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
+ // 2). for the OperatorPresencePpi service to determine whether to
// lock the TPM
//
Status = PeiServicesNotifyPpi (&mNotifyList[0]);
@@ -576,13 +764,19 @@ PeimEntryMA (
)
{
EFI_STATUS Status;
+ EFI_STATUS Status2;
EFI_BOOT_MODE BootMode;
- TIS_TPM_HANDLE TpmHandle;
- if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
+ if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
+ DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
return EFI_UNSUPPORTED;
}
+ if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
+ DEBUG ((EFI_D_ERROR, "TPM error!\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
//
// Initialize TPM device
//
@@ -602,31 +796,60 @@ PeimEntryMA (
}
if (!mImageInMemory) {
- TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
- Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
+ Status = Tpm12RequestUseTpm ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
- return Status;
+ goto Done;
}
- Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
- if (EFI_ERROR (Status) ) {
- return Status;
+ if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ Status = Tpm12Startup (TPM_ST_STATE);
+ } else {
+ Status = Tpm12Startup (TPM_ST_CLEAR);
+ }
+ if (EFI_ERROR (Status) ) {
+ goto Done;
+ }
}
- Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);
- if (EFI_ERROR (Status)) {
- return Status;
+
+ //
+ // TpmSelfTest is optional on S3 path, skip it to save S3 time
+ //
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ Status = Tpm12ContinueSelfTest ();
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
}
+
+ //
+ // Only intall TpmInitializedPpi on success
+ //
Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
ASSERT_EFI_ERROR (Status);
}
if (mImageInMemory) {
Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ return Status;
}
+Done:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TPM error! Build Hob\n"));
+ BuildGuidHob (&gTpmErrorHobGuid,0);
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
+ );
+ }
+ //
+ // Always intall TpmInitializationDonePpi no matter success or fail.
+ // Other driver can know TPM initialization state by TpmInitializedPpi.
+ //
+ Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
+ ASSERT_EFI_ERROR (Status2);
+
return Status;
}