2 Initialize TPM device and measure FVs before handing off control to DXE.
4 Copyright (c) 2005 - 2020, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <IndustryStandard/Tpm12.h>
12 #include <IndustryStandard/UefiTcgPlatform.h>
13 #include <Ppi/FirmwareVolumeInfo.h>
14 #include <Ppi/FirmwareVolumeInfo2.h>
15 #include <Ppi/LockPhysicalPresence.h>
16 #include <Ppi/TpmInitialized.h>
17 #include <Ppi/FirmwareVolume.h>
18 #include <Ppi/EndOfPeiPhase.h>
19 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
22 #include <Guid/TcgEventHob.h>
23 #include <Guid/MeasuredFvHob.h>
24 #include <Guid/TpmInstance.h>
25 #include <Guid/MigratedFvInfo.h>
27 #include <Library/DebugLib.h>
28 #include <Library/BaseMemoryLib.h>
29 #include <Library/PeiServicesLib.h>
30 #include <Library/PeimEntryPoint.h>
31 #include <Library/HobLib.h>
32 #include <Library/PcdLib.h>
33 #include <Library/PeiServicesTablePointerLib.h>
34 #include <Library/BaseLib.h>
35 #include <Library/MemoryAllocationLib.h>
36 #include <Library/ReportStatusCodeLib.h>
37 #include <Library/Tpm12DeviceLib.h>
38 #include <Library/Tpm12CommandLib.h>
39 #include <Library/BaseCryptLib.h>
40 #include <Library/PerformanceLib.h>
42 BOOLEAN mImageInMemory
= FALSE
;
44 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList
= {
45 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
46 &gPeiTpmInitializedPpiGuid
,
50 EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList
= {
51 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
52 &gPeiTpmInitializationDonePpiGuid
,
57 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
58 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
59 added into the Event Log.
61 @param[in] This Indicates the calling context
62 @param[in] Flags Bitmap providing additional information.
63 @param[in] HashData Physical address of the start of the data buffer
64 to be hashed, extended, and logged.
65 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
66 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
67 @param[in] NewEventData Pointer to the new event data.
69 @retval EFI_SUCCESS Operation completed successfully.
70 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
71 @retval EFI_DEVICE_ERROR The command was unsuccessful.
77 IN EDKII_TCG_PPI
*This
,
81 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
82 IN UINT8
*NewEventData
85 EDKII_TCG_PPI mEdkiiTcgPpi
= {
89 EFI_PEI_PPI_DESCRIPTOR mTcgPpiList
= {
90 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
96 // Number of firmware blobs to grow by each time we run out of room
98 #define FIRMWARE_BLOB_GROWTH_STEP 4
100 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredBaseFvInfo
;
101 UINT32 mMeasuredMaxBaseFvIndex
= 0;
102 UINT32 mMeasuredBaseFvIndex
= 0;
104 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredChildFvInfo
;
105 UINT32 mMeasuredMaxChildFvIndex
= 0;
106 UINT32 mMeasuredChildFvIndex
= 0;
108 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI
*mMeasurementExcludedFvPpi
;
111 Lock physical presence if needed.
113 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
114 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
115 @param[in] Ppi Address of the PPI that was installed.
117 @retval EFI_SUCCESS Operation completed successfully.
122 PhysicalPresencePpiNotifyCallback (
123 IN EFI_PEI_SERVICES
**PeiServices
,
124 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
129 Measure and record the Firmware Volume Information once FvInfoPPI install.
131 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
132 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
133 @param[in] Ppi Address of the PPI that was installed.
135 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
136 @return Others Fail to measure FV.
141 FirmwareVolumeInfoPpiNotifyCallback (
142 IN EFI_PEI_SERVICES
**PeiServices
,
143 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
148 Record all measured Firmware Volume Information into a Guid Hob
150 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
151 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
152 @param[in] Ppi Address of the PPI that was installed.
154 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
155 @return Others Fail to measure FV.
160 EndofPeiSignalNotifyCallBack (
161 IN EFI_PEI_SERVICES
**PeiServices
,
162 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
166 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
168 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
169 &gPeiLockPhysicalPresencePpiGuid
,
170 PhysicalPresencePpiNotifyCallback
173 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
174 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
175 FirmwareVolumeInfoPpiNotifyCallback
178 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
179 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
180 FirmwareVolumeInfoPpiNotifyCallback
183 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
184 &gEfiEndOfPeiSignalPpiGuid
,
185 EndofPeiSignalNotifyCallBack
190 Record all measured Firmware Volume Information into a Guid Hob
191 Guid Hob payload layout is
193 UINT32 *************************** FIRMWARE_BLOB number
194 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
196 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
197 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
198 @param[in] Ppi Address of the PPI that was installed.
200 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
201 @return Others Fail to measure FV.
206 EndofPeiSignalNotifyCallBack (
207 IN EFI_PEI_SERVICES
**PeiServices
,
208 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
212 MEASURED_HOB_DATA
*MeasuredHobData
;
214 MeasuredHobData
= NULL
;
216 PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid
);
219 // Create a Guid hob to save all measured Fv
221 MeasuredHobData
= BuildGuidHob(
223 sizeof(UINTN
) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
)
226 if (MeasuredHobData
!= NULL
){
228 // Save measured FV info enty number
230 MeasuredHobData
->Num
= mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
;
233 // Save measured base Fv info
235 CopyMem (MeasuredHobData
->MeasuredFvBuf
, mMeasuredBaseFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
));
238 // Save measured child Fv info
240 CopyMem (&MeasuredHobData
->MeasuredFvBuf
[mMeasuredBaseFvIndex
] , mMeasuredChildFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredChildFvIndex
));
243 PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid
);
249 Single function calculates SHA1 digest value for all raw data. It
250 combines Sha1Init(), Sha1Update() and Sha1Final().
252 @param[in] Data Raw data to be digested.
253 @param[in] DataLen Size of the raw data.
254 @param[out] Digest Pointer to a buffer that stores the final digest.
256 @retval EFI_SUCCESS Always successfully calculate the final digest.
261 IN CONST UINT8
*Data
,
263 OUT TPM_DIGEST
*Digest
269 CtxSize
= Sha1GetContextSize ();
270 Sha1Ctx
= AllocatePool (CtxSize
);
271 ASSERT (Sha1Ctx
!= NULL
);
274 Sha1Update (Sha1Ctx
, Data
, DataLen
);
275 Sha1Final (Sha1Ctx
, (UINT8
*)Digest
);
283 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
284 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
285 added into the Event Log.
287 @param[in] This Indicates the calling context.
288 @param[in] Flags Bitmap providing additional information.
289 @param[in] HashData Physical address of the start of the data buffer
290 to be hashed, extended, and logged.
291 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
292 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
293 @param[in] NewEventData Pointer to the new event data.
295 @retval EFI_SUCCESS Operation completed successfully.
296 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
297 @retval EFI_DEVICE_ERROR The command was unsuccessful.
303 IN EDKII_TCG_PPI
*This
,
306 IN UINTN HashDataLen
,
307 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
308 IN UINT8
*NewEventData
314 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
315 return EFI_DEVICE_ERROR
;
319 if (HashDataLen
!= 0) {
320 Status
= TpmCommHashAll (
325 if (EFI_ERROR (Status
)) {
330 Status
= Tpm12Extend (
331 &NewEventHdr
->Digest
,
332 NewEventHdr
->PCRIndex
,
335 if (EFI_ERROR (Status
)) {
339 HobData
= BuildGuidHob (
340 &gTcgEventEntryHobGuid
,
341 sizeof (*NewEventHdr
) + NewEventHdr
->EventSize
343 if (HobData
== NULL
) {
344 Status
= EFI_OUT_OF_RESOURCES
;
348 CopyMem (HobData
, NewEventHdr
, sizeof (*NewEventHdr
));
349 HobData
= (VOID
*) ((UINT8
*)HobData
+ sizeof (*NewEventHdr
));
350 CopyMem (HobData
, NewEventData
, NewEventHdr
->EventSize
);
353 if ((Status
== EFI_DEVICE_ERROR
) || (Status
== EFI_TIMEOUT
)) {
354 DEBUG ((DEBUG_ERROR
, "HashLogExtendEvent - %r. Disable TPM.\n", Status
));
355 BuildGuidHob (&gTpmErrorHobGuid
,0);
357 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
358 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
360 Status
= EFI_DEVICE_ERROR
;
366 Measure CRTM version.
368 @param[in] PeiServices Describes the list of possible PEI Services.
370 @retval EFI_SUCCESS Operation completed successfully.
371 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
372 @retval EFI_DEVICE_ERROR The command was unsuccessful.
378 IN EFI_PEI_SERVICES
**PeiServices
381 TCG_PCR_EVENT_HDR TcgEventHdr
;
384 // Use FirmwareVersion string to represent CRTM version.
385 // OEMs should get real CRTM version string and measure it.
388 TcgEventHdr
.PCRIndex
= 0;
389 TcgEventHdr
.EventType
= EV_S_CRTM_VERSION
;
390 TcgEventHdr
.EventSize
= (UINT32
) StrSize((CHAR16
*)PcdGetPtr (PcdFirmwareVersionString
));
392 return HashLogExtendEvent (
395 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
),
396 TcgEventHdr
.EventSize
,
398 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
)
404 Add it into the measured FV list after the FV is measured successfully.
406 @param[in] FvBase Base address of FV image.
407 @param[in] FvLength Length of FV image.
409 @retval EFI_SUCCESS Fv image is measured successfully
410 or it has been already measured.
411 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
412 @retval EFI_DEVICE_ERROR The command was unsuccessful.
418 IN EFI_PHYSICAL_ADDRESS FvBase
,
424 EFI_PLATFORM_FIRMWARE_BLOB FvBlob
;
425 TCG_PCR_EVENT_HDR TcgEventHdr
;
426 EFI_PHYSICAL_ADDRESS FvOrgBase
;
427 EFI_PHYSICAL_ADDRESS FvDataBase
;
428 EFI_PEI_HOB_POINTERS Hob
;
429 EDKII_MIGRATED_FV_INFO
*MigratedFvInfo
;
432 // Check if it is in Excluded FV list
434 if (mMeasurementExcludedFvPpi
!= NULL
) {
435 for (Index
= 0; Index
< mMeasurementExcludedFvPpi
->Count
; Index
++) {
436 if (mMeasurementExcludedFvPpi
->Fv
[Index
].FvBase
== FvBase
) {
437 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase
));
438 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength
));
445 // Check whether FV is in the measured FV list.
447 for (Index
= 0; Index
< mMeasuredBaseFvIndex
; Index
++) {
448 if (mMeasuredBaseFvInfo
[Index
].BlobBase
== FvBase
) {
454 // Search the matched migration FV info
458 Hob
.Raw
= GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid
);
459 while (Hob
.Raw
!= NULL
) {
460 MigratedFvInfo
= GET_GUID_HOB_DATA (Hob
);
461 if ((MigratedFvInfo
->FvNewBase
== (UINT32
) FvBase
) && (MigratedFvInfo
->FvLength
== (UINT32
) FvLength
)) {
463 // Found the migrated FV info
465 FvOrgBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) MigratedFvInfo
->FvOrgBase
;
466 FvDataBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) MigratedFvInfo
->FvDataBase
;
469 Hob
.Raw
= GET_NEXT_HOB (Hob
);
470 Hob
.Raw
= GetNextGuidHob (&gEdkiiMigratedFvInfoGuid
, Hob
.Raw
);
474 // Measure and record the FV to the TPM
476 FvBlob
.BlobBase
= FvOrgBase
;
477 FvBlob
.BlobLength
= FvLength
;
479 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob
.BlobBase
));
480 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob
.BlobLength
));
482 TcgEventHdr
.PCRIndex
= 0;
483 TcgEventHdr
.EventType
= EV_EFI_PLATFORM_FIRMWARE_BLOB
;
484 TcgEventHdr
.EventSize
= sizeof (FvBlob
);
486 Status
= HashLogExtendEvent (
489 (UINT8
*) (UINTN
) FvDataBase
,
490 (UINTN
) FvBlob
.BlobLength
,
496 // Add new FV into the measured FV list.
498 if (mMeasuredBaseFvIndex
>= mMeasuredMaxBaseFvIndex
) {
499 mMeasuredBaseFvInfo
= ReallocatePool (
500 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * mMeasuredMaxBaseFvIndex
,
501 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredMaxBaseFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
),
504 ASSERT (mMeasuredBaseFvInfo
!= NULL
);
505 mMeasuredMaxBaseFvIndex
= mMeasuredMaxBaseFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
;
508 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobBase
= FvBase
;
509 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobLength
= FvLength
;
510 mMeasuredBaseFvIndex
++;
518 @param[in] PeiServices Describes the list of possible PEI Services.
520 @retval EFI_SUCCESS Operation completed successfully.
521 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
522 @retval EFI_DEVICE_ERROR The command was unsuccessful.
528 IN EFI_PEI_SERVICES
**PeiServices
533 EFI_PEI_FV_HANDLE VolumeHandle
;
534 EFI_FV_INFO VolumeInfo
;
535 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
540 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
541 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
542 // platform for special CRTM TPM measuring.
544 Status
= PeiServicesFfsFindNextVolume (FvInstances
, &VolumeHandle
);
545 if (EFI_ERROR (Status
)) {
550 // Measure and record the firmware volume that is dispatched by PeiCore
552 Status
= PeiServicesFfsGetVolumeInfo (VolumeHandle
, &VolumeInfo
);
553 ASSERT_EFI_ERROR (Status
);
555 // Locate the corresponding FV_PPI according to founded FV's format guid
557 Status
= PeiServicesLocatePpi (
558 &VolumeInfo
.FvFormat
,
563 if (!EFI_ERROR (Status
)) {
564 MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) VolumeInfo
.FvStart
, VolumeInfo
.FvSize
);
574 Measure and record the Firmware Volume Information once FvInfoPPI install.
576 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
577 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
578 @param[in] Ppi Address of the PPI that was installed.
580 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
581 @return Others Fail to measure FV.
586 FirmwareVolumeInfoPpiNotifyCallback (
587 IN EFI_PEI_SERVICES
**PeiServices
,
588 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
592 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
594 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
597 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*) Ppi
;
600 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
602 Status
= PeiServicesLocatePpi (
608 if (EFI_ERROR (Status
)) {
613 // This is an FV from an FFS file, and the parent FV must have already been measured,
614 // No need to measure twice, so just record the FV and return
616 if (Fv
->ParentFvName
!= NULL
|| Fv
->ParentFileName
!= NULL
) {
618 if (mMeasuredChildFvIndex
>= mMeasuredMaxChildFvIndex
) {
619 mMeasuredChildFvInfo
= ReallocatePool (
620 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * mMeasuredMaxChildFvIndex
,
621 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredMaxChildFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
),
624 ASSERT (mMeasuredChildFvInfo
!= NULL
);
625 mMeasuredMaxChildFvIndex
= mMeasuredMaxChildFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
;
628 // Check whether FV is in the measured child FV list.
630 for (Index
= 0; Index
< mMeasuredChildFvIndex
; Index
++) {
631 if (mMeasuredChildFvInfo
[Index
].BlobBase
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
) {
635 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
;
636 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobLength
= Fv
->FvInfoSize
;
637 mMeasuredChildFvIndex
++;
641 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
, Fv
->FvInfoSize
);
645 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.
646 And lock physical presence if needed.
648 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
649 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
650 @param[in] Ppi Address of the PPI that was installed.
652 @retval EFI_SUCCESS Operation completed successfully.
653 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.
654 @retval EFI_DEVICE_ERROR The command was unsuccessful.
659 PhysicalPresencePpiNotifyCallback (
660 IN EFI_PEI_SERVICES
**PeiServices
,
661 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
666 TPM_PERMANENT_FLAGS TpmPermanentFlags
;
667 PEI_LOCK_PHYSICAL_PRESENCE_PPI
*LockPhysicalPresencePpi
;
668 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue
;
670 Status
= Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags
);
671 if (EFI_ERROR (Status
)) {
676 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
678 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock
) && !TpmPermanentFlags
.physicalPresenceLifetimeLock
) {
680 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
682 PhysicalPresenceValue
= TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK
;
683 TpmPermanentFlags
.physicalPresenceLifetimeLock
= TRUE
;
685 if (PcdGetBool (PcdPhysicalPresenceCmdEnable
)) {
686 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_ENABLE
;
687 TpmPermanentFlags
.physicalPresenceCMDEnable
= TRUE
;
689 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_DISABLE
;
690 TpmPermanentFlags
.physicalPresenceCMDEnable
= FALSE
;
693 if (PcdGetBool (PcdPhysicalPresenceHwEnable
)) {
694 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_ENABLE
;
696 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_DISABLE
;
699 Status
= Tpm12PhysicalPresence (
700 PhysicalPresenceValue
702 if (EFI_ERROR (Status
)) {
708 // 2. Lock physical presence if it is required.
710 LockPhysicalPresencePpi
= (PEI_LOCK_PHYSICAL_PRESENCE_PPI
*) Ppi
;
711 if (!LockPhysicalPresencePpi
->LockPhysicalPresence ((CONST EFI_PEI_SERVICES
**) PeiServices
)) {
715 if (!TpmPermanentFlags
.physicalPresenceCMDEnable
) {
716 if (TpmPermanentFlags
.physicalPresenceLifetimeLock
) {
718 // physicalPresenceCMDEnable is locked, can't change.
724 // Enable physical presence command
725 // It is necessary in order to lock physical presence
727 Status
= Tpm12PhysicalPresence (
728 TPM_PHYSICAL_PRESENCE_CMD_ENABLE
730 if (EFI_ERROR (Status
)) {
736 // Lock physical presence
738 Status
= Tpm12PhysicalPresence (
739 TPM_PHYSICAL_PRESENCE_LOCK
745 Check if TPM chip is activated or not.
747 @param[in] PeiServices Describes the list of possible PEI Services.
749 @retval TRUE TPM is activated.
750 @retval FALSE TPM is deactivated.
759 TPM_PERMANENT_FLAGS TpmPermanentFlags
;
761 Status
= Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags
);
762 if (EFI_ERROR (Status
)) {
765 return (BOOLEAN
)(!TpmPermanentFlags
.deactivated
);
769 Do measurement after memory is ready.
771 @param[in] PeiServices Describes the list of possible PEI Services.
773 @retval EFI_SUCCESS Operation completed successfully.
774 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
775 @retval EFI_DEVICE_ERROR The command was unsuccessful.
781 IN EFI_PEI_SERVICES
**PeiServices
786 Status
= PeiServicesLocatePpi (
787 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
,
790 (VOID
**)&mMeasurementExcludedFvPpi
792 // Do not check status, because it is optional
794 Status
= Tpm12RequestUseTpm ();
795 if (EFI_ERROR (Status
)) {
799 if (IsTpmUsable ()) {
800 if (PcdGet8 (PcdTpmScrtmPolicy
) == 1) {
801 Status
= MeasureCRTMVersion (PeiServices
);
804 Status
= MeasureMainBios (PeiServices
);
809 // 1). for the FvInfoPpi services to measure and record
810 // the additional Fvs to TPM
811 // 2). for the OperatorPresencePpi service to determine whether to
814 Status
= PeiServicesNotifyPpi (&mNotifyList
[0]);
815 ASSERT_EFI_ERROR (Status
);
818 // install Tcg Services
820 Status
= PeiServicesInstallPpi (&mTcgPpiList
);
821 ASSERT_EFI_ERROR (Status
);
827 Entry point of this module.
829 @param[in] FileHandle Handle of the file being invoked.
830 @param[in] PeiServices Describes the list of possible PEI Services.
838 IN EFI_PEI_FILE_HANDLE FileHandle
,
839 IN CONST EFI_PEI_SERVICES
**PeiServices
844 EFI_BOOT_MODE BootMode
;
846 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
847 DEBUG ((DEBUG_ERROR
, "No TPM12 instance required!\n"));
848 return EFI_UNSUPPORTED
;
851 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
852 DEBUG ((DEBUG_ERROR
, "TPM error!\n"));
853 return EFI_DEVICE_ERROR
;
857 // Initialize TPM device
859 Status
= PeiServicesGetBootMode (&BootMode
);
860 ASSERT_EFI_ERROR (Status
);
863 // In S3 path, skip shadow logic. no measurement is required
865 if (BootMode
!= BOOT_ON_S3_RESUME
) {
866 Status
= (**PeiServices
).RegisterForShadow(FileHandle
);
867 if (Status
== EFI_ALREADY_STARTED
) {
868 mImageInMemory
= TRUE
;
869 } else if (Status
== EFI_NOT_FOUND
) {
870 ASSERT_EFI_ERROR (Status
);
874 if (!mImageInMemory
) {
875 Status
= Tpm12RequestUseTpm ();
876 if (EFI_ERROR (Status
)) {
877 DEBUG ((DEBUG_ERROR
, "TPM not detected!\n"));
881 if (PcdGet8 (PcdTpmInitializationPolicy
) == 1) {
882 if (BootMode
== BOOT_ON_S3_RESUME
) {
883 Status
= Tpm12Startup (TPM_ST_STATE
);
885 Status
= Tpm12Startup (TPM_ST_CLEAR
);
887 if (EFI_ERROR (Status
) ) {
893 // TpmSelfTest is optional on S3 path, skip it to save S3 time
895 if (BootMode
!= BOOT_ON_S3_RESUME
) {
896 Status
= Tpm12ContinueSelfTest ();
897 if (EFI_ERROR (Status
)) {
903 // Only install TpmInitializedPpi on success
905 Status
= PeiServicesInstallPpi (&mTpmInitializedPpiList
);
906 ASSERT_EFI_ERROR (Status
);
909 if (mImageInMemory
) {
910 Status
= PeimEntryMP ((EFI_PEI_SERVICES
**)PeiServices
);
915 if (EFI_ERROR (Status
)) {
916 DEBUG ((DEBUG_ERROR
, "TPM error! Build Hob\n"));
917 BuildGuidHob (&gTpmErrorHobGuid
,0);
919 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
920 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
924 // Always install TpmInitializationDonePpi no matter success or fail.
925 // Other driver can know TPM initialization state by TpmInitializedPpi.
927 Status2
= PeiServicesInstallPpi (&mTpmInitializationDonePpiList
);
928 ASSERT_EFI_ERROR (Status2
);