2 Initialize TPM device and measure FVs before handing off control to DXE.
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <IndustryStandard/Tpm12.h>
18 #include <IndustryStandard/UefiTcgPlatform.h>
19 #include <Ppi/FirmwareVolumeInfo.h>
20 #include <Ppi/FirmwareVolumeInfo2.h>
21 #include <Ppi/LockPhysicalPresence.h>
22 #include <Ppi/TpmInitialized.h>
23 #include <Ppi/FirmwareVolume.h>
24 #include <Ppi/EndOfPeiPhase.h>
25 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
27 #include <Guid/TcgEventHob.h>
28 #include <Guid/MeasuredFvHob.h>
29 #include <Guid/TpmInstance.h>
31 #include <Library/DebugLib.h>
32 #include <Library/BaseMemoryLib.h>
33 #include <Library/PeiServicesLib.h>
34 #include <Library/PeimEntryPoint.h>
35 #include <Library/HobLib.h>
36 #include <Library/PcdLib.h>
37 #include <Library/PeiServicesTablePointerLib.h>
38 #include <Library/BaseLib.h>
39 #include <Library/MemoryAllocationLib.h>
40 #include <Library/ReportStatusCodeLib.h>
41 #include <Library/Tpm12DeviceLib.h>
42 #include <Library/Tpm12CommandLib.h>
43 #include <Library/BaseCryptLib.h>
44 #include <Library/PerformanceLib.h>
46 BOOLEAN mImageInMemory
= FALSE
;
48 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList
= {
49 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
50 &gPeiTpmInitializedPpiGuid
,
54 EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList
= {
55 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
56 &gPeiTpmInitializationDonePpiGuid
,
61 // Number of firmware blobs to grow by each time we run out of room
63 #define FIRMWARE_BLOB_GROWTH_STEP 4
65 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredBaseFvInfo
;
66 UINT32 mMeasuredMaxBaseFvIndex
= 0;
67 UINT32 mMeasuredBaseFvIndex
= 0;
69 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredChildFvInfo
;
70 UINT32 mMeasuredMaxChildFvIndex
= 0;
71 UINT32 mMeasuredChildFvIndex
= 0;
73 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI
*mMeasurementExcludedFvPpi
;
76 Lock physical presence if needed.
78 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
79 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
80 @param[in] Ppi Address of the PPI that was installed.
82 @retval EFI_SUCCESS Operation completed successfully.
87 PhysicalPresencePpiNotifyCallback (
88 IN EFI_PEI_SERVICES
**PeiServices
,
89 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
94 Measure and record the Firmware Volum Information once FvInfoPPI install.
96 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
97 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
98 @param[in] Ppi Address of the PPI that was installed.
100 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
101 @return Others Fail to measure FV.
106 FirmwareVolmeInfoPpiNotifyCallback (
107 IN EFI_PEI_SERVICES
**PeiServices
,
108 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
113 Record all measured Firmware Volum Information into a Guid Hob
115 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
116 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
117 @param[in] Ppi Address of the PPI that was installed.
119 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
120 @return Others Fail to measure FV.
125 EndofPeiSignalNotifyCallBack (
126 IN EFI_PEI_SERVICES
**PeiServices
,
127 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
131 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
133 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
134 &gPeiLockPhysicalPresencePpiGuid
,
135 PhysicalPresencePpiNotifyCallback
138 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
139 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
140 FirmwareVolmeInfoPpiNotifyCallback
143 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
144 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
145 FirmwareVolmeInfoPpiNotifyCallback
148 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
149 &gEfiEndOfPeiSignalPpiGuid
,
150 EndofPeiSignalNotifyCallBack
155 Record all measured Firmware Volum Information into a Guid Hob
156 Guid Hob payload layout is
158 UINT32 *************************** FIRMWARE_BLOB number
159 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
161 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
162 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
163 @param[in] Ppi Address of the PPI that was installed.
165 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
166 @return Others Fail to measure FV.
171 EndofPeiSignalNotifyCallBack (
172 IN EFI_PEI_SERVICES
**PeiServices
,
173 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
177 MEASURED_HOB_DATA
*MeasuredHobData
;
179 MeasuredHobData
= NULL
;
181 PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid
);
184 // Create a Guid hob to save all measured Fv
186 MeasuredHobData
= BuildGuidHob(
188 sizeof(UINTN
) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
)
191 if (MeasuredHobData
!= NULL
){
193 // Save measured FV info enty number
195 MeasuredHobData
->Num
= mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
;
198 // Save measured base Fv info
200 CopyMem (MeasuredHobData
->MeasuredFvBuf
, mMeasuredBaseFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
));
203 // Save measured child Fv info
205 CopyMem (&MeasuredHobData
->MeasuredFvBuf
[mMeasuredBaseFvIndex
] , mMeasuredChildFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredChildFvIndex
));
208 PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid
);
214 Single function calculates SHA1 digest value for all raw data. It
215 combines Sha1Init(), Sha1Update() and Sha1Final().
217 @param[in] Data Raw data to be digested.
218 @param[in] DataLen Size of the raw data.
219 @param[out] Digest Pointer to a buffer that stores the final digest.
221 @retval EFI_SUCCESS Always successfully calculate the final digest.
226 IN CONST UINT8
*Data
,
228 OUT TPM_DIGEST
*Digest
234 CtxSize
= Sha1GetContextSize ();
235 Sha1Ctx
= AllocatePool (CtxSize
);
236 ASSERT (Sha1Ctx
!= NULL
);
239 Sha1Update (Sha1Ctx
, Data
, DataLen
);
240 Sha1Final (Sha1Ctx
, (UINT8
*)Digest
);
248 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
249 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
250 added into the Event Log.
252 @param[in] PeiServices Describes the list of possible PEI Services.
253 @param[in] HashData Physical address of the start of the data buffer
254 to be hashed, extended, and logged.
255 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
256 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
257 @param[in] NewEventData Pointer to the new event data.
259 @retval EFI_SUCCESS Operation completed successfully.
260 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
261 @retval EFI_DEVICE_ERROR The command was unsuccessful.
266 IN EFI_PEI_SERVICES
**PeiServices
,
268 IN UINTN HashDataLen
,
269 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
270 IN UINT8
*NewEventData
276 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
277 return EFI_DEVICE_ERROR
;
281 if (HashDataLen
!= 0) {
282 Status
= TpmCommHashAll (
287 if (EFI_ERROR (Status
)) {
292 Status
= Tpm12Extend (
293 &NewEventHdr
->Digest
,
294 NewEventHdr
->PCRIndex
,
297 if (EFI_ERROR (Status
)) {
301 HobData
= BuildGuidHob (
302 &gTcgEventEntryHobGuid
,
303 sizeof (*NewEventHdr
) + NewEventHdr
->EventSize
305 if (HobData
== NULL
) {
306 Status
= EFI_OUT_OF_RESOURCES
;
310 CopyMem (HobData
, NewEventHdr
, sizeof (*NewEventHdr
));
311 HobData
= (VOID
*) ((UINT8
*)HobData
+ sizeof (*NewEventHdr
));
312 CopyMem (HobData
, NewEventData
, NewEventHdr
->EventSize
);
315 if ((Status
== EFI_DEVICE_ERROR
) || (Status
== EFI_TIMEOUT
)) {
316 DEBUG ((EFI_D_ERROR
, "HashLogExtendEvent - %r. Disable TPM.\n", Status
));
317 BuildGuidHob (&gTpmErrorHobGuid
,0);
319 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
320 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
322 Status
= EFI_DEVICE_ERROR
;
328 Measure CRTM version.
330 @param[in] PeiServices Describes the list of possible PEI Services.
332 @retval EFI_SUCCESS Operation completed successfully.
333 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
334 @retval EFI_DEVICE_ERROR The command was unsuccessful.
340 IN EFI_PEI_SERVICES
**PeiServices
343 TCG_PCR_EVENT_HDR TcgEventHdr
;
346 // Use FirmwareVersion string to represent CRTM version.
347 // OEMs should get real CRTM version string and measure it.
350 TcgEventHdr
.PCRIndex
= 0;
351 TcgEventHdr
.EventType
= EV_S_CRTM_VERSION
;
352 TcgEventHdr
.EventSize
= (UINT32
) StrSize((CHAR16
*)PcdGetPtr (PcdFirmwareVersionString
));
354 return HashLogExtendEvent (
356 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
),
357 TcgEventHdr
.EventSize
,
359 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
)
365 Add it into the measured FV list after the FV is measured successfully.
367 @param[in] FvBase Base address of FV image.
368 @param[in] FvLength Length of FV image.
370 @retval EFI_SUCCESS Fv image is measured successfully
371 or it has been already measured.
372 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
373 @retval EFI_DEVICE_ERROR The command was unsuccessful.
379 IN EFI_PHYSICAL_ADDRESS FvBase
,
385 EFI_PLATFORM_FIRMWARE_BLOB FvBlob
;
386 TCG_PCR_EVENT_HDR TcgEventHdr
;
389 // Check if it is in Excluded FV list
391 if (mMeasurementExcludedFvPpi
!= NULL
) {
392 for (Index
= 0; Index
< mMeasurementExcludedFvPpi
->Count
; Index
++) {
393 if (mMeasurementExcludedFvPpi
->Fv
[Index
].FvBase
== FvBase
) {
394 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase
));
395 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength
));
402 // Check whether FV is in the measured FV list.
404 for (Index
= 0; Index
< mMeasuredBaseFvIndex
; Index
++) {
405 if (mMeasuredBaseFvInfo
[Index
].BlobBase
== FvBase
) {
411 // Measure and record the FV to the TPM
413 FvBlob
.BlobBase
= FvBase
;
414 FvBlob
.BlobLength
= FvLength
;
416 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob
.BlobBase
));
417 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob
.BlobLength
));
419 TcgEventHdr
.PCRIndex
= 0;
420 TcgEventHdr
.EventType
= EV_EFI_PLATFORM_FIRMWARE_BLOB
;
421 TcgEventHdr
.EventSize
= sizeof (FvBlob
);
423 Status
= HashLogExtendEvent (
424 (EFI_PEI_SERVICES
**) GetPeiServicesTablePointer(),
425 (UINT8
*) (UINTN
) FvBlob
.BlobBase
,
426 (UINTN
) FvBlob
.BlobLength
,
432 // Add new FV into the measured FV list.
434 if (mMeasuredBaseFvIndex
>= mMeasuredMaxBaseFvIndex
) {
435 mMeasuredBaseFvInfo
= ReallocatePool (
436 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * mMeasuredMaxBaseFvIndex
,
437 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredMaxBaseFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
),
440 ASSERT (mMeasuredBaseFvInfo
!= NULL
);
441 mMeasuredMaxBaseFvIndex
= mMeasuredMaxBaseFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
;
444 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobBase
= FvBase
;
445 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobLength
= FvLength
;
446 mMeasuredBaseFvIndex
++;
454 @param[in] PeiServices Describes the list of possible PEI Services.
456 @retval EFI_SUCCESS Operation completed successfully.
457 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
458 @retval EFI_DEVICE_ERROR The command was unsuccessful.
464 IN EFI_PEI_SERVICES
**PeiServices
469 EFI_PEI_FV_HANDLE VolumeHandle
;
470 EFI_FV_INFO VolumeInfo
;
471 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
476 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
477 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
478 // platform for special CRTM TPM measuring.
480 Status
= PeiServicesFfsFindNextVolume (FvInstances
, &VolumeHandle
);
481 if (EFI_ERROR (Status
)) {
486 // Measure and record the firmware volume that is dispatched by PeiCore
488 Status
= PeiServicesFfsGetVolumeInfo (VolumeHandle
, &VolumeInfo
);
489 ASSERT_EFI_ERROR (Status
);
491 // Locate the corresponding FV_PPI according to founded FV's format guid
493 Status
= PeiServicesLocatePpi (
494 &VolumeInfo
.FvFormat
,
499 if (!EFI_ERROR (Status
)) {
500 MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) VolumeInfo
.FvStart
, VolumeInfo
.FvSize
);
510 Measure and record the Firmware Volum Information once FvInfoPPI install.
512 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
513 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
514 @param[in] Ppi Address of the PPI that was installed.
516 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
517 @return Others Fail to measure FV.
522 FirmwareVolmeInfoPpiNotifyCallback (
523 IN EFI_PEI_SERVICES
**PeiServices
,
524 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
528 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
530 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
533 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*) Ppi
;
536 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
538 Status
= PeiServicesLocatePpi (
544 if (EFI_ERROR (Status
)) {
549 // This is an FV from an FFS file, and the parent FV must have already been measured,
550 // No need to measure twice, so just record the FV and return
552 if (Fv
->ParentFvName
!= NULL
|| Fv
->ParentFileName
!= NULL
) {
554 if (mMeasuredChildFvIndex
>= mMeasuredMaxChildFvIndex
) {
555 mMeasuredChildFvInfo
= ReallocatePool (
556 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * mMeasuredMaxChildFvIndex
,
557 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredMaxChildFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
),
560 ASSERT (mMeasuredChildFvInfo
!= NULL
);
561 mMeasuredMaxChildFvIndex
= mMeasuredMaxChildFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
;
564 // Check whether FV is in the measured child FV list.
566 for (Index
= 0; Index
< mMeasuredChildFvIndex
; Index
++) {
567 if (mMeasuredChildFvInfo
[Index
].BlobBase
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
) {
571 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
;
572 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobLength
= Fv
->FvInfoSize
;
573 mMeasuredChildFvIndex
++;
577 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
, Fv
->FvInfoSize
);
581 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.
582 And lock physical presence if needed.
584 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
585 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
586 @param[in] Ppi Address of the PPI that was installed.
588 @retval EFI_SUCCESS Operation completed successfully.
589 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.
590 @retval EFI_DEVICE_ERROR The command was unsuccessful.
595 PhysicalPresencePpiNotifyCallback (
596 IN EFI_PEI_SERVICES
**PeiServices
,
597 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
602 TPM_PERMANENT_FLAGS TpmPermanentFlags
;
603 PEI_LOCK_PHYSICAL_PRESENCE_PPI
*LockPhysicalPresencePpi
;
604 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue
;
606 Status
= Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags
);
607 if (EFI_ERROR (Status
)) {
612 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
614 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock
) && !TpmPermanentFlags
.physicalPresenceLifetimeLock
) {
616 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
618 PhysicalPresenceValue
= TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK
;
619 TpmPermanentFlags
.physicalPresenceLifetimeLock
= TRUE
;
621 if (PcdGetBool (PcdPhysicalPresenceCmdEnable
)) {
622 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_ENABLE
;
623 TpmPermanentFlags
.physicalPresenceCMDEnable
= TRUE
;
625 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_DISABLE
;
626 TpmPermanentFlags
.physicalPresenceCMDEnable
= FALSE
;
629 if (PcdGetBool (PcdPhysicalPresenceHwEnable
)) {
630 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_ENABLE
;
632 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_DISABLE
;
635 Status
= Tpm12PhysicalPresence (
636 PhysicalPresenceValue
638 if (EFI_ERROR (Status
)) {
644 // 2. Lock physical presence if it is required.
646 LockPhysicalPresencePpi
= (PEI_LOCK_PHYSICAL_PRESENCE_PPI
*) Ppi
;
647 if (!LockPhysicalPresencePpi
->LockPhysicalPresence ((CONST EFI_PEI_SERVICES
**) PeiServices
)) {
651 if (!TpmPermanentFlags
.physicalPresenceCMDEnable
) {
652 if (TpmPermanentFlags
.physicalPresenceLifetimeLock
) {
654 // physicalPresenceCMDEnable is locked, can't change.
660 // Enable physical presence command
661 // It is necessary in order to lock physical presence
663 Status
= Tpm12PhysicalPresence (
664 TPM_PHYSICAL_PRESENCE_CMD_ENABLE
666 if (EFI_ERROR (Status
)) {
672 // Lock physical presence
674 Status
= Tpm12PhysicalPresence (
675 TPM_PHYSICAL_PRESENCE_LOCK
681 Check if TPM chip is activeated or not.
683 @param[in] PeiServices Describes the list of possible PEI Services.
685 @retval TRUE TPM is activated.
686 @retval FALSE TPM is deactivated.
695 TPM_PERMANENT_FLAGS TpmPermanentFlags
;
697 Status
= Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags
);
698 if (EFI_ERROR (Status
)) {
701 return (BOOLEAN
)(!TpmPermanentFlags
.deactivated
);
705 Do measurement after memory is ready.
707 @param[in] PeiServices Describes the list of possible PEI Services.
709 @retval EFI_SUCCESS Operation completed successfully.
710 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
711 @retval EFI_DEVICE_ERROR The command was unsuccessful.
717 IN EFI_PEI_SERVICES
**PeiServices
722 Status
= PeiServicesLocatePpi (
723 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
,
726 (VOID
**)&mMeasurementExcludedFvPpi
728 // Do not check status, because it is optional
730 Status
= Tpm12RequestUseTpm ();
731 if (EFI_ERROR (Status
)) {
735 if (IsTpmUsable ()) {
736 if (PcdGet8 (PcdTpmScrtmPolicy
) == 1) {
737 Status
= MeasureCRTMVersion (PeiServices
);
740 Status
= MeasureMainBios (PeiServices
);
745 // 1). for the FvInfoPpi services to measure and record
746 // the additional Fvs to TPM
747 // 2). for the OperatorPresencePpi service to determine whether to
750 Status
= PeiServicesNotifyPpi (&mNotifyList
[0]);
751 ASSERT_EFI_ERROR (Status
);
757 Entry point of this module.
759 @param[in] FileHandle Handle of the file being invoked.
760 @param[in] PeiServices Describes the list of possible PEI Services.
768 IN EFI_PEI_FILE_HANDLE FileHandle
,
769 IN CONST EFI_PEI_SERVICES
**PeiServices
774 EFI_BOOT_MODE BootMode
;
776 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
777 DEBUG ((EFI_D_ERROR
, "No TPM12 instance required!\n"));
778 return EFI_UNSUPPORTED
;
781 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
782 DEBUG ((EFI_D_ERROR
, "TPM error!\n"));
783 return EFI_DEVICE_ERROR
;
787 // Initialize TPM device
789 Status
= PeiServicesGetBootMode (&BootMode
);
790 ASSERT_EFI_ERROR (Status
);
793 // In S3 path, skip shadow logic. no measurement is required
795 if (BootMode
!= BOOT_ON_S3_RESUME
) {
796 Status
= (**PeiServices
).RegisterForShadow(FileHandle
);
797 if (Status
== EFI_ALREADY_STARTED
) {
798 mImageInMemory
= TRUE
;
799 } else if (Status
== EFI_NOT_FOUND
) {
800 ASSERT_EFI_ERROR (Status
);
804 if (!mImageInMemory
) {
805 Status
= Tpm12RequestUseTpm ();
806 if (EFI_ERROR (Status
)) {
807 DEBUG ((DEBUG_ERROR
, "TPM not detected!\n"));
811 if (PcdGet8 (PcdTpmInitializationPolicy
) == 1) {
812 if (BootMode
== BOOT_ON_S3_RESUME
) {
813 Status
= Tpm12Startup (TPM_ST_STATE
);
815 Status
= Tpm12Startup (TPM_ST_CLEAR
);
817 if (EFI_ERROR (Status
) ) {
823 // TpmSelfTest is optional on S3 path, skip it to save S3 time
825 if (BootMode
!= BOOT_ON_S3_RESUME
) {
826 Status
= Tpm12ContinueSelfTest ();
827 if (EFI_ERROR (Status
)) {
833 // Only intall TpmInitializedPpi on success
835 Status
= PeiServicesInstallPpi (&mTpmInitializedPpiList
);
836 ASSERT_EFI_ERROR (Status
);
839 if (mImageInMemory
) {
840 Status
= PeimEntryMP ((EFI_PEI_SERVICES
**)PeiServices
);
845 if (EFI_ERROR (Status
)) {
846 DEBUG ((EFI_D_ERROR
, "TPM error! Build Hob\n"));
847 BuildGuidHob (&gTpmErrorHobGuid
,0);
849 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
850 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
854 // Always intall TpmInitializationDonePpi no matter success or fail.
855 // Other driver can know TPM initialization state by TpmInitializedPpi.
857 Status2
= PeiServicesInstallPpi (&mTpmInitializationDonePpiList
);
858 ASSERT_EFI_ERROR (Status2
);