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