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; }