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