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