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