TianoCore EDK2 master
Loading...
Searching...
No Matches
DxeTpm2MeasureBootLib.c
Go to the documentation of this file.
1
27#include <PiDxe.h>
28
30#include <Protocol/BlockIo.h>
31#include <Protocol/DiskIo.h>
34
35#include <Guid/MeasuredFvHob.h>
36
37#include <Library/BaseLib.h>
38#include <Library/DebugLib.h>
44#include <Library/PeCoffLib.h>
46#include <Library/HobLib.h>
48
50
51typedef struct {
52 EFI_TCG2_PROTOCOL *Tcg2Protocol;
55
56//
57// Flag to check GPT partition. It only need be measured once.
58//
59BOOLEAN mTcg2MeasureGptTableFlag = FALSE;
60UINTN mTcg2MeasureGptCount = 0;
61VOID *mTcg2FileBuffer;
62UINTN mTcg2ImageSize;
63//
64// Measured FV handle cache
65//
66EFI_HANDLE mTcg2CacheMeasuredHandle = NULL;
67MEASURED_HOB_DATA *mTcg2MeasuredHobData = NULL;
68
85EFIAPI
87 IN VOID *FileHandle,
88 IN UINTN FileOffset,
89 IN OUT UINTN *ReadSize,
90 OUT VOID *Buffer
91 )
92{
93 UINTN EndPosition;
94
95 if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) {
96 return EFI_INVALID_PARAMETER;
97 }
98
99 if (MAX_ADDRESS - FileOffset < *ReadSize) {
100 return EFI_INVALID_PARAMETER;
101 }
102
103 EndPosition = FileOffset + *ReadSize;
104 if (EndPosition > mTcg2ImageSize) {
105 *ReadSize = (UINT32)(mTcg2ImageSize - FileOffset);
106 }
107
108 if (FileOffset >= mTcg2ImageSize) {
109 *ReadSize = 0;
110 }
111
112 CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize);
113
114 return EFI_SUCCESS;
115}
116
133EFIAPI
135 IN MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols,
136 IN EFI_HANDLE GptHandle
137 )
138{
139 EFI_STATUS Status;
140 EFI_BLOCK_IO_PROTOCOL *BlockIo;
141 EFI_DISK_IO_PROTOCOL *DiskIo;
142 EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
143 EFI_PARTITION_ENTRY *PartitionEntry;
144 UINT8 *EntryPtr;
145 UINTN NumberOfPartition;
146 UINT32 Index;
147 UINT8 *EventPtr;
148 EFI_TCG2_EVENT *Tcg2Event;
149 EFI_CC_EVENT *CcEvent;
150 EFI_GPT_DATA *GptData;
151 UINT32 TcgEventSize;
152 EFI_TCG2_PROTOCOL *Tcg2Protocol;
153 EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;
154 EFI_CC_MR_INDEX MrIndex;
155 UINT32 AllocSize;
156
157 if (mTcg2MeasureGptCount > 0) {
158 return EFI_SUCCESS;
159 }
160
161 PrimaryHeader = NULL;
162 EntryPtr = NULL;
163 EventPtr = NULL;
164
165 Tcg2Protocol = MeasureBootProtocols->Tcg2Protocol;
166 CcProtocol = MeasureBootProtocols->CcProtocol;
167
168 if ((Tcg2Protocol == NULL) && (CcProtocol == NULL)) {
169 ASSERT (FALSE);
170 return EFI_UNSUPPORTED;
171 }
172
173 if (sizeof (EFI_CC_EVENT) != sizeof (EFI_TCG2_EVENT)) {
174 ASSERT (FALSE);
175 return EFI_UNSUPPORTED;
176 }
177
178 Status = gBS->HandleProtocol (GptHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
179 if (EFI_ERROR (Status)) {
180 return EFI_UNSUPPORTED;
181 }
182
183 Status = gBS->HandleProtocol (GptHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
184 if (EFI_ERROR (Status)) {
185 return EFI_UNSUPPORTED;
186 }
187
188 //
189 // Read the EFI Partition Table Header
190 //
191 PrimaryHeader = (EFI_PARTITION_TABLE_HEADER *)AllocatePool (BlockIo->Media->BlockSize);
192 if (PrimaryHeader == NULL) {
193 return EFI_OUT_OF_RESOURCES;
194 }
195
196 Status = DiskIo->ReadDisk (
197 DiskIo,
198 BlockIo->Media->MediaId,
199 1 * BlockIo->Media->BlockSize,
200 BlockIo->Media->BlockSize,
201 (UINT8 *)PrimaryHeader
202 );
203 if (EFI_ERROR (Status) || EFI_ERROR (Tpm2SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) {
204 DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n"));
205 FreePool (PrimaryHeader);
206 return EFI_DEVICE_ERROR;
207 }
208
209 //
210 // Read the partition entry.
211 //
212 Status = Tpm2SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize);
213 if (EFI_ERROR (Status)) {
214 FreePool (PrimaryHeader);
215 return EFI_BAD_BUFFER_SIZE;
216 }
217
218 EntryPtr = (UINT8 *)AllocatePool (AllocSize);
219 if (EntryPtr == NULL) {
220 FreePool (PrimaryHeader);
221 return EFI_OUT_OF_RESOURCES;
222 }
223
224 Status = DiskIo->ReadDisk (
225 DiskIo,
226 BlockIo->Media->MediaId,
227 MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
228 AllocSize,
229 EntryPtr
230 );
231 if (EFI_ERROR (Status)) {
232 FreePool (PrimaryHeader);
233 FreePool (EntryPtr);
234 return EFI_DEVICE_ERROR;
235 }
236
237 //
238 // Count the valid partition
239 //
240 PartitionEntry = (EFI_PARTITION_ENTRY *)EntryPtr;
241 NumberOfPartition = 0;
242 for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
243 if (!IsZeroGuid (&PartitionEntry->PartitionTypeGUID)) {
244 NumberOfPartition++;
245 }
246
247 PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);
248 }
249
250 //
251 // Prepare Data for Measurement (CcProtocol and Tcg2Protocol)
252 //
253 Status = Tpm2SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize);
254 if (EFI_ERROR (Status)) {
255 FreePool (PrimaryHeader);
256 FreePool (EntryPtr);
257 return EFI_DEVICE_ERROR;
258 }
259
260 EventPtr = (UINT8 *)AllocateZeroPool (TcgEventSize);
261 if (EventPtr == NULL) {
262 Status = EFI_OUT_OF_RESOURCES;
263 goto Exit;
264 }
265
266 Tcg2Event = (EFI_TCG2_EVENT *)EventPtr;
267 Tcg2Event->Size = TcgEventSize;
268 Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
269 Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
270 Tcg2Event->Header.PCRIndex = 5;
271 Tcg2Event->Header.EventType = EV_EFI_GPT_EVENT;
272 GptData = (EFI_GPT_DATA *)Tcg2Event->Event;
273
274 //
275 // Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition
276 //
277 CopyMem ((UINT8 *)GptData, (UINT8 *)PrimaryHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
278 GptData->NumberOfPartitions = NumberOfPartition;
279 //
280 // Copy the valid partition entry
281 //
282 PartitionEntry = (EFI_PARTITION_ENTRY *)EntryPtr;
283 NumberOfPartition = 0;
284 for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
285 if (!IsZeroGuid (&PartitionEntry->PartitionTypeGUID)) {
286 CopyMem (
287 (UINT8 *)&GptData->Partitions + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry,
288 (UINT8 *)PartitionEntry,
289 PrimaryHeader->SizeOfPartitionEntry
290 );
291 NumberOfPartition++;
292 }
293
294 PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);
295 }
296
297 //
298 // Only one of TCG2_PROTOCOL or CC_MEASUREMENT_PROTOCOL is exposed.
299 // So Measure the GPT data with one of the protocol.
300 //
301 if (CcProtocol != NULL) {
302 //
303 // EFI_CC_EVENT share the same data structure with EFI_TCG2_EVENT
304 // except the MrIndex and PCRIndex in Header.
305 // Tcg2Event has been created and initialized before. So only the MrIndex need
306 // be adjusted.
307 //
308 Status = CcProtocol->MapPcrToMrIndex (CcProtocol, Tcg2Event->Header.PCRIndex, &MrIndex);
309 if (EFI_ERROR (Status)) {
310 DEBUG ((DEBUG_ERROR, "Cannot map PcrIndex(%d) to MrIndex\n", Tcg2Event->Header.PCRIndex));
311 goto Exit;
312 }
313
314 CcEvent = (EFI_CC_EVENT *)EventPtr;
315 CcEvent->Header.MrIndex = MrIndex;
316 Status = CcProtocol->HashLogExtendEvent (
317 CcProtocol,
318 0,
319 (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData,
320 (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event),
321 CcEvent
322 );
323 if (!EFI_ERROR (Status)) {
324 mTcg2MeasureGptCount++;
325 }
326
327 DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - Cc MeasureGptTable - %r\n", Status));
328 } else if (Tcg2Protocol != NULL) {
329 //
330 // If Tcg2Protocol is installed, then Measure GPT data with this protocol.
331 //
332 Status = Tcg2Protocol->HashLogExtendEvent (
333 Tcg2Protocol,
334 0,
335 (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData,
336 (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event),
337 Tcg2Event
338 );
339 if (!EFI_ERROR (Status)) {
340 mTcg2MeasureGptCount++;
341 }
342
343 DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - Tcg2 MeasureGptTable - %r\n", Status));
344 }
345
346Exit:
347 if (PrimaryHeader != NULL) {
348 FreePool (PrimaryHeader);
349 }
350
351 if (EntryPtr != NULL) {
352 FreePool (EntryPtr);
353 }
354
355 if (EventPtr != NULL) {
356 FreePool (EventPtr);
357 }
358
359 return Status;
360}
361
383EFIAPI
385 IN MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols,
386 IN EFI_PHYSICAL_ADDRESS ImageAddress,
387 IN UINTN ImageSize,
388 IN UINTN LinkTimeBase,
389 IN UINT16 ImageType,
391 )
392{
393 EFI_STATUS Status;
394 EFI_TCG2_EVENT *Tcg2Event;
395 EFI_IMAGE_LOAD_EVENT *ImageLoad;
396 UINT32 FilePathSize;
397 UINT32 EventSize;
398 EFI_CC_EVENT *CcEvent;
399 EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;
400 EFI_TCG2_PROTOCOL *Tcg2Protocol;
401 UINT8 *EventPtr;
402 EFI_CC_MR_INDEX MrIndex;
403
404 Status = EFI_UNSUPPORTED;
405 ImageLoad = NULL;
406 EventPtr = NULL;
407 Tcg2Event = NULL;
408
409 Tcg2Protocol = MeasureBootProtocols->Tcg2Protocol;
410 CcProtocol = MeasureBootProtocols->CcProtocol;
411
412 if ((Tcg2Protocol == NULL) && (CcProtocol == NULL)) {
413 ASSERT (FALSE);
414 return EFI_UNSUPPORTED;
415 }
416
417 if (sizeof (EFI_CC_EVENT) != sizeof (EFI_TCG2_EVENT)) {
418 ASSERT (FALSE);
419 return EFI_UNSUPPORTED;
420 }
421
422 FilePathSize = (UINT32)GetDevicePathSize (FilePath);
423 Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize);
424 if (EFI_ERROR (Status)) {
425 return EFI_UNSUPPORTED;
426 }
427
428 //
429 // Determine destination PCR by BootPolicy
430 //
431 // from a malicious GPT disk partition
432 EventPtr = AllocateZeroPool (EventSize);
433 if (EventPtr == NULL) {
434 return EFI_OUT_OF_RESOURCES;
435 }
436
437 Tcg2Event = (EFI_TCG2_EVENT *)EventPtr;
438 Tcg2Event->Size = EventSize;
439 Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
440 Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
441 ImageLoad = (EFI_IMAGE_LOAD_EVENT *)Tcg2Event->Event;
442
443 switch (ImageType) {
444 case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
445 Tcg2Event->Header.EventType = EV_EFI_BOOT_SERVICES_APPLICATION;
446 Tcg2Event->Header.PCRIndex = 4;
447 break;
448 case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
449 Tcg2Event->Header.EventType = EV_EFI_BOOT_SERVICES_DRIVER;
450 Tcg2Event->Header.PCRIndex = 2;
451 break;
452 case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
453 Tcg2Event->Header.EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;
454 Tcg2Event->Header.PCRIndex = 2;
455 break;
456 default:
457 DEBUG (
458 (
459 DEBUG_ERROR,
460 "Tcg2MeasurePeImage: Unknown subsystem type %d",
461 ImageType
462 )
463 );
464 goto Finish;
465 }
466
467 ImageLoad->ImageLocationInMemory = ImageAddress;
468 ImageLoad->ImageLengthInMemory = ImageSize;
469 ImageLoad->ImageLinkTimeAddress = LinkTimeBase;
470 ImageLoad->LengthOfDevicePath = FilePathSize;
471 if ((FilePath != NULL) && (FilePathSize != 0)) {
472 CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
473 }
474
475 //
476 // Log the PE data
477 //
478 if (CcProtocol != NULL) {
479 Status = CcProtocol->MapPcrToMrIndex (CcProtocol, Tcg2Event->Header.PCRIndex, &MrIndex);
480 if (EFI_ERROR (Status)) {
481 DEBUG ((DEBUG_ERROR, "Cannot map PcrIndex(%d) to MrIndex\n", Tcg2Event->Header.PCRIndex));
482 goto Finish;
483 }
484
485 CcEvent = (EFI_CC_EVENT *)EventPtr;
486 CcEvent->Header.MrIndex = MrIndex;
487
488 Status = CcProtocol->HashLogExtendEvent (
489 CcProtocol,
490 PE_COFF_IMAGE,
491 ImageAddress,
492 ImageSize,
493 CcEvent
494 );
495 DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - Cc MeasurePeImage - %r\n", Status));
496 } else if (Tcg2Protocol != NULL) {
497 Status = Tcg2Protocol->HashLogExtendEvent (
498 Tcg2Protocol,
499 PE_COFF_IMAGE,
500 ImageAddress,
501 ImageSize,
502 Tcg2Event
503 );
504 DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - Tcg2 MeasurePeImage - %r\n", Status));
505 }
506
507 if (Status == EFI_VOLUME_FULL) {
508 //
509 // Volume full here means the image is hashed and its result is extended to PCR.
510 // But the event log can't be saved since log area is full.
511 // Just return EFI_SUCCESS in order not to block the image load.
512 //
513 Status = EFI_SUCCESS;
514 }
515
516Finish:
517 if (EventPtr != NULL) {
518 FreePool (EventPtr);
519 }
520
521 return Status;
522}
523
535EFIAPI
537 MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols
538 )
539{
540 EFI_STATUS Status;
541 EFI_TCG2_PROTOCOL *Tcg2Protocol;
542 EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;
543 EFI_TCG2_BOOT_SERVICE_CAPABILITY Tcg2ProtocolCapability;
544 EFI_CC_BOOT_SERVICE_CAPABILITY CcProtocolCapability;
545
546 CcProtocol = NULL;
547 Status = gBS->LocateProtocol (&gEfiCcMeasurementProtocolGuid, NULL, (VOID **)&CcProtocol);
548 if (EFI_ERROR (Status)) {
549 //
550 // Cc Measurement protocol is not installed.
551 //
552 DEBUG ((DEBUG_VERBOSE, "CcMeasurementProtocol is not installed. - %r\n", Status));
553 } else {
554 ZeroMem (&CcProtocolCapability, sizeof (CcProtocolCapability));
555 CcProtocolCapability.Size = sizeof (CcProtocolCapability);
556 Status = CcProtocol->GetCapability (CcProtocol, &CcProtocolCapability);
557 if (EFI_ERROR (Status) || (CcProtocolCapability.CcType.Type == EFI_CC_TYPE_NONE)) {
558 DEBUG ((DEBUG_ERROR, " CcProtocol->GetCapability returns : %x, %r\n", CcProtocolCapability.CcType.Type, Status));
559 CcProtocol = NULL;
560 }
561 }
562
563 Tcg2Protocol = NULL;
564 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);
565 if (EFI_ERROR (Status)) {
566 //
567 // Tcg2 protocol is not installed. So, TPM2 is not present.
568 //
569 DEBUG ((DEBUG_VERBOSE, "Tcg2Protocol is not installed. - %r\n", Status));
570 } else {
571 Tcg2ProtocolCapability.Size = (UINT8)sizeof (Tcg2ProtocolCapability);
572 Status = Tcg2Protocol->GetCapability (Tcg2Protocol, &Tcg2ProtocolCapability);
573 if (EFI_ERROR (Status) || (!Tcg2ProtocolCapability.TPMPresentFlag)) {
574 //
575 // TPM device doesn't work or activate.
576 //
577 DEBUG ((DEBUG_ERROR, "TPMPresentFlag=FALSE %r\n", Status));
578 Tcg2Protocol = NULL;
579 }
580 }
581
582 MeasureBootProtocols->Tcg2Protocol = Tcg2Protocol;
583 MeasureBootProtocols->CcProtocol = CcProtocol;
584
585 return (Tcg2Protocol == NULL && CcProtocol == NULL) ? EFI_UNSUPPORTED : EFI_SUCCESS;
586}
587
627EFIAPI
629 IN UINT32 AuthenticationStatus,
630 IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL,
631 IN VOID *FileBuffer,
632 IN UINTN FileSize,
633 IN BOOLEAN BootPolicy
634 )
635{
636 MEASURE_BOOT_PROTOCOLS MeasureBootProtocols;
637 EFI_STATUS Status;
638 EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
639 EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;
640 EFI_HANDLE Handle;
641 EFI_HANDLE TempHandle;
642 BOOLEAN ApplicationRequired;
643 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
645 EFI_PHYSICAL_ADDRESS FvAddress;
646 UINT32 Index;
647
648 MeasureBootProtocols.Tcg2Protocol = NULL;
649 MeasureBootProtocols.CcProtocol = NULL;
650
651 Status = GetMeasureBootProtocols (&MeasureBootProtocols);
652
653 if (EFI_ERROR (Status)) {
654 //
655 // None of Measured boot protocols (Tcg2, Cc) is installed.
656 // Don't do any measurement, and directly return EFI_SUCCESS.
657 //
658 DEBUG ((DEBUG_INFO, "None of Tcg2Protocol/CcMeasurementProtocol is installed.\n"));
659 return EFI_SUCCESS;
660 }
661
662 DEBUG (
663 (
664 DEBUG_INFO,
665 "Tcg2Protocol = %p, CcMeasurementProtocol = %p\n",
666 MeasureBootProtocols.Tcg2Protocol,
667 MeasureBootProtocols.CcProtocol
668 )
669 );
670
671 //
672 // Copy File Device Path
673 //
674 OrigDevicePathNode = DuplicateDevicePath (File);
675
676 //
677 // 1. Check whether this device path support BlockIo protocol.
678 // Is so, this device path may be a GPT device path.
679 //
680 DevicePathNode = OrigDevicePathNode;
681 Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);
682 if (!EFI_ERROR (Status) && !mTcg2MeasureGptTableFlag) {
683 //
684 // Find the gpt partition on the given devicepath
685 //
686 DevicePathNode = OrigDevicePathNode;
687 ASSERT (DevicePathNode != NULL);
688 while (!IsDevicePathEnd (DevicePathNode)) {
689 //
690 // Find the Gpt partition
691 //
692 if ((DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) &&
693 (DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP))
694 {
695 //
696 // Check whether it is a gpt partition or not
697 //
698 if ((((HARDDRIVE_DEVICE_PATH *)DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER) &&
699 (((HARDDRIVE_DEVICE_PATH *)DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID))
700 {
701 //
702 // Change the partition device path to its parent device path (disk) and get the handle.
703 //
704 DevicePathNode->Type = END_DEVICE_PATH_TYPE;
705 DevicePathNode->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
706 DevicePathNode = OrigDevicePathNode;
707 Status = gBS->LocateDevicePath (
708 &gEfiDiskIoProtocolGuid,
709 &DevicePathNode,
710 &Handle
711 );
712 if (!EFI_ERROR (Status)) {
713 //
714 // Measure GPT disk.
715 //
716 Status = Tcg2MeasureGptTable (&MeasureBootProtocols, Handle);
717
718 if (!EFI_ERROR (Status)) {
719 //
720 // GPT disk check done.
721 //
722 mTcg2MeasureGptTableFlag = TRUE;
723 }
724 }
725
726 FreePool (OrigDevicePathNode);
727 OrigDevicePathNode = DuplicateDevicePath (File);
728 ASSERT (OrigDevicePathNode != NULL);
729 break;
730 }
731 }
732
733 DevicePathNode = NextDevicePathNode (DevicePathNode);
734 }
735 }
736
737 //
738 // 2. Measure PE image.
739 //
740 ApplicationRequired = FALSE;
741
742 //
743 // Check whether this device path support FVB protocol.
744 //
745 DevicePathNode = OrigDevicePathNode;
746 Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle);
747 if (!EFI_ERROR (Status)) {
748 //
749 // Don't check FV image, and directly return EFI_SUCCESS.
750 // It can be extended to the specific FV authentication according to the different requirement.
751 //
752 if (IsDevicePathEnd (DevicePathNode)) {
753 return EFI_SUCCESS;
754 }
755
756 //
757 // The PE image from unmeasured Firmware volume need be measured
758 // The PE image from measured Firmware volume will be measured according to policy below.
759 // If it is driver, do not measure
760 // If it is application, still measure.
761 //
762 ApplicationRequired = TRUE;
763
764 if ((mTcg2CacheMeasuredHandle != Handle) && (mTcg2MeasuredHobData != NULL)) {
765 //
766 // Search for Root FV of this PE image
767 //
768 TempHandle = Handle;
769 do {
770 Status = gBS->HandleProtocol (
771 TempHandle,
772 &gEfiFirmwareVolumeBlockProtocolGuid,
773 (VOID **)&FvbProtocol
774 );
775 TempHandle = FvbProtocol->ParentHandle;
776 } while (!EFI_ERROR (Status) && FvbProtocol->ParentHandle != NULL);
777
778 //
779 // Search in measured FV Hob
780 //
781 Status = FvbProtocol->GetPhysicalAddress (FvbProtocol, &FvAddress);
782 if (EFI_ERROR (Status)) {
783 return Status;
784 }
785
786 ApplicationRequired = FALSE;
787
788 for (Index = 0; Index < mTcg2MeasuredHobData->Num; Index++) {
789 if (mTcg2MeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) {
790 //
791 // Cache measured FV for next measurement
792 //
793 mTcg2CacheMeasuredHandle = Handle;
794 ApplicationRequired = TRUE;
795 break;
796 }
797 }
798 }
799 }
800
801 //
802 // File is not found.
803 //
804 if (FileBuffer == NULL) {
805 Status = EFI_SECURITY_VIOLATION;
806 goto Finish;
807 }
808
809 mTcg2ImageSize = FileSize;
810 mTcg2FileBuffer = FileBuffer;
811
812 //
813 // Measure PE Image
814 //
815 DevicePathNode = OrigDevicePathNode;
816 ZeroMem (&ImageContext, sizeof (ImageContext));
817 ImageContext.Handle = (VOID *)FileBuffer;
819
820 //
821 // Get information about the image being loaded
822 //
823 Status = PeCoffLoaderGetImageInfo (&ImageContext);
824 if (EFI_ERROR (Status)) {
825 //
826 // Check for invalid parameters.
827 //
828 if (File == NULL) {
829 Status = EFI_ACCESS_DENIED;
830 }
831
832 //
833 // The information can't be got from the invalid PeImage
834 //
835 goto Finish;
836 }
837
838 //
839 // Measure only application if Application flag is set
840 // Measure drivers and applications if Application flag is not set
841 //
842 if ((!ApplicationRequired) ||
843 (ApplicationRequired && (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)))
844 {
845 //
846 // Print the image path to be measured.
847 //
849 CHAR16 *ToText;
850 ToText = ConvertDevicePathToText (
851 DevicePathNode,
852 FALSE,
853 TRUE
854 );
855 if (ToText != NULL) {
856 DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText));
857 FreePool (ToText);
858 }
859
861
862 //
863 // Measure PE image into TPM log.
864 //
865 Status = Tcg2MeasurePeImage (
866 &MeasureBootProtocols,
867 (EFI_PHYSICAL_ADDRESS)(UINTN)FileBuffer,
868 FileSize,
869 (UINTN)ImageContext.ImageAddress,
870 ImageContext.ImageType,
871 DevicePathNode
872 );
873 }
874
875 //
876 // Done, free the allocated resource.
877 //
878Finish:
879 if (OrigDevicePathNode != NULL) {
880 FreePool (OrigDevicePathNode);
881 }
882
883 DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - %r\n", Status));
884
885 return Status;
886}
887
898EFIAPI
900 IN EFI_HANDLE ImageHandle,
901 IN EFI_SYSTEM_TABLE *SystemTable
902 )
903{
904 EFI_HOB_GUID_TYPE *GuidHob;
905
906 GuidHob = NULL;
907
908 GuidHob = GetFirstGuidHob (&gMeasuredFvHobGuid);
909
910 if (GuidHob != NULL) {
911 mTcg2MeasuredHobData = GET_GUID_HOB_DATA (GuidHob);
912 }
913
916 EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED
917 );
918}
UINT64 UINTN
#define MAX_ADDRESS
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI IsZeroGuid(IN CONST GUID *Guid)
Definition: MemLibGuid.c:156
#define MEDIA_HARDDRIVE_DP
Definition: DevicePath.h:1014
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_STATUS EFIAPI Tcg2MeasureGptTable(IN MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols, IN EFI_HANDLE GptHandle)
EFI_STATUS EFIAPI DxeTpm2MeasureBootLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI DxeTpm2MeasureBootHandler(IN UINT32 AuthenticationStatus, IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL, IN VOID *FileBuffer, IN UINTN FileSize, IN BOOLEAN BootPolicy)
EFI_STATUS EFIAPI GetMeasureBootProtocols(MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols)
EFI_STATUS EFIAPI Tcg2MeasurePeImage(IN MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols, IN EFI_PHYSICAL_ADDRESS ImageAddress, IN UINTN ImageSize, IN UINTN LinkTimeBase, IN UINT16 ImageType, IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
EFI_STATUS EFIAPI DxeTpm2MeasureBootLibImageRead(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
EFI_STATUS EFIAPI Tpm2SanitizeEfiPartitionTableHeader(IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo)
EFI_STATUS EFIAPI Tpm2SanitizePrimaryHeaderAllocationSize(IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, OUT UINT32 *AllocationSize)
EFI_STATUS Tpm2SanitizePeImageEventSize(IN UINT32 FilePathSize, OUT UINT32 *EventSize)
EFI_STATUS Tpm2SanitizePrimaryHeaderGptEventSize(IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, IN UINTN NumberOfPartition, OUT UINT32 *EventSize)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
RETURN_STATUS(EFIAPI * PE_COFF_LOADER_READ_FILE)(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: PeCoffLib.h:65
RETURN_STATUS EFIAPI PeCoffLoaderGetImageInfo(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:577
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
#define EFI_AUTH_OPERATION_IMAGE_REQUIRED
EFI_STATUS EFIAPI RegisterSecurity2Handler(IN SECURITY2_FILE_AUTHENTICATION_HANDLER Security2Handler, IN UINT32 AuthenticationOperation)
VOID EFIAPI Exit(IN EFI_STATUS Status)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo.h:224
UINT32 BlockSize
Definition: BlockIo.h:167
EFI_GUID PartitionTypeGUID
Definition: UefiGpt.h:91
UINT32 NumberOfPartitionEntries
Definition: UefiGpt.h:66
PE_COFF_LOADER_READ_FILE ImageRead
Definition: PeCoffLib.h:100
PHYSICAL_ADDRESS ImageAddress
Definition: PeCoffLib.h:79