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