2 This module implements TrEE Protocol.
4 Copyright (c) 2013, 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/SmBios.h>
19 #include <IndustryStandard/TcpaAcpi.h>
21 #include <Guid/GlobalVariable.h>
22 #include <Guid/SmBios.h>
23 #include <Guid/HobList.h>
24 #include <Guid/TcgEventHob.h>
25 #include <Guid/EventGroup.h>
26 #include <Guid/EventExitBootServiceFailed.h>
27 #include <Guid/ImageAuthentication.h>
28 #include <Guid/TpmInstance.h>
30 #include <Protocol/DevicePath.h>
31 #include <Protocol/AcpiTable.h>
32 #include <Protocol/MpService.h>
33 #include <Protocol/VariableWrite.h>
34 #include <Protocol/TrEEProtocol.h>
36 #include <Library/DebugLib.h>
37 #include <Library/BaseMemoryLib.h>
38 #include <Library/UefiRuntimeServicesTableLib.h>
39 #include <Library/UefiDriverEntryPoint.h>
40 #include <Library/HobLib.h>
41 #include <Library/UefiBootServicesTableLib.h>
42 #include <Library/BaseLib.h>
43 #include <Library/MemoryAllocationLib.h>
44 #include <Library/PrintLib.h>
45 #include <Library/Tpm2CommandLib.h>
46 #include <Library/PcdLib.h>
47 #include <Library/UefiLib.h>
48 #include <Library/Tpm2DeviceLib.h>
49 #include <Library/HashLib.h>
50 #include <Library/PerformanceLib.h>
52 #define PERF_ID_TREE_DXE 0x3120
59 #define EFI_TCG_LOG_AREA_SIZE 0x10000
61 #define TREE_DEFAULT_MAX_COMMAND_SIZE 0x1000
62 #define TREE_DEFAULT_MAX_RESPONSE_SIZE 0x1000
66 TREE_EVENT_LOG_FORMAT LogFormat
;
69 TPMI_ALG_HASH TpmHashAlgo
;
70 } TREE_EVENT_INFO_STRUCT
;
72 TREE_EVENT_INFO_STRUCT mTreeEventInfo
[] = {
73 {&gTcgEventEntryHobGuid
, TREE_EVENT_LOG_FORMAT_TCG_1_2
, TREE_BOOT_HASH_ALG_SHA1
, 0, TPM_ALG_SHA1
},
76 #define TCG_EVENT_LOG_AREA_COUNT_MAX 5
79 TREE_EVENT_LOG_FORMAT EventLogFormat
;
80 EFI_PHYSICAL_ADDRESS Lasa
;
84 BOOLEAN EventLogStarted
;
85 BOOLEAN EventLogTruncated
;
86 } TCG_EVENT_LOG_AREA_STRUCT
;
88 typedef struct _TCG_DXE_DATA
{
89 TREE_BOOT_SERVICE_CAPABILITY BsCap
;
90 EFI_TCG_CLIENT_ACPI_TABLE
*TcgClientAcpiTable
;
91 EFI_TCG_SERVER_ACPI_TABLE
*TcgServerAcpiTable
;
92 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
95 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate
= {
97 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
98 sizeof (mTcgClientAcpiTemplate
),
101 // Compiler initializes the remaining bytes to 0
102 // These fields should be filled in in production
105 0, // 0 for PC Client Platform Class
106 0, // Log Area Max Length
107 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1) // Log Area Start Address
111 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,
112 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,
113 // this _UID can be changed and should match with the _UID setting of the TPM
114 // ACPI device object
116 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate
= {
118 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
119 sizeof (mTcgServerAcpiTemplate
),
122 // Compiler initializes the remaining bytes to 0
123 // These fields should be filled in in production
126 1, // 1 for Server Platform Class
128 0, // Log Area Max Length
129 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1), // Log Area Start Address
130 0x0100, // TCG Specification revision 1.0
132 0, // Interrupt Flags
134 {0}, // Reserved 3 bytes
135 0, // Global System Interrupt
137 EFI_ACPI_3_0_SYSTEM_MEMORY
,
144 {0}, // Configuration Address
145 0xFF, // ACPI _UID value of the device, can be changed for different platforms
146 0, // ACPI _UID value of the device, can be changed for different platforms
147 0, // ACPI _UID value of the device, can be changed for different platforms
148 0 // ACPI _UID value of the device, can be changed for different platforms
151 TCG_DXE_DATA mTcgDxeData
= {
153 sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0
), // Size
154 { 1, 0 }, // StructureVersion
155 { 1, 0 }, // ProtocolVersion
156 TREE_BOOT_HASH_ALG_SHA1
, // HashAlgorithmBitmap
157 TREE_EVENT_LOG_FORMAT_TCG_1_2
, // SupportedEventLogs
158 TRUE
, // TrEEPresentFlag
159 TREE_DEFAULT_MAX_COMMAND_SIZE
, // MaxCommandSize
160 TREE_DEFAULT_MAX_RESPONSE_SIZE
, // MaxResponseSize
163 &mTcgClientAcpiTemplate
,
164 &mTcgServerAcpiTemplate
,
167 UINTN mBootAttempts
= 0;
168 CHAR16 mBootVarName
[] = L
"BootOrder";
170 VARIABLE_TYPE mVariableType
[] = {
171 {EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
},
172 {EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
},
173 {EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
},
174 {EFI_IMAGE_SECURITY_DATABASE
, &gEfiImageSecurityDatabaseGuid
},
175 {EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
},
178 EFI_HANDLE mImageHandle
;
181 Measure PE image into TPM log based on the authenticode image hashing in
182 PE/COFF Specification 8.0 Appendix A.
184 Caution: This function may receive untrusted input.
185 PE/COFF image is external input, so this function will validate its data structure
186 within this image buffer before use.
188 @param[in] PCRIndex TPM PCR index
189 @param[in] ImageAddress Start address of image buffer.
190 @param[in] ImageSize Image size
191 @param[out] DigestList Digeest list of this image.
193 @retval EFI_SUCCESS Successfully measure image.
194 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
195 @retval other error value
198 MeasurePeImageAndExtend (
200 IN EFI_PHYSICAL_ADDRESS ImageAddress
,
202 OUT TPML_DIGEST_VALUES
*DigestList
207 This function dump raw data.
210 @param Size raw data size
220 for (Index
= 0; Index
< Size
; Index
++) {
221 DEBUG ((EFI_D_INFO
, "%02x", (UINTN
)Data
[Index
]));
227 This function dump raw data with colume format.
230 @param Size raw data size
243 #define COLUME_SIZE (16 * 2)
245 Count
= Size
/ COLUME_SIZE
;
246 Left
= Size
% COLUME_SIZE
;
247 for (Index
= 0; Index
< Count
; Index
++) {
248 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
249 InternalDumpData (Data
+ Index
* COLUME_SIZE
, COLUME_SIZE
);
250 DEBUG ((EFI_D_INFO
, "\n"));
254 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
255 InternalDumpData (Data
+ Index
* COLUME_SIZE
, Left
);
256 DEBUG ((EFI_D_INFO
, "\n"));
261 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
262 Caller is responsible to free LocationBuf.
264 @param[out] LocationBuf Returns Processor Location Buffer.
265 @param[out] Num Returns processor number.
267 @retval EFI_SUCCESS Operation completed successfully.
268 @retval EFI_UNSUPPORTED MpService protocol not found.
272 GetProcessorsCpuLocation (
273 OUT EFI_CPU_PHYSICAL_LOCATION
**LocationBuf
,
278 EFI_MP_SERVICES_PROTOCOL
*MpProtocol
;
280 UINTN EnabledProcessorNum
;
281 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
282 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
285 Status
= gBS
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**) &MpProtocol
);
286 if (EFI_ERROR (Status
)) {
288 // MP protocol is not installed
290 return EFI_UNSUPPORTED
;
293 Status
= MpProtocol
->GetNumberOfProcessors(
298 if (EFI_ERROR(Status
)){
302 Status
= gBS
->AllocatePool(
304 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
305 (VOID
**) &ProcessorLocBuf
307 if (EFI_ERROR(Status
)){
312 // Get each processor Location info
314 for (Index
= 0; Index
< ProcessorNum
; Index
++) {
315 Status
= MpProtocol
->GetProcessorInfo(
320 if (EFI_ERROR(Status
)){
321 FreePool(ProcessorLocBuf
);
326 // Get all Processor Location info & measure
329 &ProcessorLocBuf
[Index
],
330 &ProcessorInfo
.Location
,
331 sizeof(EFI_CPU_PHYSICAL_LOCATION
)
335 *LocationBuf
= ProcessorLocBuf
;
342 The EFI_TREE_PROTOCOL GetCapability function call provides protocol
343 capability information and state information about the TrEE.
345 @param[in] This Indicates the calling context
346 @param[in, out] ProtocolCapability The caller allocates memory for a TREE_BOOT_SERVICE_CAPABILITY
347 structure and sets the size field to the size of the structure allocated.
348 The callee fills in the fields with the EFI protocol capability information
349 and the current TrEE state information up to the number of fields which
350 fit within the size of the structure passed in.
352 @retval EFI_SUCCESS Operation completed successfully.
353 @retval EFI_DEVICE_ERROR The command was unsuccessful.
354 The ProtocolCapability variable will not be populated.
355 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
356 The ProtocolCapability variable will not be populated.
357 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
358 It will be partially populated (required Size field will be set).
363 IN EFI_TREE_PROTOCOL
*This
,
364 IN OUT TREE_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
367 DEBUG ((EFI_D_ERROR
, "TreeGetCapability ...\n"));
369 if ((This
== NULL
) || (ProtocolCapability
== NULL
)) {
370 return EFI_INVALID_PARAMETER
;
373 if (ProtocolCapability
->Size
< mTcgDxeData
.BsCap
.Size
) {
374 ProtocolCapability
->Size
= mTcgDxeData
.BsCap
.Size
;
375 return EFI_BUFFER_TOO_SMALL
;
378 CopyMem (ProtocolCapability
, &mTcgDxeData
.BsCap
, mTcgDxeData
.BsCap
.Size
);
379 DEBUG ((EFI_D_ERROR
, "TreeGetCapability - %r\n", EFI_SUCCESS
));
384 This function dump event log.
386 @param[in] EventLogFormat The type of the event log for which the information is requested.
387 @param[in] EventLogLocation A pointer to the memory address of the event log.
388 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
389 address of the start of the last entry in the event log in memory.
393 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
394 IN EFI_PHYSICAL_ADDRESS EventLogLocation
,
395 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry
398 TCG_PCR_EVENT_HDR
*EventHdr
;
401 DEBUG ((EFI_D_INFO
, "EventLogFormat: (0x%x)\n", EventLogFormat
));
403 switch (EventLogFormat
) {
404 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
405 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)EventLogLocation
;
406 while ((UINTN
)EventHdr
<= EventLogLastEntry
) {
407 DEBUG ((EFI_D_INFO
, " Event:\n"));
408 DEBUG ((EFI_D_INFO
, " PCRIndex - %d\n", EventHdr
->PCRIndex
));
409 DEBUG ((EFI_D_INFO
, " EventType - 0x%08x\n", EventHdr
->EventType
));
410 DEBUG ((EFI_D_INFO
, " Digest - "));
411 for (Index
= 0; Index
< sizeof(TCG_DIGEST
); Index
++) {
412 DEBUG ((EFI_D_INFO
, "%02x ", EventHdr
->Digest
.digest
[Index
]));
414 DEBUG ((EFI_D_INFO
, "\n"));
415 DEBUG ((EFI_D_INFO
, " EventSize - 0x%08x\n", EventHdr
->EventSize
));
416 InternalDumpHex ((UINT8
*)(EventHdr
+ 1), EventHdr
->EventSize
);
417 EventHdr
= (TCG_PCR_EVENT_HDR
*)((UINTN
)EventHdr
+ sizeof(TCG_PCR_EVENT_HDR
) + EventHdr
->EventSize
);
426 The EFI_TREE_PROTOCOL Get Event Log function call allows a caller to
427 retrieve the address of a given event log and its last entry.
429 @param[in] This Indicates the calling context
430 @param[in] EventLogFormat The type of the event log for which the information is requested.
431 @param[out] EventLogLocation A pointer to the memory address of the event log.
432 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
433 address of the start of the last entry in the event log in memory.
434 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
435 have exceeded the area allocated for events, this value is set to TRUE.
436 Otherwise, the value will be FALSE and the Event Log will be complete.
438 @retval EFI_SUCCESS Operation completed successfully.
439 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
440 (e.g. asking for an event log whose format is not supported).
445 IN EFI_TREE_PROTOCOL
*This
,
446 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
447 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
448 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
,
449 OUT BOOLEAN
*EventLogTruncated
454 DEBUG ((EFI_D_ERROR
, "TreeGetEventLog ...\n"));
457 return EFI_INVALID_PARAMETER
;
460 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
461 if (EventLogFormat
== mTreeEventInfo
[Index
].LogFormat
) {
466 if (Index
== sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0])) {
467 return EFI_INVALID_PARAMETER
;
470 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
471 if (EventLogLocation
!= NULL
) {
472 *EventLogLocation
= 0;
474 if (EventLogLastEntry
!= NULL
) {
475 *EventLogLastEntry
= 0;
477 if (EventLogTruncated
!= NULL
) {
478 *EventLogTruncated
= FALSE
;
483 if (EventLogLocation
!= NULL
) {
484 *EventLogLocation
= mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
;
485 DEBUG ((EFI_D_ERROR
, "TreeGetEventLog (EventLogLocation - %x)\n", *EventLogLocation
));
488 if (EventLogLastEntry
!= NULL
) {
489 if (!mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
) {
490 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
492 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
;
494 DEBUG ((EFI_D_ERROR
, "TreeGetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry
));
497 if (EventLogTruncated
!= NULL
) {
498 *EventLogTruncated
= mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
;
499 DEBUG ((EFI_D_ERROR
, "TreeGetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated
));
502 DEBUG ((EFI_D_ERROR
, "TreeGetEventLog - %r\n", EFI_SUCCESS
));
504 // Dump Event Log for debug purpose
505 if ((EventLogLocation
!= NULL
) && (EventLogLastEntry
!= NULL
)) {
506 DumpEventLog (EventLogFormat
, *EventLogLocation
, *EventLogLastEntry
);
513 Add a new entry to the Event Log.
515 @param[in, out] EventLogPtr Pointer to the Event Log data.
516 @param[in, out] LogSize Size of the Event Log.
517 @param[in] MaxSize Maximum size of the Event Log.
518 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
519 @param[in] NewEventHdrSize New event header size.
520 @param[in] NewEventData Pointer to the new event data.
521 @param[in] NewEventSize New event data size.
523 @retval EFI_SUCCESS The new event log entry was added.
524 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
529 IN OUT UINT8
**EventLogPtr
,
530 IN OUT UINTN
*LogSize
,
532 IN VOID
*NewEventHdr
,
533 IN UINT32 NewEventHdrSize
,
534 IN UINT8
*NewEventData
,
535 IN UINT32 NewEventSize
540 if (NewEventSize
> MAX_ADDRESS
- NewEventHdrSize
) {
541 return EFI_OUT_OF_RESOURCES
;
544 NewLogSize
= NewEventHdrSize
+ NewEventSize
;
546 if (NewLogSize
> MAX_ADDRESS
- *LogSize
) {
547 return EFI_OUT_OF_RESOURCES
;
550 if (NewLogSize
+ *LogSize
> MaxSize
) {
551 DEBUG ((EFI_D_INFO
, " MaxSize - 0x%x\n", MaxSize
));
552 DEBUG ((EFI_D_INFO
, " NewLogSize - 0x%x\n", NewLogSize
));
553 DEBUG ((EFI_D_INFO
, " LogSize - 0x%x\n", *LogSize
));
554 DEBUG ((EFI_D_INFO
, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES
));
555 return EFI_OUT_OF_RESOURCES
;
558 *EventLogPtr
+= *LogSize
;
559 *LogSize
+= NewLogSize
;
560 CopyMem (*EventLogPtr
, NewEventHdr
, NewEventHdrSize
);
562 *EventLogPtr
+ NewEventHdrSize
,
570 Add a new entry to the Event Log.
572 @param[in] EventLogFormat The type of the event log for which the information is requested.
573 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
574 @param[in] NewEventHdrSize New event header size.
575 @param[in] NewEventData Pointer to the new event data.
576 @param[in] NewEventSize New event data size.
578 @retval EFI_SUCCESS The new event log entry was added.
579 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
584 IN TREE_EVENT_LOG_FORMAT EventLogFormat
,
585 IN VOID
*NewEventHdr
,
586 IN UINT32 NewEventHdrSize
,
587 IN UINT8
*NewEventData
,
588 IN UINT32 NewEventSize
594 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
595 if (EventLogFormat
== mTreeEventInfo
[Index
].LogFormat
) {
600 if (Index
== sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0])) {
601 return EFI_INVALID_PARAMETER
;
604 if (mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
) {
605 return EFI_VOLUME_FULL
;
608 mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
= (UINT8
*)(UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
;
609 Status
= TcgCommLogEvent (
610 &mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
,
611 &mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogSize
,
612 (UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
,
619 if (Status
== EFI_DEVICE_ERROR
) {
620 return EFI_DEVICE_ERROR
;
621 } else if (Status
== EFI_OUT_OF_RESOURCES
) {
622 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
= TRUE
;
623 return EFI_VOLUME_FULL
;
624 } else if (Status
== EFI_SUCCESS
) {
625 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
= TRUE
;
632 This function return hash algorithm from event log format.
634 @param[in] EventLogFormat Event log format.
636 @return hash algorithm.
639 TrEEGetHashAlgoFromLogFormat (
640 IN TREE_EVENT_LOG_FORMAT EventLogFormat
645 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
646 if (mTreeEventInfo
[Index
].LogFormat
== EventLogFormat
) {
647 return mTreeEventInfo
[Index
].TpmHashAlgo
;
654 This function return hash algorithm ID from event log format.
656 @param[in] EventLogFormat Event log format.
658 @return hash algorithm ID.
661 TrEEGetAlgIDFromLogFormat (
662 IN TREE_EVENT_LOG_FORMAT EventLogFormat
667 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
668 if (mTreeEventInfo
[Index
].LogFormat
== EventLogFormat
) {
669 return mTreeEventInfo
[Index
].DigestAlgID
;
676 This function return boot hash algorithm from event log format.
678 @param[in] EventLogFormat Event log format.
680 @return boot hash algorithm.
683 TrEEGetBootHashAlgFromLogFormat (
684 IN TREE_EVENT_LOG_FORMAT EventLogFormat
689 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
690 if (mTreeEventInfo
[Index
].LogFormat
== EventLogFormat
) {
691 return mTreeEventInfo
[Index
].BootHashAlg
;
694 return TREE_BOOT_HASH_ALG_SHA1
;
698 This function get digest from digest list.
700 @param HashAlg digest algorithm
701 @param DigestList digest list
704 @retval EFI_SUCCESS Sha1Digest is found and returned.
705 @retval EFI_NOT_FOUND Sha1Digest is not found.
708 Tpm2GetDigestFromDigestList (
709 IN TPMI_ALG_HASH HashAlg
,
710 IN TPML_DIGEST_VALUES
*DigestList
,
717 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
718 for (Index
= 0; Index
< DigestList
->count
; Index
++) {
719 if (DigestList
->digests
[Index
].hashAlg
== HashAlg
) {
722 &DigestList
->digests
[Index
].digest
,
729 return EFI_NOT_FOUND
;
733 Add a new entry to the Event Log.
735 @param[in] DigestList A list of digest.
736 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
737 @param[in] NewEventData Pointer to the new event data.
739 @retval EFI_SUCCESS The new event log entry was added.
740 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
744 IN TPML_DIGEST_VALUES
*DigestList
,
745 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
746 IN UINT8
*NewEventData
752 EFI_STATUS RetStatus
;
754 RetStatus
= EFI_SUCCESS
;
755 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
756 DEBUG ((EFI_D_INFO
, " LogFormat - 0x%08x\n", mTreeEventInfo
[Index
].LogFormat
));
757 switch (mTreeEventInfo
[Index
].LogFormat
) {
758 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
759 Status
= Tpm2GetDigestFromDigestList (TPM_ALG_SHA1
, DigestList
, &NewEventHdr
->Digest
);
760 if (!EFI_ERROR (Status
)) {
762 // Enter critical region
764 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
765 Status
= TcgDxeLogEvent (
766 mTreeEventInfo
[Index
].LogFormat
,
768 sizeof(TCG_PCR_EVENT_HDR
),
770 NewEventHdr
->EventSize
772 if (Status
!= EFI_SUCCESS
) {
775 gBS
->RestoreTPL (OldTpl
);
777 // Exit critical region
788 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
789 and add an entry to the Event Log.
791 @param[in] Flags Bitmap providing additional information.
792 @param[in] HashData Physical address of the start of the data buffer
793 to be hashed, extended, and logged.
794 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
795 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
796 @param[in] NewEventData Pointer to the new event data.
798 @retval EFI_SUCCESS Operation completed successfully.
799 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
800 @retval EFI_DEVICE_ERROR The command was unsuccessful.
804 TcgDxeHashLogExtendEvent (
807 IN UINT64 HashDataLen
,
808 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
809 IN UINT8
*NewEventData
813 TPML_DIGEST_VALUES DigestList
;
815 Status
= HashAndExtend (
816 NewEventHdr
->PCRIndex
,
821 if (!EFI_ERROR (Status
)) {
822 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
823 Status
= TcgDxeLogHashEvent (&DigestList
, NewEventHdr
, NewEventData
);
831 The EFI_TREE_PROTOCOL HashLogExtendEvent function call provides callers with
832 an opportunity to extend and optionally log events without requiring
833 knowledge of actual TPM commands.
834 The extend operation will occur even if this function cannot create an event
835 log entry (e.g. due to the event log being full).
837 @param[in] This Indicates the calling context
838 @param[in] Flags Bitmap providing additional information.
839 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
840 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
841 @param[in] Event Pointer to data buffer containing information about the event.
843 @retval EFI_SUCCESS Operation completed successfully.
844 @retval EFI_DEVICE_ERROR The command was unsuccessful.
845 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
846 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
847 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
851 TreeHashLogExtendEvent (
852 IN EFI_TREE_PROTOCOL
*This
,
854 IN EFI_PHYSICAL_ADDRESS DataToHash
,
855 IN UINT64 DataToHashLen
,
860 TCG_PCR_EVENT_HDR NewEventHdr
;
861 TPML_DIGEST_VALUES DigestList
;
863 DEBUG ((EFI_D_ERROR
, "TreeHashLogExtendEvent ...\n"));
865 if ((This
== NULL
) || (DataToHash
== 0) || (Event
== NULL
)) {
866 return EFI_INVALID_PARAMETER
;
869 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
870 return EFI_UNSUPPORTED
;
873 if (Event
->Size
< Event
->Header
.HeaderSize
+ sizeof(UINT32
)) {
874 return EFI_INVALID_PARAMETER
;
877 if (Event
->Header
.PCRIndex
> MAX_PCR_INDEX
) {
878 return EFI_INVALID_PARAMETER
;
881 NewEventHdr
.PCRIndex
= Event
->Header
.PCRIndex
;
882 NewEventHdr
.EventType
= Event
->Header
.EventType
;
883 NewEventHdr
.EventSize
= Event
->Size
- sizeof(UINT32
) - Event
->Header
.HeaderSize
;
884 if ((Flags
& PE_COFF_IMAGE
) != 0) {
885 Status
= MeasurePeImageAndExtend (
886 NewEventHdr
.PCRIndex
,
888 (UINTN
)DataToHashLen
,
891 if (!EFI_ERROR (Status
)) {
892 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
893 Status
= TcgDxeLogHashEvent (&DigestList
, &NewEventHdr
, Event
->Event
);
897 Status
= TcgDxeHashLogExtendEvent (
899 (UINT8
*) (UINTN
) DataToHash
,
905 DEBUG ((EFI_D_ERROR
, "TreeHashLogExtendEvent - %r\n", Status
));
910 This service enables the sending of commands to the TrEE.
912 @param[in] This Indicates the calling context
913 @param[in] InputParameterBlockSize Size of the TrEE input parameter block.
914 @param[in] InputParameterBlock Pointer to the TrEE input parameter block.
915 @param[in] OutputParameterBlockSize Size of the TrEE output parameter block.
916 @param[in] OutputParameterBlock Pointer to the TrEE output parameter block.
918 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
919 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
920 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
921 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
926 IN EFI_TREE_PROTOCOL
*This
,
927 IN UINT32 InputParameterBlockSize
,
928 IN UINT8
*InputParameterBlock
,
929 IN UINT32 OutputParameterBlockSize
,
930 IN UINT8
*OutputParameterBlock
935 DEBUG ((EFI_D_ERROR
, "TreeSubmitCommand ...\n"));
937 if ((This
== NULL
) ||
938 (InputParameterBlockSize
== 0) || (InputParameterBlock
== NULL
) ||
939 (OutputParameterBlockSize
== 0) || (OutputParameterBlock
== NULL
)) {
940 return EFI_INVALID_PARAMETER
;
943 if (!mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
944 return EFI_UNSUPPORTED
;
947 if (InputParameterBlockSize
>= mTcgDxeData
.BsCap
.MaxCommandSize
) {
948 return EFI_INVALID_PARAMETER
;
950 if (OutputParameterBlockSize
>= mTcgDxeData
.BsCap
.MaxResponseSize
) {
951 return EFI_INVALID_PARAMETER
;
954 Status
= Tpm2SubmitCommand (
955 InputParameterBlockSize
,
957 &OutputParameterBlockSize
,
960 DEBUG ((EFI_D_ERROR
, "TreeSubmitCommand - %r\n", Status
));
965 EFI_TREE_PROTOCOL mTreeProtocol
= {
968 TreeHashLogExtendEvent
,
973 Initialize the Event Log and log events passed from the PEI phase.
975 @retval EFI_SUCCESS Operation completed successfully.
976 @retval EFI_OUT_OF_RESOURCES Out of memory.
986 EFI_PEI_HOB_POINTERS GuidHob
;
987 EFI_PHYSICAL_ADDRESS Lasa
;
990 DEBUG ((EFI_D_INFO
, "SetupEventLog\n"));
993 // 1. Create Log Area
995 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
996 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogFormat
= mTreeEventInfo
[Index
].LogFormat
;
997 Lasa
= (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1);
998 Status
= gBS
->AllocatePages (
1001 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE
),
1004 if (EFI_ERROR (Status
)) {
1007 mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
= Lasa
;
1008 mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
= EFI_TCG_LOG_AREA_SIZE
;
1010 // To initialize them as 0xFF is recommended
1011 // because the OS can know the last entry for that.
1013 SetMem ((VOID
*)(UINTN
)Lasa
, EFI_TCG_LOG_AREA_SIZE
, 0xFF);
1017 // 2. Create ACPI table for TCG1.2 only
1019 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
1020 mTcgClientAcpiTemplate
.Lasa
= mTcgDxeData
.EventLogAreaStruct
[0].Lasa
;
1021 mTcgClientAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
1023 mTcgServerAcpiTemplate
.Lasa
= mTcgDxeData
.EventLogAreaStruct
[0].Lasa
;
1024 mTcgServerAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
1028 // 3. Sync data from PEI to DXE
1030 Status
= EFI_SUCCESS
;
1031 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
1032 GuidHob
.Raw
= GetHobList ();
1033 Status
= EFI_SUCCESS
;
1034 while (!EFI_ERROR (Status
) &&
1035 (GuidHob
.Raw
= GetNextGuidHob (mTreeEventInfo
[Index
].EventGuid
, GuidHob
.Raw
)) != NULL
) {
1036 TcgEvent
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
1037 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
1038 switch (mTreeEventInfo
[Index
].LogFormat
) {
1039 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
1040 Status
= TcgDxeLogEvent (
1041 mTreeEventInfo
[Index
].LogFormat
,
1043 sizeof(TCG_PCR_EVENT_HDR
),
1044 ((TCG_PCR_EVENT
*)TcgEvent
)->Event
,
1045 ((TCG_PCR_EVENT_HDR
*)TcgEvent
)->EventSize
1056 Measure and log an action string, and extend the measurement result into PCR[5].
1058 @param[in] String A specific string that indicates an Action event.
1060 @retval EFI_SUCCESS Operation completed successfully.
1061 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1069 TCG_PCR_EVENT_HDR TcgEvent
;
1071 TcgEvent
.PCRIndex
= 5;
1072 TcgEvent
.EventType
= EV_EFI_ACTION
;
1073 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
1074 return TcgDxeHashLogExtendEvent (
1084 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1086 @retval EFI_SUCCESS Operation completed successfully.
1087 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1091 MeasureHandoffTables (
1096 SMBIOS_TABLE_ENTRY_POINT
*SmbiosTable
;
1097 TCG_PCR_EVENT_HDR TcgEvent
;
1098 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
1100 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
1103 // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]
1105 Status
= EfiGetSystemConfigurationTable (
1106 &gEfiSmbiosTableGuid
,
1107 (VOID
**) &SmbiosTable
1110 if (!EFI_ERROR (Status
)) {
1111 ASSERT (SmbiosTable
!= NULL
);
1113 TcgEvent
.PCRIndex
= 1;
1114 TcgEvent
.EventType
= EV_EFI_HANDOFF_TABLES
;
1115 TcgEvent
.EventSize
= sizeof (HandoffTables
);
1117 HandoffTables
.NumberOfTables
= 1;
1118 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiSmbiosTableGuid
;
1119 HandoffTables
.TableEntry
[0].VendorTable
= SmbiosTable
;
1121 DEBUG ((DEBUG_INFO
, "The Smbios Table starts at: 0x%x\n", SmbiosTable
->TableAddress
));
1122 DEBUG ((DEBUG_INFO
, "The Smbios Table size: 0x%x\n", SmbiosTable
->TableLength
));
1124 Status
= TcgDxeHashLogExtendEvent (
1126 (UINT8
*)(UINTN
)SmbiosTable
->TableAddress
,
1127 SmbiosTable
->TableLength
,
1129 (UINT8
*)&HandoffTables
1133 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
1136 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1138 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
1140 if (!EFI_ERROR(Status
)){
1141 TcgEvent
.PCRIndex
= 1;
1142 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
1143 TcgEvent
.EventSize
= sizeof (HandoffTables
);
1145 HandoffTables
.NumberOfTables
= 1;
1146 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
1147 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
1149 Status
= TcgDxeHashLogExtendEvent (
1151 (UINT8
*)(UINTN
)ProcessorLocBuf
,
1152 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
1154 (UINT8
*)&HandoffTables
1157 FreePool(ProcessorLocBuf
);
1165 Measure and log Separator event, and extend the measurement result into a specific PCR.
1167 @param[in] PCRIndex PCR index.
1169 @retval EFI_SUCCESS Operation completed successfully.
1170 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1174 MeasureSeparatorEvent (
1175 IN TPM_PCRINDEX PCRIndex
1178 TCG_PCR_EVENT_HDR TcgEvent
;
1181 DEBUG ((EFI_D_ERROR
, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex
));
1184 TcgEvent
.PCRIndex
= PCRIndex
;
1185 TcgEvent
.EventType
= EV_SEPARATOR
;
1186 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
1187 return TcgDxeHashLogExtendEvent (
1189 (UINT8
*)&EventData
,
1197 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1199 @param[in] PCRIndex PCR Index.
1200 @param[in] EventType Event type.
1201 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1202 @param[in] VendorGuid A unique identifier for the vendor.
1203 @param[in] VarData The content of the variable data.
1204 @param[in] VarSize The size of the variable data.
1206 @retval EFI_SUCCESS Operation completed successfully.
1207 @retval EFI_OUT_OF_RESOURCES Out of memory.
1208 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1213 IN TPM_PCRINDEX PCRIndex
,
1214 IN TCG_EVENTTYPE EventType
,
1216 IN EFI_GUID
*VendorGuid
,
1222 TCG_PCR_EVENT_HDR TcgEvent
;
1223 UINTN VarNameLength
;
1224 EFI_VARIABLE_DATA_TREE
*VarLog
;
1226 ASSERT ((VarSize
== 0 && VarData
== NULL
) || (VarSize
!= 0 && VarData
!= NULL
));
1228 DEBUG ((EFI_D_ERROR
, "TrEEDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN
)PCRIndex
, (UINTN
)EventType
));
1229 DEBUG ((EFI_D_ERROR
, "VariableName - %s, VendorGuid - %g)\n", VarName
, VendorGuid
));
1231 VarNameLength
= StrLen (VarName
);
1232 TcgEvent
.PCRIndex
= PCRIndex
;
1233 TcgEvent
.EventType
= EventType
;
1234 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
1235 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
1237 VarLog
= (EFI_VARIABLE_DATA_TREE
*)AllocatePool (TcgEvent
.EventSize
);
1238 if (VarLog
== NULL
) {
1239 return EFI_OUT_OF_RESOURCES
;
1242 VarLog
->VariableName
= *VendorGuid
;
1243 VarLog
->UnicodeNameLength
= VarNameLength
;
1244 VarLog
->VariableDataLength
= VarSize
;
1246 VarLog
->UnicodeName
,
1248 VarNameLength
* sizeof (*VarName
)
1252 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
1258 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1260 // Digest is the event data (EFI_VARIABLE_DATA_TREE)
1262 Status
= TcgDxeHashLogExtendEvent (
1270 Status
= TcgDxeHashLogExtendEvent (
1283 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1285 @param[in] PCRIndex PCR Index.
1286 @param[in] EventType Event type.
1287 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1288 @param[in] VendorGuid A unique identifier for the vendor.
1289 @param[out] VarSize The size of the variable data.
1290 @param[out] VarData Pointer to the content of the variable.
1292 @retval EFI_SUCCESS Operation completed successfully.
1293 @retval EFI_OUT_OF_RESOURCES Out of memory.
1294 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1298 ReadAndMeasureVariable (
1299 IN TPM_PCRINDEX PCRIndex
,
1300 IN TCG_EVENTTYPE EventType
,
1302 IN EFI_GUID
*VendorGuid
,
1309 Status
= GetVariable2 (VarName
, VendorGuid
, VarData
, VarSize
);
1310 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1311 if (EFI_ERROR (Status
)) {
1313 // It is valid case, so we need handle it.
1319 if (EFI_ERROR (Status
)) {
1322 ASSERT (*VarData
!= NULL
);
1325 Status
= MeasureVariable (
1337 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
1339 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1340 @param[in] VendorGuid A unique identifier for the vendor.
1341 @param[out] VarSize The size of the variable data.
1342 @param[out] VarData Pointer to the content of the variable.
1344 @retval EFI_SUCCESS Operation completed successfully.
1345 @retval EFI_OUT_OF_RESOURCES Out of memory.
1346 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1350 ReadAndMeasureBootVariable (
1352 IN EFI_GUID
*VendorGuid
,
1357 return ReadAndMeasureVariable (
1359 EV_EFI_VARIABLE_BOOT
,
1368 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1370 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1371 @param[in] VendorGuid A unique identifier for the vendor.
1372 @param[out] VarSize The size of the variable data.
1373 @param[out] VarData Pointer to the content of the variable.
1375 @retval EFI_SUCCESS Operation completed successfully.
1376 @retval EFI_OUT_OF_RESOURCES Out of memory.
1377 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1381 ReadAndMeasureSecureVariable (
1383 IN EFI_GUID
*VendorGuid
,
1388 return ReadAndMeasureVariable (
1390 EV_EFI_VARIABLE_DRIVER_CONFIG
,
1399 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1401 The EFI boot variables are BootOrder and Boot#### variables.
1403 @retval EFI_SUCCESS Operation completed successfully.
1404 @retval EFI_OUT_OF_RESOURCES Out of memory.
1405 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1409 MeasureAllBootVariables (
1420 Status
= ReadAndMeasureBootVariable (
1422 &gEfiGlobalVariableGuid
,
1424 (VOID
**) &BootOrder
1426 if (Status
== EFI_NOT_FOUND
) {
1429 ASSERT (BootOrder
!= NULL
);
1431 if (EFI_ERROR (Status
)) {
1432 FreePool (BootOrder
);
1436 BootCount
/= sizeof (*BootOrder
);
1437 for (Index
= 0; Index
< BootCount
; Index
++) {
1438 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
1439 Status
= ReadAndMeasureBootVariable (
1441 &gEfiGlobalVariableGuid
,
1445 if (!EFI_ERROR (Status
)) {
1446 FreePool (BootVarData
);
1450 FreePool (BootOrder
);
1455 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1457 The EFI boot variables are BootOrder and Boot#### variables.
1459 @retval EFI_SUCCESS Operation completed successfully.
1460 @retval EFI_OUT_OF_RESOURCES Out of memory.
1461 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1465 MeasureAllSecureVariables (
1474 Status
= EFI_NOT_FOUND
;
1475 for (Index
= 0; Index
< sizeof(mVariableType
)/sizeof(mVariableType
[0]); Index
++) {
1476 Status
= ReadAndMeasureSecureVariable (
1477 mVariableType
[Index
].VariableName
,
1478 mVariableType
[Index
].VendorGuid
,
1482 if (!EFI_ERROR (Status
)) {
1493 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
1495 @retval EFI_SUCCESS Operation completed successfully.
1496 @retval EFI_OUT_OF_RESOURCES Out of memory.
1497 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1501 MeasureLaunchOfFirmwareDebugger (
1505 TCG_PCR_EVENT_HDR TcgEvent
;
1507 TcgEvent
.PCRIndex
= 7;
1508 TcgEvent
.EventType
= EV_EFI_ACTION
;
1509 TcgEvent
.EventSize
= sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1;
1510 return TcgDxeHashLogExtendEvent (
1512 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
,
1513 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1,
1515 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
1520 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
1522 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
1523 - The contents of the SecureBoot variable
1524 - The contents of the PK variable
1525 - The contents of the KEK variable
1526 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
1527 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
1529 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
1531 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
1532 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
1534 @param[in] Event Event whose notification function is being invoked
1535 @param[in] Context Pointer to the notification function's context
1539 MeasureSecureBootPolicy (
1547 Status
= gBS
->LocateProtocol (&gEfiVariableWriteArchProtocolGuid
, NULL
, (VOID
**)&Protocol
);
1548 if (EFI_ERROR (Status
)) {
1552 if (PcdGetBool (PcdFirmwareDebuggerInitialized
)) {
1553 Status
= MeasureLaunchOfFirmwareDebugger ();
1554 DEBUG ((EFI_D_ERROR
, "MeasureLaunchOfFirmwareDebugger - %r\n", Status
));
1557 Status
= MeasureAllSecureVariables ();
1558 DEBUG ((EFI_D_ERROR
, "MeasureAllSecureVariables - %r\n", Status
));
1561 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
1562 // and ImageVerification (Authority)
1563 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
1564 // the Authority measurement happen before ReadToBoot event.
1566 Status
= MeasureSeparatorEvent (7);
1567 DEBUG ((EFI_D_ERROR
, "MeasureSeparatorEvent - %r\n", Status
));
1572 Ready to Boot Event notification handler.
1574 Sequence of OS boot events is measured in this event notification handler.
1576 @param[in] Event Event whose notification function is being invoked
1577 @param[in] Context Pointer to the notification function's context
1588 TPM_PCRINDEX PcrIndex
;
1590 PERF_START_EX (mImageHandle
, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE
);
1591 if (mBootAttempts
== 0) {
1594 // Measure handoff tables.
1596 Status
= MeasureHandoffTables ();
1597 if (EFI_ERROR (Status
)) {
1598 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
1602 // Measure BootOrder & Boot#### variables.
1604 Status
= MeasureAllBootVariables ();
1605 if (EFI_ERROR (Status
)) {
1606 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
1610 // 1. This is the first boot attempt.
1612 Status
= TcgMeasureAction (
1613 EFI_CALLING_EFI_APPLICATION
1617 // 2. Draw a line between pre-boot env and entering post-boot env.
1618 // PCR[7] is already done.
1620 for (PcrIndex
= 0; PcrIndex
< 7; PcrIndex
++) {
1621 Status
= MeasureSeparatorEvent (PcrIndex
);
1625 // 3. Measure GPT. It would be done in SAP driver.
1629 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1633 // 5. Read & Measure variable. BootOrder already measured.
1637 // 6. Not first attempt, meaning a return from last attempt
1639 Status
= TcgMeasureAction (
1640 EFI_RETURNING_FROM_EFI_APPLICATOIN
1644 DEBUG ((EFI_D_INFO
, "TPM2 TrEEDxe Measure Data when ReadyToBoot\n"));
1646 // Increase boot attempt counter.
1649 PERF_END_EX (mImageHandle
, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE
+ 1);
1653 Install TCG ACPI Table when ACPI Table Protocol is available.
1655 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1656 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1657 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1659 @param[in] Event Event whose notification function is being invoked
1660 @param[in] Context Pointer to the notification function's context
1671 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
1675 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
1676 if (EFI_ERROR (Status
)) {
1680 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
1681 CopyMem (mTcgClientAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgClientAcpiTemplate
.Header
.OemId
));
1682 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1683 CopyMem (&mTcgClientAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1684 mTcgClientAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1685 mTcgClientAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1686 mTcgClientAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1688 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1689 // service of the ACPI table protocol to install it.
1691 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgClientAcpiTemplate
, sizeof (mTcgClientAcpiTemplate
));
1692 mTcgClientAcpiTemplate
.Header
.Checksum
= Checksum
;
1694 Status
= AcpiTable
->InstallAcpiTable (
1696 &mTcgClientAcpiTemplate
,
1697 sizeof (mTcgClientAcpiTemplate
),
1701 CopyMem (mTcgServerAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgServerAcpiTemplate
.Header
.OemId
));
1702 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1703 CopyMem (&mTcgServerAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1704 mTcgServerAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1705 mTcgServerAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1706 mTcgServerAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1708 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1709 // service of the ACPI table protocol to install it.
1711 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgServerAcpiTemplate
, sizeof (mTcgServerAcpiTemplate
));
1712 mTcgServerAcpiTemplate
.Header
.Checksum
= Checksum
;
1714 mTcgServerAcpiTemplate
.BaseAddress
.Address
= PcdGet64 (PcdTpmBaseAddress
);
1715 Status
= AcpiTable
->InstallAcpiTable (
1717 &mTcgServerAcpiTemplate
,
1718 sizeof (mTcgServerAcpiTemplate
),
1722 ASSERT_EFI_ERROR (Status
);
1726 Exit Boot Services Event notification handler.
1728 Measure invocation and success of ExitBootServices.
1730 @param[in] Event Event whose notification function is being invoked
1731 @param[in] Context Pointer to the notification function's context
1736 OnExitBootServices (
1744 // Measure invocation of ExitBootServices,
1746 Status
= TcgMeasureAction (
1747 EFI_EXIT_BOOT_SERVICES_INVOCATION
1749 ASSERT_EFI_ERROR (Status
);
1752 // Measure success of ExitBootServices
1754 Status
= TcgMeasureAction (
1755 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1757 ASSERT_EFI_ERROR (Status
);
1761 Exit Boot Services Failed Event notification handler.
1763 Measure Failure of ExitBootServices.
1765 @param[in] Event Event whose notification function is being invoked
1766 @param[in] Context Pointer to the notification function's context
1771 OnExitBootServicesFailed (
1779 // Measure Failure of ExitBootServices,
1781 Status
= TcgMeasureAction (
1782 EFI_EXIT_BOOT_SERVICES_FAILED
1784 ASSERT_EFI_ERROR (Status
);
1789 The function install TrEE protocol.
1791 @retval EFI_SUCCESS TrEE protocol is installed.
1792 @retval other Some error occurs.
1803 Status
= gBS
->InstallMultipleProtocolInterfaces (
1805 &gEfiTrEEProtocolGuid
,
1813 The driver's entry point. It publishes EFI TrEE Protocol.
1815 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1816 @param[in] SystemTable A pointer to the EFI System Table.
1818 @retval EFI_SUCCESS The entry point is executed successfully.
1819 @retval other Some error occurs when executing this entry point.
1824 IN EFI_HANDLE ImageHandle
,
1825 IN EFI_SYSTEM_TABLE
*SystemTable
1831 UINT32 MaxCommandSize
;
1832 UINT32 MaxResponseSize
;
1833 TPML_PCR_SELECTION Pcrs
;
1835 UINT32 TpmHashAlgorithmBitmap
;
1837 mImageHandle
= ImageHandle
;
1839 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceNoneGuid
) ||
1840 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
1841 DEBUG ((EFI_D_ERROR
, "No TPM2 instance required!\n"));
1842 return EFI_UNSUPPORTED
;
1845 Status
= Tpm2RequestUseTpm ();
1846 if (EFI_ERROR (Status
)) {
1847 DEBUG ((EFI_D_ERROR
, "TPM not detected!\n"));
1854 DEBUG ((EFI_D_ERROR
, "TrEE.ProtocolVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.ProtocolVersion
.Major
, mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
));
1855 DEBUG ((EFI_D_ERROR
, "TrEE.StructureVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.StructureVersion
.Major
, mTcgDxeData
.BsCap
.StructureVersion
.Minor
));
1857 Status
= Tpm2GetCapabilityManufactureID (&mTcgDxeData
.BsCap
.ManufacturerID
);
1858 if (EFI_ERROR (Status
)) {
1859 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityManufactureID fail!\n"));
1861 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData
.BsCap
.ManufacturerID
));
1865 UINT32 FirmwareVersion1
;
1866 UINT32 FirmwareVersion2
;
1868 Status
= Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1
, &FirmwareVersion2
);
1869 if (EFI_ERROR (Status
)) {
1870 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
1872 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1
, FirmwareVersion2
));
1876 Status
= Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize
, &MaxResponseSize
);
1877 if (EFI_ERROR (Status
)) {
1878 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
1880 mTcgDxeData
.BsCap
.MaxCommandSize
= (UINT16
)MaxCommandSize
;
1881 mTcgDxeData
.BsCap
.MaxResponseSize
= (UINT16
)MaxResponseSize
;
1882 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize
, MaxResponseSize
));
1885 Status
= Tpm2GetCapabilityPcrs (&Pcrs
);
1886 if (EFI_ERROR (Status
)) {
1887 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityPcrs fail!\n"));
1888 TpmHashAlgorithmBitmap
= TREE_BOOT_HASH_ALG_SHA1
;
1890 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs
.count
));
1891 TpmHashAlgorithmBitmap
= 0;
1892 for (Index
= 0; Index
< Pcrs
.count
; Index
++) {
1893 DEBUG ((EFI_D_ERROR
, "hash - %x\n", Pcrs
.pcrSelections
[Index
].hash
));
1894 switch (Pcrs
.pcrSelections
[Index
].hash
) {
1896 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA1
;
1898 case TPM_ALG_SHA256
:
1899 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA256
;
1901 case TPM_ALG_SHA384
:
1902 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA384
;
1904 case TPM_ALG_SHA512
:
1905 TpmHashAlgorithmBitmap
|= TREE_BOOT_HASH_ALG_SHA512
;
1907 case TPM_ALG_SM3_256
:
1908 // TBD: Spec not define TREE_BOOT_HASH_ALG_SM3_256 yet
1913 DEBUG ((EFI_D_ERROR
, "TPM.HashAlgorithmBitmap - 0x%08x\n", TpmHashAlgorithmBitmap
));
1915 DEBUG ((EFI_D_ERROR
, "TrEE.SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
1916 mTcgDxeData
.BsCap
.HashAlgorithmBitmap
= TpmHashAlgorithmBitmap
;
1917 DEBUG ((EFI_D_ERROR
, "TrEE.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData
.BsCap
.HashAlgorithmBitmap
));
1919 if (mTcgDxeData
.BsCap
.TrEEPresentFlag
) {
1921 // Setup the log area and copy event log from hob list to it
1923 Status
= SetupEventLog ();
1924 ASSERT_EFI_ERROR (Status
);
1927 // Measure handoff tables, Boot#### variables etc.
1929 Status
= EfiCreateEventReadyToBootEx (
1936 Status
= gBS
->CreateEventEx (
1941 &gEfiEventExitBootServicesGuid
,
1946 // Measure Exit Boot Service failed
1948 Status
= gBS
->CreateEventEx (
1951 OnExitBootServicesFailed
,
1953 &gEventExitBootServicesFailedGuid
,
1958 // Create event callback, because we need access variable on SecureBootPolicyVariable
1959 // We should use VariableWriteArch instead of VariableArch, because Variable driver
1960 // may update SecureBoot value based on last setting.
1962 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid
, TPL_CALLBACK
, MeasureSecureBootPolicy
, NULL
, &Registration
);
1966 // Install ACPI Table
1968 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid
, TPL_CALLBACK
, InstallAcpiTable
, NULL
, &Registration
);
1971 // Install TrEEProtocol
1973 Status
= InstallTrEE ();
1974 DEBUG ((EFI_D_ERROR
, "InstallTrEE - %r\n", Status
));