2 This module implements TrEE Protocol.
4 Copyright (c) 2013 - 2017, 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 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
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 Add a new entry to the Event Log.
630 @param[in] DigestList A list of digest.
631 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
632 @param[in] NewEventData Pointer to the new event data.
634 @retval EFI_SUCCESS The new event log entry was added.
635 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
639 IN TPML_DIGEST_VALUES
*DigestList
,
640 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
641 IN UINT8
*NewEventData
647 EFI_STATUS RetStatus
;
649 RetStatus
= EFI_SUCCESS
;
650 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
651 DEBUG ((EFI_D_INFO
, " LogFormat - 0x%08x\n", mTreeEventInfo
[Index
].LogFormat
));
652 switch (mTreeEventInfo
[Index
].LogFormat
) {
653 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
654 Status
= GetDigestFromDigestList (TPM_ALG_SHA1
, DigestList
, &NewEventHdr
->Digest
);
655 if (!EFI_ERROR (Status
)) {
657 // Enter critical region
659 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
660 Status
= TcgDxeLogEvent (
661 mTreeEventInfo
[Index
].LogFormat
,
663 sizeof(TCG_PCR_EVENT_HDR
),
665 NewEventHdr
->EventSize
667 if (Status
!= EFI_SUCCESS
) {
670 gBS
->RestoreTPL (OldTpl
);
672 // Exit critical region
683 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
684 and add an entry to the Event Log.
686 @param[in] Flags Bitmap providing additional information.
687 @param[in] HashData Physical address of the start of the data buffer
688 to be hashed, extended, and logged.
689 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
690 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
691 @param[in] NewEventData Pointer to the new event data.
693 @retval EFI_SUCCESS Operation completed successfully.
694 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
695 @retval EFI_DEVICE_ERROR The command was unsuccessful.
699 TcgDxeHashLogExtendEvent (
702 IN UINT64 HashDataLen
,
703 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
704 IN UINT8
*NewEventData
708 TPML_DIGEST_VALUES DigestList
;
710 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
711 return EFI_DEVICE_ERROR
;
714 Status
= HashAndExtend (
715 NewEventHdr
->PCRIndex
,
720 if (!EFI_ERROR (Status
)) {
721 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
722 Status
= TcgDxeLogHashEvent (&DigestList
, NewEventHdr
, NewEventData
);
726 if (Status
== EFI_DEVICE_ERROR
) {
727 DEBUG ((EFI_D_ERROR
, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status
));
728 mTcgDxeData
.BsCap
.TrEEPresentFlag
= FALSE
;
730 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
731 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
739 The EFI_TREE_PROTOCOL HashLogExtendEvent function call provides callers with
740 an opportunity to extend and optionally log events without requiring
741 knowledge of actual TPM commands.
742 The extend operation will occur even if this function cannot create an event
743 log entry (e.g. due to the event log being full).
745 @param[in] This Indicates the calling context
746 @param[in] Flags Bitmap providing additional information.
747 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
748 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
749 @param[in] Event Pointer to data buffer containing information about the event.
751 @retval EFI_SUCCESS Operation completed successfully.
752 @retval EFI_DEVICE_ERROR The command was unsuccessful.
753 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
754 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
755 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
759 TreeHashLogExtendEvent (
760 IN EFI_TREE_PROTOCOL
*This
,
762 IN EFI_PHYSICAL_ADDRESS DataToHash
,
763 IN UINT64 DataToHashLen
,
768 TCG_PCR_EVENT_HDR NewEventHdr
;
769 TPML_DIGEST_VALUES DigestList
;
771 DEBUG ((EFI_D_INFO
, "TreeHashLogExtendEvent ...\n"));
773 if ((This
== NULL
) || (DataToHash
== 0) || (Event
== NULL
)) {
774 return EFI_INVALID_PARAMETER
;
777 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
778 return EFI_UNSUPPORTED
;
781 if (Event
->Size
< Event
->Header
.HeaderSize
+ sizeof(UINT32
)) {
782 return EFI_INVALID_PARAMETER
;
785 if (Event
->Header
.PCRIndex
> MAX_PCR_INDEX
) {
786 return EFI_INVALID_PARAMETER
;
789 NewEventHdr
.PCRIndex
= Event
->Header
.PCRIndex
;
790 NewEventHdr
.EventType
= Event
->Header
.EventType
;
791 NewEventHdr
.EventSize
= Event
->Size
- sizeof(UINT32
) - Event
->Header
.HeaderSize
;
792 if ((Flags
& PE_COFF_IMAGE
) != 0) {
793 Status
= MeasurePeImageAndExtend (
794 NewEventHdr
.PCRIndex
,
796 (UINTN
)DataToHashLen
,
799 if (!EFI_ERROR (Status
)) {
800 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
801 Status
= TcgDxeLogHashEvent (&DigestList
, &NewEventHdr
, Event
->Event
);
804 if (Status
== EFI_DEVICE_ERROR
) {
805 DEBUG ((EFI_D_ERROR
, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status
));
806 mTcgDxeData
.BsCap
.TrEEPresentFlag
= FALSE
;
808 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
809 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
813 Status
= TcgDxeHashLogExtendEvent (
815 (UINT8
*) (UINTN
) DataToHash
,
821 DEBUG ((EFI_D_INFO
, "TreeHashLogExtendEvent - %r\n", Status
));
826 This service enables the sending of commands to the TrEE.
828 @param[in] This Indicates the calling context
829 @param[in] InputParameterBlockSize Size of the TrEE input parameter block.
830 @param[in] InputParameterBlock Pointer to the TrEE input parameter block.
831 @param[in] OutputParameterBlockSize Size of the TrEE output parameter block.
832 @param[in] OutputParameterBlock Pointer to the TrEE output parameter block.
834 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
835 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
836 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
837 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
842 IN EFI_TREE_PROTOCOL
*This
,
843 IN UINT32 InputParameterBlockSize
,
844 IN UINT8
*InputParameterBlock
,
845 IN UINT32 OutputParameterBlockSize
,
846 IN UINT8
*OutputParameterBlock
851 DEBUG ((EFI_D_INFO
, "TreeSubmitCommand ...\n"));
853 if ((This
== NULL
) ||
854 (InputParameterBlockSize
== 0) || (InputParameterBlock
== NULL
) ||
855 (OutputParameterBlockSize
== 0) || (OutputParameterBlock
== NULL
)) {
856 return EFI_INVALID_PARAMETER
;
859 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
860 return EFI_UNSUPPORTED
;
863 if (InputParameterBlockSize
> mTcgDxeData
.BsCap
.MaxCommandSize
) {
864 return EFI_INVALID_PARAMETER
;
866 if (OutputParameterBlockSize
> mTcgDxeData
.BsCap
.MaxResponseSize
) {
867 return EFI_INVALID_PARAMETER
;
870 Status
= Tpm2SubmitCommand (
871 InputParameterBlockSize
,
873 &OutputParameterBlockSize
,
876 DEBUG ((EFI_D_INFO
, "TreeSubmitCommand - %r\n", Status
));
881 EFI_TREE_PROTOCOL mTreeProtocol
= {
884 TreeHashLogExtendEvent
,
889 Initialize the Event Log and log events passed from the PEI phase.
891 @retval EFI_SUCCESS Operation completed successfully.
892 @retval EFI_OUT_OF_RESOURCES Out of memory.
902 EFI_PEI_HOB_POINTERS GuidHob
;
903 EFI_PHYSICAL_ADDRESS Lasa
;
906 DEBUG ((EFI_D_INFO
, "SetupEventLog\n"));
909 // 1. Create Log Area
911 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
912 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogFormat
= mTreeEventInfo
[Index
].LogFormat
;
913 Lasa
= (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1);
914 Status
= gBS
->AllocatePages (
917 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen
)),
920 if (EFI_ERROR (Status
)) {
923 mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
= Lasa
;
924 mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
926 // To initialize them as 0xFF is recommended
927 // because the OS can know the last entry for that.
929 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcgLogAreaMinLen
), 0xFF);
933 // 2. Create ACPI table for TCG1.2 only
935 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
936 mTcgClientAcpiTemplate
.Lasa
= mTcgDxeData
.EventLogAreaStruct
[0].Lasa
;
937 mTcgClientAcpiTemplate
.Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
939 mTcgServerAcpiTemplate
.Lasa
= mTcgDxeData
.EventLogAreaStruct
[0].Lasa
;
940 mTcgServerAcpiTemplate
.Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
944 // 3. Sync data from PEI to DXE
946 Status
= EFI_SUCCESS
;
947 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
948 GuidHob
.Raw
= GetHobList ();
949 Status
= EFI_SUCCESS
;
950 while (!EFI_ERROR (Status
) &&
951 (GuidHob
.Raw
= GetNextGuidHob (mTreeEventInfo
[Index
].EventGuid
, GuidHob
.Raw
)) != NULL
) {
952 TcgEvent
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
953 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
954 switch (mTreeEventInfo
[Index
].LogFormat
) {
955 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
956 Status
= TcgDxeLogEvent (
957 mTreeEventInfo
[Index
].LogFormat
,
959 sizeof(TCG_PCR_EVENT_HDR
),
960 ((TCG_PCR_EVENT
*)TcgEvent
)->Event
,
961 ((TCG_PCR_EVENT_HDR
*)TcgEvent
)->EventSize
972 Measure and log an action string, and extend the measurement result into PCR[5].
974 @param[in] String A specific string that indicates an Action event.
976 @retval EFI_SUCCESS Operation completed successfully.
977 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
985 TCG_PCR_EVENT_HDR TcgEvent
;
987 TcgEvent
.PCRIndex
= 5;
988 TcgEvent
.EventType
= EV_EFI_ACTION
;
989 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
990 return TcgDxeHashLogExtendEvent (
1000 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1002 @retval EFI_SUCCESS Operation completed successfully.
1003 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1007 MeasureHandoffTables (
1012 TCG_PCR_EVENT_HDR TcgEvent
;
1013 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
1015 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
1017 ProcessorLocBuf
= NULL
;
1018 Status
= EFI_SUCCESS
;
1020 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
1023 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1025 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
1027 if (!EFI_ERROR(Status
)){
1028 TcgEvent
.PCRIndex
= 1;
1029 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
1030 TcgEvent
.EventSize
= sizeof (HandoffTables
);
1032 HandoffTables
.NumberOfTables
= 1;
1033 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
1034 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
1036 Status
= TcgDxeHashLogExtendEvent (
1038 (UINT8
*)(UINTN
)ProcessorLocBuf
,
1039 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
1041 (UINT8
*)&HandoffTables
1044 FreePool(ProcessorLocBuf
);
1052 Measure and log Separator event, and extend the measurement result into a specific PCR.
1054 @param[in] PCRIndex PCR index.
1056 @retval EFI_SUCCESS Operation completed successfully.
1057 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1061 MeasureSeparatorEvent (
1062 IN TPM_PCRINDEX PCRIndex
1065 TCG_PCR_EVENT_HDR TcgEvent
;
1068 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex
));
1071 TcgEvent
.PCRIndex
= PCRIndex
;
1072 TcgEvent
.EventType
= EV_SEPARATOR
;
1073 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
1074 return TcgDxeHashLogExtendEvent (
1076 (UINT8
*)&EventData
,
1084 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1086 @param[in] PCRIndex PCR Index.
1087 @param[in] EventType Event type.
1088 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1089 @param[in] VendorGuid A unique identifier for the vendor.
1090 @param[in] VarData The content of the variable data.
1091 @param[in] VarSize The size of the variable data.
1093 @retval EFI_SUCCESS Operation completed successfully.
1094 @retval EFI_OUT_OF_RESOURCES Out of memory.
1095 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1100 IN TPM_PCRINDEX PCRIndex
,
1101 IN TCG_EVENTTYPE EventType
,
1103 IN EFI_GUID
*VendorGuid
,
1109 TCG_PCR_EVENT_HDR TcgEvent
;
1110 UINTN VarNameLength
;
1111 EFI_VARIABLE_DATA_TREE
*VarLog
;
1113 DEBUG ((EFI_D_INFO
, "TrEEDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN
)PCRIndex
, (UINTN
)EventType
));
1114 DEBUG ((EFI_D_INFO
, "VariableName - %s, VendorGuid - %g)\n", VarName
, VendorGuid
));
1116 VarNameLength
= StrLen (VarName
);
1117 TcgEvent
.PCRIndex
= PCRIndex
;
1118 TcgEvent
.EventType
= EventType
;
1119 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
1120 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
1122 VarLog
= (EFI_VARIABLE_DATA_TREE
*)AllocatePool (TcgEvent
.EventSize
);
1123 if (VarLog
== NULL
) {
1124 return EFI_OUT_OF_RESOURCES
;
1127 VarLog
->VariableName
= *VendorGuid
;
1128 VarLog
->UnicodeNameLength
= VarNameLength
;
1129 VarLog
->VariableDataLength
= VarSize
;
1131 VarLog
->UnicodeName
,
1133 VarNameLength
* sizeof (*VarName
)
1135 if (VarSize
!= 0 && VarData
!= NULL
) {
1137 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
1143 Status
= TcgDxeHashLogExtendEvent (
1156 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1158 @param[in] PCRIndex PCR Index.
1159 @param[in] EventType Event type.
1160 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1161 @param[in] VendorGuid A unique identifier for the vendor.
1162 @param[out] VarSize The size of the variable data.
1163 @param[out] VarData Pointer to the content of the variable.
1165 @retval EFI_SUCCESS Operation completed successfully.
1166 @retval EFI_OUT_OF_RESOURCES Out of memory.
1167 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1171 ReadAndMeasureVariable (
1172 IN TPM_PCRINDEX PCRIndex
,
1173 IN TCG_EVENTTYPE EventType
,
1175 IN EFI_GUID
*VendorGuid
,
1182 Status
= GetVariable2 (VarName
, VendorGuid
, VarData
, VarSize
);
1183 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1184 if (EFI_ERROR (Status
)) {
1186 // It is valid case, so we need handle it.
1193 // if status error, VarData is freed and set NULL by GetVariable2
1195 if (EFI_ERROR (Status
)) {
1196 return EFI_NOT_FOUND
;
1200 Status
= MeasureVariable (
1212 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
1214 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1215 @param[in] VendorGuid A unique identifier for the vendor.
1216 @param[out] VarSize The size of the variable data.
1217 @param[out] VarData Pointer to the content of the variable.
1219 @retval EFI_SUCCESS Operation completed successfully.
1220 @retval EFI_OUT_OF_RESOURCES Out of memory.
1221 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1225 ReadAndMeasureBootVariable (
1227 IN EFI_GUID
*VendorGuid
,
1232 return ReadAndMeasureVariable (
1234 EV_EFI_VARIABLE_BOOT
,
1243 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1245 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1246 @param[in] VendorGuid A unique identifier for the vendor.
1247 @param[out] VarSize The size of the variable data.
1248 @param[out] VarData Pointer to the content of the variable.
1250 @retval EFI_SUCCESS Operation completed successfully.
1251 @retval EFI_OUT_OF_RESOURCES Out of memory.
1252 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1256 ReadAndMeasureSecureVariable (
1258 IN EFI_GUID
*VendorGuid
,
1263 return ReadAndMeasureVariable (
1265 EV_EFI_VARIABLE_DRIVER_CONFIG
,
1274 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1276 The EFI boot variables are BootOrder and Boot#### variables.
1278 @retval EFI_SUCCESS Operation completed successfully.
1279 @retval EFI_OUT_OF_RESOURCES Out of memory.
1280 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1284 MeasureAllBootVariables (
1295 Status
= ReadAndMeasureBootVariable (
1297 &gEfiGlobalVariableGuid
,
1299 (VOID
**) &BootOrder
1301 if (Status
== EFI_NOT_FOUND
|| BootOrder
== NULL
) {
1305 if (EFI_ERROR (Status
)) {
1307 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1309 FreePool (BootOrder
);
1313 BootCount
/= sizeof (*BootOrder
);
1314 for (Index
= 0; Index
< BootCount
; Index
++) {
1315 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
1316 Status
= ReadAndMeasureBootVariable (
1318 &gEfiGlobalVariableGuid
,
1322 if (!EFI_ERROR (Status
)) {
1323 FreePool (BootVarData
);
1327 FreePool (BootOrder
);
1332 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1334 The EFI boot variables are BootOrder and Boot#### variables.
1336 @retval EFI_SUCCESS Operation completed successfully.
1337 @retval EFI_OUT_OF_RESOURCES Out of memory.
1338 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1342 MeasureAllSecureVariables (
1351 Status
= EFI_NOT_FOUND
;
1352 for (Index
= 0; Index
< sizeof(mVariableType
)/sizeof(mVariableType
[0]); Index
++) {
1353 Status
= ReadAndMeasureSecureVariable (
1354 mVariableType
[Index
].VariableName
,
1355 mVariableType
[Index
].VendorGuid
,
1359 if (!EFI_ERROR (Status
)) {
1370 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
1372 @retval EFI_SUCCESS Operation completed successfully.
1373 @retval EFI_OUT_OF_RESOURCES Out of memory.
1374 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1378 MeasureLaunchOfFirmwareDebugger (
1382 TCG_PCR_EVENT_HDR TcgEvent
;
1384 TcgEvent
.PCRIndex
= 7;
1385 TcgEvent
.EventType
= EV_EFI_ACTION
;
1386 TcgEvent
.EventSize
= sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1;
1387 return TcgDxeHashLogExtendEvent (
1389 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
,
1390 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1,
1392 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
1397 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
1399 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
1400 - The contents of the SecureBoot variable
1401 - The contents of the PK variable
1402 - The contents of the KEK variable
1403 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
1404 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
1406 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
1408 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
1409 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
1411 @param[in] Event Event whose notification function is being invoked
1412 @param[in] Context Pointer to the notification function's context
1416 MeasureSecureBootPolicy (
1424 Status
= gBS
->LocateProtocol (&gEfiVariableWriteArchProtocolGuid
, NULL
, (VOID
**)&Protocol
);
1425 if (EFI_ERROR (Status
)) {
1429 if (PcdGetBool (PcdFirmwareDebuggerInitialized
)) {
1430 Status
= MeasureLaunchOfFirmwareDebugger ();
1431 DEBUG ((EFI_D_INFO
, "MeasureLaunchOfFirmwareDebugger - %r\n", Status
));
1434 Status
= MeasureAllSecureVariables ();
1435 DEBUG ((EFI_D_INFO
, "MeasureAllSecureVariables - %r\n", Status
));
1438 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
1439 // and ImageVerification (Authority)
1440 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
1441 // the Authority measurement happen before ReadToBoot event.
1443 Status
= MeasureSeparatorEvent (7);
1444 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent - %r\n", Status
));
1449 Ready to Boot Event notification handler.
1451 Sequence of OS boot events is measured in this event notification handler.
1453 @param[in] Event Event whose notification function is being invoked
1454 @param[in] Context Pointer to the notification function's context
1465 TPM_PCRINDEX PcrIndex
;
1467 PERF_START_EX (mImageHandle
, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE
);
1468 if (mBootAttempts
== 0) {
1471 // Measure handoff tables.
1473 Status
= MeasureHandoffTables ();
1474 if (EFI_ERROR (Status
)) {
1475 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
1479 // Measure BootOrder & Boot#### variables.
1481 Status
= MeasureAllBootVariables ();
1482 if (EFI_ERROR (Status
)) {
1483 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
1487 // 1. This is the first boot attempt.
1489 Status
= TcgMeasureAction (
1490 EFI_CALLING_EFI_APPLICATION
1492 if (EFI_ERROR (Status
)) {
1493 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
1497 // 2. Draw a line between pre-boot env and entering post-boot env.
1498 // PCR[7] is already done.
1500 for (PcrIndex
= 0; PcrIndex
< 7; PcrIndex
++) {
1501 Status
= MeasureSeparatorEvent (PcrIndex
);
1502 if (EFI_ERROR (Status
)) {
1503 DEBUG ((EFI_D_ERROR
, "Seperator Event not Measured. Error!\n"));
1508 // 3. Measure GPT. It would be done in SAP driver.
1512 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1516 // 5. Read & Measure variable. BootOrder already measured.
1520 // 6. Not first attempt, meaning a return from last attempt
1522 Status
= TcgMeasureAction (
1523 EFI_RETURNING_FROM_EFI_APPLICATOIN
1525 if (EFI_ERROR (Status
)) {
1526 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN
));
1530 DEBUG ((EFI_D_INFO
, "TPM2 TrEEDxe Measure Data when ReadyToBoot\n"));
1532 // Increase boot attempt counter.
1535 PERF_END_EX (mImageHandle
, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE
+ 1);
1539 Install TCG ACPI Table when ACPI Table Protocol is available.
1541 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1542 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1543 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1545 @param[in] Event Event whose notification function is being invoked
1546 @param[in] Context Pointer to the notification function's context
1557 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
1561 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
1562 if (EFI_ERROR (Status
)) {
1566 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
1567 CopyMem (mTcgClientAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgClientAcpiTemplate
.Header
.OemId
));
1568 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1569 CopyMem (&mTcgClientAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1570 mTcgClientAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1571 mTcgClientAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1572 mTcgClientAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1574 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1575 // service of the ACPI table protocol to install it.
1577 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgClientAcpiTemplate
, sizeof (mTcgClientAcpiTemplate
));
1578 mTcgClientAcpiTemplate
.Header
.Checksum
= Checksum
;
1580 Status
= AcpiTable
->InstallAcpiTable (
1582 &mTcgClientAcpiTemplate
,
1583 sizeof (mTcgClientAcpiTemplate
),
1587 CopyMem (mTcgServerAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgServerAcpiTemplate
.Header
.OemId
));
1588 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1589 CopyMem (&mTcgServerAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1590 mTcgServerAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1591 mTcgServerAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1592 mTcgServerAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1594 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1595 // service of the ACPI table protocol to install it.
1597 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgServerAcpiTemplate
, sizeof (mTcgServerAcpiTemplate
));
1598 mTcgServerAcpiTemplate
.Header
.Checksum
= Checksum
;
1600 mTcgServerAcpiTemplate
.BaseAddress
.Address
= PcdGet64 (PcdTpmBaseAddress
);
1601 Status
= AcpiTable
->InstallAcpiTable (
1603 &mTcgServerAcpiTemplate
,
1604 sizeof (mTcgServerAcpiTemplate
),
1609 if (EFI_ERROR (Status
)) {
1610 DEBUG((EFI_D_ERROR
, "Tcg Acpi Table installation failure"));
1615 Exit Boot Services Event notification handler.
1617 Measure invocation and success of ExitBootServices.
1619 @param[in] Event Event whose notification function is being invoked
1620 @param[in] Context Pointer to the notification function's context
1625 OnExitBootServices (
1633 // Measure invocation of ExitBootServices,
1635 Status
= TcgMeasureAction (
1636 EFI_EXIT_BOOT_SERVICES_INVOCATION
1638 if (EFI_ERROR (Status
)) {
1639 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION
));
1643 // Measure success of ExitBootServices
1645 Status
= TcgMeasureAction (
1646 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1648 if (EFI_ERROR (Status
)) {
1649 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED
));
1654 Exit Boot Services Failed Event notification handler.
1656 Measure Failure of ExitBootServices.
1658 @param[in] Event Event whose notification function is being invoked
1659 @param[in] Context Pointer to the notification function's context
1664 OnExitBootServicesFailed (
1672 // Measure Failure of ExitBootServices,
1674 Status
= TcgMeasureAction (
1675 EFI_EXIT_BOOT_SERVICES_FAILED
1677 if (EFI_ERROR (Status
)) {
1678 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED
));
1684 The function install TrEE protocol.
1686 @retval EFI_SUCCESS TrEE protocol is installed.
1687 @retval other Some error occurs.
1698 Status
= gBS
->InstallMultipleProtocolInterfaces (
1700 &gEfiTrEEProtocolGuid
,
1708 The driver's entry point. It publishes EFI TrEE Protocol.
1710 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1711 @param[in] SystemTable A pointer to the EFI System Table.
1713 @retval EFI_SUCCESS The entry point is executed successfully.
1714 @retval other Some error occurs when executing this entry point.
1719 IN EFI_HANDLE ImageHandle
,
1720 IN EFI_SYSTEM_TABLE
*SystemTable
1726 UINT32 MaxCommandSize
;
1727 UINT32 MaxResponseSize
;
1728 TPML_PCR_SELECTION Pcrs
;
1730 UINT32 TpmHashAlgorithmBitmap
;
1732 mImageHandle
= ImageHandle
;
1734 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceNoneGuid
) ||
1735 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
1736 DEBUG ((DEBUG_INFO
, "No TPM2 instance required!\n"));
1737 return EFI_UNSUPPORTED
;
1740 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
1741 DEBUG ((EFI_D_ERROR
, "TPM2 error!\n"));
1742 return EFI_DEVICE_ERROR
;
1745 Status
= Tpm2RequestUseTpm ();
1746 if (EFI_ERROR (Status
)) {
1747 DEBUG ((EFI_D_ERROR
, "TPM2 not detected!\n"));
1754 DEBUG ((EFI_D_INFO
, "TrEE.ProtocolVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.ProtocolVersion
.Major
, mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
));
1755 DEBUG ((EFI_D_INFO
, "TrEE.StructureVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.StructureVersion
.Major
, mTcgDxeData
.BsCap
.StructureVersion
.Minor
));
1757 Status
= Tpm2GetCapabilityManufactureID (&mTcgDxeData
.BsCap
.ManufacturerID
);
1758 if (EFI_ERROR (Status
)) {
1759 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityManufactureID fail!\n"));
1761 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData
.BsCap
.ManufacturerID
));
1765 UINT32 FirmwareVersion1
;
1766 UINT32 FirmwareVersion2
;
1768 Status
= Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1
, &FirmwareVersion2
);
1769 if (EFI_ERROR (Status
)) {
1770 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
1772 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1
, FirmwareVersion2
));
1776 Status
= Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize
, &MaxResponseSize
);
1777 if (EFI_ERROR (Status
)) {
1778 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
1780 mTcgDxeData
.BsCap
.MaxCommandSize
= (UINT16
)MaxCommandSize
;
1781 mTcgDxeData
.BsCap
.MaxResponseSize
= (UINT16
)MaxResponseSize
;
1782 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize
, MaxResponseSize
));
1785 Status
= Tpm2GetCapabilityPcrs (&Pcrs
);
1786 if (EFI_ERROR (Status
)) {
1787 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityPcrs fail!\n"));
1788 TpmHashAlgorithmBitmap
= TREE_BOOT_HASH_ALG_SHA1
;
1790 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs
.count
));
1791 TpmHashAlgorithmBitmap
= 0;
1792 for (Index
= 0; Index
< Pcrs
.count
; Index
++) {
1793 DEBUG ((EFI_D_INFO
, "hash - %x\n", Pcrs
.pcrSelections
[Index
].hash
));
1794 switch (Pcrs
.pcrSelections
[Index
].hash
) {
1796 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA1
;
1798 case TPM_ALG_SHA256
:
1799 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA256
;
1801 case TPM_ALG_SHA384
:
1802 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA384
;
1804 case TPM_ALG_SHA512
:
1805 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA512
;
1807 case TPM_ALG_SM3_256
:
1808 // TBD: Spec not define TREE_BOOT_HASH_ALG_SM3_256 yet
1813 DEBUG ((EFI_D_INFO
, "TPM.HashAlgorithmBitmap - 0x%08x\n", TpmHashAlgorithmBitmap
));
1815 DEBUG ((EFI_D_INFO
, "TrEE.SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
1816 mTcgDxeData
.BsCap
.HashAlgorithmBitmap
= TpmHashAlgorithmBitmap
;
1817 DEBUG ((EFI_D_INFO
, "TrEE.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData
.BsCap
.HashAlgorithmBitmap
));
1819 if (mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
1821 // Setup the log area and copy event log from hob list to it
1823 Status
= SetupEventLog ();
1824 ASSERT_EFI_ERROR (Status
);
1827 // Measure handoff tables, Boot#### variables etc.
1829 Status
= EfiCreateEventReadyToBootEx (
1836 Status
= gBS
->CreateEventEx (
1841 &gEfiEventExitBootServicesGuid
,
1846 // Measure Exit Boot Service failed
1848 Status
= gBS
->CreateEventEx (
1851 OnExitBootServicesFailed
,
1853 &gEventExitBootServicesFailedGuid
,
1858 // Create event callback, because we need access variable on SecureBootPolicyVariable
1859 // We should use VariableWriteArch instead of VariableArch, because Variable driver
1860 // may update SecureBoot value based on last setting.
1862 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid
, TPL_CALLBACK
, MeasureSecureBootPolicy
, NULL
, &Registration
);
1866 // Install ACPI Table
1868 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid
, TPL_CALLBACK
, InstallAcpiTable
, NULL
, &Registration
);
1871 // Install TrEEProtocol
1873 Status
= InstallTrEE ();
1874 DEBUG ((EFI_D_INFO
, "InstallTrEE - %r\n", Status
));