X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=SecurityPkg%2FTcg%2FTcgPei%2FTcgPei.c;h=0adfcc50c5098f783415556c2c39cd92a6332eb3;hp=419eacf37d2ab29aefc7b8f8176a74f82579f9f4;hb=289b714b77008aa4200c0be25c4b4e25df04955a;hpb=3dd05ac3e6a047cd0e85f590a9886a8cd4fd7a16 diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.c b/SecurityPkg/Tcg/TcgPei/TcgPei.c index 419eacf37d..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 - 2015, 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 **/ @@ -32,15 +26,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include -#include #include #include #include #include #include #include - -#include "TpmComm.h" +#include +#include +#include +#include BOOLEAN mImageInMemory = FALSE; @@ -56,10 +51,17 @@ EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = { 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; @@ -129,12 +131,12 @@ EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = { { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, &gEfiPeiFirmwareVolumeInfoPpiGuid, - FirmwareVolmeInfoPpiNotifyCallback + FirmwareVolmeInfoPpiNotifyCallback }, { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, &gEfiPeiFirmwareVolumeInfo2PpiGuid, - FirmwareVolmeInfoPpiNotifyCallback + FirmwareVolmeInfoPpiNotifyCallback }, { (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), @@ -145,7 +147,7 @@ EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = { /** Record all measured Firmware Volum Information into a Guid Hob - Guid Hob payload layout is + Guid Hob payload layout is UINT32 *************************** FIRMWARE_BLOB number EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array @@ -165,13 +167,15 @@ EndofPeiSignalNotifyCallBack ( 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 + // Create a Guid hob to save all measured Fv // MeasuredHobData = BuildGuidHob( &gMeasuredFvHobGuid, @@ -195,6 +199,42 @@ EndofPeiSignalNotifyCallBack ( 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; } @@ -204,12 +244,11 @@ EndofPeiSignalNotifyCallBack ( 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. @@ -221,14 +260,13 @@ 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; - + if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { return EFI_DEVICE_ERROR; } @@ -245,9 +283,7 @@ HashLogExtendEvent ( } } - Status = TpmCommExtend ( - PeiServices, - TpmHandle, + Status = Tpm12Extend ( &NewEventHdr->Digest, NewEventHdr->PCRIndex, NULL @@ -286,7 +322,6 @@ Done: 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. @@ -296,8 +331,7 @@ Done: EFI_STATUS EFIAPI MeasureCRTMVersion ( - IN EFI_PEI_SERVICES **PeiServices, - IN TIS_TPM_HANDLE TpmHandle + IN EFI_PEI_SERVICES **PeiServices ) { TCG_PCR_EVENT_HDR TcgEventHdr; @@ -315,20 +349,19 @@ MeasureCRTMVersion ( 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. @@ -345,9 +378,6 @@ 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 @@ -370,7 +400,7 @@ MeasureFvImage ( return EFI_SUCCESS; } } - + // // Measure and record the FV to the TPM // @@ -388,7 +418,6 @@ MeasureFvImage ( (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(), (UINT8*) (UINTN) FvBlob.BlobBase, (UINTN) FvBlob.BlobLength, - TpmHandle, &TcgEventHdr, (UINT8*) &FvBlob ); @@ -396,13 +425,20 @@ MeasureFvImage ( // // Add new FV into the measured FV list. // - ASSERT (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)); - if (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) { - mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase; - mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength; - mMeasuredBaseFvIndex++; + 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; } @@ -410,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. @@ -420,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; @@ -429,7 +463,7 @@ MeasureMainBios ( EFI_PEI_FV_HANDLE VolumeHandle; EFI_FV_INFO VolumeInfo; EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; - + FvInstances = 0; while (TRUE) { // @@ -441,7 +475,7 @@ MeasureMainBios ( if (EFI_ERROR (Status)) { break; } - + // // Measure and record the firmware volume that is dispatched by PeiCore // @@ -451,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 ); @@ -496,35 +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 record the FV and return // if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) { - - ASSERT (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)); - if (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) { - // - // 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; - } + + 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++; } + mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo; + mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize; + mMeasuredChildFvIndex++; return EFI_SUCCESS; } @@ -553,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; } @@ -569,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. // @@ -607,8 +642,8 @@ PhysicalPresencePpiNotifyCallback ( return EFI_SUCCESS; } - if (!CmdEnable) { - if (LifetimeLock) { + if (!TpmPermanentFlags.physicalPresenceCMDEnable) { + if (TpmPermanentFlags.physicalPresenceLifetimeLock) { // // physicalPresenceCMDEnable is locked, can't change. // @@ -619,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)) { @@ -631,10 +664,8 @@ PhysicalPresencePpiNotifyCallback ( // // Lock physical presence - // - Status = TpmCommPhysicalPresence ( - PeiServices, - TpmHandle, + // + Status = Tpm12PhysicalPresence ( TPM_PHYSICAL_PRESENCE_LOCK ); return Status; @@ -644,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); } /** @@ -684,40 +712,33 @@ PeimEntryMP ( ) { EFI_STATUS Status; - TIS_TPM_HANDLE TpmHandle; Status = PeiServicesLocatePpi ( - &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, - 0, + &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, + 0, NULL, (VOID**)&mMeasurementExcludedFvPpi ); // Do not check status, because it is optional - mMeasuredBaseFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported)); - ASSERT (mMeasuredBaseFvInfo != NULL); - mMeasuredChildFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported)); - ASSERT (mMeasuredChildFvInfo != NULL); - - TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS; - Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle); + Status = Tpm12RequestUseTpm (); if (EFI_ERROR (Status)) { return Status; } - if (IsTpmUsable (PeiServices, TpmHandle)) { + if (IsTpmUsable ()) { if (PcdGet8 (PcdTpmScrtmPolicy) == 1) { - Status = MeasureCRTMVersion (PeiServices, TpmHandle); + 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]); @@ -745,7 +766,6 @@ PeimEntryMA ( EFI_STATUS Status; EFI_STATUS Status2; EFI_BOOT_MODE BootMode; - TIS_TPM_HANDLE TpmHandle; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n")); @@ -776,15 +796,18 @@ 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")); goto Done; } if (PcdGet8 (PcdTpmInitializationPolicy) == 1) { - Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode); + if (BootMode == BOOT_ON_S3_RESUME) { + Status = Tpm12Startup (TPM_ST_STATE); + } else { + Status = Tpm12Startup (TPM_ST_CLEAR); + } if (EFI_ERROR (Status) ) { goto Done; } @@ -794,7 +817,7 @@ PeimEntryMA ( // TpmSelfTest is optional on S3 path, skip it to save S3 time // if (BootMode != BOOT_ON_S3_RESUME) { - Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle); + Status = Tpm12ContinueSelfTest (); if (EFI_ERROR (Status)) { goto Done; }