]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
SecurityPkg: Initailize variable Status before it is consumed.
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Pei / Tcg2Pei.c
1 /** @file
2 Initialize TPM2 device and measure FVs before handing off control to DXE.
3
4 Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017, Microsoft Corporation. All rights reserved. <BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <PiPei.h>
11
12 #include <IndustryStandard/UefiTcgPlatform.h>
13 #include <Ppi/FirmwareVolumeInfo.h>
14 #include <Ppi/FirmwareVolumeInfo2.h>
15 #include <Ppi/TpmInitialized.h>
16 #include <Ppi/FirmwareVolume.h>
17 #include <Ppi/EndOfPeiPhase.h>
18 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
19 #include <Ppi/FirmwareVolumeInfoPrehashedFV.h>
20 #include <Ppi/Tcg.h>
21
22 #include <Guid/TcgEventHob.h>
23 #include <Guid/MeasuredFvHob.h>
24 #include <Guid/TpmInstance.h>
25 #include <Guid/MigratedFvInfo.h>
26
27 #include <Library/DebugLib.h>
28 #include <Library/BaseMemoryLib.h>
29 #include <Library/PeiServicesLib.h>
30 #include <Library/PeimEntryPoint.h>
31 #include <Library/Tpm2CommandLib.h>
32 #include <Library/Tpm2DeviceLib.h>
33 #include <Library/HashLib.h>
34 #include <Library/HobLib.h>
35 #include <Library/PcdLib.h>
36 #include <Library/PeiServicesTablePointerLib.h>
37 #include <Protocol/Tcg2Protocol.h>
38 #include <Library/PerformanceLib.h>
39 #include <Library/MemoryAllocationLib.h>
40 #include <Library/ReportStatusCodeLib.h>
41 #include <Library/ResetSystemLib.h>
42 #include <Library/PrintLib.h>
43
44 #define PERF_ID_TCG2_PEI 0x3080
45
46 typedef struct {
47 EFI_GUID *EventGuid;
48 EFI_TCG2_EVENT_LOG_FORMAT LogFormat;
49 } TCG2_EVENT_INFO_STRUCT;
50
51 TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = {
52 {&gTcgEventEntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2},
53 {&gTcgEvent2EntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2},
54 };
55
56 BOOLEAN mImageInMemory = FALSE;
57 EFI_PEI_FILE_HANDLE mFileHandle;
58
59 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {
60 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
61 &gPeiTpmInitializedPpiGuid,
62 NULL
63 };
64
65 EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = {
66 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
67 &gPeiTpmInitializationDonePpiGuid,
68 NULL
69 };
70
71 /**
72 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
73 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
74 added into the Event Log.
75
76 @param[in] This Indicates the calling context
77 @param[in] Flags Bitmap providing additional information.
78 @param[in] HashData If BIT0 of Flags is 0, it is physical address of the
79 start of the data buffer to be hashed, extended, and logged.
80 If BIT0 of Flags is 1, it is physical address of the
81 start of the pre-hash data buffter to be extended, and logged.
82 The pre-hash data format is TPML_DIGEST_VALUES.
83 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
84 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
85 @param[in] NewEventData Pointer to the new event data.
86
87 @retval EFI_SUCCESS Operation completed successfully.
88 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
89 @retval EFI_DEVICE_ERROR The command was unsuccessful.
90
91 **/
92 EFI_STATUS
93 EFIAPI
94 HashLogExtendEvent (
95 IN EDKII_TCG_PPI *This,
96 IN UINT64 Flags,
97 IN UINT8 *HashData,
98 IN UINTN HashDataLen,
99 IN TCG_PCR_EVENT_HDR *NewEventHdr,
100 IN UINT8 *NewEventData
101 );
102
103 EDKII_TCG_PPI mEdkiiTcgPpi = {
104 HashLogExtendEvent
105 };
106
107 EFI_PEI_PPI_DESCRIPTOR mTcgPpiList = {
108 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
109 &gEdkiiTcgPpiGuid,
110 &mEdkiiTcgPpi
111 };
112
113 //
114 // Number of firmware blobs to grow by each time we run out of room
115 //
116 #define FIRMWARE_BLOB_GROWTH_STEP 4
117
118 EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredBaseFvInfo;
119 UINT32 mMeasuredMaxBaseFvIndex = 0;
120 UINT32 mMeasuredBaseFvIndex = 0;
121
122 EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;
123 UINT32 mMeasuredMaxChildFvIndex = 0;
124 UINT32 mMeasuredChildFvIndex = 0;
125
126 #pragma pack (1)
127
128 #define FV_HANDOFF_TABLE_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
129 typedef struct {
130 UINT8 BlobDescriptionSize;
131 UINT8 BlobDescription[sizeof(FV_HANDOFF_TABLE_DESC)];
132 EFI_PHYSICAL_ADDRESS BlobBase;
133 UINT64 BlobLength;
134 } FV_HANDOFF_TABLE_POINTERS2;
135
136 #pragma pack ()
137
138 /**
139 Measure and record the Firmware Volume Information once FvInfoPPI install.
140
141 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
142 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
143 @param[in] Ppi Address of the PPI that was installed.
144
145 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
146 @return Others Fail to measure FV.
147
148 **/
149 EFI_STATUS
150 EFIAPI
151 FirmwareVolumeInfoPpiNotifyCallback (
152 IN EFI_PEI_SERVICES **PeiServices,
153 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
154 IN VOID *Ppi
155 );
156
157 /**
158 Record all measured Firmware Volume Information into a Guid Hob
159
160 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
161 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
162 @param[in] Ppi Address of the PPI that was installed.
163
164 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
165 @return Others Fail to measure FV.
166
167 **/
168 EFI_STATUS
169 EFIAPI
170 EndofPeiSignalNotifyCallBack (
171 IN EFI_PEI_SERVICES **PeiServices,
172 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
173 IN VOID *Ppi
174 );
175
176 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
177 {
178 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
179 &gEfiPeiFirmwareVolumeInfoPpiGuid,
180 FirmwareVolumeInfoPpiNotifyCallback
181 },
182 {
183 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
184 &gEfiPeiFirmwareVolumeInfo2PpiGuid,
185 FirmwareVolumeInfoPpiNotifyCallback
186 },
187 {
188 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
189 &gEfiEndOfPeiSignalPpiGuid,
190 EndofPeiSignalNotifyCallBack
191 }
192 };
193
194
195 /**
196 Record all measured Firmware Volume Information into a Guid Hob
197 Guid Hob payload layout is
198
199 UINT32 *************************** FIRMWARE_BLOB number
200 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
201
202 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
203 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
204 @param[in] Ppi Address of the PPI that was installed.
205
206 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
207 @return Others Fail to measure FV.
208
209 **/
210 EFI_STATUS
211 EFIAPI
212 EndofPeiSignalNotifyCallBack (
213 IN EFI_PEI_SERVICES **PeiServices,
214 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
215 IN VOID *Ppi
216 )
217 {
218 MEASURED_HOB_DATA *MeasuredHobData;
219
220 MeasuredHobData = NULL;
221
222 PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid);
223
224 //
225 // Create a Guid hob to save all measured Fv
226 //
227 MeasuredHobData = BuildGuidHob(
228 &gMeasuredFvHobGuid,
229 sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)
230 );
231
232 if (MeasuredHobData != NULL){
233 //
234 // Save measured FV info enty number
235 //
236 MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;
237
238 //
239 // Save measured base Fv info
240 //
241 CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));
242
243 //
244 // Save measured child Fv info
245 //
246 CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));
247 }
248
249 PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid);
250
251 return EFI_SUCCESS;
252 }
253
254 /**
255 Make sure that the current PCR allocations, the TPM supported PCRs,
256 and the PcdTpm2HashMask are all in agreement.
257 **/
258 VOID
259 SyncPcrAllocationsAndPcrMask (
260 VOID
261 )
262 {
263 EFI_STATUS Status;
264 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
265 UINT32 TpmActivePcrBanks;
266 UINT32 NewTpmActivePcrBanks;
267 UINT32 Tpm2PcrMask;
268 UINT32 NewTpm2PcrMask;
269
270 DEBUG ((EFI_D_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
271
272 //
273 // Determine the current TPM support and the Platform PCR mask.
274 //
275 Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &TpmActivePcrBanks);
276 ASSERT_EFI_ERROR (Status);
277
278 Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask);
279 if (Tpm2PcrMask == 0) {
280 //
281 // if PcdTPm2HashMask is zero, use ActivePcr setting
282 //
283 PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks);
284 Tpm2PcrMask = TpmActivePcrBanks;
285 }
286
287 //
288 // Find the intersection of Pcd support and TPM support.
289 // If banks are missing from the TPM support that are in the PCD, update the PCD.
290 // If banks are missing from the PCD that are active in the TPM, reallocate the banks and reboot.
291 //
292
293 //
294 // If there are active PCR banks that are not supported by the Platform mask,
295 // update the TPM allocations and reboot the machine.
296 //
297 if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) {
298 NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask;
299
300 DEBUG ((EFI_D_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n", __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
301 if (NewTpmActivePcrBanks == 0) {
302 DEBUG ((EFI_D_ERROR, "%a - No viable PCRs active! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
303 ASSERT (FALSE);
304 } else {
305 Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap, NewTpmActivePcrBanks);
306 if (EFI_ERROR (Status)) {
307 //
308 // We can't do much here, but we hope that this doesn't happen.
309 //
310 DEBUG ((EFI_D_ERROR, "%a - Failed to reallocate PCRs!\n", __FUNCTION__));
311 ASSERT_EFI_ERROR (Status);
312 }
313 //
314 // Need reset system, since we just called Tpm2PcrAllocateBanks().
315 //
316 ResetCold();
317 }
318 }
319
320 //
321 // If there are any PCRs that claim support in the Platform mask that are
322 // not supported by the TPM, update the mask.
323 //
324 if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) {
325 NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap;
326
327 DEBUG ((EFI_D_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
328 if (NewTpm2PcrMask == 0) {
329 DEBUG ((EFI_D_ERROR, "%a - No viable PCRs supported! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
330 ASSERT (FALSE);
331 }
332
333 Status = PcdSet32S (PcdTpm2HashMask, NewTpm2PcrMask);
334 ASSERT_EFI_ERROR (Status);
335 }
336 }
337
338 /**
339 Add a new entry to the Event Log.
340
341 @param[in] DigestList A list of digest.
342 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
343 @param[in] NewEventData Pointer to the new event data.
344
345 @retval EFI_SUCCESS The new event log entry was added.
346 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
347 **/
348 EFI_STATUS
349 LogHashEvent (
350 IN TPML_DIGEST_VALUES *DigestList,
351 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
352 IN UINT8 *NewEventData
353 )
354 {
355 VOID *HobData;
356 EFI_STATUS Status;
357 UINTN Index;
358 EFI_STATUS RetStatus;
359 UINT32 SupportedEventLogs;
360 TCG_PCR_EVENT2 *TcgPcrEvent2;
361 UINT8 *DigestBuffer;
362
363 SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
364
365 RetStatus = EFI_SUCCESS;
366 for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
367 if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
368 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
369 switch (mTcg2EventInfo[Index].LogFormat) {
370 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
371 Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
372 if (!EFI_ERROR (Status)) {
373 HobData = BuildGuidHob (
374 &gTcgEventEntryHobGuid,
375 sizeof (*NewEventHdr) + NewEventHdr->EventSize
376 );
377 if (HobData == NULL) {
378 RetStatus = EFI_OUT_OF_RESOURCES;
379 break;
380 }
381
382 CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));
383 HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));
384 CopyMem (HobData, NewEventData, NewEventHdr->EventSize);
385 }
386 break;
387 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:
388 //
389 // Use GetDigestListSize (DigestList) in the GUID HOB DataLength calculation
390 // to reserve enough buffer to hold TPML_DIGEST_VALUES compact binary.
391 //
392 HobData = BuildGuidHob (
393 &gTcgEvent2EntryHobGuid,
394 sizeof(TcgPcrEvent2->PCRIndex) + sizeof(TcgPcrEvent2->EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2->EventSize) + NewEventHdr->EventSize
395 );
396 if (HobData == NULL) {
397 RetStatus = EFI_OUT_OF_RESOURCES;
398 break;
399 }
400
401 TcgPcrEvent2 = HobData;
402 TcgPcrEvent2->PCRIndex = NewEventHdr->PCRIndex;
403 TcgPcrEvent2->EventType = NewEventHdr->EventType;
404 DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest;
405 DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList, PcdGet32 (PcdTpm2HashMask));
406 CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(TcgPcrEvent2->EventSize));
407 DigestBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);
408 CopyMem (DigestBuffer, NewEventData, NewEventHdr->EventSize);
409 break;
410 }
411 }
412 }
413
414 return RetStatus;
415 }
416
417 /**
418 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
419 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
420 added into the Event Log.
421
422 @param[in] This Indicates the calling context
423 @param[in] Flags Bitmap providing additional information.
424 @param[in] HashData If BIT0 of Flags is 0, it is physical address of the
425 start of the data buffer to be hashed, extended, and logged.
426 If BIT0 of Flags is 1, it is physical address of the
427 start of the pre-hash data buffter to be extended, and logged.
428 The pre-hash data format is TPML_DIGEST_VALUES.
429 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
430 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
431 @param[in] NewEventData Pointer to the new event data.
432
433 @retval EFI_SUCCESS Operation completed successfully.
434 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
435 @retval EFI_DEVICE_ERROR The command was unsuccessful.
436
437 **/
438 EFI_STATUS
439 EFIAPI
440 HashLogExtendEvent (
441 IN EDKII_TCG_PPI *This,
442 IN UINT64 Flags,
443 IN UINT8 *HashData,
444 IN UINTN HashDataLen,
445 IN TCG_PCR_EVENT_HDR *NewEventHdr,
446 IN UINT8 *NewEventData
447 )
448 {
449 EFI_STATUS Status;
450 TPML_DIGEST_VALUES DigestList;
451
452 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
453 return EFI_DEVICE_ERROR;
454 }
455
456 if ((Flags & EDKII_TCG_PRE_HASH) != 0 || (Flags & EDKII_TCG_PRE_HASH_LOG_ONLY) != 0) {
457 ZeroMem (&DigestList, sizeof(DigestList));
458 CopyMem (&DigestList, HashData, sizeof(DigestList));
459 Status = EFI_SUCCESS;
460 if ((Flags & EDKII_TCG_PRE_HASH) !=0 ) {
461 Status = Tpm2PcrExtend (
462 NewEventHdr->PCRIndex,
463 &DigestList
464 );
465 }
466 } else {
467 Status = HashAndExtend (
468 NewEventHdr->PCRIndex,
469 HashData,
470 HashDataLen,
471 &DigestList
472 );
473 }
474 if (!EFI_ERROR (Status)) {
475 Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);
476 }
477
478 if (Status == EFI_DEVICE_ERROR) {
479 DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
480 BuildGuidHob (&gTpmErrorHobGuid,0);
481 REPORT_STATUS_CODE (
482 EFI_ERROR_CODE | EFI_ERROR_MINOR,
483 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
484 );
485 }
486
487 return Status;
488 }
489
490 /**
491 Measure CRTM version.
492
493 @retval EFI_SUCCESS Operation completed successfully.
494 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
495 @retval EFI_DEVICE_ERROR The command was unsuccessful.
496
497 **/
498 EFI_STATUS
499 MeasureCRTMVersion (
500 VOID
501 )
502 {
503 TCG_PCR_EVENT_HDR TcgEventHdr;
504
505 //
506 // Use FirmwareVersion string to represent CRTM version.
507 // OEMs should get real CRTM version string and measure it.
508 //
509
510 TcgEventHdr.PCRIndex = 0;
511 TcgEventHdr.EventType = EV_S_CRTM_VERSION;
512 TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));
513
514 return HashLogExtendEvent (
515 &mEdkiiTcgPpi,
516 0,
517 (UINT8*)PcdGetPtr (PcdFirmwareVersionString),
518 TcgEventHdr.EventSize,
519 &TcgEventHdr,
520 (UINT8*)PcdGetPtr (PcdFirmwareVersionString)
521 );
522 }
523
524 /**
525 Get the FvName from the FV header.
526
527 Causion: The FV is untrusted input.
528
529 @param[in] FvBase Base address of FV image.
530 @param[in] FvLength Length of FV image.
531
532 @return FvName pointer
533 @retval NULL FvName is NOT found
534 **/
535 VOID *
536 GetFvName (
537 IN EFI_PHYSICAL_ADDRESS FvBase,
538 IN UINT64 FvLength
539 )
540 {
541 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
542 EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
543
544 if (FvBase >= MAX_ADDRESS) {
545 return NULL;
546 }
547 if (FvLength >= MAX_ADDRESS - FvBase) {
548 return NULL;
549 }
550 if (FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {
551 return NULL;
552 }
553
554 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;
555 if (FvHeader->ExtHeaderOffset < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {
556 return NULL;
557 }
558 if (FvHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) {
559 return NULL;
560 }
561 FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset);
562
563 return &FvExtHeader->FvName;
564 }
565
566 /**
567 Measure FV image.
568 Add it into the measured FV list after the FV is measured successfully.
569
570 @param[in] FvBase Base address of FV image.
571 @param[in] FvLength Length of FV image.
572
573 @retval EFI_SUCCESS Fv image is measured successfully
574 or it has been already measured.
575 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
576 @retval EFI_DEVICE_ERROR The command was unsuccessful.
577
578 **/
579 EFI_STATUS
580 MeasureFvImage (
581 IN EFI_PHYSICAL_ADDRESS FvBase,
582 IN UINT64 FvLength
583 )
584 {
585 UINT32 Index;
586 EFI_STATUS Status;
587 EFI_PLATFORM_FIRMWARE_BLOB FvBlob;
588 FV_HANDOFF_TABLE_POINTERS2 FvBlob2;
589 VOID *EventData;
590 VOID *FvName;
591 TCG_PCR_EVENT_HDR TcgEventHdr;
592 UINT32 Instance;
593 UINT32 Tpm2HashMask;
594 TPML_DIGEST_VALUES DigestList;
595 UINT32 DigestCount;
596 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi;
597 EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI *PrehashedFvPpi;
598 HASH_INFO *PreHashInfo;
599 UINT32 HashAlgoMask;
600 EFI_PHYSICAL_ADDRESS FvOrgBase;
601 EFI_PHYSICAL_ADDRESS FvDataBase;
602 EFI_PEI_HOB_POINTERS Hob;
603 EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
604
605 //
606 // Check Excluded FV list
607 //
608 Instance = 0;
609 do {
610 Status = PeiServicesLocatePpi(
611 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid,
612 Instance,
613 NULL,
614 (VOID**)&MeasurementExcludedFvPpi
615 );
616 if (!EFI_ERROR(Status)) {
617 for (Index = 0; Index < MeasurementExcludedFvPpi->Count; Index ++) {
618 if (MeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase
619 && MeasurementExcludedFvPpi->Fv[Index].FvLength == FvLength) {
620 DEBUG ((DEBUG_INFO, "The FV which is excluded by Tcg2Pei starts at: 0x%x\n", FvBase));
621 DEBUG ((DEBUG_INFO, "The FV which is excluded by Tcg2Pei has the size: 0x%x\n", FvLength));
622 return EFI_SUCCESS;
623 }
624 }
625
626 Instance++;
627 }
628 } while (!EFI_ERROR(Status));
629
630 //
631 // Check measured FV list
632 //
633 for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {
634 if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase && mMeasuredBaseFvInfo[Index].BlobLength == FvLength) {
635 DEBUG ((DEBUG_INFO, "The FV which is already measured by Tcg2Pei starts at: 0x%x\n", FvBase));
636 DEBUG ((DEBUG_INFO, "The FV which is already measured by Tcg2Pei has the size: 0x%x\n", FvLength));
637 return EFI_SUCCESS;
638 }
639 }
640
641 //
642 // Check pre-hashed FV list
643 //
644 Instance = 0;
645 Tpm2HashMask = PcdGet32 (PcdTpm2HashMask);
646 do {
647 Status = PeiServicesLocatePpi (
648 &gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid,
649 Instance,
650 NULL,
651 (VOID**)&PrehashedFvPpi
652 );
653 if (!EFI_ERROR(Status) && PrehashedFvPpi->FvBase == FvBase && PrehashedFvPpi->FvLength == FvLength) {
654 ZeroMem (&DigestList, sizeof(TPML_DIGEST_VALUES));
655
656 //
657 // The FV is prehashed, check against TPM hash mask
658 //
659 PreHashInfo = (HASH_INFO *)(PrehashedFvPpi + 1);
660 for (Index = 0, DigestCount = 0; Index < PrehashedFvPpi->Count; Index++) {
661 DEBUG((DEBUG_INFO, "Hash Algo ID in PrehashedFvPpi=0x%x\n", PreHashInfo->HashAlgoId));
662 HashAlgoMask = GetHashMaskFromAlgo(PreHashInfo->HashAlgoId);
663 if ((Tpm2HashMask & HashAlgoMask) != 0 ) {
664 //
665 // Hash is required, copy it to DigestList
666 //
667 WriteUnaligned16(&(DigestList.digests[DigestCount].hashAlg), PreHashInfo->HashAlgoId);
668 CopyMem (
669 &DigestList.digests[DigestCount].digest,
670 PreHashInfo + 1,
671 PreHashInfo->HashSize
672 );
673 DigestCount++;
674 //
675 // Clean the corresponding Hash Algo mask bit
676 //
677 Tpm2HashMask &= ~HashAlgoMask;
678 }
679 PreHashInfo = (HASH_INFO *)((UINT8 *)(PreHashInfo + 1) + PreHashInfo->HashSize);
680 }
681
682 WriteUnaligned32(&DigestList.count, DigestCount);
683
684 break;
685 }
686 Instance++;
687 } while (!EFI_ERROR(Status));
688
689 //
690 // Search the matched migration FV info
691 //
692 FvOrgBase = FvBase;
693 FvDataBase = FvBase;
694 Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
695 while (Hob.Raw != NULL) {
696 MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
697 if ((MigratedFvInfo->FvNewBase == (UINT32) FvBase) && (MigratedFvInfo->FvLength == (UINT32) FvLength)) {
698 //
699 // Found the migrated FV info
700 //
701 FvOrgBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvOrgBase;
702 FvDataBase = (EFI_PHYSICAL_ADDRESS) (UINTN) MigratedFvInfo->FvDataBase;
703 break;
704 }
705 Hob.Raw = GET_NEXT_HOB (Hob);
706 Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
707 }
708
709 //
710 // Init the log event for FV measurement
711 //
712 if (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105) {
713 FvBlob2.BlobDescriptionSize = sizeof(FvBlob2.BlobDescription);
714 CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof(FvBlob2.BlobDescription));
715 FvName = GetFvName (FvBase, FvLength);
716 if (FvName != NULL) {
717 AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);
718 }
719 FvBlob2.BlobBase = FvOrgBase;
720 FvBlob2.BlobLength = FvLength;
721 TcgEventHdr.PCRIndex = 0;
722 TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;
723 TcgEventHdr.EventSize = sizeof (FvBlob2);
724 EventData = &FvBlob2;
725 } else {
726 FvBlob.BlobBase = FvOrgBase;
727 FvBlob.BlobLength = FvLength;
728 TcgEventHdr.PCRIndex = 0;
729 TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
730 TcgEventHdr.EventSize = sizeof (FvBlob);
731 EventData = &FvBlob;
732 }
733
734 if (Tpm2HashMask == 0) {
735 //
736 // FV pre-hash algos comply with current TPM hash requirement
737 // Skip hashing step in measure, only extend DigestList to PCR and log event
738 //
739 Status = HashLogExtendEvent (
740 &mEdkiiTcgPpi,
741 EDKII_TCG_PRE_HASH,
742 (UINT8*) &DigestList, // HashData
743 (UINTN) sizeof(DigestList), // HashDataLen
744 &TcgEventHdr, // EventHdr
745 EventData // EventData
746 );
747 DEBUG ((DEBUG_INFO, "The pre-hashed FV which is extended & logged by Tcg2Pei starts at: 0x%x\n", FvBase));
748 DEBUG ((DEBUG_INFO, "The pre-hashed FV which is extended & logged by Tcg2Pei has the size: 0x%x\n", FvLength));
749 } else {
750 //
751 // Hash the FV, extend digest to the TPM and log TCG event
752 //
753 Status = HashLogExtendEvent (
754 &mEdkiiTcgPpi,
755 0,
756 (UINT8*) (UINTN) FvDataBase, // HashData
757 (UINTN) FvLength, // HashDataLen
758 &TcgEventHdr, // EventHdr
759 EventData // EventData
760 );
761 DEBUG ((DEBUG_INFO, "The FV which is measured by Tcg2Pei starts at: 0x%x\n", FvBase));
762 DEBUG ((DEBUG_INFO, "The FV which is measured by Tcg2Pei has the size: 0x%x\n", FvLength));
763 }
764
765 if (EFI_ERROR(Status)) {
766 DEBUG ((DEBUG_ERROR, "The FV which failed to be measured starts at: 0x%x\n", FvBase));
767 return Status;
768 }
769
770 //
771 // Add new FV into the measured FV list.
772 //
773 if (mMeasuredBaseFvIndex >= mMeasuredMaxBaseFvIndex) {
774 mMeasuredBaseFvInfo = ReallocatePool (
775 sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * mMeasuredMaxBaseFvIndex,
776 sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredMaxBaseFvIndex + FIRMWARE_BLOB_GROWTH_STEP),
777 mMeasuredBaseFvInfo
778 );
779 ASSERT (mMeasuredBaseFvInfo != NULL);
780 mMeasuredMaxBaseFvIndex = mMeasuredMaxBaseFvIndex + FIRMWARE_BLOB_GROWTH_STEP;
781 }
782
783 mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;
784 mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;
785 mMeasuredBaseFvIndex++;
786
787 return Status;
788 }
789
790 /**
791 Measure main BIOS.
792
793 @retval EFI_SUCCESS Operation completed successfully.
794 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
795 @retval EFI_DEVICE_ERROR The command was unsuccessful.
796
797 **/
798 EFI_STATUS
799 MeasureMainBios (
800 VOID
801 )
802 {
803 EFI_STATUS Status;
804 EFI_PEI_FV_HANDLE VolumeHandle;
805 EFI_FV_INFO VolumeInfo;
806 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
807
808 PERF_START_EX (mFileHandle, "EventRec", "Tcg2Pei", 0, PERF_ID_TCG2_PEI);
809
810 //
811 // Only measure BFV at the very beginning. Other parts of Static Core Root of
812 // Trust for Measurement(S-CRTM) will be measured later on FvInfoNotify.
813 // BFV is processed without installing FV Info Ppi. Other FVs either inside BFV or
814 // reported by platform will be installed with Fv Info Ppi
815 // This firmware volume measure policy can be modified/enhanced by special
816 // platform for special CRTM TPM measuring.
817 //
818 Status = PeiServicesFfsFindNextVolume (0, &VolumeHandle);
819 ASSERT_EFI_ERROR (Status);
820
821 //
822 // Measure and record the firmware volume that is dispatched by PeiCore
823 //
824 Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
825 ASSERT_EFI_ERROR (Status);
826 //
827 // Locate the corresponding FV_PPI according to founded FV's format guid
828 //
829 Status = PeiServicesLocatePpi (
830 &VolumeInfo.FvFormat,
831 0,
832 NULL,
833 (VOID**)&FvPpi
834 );
835 ASSERT_EFI_ERROR (Status);
836
837 Status = MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);
838
839 PERF_END_EX (mFileHandle, "EventRec", "Tcg2Pei", 0, PERF_ID_TCG2_PEI + 1);
840
841 return Status;
842 }
843
844 /**
845 Measure and record the Firmware Volume Information once FvInfoPPI install.
846
847 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
848 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
849 @param[in] Ppi Address of the PPI that was installed.
850
851 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
852 @return Others Fail to measure FV.
853
854 **/
855 EFI_STATUS
856 EFIAPI
857 FirmwareVolumeInfoPpiNotifyCallback (
858 IN EFI_PEI_SERVICES **PeiServices,
859 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
860 IN VOID *Ppi
861 )
862 {
863 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
864 EFI_STATUS Status;
865 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
866 UINTN Index;
867
868 Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;
869
870 //
871 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
872 //
873 Status = PeiServicesLocatePpi (
874 &Fv->FvFormat,
875 0,
876 NULL,
877 (VOID**)&FvPpi
878 );
879 if (EFI_ERROR (Status)) {
880 return EFI_SUCCESS;
881 }
882
883 //
884 // This is an FV from an FFS file, and the parent FV must have already been measured,
885 // No need to measure twice, so just record the FV and return
886 //
887 if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {
888
889 if (mMeasuredChildFvIndex >= mMeasuredMaxChildFvIndex) {
890 mMeasuredChildFvInfo = ReallocatePool (
891 sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * mMeasuredMaxChildFvIndex,
892 sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredMaxChildFvIndex + FIRMWARE_BLOB_GROWTH_STEP),
893 mMeasuredChildFvInfo
894 );
895 ASSERT (mMeasuredChildFvInfo != NULL);
896 mMeasuredMaxChildFvIndex = mMeasuredMaxChildFvIndex + FIRMWARE_BLOB_GROWTH_STEP;
897 }
898 //
899 // Check whether FV is in the measured child FV list.
900 //
901 for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {
902 if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) {
903 return EFI_SUCCESS;
904 }
905 }
906 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;
907 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;
908 mMeasuredChildFvIndex++;
909 return EFI_SUCCESS;
910 }
911
912 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);
913 }
914
915 /**
916 Do measurement after memory is ready.
917
918 @param[in] PeiServices Describes the list of possible PEI Services.
919
920 @retval EFI_SUCCESS Operation completed successfully.
921 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
922 @retval EFI_DEVICE_ERROR The command was unsuccessful.
923
924 **/
925 EFI_STATUS
926 PeimEntryMP (
927 IN EFI_PEI_SERVICES **PeiServices
928 )
929 {
930 EFI_STATUS Status;
931
932 //
933 // install Tcg Services
934 //
935 Status = PeiServicesInstallPpi (&mTcgPpiList);
936 ASSERT_EFI_ERROR (Status);
937
938 if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) {
939 Status = MeasureCRTMVersion ();
940 }
941
942 Status = MeasureMainBios ();
943 if (EFI_ERROR(Status)) {
944 return Status;
945 }
946
947 //
948 // Post callbacks:
949 // for the FvInfoPpi services to measure and record
950 // the additional Fvs to TPM
951 //
952 Status = PeiServicesNotifyPpi (&mNotifyList[0]);
953 ASSERT_EFI_ERROR (Status);
954
955 return Status;
956 }
957
958 /**
959 Measure and log Separator event with error, and extend the measurement result into a specific PCR.
960
961 @param[in] PCRIndex PCR index.
962
963 @retval EFI_SUCCESS Operation completed successfully.
964 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
965
966 **/
967 EFI_STATUS
968 MeasureSeparatorEventWithError (
969 IN TPM_PCRINDEX PCRIndex
970 )
971 {
972 TCG_PCR_EVENT_HDR TcgEvent;
973 UINT32 EventData;
974
975 //
976 // Use EventData 0x1 to indicate there is error.
977 //
978 EventData = 0x1;
979 TcgEvent.PCRIndex = PCRIndex;
980 TcgEvent.EventType = EV_SEPARATOR;
981 TcgEvent.EventSize = (UINT32)sizeof (EventData);
982 return HashLogExtendEvent(&mEdkiiTcgPpi, 0, (UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent,(UINT8 *)&EventData);
983 }
984
985 /**
986 Entry point of this module.
987
988 @param[in] FileHandle Handle of the file being invoked.
989 @param[in] PeiServices Describes the list of possible PEI Services.
990
991 @return Status.
992
993 **/
994 EFI_STATUS
995 EFIAPI
996 PeimEntryMA (
997 IN EFI_PEI_FILE_HANDLE FileHandle,
998 IN CONST EFI_PEI_SERVICES **PeiServices
999 )
1000 {
1001 EFI_STATUS Status;
1002 EFI_STATUS Status2;
1003 EFI_BOOT_MODE BootMode;
1004 TPM_PCRINDEX PcrIndex;
1005 BOOLEAN S3ErrorReport;
1006
1007 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
1008 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
1009 DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));
1010 return EFI_UNSUPPORTED;
1011 }
1012
1013 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
1014 DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
1015 return EFI_DEVICE_ERROR;
1016 }
1017
1018 Status = PeiServicesGetBootMode (&BootMode);
1019 ASSERT_EFI_ERROR (Status);
1020
1021 //
1022 // In S3 path, skip shadow logic. no measurement is required
1023 //
1024 if (BootMode != BOOT_ON_S3_RESUME) {
1025 Status = (**PeiServices).RegisterForShadow(FileHandle);
1026 if (Status == EFI_ALREADY_STARTED) {
1027 mImageInMemory = TRUE;
1028 mFileHandle = FileHandle;
1029 } else if (Status == EFI_NOT_FOUND) {
1030 ASSERT_EFI_ERROR (Status);
1031 }
1032 }
1033
1034 if (!mImageInMemory) {
1035 //
1036 // Initialize TPM device
1037 //
1038 Status = Tpm2RequestUseTpm ();
1039 if (EFI_ERROR (Status)) {
1040 DEBUG ((DEBUG_ERROR, "TPM2 not detected!\n"));
1041 goto Done;
1042 }
1043
1044 S3ErrorReport = FALSE;
1045 if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {
1046 if (BootMode == BOOT_ON_S3_RESUME) {
1047 Status = Tpm2Startup (TPM_SU_STATE);
1048 if (EFI_ERROR (Status) ) {
1049 Status = Tpm2Startup (TPM_SU_CLEAR);
1050 if (!EFI_ERROR(Status)) {
1051 S3ErrorReport = TRUE;
1052 }
1053 }
1054 } else {
1055 Status = Tpm2Startup (TPM_SU_CLEAR);
1056 }
1057 if (EFI_ERROR (Status) ) {
1058 goto Done;
1059 }
1060 }
1061
1062 //
1063 // Update Tpm2HashMask according to PCR bank.
1064 //
1065 SyncPcrAllocationsAndPcrMask ();
1066
1067 if (S3ErrorReport) {
1068 //
1069 // The system firmware that resumes from S3 MUST deal with a
1070 // TPM2_Startup error appropriately.
1071 // For example, issue a TPM2_Startup(TPM_SU_CLEAR) command and
1072 // configuring the device securely by taking actions like extending a
1073 // separator with an error digest (0x01) into PCRs 0 through 7.
1074 //
1075 for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
1076 Status = MeasureSeparatorEventWithError (PcrIndex);
1077 if (EFI_ERROR (Status)) {
1078 DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n"));
1079 }
1080 }
1081 }
1082
1083 //
1084 // TpmSelfTest is optional on S3 path, skip it to save S3 time
1085 //
1086 if (BootMode != BOOT_ON_S3_RESUME) {
1087 if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) {
1088 Status = Tpm2SelfTest (NO);
1089 if (EFI_ERROR (Status)) {
1090 goto Done;
1091 }
1092 }
1093 }
1094
1095 //
1096 // Only install TpmInitializedPpi on success
1097 //
1098 Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
1099 ASSERT_EFI_ERROR (Status);
1100 }
1101
1102 if (mImageInMemory) {
1103 Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
1104 return Status;
1105 }
1106
1107 Done:
1108 if (EFI_ERROR (Status)) {
1109 DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));
1110 BuildGuidHob (&gTpmErrorHobGuid,0);
1111 REPORT_STATUS_CODE (
1112 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1113 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
1114 );
1115 }
1116 //
1117 // Always install TpmInitializationDonePpi no matter success or fail.
1118 // Other driver can know TPM initialization state by TpmInitializedPpi.
1119 //
1120 Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
1121 ASSERT_EFI_ERROR (Status2);
1122
1123 return Status;
1124 }