]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/TcgPei/TcgPei.c
Update TcgPei and TrEEPei driver to make gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMax...
[mirror_edk2.git] / SecurityPkg / Tcg / TcgPei / TcgPei.c
CommitLineData
0c18794e 1/** @file\r
2 Initialize TPM device and measure FVs before handing off control to DXE.\r
3\r
2bc36371 4Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>\r
0c18794e 5This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiPei.h>\r
16\r
17#include <IndustryStandard/Tpm12.h>\r
18#include <IndustryStandard/UefiTcgPlatform.h>\r
19#include <Ppi/FirmwareVolumeInfo.h>\r
c7935105 20#include <Ppi/FirmwareVolumeInfo2.h>\r
0c18794e 21#include <Ppi/LockPhysicalPresence.h>\r
22#include <Ppi/TpmInitialized.h>\r
23#include <Ppi/FirmwareVolume.h>\r
2aadc920 24#include <Ppi/EndOfPeiPhase.h>\r
c1d93242 25#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>\r
2aadc920 26\r
0c18794e 27#include <Guid/TcgEventHob.h>\r
0758c830 28#include <Guid/MeasuredFvHob.h>\r
c1d93242 29#include <Guid/TpmInstance.h>\r
2aadc920 30\r
0c18794e 31#include <Library/DebugLib.h>\r
32#include <Library/BaseMemoryLib.h>\r
33#include <Library/PeiServicesLib.h>\r
34#include <Library/PeimEntryPoint.h>\r
35#include <Library/TpmCommLib.h>\r
36#include <Library/HobLib.h>\r
37#include <Library/PcdLib.h>\r
38#include <Library/PeiServicesTablePointerLib.h>\r
333a53ee 39#include <Library/BaseLib.h>\r
b5412eac 40#include <Library/MemoryAllocationLib.h>\r
0c18794e 41\r
42#include "TpmComm.h"\r
43\r
44BOOLEAN mImageInMemory = FALSE;\r
45\r
46EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {\r
47 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
48 &gPeiTpmInitializedPpiGuid,\r
49 NULL\r
50};\r
51\r
b5412eac 52EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredBaseFvInfo;\r
2aadc920 53UINT32 mMeasuredBaseFvIndex = 0;\r
54\r
b5412eac 55EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;\r
2aadc920 56UINT32 mMeasuredChildFvIndex = 0;\r
57\r
c1d93242
JY
58EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;\r
59\r
0c18794e 60/**\r
61 Lock physical presence if needed.\r
62\r
63 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
64 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
65 @param[in] Ppi Address of the PPI that was installed.\r
66\r
67 @retval EFI_SUCCESS Operation completed successfully.\r
68\r
69**/\r
70EFI_STATUS\r
71EFIAPI\r
72PhysicalPresencePpiNotifyCallback (\r
73 IN EFI_PEI_SERVICES **PeiServices,\r
74 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
75 IN VOID *Ppi\r
76 );\r
77\r
78/**\r
79 Measure and record the Firmware Volum Information once FvInfoPPI install.\r
80\r
81 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
82 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
83 @param[in] Ppi Address of the PPI that was installed.\r
84\r
85 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
86 @return Others Fail to measure FV.\r
87\r
88**/\r
89EFI_STATUS\r
90EFIAPI\r
91FirmwareVolmeInfoPpiNotifyCallback (\r
92 IN EFI_PEI_SERVICES **PeiServices,\r
93 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
94 IN VOID *Ppi\r
95 );\r
96\r
2aadc920 97/**\r
98 Record all measured Firmware Volum Information into a Guid Hob\r
99\r
100 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
101 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
102 @param[in] Ppi Address of the PPI that was installed.\r
103\r
104 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
105 @return Others Fail to measure FV.\r
106\r
107**/\r
108EFI_STATUS\r
109EFIAPI\r
110EndofPeiSignalNotifyCallBack (\r
111 IN EFI_PEI_SERVICES **PeiServices,\r
112 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
113 IN VOID *Ppi\r
114 );\r
115\r
0c18794e 116EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {\r
117 {\r
118 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
119 &gPeiLockPhysicalPresencePpiGuid,\r
120 PhysicalPresencePpiNotifyCallback\r
121 },\r
122 {\r
2aadc920 123 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
0c18794e 124 &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
125 FirmwareVolmeInfoPpiNotifyCallback \r
2aadc920 126 },\r
c7935105
SZ
127 {\r
128 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
129 &gEfiPeiFirmwareVolumeInfo2PpiGuid,\r
130 FirmwareVolmeInfoPpiNotifyCallback \r
131 },\r
2aadc920 132 {\r
133 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
134 &gEfiEndOfPeiSignalPpiGuid,\r
135 EndofPeiSignalNotifyCallBack\r
0c18794e 136 }\r
137};\r
138\r
2aadc920 139/**\r
140 Record all measured Firmware Volum Information into a Guid Hob\r
141 Guid Hob payload layout is \r
142\r
143 UINT32 *************************** FIRMWARE_BLOB number\r
144 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array\r
145\r
146 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
147 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
148 @param[in] Ppi Address of the PPI that was installed.\r
149\r
150 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
151 @return Others Fail to measure FV.\r
152\r
153**/\r
154EFI_STATUS\r
155EFIAPI\r
156EndofPeiSignalNotifyCallBack (\r
157 IN EFI_PEI_SERVICES **PeiServices,\r
158 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
159 IN VOID *Ppi\r
160 )\r
161{ \r
0758c830 162 MEASURED_HOB_DATA *MeasuredHobData;\r
2aadc920 163\r
0758c830 164 MeasuredHobData = NULL;\r
2aadc920 165\r
166 //\r
0758c830 167 // Create a Guid hob to save all measured Fv \r
2aadc920 168 //\r
0758c830 169 MeasuredHobData = BuildGuidHob(\r
170 &gMeasuredFvHobGuid,\r
171 sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)\r
172 );\r
2aadc920 173\r
0758c830 174 if (MeasuredHobData != NULL){\r
2aadc920 175 //\r
176 // Save measured FV info enty number\r
177 //\r
0758c830 178 MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;\r
2aadc920 179\r
2aadc920 180 //\r
181 // Save measured base Fv info\r
182 //\r
0758c830 183 CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));\r
2aadc920 184\r
2aadc920 185 //\r
186 // Save measured child Fv info\r
187 //\r
0758c830 188 CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));\r
2aadc920 189 }\r
190\r
191 return EFI_SUCCESS;\r
192}\r
0c18794e 193\r
194/**\r
195 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
196 and build a GUIDed HOB recording the event which will be passed to the DXE phase and\r
197 added into the Event Log.\r
198\r
199 @param[in] PeiServices Describes the list of possible PEI Services.\r
200 @param[in] HashData Physical address of the start of the data buffer \r
201 to be hashed, extended, and logged.\r
202 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.\r
203 @param[in] TpmHandle TPM handle.\r
204 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
205 @param[in] NewEventData Pointer to the new event data. \r
206\r
207 @retval EFI_SUCCESS Operation completed successfully.\r
208 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
209 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
210\r
211**/\r
212EFI_STATUS\r
213HashLogExtendEvent (\r
214 IN EFI_PEI_SERVICES **PeiServices,\r
215 IN UINT8 *HashData,\r
216 IN UINTN HashDataLen,\r
217 IN TIS_TPM_HANDLE TpmHandle,\r
218 IN TCG_PCR_EVENT_HDR *NewEventHdr,\r
219 IN UINT8 *NewEventData\r
220 )\r
221{\r
222 EFI_STATUS Status;\r
223 VOID *HobData;\r
224\r
225 HobData = NULL;\r
226 if (HashDataLen != 0) {\r
227 Status = TpmCommHashAll (\r
228 HashData,\r
229 HashDataLen,\r
230 &NewEventHdr->Digest\r
231 );\r
232 ASSERT_EFI_ERROR (Status);\r
233 }\r
234\r
235 Status = TpmCommExtend (\r
236 PeiServices,\r
237 TpmHandle,\r
238 &NewEventHdr->Digest,\r
239 NewEventHdr->PCRIndex,\r
240 NULL\r
241 );\r
242 ASSERT_EFI_ERROR (Status);\r
243\r
244 HobData = BuildGuidHob (\r
245 &gTcgEventEntryHobGuid,\r
246 sizeof (*NewEventHdr) + NewEventHdr->EventSize\r
247 );\r
248 if (HobData == NULL) {\r
249 return EFI_OUT_OF_RESOURCES;\r
250 }\r
251\r
252 CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));\r
253 HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));\r
254 CopyMem (HobData, NewEventData, NewEventHdr->EventSize);\r
255 return EFI_SUCCESS;\r
256}\r
257\r
258/**\r
259 Measure CRTM version.\r
260\r
261 @param[in] PeiServices Describes the list of possible PEI Services.\r
262 @param[in] TpmHandle TPM handle.\r
263\r
264 @retval EFI_SUCCESS Operation completed successfully.\r
265 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
266 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
267\r
268**/\r
269EFI_STATUS\r
270EFIAPI\r
271MeasureCRTMVersion (\r
272 IN EFI_PEI_SERVICES **PeiServices,\r
273 IN TIS_TPM_HANDLE TpmHandle\r
274 )\r
275{\r
276 TCG_PCR_EVENT_HDR TcgEventHdr;\r
277\r
278 //\r
333a53ee 279 // Use FirmwareVersion string to represent CRTM version.\r
0c18794e 280 // OEMs should get real CRTM version string and measure it.\r
281 //\r
282\r
283 TcgEventHdr.PCRIndex = 0;\r
284 TcgEventHdr.EventType = EV_S_CRTM_VERSION;\r
8cc06814 285 TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));\r
333a53ee 286\r
0c18794e 287 return HashLogExtendEvent (\r
288 PeiServices,\r
333a53ee 289 (UINT8*)PcdGetPtr (PcdFirmwareVersionString),\r
0c18794e 290 TcgEventHdr.EventSize,\r
291 TpmHandle,\r
292 &TcgEventHdr,\r
333a53ee 293 (UINT8*)PcdGetPtr (PcdFirmwareVersionString)\r
0c18794e 294 );\r
295}\r
296\r
297/**\r
298 Measure FV image. \r
299 Add it into the measured FV list after the FV is measured successfully. \r
300\r
301 @param[in] FvBase Base address of FV image.\r
302 @param[in] FvLength Length of FV image.\r
303\r
304 @retval EFI_SUCCESS Fv image is measured successfully \r
305 or it has been already measured.\r
306 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
307 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
308\r
309**/\r
310EFI_STATUS\r
311EFIAPI\r
312MeasureFvImage (\r
313 IN EFI_PHYSICAL_ADDRESS FvBase,\r
314 IN UINT64 FvLength\r
315 )\r
316{\r
317 UINT32 Index;\r
318 EFI_STATUS Status;\r
319 EFI_PLATFORM_FIRMWARE_BLOB FvBlob;\r
320 TCG_PCR_EVENT_HDR TcgEventHdr;\r
321 TIS_TPM_HANDLE TpmHandle;\r
322\r
323 TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;\r
324\r
c1d93242
JY
325 //\r
326 // Check if it is in Excluded FV list\r
327 //\r
328 if (mMeasurementExcludedFvPpi != NULL) {\r
329 for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {\r
330 if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {\r
331 DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase));\r
332 DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength));\r
333 return EFI_SUCCESS;\r
334 }\r
335 }\r
336 }\r
337\r
0c18794e 338 //\r
339 // Check whether FV is in the measured FV list.\r
340 //\r
2aadc920 341 for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {\r
342 if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {\r
0c18794e 343 return EFI_SUCCESS;\r
344 }\r
345 }\r
346 \r
347 //\r
348 // Measure and record the FV to the TPM\r
349 //\r
350 FvBlob.BlobBase = FvBase;\r
351 FvBlob.BlobLength = FvLength;\r
352\r
353 DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob.BlobBase));\r
354 DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob.BlobLength));\r
355\r
356 TcgEventHdr.PCRIndex = 0;\r
357 TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
358 TcgEventHdr.EventSize = sizeof (FvBlob);\r
359\r
360 Status = HashLogExtendEvent (\r
361 (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),\r
362 (UINT8*) (UINTN) FvBlob.BlobBase,\r
363 (UINTN) FvBlob.BlobLength,\r
364 TpmHandle,\r
365 &TcgEventHdr,\r
366 (UINT8*) &FvBlob\r
367 );\r
368 ASSERT_EFI_ERROR (Status);\r
369\r
370 //\r
371 // Add new FV into the measured FV list.\r
372 //\r
b5412eac
DG
373 ASSERT (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));\r
374 if (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
2aadc920 375 mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;\r
376 mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;\r
377 mMeasuredBaseFvIndex++;\r
0c18794e 378 }\r
379\r
380 return Status;\r
381}\r
382\r
383/**\r
384 Measure main BIOS.\r
385\r
386 @param[in] PeiServices Describes the list of possible PEI Services.\r
387 @param[in] TpmHandle TPM handle.\r
388\r
389 @retval EFI_SUCCESS Operation completed successfully.\r
390 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
391 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
392\r
393**/\r
394EFI_STATUS\r
395EFIAPI\r
396MeasureMainBios (\r
397 IN EFI_PEI_SERVICES **PeiServices,\r
398 IN TIS_TPM_HANDLE TpmHandle\r
399 )\r
400{\r
401 EFI_STATUS Status;\r
402 UINT32 FvInstances;\r
403 EFI_PEI_FV_HANDLE VolumeHandle;\r
404 EFI_FV_INFO VolumeInfo;\r
405 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
406 \r
407 FvInstances = 0;\r
408 while (TRUE) {\r
409 //\r
410 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement\r
411 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special\r
412 // platform for special CRTM TPM measuring.\r
413 //\r
414 Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);\r
415 if (EFI_ERROR (Status)) {\r
416 break;\r
417 }\r
418 \r
419 //\r
420 // Measure and record the firmware volume that is dispatched by PeiCore\r
421 //\r
422 Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);\r
423 ASSERT_EFI_ERROR (Status);\r
424 //\r
425 // Locate the corresponding FV_PPI according to founded FV's format guid\r
426 //\r
427 Status = PeiServicesLocatePpi (\r
428 &VolumeInfo.FvFormat, \r
429 0, \r
430 NULL,\r
431 (VOID**)&FvPpi\r
432 );\r
433 if (!EFI_ERROR (Status)) {\r
434 MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);\r
435 }\r
436\r
437 FvInstances++;\r
438 }\r
439\r
440 return EFI_SUCCESS;\r
441}\r
442\r
443/**\r
444 Measure and record the Firmware Volum Information once FvInfoPPI install.\r
445\r
446 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
447 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
448 @param[in] Ppi Address of the PPI that was installed.\r
449\r
450 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
451 @return Others Fail to measure FV.\r
452\r
453**/\r
454EFI_STATUS\r
455EFIAPI\r
456FirmwareVolmeInfoPpiNotifyCallback (\r
457 IN EFI_PEI_SERVICES **PeiServices,\r
458 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
459 IN VOID *Ppi\r
460 )\r
461{\r
462 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;\r
463 EFI_STATUS Status;\r
464 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
387208ab 465 UINTN Index;\r
0c18794e 466\r
467 Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;\r
468\r
469 //\r
470 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.\r
471 //\r
472 Status = PeiServicesLocatePpi (\r
473 &Fv->FvFormat, \r
474 0, \r
475 NULL,\r
476 (VOID**)&FvPpi\r
477 );\r
478 if (EFI_ERROR (Status)) {\r
479 return EFI_SUCCESS;\r
480 }\r
481 \r
482 //\r
483 // This is an FV from an FFS file, and the parent FV must have already been measured,\r
2aadc920 484 // No need to measure twice, so just record the FV and return\r
0c18794e 485 //\r
486 if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {\r
2aadc920 487 \r
b5412eac
DG
488 ASSERT (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));\r
489 if (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
387208ab
SZ
490 //\r
491 // Check whether FV is in the measured child FV list.\r
492 //\r
493 for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {\r
494 if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) {\r
495 return EFI_SUCCESS;\r
496 }\r
497 }\r
2aadc920 498 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;\r
499 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;\r
500 mMeasuredChildFvIndex++;\r
501 }\r
0c18794e 502 return EFI_SUCCESS;\r
503 }\r
504\r
505 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);\r
506}\r
507\r
508/**\r
5a500332 509 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.\r
510 And lock physical presence if needed.\r
0c18794e 511\r
512 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
513 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
514 @param[in] Ppi Address of the PPI that was installed.\r
515\r
516 @retval EFI_SUCCESS Operation completed successfully.\r
517 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.\r
518 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
519\r
520**/\r
521EFI_STATUS\r
522EFIAPI\r
523PhysicalPresencePpiNotifyCallback (\r
524 IN EFI_PEI_SERVICES **PeiServices,\r
525 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
526 IN VOID *Ppi\r
527 )\r
528{\r
529 EFI_STATUS Status;\r
530 PEI_LOCK_PHYSICAL_PRESENCE_PPI *LockPhysicalPresencePpi;\r
531 BOOLEAN LifetimeLock;\r
532 BOOLEAN CmdEnable;\r
533 TIS_TPM_HANDLE TpmHandle;\r
5a500332 534 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue;\r
0c18794e 535\r
536 TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;\r
0c18794e 537\r
5a500332 538 Status = TpmCommGetCapability (PeiServices, TpmHandle, NULL, &LifetimeLock, &CmdEnable);\r
539 if (EFI_ERROR (Status)) {\r
540 return Status;\r
0c18794e 541 }\r
542\r
543 //\r
5a500332 544 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.\r
0c18794e 545 //\r
5a500332 546 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !LifetimeLock) {\r
547 //\r
548 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet. \r
549 //\r
550 PhysicalPresenceValue = TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK;\r
551\r
552 if (PcdGetBool (PcdPhysicalPresenceCmdEnable)) {\r
553 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_ENABLE;\r
554 CmdEnable = TRUE;\r
555 } else {\r
556 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_DISABLE;\r
557 CmdEnable = FALSE;\r
558 }\r
0c18794e 559\r
5a500332 560 if (PcdGetBool (PcdPhysicalPresenceHwEnable)) {\r
561 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_ENABLE;\r
562 } else {\r
563 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_DISABLE;\r
564 } \r
565 \r
566 Status = TpmCommPhysicalPresence (\r
567 PeiServices,\r
568 TpmHandle,\r
569 PhysicalPresenceValue\r
570 );\r
571 if (EFI_ERROR (Status)) {\r
572 return Status;\r
573 }\r
574 }\r
575 \r
576 //\r
577 // 2. Lock physical presence if it is required.\r
578 //\r
579 LockPhysicalPresencePpi = (PEI_LOCK_PHYSICAL_PRESENCE_PPI *) Ppi;\r
580 if (!LockPhysicalPresencePpi->LockPhysicalPresence ((CONST EFI_PEI_SERVICES**) PeiServices)) {\r
581 return EFI_SUCCESS;\r
0c18794e 582 }\r
583\r
584 if (!CmdEnable) {\r
585 if (LifetimeLock) {\r
586 //\r
587 // physicalPresenceCMDEnable is locked, can't change.\r
588 //\r
589 return EFI_ABORTED;\r
590 }\r
591\r
592 //\r
593 // Enable physical presence command\r
594 // It is necessary in order to lock physical presence\r
595 //\r
596 Status = TpmCommPhysicalPresence (\r
597 PeiServices,\r
598 TpmHandle,\r
599 TPM_PHYSICAL_PRESENCE_CMD_ENABLE\r
600 );\r
601 if (EFI_ERROR (Status)) {\r
602 return Status;\r
603 }\r
604 }\r
605\r
606 //\r
607 // Lock physical presence\r
608 // \r
609 Status = TpmCommPhysicalPresence (\r
610 PeiServices,\r
611 TpmHandle,\r
612 TPM_PHYSICAL_PRESENCE_LOCK\r
613 );\r
614 return Status;\r
615}\r
616\r
617/**\r
618 Check if TPM chip is activeated or not.\r
619\r
620 @param[in] PeiServices Describes the list of possible PEI Services.\r
621 @param[in] TpmHandle TPM handle.\r
622\r
623 @retval TRUE TPM is activated.\r
624 @retval FALSE TPM is deactivated.\r
625\r
626**/\r
627BOOLEAN\r
628EFIAPI\r
629IsTpmUsable (\r
630 IN EFI_PEI_SERVICES **PeiServices,\r
631 IN TIS_TPM_HANDLE TpmHandle\r
632 )\r
633{\r
634 EFI_STATUS Status;\r
635 BOOLEAN Deactivated;\r
636\r
637 Status = TpmCommGetCapability (PeiServices, TpmHandle, &Deactivated, NULL, NULL);\r
638 if (EFI_ERROR (Status)) {\r
639 return FALSE;\r
640 }\r
641 return (BOOLEAN)(!Deactivated); \r
642}\r
643\r
644/**\r
645 Do measurement after memory is ready.\r
646\r
647 @param[in] PeiServices Describes the list of possible PEI Services.\r
648\r
649 @retval EFI_SUCCESS Operation completed successfully.\r
650 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
651 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
652\r
653**/\r
654EFI_STATUS\r
655EFIAPI\r
656PeimEntryMP (\r
657 IN EFI_PEI_SERVICES **PeiServices\r
658 )\r
659{\r
660 EFI_STATUS Status;\r
661 TIS_TPM_HANDLE TpmHandle;\r
662\r
c1d93242
JY
663 Status = PeiServicesLocatePpi (\r
664 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, \r
665 0, \r
666 NULL,\r
667 (VOID**)&mMeasurementExcludedFvPpi\r
668 );\r
669 // Do not check status, because it is optional\r
670\r
b5412eac
DG
671 mMeasuredBaseFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
672 ASSERT (mMeasuredBaseFvInfo != NULL);\r
673 mMeasuredChildFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
674 ASSERT (mMeasuredChildFvInfo != NULL);\r
675\r
0c18794e 676 TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
677 Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);\r
678 if (EFI_ERROR (Status)) {\r
679 return Status;\r
680 }\r
681\r
682 if (IsTpmUsable (PeiServices, TpmHandle)) {\r
c1d93242
JY
683 if (PcdGet8 (PcdTpmScrtmPolicy) == 1) {\r
684 Status = MeasureCRTMVersion (PeiServices, TpmHandle);\r
685 ASSERT_EFI_ERROR (Status);\r
686 }\r
0c18794e 687\r
688 Status = MeasureMainBios (PeiServices, TpmHandle);\r
689 } \r
690\r
691 //\r
692 // Post callbacks:\r
693 // 1). for the FvInfoPpi services to measure and record\r
694 // the additional Fvs to TPM\r
695 // 2). for the OperatorPresencePpi service to determine whether to \r
696 // lock the TPM\r
697 //\r
698 Status = PeiServicesNotifyPpi (&mNotifyList[0]);\r
699 ASSERT_EFI_ERROR (Status);\r
700\r
701 return Status;\r
702}\r
703\r
704/**\r
705 Entry point of this module.\r
706\r
707 @param[in] FileHandle Handle of the file being invoked.\r
708 @param[in] PeiServices Describes the list of possible PEI Services.\r
709\r
710 @return Status.\r
711\r
712**/\r
713EFI_STATUS\r
714EFIAPI\r
715PeimEntryMA (\r
716 IN EFI_PEI_FILE_HANDLE FileHandle,\r
717 IN CONST EFI_PEI_SERVICES **PeiServices\r
718 )\r
719{\r
720 EFI_STATUS Status;\r
721 EFI_BOOT_MODE BootMode;\r
722 TIS_TPM_HANDLE TpmHandle;\r
723\r
c1d93242
JY
724 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
725 DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));\r
726 return EFI_UNSUPPORTED;\r
727 }\r
728\r
055c829c 729 //\r
730 // Initialize TPM device\r
731 //\r
732 Status = PeiServicesGetBootMode (&BootMode);\r
733 ASSERT_EFI_ERROR (Status);\r
734\r
735 //\r
736 // In S3 path, skip shadow logic. no measurement is required\r
737 //\r
738 if (BootMode != BOOT_ON_S3_RESUME) {\r
739 Status = (**PeiServices).RegisterForShadow(FileHandle);\r
740 if (Status == EFI_ALREADY_STARTED) {\r
741 mImageInMemory = TRUE;\r
742 } else if (Status == EFI_NOT_FOUND) {\r
743 ASSERT_EFI_ERROR (Status);\r
744 }\r
0c18794e 745 }\r
746\r
747 if (!mImageInMemory) {\r
0c18794e 748 TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
749 Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);\r
750 if (EFI_ERROR (Status)) {\r
751 DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));\r
752 return Status;\r
753 }\r
754\r
c1d93242
JY
755 if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {\r
756 Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);\r
757 if (EFI_ERROR (Status) ) {\r
758 return Status;\r
759 }\r
0c18794e 760 }\r
6f6c7857 761\r
762 //\r
763 // TpmSelfTest is optional on S3 path, skip it to save S3 time\r
764 //\r
765 if (BootMode != BOOT_ON_S3_RESUME) {\r
766 Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);\r
767 if (EFI_ERROR (Status)) {\r
768 return Status;\r
769 }\r
0c18794e 770 }\r
6f6c7857 771\r
0c18794e 772 Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);\r
773 ASSERT_EFI_ERROR (Status);\r
774 }\r
775\r
776 if (mImageInMemory) {\r
777 Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);\r
778 if (EFI_ERROR (Status)) {\r
779 return Status;\r
780 }\r
781 }\r
782\r
783 return Status;\r
784}\r