]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/TcgPei/TcgPei.c
ArmPlatformPkg/ArmVExpressPkg: Update the Runtime Code and Data number of pages
[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
464\r
465 Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;\r
466\r
467 //\r
468 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.\r
469 //\r
470 Status = PeiServicesLocatePpi (\r
471 &Fv->FvFormat, \r
472 0, \r
473 NULL,\r
474 (VOID**)&FvPpi\r
475 );\r
476 if (EFI_ERROR (Status)) {\r
477 return EFI_SUCCESS;\r
478 }\r
479 \r
480 //\r
481 // This is an FV from an FFS file, and the parent FV must have already been measured,\r
2aadc920 482 // No need to measure twice, so just record the FV and return\r
0c18794e 483 //\r
484 if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {\r
2aadc920 485 \r
486 ASSERT (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
487 if (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
488 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;\r
489 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;\r
490 mMeasuredChildFvIndex++;\r
491 }\r
0c18794e 492 return EFI_SUCCESS;\r
493 }\r
494\r
495 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);\r
496}\r
497\r
498/**\r
5a500332 499 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.\r
500 And lock physical presence if needed.\r
0c18794e 501\r
502 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
503 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
504 @param[in] Ppi Address of the PPI that was installed.\r
505\r
506 @retval EFI_SUCCESS Operation completed successfully.\r
507 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.\r
508 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
509\r
510**/\r
511EFI_STATUS\r
512EFIAPI\r
513PhysicalPresencePpiNotifyCallback (\r
514 IN EFI_PEI_SERVICES **PeiServices,\r
515 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
516 IN VOID *Ppi\r
517 )\r
518{\r
519 EFI_STATUS Status;\r
520 PEI_LOCK_PHYSICAL_PRESENCE_PPI *LockPhysicalPresencePpi;\r
521 BOOLEAN LifetimeLock;\r
522 BOOLEAN CmdEnable;\r
523 TIS_TPM_HANDLE TpmHandle;\r
5a500332 524 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue;\r
0c18794e 525\r
526 TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;\r
0c18794e 527\r
5a500332 528 Status = TpmCommGetCapability (PeiServices, TpmHandle, NULL, &LifetimeLock, &CmdEnable);\r
529 if (EFI_ERROR (Status)) {\r
530 return Status;\r
0c18794e 531 }\r
532\r
533 //\r
5a500332 534 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.\r
0c18794e 535 //\r
5a500332 536 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !LifetimeLock) {\r
537 //\r
538 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet. \r
539 //\r
540 PhysicalPresenceValue = TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK;\r
541\r
542 if (PcdGetBool (PcdPhysicalPresenceCmdEnable)) {\r
543 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_ENABLE;\r
544 CmdEnable = TRUE;\r
545 } else {\r
546 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_DISABLE;\r
547 CmdEnable = FALSE;\r
548 }\r
0c18794e 549\r
5a500332 550 if (PcdGetBool (PcdPhysicalPresenceHwEnable)) {\r
551 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_ENABLE;\r
552 } else {\r
553 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_DISABLE;\r
554 } \r
555 \r
556 Status = TpmCommPhysicalPresence (\r
557 PeiServices,\r
558 TpmHandle,\r
559 PhysicalPresenceValue\r
560 );\r
561 if (EFI_ERROR (Status)) {\r
562 return Status;\r
563 }\r
564 }\r
565 \r
566 //\r
567 // 2. Lock physical presence if it is required.\r
568 //\r
569 LockPhysicalPresencePpi = (PEI_LOCK_PHYSICAL_PRESENCE_PPI *) Ppi;\r
570 if (!LockPhysicalPresencePpi->LockPhysicalPresence ((CONST EFI_PEI_SERVICES**) PeiServices)) {\r
571 return EFI_SUCCESS;\r
0c18794e 572 }\r
573\r
574 if (!CmdEnable) {\r
575 if (LifetimeLock) {\r
576 //\r
577 // physicalPresenceCMDEnable is locked, can't change.\r
578 //\r
579 return EFI_ABORTED;\r
580 }\r
581\r
582 //\r
583 // Enable physical presence command\r
584 // It is necessary in order to lock physical presence\r
585 //\r
586 Status = TpmCommPhysicalPresence (\r
587 PeiServices,\r
588 TpmHandle,\r
589 TPM_PHYSICAL_PRESENCE_CMD_ENABLE\r
590 );\r
591 if (EFI_ERROR (Status)) {\r
592 return Status;\r
593 }\r
594 }\r
595\r
596 //\r
597 // Lock physical presence\r
598 // \r
599 Status = TpmCommPhysicalPresence (\r
600 PeiServices,\r
601 TpmHandle,\r
602 TPM_PHYSICAL_PRESENCE_LOCK\r
603 );\r
604 return Status;\r
605}\r
606\r
607/**\r
608 Check if TPM chip is activeated or not.\r
609\r
610 @param[in] PeiServices Describes the list of possible PEI Services.\r
611 @param[in] TpmHandle TPM handle.\r
612\r
613 @retval TRUE TPM is activated.\r
614 @retval FALSE TPM is deactivated.\r
615\r
616**/\r
617BOOLEAN\r
618EFIAPI\r
619IsTpmUsable (\r
620 IN EFI_PEI_SERVICES **PeiServices,\r
621 IN TIS_TPM_HANDLE TpmHandle\r
622 )\r
623{\r
624 EFI_STATUS Status;\r
625 BOOLEAN Deactivated;\r
626\r
627 Status = TpmCommGetCapability (PeiServices, TpmHandle, &Deactivated, NULL, NULL);\r
628 if (EFI_ERROR (Status)) {\r
629 return FALSE;\r
630 }\r
631 return (BOOLEAN)(!Deactivated); \r
632}\r
633\r
634/**\r
635 Do measurement after memory is ready.\r
636\r
637 @param[in] PeiServices Describes the list of possible PEI Services.\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
645EFIAPI\r
646PeimEntryMP (\r
647 IN EFI_PEI_SERVICES **PeiServices\r
648 )\r
649{\r
650 EFI_STATUS Status;\r
651 TIS_TPM_HANDLE TpmHandle;\r
652\r
c1d93242
JY
653 Status = PeiServicesLocatePpi (\r
654 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, \r
655 0, \r
656 NULL,\r
657 (VOID**)&mMeasurementExcludedFvPpi\r
658 );\r
659 // Do not check status, because it is optional\r
660\r
0c18794e 661 TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
662 Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);\r
663 if (EFI_ERROR (Status)) {\r
664 return Status;\r
665 }\r
666\r
667 if (IsTpmUsable (PeiServices, TpmHandle)) {\r
c1d93242
JY
668 if (PcdGet8 (PcdTpmScrtmPolicy) == 1) {\r
669 Status = MeasureCRTMVersion (PeiServices, TpmHandle);\r
670 ASSERT_EFI_ERROR (Status);\r
671 }\r
0c18794e 672\r
673 Status = MeasureMainBios (PeiServices, TpmHandle);\r
674 } \r
675\r
676 //\r
677 // Post callbacks:\r
678 // 1). for the FvInfoPpi services to measure and record\r
679 // the additional Fvs to TPM\r
680 // 2). for the OperatorPresencePpi service to determine whether to \r
681 // lock the TPM\r
682 //\r
683 Status = PeiServicesNotifyPpi (&mNotifyList[0]);\r
684 ASSERT_EFI_ERROR (Status);\r
685\r
686 return Status;\r
687}\r
688\r
689/**\r
690 Entry point of this module.\r
691\r
692 @param[in] FileHandle Handle of the file being invoked.\r
693 @param[in] PeiServices Describes the list of possible PEI Services.\r
694\r
695 @return Status.\r
696\r
697**/\r
698EFI_STATUS\r
699EFIAPI\r
700PeimEntryMA (\r
701 IN EFI_PEI_FILE_HANDLE FileHandle,\r
702 IN CONST EFI_PEI_SERVICES **PeiServices\r
703 )\r
704{\r
705 EFI_STATUS Status;\r
706 EFI_BOOT_MODE BootMode;\r
707 TIS_TPM_HANDLE TpmHandle;\r
708\r
c1d93242
JY
709 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
710 DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));\r
711 return EFI_UNSUPPORTED;\r
712 }\r
713\r
055c829c 714 //\r
715 // Initialize TPM device\r
716 //\r
717 Status = PeiServicesGetBootMode (&BootMode);\r
718 ASSERT_EFI_ERROR (Status);\r
719\r
720 //\r
721 // In S3 path, skip shadow logic. no measurement is required\r
722 //\r
723 if (BootMode != BOOT_ON_S3_RESUME) {\r
724 Status = (**PeiServices).RegisterForShadow(FileHandle);\r
725 if (Status == EFI_ALREADY_STARTED) {\r
726 mImageInMemory = TRUE;\r
727 } else if (Status == EFI_NOT_FOUND) {\r
728 ASSERT_EFI_ERROR (Status);\r
729 }\r
0c18794e 730 }\r
731\r
732 if (!mImageInMemory) {\r
0c18794e 733 TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
734 Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);\r
735 if (EFI_ERROR (Status)) {\r
736 DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));\r
737 return Status;\r
738 }\r
739\r
c1d93242
JY
740 if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {\r
741 Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);\r
742 if (EFI_ERROR (Status) ) {\r
743 return Status;\r
744 }\r
0c18794e 745 }\r
6f6c7857 746\r
747 //\r
748 // TpmSelfTest is optional on S3 path, skip it to save S3 time\r
749 //\r
750 if (BootMode != BOOT_ON_S3_RESUME) {\r
751 Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);\r
752 if (EFI_ERROR (Status)) {\r
753 return Status;\r
754 }\r
0c18794e 755 }\r
6f6c7857 756\r
0c18794e 757 Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);\r
758 ASSERT_EFI_ERROR (Status);\r
759 }\r
760\r
761 if (mImageInMemory) {\r
762 Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);\r
763 if (EFI_ERROR (Status)) {\r
764 return Status;\r
765 }\r
766 }\r
767\r
768 return Status;\r
769}\r