2 This module implements TrEE Protocol.
4 Copyright (c) 2013 - 2016, 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
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.
16 #include <IndustryStandard/Acpi.h>
17 #include <IndustryStandard/PeImage.h>
18 #include <IndustryStandard/TcpaAcpi.h>
20 #include <Guid/GlobalVariable.h>
21 #include <Guid/HobList.h>
22 #include <Guid/TcgEventHob.h>
23 #include <Guid/EventGroup.h>
24 #include <Guid/EventExitBootServiceFailed.h>
25 #include <Guid/ImageAuthentication.h>
26 #include <Guid/TpmInstance.h>
28 #include <Protocol/DevicePath.h>
29 #include <Protocol/AcpiTable.h>
30 #include <Protocol/MpService.h>
31 #include <Protocol/VariableWrite.h>
32 #include <Protocol/TrEEProtocol.h>
34 #include <Library/DebugLib.h>
35 #include <Library/BaseMemoryLib.h>
36 #include <Library/UefiRuntimeServicesTableLib.h>
37 #include <Library/UefiDriverEntryPoint.h>
38 #include <Library/HobLib.h>
39 #include <Library/UefiBootServicesTableLib.h>
40 #include <Library/BaseLib.h>
41 #include <Library/MemoryAllocationLib.h>
42 #include <Library/PrintLib.h>
43 #include <Library/Tpm2CommandLib.h>
44 #include <Library/PcdLib.h>
45 #include <Library/UefiLib.h>
46 #include <Library/Tpm2DeviceLib.h>
47 #include <Library/HashLib.h>
48 #include <Library/PerformanceLib.h>
49 #include <Library/ReportStatusCodeLib.h>
51 #define PERF_ID_TREE_DXE 0x3120
58 #define TREE_DEFAULT_MAX_COMMAND_SIZE 0x1000
59 #define TREE_DEFAULT_MAX_RESPONSE_SIZE 0x1000
63 TREE_EVENT_LOG_FORMAT LogFormat
;
64 } TREE_EVENT_INFO_STRUCT
;
66 TREE_EVENT_INFO_STRUCT mTreeEventInfo
[] = {
67 {&gTcgEventEntryHobGuid
, TREE_EVENT_LOG_FORMAT_TCG_1_2
},
70 #define TCG_EVENT_LOG_AREA_COUNT_MAX 2
73 TREE_EVENT_LOG_FORMAT EventLogFormat
;
74 EFI_PHYSICAL_ADDRESS Lasa
;
78 BOOLEAN EventLogStarted
;
79 BOOLEAN EventLogTruncated
;
80 } TCG_EVENT_LOG_AREA_STRUCT
;
82 typedef struct _TCG_DXE_DATA
{
83 TREE_BOOT_SERVICE_CAPABILITY BsCap
;
84 EFI_TCG_CLIENT_ACPI_TABLE
*TcgClientAcpiTable
;
85 EFI_TCG_SERVER_ACPI_TABLE
*TcgServerAcpiTable
;
86 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
89 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate
= {
91 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
92 sizeof (mTcgClientAcpiTemplate
),
95 // Compiler initializes the remaining bytes to 0
96 // These fields should be filled in in production
99 0, // 0 for PC Client Platform Class
100 0, // Log Area Max Length
101 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1) // Log Area Start Address
105 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,
106 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,
107 // this _UID can be changed and should match with the _UID setting of the TPM
108 // ACPI device object
110 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate
= {
112 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
113 sizeof (mTcgServerAcpiTemplate
),
116 // Compiler initializes the remaining bytes to 0
117 // These fields should be filled in in production
120 1, // 1 for Server Platform Class
122 0, // Log Area Max Length
123 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1), // Log Area Start Address
124 0x0100, // TCG Specification revision 1.0
126 0, // Interrupt Flags
128 {0}, // Reserved 3 bytes
129 0, // Global System Interrupt
131 EFI_ACPI_3_0_SYSTEM_MEMORY
,
138 {0}, // Configuration Address
139 0xFF, // ACPI _UID value of the device, can be changed for different platforms
140 0, // ACPI _UID value of the device, can be changed for different platforms
141 0, // ACPI _UID value of the device, can be changed for different platforms
142 0 // ACPI _UID value of the device, can be changed for different platforms
145 TCG_DXE_DATA mTcgDxeData
= {
147 sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0
), // Size
148 { 1, 0 }, // StructureVersion
149 { 1, 0 }, // ProtocolVersion
150 TREE_BOOT_HASH_ALG_SHA1
, // HashAlgorithmBitmap
151 TREE_EVENT_LOG_FORMAT_TCG_1_2
, // SupportedEventLogs
152 TRUE
, // TrEEPresentFlag
153 TREE_DEFAULT_MAX_COMMAND_SIZE
, // MaxCommandSize
154 TREE_DEFAULT_MAX_RESPONSE_SIZE
, // MaxResponseSize
157 &mTcgClientAcpiTemplate
,
158 &mTcgServerAcpiTemplate
,
161 UINTN mBootAttempts
= 0;
162 CHAR16 mBootVarName
[] = L
"BootOrder";
164 VARIABLE_TYPE mVariableType
[] = {
165 {EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
},
166 {EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
},
167 {EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
},
168 {EFI_IMAGE_SECURITY_DATABASE
, &gEfiImageSecurityDatabaseGuid
},
169 {EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
},
172 EFI_HANDLE mImageHandle
;
175 Measure PE image into TPM log based on the authenticode image hashing in
176 PE/COFF Specification 8.0 Appendix A.
178 Caution: This function may receive untrusted input.
179 PE/COFF image is external input, so this function will validate its data structure
180 within this image buffer before use.
182 @param[in] PCRIndex TPM PCR index
183 @param[in] ImageAddress Start address of image buffer.
184 @param[in] ImageSize Image size
185 @param[out] DigestList Digeest list of this image.
187 @retval EFI_SUCCESS Successfully measure image.
188 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
189 @retval other error value
192 MeasurePeImageAndExtend (
194 IN EFI_PHYSICAL_ADDRESS ImageAddress
,
196 OUT TPML_DIGEST_VALUES
*DigestList
201 This function dump raw data.
204 @param Size raw data size
214 for (Index
= 0; Index
< Size
; Index
++) {
215 DEBUG ((EFI_D_INFO
, "%02x", (UINTN
)Data
[Index
]));
221 This function dump raw data with colume format.
224 @param Size raw data size
237 #define COLUME_SIZE (16 * 2)
239 Count
= Size
/ COLUME_SIZE
;
240 Left
= Size
% COLUME_SIZE
;
241 for (Index
= 0; Index
< Count
; Index
++) {
242 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
243 InternalDumpData (Data
+ Index
* COLUME_SIZE
, COLUME_SIZE
);
244 DEBUG ((EFI_D_INFO
, "\n"));
248 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
249 InternalDumpData (Data
+ Index
* COLUME_SIZE
, Left
);
250 DEBUG ((EFI_D_INFO
, "\n"));
255 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
256 Caller is responsible to free LocationBuf.
258 @param[out] LocationBuf Returns Processor Location Buffer.
259 @param[out] Num Returns processor number.
261 @retval EFI_SUCCESS Operation completed successfully.
262 @retval EFI_UNSUPPORTED MpService protocol not found.
266 GetProcessorsCpuLocation (
267 OUT EFI_CPU_PHYSICAL_LOCATION
**LocationBuf
,
272 EFI_MP_SERVICES_PROTOCOL
*MpProtocol
;
274 UINTN EnabledProcessorNum
;
275 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
276 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
279 Status
= gBS
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**) &MpProtocol
);
280 if (EFI_ERROR (Status
)) {
282 // MP protocol is not installed
284 return EFI_UNSUPPORTED
;
287 Status
= MpProtocol
->GetNumberOfProcessors(
292 if (EFI_ERROR(Status
)){
296 Status
= gBS
->AllocatePool(
298 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
299 (VOID
**) &ProcessorLocBuf
301 if (EFI_ERROR(Status
)){
306 // Get each processor Location info
308 for (Index
= 0; Index
< ProcessorNum
; Index
++) {
309 Status
= MpProtocol
->GetProcessorInfo(
314 if (EFI_ERROR(Status
)){
315 FreePool(ProcessorLocBuf
);
320 // Get all Processor Location info & measure
323 &ProcessorLocBuf
[Index
],
324 &ProcessorInfo
.Location
,
325 sizeof(EFI_CPU_PHYSICAL_LOCATION
)
329 *LocationBuf
= ProcessorLocBuf
;
336 The EFI_TREE_PROTOCOL GetCapability function call provides protocol
337 capability information and state information about the TrEE.
339 @param[in] This Indicates the calling context
340 @param[in, out] ProtocolCapability The caller allocates memory for a TREE_BOOT_SERVICE_CAPABILITY
341 structure and sets the size field to the size of the structure allocated.
342 The callee fills in the fields with the EFI protocol capability information
343 and the current TrEE state information up to the number of fields which
344 fit within the size of the structure passed in.
346 @retval EFI_SUCCESS Operation completed successfully.
347 @retval EFI_DEVICE_ERROR The command was unsuccessful.
348 The ProtocolCapability variable will not be populated.
349 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
350 The ProtocolCapability variable will not be populated.
351 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
352 It will be partially populated (required Size field will be set).
357 IN EFI_TREE_PROTOCOL
*This
,
358 IN OUT TREE_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
361 DEBUG ((EFI_D_INFO
, "TreeGetCapability ...\n"));
363 if ((This
== NULL
) || (ProtocolCapability
== NULL
)) {
364 return EFI_INVALID_PARAMETER
;
367 if (ProtocolCapability
->Size
< mTcgDxeData
.BsCap
.Size
) {
368 ProtocolCapability
->Size
= mTcgDxeData
.BsCap
.Size
;
369 return EFI_BUFFER_TOO_SMALL
;
372 CopyMem (ProtocolCapability
, &mTcgDxeData
.BsCap
, mTcgDxeData
.BsCap
.Size
);
373 DEBUG ((EFI_D_INFO
, "TreeGetCapability - %r\n", EFI_SUCCESS
));
378 This function dump event log.
380 @param[in] EventLogFormat The type of the event log for which the information is requested.
381 @param[in] EventLogLocation A pointer to the memory address of the event log.
382 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
383 address of the start of the last entry in the event log in memory.
387 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
388 IN EFI_PHYSICAL_ADDRESS EventLogLocation
,
389 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry
392 TCG_PCR_EVENT_HDR
*EventHdr
;
395 DEBUG ((EFI_D_INFO
, "EventLogFormat: (0x%x)\n", EventLogFormat
));
397 switch (EventLogFormat
) {
398 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
399 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)EventLogLocation
;
400 while ((UINTN
)EventHdr
<= EventLogLastEntry
) {
401 DEBUG ((EFI_D_INFO
, " Event:\n"));
402 DEBUG ((EFI_D_INFO
, " PCRIndex - %d\n", EventHdr
->PCRIndex
));
403 DEBUG ((EFI_D_INFO
, " EventType - 0x%08x\n", EventHdr
->EventType
));
404 DEBUG ((EFI_D_INFO
, " Digest - "));
405 for (Index
= 0; Index
< sizeof(TCG_DIGEST
); Index
++) {
406 DEBUG ((EFI_D_INFO
, "%02x ", EventHdr
->Digest
.digest
[Index
]));
408 DEBUG ((EFI_D_INFO
, "\n"));
409 DEBUG ((EFI_D_INFO
, " EventSize - 0x%08x\n", EventHdr
->EventSize
));
410 InternalDumpHex ((UINT8
*)(EventHdr
+ 1), EventHdr
->EventSize
);
411 EventHdr
= (TCG_PCR_EVENT_HDR
*)((UINTN
)EventHdr
+ sizeof(TCG_PCR_EVENT_HDR
) + EventHdr
->EventSize
);
420 The EFI_TREE_PROTOCOL Get Event Log function call allows a caller to
421 retrieve the address of a given event log and its last entry.
423 @param[in] This Indicates the calling context
424 @param[in] EventLogFormat The type of the event log for which the information is requested.
425 @param[out] EventLogLocation A pointer to the memory address of the event log.
426 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
427 address of the start of the last entry in the event log in memory.
428 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
429 have exceeded the area allocated for events, this value is set to TRUE.
430 Otherwise, the value will be FALSE and the Event Log will be complete.
432 @retval EFI_SUCCESS Operation completed successfully.
433 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
434 (e.g. asking for an event log whose format is not supported).
439 IN EFI_TREE_PROTOCOL
*This
,
440 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
441 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
442 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
,
443 OUT BOOLEAN
*EventLogTruncated
448 DEBUG ((EFI_D_INFO
, "TreeGetEventLog ...\n"));
451 return EFI_INVALID_PARAMETER
;
454 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
455 if (EventLogFormat
== mTreeEventInfo
[Index
].LogFormat
) {
460 if (Index
== sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0])) {
461 return EFI_INVALID_PARAMETER
;
464 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
465 if (EventLogLocation
!= NULL
) {
466 *EventLogLocation
= 0;
468 if (EventLogLastEntry
!= NULL
) {
469 *EventLogLastEntry
= 0;
471 if (EventLogTruncated
!= NULL
) {
472 *EventLogTruncated
= FALSE
;
477 if (EventLogLocation
!= NULL
) {
478 *EventLogLocation
= mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
;
479 DEBUG ((EFI_D_INFO
, "TreeGetEventLog (EventLogLocation - %x)\n", *EventLogLocation
));
482 if (EventLogLastEntry
!= NULL
) {
483 if (!mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
) {
484 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
486 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
;
488 DEBUG ((EFI_D_INFO
, "TreeGetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry
));
491 if (EventLogTruncated
!= NULL
) {
492 *EventLogTruncated
= mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
;
493 DEBUG ((EFI_D_INFO
, "TreeGetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated
));
496 DEBUG ((EFI_D_INFO
, "TreeGetEventLog - %r\n", EFI_SUCCESS
));
498 // Dump Event Log for debug purpose
499 if ((EventLogLocation
!= NULL
) && (EventLogLastEntry
!= NULL
)) {
500 DumpEventLog (EventLogFormat
, *EventLogLocation
, *EventLogLastEntry
);
507 Add a new entry to the Event Log.
509 @param[in, out] EventLogPtr Pointer to the Event Log data.
510 @param[in, out] LogSize Size of the Event Log.
511 @param[in] MaxSize Maximum size of the Event Log.
512 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
513 @param[in] NewEventHdrSize New event header size.
514 @param[in] NewEventData Pointer to the new event data.
515 @param[in] NewEventSize New event data size.
517 @retval EFI_SUCCESS The new event log entry was added.
518 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
523 IN OUT UINT8
**EventLogPtr
,
524 IN OUT UINTN
*LogSize
,
526 IN VOID
*NewEventHdr
,
527 IN UINT32 NewEventHdrSize
,
528 IN UINT8
*NewEventData
,
529 IN UINT32 NewEventSize
534 if (NewEventSize
> MAX_ADDRESS
- NewEventHdrSize
) {
535 return EFI_OUT_OF_RESOURCES
;
538 NewLogSize
= NewEventHdrSize
+ NewEventSize
;
540 if (NewLogSize
> MAX_ADDRESS
- *LogSize
) {
541 return EFI_OUT_OF_RESOURCES
;
544 if (NewLogSize
+ *LogSize
> MaxSize
) {
545 DEBUG ((EFI_D_INFO
, " MaxSize - 0x%x\n", MaxSize
));
546 DEBUG ((EFI_D_INFO
, " NewLogSize - 0x%x\n", NewLogSize
));
547 DEBUG ((EFI_D_INFO
, " LogSize - 0x%x\n", *LogSize
));
548 DEBUG ((EFI_D_INFO
, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES
));
549 return EFI_OUT_OF_RESOURCES
;
552 *EventLogPtr
+= *LogSize
;
553 *LogSize
+= NewLogSize
;
554 CopyMem (*EventLogPtr
, NewEventHdr
, NewEventHdrSize
);
556 *EventLogPtr
+ NewEventHdrSize
,
564 Add a new entry to the Event Log.
566 @param[in] EventLogFormat The type of the event log for which the information is requested.
567 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
568 @param[in] NewEventHdrSize New event header size.
569 @param[in] NewEventData Pointer to the new event data.
570 @param[in] NewEventSize New event data size.
572 @retval EFI_SUCCESS The new event log entry was added.
573 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
578 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
579 IN VOID
*NewEventHdr
,
580 IN UINT32 NewEventHdrSize
,
581 IN UINT8
*NewEventData
,
582 IN UINT32 NewEventSize
588 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
589 if (EventLogFormat
== mTreeEventInfo
[Index
].LogFormat
) {
594 if (Index
== sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0])) {
595 return EFI_INVALID_PARAMETER
;
598 if (mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
) {
599 return EFI_VOLUME_FULL
;
602 mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
= (UINT8
*)(UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
;
603 Status
= TcgCommLogEvent (
604 &mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
,
605 &mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogSize
,
606 (UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
,
613 if (Status
== EFI_DEVICE_ERROR
) {
614 return EFI_DEVICE_ERROR
;
615 } else if (Status
== EFI_OUT_OF_RESOURCES
) {
616 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
= TRUE
;
617 return EFI_VOLUME_FULL
;
618 } else if (Status
== EFI_SUCCESS
) {
619 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
= TRUE
;
626 This function get digest from digest list.
628 @param HashAlg digest algorithm
629 @param DigestList digest list
632 @retval EFI_SUCCESS Sha1Digest is found and returned.
633 @retval EFI_NOT_FOUND Sha1Digest is not found.
636 Tpm2GetDigestFromDigestList (
637 IN TPMI_ALG_HASH HashAlg
,
638 IN TPML_DIGEST_VALUES
*DigestList
,
645 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
646 for (Index
= 0; Index
< DigestList
->count
; Index
++) {
647 if (DigestList
->digests
[Index
].hashAlg
== HashAlg
) {
650 &DigestList
->digests
[Index
].digest
,
657 return EFI_NOT_FOUND
;
661 Add a new entry to the Event Log.
663 @param[in] DigestList A list of digest.
664 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
665 @param[in] NewEventData Pointer to the new event data.
667 @retval EFI_SUCCESS The new event log entry was added.
668 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
672 IN TPML_DIGEST_VALUES
*DigestList
,
673 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
674 IN UINT8
*NewEventData
680 EFI_STATUS RetStatus
;
682 RetStatus
= EFI_SUCCESS
;
683 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
684 DEBUG ((EFI_D_INFO
, " LogFormat - 0x%08x\n", mTreeEventInfo
[Index
].LogFormat
));
685 switch (mTreeEventInfo
[Index
].LogFormat
) {
686 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
687 Status
= Tpm2GetDigestFromDigestList (TPM_ALG_SHA1
, DigestList
, &NewEventHdr
->Digest
);
688 if (!EFI_ERROR (Status
)) {
690 // Enter critical region
692 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
693 Status
= TcgDxeLogEvent (
694 mTreeEventInfo
[Index
].LogFormat
,
696 sizeof(TCG_PCR_EVENT_HDR
),
698 NewEventHdr
->EventSize
700 if (Status
!= EFI_SUCCESS
) {
703 gBS
->RestoreTPL (OldTpl
);
705 // Exit critical region
716 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
717 and add an entry to the Event Log.
719 @param[in] Flags Bitmap providing additional information.
720 @param[in] HashData Physical address of the start of the data buffer
721 to be hashed, extended, and logged.
722 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
723 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
724 @param[in] NewEventData Pointer to the new event data.
726 @retval EFI_SUCCESS Operation completed successfully.
727 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
728 @retval EFI_DEVICE_ERROR The command was unsuccessful.
732 TcgDxeHashLogExtendEvent (
735 IN UINT64 HashDataLen
,
736 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
737 IN UINT8
*NewEventData
741 TPML_DIGEST_VALUES DigestList
;
743 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
744 return EFI_DEVICE_ERROR
;
747 Status
= HashAndExtend (
748 NewEventHdr
->PCRIndex
,
753 if (!EFI_ERROR (Status
)) {
754 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
755 Status
= TcgDxeLogHashEvent (&DigestList
, NewEventHdr
, NewEventData
);
759 if (Status
== EFI_DEVICE_ERROR
) {
760 DEBUG ((EFI_D_ERROR
, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status
));
761 mTcgDxeData
.BsCap
.TrEEPresentFlag
= FALSE
;
763 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
764 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
772 The EFI_TREE_PROTOCOL HashLogExtendEvent function call provides callers with
773 an opportunity to extend and optionally log events without requiring
774 knowledge of actual TPM commands.
775 The extend operation will occur even if this function cannot create an event
776 log entry (e.g. due to the event log being full).
778 @param[in] This Indicates the calling context
779 @param[in] Flags Bitmap providing additional information.
780 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
781 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
782 @param[in] Event Pointer to data buffer containing information about the event.
784 @retval EFI_SUCCESS Operation completed successfully.
785 @retval EFI_DEVICE_ERROR The command was unsuccessful.
786 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
787 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
788 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
792 TreeHashLogExtendEvent (
793 IN EFI_TREE_PROTOCOL
*This
,
795 IN EFI_PHYSICAL_ADDRESS DataToHash
,
796 IN UINT64 DataToHashLen
,
801 TCG_PCR_EVENT_HDR NewEventHdr
;
802 TPML_DIGEST_VALUES DigestList
;
804 DEBUG ((EFI_D_INFO
, "TreeHashLogExtendEvent ...\n"));
806 if ((This
== NULL
) || (DataToHash
== 0) || (Event
== NULL
)) {
807 return EFI_INVALID_PARAMETER
;
810 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
811 return EFI_UNSUPPORTED
;
814 if (Event
->Size
< Event
->Header
.HeaderSize
+ sizeof(UINT32
)) {
815 return EFI_INVALID_PARAMETER
;
818 if (Event
->Header
.PCRIndex
> MAX_PCR_INDEX
) {
819 return EFI_INVALID_PARAMETER
;
822 NewEventHdr
.PCRIndex
= Event
->Header
.PCRIndex
;
823 NewEventHdr
.EventType
= Event
->Header
.EventType
;
824 NewEventHdr
.EventSize
= Event
->Size
- sizeof(UINT32
) - Event
->Header
.HeaderSize
;
825 if ((Flags
& PE_COFF_IMAGE
) != 0) {
826 Status
= MeasurePeImageAndExtend (
827 NewEventHdr
.PCRIndex
,
829 (UINTN
)DataToHashLen
,
832 if (!EFI_ERROR (Status
)) {
833 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
834 Status
= TcgDxeLogHashEvent (&DigestList
, &NewEventHdr
, Event
->Event
);
837 if (Status
== EFI_DEVICE_ERROR
) {
838 DEBUG ((EFI_D_ERROR
, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status
));
839 mTcgDxeData
.BsCap
.TrEEPresentFlag
= FALSE
;
841 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
842 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
846 Status
= TcgDxeHashLogExtendEvent (
848 (UINT8
*) (UINTN
) DataToHash
,
854 DEBUG ((EFI_D_INFO
, "TreeHashLogExtendEvent - %r\n", Status
));
859 This service enables the sending of commands to the TrEE.
861 @param[in] This Indicates the calling context
862 @param[in] InputParameterBlockSize Size of the TrEE input parameter block.
863 @param[in] InputParameterBlock Pointer to the TrEE input parameter block.
864 @param[in] OutputParameterBlockSize Size of the TrEE output parameter block.
865 @param[in] OutputParameterBlock Pointer to the TrEE output parameter block.
867 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
868 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
869 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
870 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
875 IN EFI_TREE_PROTOCOL
*This
,
876 IN UINT32 InputParameterBlockSize
,
877 IN UINT8
*InputParameterBlock
,
878 IN UINT32 OutputParameterBlockSize
,
879 IN UINT8
*OutputParameterBlock
884 DEBUG ((EFI_D_INFO
, "TreeSubmitCommand ...\n"));
886 if ((This
== NULL
) ||
887 (InputParameterBlockSize
== 0) || (InputParameterBlock
== NULL
) ||
888 (OutputParameterBlockSize
== 0) || (OutputParameterBlock
== NULL
)) {
889 return EFI_INVALID_PARAMETER
;
892 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
893 return EFI_UNSUPPORTED
;
896 if (InputParameterBlockSize
>= mTcgDxeData
.BsCap
.MaxCommandSize
) {
897 return EFI_INVALID_PARAMETER
;
899 if (OutputParameterBlockSize
>= mTcgDxeData
.BsCap
.MaxResponseSize
) {
900 return EFI_INVALID_PARAMETER
;
903 Status
= Tpm2SubmitCommand (
904 InputParameterBlockSize
,
906 &OutputParameterBlockSize
,
909 DEBUG ((EFI_D_INFO
, "TreeSubmitCommand - %r\n", Status
));
914 EFI_TREE_PROTOCOL mTreeProtocol
= {
917 TreeHashLogExtendEvent
,
922 Initialize the Event Log and log events passed from the PEI phase.
924 @retval EFI_SUCCESS Operation completed successfully.
925 @retval EFI_OUT_OF_RESOURCES Out of memory.
935 EFI_PEI_HOB_POINTERS GuidHob
;
936 EFI_PHYSICAL_ADDRESS Lasa
;
939 DEBUG ((EFI_D_INFO
, "SetupEventLog\n"));
942 // 1. Create Log Area
944 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
945 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogFormat
= mTreeEventInfo
[Index
].LogFormat
;
946 Lasa
= (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1);
947 Status
= gBS
->AllocatePages (
950 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen
)),
953 if (EFI_ERROR (Status
)) {
956 mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
= Lasa
;
957 mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
959 // To initialize them as 0xFF is recommended
960 // because the OS can know the last entry for that.
962 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcgLogAreaMinLen
), 0xFF);
966 // 2. Create ACPI table for TCG1.2 only
968 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
969 mTcgClientAcpiTemplate
.Lasa
= mTcgDxeData
.EventLogAreaStruct
[0].Lasa
;
970 mTcgClientAcpiTemplate
.Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
972 mTcgServerAcpiTemplate
.Lasa
= mTcgDxeData
.EventLogAreaStruct
[0].Lasa
;
973 mTcgServerAcpiTemplate
.Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
977 // 3. Sync data from PEI to DXE
979 Status
= EFI_SUCCESS
;
980 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
981 GuidHob
.Raw
= GetHobList ();
982 Status
= EFI_SUCCESS
;
983 while (!EFI_ERROR (Status
) &&
984 (GuidHob
.Raw
= GetNextGuidHob (mTreeEventInfo
[Index
].EventGuid
, GuidHob
.Raw
)) != NULL
) {
985 TcgEvent
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
986 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
987 switch (mTreeEventInfo
[Index
].LogFormat
) {
988 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
989 Status
= TcgDxeLogEvent (
990 mTreeEventInfo
[Index
].LogFormat
,
992 sizeof(TCG_PCR_EVENT_HDR
),
993 ((TCG_PCR_EVENT
*)TcgEvent
)->Event
,
994 ((TCG_PCR_EVENT_HDR
*)TcgEvent
)->EventSize
1005 Measure and log an action string, and extend the measurement result into PCR[5].
1007 @param[in] String A specific string that indicates an Action event.
1009 @retval EFI_SUCCESS Operation completed successfully.
1010 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1018 TCG_PCR_EVENT_HDR TcgEvent
;
1020 TcgEvent
.PCRIndex
= 5;
1021 TcgEvent
.EventType
= EV_EFI_ACTION
;
1022 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
1023 return TcgDxeHashLogExtendEvent (
1033 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1035 @retval EFI_SUCCESS Operation completed successfully.
1036 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1040 MeasureHandoffTables (
1045 TCG_PCR_EVENT_HDR TcgEvent
;
1046 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
1048 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
1050 ProcessorLocBuf
= NULL
;
1051 Status
= EFI_SUCCESS
;
1053 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
1056 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1058 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
1060 if (!EFI_ERROR(Status
)){
1061 TcgEvent
.PCRIndex
= 1;
1062 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
1063 TcgEvent
.EventSize
= sizeof (HandoffTables
);
1065 HandoffTables
.NumberOfTables
= 1;
1066 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
1067 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
1069 Status
= TcgDxeHashLogExtendEvent (
1071 (UINT8
*)(UINTN
)ProcessorLocBuf
,
1072 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
1074 (UINT8
*)&HandoffTables
1077 FreePool(ProcessorLocBuf
);
1085 Measure and log Separator event, and extend the measurement result into a specific PCR.
1087 @param[in] PCRIndex PCR index.
1089 @retval EFI_SUCCESS Operation completed successfully.
1090 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1094 MeasureSeparatorEvent (
1095 IN TPM_PCRINDEX PCRIndex
1098 TCG_PCR_EVENT_HDR TcgEvent
;
1101 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex
));
1104 TcgEvent
.PCRIndex
= PCRIndex
;
1105 TcgEvent
.EventType
= EV_SEPARATOR
;
1106 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
1107 return TcgDxeHashLogExtendEvent (
1109 (UINT8
*)&EventData
,
1117 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1119 @param[in] PCRIndex PCR Index.
1120 @param[in] EventType Event type.
1121 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1122 @param[in] VendorGuid A unique identifier for the vendor.
1123 @param[in] VarData The content of the variable data.
1124 @param[in] VarSize The size of the variable data.
1126 @retval EFI_SUCCESS Operation completed successfully.
1127 @retval EFI_OUT_OF_RESOURCES Out of memory.
1128 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1133 IN TPM_PCRINDEX PCRIndex
,
1134 IN TCG_EVENTTYPE EventType
,
1136 IN EFI_GUID
*VendorGuid
,
1142 TCG_PCR_EVENT_HDR TcgEvent
;
1143 UINTN VarNameLength
;
1144 EFI_VARIABLE_DATA_TREE
*VarLog
;
1146 DEBUG ((EFI_D_INFO
, "TrEEDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN
)PCRIndex
, (UINTN
)EventType
));
1147 DEBUG ((EFI_D_INFO
, "VariableName - %s, VendorGuid - %g)\n", VarName
, VendorGuid
));
1149 VarNameLength
= StrLen (VarName
);
1150 TcgEvent
.PCRIndex
= PCRIndex
;
1151 TcgEvent
.EventType
= EventType
;
1152 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
1153 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
1155 VarLog
= (EFI_VARIABLE_DATA_TREE
*)AllocatePool (TcgEvent
.EventSize
);
1156 if (VarLog
== NULL
) {
1157 return EFI_OUT_OF_RESOURCES
;
1160 VarLog
->VariableName
= *VendorGuid
;
1161 VarLog
->UnicodeNameLength
= VarNameLength
;
1162 VarLog
->VariableDataLength
= VarSize
;
1164 VarLog
->UnicodeName
,
1166 VarNameLength
* sizeof (*VarName
)
1168 if (VarSize
!= 0 && VarData
!= NULL
) {
1170 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
1176 Status
= TcgDxeHashLogExtendEvent (
1189 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1191 @param[in] PCRIndex PCR Index.
1192 @param[in] EventType Event type.
1193 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1194 @param[in] VendorGuid A unique identifier for the vendor.
1195 @param[out] VarSize The size of the variable data.
1196 @param[out] VarData Pointer to the content of the variable.
1198 @retval EFI_SUCCESS Operation completed successfully.
1199 @retval EFI_OUT_OF_RESOURCES Out of memory.
1200 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1204 ReadAndMeasureVariable (
1205 IN TPM_PCRINDEX PCRIndex
,
1206 IN TCG_EVENTTYPE EventType
,
1208 IN EFI_GUID
*VendorGuid
,
1215 Status
= GetVariable2 (VarName
, VendorGuid
, VarData
, VarSize
);
1216 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1217 if (EFI_ERROR (Status
)) {
1219 // It is valid case, so we need handle it.
1226 // if status error, VarData is freed and set NULL by GetVariable2
1228 if (EFI_ERROR (Status
)) {
1229 return EFI_NOT_FOUND
;
1233 Status
= MeasureVariable (
1245 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
1247 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1248 @param[in] VendorGuid A unique identifier for the vendor.
1249 @param[out] VarSize The size of the variable data.
1250 @param[out] VarData Pointer to the content of the variable.
1252 @retval EFI_SUCCESS Operation completed successfully.
1253 @retval EFI_OUT_OF_RESOURCES Out of memory.
1254 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1258 ReadAndMeasureBootVariable (
1260 IN EFI_GUID
*VendorGuid
,
1265 return ReadAndMeasureVariable (
1267 EV_EFI_VARIABLE_BOOT
,
1276 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1278 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1279 @param[in] VendorGuid A unique identifier for the vendor.
1280 @param[out] VarSize The size of the variable data.
1281 @param[out] VarData Pointer to the content of the variable.
1283 @retval EFI_SUCCESS Operation completed successfully.
1284 @retval EFI_OUT_OF_RESOURCES Out of memory.
1285 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1289 ReadAndMeasureSecureVariable (
1291 IN EFI_GUID
*VendorGuid
,
1296 return ReadAndMeasureVariable (
1298 EV_EFI_VARIABLE_DRIVER_CONFIG
,
1307 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1309 The EFI boot variables are BootOrder and Boot#### variables.
1311 @retval EFI_SUCCESS Operation completed successfully.
1312 @retval EFI_OUT_OF_RESOURCES Out of memory.
1313 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1317 MeasureAllBootVariables (
1328 Status
= ReadAndMeasureBootVariable (
1330 &gEfiGlobalVariableGuid
,
1332 (VOID
**) &BootOrder
1334 if (Status
== EFI_NOT_FOUND
|| BootOrder
== NULL
) {
1338 if (EFI_ERROR (Status
)) {
1340 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1342 FreePool (BootOrder
);
1346 BootCount
/= sizeof (*BootOrder
);
1347 for (Index
= 0; Index
< BootCount
; Index
++) {
1348 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
1349 Status
= ReadAndMeasureBootVariable (
1351 &gEfiGlobalVariableGuid
,
1355 if (!EFI_ERROR (Status
)) {
1356 FreePool (BootVarData
);
1360 FreePool (BootOrder
);
1365 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1367 The EFI boot variables are BootOrder and Boot#### variables.
1369 @retval EFI_SUCCESS Operation completed successfully.
1370 @retval EFI_OUT_OF_RESOURCES Out of memory.
1371 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1375 MeasureAllSecureVariables (
1384 Status
= EFI_NOT_FOUND
;
1385 for (Index
= 0; Index
< sizeof(mVariableType
)/sizeof(mVariableType
[0]); Index
++) {
1386 Status
= ReadAndMeasureSecureVariable (
1387 mVariableType
[Index
].VariableName
,
1388 mVariableType
[Index
].VendorGuid
,
1392 if (!EFI_ERROR (Status
)) {
1403 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
1405 @retval EFI_SUCCESS Operation completed successfully.
1406 @retval EFI_OUT_OF_RESOURCES Out of memory.
1407 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1411 MeasureLaunchOfFirmwareDebugger (
1415 TCG_PCR_EVENT_HDR TcgEvent
;
1417 TcgEvent
.PCRIndex
= 7;
1418 TcgEvent
.EventType
= EV_EFI_ACTION
;
1419 TcgEvent
.EventSize
= sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1;
1420 return TcgDxeHashLogExtendEvent (
1422 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
,
1423 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1,
1425 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
1430 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
1432 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
1433 - The contents of the SecureBoot variable
1434 - The contents of the PK variable
1435 - The contents of the KEK variable
1436 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
1437 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
1439 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
1441 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
1442 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
1444 @param[in] Event Event whose notification function is being invoked
1445 @param[in] Context Pointer to the notification function's context
1449 MeasureSecureBootPolicy (
1457 Status
= gBS
->LocateProtocol (&gEfiVariableWriteArchProtocolGuid
, NULL
, (VOID
**)&Protocol
);
1458 if (EFI_ERROR (Status
)) {
1462 if (PcdGetBool (PcdFirmwareDebuggerInitialized
)) {
1463 Status
= MeasureLaunchOfFirmwareDebugger ();
1464 DEBUG ((EFI_D_INFO
, "MeasureLaunchOfFirmwareDebugger - %r\n", Status
));
1467 Status
= MeasureAllSecureVariables ();
1468 DEBUG ((EFI_D_INFO
, "MeasureAllSecureVariables - %r\n", Status
));
1471 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
1472 // and ImageVerification (Authority)
1473 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
1474 // the Authority measurement happen before ReadToBoot event.
1476 Status
= MeasureSeparatorEvent (7);
1477 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent - %r\n", Status
));
1482 Ready to Boot Event notification handler.
1484 Sequence of OS boot events is measured in this event notification handler.
1486 @param[in] Event Event whose notification function is being invoked
1487 @param[in] Context Pointer to the notification function's context
1498 TPM_PCRINDEX PcrIndex
;
1500 PERF_START_EX (mImageHandle
, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE
);
1501 if (mBootAttempts
== 0) {
1504 // Measure handoff tables.
1506 Status
= MeasureHandoffTables ();
1507 if (EFI_ERROR (Status
)) {
1508 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
1512 // Measure BootOrder & Boot#### variables.
1514 Status
= MeasureAllBootVariables ();
1515 if (EFI_ERROR (Status
)) {
1516 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
1520 // 1. This is the first boot attempt.
1522 Status
= TcgMeasureAction (
1523 EFI_CALLING_EFI_APPLICATION
1525 if (EFI_ERROR (Status
)) {
1526 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
1530 // 2. Draw a line between pre-boot env and entering post-boot env.
1531 // PCR[7] is already done.
1533 for (PcrIndex
= 0; PcrIndex
< 7; PcrIndex
++) {
1534 Status
= MeasureSeparatorEvent (PcrIndex
);
1535 if (EFI_ERROR (Status
)) {
1536 DEBUG ((EFI_D_ERROR
, "Seperator Event not Measured. Error!\n"));
1541 // 3. Measure GPT. It would be done in SAP driver.
1545 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1549 // 5. Read & Measure variable. BootOrder already measured.
1553 // 6. Not first attempt, meaning a return from last attempt
1555 Status
= TcgMeasureAction (
1556 EFI_RETURNING_FROM_EFI_APPLICATOIN
1558 if (EFI_ERROR (Status
)) {
1559 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN
));
1563 DEBUG ((EFI_D_INFO
, "TPM2 TrEEDxe Measure Data when ReadyToBoot\n"));
1565 // Increase boot attempt counter.
1568 PERF_END_EX (mImageHandle
, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE
+ 1);
1572 Install TCG ACPI Table when ACPI Table Protocol is available.
1574 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1575 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1576 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1578 @param[in] Event Event whose notification function is being invoked
1579 @param[in] Context Pointer to the notification function's context
1590 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
1594 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
1595 if (EFI_ERROR (Status
)) {
1599 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
1600 CopyMem (mTcgClientAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgClientAcpiTemplate
.Header
.OemId
));
1601 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1602 CopyMem (&mTcgClientAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1603 mTcgClientAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1604 mTcgClientAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1605 mTcgClientAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1607 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1608 // service of the ACPI table protocol to install it.
1610 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgClientAcpiTemplate
, sizeof (mTcgClientAcpiTemplate
));
1611 mTcgClientAcpiTemplate
.Header
.Checksum
= Checksum
;
1613 Status
= AcpiTable
->InstallAcpiTable (
1615 &mTcgClientAcpiTemplate
,
1616 sizeof (mTcgClientAcpiTemplate
),
1620 CopyMem (mTcgServerAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgServerAcpiTemplate
.Header
.OemId
));
1621 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1622 CopyMem (&mTcgServerAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1623 mTcgServerAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1624 mTcgServerAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1625 mTcgServerAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1627 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1628 // service of the ACPI table protocol to install it.
1630 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgServerAcpiTemplate
, sizeof (mTcgServerAcpiTemplate
));
1631 mTcgServerAcpiTemplate
.Header
.Checksum
= Checksum
;
1633 mTcgServerAcpiTemplate
.BaseAddress
.Address
= PcdGet64 (PcdTpmBaseAddress
);
1634 Status
= AcpiTable
->InstallAcpiTable (
1636 &mTcgServerAcpiTemplate
,
1637 sizeof (mTcgServerAcpiTemplate
),
1642 if (EFI_ERROR (Status
)) {
1643 DEBUG((EFI_D_ERROR
, "Tcg Acpi Table installation failure"));
1648 Exit Boot Services Event notification handler.
1650 Measure invocation and success of ExitBootServices.
1652 @param[in] Event Event whose notification function is being invoked
1653 @param[in] Context Pointer to the notification function's context
1658 OnExitBootServices (
1666 // Measure invocation of ExitBootServices,
1668 Status
= TcgMeasureAction (
1669 EFI_EXIT_BOOT_SERVICES_INVOCATION
1671 if (EFI_ERROR (Status
)) {
1672 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION
));
1676 // Measure success of ExitBootServices
1678 Status
= TcgMeasureAction (
1679 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1681 if (EFI_ERROR (Status
)) {
1682 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED
));
1687 Exit Boot Services Failed Event notification handler.
1689 Measure Failure of ExitBootServices.
1691 @param[in] Event Event whose notification function is being invoked
1692 @param[in] Context Pointer to the notification function's context
1697 OnExitBootServicesFailed (
1705 // Measure Failure of ExitBootServices,
1707 Status
= TcgMeasureAction (
1708 EFI_EXIT_BOOT_SERVICES_FAILED
1710 if (EFI_ERROR (Status
)) {
1711 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED
));
1717 The function install TrEE protocol.
1719 @retval EFI_SUCCESS TrEE protocol is installed.
1720 @retval other Some error occurs.
1731 Status
= gBS
->InstallMultipleProtocolInterfaces (
1733 &gEfiTrEEProtocolGuid
,
1741 The driver's entry point. It publishes EFI TrEE Protocol.
1743 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1744 @param[in] SystemTable A pointer to the EFI System Table.
1746 @retval EFI_SUCCESS The entry point is executed successfully.
1747 @retval other Some error occurs when executing this entry point.
1752 IN EFI_HANDLE ImageHandle
,
1753 IN EFI_SYSTEM_TABLE
*SystemTable
1759 UINT32 MaxCommandSize
;
1760 UINT32 MaxResponseSize
;
1761 TPML_PCR_SELECTION Pcrs
;
1763 UINT32 TpmHashAlgorithmBitmap
;
1765 mImageHandle
= ImageHandle
;
1767 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceNoneGuid
) ||
1768 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
1769 DEBUG ((EFI_D_ERROR
, "No TPM2 instance required!\n"));
1770 return EFI_UNSUPPORTED
;
1773 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
1774 DEBUG ((EFI_D_ERROR
, "TPM2 error!\n"));
1775 return EFI_DEVICE_ERROR
;
1778 Status
= Tpm2RequestUseTpm ();
1779 if (EFI_ERROR (Status
)) {
1780 DEBUG ((EFI_D_ERROR
, "TPM2 not detected!\n"));
1787 DEBUG ((EFI_D_INFO
, "TrEE.ProtocolVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.ProtocolVersion
.Major
, mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
));
1788 DEBUG ((EFI_D_INFO
, "TrEE.StructureVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.StructureVersion
.Major
, mTcgDxeData
.BsCap
.StructureVersion
.Minor
));
1790 Status
= Tpm2GetCapabilityManufactureID (&mTcgDxeData
.BsCap
.ManufacturerID
);
1791 if (EFI_ERROR (Status
)) {
1792 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityManufactureID fail!\n"));
1794 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData
.BsCap
.ManufacturerID
));
1798 UINT32 FirmwareVersion1
;
1799 UINT32 FirmwareVersion2
;
1801 Status
= Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1
, &FirmwareVersion2
);
1802 if (EFI_ERROR (Status
)) {
1803 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
1805 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1
, FirmwareVersion2
));
1809 Status
= Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize
, &MaxResponseSize
);
1810 if (EFI_ERROR (Status
)) {
1811 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
1813 mTcgDxeData
.BsCap
.MaxCommandSize
= (UINT16
)MaxCommandSize
;
1814 mTcgDxeData
.BsCap
.MaxResponseSize
= (UINT16
)MaxResponseSize
;
1815 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize
, MaxResponseSize
));
1818 Status
= Tpm2GetCapabilityPcrs (&Pcrs
);
1819 if (EFI_ERROR (Status
)) {
1820 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityPcrs fail!\n"));
1821 TpmHashAlgorithmBitmap
= TREE_BOOT_HASH_ALG_SHA1
;
1823 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs
.count
));
1824 TpmHashAlgorithmBitmap
= 0;
1825 for (Index
= 0; Index
< Pcrs
.count
; Index
++) {
1826 DEBUG ((EFI_D_INFO
, "hash - %x\n", Pcrs
.pcrSelections
[Index
].hash
));
1827 switch (Pcrs
.pcrSelections
[Index
].hash
) {
1829 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA1
;
1831 case TPM_ALG_SHA256
:
1832 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA256
;
1834 case TPM_ALG_SHA384
:
1835 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA384
;
1837 case TPM_ALG_SHA512
:
1838 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA512
;
1840 case TPM_ALG_SM3_256
:
1841 // TBD: Spec not define TREE_BOOT_HASH_ALG_SM3_256 yet
1846 DEBUG ((EFI_D_INFO
, "TPM.HashAlgorithmBitmap - 0x%08x\n", TpmHashAlgorithmBitmap
));
1848 DEBUG ((EFI_D_INFO
, "TrEE.SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
1849 mTcgDxeData
.BsCap
.HashAlgorithmBitmap
= TpmHashAlgorithmBitmap
;
1850 DEBUG ((EFI_D_INFO
, "TrEE.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData
.BsCap
.HashAlgorithmBitmap
));
1852 if (mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
1854 // Setup the log area and copy event log from hob list to it
1856 Status
= SetupEventLog ();
1857 ASSERT_EFI_ERROR (Status
);
1860 // Measure handoff tables, Boot#### variables etc.
1862 Status
= EfiCreateEventReadyToBootEx (
1869 Status
= gBS
->CreateEventEx (
1874 &gEfiEventExitBootServicesGuid
,
1879 // Measure Exit Boot Service failed
1881 Status
= gBS
->CreateEventEx (
1884 OnExitBootServicesFailed
,
1886 &gEventExitBootServicesFailedGuid
,
1891 // Create event callback, because we need access variable on SecureBootPolicyVariable
1892 // We should use VariableWriteArch instead of VariableArch, because Variable driver
1893 // may update SecureBoot value based on last setting.
1895 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid
, TPL_CALLBACK
, MeasureSecureBootPolicy
, NULL
, &Registration
);
1899 // Install ACPI Table
1901 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid
, TPL_CALLBACK
, InstallAcpiTable
, NULL
, &Registration
);
1904 // Install TrEEProtocol
1906 Status
= InstallTrEE ();
1907 DEBUG ((EFI_D_INFO
, "InstallTrEE - %r\n", Status
));