+++ /dev/null
-/** @file\r
- Initialize TPM2 device and measure FVs before handing off control to DXE.\r
-\r
-Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <PiPei.h>\r
-\r
-#include <IndustryStandard/UefiTcgPlatform.h>\r
-#include <Ppi/FirmwareVolumeInfo.h>\r
-#include <Ppi/FirmwareVolumeInfo2.h>\r
-#include <Ppi/LockPhysicalPresence.h>\r
-#include <Ppi/TpmInitialized.h>\r
-#include <Ppi/FirmwareVolume.h>\r
-#include <Ppi/EndOfPeiPhase.h>\r
-#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>\r
-\r
-#include <Guid/TcgEventHob.h>\r
-#include <Guid/MeasuredFvHob.h>\r
-#include <Guid/TpmInstance.h>\r
-\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/PeiServicesLib.h>\r
-#include <Library/PeimEntryPoint.h>\r
-#include <Library/Tpm2CommandLib.h>\r
-#include <Library/Tpm2DeviceLib.h>\r
-#include <Library/HashLib.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/PeiServicesTablePointerLib.h>\r
-#include <Protocol/TrEEProtocol.h>\r
-#include <Library/PerformanceLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/ReportStatusCodeLib.h>\r
-\r
-#define PERF_ID_TREE_PEI 0x3080\r
-\r
-typedef struct {\r
- EFI_GUID *EventGuid;\r
- TREE_EVENT_LOG_FORMAT LogFormat;\r
-} TREE_EVENT_INFO_STRUCT;\r
-\r
-TREE_EVENT_INFO_STRUCT mTreeEventInfo[] = {\r
- {&gTcgEventEntryHobGuid, TREE_EVENT_LOG_FORMAT_TCG_1_2},\r
-};\r
-\r
-BOOLEAN mImageInMemory = FALSE;\r
-EFI_PEI_FILE_HANDLE mFileHandle;\r
-\r
-EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
- &gPeiTpmInitializedPpiGuid,\r
- NULL\r
-};\r
-\r
-EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = {\r
- EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
- &gPeiTpmInitializationDonePpiGuid,\r
- NULL\r
-};\r
-\r
-EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredBaseFvInfo;\r
-UINT32 mMeasuredBaseFvIndex = 0;\r
-\r
-EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;\r
-UINT32 mMeasuredChildFvIndex = 0;\r
-\r
-/**\r
- Measure and record the Firmware Volum Information once FvInfoPPI install.\r
-\r
- @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
- @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
- @param[in] Ppi Address of the PPI that was installed.\r
-\r
- @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
- @return Others Fail to measure FV.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FirmwareVolmeInfoPpiNotifyCallback (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
- IN VOID *Ppi\r
- );\r
-\r
-/**\r
- Record all measured Firmware Volum Information into a Guid Hob\r
-\r
- @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
- @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
- @param[in] Ppi Address of the PPI that was installed.\r
-\r
- @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
- @return Others Fail to measure FV.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EndofPeiSignalNotifyCallBack (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
- IN VOID *Ppi\r
- );\r
-\r
-EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
- &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
- FirmwareVolmeInfoPpiNotifyCallback \r
- },\r
- {\r
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
- &gEfiPeiFirmwareVolumeInfo2PpiGuid,\r
- FirmwareVolmeInfoPpiNotifyCallback \r
- },\r
- {\r
- (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
- &gEfiEndOfPeiSignalPpiGuid,\r
- EndofPeiSignalNotifyCallBack\r
- }\r
-};\r
-\r
-EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;\r
-\r
-/**\r
- Record all measured Firmware Volum Information into a Guid Hob\r
- Guid Hob payload layout is \r
-\r
- UINT32 *************************** FIRMWARE_BLOB number\r
- EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array\r
-\r
- @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
- @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
- @param[in] Ppi Address of the PPI that was installed.\r
-\r
- @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
- @return Others Fail to measure FV.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EndofPeiSignalNotifyCallBack (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
- IN VOID *Ppi\r
- )\r
-{ \r
- MEASURED_HOB_DATA *MeasuredHobData;\r
-\r
- MeasuredHobData = NULL;\r
-\r
- //\r
- // Create a Guid hob to save all measured Fv \r
- //\r
- MeasuredHobData = BuildGuidHob(\r
- &gMeasuredFvHobGuid,\r
- sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)\r
- );\r
-\r
- if (MeasuredHobData != NULL){\r
- //\r
- // Save measured FV info enty number\r
- //\r
- MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;\r
-\r
- //\r
- // Save measured base Fv info\r
- //\r
- CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));\r
-\r
- //\r
- // Save measured child Fv info\r
- //\r
- CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Add a new entry to the Event Log.\r
-\r
- @param[in] DigestList A list of digest.\r
- @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
- @param[in] NewEventData Pointer to the new event data.\r
-\r
- @retval EFI_SUCCESS The new event log entry was added.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
-**/\r
-EFI_STATUS\r
-LogHashEvent (\r
- IN TPML_DIGEST_VALUES *DigestList,\r
- IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
- IN UINT8 *NewEventData\r
- )\r
-{\r
- VOID *HobData;\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- EFI_STATUS RetStatus;\r
-\r
- RetStatus = EFI_SUCCESS;\r
- for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {\r
- DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTreeEventInfo[Index].LogFormat));\r
- switch (mTreeEventInfo[Index].LogFormat) {\r
- case TREE_EVENT_LOG_FORMAT_TCG_1_2:\r
- Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
- if (!EFI_ERROR (Status)) {\r
- HobData = BuildGuidHob (\r
- &gTcgEventEntryHobGuid,\r
- sizeof (*NewEventHdr) + NewEventHdr->EventSize\r
- );\r
- if (HobData == NULL) {\r
- RetStatus = EFI_OUT_OF_RESOURCES;\r
- break;\r
- }\r
-\r
- CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));\r
- HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));\r
- CopyMem (HobData, NewEventData, NewEventHdr->EventSize);\r
- }\r
- break;\r
- }\r
- }\r
-\r
- return RetStatus;\r
-}\r
-\r
-/**\r
- Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
- and build a GUIDed HOB recording the event which will be passed to the DXE phase and\r
- added into the Event Log.\r
-\r
- @param[in] Flags Bitmap providing additional information.\r
- @param[in] HashData Physical address of the start of the data buffer \r
- to be hashed, extended, and logged.\r
- @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.\r
- @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
- @param[in] NewEventData Pointer to the new event data. \r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
- @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-HashLogExtendEvent (\r
- IN UINT64 Flags,\r
- IN UINT8 *HashData,\r
- IN UINTN HashDataLen,\r
- IN TCG_PCR_EVENT_HDR *NewEventHdr,\r
- IN UINT8 *NewEventData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- TPML_DIGEST_VALUES DigestList;\r
-\r
- if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Status = HashAndExtend (\r
- NewEventHdr->PCRIndex,\r
- HashData,\r
- HashDataLen,\r
- &DigestList\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- if ((Flags & TREE_EXTEND_ONLY) == 0) {\r
- Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
- }\r
- }\r
- \r
- if (Status == EFI_DEVICE_ERROR) {\r
- DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));\r
- BuildGuidHob (&gTpmErrorHobGuid,0);\r
- REPORT_STATUS_CODE (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Measure CRTM version.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
- @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureCRTMVersion (\r
- VOID\r
- )\r
-{\r
- TCG_PCR_EVENT_HDR TcgEventHdr;\r
-\r
- //\r
- // Use FirmwareVersion string to represent CRTM version.\r
- // OEMs should get real CRTM version string and measure it.\r
- //\r
-\r
- TcgEventHdr.PCRIndex = 0;\r
- TcgEventHdr.EventType = EV_S_CRTM_VERSION;\r
- TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));\r
-\r
- return HashLogExtendEvent (\r
- 0,\r
- (UINT8*)PcdGetPtr (PcdFirmwareVersionString),\r
- TcgEventHdr.EventSize,\r
- &TcgEventHdr,\r
- (UINT8*)PcdGetPtr (PcdFirmwareVersionString)\r
- );\r
-}\r
-\r
-/**\r
- Measure FV image. \r
- Add it into the measured FV list after the FV is measured successfully. \r
-\r
- @param[in] FvBase Base address of FV image.\r
- @param[in] FvLength Length of FV image.\r
-\r
- @retval EFI_SUCCESS Fv image is measured successfully \r
- or it has been already measured.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
- @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureFvImage (\r
- IN EFI_PHYSICAL_ADDRESS FvBase,\r
- IN UINT64 FvLength\r
- )\r
-{\r
- UINT32 Index;\r
- EFI_STATUS Status;\r
- EFI_PLATFORM_FIRMWARE_BLOB FvBlob;\r
- TCG_PCR_EVENT_HDR TcgEventHdr;\r
-\r
- //\r
- // Check if it is in Excluded FV list\r
- //\r
- if (mMeasurementExcludedFvPpi != NULL) {\r
- for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {\r
- if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {\r
- DEBUG ((DEBUG_INFO, "The FV which is excluded by TrEEPei starts at: 0x%x\n", FvBase));\r
- DEBUG ((DEBUG_INFO, "The FV which is excluded by TrEEPei has the size: 0x%x\n", FvLength));\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Check whether FV is in the measured FV list.\r
- //\r
- for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {\r
- if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- \r
- //\r
- // Measure and record the FV to the TPM\r
- //\r
- FvBlob.BlobBase = FvBase;\r
- FvBlob.BlobLength = FvLength;\r
-\r
- DEBUG ((DEBUG_INFO, "The FV which is measured by TrEEPei starts at: 0x%x\n", FvBlob.BlobBase));\r
- DEBUG ((DEBUG_INFO, "The FV which is measured by TrEEPei has the size: 0x%x\n", FvBlob.BlobLength));\r
-\r
- TcgEventHdr.PCRIndex = 0;\r
- TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
- TcgEventHdr.EventSize = sizeof (FvBlob);\r
-\r
- Status = HashLogExtendEvent (\r
- 0,\r
- (UINT8*) (UINTN) FvBlob.BlobBase,\r
- (UINTN) FvBlob.BlobLength,\r
- &TcgEventHdr,\r
- (UINT8*) &FvBlob\r
- );\r
-\r
- //\r
- // Add new FV into the measured FV list.\r
- //\r
- ASSERT (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));\r
- if (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
- mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;\r
- mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;\r
- mMeasuredBaseFvIndex++;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Measure main BIOS.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
- @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureMainBios (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 FvInstances;\r
- EFI_PEI_FV_HANDLE VolumeHandle;\r
- EFI_FV_INFO VolumeInfo;\r
- EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
-\r
- PERF_START_EX (mFileHandle, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI);\r
- FvInstances = 0;\r
- while (TRUE) {\r
- //\r
- // Traverse all firmware volume instances of Static Core Root of Trust for Measurement\r
- // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special\r
- // platform for special CRTM TPM measuring.\r
- //\r
- Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- \r
- //\r
- // Measure and record the firmware volume that is dispatched by PeiCore\r
- //\r
- Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);\r
- ASSERT_EFI_ERROR (Status);\r
- //\r
- // Locate the corresponding FV_PPI according to founded FV's format guid\r
- //\r
- Status = PeiServicesLocatePpi (\r
- &VolumeInfo.FvFormat, \r
- 0, \r
- NULL,\r
- (VOID**)&FvPpi\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);\r
- }\r
-\r
- FvInstances++;\r
- }\r
- PERF_END_EX (mFileHandle, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI + 1);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Measure and record the Firmware Volum Information once FvInfoPPI install.\r
-\r
- @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
- @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
- @param[in] Ppi Address of the PPI that was installed.\r
-\r
- @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
- @return Others Fail to measure FV.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FirmwareVolmeInfoPpiNotifyCallback (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
- IN VOID *Ppi\r
- )\r
-{\r
- EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;\r
- EFI_STATUS Status;\r
- EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
- UINTN Index;\r
-\r
- Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;\r
-\r
- //\r
- // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.\r
- //\r
- Status = PeiServicesLocatePpi (\r
- &Fv->FvFormat, \r
- 0, \r
- NULL,\r
- (VOID**)&FvPpi\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_SUCCESS;\r
- }\r
- \r
- //\r
- // This is an FV from an FFS file, and the parent FV must have already been measured,\r
- // No need to measure twice, so just record the FV and return\r
- //\r
- if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {\r
- \r
- ASSERT (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));\r
- if (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
- //\r
- // Check whether FV is in the measured child FV list.\r
- //\r
- for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {\r
- if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;\r
- mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;\r
- mMeasuredChildFvIndex++;\r
- }\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);\r
-}\r
-\r
-/**\r
- Do measurement after memory is ready.\r
-\r
- @param[in] PeiServices Describes the list of possible PEI Services.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
- @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-PeimEntryMP (\r
- IN EFI_PEI_SERVICES **PeiServices\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = PeiServicesLocatePpi (\r
- &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, \r
- 0, \r
- NULL,\r
- (VOID**)&mMeasurementExcludedFvPpi\r
- );\r
- // Do not check status, because it is optional\r
-\r
- mMeasuredBaseFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
- ASSERT (mMeasuredBaseFvInfo != NULL);\r
- mMeasuredChildFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
- ASSERT (mMeasuredChildFvInfo != NULL);\r
- \r
- if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) {\r
- Status = MeasureCRTMVersion ();\r
- }\r
-\r
- Status = MeasureMainBios ();\r
-\r
- //\r
- // Post callbacks:\r
- // for the FvInfoPpi services to measure and record\r
- // the additional Fvs to TPM\r
- //\r
- Status = PeiServicesNotifyPpi (&mNotifyList[0]);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Entry point of this module.\r
-\r
- @param[in] FileHandle Handle of the file being invoked.\r
- @param[in] PeiServices Describes the list of possible PEI Services.\r
-\r
- @return Status.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PeimEntryMA (\r
- IN EFI_PEI_FILE_HANDLE FileHandle,\r
- IN CONST EFI_PEI_SERVICES **PeiServices\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS Status2;\r
- EFI_BOOT_MODE BootMode;\r
-\r
- if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
- CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
- DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
- DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Status = PeiServicesGetBootMode (&BootMode);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // In S3 path, skip shadow logic. no measurement is required\r
- //\r
- if (BootMode != BOOT_ON_S3_RESUME) {\r
- Status = (**PeiServices).RegisterForShadow(FileHandle);\r
- if (Status == EFI_ALREADY_STARTED) {\r
- mImageInMemory = TRUE;\r
- mFileHandle = FileHandle;\r
- } else if (Status == EFI_NOT_FOUND) {\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
- }\r
-\r
- if (!mImageInMemory) {\r
- //\r
- // Initialize TPM device\r
- //\r
- Status = Tpm2RequestUseTpm ();\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "TPM2 not detected!\n"));\r
- goto Done;\r
- }\r
-\r
- if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {\r
- if (BootMode == BOOT_ON_S3_RESUME) {\r
- Status = Tpm2Startup (TPM_SU_STATE);\r
- if (EFI_ERROR (Status) ) {\r
- Status = Tpm2Startup (TPM_SU_CLEAR);\r
- }\r
- } else {\r
- Status = Tpm2Startup (TPM_SU_CLEAR);\r
- }\r
- if (EFI_ERROR (Status) ) {\r
- goto Done;\r
- }\r
- }\r
-\r
- //\r
- // TpmSelfTest is optional on S3 path, skip it to save S3 time\r
- //\r
- if (BootMode != BOOT_ON_S3_RESUME) {\r
- if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) {\r
- Status = Tpm2SelfTest (NO);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Only intall TpmInitializedPpi on success\r
- //\r
- Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
- if (mImageInMemory) {\r
- Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);\r
- return Status;\r
- }\r
-\r
-Done:\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));\r
- BuildGuidHob (&gTpmErrorHobGuid,0);\r
- REPORT_STATUS_CODE (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
- );\r
- }\r
- //\r
- // Always intall TpmInitializationDonePpi no matter success or fail.\r
- // Other driver can know TPM initialization state by TpmInitializedPpi.\r
- //\r
- Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);\r
- ASSERT_EFI_ERROR (Status2);\r
-\r
- return Status;\r
-}\r