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