2 This module implements TrEE Protocol.
4 Copyright (c) 2013 - 2015, 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 EFI_TCG_LOG_AREA_SIZE 0x10000
60 #define TREE_DEFAULT_MAX_COMMAND_SIZE 0x1000
61 #define TREE_DEFAULT_MAX_RESPONSE_SIZE 0x1000
65 TREE_EVENT_LOG_FORMAT LogFormat
;
66 } TREE_EVENT_INFO_STRUCT
;
68 TREE_EVENT_INFO_STRUCT mTreeEventInfo
[] = {
69 {&gTcgEventEntryHobGuid
, TREE_EVENT_LOG_FORMAT_TCG_1_2
},
72 #define TCG_EVENT_LOG_AREA_COUNT_MAX 2
75 TREE_EVENT_LOG_FORMAT EventLogFormat
;
76 EFI_PHYSICAL_ADDRESS Lasa
;
80 BOOLEAN EventLogStarted
;
81 BOOLEAN EventLogTruncated
;
82 } TCG_EVENT_LOG_AREA_STRUCT
;
84 typedef struct _TCG_DXE_DATA
{
85 TREE_BOOT_SERVICE_CAPABILITY BsCap
;
86 EFI_TCG_CLIENT_ACPI_TABLE
*TcgClientAcpiTable
;
87 EFI_TCG_SERVER_ACPI_TABLE
*TcgServerAcpiTable
;
88 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
91 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate
= {
93 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
94 sizeof (mTcgClientAcpiTemplate
),
97 // Compiler initializes the remaining bytes to 0
98 // These fields should be filled in in production
101 0, // 0 for PC Client Platform Class
102 0, // Log Area Max Length
103 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1) // Log Area Start Address
107 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,
108 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,
109 // this _UID can be changed and should match with the _UID setting of the TPM
110 // ACPI device object
112 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate
= {
114 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
115 sizeof (mTcgServerAcpiTemplate
),
118 // Compiler initializes the remaining bytes to 0
119 // These fields should be filled in in production
122 1, // 1 for Server Platform Class
124 0, // Log Area Max Length
125 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1), // Log Area Start Address
126 0x0100, // TCG Specification revision 1.0
128 0, // Interrupt Flags
130 {0}, // Reserved 3 bytes
131 0, // Global System Interrupt
133 EFI_ACPI_3_0_SYSTEM_MEMORY
,
140 {0}, // Configuration Address
141 0xFF, // 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
143 0, // ACPI _UID value of the device, can be changed for different platforms
144 0 // ACPI _UID value of the device, can be changed for different platforms
147 TCG_DXE_DATA mTcgDxeData
= {
149 sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0
), // Size
150 { 1, 0 }, // StructureVersion
151 { 1, 0 }, // ProtocolVersion
152 TREE_BOOT_HASH_ALG_SHA1
, // HashAlgorithmBitmap
153 TREE_EVENT_LOG_FORMAT_TCG_1_2
, // SupportedEventLogs
154 TRUE
, // TrEEPresentFlag
155 TREE_DEFAULT_MAX_COMMAND_SIZE
, // MaxCommandSize
156 TREE_DEFAULT_MAX_RESPONSE_SIZE
, // MaxResponseSize
159 &mTcgClientAcpiTemplate
,
160 &mTcgServerAcpiTemplate
,
163 UINTN mBootAttempts
= 0;
164 CHAR16 mBootVarName
[] = L
"BootOrder";
166 VARIABLE_TYPE mVariableType
[] = {
167 {EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
},
168 {EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
},
169 {EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
},
170 {EFI_IMAGE_SECURITY_DATABASE
, &gEfiImageSecurityDatabaseGuid
},
171 {EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
},
174 EFI_HANDLE mImageHandle
;
177 Measure PE image into TPM log based on the authenticode image hashing in
178 PE/COFF Specification 8.0 Appendix A.
180 Caution: This function may receive untrusted input.
181 PE/COFF image is external input, so this function will validate its data structure
182 within this image buffer before use.
184 @param[in] PCRIndex TPM PCR index
185 @param[in] ImageAddress Start address of image buffer.
186 @param[in] ImageSize Image size
187 @param[out] DigestList Digeest list of this image.
189 @retval EFI_SUCCESS Successfully measure image.
190 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
191 @retval other error value
194 MeasurePeImageAndExtend (
196 IN EFI_PHYSICAL_ADDRESS ImageAddress
,
198 OUT TPML_DIGEST_VALUES
*DigestList
203 This function dump raw data.
206 @param Size raw data size
216 for (Index
= 0; Index
< Size
; Index
++) {
217 DEBUG ((EFI_D_INFO
, "%02x", (UINTN
)Data
[Index
]));
223 This function dump raw data with colume format.
226 @param Size raw data size
239 #define COLUME_SIZE (16 * 2)
241 Count
= Size
/ COLUME_SIZE
;
242 Left
= Size
% COLUME_SIZE
;
243 for (Index
= 0; Index
< Count
; Index
++) {
244 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
245 InternalDumpData (Data
+ Index
* COLUME_SIZE
, COLUME_SIZE
);
246 DEBUG ((EFI_D_INFO
, "\n"));
250 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
251 InternalDumpData (Data
+ Index
* COLUME_SIZE
, Left
);
252 DEBUG ((EFI_D_INFO
, "\n"));
257 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
258 Caller is responsible to free LocationBuf.
260 @param[out] LocationBuf Returns Processor Location Buffer.
261 @param[out] Num Returns processor number.
263 @retval EFI_SUCCESS Operation completed successfully.
264 @retval EFI_UNSUPPORTED MpService protocol not found.
268 GetProcessorsCpuLocation (
269 OUT EFI_CPU_PHYSICAL_LOCATION
**LocationBuf
,
274 EFI_MP_SERVICES_PROTOCOL
*MpProtocol
;
276 UINTN EnabledProcessorNum
;
277 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
278 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
281 Status
= gBS
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**) &MpProtocol
);
282 if (EFI_ERROR (Status
)) {
284 // MP protocol is not installed
286 return EFI_UNSUPPORTED
;
289 Status
= MpProtocol
->GetNumberOfProcessors(
294 if (EFI_ERROR(Status
)){
298 Status
= gBS
->AllocatePool(
300 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
301 (VOID
**) &ProcessorLocBuf
303 if (EFI_ERROR(Status
)){
308 // Get each processor Location info
310 for (Index
= 0; Index
< ProcessorNum
; Index
++) {
311 Status
= MpProtocol
->GetProcessorInfo(
316 if (EFI_ERROR(Status
)){
317 FreePool(ProcessorLocBuf
);
322 // Get all Processor Location info & measure
325 &ProcessorLocBuf
[Index
],
326 &ProcessorInfo
.Location
,
327 sizeof(EFI_CPU_PHYSICAL_LOCATION
)
331 *LocationBuf
= ProcessorLocBuf
;
338 The EFI_TREE_PROTOCOL GetCapability function call provides protocol
339 capability information and state information about the TrEE.
341 @param[in] This Indicates the calling context
342 @param[in, out] ProtocolCapability The caller allocates memory for a TREE_BOOT_SERVICE_CAPABILITY
343 structure and sets the size field to the size of the structure allocated.
344 The callee fills in the fields with the EFI protocol capability information
345 and the current TrEE state information up to the number of fields which
346 fit within the size of the structure passed in.
348 @retval EFI_SUCCESS Operation completed successfully.
349 @retval EFI_DEVICE_ERROR The command was unsuccessful.
350 The ProtocolCapability variable will not be populated.
351 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
352 The ProtocolCapability variable will not be populated.
353 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
354 It will be partially populated (required Size field will be set).
359 IN EFI_TREE_PROTOCOL
*This
,
360 IN OUT TREE_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
363 DEBUG ((EFI_D_INFO
, "TreeGetCapability ...\n"));
365 if ((This
== NULL
) || (ProtocolCapability
== NULL
)) {
366 return EFI_INVALID_PARAMETER
;
369 if (ProtocolCapability
->Size
< mTcgDxeData
.BsCap
.Size
) {
370 ProtocolCapability
->Size
= mTcgDxeData
.BsCap
.Size
;
371 return EFI_BUFFER_TOO_SMALL
;
374 CopyMem (ProtocolCapability
, &mTcgDxeData
.BsCap
, mTcgDxeData
.BsCap
.Size
);
375 DEBUG ((EFI_D_INFO
, "TreeGetCapability - %r\n", EFI_SUCCESS
));
380 This function dump event log.
382 @param[in] EventLogFormat The type of the event log for which the information is requested.
383 @param[in] EventLogLocation A pointer to the memory address of the event log.
384 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
385 address of the start of the last entry in the event log in memory.
389 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
390 IN EFI_PHYSICAL_ADDRESS EventLogLocation
,
391 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry
394 TCG_PCR_EVENT_HDR
*EventHdr
;
397 DEBUG ((EFI_D_INFO
, "EventLogFormat: (0x%x)\n", EventLogFormat
));
399 switch (EventLogFormat
) {
400 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
401 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)EventLogLocation
;
402 while ((UINTN
)EventHdr
<= EventLogLastEntry
) {
403 DEBUG ((EFI_D_INFO
, " Event:\n"));
404 DEBUG ((EFI_D_INFO
, " PCRIndex - %d\n", EventHdr
->PCRIndex
));
405 DEBUG ((EFI_D_INFO
, " EventType - 0x%08x\n", EventHdr
->EventType
));
406 DEBUG ((EFI_D_INFO
, " Digest - "));
407 for (Index
= 0; Index
< sizeof(TCG_DIGEST
); Index
++) {
408 DEBUG ((EFI_D_INFO
, "%02x ", EventHdr
->Digest
.digest
[Index
]));
410 DEBUG ((EFI_D_INFO
, "\n"));
411 DEBUG ((EFI_D_INFO
, " EventSize - 0x%08x\n", EventHdr
->EventSize
));
412 InternalDumpHex ((UINT8
*)(EventHdr
+ 1), EventHdr
->EventSize
);
413 EventHdr
= (TCG_PCR_EVENT_HDR
*)((UINTN
)EventHdr
+ sizeof(TCG_PCR_EVENT_HDR
) + EventHdr
->EventSize
);
422 The EFI_TREE_PROTOCOL Get Event Log function call allows a caller to
423 retrieve the address of a given event log and its last entry.
425 @param[in] This Indicates the calling context
426 @param[in] EventLogFormat The type of the event log for which the information is requested.
427 @param[out] EventLogLocation A pointer to the memory address of the event log.
428 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
429 address of the start of the last entry in the event log in memory.
430 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
431 have exceeded the area allocated for events, this value is set to TRUE.
432 Otherwise, the value will be FALSE and the Event Log will be complete.
434 @retval EFI_SUCCESS Operation completed successfully.
435 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
436 (e.g. asking for an event log whose format is not supported).
441 IN EFI_TREE_PROTOCOL
*This
,
442 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
443 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
444 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
,
445 OUT BOOLEAN
*EventLogTruncated
450 DEBUG ((EFI_D_INFO
, "TreeGetEventLog ...\n"));
453 return EFI_INVALID_PARAMETER
;
456 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
457 if (EventLogFormat
== mTreeEventInfo
[Index
].LogFormat
) {
462 if (Index
== sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0])) {
463 return EFI_INVALID_PARAMETER
;
466 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
467 if (EventLogLocation
!= NULL
) {
468 *EventLogLocation
= 0;
470 if (EventLogLastEntry
!= NULL
) {
471 *EventLogLastEntry
= 0;
473 if (EventLogTruncated
!= NULL
) {
474 *EventLogTruncated
= FALSE
;
479 if (EventLogLocation
!= NULL
) {
480 *EventLogLocation
= mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
;
481 DEBUG ((EFI_D_INFO
, "TreeGetEventLog (EventLogLocation - %x)\n", *EventLogLocation
));
484 if (EventLogLastEntry
!= NULL
) {
485 if (!mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
) {
486 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
488 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
;
490 DEBUG ((EFI_D_INFO
, "TreeGetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry
));
493 if (EventLogTruncated
!= NULL
) {
494 *EventLogTruncated
= mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
;
495 DEBUG ((EFI_D_INFO
, "TreeGetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated
));
498 DEBUG ((EFI_D_INFO
, "TreeGetEventLog - %r\n", EFI_SUCCESS
));
500 // Dump Event Log for debug purpose
501 if ((EventLogLocation
!= NULL
) && (EventLogLastEntry
!= NULL
)) {
502 DumpEventLog (EventLogFormat
, *EventLogLocation
, *EventLogLastEntry
);
509 Add a new entry to the Event Log.
511 @param[in, out] EventLogPtr Pointer to the Event Log data.
512 @param[in, out] LogSize Size of the Event Log.
513 @param[in] MaxSize Maximum size of the Event Log.
514 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
515 @param[in] NewEventHdrSize New event header size.
516 @param[in] NewEventData Pointer to the new event data.
517 @param[in] NewEventSize New event data size.
519 @retval EFI_SUCCESS The new event log entry was added.
520 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
525 IN OUT UINT8
**EventLogPtr
,
526 IN OUT UINTN
*LogSize
,
528 IN VOID
*NewEventHdr
,
529 IN UINT32 NewEventHdrSize
,
530 IN UINT8
*NewEventData
,
531 IN UINT32 NewEventSize
536 if (NewEventSize
> MAX_ADDRESS
- NewEventHdrSize
) {
537 return EFI_OUT_OF_RESOURCES
;
540 NewLogSize
= NewEventHdrSize
+ NewEventSize
;
542 if (NewLogSize
> MAX_ADDRESS
- *LogSize
) {
543 return EFI_OUT_OF_RESOURCES
;
546 if (NewLogSize
+ *LogSize
> MaxSize
) {
547 DEBUG ((EFI_D_INFO
, " MaxSize - 0x%x\n", MaxSize
));
548 DEBUG ((EFI_D_INFO
, " NewLogSize - 0x%x\n", NewLogSize
));
549 DEBUG ((EFI_D_INFO
, " LogSize - 0x%x\n", *LogSize
));
550 DEBUG ((EFI_D_INFO
, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES
));
551 return EFI_OUT_OF_RESOURCES
;
554 *EventLogPtr
+= *LogSize
;
555 *LogSize
+= NewLogSize
;
556 CopyMem (*EventLogPtr
, NewEventHdr
, NewEventHdrSize
);
558 *EventLogPtr
+ NewEventHdrSize
,
566 Add a new entry to the Event Log.
568 @param[in] EventLogFormat The type of the event log for which the information is requested.
569 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
570 @param[in] NewEventHdrSize New event header size.
571 @param[in] NewEventData Pointer to the new event data.
572 @param[in] NewEventSize New event data size.
574 @retval EFI_SUCCESS The new event log entry was added.
575 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
580 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
581 IN VOID
*NewEventHdr
,
582 IN UINT32 NewEventHdrSize
,
583 IN UINT8
*NewEventData
,
584 IN UINT32 NewEventSize
590 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
591 if (EventLogFormat
== mTreeEventInfo
[Index
].LogFormat
) {
596 if (Index
== sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0])) {
597 return EFI_INVALID_PARAMETER
;
600 if (mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
) {
601 return EFI_VOLUME_FULL
;
604 mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
= (UINT8
*)(UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
;
605 Status
= TcgCommLogEvent (
606 &mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
,
607 &mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogSize
,
608 (UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
,
615 if (Status
== EFI_DEVICE_ERROR
) {
616 return EFI_DEVICE_ERROR
;
617 } else if (Status
== EFI_OUT_OF_RESOURCES
) {
618 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
= TRUE
;
619 return EFI_VOLUME_FULL
;
620 } else if (Status
== EFI_SUCCESS
) {
621 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
= TRUE
;
628 This function get digest from digest list.
630 @param HashAlg digest algorithm
631 @param DigestList digest list
634 @retval EFI_SUCCESS Sha1Digest is found and returned.
635 @retval EFI_NOT_FOUND Sha1Digest is not found.
638 Tpm2GetDigestFromDigestList (
639 IN TPMI_ALG_HASH HashAlg
,
640 IN TPML_DIGEST_VALUES
*DigestList
,
647 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
648 for (Index
= 0; Index
< DigestList
->count
; Index
++) {
649 if (DigestList
->digests
[Index
].hashAlg
== HashAlg
) {
652 &DigestList
->digests
[Index
].digest
,
659 return EFI_NOT_FOUND
;
663 Add a new entry to the Event Log.
665 @param[in] DigestList A list of digest.
666 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
667 @param[in] NewEventData Pointer to the new event data.
669 @retval EFI_SUCCESS The new event log entry was added.
670 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
674 IN TPML_DIGEST_VALUES
*DigestList
,
675 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
676 IN UINT8
*NewEventData
682 EFI_STATUS RetStatus
;
684 RetStatus
= EFI_SUCCESS
;
685 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
686 DEBUG ((EFI_D_INFO
, " LogFormat - 0x%08x\n", mTreeEventInfo
[Index
].LogFormat
));
687 switch (mTreeEventInfo
[Index
].LogFormat
) {
688 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
689 Status
= Tpm2GetDigestFromDigestList (TPM_ALG_SHA1
, DigestList
, &NewEventHdr
->Digest
);
690 if (!EFI_ERROR (Status
)) {
692 // Enter critical region
694 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
695 Status
= TcgDxeLogEvent (
696 mTreeEventInfo
[Index
].LogFormat
,
698 sizeof(TCG_PCR_EVENT_HDR
),
700 NewEventHdr
->EventSize
702 if (Status
!= EFI_SUCCESS
) {
705 gBS
->RestoreTPL (OldTpl
);
707 // Exit critical region
718 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
719 and add an entry to the Event Log.
721 @param[in] Flags Bitmap providing additional information.
722 @param[in] HashData Physical address of the start of the data buffer
723 to be hashed, extended, and logged.
724 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
725 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
726 @param[in] NewEventData Pointer to the new event data.
728 @retval EFI_SUCCESS Operation completed successfully.
729 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
730 @retval EFI_DEVICE_ERROR The command was unsuccessful.
734 TcgDxeHashLogExtendEvent (
737 IN UINT64 HashDataLen
,
738 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
739 IN UINT8
*NewEventData
743 TPML_DIGEST_VALUES DigestList
;
745 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
746 return EFI_DEVICE_ERROR
;
749 Status
= HashAndExtend (
750 NewEventHdr
->PCRIndex
,
755 if (!EFI_ERROR (Status
)) {
756 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
757 Status
= TcgDxeLogHashEvent (&DigestList
, NewEventHdr
, NewEventData
);
761 if (Status
== EFI_DEVICE_ERROR
) {
762 DEBUG ((EFI_D_ERROR
, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status
));
763 mTcgDxeData
.BsCap
.TrEEPresentFlag
= FALSE
;
765 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
766 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
774 The EFI_TREE_PROTOCOL HashLogExtendEvent function call provides callers with
775 an opportunity to extend and optionally log events without requiring
776 knowledge of actual TPM commands.
777 The extend operation will occur even if this function cannot create an event
778 log entry (e.g. due to the event log being full).
780 @param[in] This Indicates the calling context
781 @param[in] Flags Bitmap providing additional information.
782 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
783 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
784 @param[in] Event Pointer to data buffer containing information about the event.
786 @retval EFI_SUCCESS Operation completed successfully.
787 @retval EFI_DEVICE_ERROR The command was unsuccessful.
788 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
789 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
790 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
794 TreeHashLogExtendEvent (
795 IN EFI_TREE_PROTOCOL
*This
,
797 IN EFI_PHYSICAL_ADDRESS DataToHash
,
798 IN UINT64 DataToHashLen
,
803 TCG_PCR_EVENT_HDR NewEventHdr
;
804 TPML_DIGEST_VALUES DigestList
;
806 DEBUG ((EFI_D_INFO
, "TreeHashLogExtendEvent ...\n"));
808 if ((This
== NULL
) || (DataToHash
== 0) || (Event
== NULL
)) {
809 return EFI_INVALID_PARAMETER
;
812 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
813 return EFI_UNSUPPORTED
;
816 if (Event
->Size
< Event
->Header
.HeaderSize
+ sizeof(UINT32
)) {
817 return EFI_INVALID_PARAMETER
;
820 if (Event
->Header
.PCRIndex
> MAX_PCR_INDEX
) {
821 return EFI_INVALID_PARAMETER
;
824 NewEventHdr
.PCRIndex
= Event
->Header
.PCRIndex
;
825 NewEventHdr
.EventType
= Event
->Header
.EventType
;
826 NewEventHdr
.EventSize
= Event
->Size
- sizeof(UINT32
) - Event
->Header
.HeaderSize
;
827 if ((Flags
& PE_COFF_IMAGE
) != 0) {
828 Status
= MeasurePeImageAndExtend (
829 NewEventHdr
.PCRIndex
,
831 (UINTN
)DataToHashLen
,
834 if (!EFI_ERROR (Status
)) {
835 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
836 Status
= TcgDxeLogHashEvent (&DigestList
, &NewEventHdr
, Event
->Event
);
839 if (Status
== EFI_DEVICE_ERROR
) {
840 DEBUG ((EFI_D_ERROR
, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status
));
841 mTcgDxeData
.BsCap
.TrEEPresentFlag
= FALSE
;
843 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
844 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
848 Status
= TcgDxeHashLogExtendEvent (
850 (UINT8
*) (UINTN
) DataToHash
,
856 DEBUG ((EFI_D_INFO
, "TreeHashLogExtendEvent - %r\n", Status
));
861 This service enables the sending of commands to the TrEE.
863 @param[in] This Indicates the calling context
864 @param[in] InputParameterBlockSize Size of the TrEE input parameter block.
865 @param[in] InputParameterBlock Pointer to the TrEE input parameter block.
866 @param[in] OutputParameterBlockSize Size of the TrEE output parameter block.
867 @param[in] OutputParameterBlock Pointer to the TrEE output parameter block.
869 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
870 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
871 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
872 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
877 IN EFI_TREE_PROTOCOL
*This
,
878 IN UINT32 InputParameterBlockSize
,
879 IN UINT8
*InputParameterBlock
,
880 IN UINT32 OutputParameterBlockSize
,
881 IN UINT8
*OutputParameterBlock
886 DEBUG ((EFI_D_INFO
, "TreeSubmitCommand ...\n"));
888 if ((This
== NULL
) ||
889 (InputParameterBlockSize
== 0) || (InputParameterBlock
== NULL
) ||
890 (OutputParameterBlockSize
== 0) || (OutputParameterBlock
== NULL
)) {
891 return EFI_INVALID_PARAMETER
;
894 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
895 return EFI_UNSUPPORTED
;
898 if (InputParameterBlockSize
>= mTcgDxeData
.BsCap
.MaxCommandSize
) {
899 return EFI_INVALID_PARAMETER
;
901 if (OutputParameterBlockSize
>= mTcgDxeData
.BsCap
.MaxResponseSize
) {
902 return EFI_INVALID_PARAMETER
;
905 Status
= Tpm2SubmitCommand (
906 InputParameterBlockSize
,
908 &OutputParameterBlockSize
,
911 DEBUG ((EFI_D_INFO
, "TreeSubmitCommand - %r\n", Status
));
916 EFI_TREE_PROTOCOL mTreeProtocol
= {
919 TreeHashLogExtendEvent
,
924 Initialize the Event Log and log events passed from the PEI phase.
926 @retval EFI_SUCCESS Operation completed successfully.
927 @retval EFI_OUT_OF_RESOURCES Out of memory.
937 EFI_PEI_HOB_POINTERS GuidHob
;
938 EFI_PHYSICAL_ADDRESS Lasa
;
941 DEBUG ((EFI_D_INFO
, "SetupEventLog\n"));
944 // 1. Create Log Area
946 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
947 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogFormat
= mTreeEventInfo
[Index
].LogFormat
;
948 Lasa
= (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1);
949 Status
= gBS
->AllocatePages (
952 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE
),
955 if (EFI_ERROR (Status
)) {
958 mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
= Lasa
;
959 mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
= EFI_TCG_LOG_AREA_SIZE
;
961 // To initialize them as 0xFF is recommended
962 // because the OS can know the last entry for that.
964 SetMem ((VOID
*)(UINTN
)Lasa
, EFI_TCG_LOG_AREA_SIZE
, 0xFF);
968 // 2. Create ACPI table for TCG1.2 only
970 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
971 mTcgClientAcpiTemplate
.Lasa
= mTcgDxeData
.EventLogAreaStruct
[0].Lasa
;
972 mTcgClientAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
974 mTcgServerAcpiTemplate
.Lasa
= mTcgDxeData
.EventLogAreaStruct
[0].Lasa
;
975 mTcgServerAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
979 // 3. Sync data from PEI to DXE
981 Status
= EFI_SUCCESS
;
982 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
983 GuidHob
.Raw
= GetHobList ();
984 Status
= EFI_SUCCESS
;
985 while (!EFI_ERROR (Status
) &&
986 (GuidHob
.Raw
= GetNextGuidHob (mTreeEventInfo
[Index
].EventGuid
, GuidHob
.Raw
)) != NULL
) {
987 TcgEvent
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
988 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
989 switch (mTreeEventInfo
[Index
].LogFormat
) {
990 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
991 Status
= TcgDxeLogEvent (
992 mTreeEventInfo
[Index
].LogFormat
,
994 sizeof(TCG_PCR_EVENT_HDR
),
995 ((TCG_PCR_EVENT
*)TcgEvent
)->Event
,
996 ((TCG_PCR_EVENT_HDR
*)TcgEvent
)->EventSize
1007 Measure and log an action string, and extend the measurement result into PCR[5].
1009 @param[in] String A specific string that indicates an Action event.
1011 @retval EFI_SUCCESS Operation completed successfully.
1012 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1020 TCG_PCR_EVENT_HDR TcgEvent
;
1022 TcgEvent
.PCRIndex
= 5;
1023 TcgEvent
.EventType
= EV_EFI_ACTION
;
1024 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
1025 return TcgDxeHashLogExtendEvent (
1035 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1037 @retval EFI_SUCCESS Operation completed successfully.
1038 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1042 MeasureHandoffTables (
1047 TCG_PCR_EVENT_HDR TcgEvent
;
1048 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
1050 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
1052 ProcessorLocBuf
= NULL
;
1053 Status
= EFI_SUCCESS
;
1055 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
1058 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1060 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
1062 if (!EFI_ERROR(Status
)){
1063 TcgEvent
.PCRIndex
= 1;
1064 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
1065 TcgEvent
.EventSize
= sizeof (HandoffTables
);
1067 HandoffTables
.NumberOfTables
= 1;
1068 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
1069 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
1071 Status
= TcgDxeHashLogExtendEvent (
1073 (UINT8
*)(UINTN
)ProcessorLocBuf
,
1074 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
1076 (UINT8
*)&HandoffTables
1079 FreePool(ProcessorLocBuf
);
1087 Measure and log Separator event, and extend the measurement result into a specific PCR.
1089 @param[in] PCRIndex PCR index.
1091 @retval EFI_SUCCESS Operation completed successfully.
1092 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1096 MeasureSeparatorEvent (
1097 IN TPM_PCRINDEX PCRIndex
1100 TCG_PCR_EVENT_HDR TcgEvent
;
1103 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex
));
1106 TcgEvent
.PCRIndex
= PCRIndex
;
1107 TcgEvent
.EventType
= EV_SEPARATOR
;
1108 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
1109 return TcgDxeHashLogExtendEvent (
1111 (UINT8
*)&EventData
,
1119 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1121 @param[in] PCRIndex PCR Index.
1122 @param[in] EventType Event type.
1123 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1124 @param[in] VendorGuid A unique identifier for the vendor.
1125 @param[in] VarData The content of the variable data.
1126 @param[in] VarSize The size of the variable data.
1128 @retval EFI_SUCCESS Operation completed successfully.
1129 @retval EFI_OUT_OF_RESOURCES Out of memory.
1130 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1135 IN TPM_PCRINDEX PCRIndex
,
1136 IN TCG_EVENTTYPE EventType
,
1138 IN EFI_GUID
*VendorGuid
,
1144 TCG_PCR_EVENT_HDR TcgEvent
;
1145 UINTN VarNameLength
;
1146 EFI_VARIABLE_DATA_TREE
*VarLog
;
1148 DEBUG ((EFI_D_INFO
, "TrEEDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN
)PCRIndex
, (UINTN
)EventType
));
1149 DEBUG ((EFI_D_INFO
, "VariableName - %s, VendorGuid - %g)\n", VarName
, VendorGuid
));
1151 VarNameLength
= StrLen (VarName
);
1152 TcgEvent
.PCRIndex
= PCRIndex
;
1153 TcgEvent
.EventType
= EventType
;
1154 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
1155 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
1157 VarLog
= (EFI_VARIABLE_DATA_TREE
*)AllocatePool (TcgEvent
.EventSize
);
1158 if (VarLog
== NULL
) {
1159 return EFI_OUT_OF_RESOURCES
;
1162 VarLog
->VariableName
= *VendorGuid
;
1163 VarLog
->UnicodeNameLength
= VarNameLength
;
1164 VarLog
->VariableDataLength
= VarSize
;
1166 VarLog
->UnicodeName
,
1168 VarNameLength
* sizeof (*VarName
)
1170 if (VarSize
!= 0 && VarData
!= NULL
) {
1172 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
1178 Status
= TcgDxeHashLogExtendEvent (
1191 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1193 @param[in] PCRIndex PCR Index.
1194 @param[in] EventType Event type.
1195 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1196 @param[in] VendorGuid A unique identifier for the vendor.
1197 @param[out] VarSize The size of the variable data.
1198 @param[out] VarData Pointer to the content of the variable.
1200 @retval EFI_SUCCESS Operation completed successfully.
1201 @retval EFI_OUT_OF_RESOURCES Out of memory.
1202 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1206 ReadAndMeasureVariable (
1207 IN TPM_PCRINDEX PCRIndex
,
1208 IN TCG_EVENTTYPE EventType
,
1210 IN EFI_GUID
*VendorGuid
,
1217 Status
= GetVariable2 (VarName
, VendorGuid
, VarData
, VarSize
);
1218 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1219 if (EFI_ERROR (Status
)) {
1221 // It is valid case, so we need handle it.
1228 // if status error, VarData is freed and set NULL by GetVariable2
1230 if (EFI_ERROR (Status
)) {
1231 return EFI_NOT_FOUND
;
1235 Status
= MeasureVariable (
1247 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
1249 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1250 @param[in] VendorGuid A unique identifier for the vendor.
1251 @param[out] VarSize The size of the variable data.
1252 @param[out] VarData Pointer to the content of the variable.
1254 @retval EFI_SUCCESS Operation completed successfully.
1255 @retval EFI_OUT_OF_RESOURCES Out of memory.
1256 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1260 ReadAndMeasureBootVariable (
1262 IN EFI_GUID
*VendorGuid
,
1267 return ReadAndMeasureVariable (
1269 EV_EFI_VARIABLE_BOOT
,
1278 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1280 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1281 @param[in] VendorGuid A unique identifier for the vendor.
1282 @param[out] VarSize The size of the variable data.
1283 @param[out] VarData Pointer to the content of the variable.
1285 @retval EFI_SUCCESS Operation completed successfully.
1286 @retval EFI_OUT_OF_RESOURCES Out of memory.
1287 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1291 ReadAndMeasureSecureVariable (
1293 IN EFI_GUID
*VendorGuid
,
1298 return ReadAndMeasureVariable (
1300 EV_EFI_VARIABLE_DRIVER_CONFIG
,
1309 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1311 The EFI boot variables are BootOrder and Boot#### variables.
1313 @retval EFI_SUCCESS Operation completed successfully.
1314 @retval EFI_OUT_OF_RESOURCES Out of memory.
1315 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1319 MeasureAllBootVariables (
1330 Status
= ReadAndMeasureBootVariable (
1332 &gEfiGlobalVariableGuid
,
1334 (VOID
**) &BootOrder
1336 if (Status
== EFI_NOT_FOUND
|| BootOrder
== NULL
) {
1340 if (EFI_ERROR (Status
)) {
1342 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1344 FreePool (BootOrder
);
1348 BootCount
/= sizeof (*BootOrder
);
1349 for (Index
= 0; Index
< BootCount
; Index
++) {
1350 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
1351 Status
= ReadAndMeasureBootVariable (
1353 &gEfiGlobalVariableGuid
,
1357 if (!EFI_ERROR (Status
)) {
1358 FreePool (BootVarData
);
1362 FreePool (BootOrder
);
1367 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1369 The EFI boot variables are BootOrder and Boot#### variables.
1371 @retval EFI_SUCCESS Operation completed successfully.
1372 @retval EFI_OUT_OF_RESOURCES Out of memory.
1373 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1377 MeasureAllSecureVariables (
1386 Status
= EFI_NOT_FOUND
;
1387 for (Index
= 0; Index
< sizeof(mVariableType
)/sizeof(mVariableType
[0]); Index
++) {
1388 Status
= ReadAndMeasureSecureVariable (
1389 mVariableType
[Index
].VariableName
,
1390 mVariableType
[Index
].VendorGuid
,
1394 if (!EFI_ERROR (Status
)) {
1405 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
1407 @retval EFI_SUCCESS Operation completed successfully.
1408 @retval EFI_OUT_OF_RESOURCES Out of memory.
1409 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1413 MeasureLaunchOfFirmwareDebugger (
1417 TCG_PCR_EVENT_HDR TcgEvent
;
1419 TcgEvent
.PCRIndex
= 7;
1420 TcgEvent
.EventType
= EV_EFI_ACTION
;
1421 TcgEvent
.EventSize
= sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1;
1422 return TcgDxeHashLogExtendEvent (
1424 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
,
1425 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1,
1427 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
1432 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
1434 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
1435 - The contents of the SecureBoot variable
1436 - The contents of the PK variable
1437 - The contents of the KEK variable
1438 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
1439 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
1441 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
1443 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
1444 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
1446 @param[in] Event Event whose notification function is being invoked
1447 @param[in] Context Pointer to the notification function's context
1451 MeasureSecureBootPolicy (
1459 Status
= gBS
->LocateProtocol (&gEfiVariableWriteArchProtocolGuid
, NULL
, (VOID
**)&Protocol
);
1460 if (EFI_ERROR (Status
)) {
1464 if (PcdGetBool (PcdFirmwareDebuggerInitialized
)) {
1465 Status
= MeasureLaunchOfFirmwareDebugger ();
1466 DEBUG ((EFI_D_INFO
, "MeasureLaunchOfFirmwareDebugger - %r\n", Status
));
1469 Status
= MeasureAllSecureVariables ();
1470 DEBUG ((EFI_D_INFO
, "MeasureAllSecureVariables - %r\n", Status
));
1473 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
1474 // and ImageVerification (Authority)
1475 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
1476 // the Authority measurement happen before ReadToBoot event.
1478 Status
= MeasureSeparatorEvent (7);
1479 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent - %r\n", Status
));
1484 Ready to Boot Event notification handler.
1486 Sequence of OS boot events is measured in this event notification handler.
1488 @param[in] Event Event whose notification function is being invoked
1489 @param[in] Context Pointer to the notification function's context
1500 TPM_PCRINDEX PcrIndex
;
1502 PERF_START_EX (mImageHandle
, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE
);
1503 if (mBootAttempts
== 0) {
1506 // Measure handoff tables.
1508 Status
= MeasureHandoffTables ();
1509 if (EFI_ERROR (Status
)) {
1510 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
1514 // Measure BootOrder & Boot#### variables.
1516 Status
= MeasureAllBootVariables ();
1517 if (EFI_ERROR (Status
)) {
1518 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
1522 // 1. This is the first boot attempt.
1524 Status
= TcgMeasureAction (
1525 EFI_CALLING_EFI_APPLICATION
1527 if (EFI_ERROR (Status
)) {
1528 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
1532 // 2. Draw a line between pre-boot env and entering post-boot env.
1533 // PCR[7] is already done.
1535 for (PcrIndex
= 0; PcrIndex
< 7; PcrIndex
++) {
1536 Status
= MeasureSeparatorEvent (PcrIndex
);
1537 if (EFI_ERROR (Status
)) {
1538 DEBUG ((EFI_D_ERROR
, "Seperator Event not Measured. Error!\n"));
1543 // 3. Measure GPT. It would be done in SAP driver.
1547 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1551 // 5. Read & Measure variable. BootOrder already measured.
1555 // 6. Not first attempt, meaning a return from last attempt
1557 Status
= TcgMeasureAction (
1558 EFI_RETURNING_FROM_EFI_APPLICATOIN
1560 if (EFI_ERROR (Status
)) {
1561 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN
));
1565 DEBUG ((EFI_D_INFO
, "TPM2 TrEEDxe Measure Data when ReadyToBoot\n"));
1567 // Increase boot attempt counter.
1570 PERF_END_EX (mImageHandle
, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE
+ 1);
1574 Install TCG ACPI Table when ACPI Table Protocol is available.
1576 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1577 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1578 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1580 @param[in] Event Event whose notification function is being invoked
1581 @param[in] Context Pointer to the notification function's context
1592 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
1596 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
1597 if (EFI_ERROR (Status
)) {
1601 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
1602 CopyMem (mTcgClientAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgClientAcpiTemplate
.Header
.OemId
));
1603 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1604 CopyMem (&mTcgClientAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1605 mTcgClientAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1606 mTcgClientAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1607 mTcgClientAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1609 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1610 // service of the ACPI table protocol to install it.
1612 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgClientAcpiTemplate
, sizeof (mTcgClientAcpiTemplate
));
1613 mTcgClientAcpiTemplate
.Header
.Checksum
= Checksum
;
1615 Status
= AcpiTable
->InstallAcpiTable (
1617 &mTcgClientAcpiTemplate
,
1618 sizeof (mTcgClientAcpiTemplate
),
1622 CopyMem (mTcgServerAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgServerAcpiTemplate
.Header
.OemId
));
1623 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1624 CopyMem (&mTcgServerAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1625 mTcgServerAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1626 mTcgServerAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1627 mTcgServerAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1629 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1630 // service of the ACPI table protocol to install it.
1632 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgServerAcpiTemplate
, sizeof (mTcgServerAcpiTemplate
));
1633 mTcgServerAcpiTemplate
.Header
.Checksum
= Checksum
;
1635 mTcgServerAcpiTemplate
.BaseAddress
.Address
= PcdGet64 (PcdTpmBaseAddress
);
1636 Status
= AcpiTable
->InstallAcpiTable (
1638 &mTcgServerAcpiTemplate
,
1639 sizeof (mTcgServerAcpiTemplate
),
1644 if (EFI_ERROR (Status
)) {
1645 DEBUG((EFI_D_ERROR
, "Tcg Acpi Table installation failure"));
1650 Exit Boot Services Event notification handler.
1652 Measure invocation and success of ExitBootServices.
1654 @param[in] Event Event whose notification function is being invoked
1655 @param[in] Context Pointer to the notification function's context
1660 OnExitBootServices (
1668 // Measure invocation of ExitBootServices,
1670 Status
= TcgMeasureAction (
1671 EFI_EXIT_BOOT_SERVICES_INVOCATION
1673 if (EFI_ERROR (Status
)) {
1674 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION
));
1678 // Measure success of ExitBootServices
1680 Status
= TcgMeasureAction (
1681 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1683 if (EFI_ERROR (Status
)) {
1684 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED
));
1689 Exit Boot Services Failed Event notification handler.
1691 Measure Failure of ExitBootServices.
1693 @param[in] Event Event whose notification function is being invoked
1694 @param[in] Context Pointer to the notification function's context
1699 OnExitBootServicesFailed (
1707 // Measure Failure of ExitBootServices,
1709 Status
= TcgMeasureAction (
1710 EFI_EXIT_BOOT_SERVICES_FAILED
1712 if (EFI_ERROR (Status
)) {
1713 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED
));
1719 The function install TrEE protocol.
1721 @retval EFI_SUCCESS TrEE protocol is installed.
1722 @retval other Some error occurs.
1733 Status
= gBS
->InstallMultipleProtocolInterfaces (
1735 &gEfiTrEEProtocolGuid
,
1743 The driver's entry point. It publishes EFI TrEE Protocol.
1745 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1746 @param[in] SystemTable A pointer to the EFI System Table.
1748 @retval EFI_SUCCESS The entry point is executed successfully.
1749 @retval other Some error occurs when executing this entry point.
1754 IN EFI_HANDLE ImageHandle
,
1755 IN EFI_SYSTEM_TABLE
*SystemTable
1761 UINT32 MaxCommandSize
;
1762 UINT32 MaxResponseSize
;
1763 TPML_PCR_SELECTION Pcrs
;
1765 UINT32 TpmHashAlgorithmBitmap
;
1767 mImageHandle
= ImageHandle
;
1769 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceNoneGuid
) ||
1770 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
1771 DEBUG ((EFI_D_ERROR
, "No TPM2 instance required!\n"));
1772 return EFI_UNSUPPORTED
;
1775 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
1776 DEBUG ((EFI_D_ERROR
, "TPM2 error!\n"));
1777 return EFI_DEVICE_ERROR
;
1780 Status
= Tpm2RequestUseTpm ();
1781 if (EFI_ERROR (Status
)) {
1782 DEBUG ((EFI_D_ERROR
, "TPM2 not detected!\n"));
1789 DEBUG ((EFI_D_INFO
, "TrEE.ProtocolVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.ProtocolVersion
.Major
, mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
));
1790 DEBUG ((EFI_D_INFO
, "TrEE.StructureVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.StructureVersion
.Major
, mTcgDxeData
.BsCap
.StructureVersion
.Minor
));
1792 Status
= Tpm2GetCapabilityManufactureID (&mTcgDxeData
.BsCap
.ManufacturerID
);
1793 if (EFI_ERROR (Status
)) {
1794 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityManufactureID fail!\n"));
1796 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData
.BsCap
.ManufacturerID
));
1800 UINT32 FirmwareVersion1
;
1801 UINT32 FirmwareVersion2
;
1803 Status
= Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1
, &FirmwareVersion2
);
1804 if (EFI_ERROR (Status
)) {
1805 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
1807 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1
, FirmwareVersion2
));
1811 Status
= Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize
, &MaxResponseSize
);
1812 if (EFI_ERROR (Status
)) {
1813 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
1815 mTcgDxeData
.BsCap
.MaxCommandSize
= (UINT16
)MaxCommandSize
;
1816 mTcgDxeData
.BsCap
.MaxResponseSize
= (UINT16
)MaxResponseSize
;
1817 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize
, MaxResponseSize
));
1820 Status
= Tpm2GetCapabilityPcrs (&Pcrs
);
1821 if (EFI_ERROR (Status
)) {
1822 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityPcrs fail!\n"));
1823 TpmHashAlgorithmBitmap
= TREE_BOOT_HASH_ALG_SHA1
;
1825 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs
.count
));
1826 TpmHashAlgorithmBitmap
= 0;
1827 for (Index
= 0; Index
< Pcrs
.count
; Index
++) {
1828 DEBUG ((EFI_D_INFO
, "hash - %x\n", Pcrs
.pcrSelections
[Index
].hash
));
1829 switch (Pcrs
.pcrSelections
[Index
].hash
) {
1831 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA1
;
1833 case TPM_ALG_SHA256
:
1834 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA256
;
1836 case TPM_ALG_SHA384
:
1837 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA384
;
1839 case TPM_ALG_SHA512
:
1840 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA512
;
1842 case TPM_ALG_SM3_256
:
1843 // TBD: Spec not define TREE_BOOT_HASH_ALG_SM3_256 yet
1848 DEBUG ((EFI_D_INFO
, "TPM.HashAlgorithmBitmap - 0x%08x\n", TpmHashAlgorithmBitmap
));
1850 DEBUG ((EFI_D_INFO
, "TrEE.SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
1851 mTcgDxeData
.BsCap
.HashAlgorithmBitmap
= TpmHashAlgorithmBitmap
;
1852 DEBUG ((EFI_D_INFO
, "TrEE.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData
.BsCap
.HashAlgorithmBitmap
));
1854 if (mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
1856 // Setup the log area and copy event log from hob list to it
1858 Status
= SetupEventLog ();
1859 ASSERT_EFI_ERROR (Status
);
1862 // Measure handoff tables, Boot#### variables etc.
1864 Status
= EfiCreateEventReadyToBootEx (
1871 Status
= gBS
->CreateEventEx (
1876 &gEfiEventExitBootServicesGuid
,
1881 // Measure Exit Boot Service failed
1883 Status
= gBS
->CreateEventEx (
1886 OnExitBootServicesFailed
,
1888 &gEventExitBootServicesFailedGuid
,
1893 // Create event callback, because we need access variable on SecureBootPolicyVariable
1894 // We should use VariableWriteArch instead of VariableArch, because Variable driver
1895 // may update SecureBoot value based on last setting.
1897 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid
, TPL_CALLBACK
, MeasureSecureBootPolicy
, NULL
, &Registration
);
1901 // Install ACPI Table
1903 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid
, TPL_CALLBACK
, InstallAcpiTable
, NULL
, &Registration
);
1906 // Install TrEEProtocol
1908 Status
= InstallTrEE ();
1909 DEBUG ((EFI_D_INFO
, "InstallTrEE - %r\n", Status
));