2 This module implements EFI TD Protocol.
4 Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <IndustryStandard/Acpi.h>
11 #include <IndustryStandard/PeImage.h>
12 #include <IndustryStandard/TcpaAcpi.h>
14 #include <Guid/GlobalVariable.h>
15 #include <Guid/HobList.h>
16 #include <Guid/EventGroup.h>
17 #include <Guid/EventExitBootServiceFailed.h>
18 #include <Guid/ImageAuthentication.h>
19 #include <Guid/TpmInstance.h>
21 #include <Protocol/DevicePath.h>
22 #include <Protocol/MpService.h>
23 #include <Protocol/VariableWrite.h>
24 #include <Protocol/Tcg2Protocol.h>
25 #include <Protocol/TrEEProtocol.h>
26 #include <Protocol/ResetNotification.h>
27 #include <Protocol/AcpiTable.h>
29 #include <Library/DebugLib.h>
30 #include <Library/BaseMemoryLib.h>
31 #include <Library/UefiRuntimeServicesTableLib.h>
32 #include <Library/UefiDriverEntryPoint.h>
33 #include <Library/HobLib.h>
34 #include <Library/UefiBootServicesTableLib.h>
35 #include <Library/BaseLib.h>
36 #include <Library/MemoryAllocationLib.h>
37 #include <Library/PrintLib.h>
38 #include <Library/PcdLib.h>
39 #include <Library/UefiLib.h>
40 #include <Library/HashLib.h>
41 #include <Library/PerformanceLib.h>
42 #include <Library/ReportStatusCodeLib.h>
43 #include <Library/TpmMeasurementLib.h>
45 #include <Protocol/CcMeasurement.h>
46 #include <Guid/CcEventHob.h>
47 #include <Library/TdxLib.h>
49 #define PERF_ID_CC_TCG2_DXE 0x3130
51 #define CC_EVENT_LOG_AREA_COUNT_MAX 1
52 #define CC_MR_INDEX_0_MRTD 0
53 #define CC_MR_INDEX_1_RTMR0 1
54 #define CC_MR_INDEX_2_RTMR1 2
55 #define CC_MR_INDEX_3_RTMR2 3
56 #define CC_MR_INDEX_INVALID 4
65 EFI_CC_EVENT_LOG_FORMAT LogFormat
;
66 } CC_EVENT_INFO_STRUCT
;
69 EFI_CC_EVENT_LOG_FORMAT EventLogFormat
;
70 EFI_PHYSICAL_ADDRESS Lasa
;
74 BOOLEAN EventLogStarted
;
75 BOOLEAN EventLogTruncated
;
76 UINTN Next800155EventOffset
;
77 } CC_EVENT_LOG_AREA_STRUCT
;
79 typedef struct _TDX_DXE_DATA
{
80 EFI_CC_BOOT_SERVICE_CAPABILITY BsCap
;
81 CC_EVENT_LOG_AREA_STRUCT EventLogAreaStruct
[CC_EVENT_LOG_AREA_COUNT_MAX
];
82 BOOLEAN GetEventLogCalled
[CC_EVENT_LOG_AREA_COUNT_MAX
];
83 CC_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct
[CC_EVENT_LOG_AREA_COUNT_MAX
];
84 EFI_CC_FINAL_EVENTS_TABLE
*FinalEventsTable
[CC_EVENT_LOG_AREA_COUNT_MAX
];
88 TPMI_ALG_HASH HashAlgo
;
95 CC_EVENT_INFO_STRUCT mCcEventInfo
[] = {
96 { &gCcEventEntryHobGuid
, EFI_CC_EVENT_LOG_FORMAT_TCG_2
},
99 TDX_DXE_DATA mTdxDxeData
= {
101 sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY
), // Size
102 { 1, 1 }, // StructureVersion
103 { 1, 1 }, // ProtocolVersion
104 EFI_CC_BOOT_HASH_ALG_SHA384
, // HashAlgorithmBitmap
105 EFI_CC_EVENT_LOG_FORMAT_TCG_2
, // SupportedEventLogs
106 { 2, 0 } // {CC_TYPE, CC_SUBTYPE}
110 UINTN mBootAttempts
= 0;
111 CHAR16 mBootVarName
[] = L
"BootOrder";
113 VARIABLE_TYPE mVariableType
[] = {
114 { EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
},
115 { EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
},
116 { EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
},
117 { EFI_IMAGE_SECURITY_DATABASE
, &gEfiImageSecurityDatabaseGuid
},
118 { EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
},
121 EFI_CC_EVENTLOG_ACPI_TABLE mTdxEventlogAcpiTemplate
= {
123 EFI_CC_EVENTLOG_ACPI_TABLE_SIGNATURE
,
124 sizeof (mTdxEventlogAcpiTemplate
),
125 EFI_CC_EVENTLOG_ACPI_TABLE_REVISION
,
127 // Compiler initializes the remaining bytes to 0
128 // These fields should be filled in production
131 { EFI_CC_TYPE_TDX
, 0 }, // CcType
138 // Supported Hash list in Td guest.
139 // Currently SHA384 is supported.
141 TDX_HASH_INFO mHashInfo
[] = {
142 { TPM_ALG_SHA384
, SHA384_DIGEST_SIZE
, HASH_ALG_SHA384
}
146 Get hash size based on Algo
148 @param[in] HashAlgo Hash Algorithm Id.
150 @return Size of the hash.
153 GetHashSizeFromAlgo (
154 IN TPMI_ALG_HASH HashAlgo
159 for (Index
= 0; Index
< sizeof (mHashInfo
)/sizeof (mHashInfo
[0]); Index
++) {
160 if (mHashInfo
[Index
].HashAlgo
== HashAlgo
) {
161 return mHashInfo
[Index
].HashSize
;
169 Get hash mask based on Algo
171 @param[in] HashAlgo Hash Algorithm Id.
176 GetHashMaskFromAlgo (
177 IN TPMI_ALG_HASH HashAlgo
182 for (Index
= 0; Index
< ARRAY_SIZE (mHashInfo
); Index
++) {
183 if (mHashInfo
[Index
].HashAlgo
== HashAlgo
) {
184 return mHashInfo
[Index
].HashMask
;
193 Copy TPML_DIGEST_VALUES into a buffer
195 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
196 @param[in] DigestList TPML_DIGEST_VALUES to be copied.
197 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
199 @return The end of buffer to hold TPML_DIGEST_VALUES.
202 CopyDigestListToBuffer (
204 IN TPML_DIGEST_VALUES
*DigestList
,
205 IN UINT32 HashAlgorithmMask
210 UINT32 DigestListCount
;
211 UINT32
*DigestListCountPtr
;
213 DigestListCountPtr
= (UINT32
*)Buffer
;
215 Buffer
= (UINT8
*)Buffer
+ sizeof (DigestList
->count
);
216 for (Index
= 0; Index
< DigestList
->count
; Index
++) {
217 if ((DigestList
->digests
[Index
].hashAlg
& HashAlgorithmMask
) == 0) {
218 DEBUG ((DEBUG_ERROR
, "WARNING: TD Event log has HashAlg unsupported (0x%x)\n", DigestList
->digests
[Index
].hashAlg
));
222 CopyMem (Buffer
, &DigestList
->digests
[Index
].hashAlg
, sizeof (DigestList
->digests
[Index
].hashAlg
));
223 Buffer
= (UINT8
*)Buffer
+ sizeof (DigestList
->digests
[Index
].hashAlg
);
224 DigestSize
= GetHashSizeFromAlgo (DigestList
->digests
[Index
].hashAlg
);
225 CopyMem (Buffer
, &DigestList
->digests
[Index
].digest
, DigestSize
);
226 Buffer
= (UINT8
*)Buffer
+ DigestSize
;
230 WriteUnaligned32 (DigestListCountPtr
, DigestListCount
);
235 EFI_HANDLE mImageHandle
;
238 Measure PE image into TPM log based on the authenticode image hashing in
239 PE/COFF Specification 8.0 Appendix A.
241 Caution: This function may receive untrusted input.
242 PE/COFF image is external input, so this function will validate its data structure
243 within this image buffer before use.
245 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
247 @param[in] RtmrIndex RTMR index
248 @param[in] ImageAddress Start address of image buffer.
249 @param[in] ImageSize Image size
250 @param[out] DigestList Digest list of this image.
252 @retval EFI_SUCCESS Successfully measure image.
253 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
254 @retval other error value
257 MeasurePeImageAndExtend (
259 IN EFI_PHYSICAL_ADDRESS ImageAddress
,
261 OUT TPML_DIGEST_VALUES
*DigestList
264 #define COLUME_SIZE (16 * 2)
268 This function dump raw data.
271 @param Size raw data size
282 for (Index
= 0; Index
< Size
; Index
++) {
283 DEBUG ((DEBUG_INFO
, Index
== COLUME_SIZE
/2 ? " | %02x" : " %02x", (UINTN
)Data
[Index
]));
289 This function dump raw data with colume format.
292 @param Size raw data size
305 Count
= Size
/ COLUME_SIZE
;
306 Left
= Size
% COLUME_SIZE
;
307 for (Index
= 0; Index
< Count
; Index
++) {
308 DEBUG ((DEBUG_INFO
, "%04x: ", Index
* COLUME_SIZE
));
309 InternalDumpData (Data
+ Index
* COLUME_SIZE
, COLUME_SIZE
);
310 DEBUG ((DEBUG_INFO
, "\n"));
314 DEBUG ((DEBUG_INFO
, "%04x: ", Index
* COLUME_SIZE
));
315 InternalDumpData (Data
+ Index
* COLUME_SIZE
, Left
);
316 DEBUG ((DEBUG_INFO
, "\n"));
322 This function initialize TD_EVENT_HDR for EV_NO_ACTION
323 Event Type other than EFI Specification ID event. The behavior is defined
324 by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types
326 @param[in, out] NoActionEvent Event Header of EV_NO_ACTION Event
327 @param[in] EventSize Event Size of the EV_NO_ACTION Event
332 IN OUT CC_EVENT_HDR
*NoActionEvent
,
336 UINT32 DigestListCount
;
337 TPMI_ALG_HASH HashAlgId
;
340 DigestBuffer
= (UINT8
*)NoActionEvent
->Digests
.digests
;
343 NoActionEvent
->MrIndex
= 0;
344 NoActionEvent
->EventType
= EV_NO_ACTION
;
347 // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0
349 ZeroMem (&NoActionEvent
->Digests
, sizeof (NoActionEvent
->Digests
));
351 if ((mTdxDxeData
.BsCap
.HashAlgorithmBitmap
& EFI_CC_BOOT_HASH_ALG_SHA384
) != 0) {
352 HashAlgId
= TPM_ALG_SHA384
;
353 CopyMem (DigestBuffer
, &HashAlgId
, sizeof (TPMI_ALG_HASH
));
354 DigestBuffer
+= sizeof (TPMI_ALG_HASH
) + GetHashSizeFromAlgo (HashAlgId
);
361 WriteUnaligned32 ((UINT32
*)&NoActionEvent
->Digests
.count
, DigestListCount
);
366 WriteUnaligned32 ((UINT32
*)DigestBuffer
, EventSize
);
370 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
371 Caller is responsible to free LocationBuf.
373 @param[out] LocationBuf Returns Processor Location Buffer.
374 @param[out] Num Returns processor number.
376 @retval EFI_SUCCESS Operation completed successfully.
377 @retval EFI_UNSUPPORTED MpService protocol not found.
381 GetProcessorsCpuLocation (
382 OUT EFI_CPU_PHYSICAL_LOCATION
**LocationBuf
,
387 EFI_MP_SERVICES_PROTOCOL
*MpProtocol
;
389 UINTN EnabledProcessorNum
;
390 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
391 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
394 Status
= gBS
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**)&MpProtocol
);
395 if (EFI_ERROR (Status
)) {
397 // MP protocol is not installed
399 return EFI_UNSUPPORTED
;
402 Status
= MpProtocol
->GetNumberOfProcessors (
407 if (EFI_ERROR (Status
)) {
411 Status
= gBS
->AllocatePool (
413 sizeof (EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
414 (VOID
**)&ProcessorLocBuf
416 if (EFI_ERROR (Status
)) {
421 // Get each processor Location info
423 for (Index
= 0; Index
< ProcessorNum
; Index
++) {
424 Status
= MpProtocol
->GetProcessorInfo (
429 if (EFI_ERROR (Status
)) {
430 FreePool (ProcessorLocBuf
);
435 // Get all Processor Location info & measure
438 &ProcessorLocBuf
[Index
],
439 &ProcessorInfo
.Location
,
440 sizeof (EFI_CPU_PHYSICAL_LOCATION
)
444 *LocationBuf
= ProcessorLocBuf
;
451 The EFI_CC_MEASUREMENT_PROTOCOL GetCapability function call provides protocol
452 capability information and state information.
454 @param[in] This Indicates the calling context
455 @param[in, out] ProtocolCapability The caller allocates memory for a EFI_CC_BOOT_SERVICE_CAPABILITY
456 structure and sets the size field to the size of the structure allocated.
457 The callee fills in the fields with the EFI protocol capability information
458 and the current EFI TCG2 state information up to the number of fields which
459 fit within the size of the structure passed in.
461 @retval EFI_SUCCESS Operation completed successfully.
462 @retval EFI_DEVICE_ERROR The command was unsuccessful.
463 The ProtocolCapability variable will not be populated.
464 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
465 The ProtocolCapability variable will not be populated.
466 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
467 It will be partially populated (required Size field will be set).
472 IN EFI_CC_MEASUREMENT_PROTOCOL
*This
,
473 IN OUT EFI_CC_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
476 DEBUG ((DEBUG_VERBOSE
, "TdGetCapability\n"));
478 if ((This
== NULL
) || (ProtocolCapability
== NULL
)) {
479 return EFI_INVALID_PARAMETER
;
482 CopyMem (ProtocolCapability
, &mTdxDxeData
.BsCap
, sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY
));
488 This function dump PCR event.
489 TD Event log reuse the TCG PCR Event spec.
490 The first event in the event log is the SHA1 log format.
491 There is only ONE TCG_PCR_EVENT in TD Event log.
493 @param[in] EventHdr TCG PCR event structure.
497 IN TCG_PCR_EVENT_HDR
*EventHdr
502 DEBUG ((DEBUG_INFO
, " Event:\n"));
503 DEBUG ((DEBUG_INFO
, " MrIndex - %d\n", EventHdr
->PCRIndex
));
504 DEBUG ((DEBUG_INFO
, " EventType - 0x%08x\n", EventHdr
->EventType
));
505 DEBUG ((DEBUG_INFO
, " Digest - "));
506 for (Index
= 0; Index
< sizeof (TCG_DIGEST
); Index
++) {
507 DEBUG ((DEBUG_INFO
, "%02x ", EventHdr
->Digest
.digest
[Index
]));
510 DEBUG ((DEBUG_INFO
, "\n"));
511 DEBUG ((DEBUG_INFO
, " EventSize - 0x%08x\n", EventHdr
->EventSize
));
512 InternalDumpHex ((UINT8
*)(EventHdr
+ 1), EventHdr
->EventSize
);
516 This function dump TCG_EfiSpecIDEventStruct.
518 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
521 DumpTcgEfiSpecIdEventStruct (
522 IN TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
525 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
527 UINT8
*VendorInfoSize
;
529 UINT32 NumberOfAlgorithms
;
531 DEBUG ((DEBUG_INFO
, " TCG_EfiSpecIDEventStruct:\n"));
532 DEBUG ((DEBUG_INFO
, " signature - '"));
533 for (Index
= 0; Index
< sizeof (TcgEfiSpecIdEventStruct
->signature
); Index
++) {
534 DEBUG ((DEBUG_INFO
, "%c", TcgEfiSpecIdEventStruct
->signature
[Index
]));
537 DEBUG ((DEBUG_INFO
, "'\n"));
538 DEBUG ((DEBUG_INFO
, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct
->platformClass
));
539 DEBUG ((DEBUG_INFO
, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct
->specVersionMajor
, TcgEfiSpecIdEventStruct
->specVersionMinor
, TcgEfiSpecIdEventStruct
->specErrata
));
540 DEBUG ((DEBUG_INFO
, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct
->uintnSize
));
542 CopyMem (&NumberOfAlgorithms
, TcgEfiSpecIdEventStruct
+ 1, sizeof (NumberOfAlgorithms
));
543 DEBUG ((DEBUG_INFO
, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms
));
545 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof (*TcgEfiSpecIdEventStruct
) + sizeof (NumberOfAlgorithms
));
546 for (Index
= 0; Index
< NumberOfAlgorithms
; Index
++) {
547 DEBUG ((DEBUG_INFO
, " digest(%d)\n", Index
));
548 DEBUG ((DEBUG_INFO
, " algorithmId - 0x%04x\n", DigestSize
[Index
].algorithmId
));
549 DEBUG ((DEBUG_INFO
, " digestSize - 0x%04x\n", DigestSize
[Index
].digestSize
));
552 VendorInfoSize
= (UINT8
*)&DigestSize
[NumberOfAlgorithms
];
553 DEBUG ((DEBUG_INFO
, " VendorInfoSize - 0x%02x\n", *VendorInfoSize
));
554 VendorInfo
= VendorInfoSize
+ 1;
555 DEBUG ((DEBUG_INFO
, " VendorInfo - "));
556 for (Index
= 0; Index
< *VendorInfoSize
; Index
++) {
557 DEBUG ((DEBUG_INFO
, "%02x ", VendorInfo
[Index
]));
560 DEBUG ((DEBUG_INFO
, "\n"));
564 This function get size of TCG_EfiSpecIDEventStruct.
566 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
569 GetTcgEfiSpecIdEventStructSize (
570 IN TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
573 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
574 UINT8
*VendorInfoSize
;
575 UINT32 NumberOfAlgorithms
;
577 CopyMem (&NumberOfAlgorithms
, TcgEfiSpecIdEventStruct
+ 1, sizeof (NumberOfAlgorithms
));
579 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof (*TcgEfiSpecIdEventStruct
) + sizeof (NumberOfAlgorithms
));
580 VendorInfoSize
= (UINT8
*)&DigestSize
[NumberOfAlgorithms
];
581 return sizeof (TCG_EfiSpecIDEventStruct
) + sizeof (UINT32
) + (NumberOfAlgorithms
* sizeof (TCG_EfiSpecIdEventAlgorithmSize
)) + sizeof (UINT8
) + (*VendorInfoSize
);
585 This function dump TD Event (including the Digests).
587 @param[in] CcEvent TD Event structure.
596 TPMI_ALG_HASH HashAlgo
;
602 DEBUG ((DEBUG_INFO
, "Cc Event:\n"));
603 DEBUG ((DEBUG_INFO
, " MrIndex - %d\n", CcEvent
->MrIndex
));
604 DEBUG ((DEBUG_INFO
, " EventType - 0x%08x\n", CcEvent
->EventType
));
605 DEBUG ((DEBUG_INFO
, " DigestCount: 0x%08x\n", CcEvent
->Digests
.count
));
607 DigestCount
= CcEvent
->Digests
.count
;
608 HashAlgo
= CcEvent
->Digests
.digests
[0].hashAlg
;
609 DigestBuffer
= (UINT8
*)&CcEvent
->Digests
.digests
[0].digest
;
610 for (DigestIndex
= 0; DigestIndex
< DigestCount
; DigestIndex
++) {
611 DEBUG ((DEBUG_INFO
, " HashAlgo : 0x%04x\n", HashAlgo
));
612 DEBUG ((DEBUG_INFO
, " Digest(%d): \n", DigestIndex
));
613 DigestSize
= GetHashSizeFromAlgo (HashAlgo
);
614 InternalDumpHex (DigestBuffer
, DigestSize
);
618 CopyMem (&HashAlgo
, DigestBuffer
+ DigestSize
, sizeof (TPMI_ALG_HASH
));
619 DigestBuffer
= DigestBuffer
+ DigestSize
+ sizeof (TPMI_ALG_HASH
);
622 DigestBuffer
= DigestBuffer
- sizeof (TPMI_ALG_HASH
);
624 CopyMem (&EventSize
, DigestBuffer
, sizeof (CcEvent
->EventSize
));
625 DEBUG ((DEBUG_INFO
, " EventSize - 0x%08x\n", EventSize
));
626 EventBuffer
= DigestBuffer
+ sizeof (CcEvent
->EventSize
);
627 InternalDumpHex (EventBuffer
, EventSize
);
628 DEBUG ((DEBUG_INFO
, "\n"));
632 This function returns size of Td Table event.
634 @param[in] CcEvent Td Table event structure.
636 @return size of Td event.
645 TPMI_ALG_HASH HashAlgo
;
651 DigestCount
= CcEvent
->Digests
.count
;
652 HashAlgo
= CcEvent
->Digests
.digests
[0].hashAlg
;
653 DigestBuffer
= (UINT8
*)&CcEvent
->Digests
.digests
[0].digest
;
654 for (DigestIndex
= 0; DigestIndex
< DigestCount
; DigestIndex
++) {
655 DigestSize
= GetHashSizeFromAlgo (HashAlgo
);
659 CopyMem (&HashAlgo
, DigestBuffer
+ DigestSize
, sizeof (TPMI_ALG_HASH
));
660 DigestBuffer
= DigestBuffer
+ DigestSize
+ sizeof (TPMI_ALG_HASH
);
663 DigestBuffer
= DigestBuffer
- sizeof (TPMI_ALG_HASH
);
665 CopyMem (&EventSize
, DigestBuffer
, sizeof (CcEvent
->EventSize
));
666 EventBuffer
= DigestBuffer
+ sizeof (CcEvent
->EventSize
);
668 return (UINTN
)EventBuffer
+ EventSize
- (UINTN
)CcEvent
;
672 This function dump CC event log.
673 TDVF only supports EFI_CC_EVENT_LOG_FORMAT_TCG_2
675 @param[in] EventLogFormat The type of the event log for which the information is requested.
676 @param[in] EventLogLocation A pointer to the memory address of the event log.
677 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
678 address of the start of the last entry in the event log in memory.
679 @param[in] FinalEventsTable A pointer to the memory address of the final event table.
683 IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat
,
684 IN EFI_PHYSICAL_ADDRESS EventLogLocation
,
685 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry
,
686 IN EFI_CC_FINAL_EVENTS_TABLE
*FinalEventsTable
689 TCG_PCR_EVENT_HDR
*EventHdr
;
691 TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
;
692 UINTN NumberOfEvents
;
694 DEBUG ((DEBUG_INFO
, "EventLogFormat: (0x%x)\n", EventLogFormat
));
695 ASSERT (EventLogFormat
== EFI_CC_EVENT_LOG_FORMAT_TCG_2
);
699 // The first event is always the TCG_PCR_EVENT_HDR
700 // After this event is a TCG_EfiSpecIDEventStruct
702 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)EventLogLocation
;
703 DumpPcrEvent (EventHdr
);
705 TcgEfiSpecIdEventStruct
= (TCG_EfiSpecIDEventStruct
*)(EventHdr
+ 1);
706 DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct
);
709 // Then the CcEvent (Its structure is similar to TCG_PCR_EVENT2)
711 CcEvent
= (CC_EVENT
*)((UINTN
)TcgEfiSpecIdEventStruct
+ GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct
));
712 while ((UINTN
)CcEvent
<= EventLogLastEntry
) {
713 DumpCcEvent (CcEvent
);
714 CcEvent
= (CC_EVENT
*)((UINTN
)CcEvent
+ GetCcEventSize (CcEvent
));
717 if (FinalEventsTable
== NULL
) {
718 DEBUG ((DEBUG_INFO
, "FinalEventsTable: NOT FOUND\n"));
720 DEBUG ((DEBUG_INFO
, "FinalEventsTable: (0x%x)\n", FinalEventsTable
));
721 DEBUG ((DEBUG_INFO
, " Version: (0x%x)\n", FinalEventsTable
->Version
));
722 DEBUG ((DEBUG_INFO
, " NumberOfEvents: (0x%x)\n", FinalEventsTable
->NumberOfEvents
));
724 CcEvent
= (CC_EVENT
*)(UINTN
)(FinalEventsTable
+ 1);
725 for (NumberOfEvents
= 0; NumberOfEvents
< FinalEventsTable
->NumberOfEvents
; NumberOfEvents
++) {
726 DumpCcEvent (CcEvent
);
727 CcEvent
= (CC_EVENT
*)((UINTN
)CcEvent
+ GetCcEventSize (CcEvent
));
735 The EFI_CC_MEASUREMENT_PROTOCOL Get Event Log function call allows a caller to
736 retrieve the address of a given event log and its last entry.
738 @param[in] This Indicates the calling context
739 @param[in] EventLogFormat The type of the event log for which the information is requested.
740 @param[out] EventLogLocation A pointer to the memory address of the event log.
741 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
742 address of the start of the last entry in the event log in memory.
743 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
744 have exceeded the area allocated for events, this value is set to TRUE.
745 Otherwise, the value will be FALSE and the Event Log will be complete.
747 @retval EFI_SUCCESS Operation completed successfully.
748 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
749 (e.g. asking for an event log whose format is not supported).
754 IN EFI_CC_MEASUREMENT_PROTOCOL
*This
,
755 IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat
,
756 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
757 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
,
758 OUT BOOLEAN
*EventLogTruncated
763 DEBUG ((DEBUG_INFO
, "TdGetEventLog ... (0x%x)\n", EventLogFormat
));
764 ASSERT (EventLogFormat
== EFI_CC_EVENT_LOG_FORMAT_TCG_2
);
766 if (EventLogLocation
!= NULL
) {
767 *EventLogLocation
= mTdxDxeData
.EventLogAreaStruct
[Index
].Lasa
;
768 DEBUG ((DEBUG_INFO
, "TdGetEventLog (EventLogLocation - %x)\n", *EventLogLocation
));
771 if (EventLogLastEntry
!= NULL
) {
772 if (!mTdxDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
) {
773 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
775 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)mTdxDxeData
.EventLogAreaStruct
[Index
].LastEvent
;
778 DEBUG ((DEBUG_INFO
, "TdGetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry
));
781 if (EventLogTruncated
!= NULL
) {
782 *EventLogTruncated
= mTdxDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
;
783 DEBUG ((DEBUG_INFO
, "TdGetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated
));
786 DEBUG ((DEBUG_INFO
, "TdGetEventLog - %r\n", EFI_SUCCESS
));
788 // Dump Event Log for debug purpose
789 if ((EventLogLocation
!= NULL
) && (EventLogLastEntry
!= NULL
)) {
790 DumpCcEventLog (EventLogFormat
, *EventLogLocation
, *EventLogLastEntry
, mTdxDxeData
.FinalEventsTable
[Index
]);
794 // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored
795 // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.
797 mTdxDxeData
.GetEventLogCalled
[Index
] = TRUE
;
803 Return if this is a Tcg800155PlatformIdEvent.
805 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
806 @param[in] NewEventHdrSize New event header size.
807 @param[in] NewEventData Pointer to the new event data.
808 @param[in] NewEventSize New event data size.
810 @retval TRUE This is a Tcg800155PlatformIdEvent.
811 @retval FALSE This is NOT a Tcg800155PlatformIdEvent.
816 IN VOID
*NewEventHdr
,
817 IN UINT32 NewEventHdrSize
,
818 IN UINT8
*NewEventData
,
819 IN UINT32 NewEventSize
822 if ((((TCG_PCR_EVENT2_HDR
*)NewEventHdr
)->EventType
== EV_NO_ACTION
) &&
823 (NewEventSize
>= sizeof (TCG_Sp800_155_PlatformId_Event2
)) &&
826 TCG_Sp800_155_PlatformId_Event2_SIGNATURE
,
827 sizeof (TCG_Sp800_155_PlatformId_Event2_SIGNATURE
) - 1
837 Add a new entry to the Event Log.
839 @param[in, out] EventLogAreaStruct The event log area data structure
840 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
841 @param[in] NewEventHdrSize New event header size.
842 @param[in] NewEventData Pointer to the new event data.
843 @param[in] NewEventSize New event data size.
845 @retval EFI_SUCCESS The new event log entry was added.
846 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
851 IN OUT CC_EVENT_LOG_AREA_STRUCT
*EventLogAreaStruct
,
852 IN VOID
*NewEventHdr
,
853 IN UINT32 NewEventHdrSize
,
854 IN UINT8
*NewEventData
,
855 IN UINT32 NewEventSize
859 BOOLEAN Record800155Event
;
860 CC_EVENT_HDR
*CcEventHdr
;
862 CcEventHdr
= (CC_EVENT_HDR
*)NewEventHdr
;
863 DEBUG ((DEBUG_VERBOSE
, "Td: Try to log event. Index = %d, EventType = 0x%x\n", CcEventHdr
->MrIndex
, CcEventHdr
->EventType
));
865 if (NewEventSize
> MAX_ADDRESS
- NewEventHdrSize
) {
866 return EFI_OUT_OF_RESOURCES
;
869 NewLogSize
= NewEventHdrSize
+ NewEventSize
;
871 if (NewLogSize
> MAX_ADDRESS
- EventLogAreaStruct
->EventLogSize
) {
872 return EFI_OUT_OF_RESOURCES
;
875 if (NewLogSize
+ EventLogAreaStruct
->EventLogSize
> EventLogAreaStruct
->Laml
) {
876 DEBUG ((DEBUG_INFO
, " Laml - 0x%x\n", EventLogAreaStruct
->Laml
));
877 DEBUG ((DEBUG_INFO
, " NewLogSize - 0x%x\n", NewLogSize
));
878 DEBUG ((DEBUG_INFO
, " LogSize - 0x%x\n", EventLogAreaStruct
->EventLogSize
));
879 DEBUG ((DEBUG_INFO
, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES
));
880 return EFI_OUT_OF_RESOURCES
;
884 // Check 800-155 event
885 // Record to 800-155 event offset only.
886 // If the offset is 0, no need to record.
888 Record800155Event
= Is800155Event (NewEventHdr
, NewEventHdrSize
, NewEventData
, NewEventSize
);
889 if (Record800155Event
) {
890 DEBUG ((DEBUG_INFO
, "It is 800155Event.\n"));
892 if (EventLogAreaStruct
->Next800155EventOffset
!= 0) {
894 (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
+ EventLogAreaStruct
->Next800155EventOffset
+ NewLogSize
,
895 (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
+ EventLogAreaStruct
->Next800155EventOffset
,
896 EventLogAreaStruct
->EventLogSize
- EventLogAreaStruct
->Next800155EventOffset
900 (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
+ EventLogAreaStruct
->Next800155EventOffset
,
905 (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
+ EventLogAreaStruct
->Next800155EventOffset
+ NewEventHdrSize
,
910 EventLogAreaStruct
->Next800155EventOffset
+= NewLogSize
;
911 EventLogAreaStruct
->LastEvent
+= NewLogSize
;
912 EventLogAreaStruct
->EventLogSize
+= NewLogSize
;
918 EventLogAreaStruct
->LastEvent
= (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
+ EventLogAreaStruct
->EventLogSize
;
919 EventLogAreaStruct
->EventLogSize
+= NewLogSize
;
921 CopyMem (EventLogAreaStruct
->LastEvent
, NewEventHdr
, NewEventHdrSize
);
923 EventLogAreaStruct
->LastEvent
+ NewEventHdrSize
,
932 According to UEFI Spec 2.10 Section 38.4.1:
933 The following table shows the TPM PCR index mapping and CC event log measurement
934 register index interpretation for Intel TDX, where MRTD means Trust Domain Measurement
935 Register and RTMR means Runtime Measurement Register
937 // TPM PCR Index | CC Measurement Register Index | TDX-measurement register
938 // ------------------------------------------------------------------------
940 // 1, 7 | 1 | RTMR[0]
942 // 8~15 | 3 | RTMR[2]
944 @param[in] PCRIndex Index of the TPM PCR
946 @retval UINT32 Index of the CC Event Log Measurement Register Index
947 @retval CC_MR_INDEX_INVALID Invalid MR Index
959 return CC_MR_INDEX_INVALID
;
964 MrIndex
= CC_MR_INDEX_0_MRTD
;
965 } else if ((PCRIndex
== 1) || (PCRIndex
== 7)) {
966 MrIndex
= CC_MR_INDEX_1_RTMR0
;
967 } else if ((PCRIndex
>= 2) && (PCRIndex
<= 6)) {
968 MrIndex
= CC_MR_INDEX_2_RTMR1
;
969 } else if ((PCRIndex
>= 8) && (PCRIndex
<= 15)) {
970 MrIndex
= CC_MR_INDEX_3_RTMR2
;
979 IN EFI_CC_MEASUREMENT_PROTOCOL
*This
,
984 if (MrIndex
== NULL
) {
985 return EFI_INVALID_PARAMETER
;
988 *MrIndex
= MapPcrToMrIndex (PCRIndex
);
990 return *MrIndex
== CC_MR_INDEX_INVALID
? EFI_INVALID_PARAMETER
: EFI_SUCCESS
;
994 Add a new entry to the Event Log.
996 @param[in] EventLogFormat The type of the event log for which the information is requested.
997 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
998 @param[in] NewEventHdrSize New event header size.
999 @param[in] NewEventData Pointer to the new event data.
1000 @param[in] NewEventSize New event data size.
1002 @retval EFI_SUCCESS The new event log entry was added.
1003 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1008 IN EFI_CC_EVENT_LOG_FORMAT EventLogFormat
,
1009 IN VOID
*NewEventHdr
,
1010 IN UINT32 NewEventHdrSize
,
1011 IN UINT8
*NewEventData
,
1012 IN UINT32 NewEventSize
1017 CC_EVENT_LOG_AREA_STRUCT
*EventLogAreaStruct
;
1019 if (EventLogFormat
!= EFI_CC_EVENT_LOG_FORMAT_TCG_2
) {
1021 return EFI_INVALID_PARAMETER
;
1027 // Record to normal event log
1029 EventLogAreaStruct
= &mTdxDxeData
.EventLogAreaStruct
[Index
];
1031 if (EventLogAreaStruct
->EventLogTruncated
) {
1032 return EFI_VOLUME_FULL
;
1035 Status
= TcgCommLogEvent (
1043 if (Status
== EFI_OUT_OF_RESOURCES
) {
1044 EventLogAreaStruct
->EventLogTruncated
= TRUE
;
1045 return EFI_VOLUME_FULL
;
1046 } else if (Status
== EFI_SUCCESS
) {
1047 EventLogAreaStruct
->EventLogStarted
= TRUE
;
1051 // If GetEventLog is called, record to FinalEventsTable, too.
1053 if (mTdxDxeData
.GetEventLogCalled
[Index
]) {
1054 if (mTdxDxeData
.FinalEventsTable
[Index
] == NULL
) {
1056 // no need for FinalEventsTable
1061 EventLogAreaStruct
= &mTdxDxeData
.FinalEventLogAreaStruct
[Index
];
1063 if (EventLogAreaStruct
->EventLogTruncated
) {
1064 return EFI_VOLUME_FULL
;
1067 Status
= TcgCommLogEvent (
1074 if (Status
== EFI_OUT_OF_RESOURCES
) {
1075 EventLogAreaStruct
->EventLogTruncated
= TRUE
;
1076 return EFI_VOLUME_FULL
;
1077 } else if (Status
== EFI_SUCCESS
) {
1078 EventLogAreaStruct
->EventLogStarted
= TRUE
;
1080 // Increase the NumberOfEvents in FinalEventsTable
1082 (mTdxDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
++;
1083 DEBUG ((DEBUG_INFO
, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTdxDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
));
1084 DEBUG ((DEBUG_INFO
, " Size - 0x%x\n", (UINTN
)EventLogAreaStruct
->EventLogSize
));
1092 Get TPML_DIGEST_VALUES compact binary buffer size.
1094 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
1096 @return TPML_DIGEST_VALUES compact binary buffer size.
1099 GetDigestListBinSize (
1100 IN VOID
*DigestListBin
1107 TPMI_ALG_HASH HashAlg
;
1109 Count
= ReadUnaligned32 (DigestListBin
);
1110 TotalSize
= sizeof (Count
);
1111 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof (Count
);
1112 for (Index
= 0; Index
< Count
; Index
++) {
1113 HashAlg
= ReadUnaligned16 (DigestListBin
);
1114 TotalSize
+= sizeof (HashAlg
);
1115 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof (HashAlg
);
1117 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
1118 TotalSize
+= DigestSize
;
1119 DigestListBin
= (UINT8
*)DigestListBin
+ DigestSize
;
1126 Copy TPML_DIGEST_VALUES compact binary into a buffer
1128 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
1129 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
1130 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
1131 @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.
1133 @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
1136 CopyDigestListBinToBuffer (
1137 IN OUT VOID
*Buffer
,
1138 IN VOID
*DigestListBin
,
1139 IN UINT32 HashAlgorithmMask
,
1140 OUT UINT32
*HashAlgorithmMaskCopied
1146 TPMI_ALG_HASH HashAlg
;
1147 UINT32 DigestListCount
;
1148 UINT32
*DigestListCountPtr
;
1150 DigestListCountPtr
= (UINT32
*)Buffer
;
1151 DigestListCount
= 0;
1152 *HashAlgorithmMaskCopied
= 0;
1154 Count
= ReadUnaligned32 (DigestListBin
);
1155 Buffer
= (UINT8
*)Buffer
+ sizeof (Count
);
1156 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof (Count
);
1157 for (Index
= 0; Index
< Count
; Index
++) {
1158 HashAlg
= ReadUnaligned16 (DigestListBin
);
1159 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof (HashAlg
);
1160 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
1162 if ((HashAlg
& HashAlgorithmMask
) != 0) {
1163 CopyMem (Buffer
, &HashAlg
, sizeof (HashAlg
));
1164 Buffer
= (UINT8
*)Buffer
+ sizeof (HashAlg
);
1165 CopyMem (Buffer
, DigestListBin
, DigestSize
);
1166 Buffer
= (UINT8
*)Buffer
+ DigestSize
;
1168 (*HashAlgorithmMaskCopied
) |= GetHashMaskFromAlgo (HashAlg
);
1170 DEBUG ((DEBUG_ERROR
, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg
));
1173 DigestListBin
= (UINT8
*)DigestListBin
+ DigestSize
;
1176 WriteUnaligned32 (DigestListCountPtr
, DigestListCount
);
1182 Add a new entry to the Event Log. The call chain is like below:
1183 TdxDxeLogHashEvent -> TdxDxeLogEvent -> TcgCommonLogEvent
1185 Before this function is called, the event information (including the digest)
1188 @param[in] DigestList A list of digest.
1189 @param[in,out] NewEventHdr Pointer to a TD_EVENT_HDR data structure.
1190 @param[in] NewEventData Pointer to the new event data.
1192 @retval EFI_SUCCESS The new event log entry was added.
1193 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1196 TdxDxeLogHashEvent (
1197 IN TPML_DIGEST_VALUES
*DigestList
,
1198 IN OUT CC_EVENT_HDR
*NewEventHdr
,
1199 IN UINT8
*NewEventData
1204 EFI_STATUS RetStatus
;
1206 UINT8
*DigestBuffer
;
1207 UINT32
*EventSizePtr
;
1208 EFI_CC_EVENT_LOG_FORMAT LogFormat
;
1210 RetStatus
= EFI_SUCCESS
;
1211 LogFormat
= EFI_CC_EVENT_LOG_FORMAT_TCG_2
;
1213 ZeroMem (&CcEvent
, sizeof (CcEvent
));
1214 CcEvent
.MrIndex
= NewEventHdr
->MrIndex
;
1215 CcEvent
.EventType
= NewEventHdr
->EventType
;
1216 DigestBuffer
= (UINT8
*)&CcEvent
.Digests
;
1217 EventSizePtr
= CopyDigestListToBuffer (DigestBuffer
, DigestList
, HASH_ALG_SHA384
);
1218 CopyMem (EventSizePtr
, &NewEventHdr
->EventSize
, sizeof (NewEventHdr
->EventSize
));
1221 // Enter critical region
1223 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
1224 Status
= TdxDxeLogEvent (
1227 sizeof (CcEvent
.MrIndex
) + sizeof (CcEvent
.EventType
) + GetDigestListBinSize (DigestBuffer
) + sizeof (CcEvent
.EventSize
),
1229 NewEventHdr
->EventSize
1231 if (Status
!= EFI_SUCCESS
) {
1235 gBS
->RestoreTPL (OldTpl
);
1241 Do a hash operation on a data buffer, extend a specific RTMR with the hash result,
1242 and add an entry to the Event Log.
1244 @param[in] Flags Bitmap providing additional information.
1245 @param[in] HashData Physical address of the start of the data buffer
1246 to be hashed, extended, and logged.
1247 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
1248 @param[in, out] NewEventHdr Pointer to a TD_EVENT_HDR data structure.
1249 @param[in] NewEventData Pointer to the new event data.
1251 @retval EFI_SUCCESS Operation completed successfully.
1252 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1253 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1257 TdxDxeHashLogExtendEvent (
1260 IN UINT64 HashDataLen
,
1261 IN OUT CC_EVENT_HDR
*NewEventHdr
,
1262 IN UINT8
*NewEventData
1266 TPML_DIGEST_VALUES DigestList
;
1267 CC_EVENT_HDR NoActionEvent
;
1269 if (NewEventHdr
->EventType
== EV_NO_ACTION
) {
1271 // Do not do RTMR extend for EV_NO_ACTION
1273 Status
= EFI_SUCCESS
;
1274 InitNoActionEvent (&NoActionEvent
, NewEventHdr
->EventSize
);
1275 if ((Flags
& EFI_CC_FLAG_EXTEND_ONLY
) == 0) {
1276 Status
= TdxDxeLogHashEvent (&(NoActionEvent
.Digests
), NewEventHdr
, NewEventData
);
1283 // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
1284 // TDX Measurement Register is:
1285 // MrIndex 0 <--> MRTD
1286 // MrIndex 1-3 <--> RTMR[0-2]
1287 // Only the RMTR registers can be extended in TDVF by HashAndExtend. So MrIndex will
1288 // decreased by 1 before it is sent to HashAndExtend.
1290 Status
= HashAndExtend (
1291 NewEventHdr
->MrIndex
- 1,
1296 if (!EFI_ERROR (Status
)) {
1297 if ((Flags
& EFI_CC_FLAG_EXTEND_ONLY
) == 0) {
1298 Status
= TdxDxeLogHashEvent (&DigestList
, NewEventHdr
, NewEventData
);
1306 The EFI_CC_MEASUREMENT_PROTOCOL HashLogExtendEvent function call provides callers with
1307 an opportunity to extend and optionally log events without requiring
1308 knowledge of actual TPM commands.
1309 The extend operation will occur even if this function cannot create an event
1310 log entry (e.g. due to the event log being full).
1312 @param[in] This Indicates the calling context
1313 @param[in] Flags Bitmap providing additional information.
1314 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
1315 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
1316 @param[in] Event Pointer to data buffer containing information about the event.
1318 @retval EFI_SUCCESS Operation completed successfully.
1319 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1320 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
1321 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1322 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
1326 TdHashLogExtendEvent (
1327 IN EFI_CC_MEASUREMENT_PROTOCOL
*This
,
1329 IN EFI_PHYSICAL_ADDRESS DataToHash
,
1330 IN UINT64 DataToHashLen
,
1331 IN EFI_CC_EVENT
*CcEvent
1335 CC_EVENT_HDR NewEventHdr
;
1336 TPML_DIGEST_VALUES DigestList
;
1338 DEBUG ((DEBUG_VERBOSE
, "TdHashLogExtendEvent ...\n"));
1340 if ((This
== NULL
) || (CcEvent
== NULL
)) {
1341 return EFI_INVALID_PARAMETER
;
1345 // Do not check hash data size for EV_NO_ACTION event.
1347 if ((CcEvent
->Header
.EventType
!= EV_NO_ACTION
) && (DataToHash
== 0)) {
1348 return EFI_INVALID_PARAMETER
;
1351 if (CcEvent
->Size
< CcEvent
->Header
.HeaderSize
+ sizeof (UINT32
)) {
1352 return EFI_INVALID_PARAMETER
;
1355 if (CcEvent
->Header
.MrIndex
== CC_MR_INDEX_0_MRTD
) {
1356 DEBUG ((DEBUG_ERROR
, "%a: MRTD cannot be extended in TDVF.\n", __FUNCTION__
));
1357 return EFI_INVALID_PARAMETER
;
1360 if (CcEvent
->Header
.MrIndex
>= CC_MR_INDEX_INVALID
) {
1361 DEBUG ((DEBUG_ERROR
, "%a: MrIndex is invalid. (%d)\n", __FUNCTION__
, CcEvent
->Header
.MrIndex
));
1362 return EFI_INVALID_PARAMETER
;
1365 NewEventHdr
.MrIndex
= CcEvent
->Header
.MrIndex
;
1366 NewEventHdr
.EventType
= CcEvent
->Header
.EventType
;
1367 NewEventHdr
.EventSize
= CcEvent
->Size
- sizeof (UINT32
) - CcEvent
->Header
.HeaderSize
;
1368 if ((Flags
& EFI_CC_FLAG_PE_COFF_IMAGE
) != 0) {
1370 // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
1371 // TDX Measurement Register is:
1372 // MrIndex 0 <--> MRTD
1373 // MrIndex 1-3 <--> RTMR[0-2]
1374 // Only the RMTR registers can be extended in TDVF by HashAndExtend. So MrIndex will
1375 // decreased by 1 before it is sent to MeasurePeImageAndExtend.
1377 Status
= MeasurePeImageAndExtend (
1378 NewEventHdr
.MrIndex
- 1,
1380 (UINTN
)DataToHashLen
,
1383 if (!EFI_ERROR (Status
)) {
1384 if ((Flags
& EFI_CC_FLAG_EXTEND_ONLY
) == 0) {
1385 Status
= TdxDxeLogHashEvent (&DigestList
, &NewEventHdr
, CcEvent
->Event
);
1389 Status
= TdxDxeHashLogExtendEvent (
1391 (UINT8
*)(UINTN
)DataToHash
,
1398 DEBUG ((DEBUG_VERBOSE
, "TdHashLogExtendEvent - %r\n", Status
));
1402 EFI_CC_MEASUREMENT_PROTOCOL mTdProtocol
= {
1405 TdHashLogExtendEvent
,
1409 #define TD_HASH_COUNT 1
1410 #define TEMP_BUF_LEN (sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) \
1411 + (TD_HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8))
1414 Initialize the TD Event Log and log events passed from the PEI phase.
1416 @retval EFI_SUCCESS Operation completed successfully.
1417 @retval EFI_OUT_OF_RESOURCES Out of memory.
1426 EFI_PHYSICAL_ADDRESS Lasa
;
1428 TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
;
1429 UINT8 TempBuf
[TEMP_BUF_LEN
];
1430 TCG_PCR_EVENT_HDR SpecIdEvent
;
1431 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
1432 TCG_EfiSpecIdEventAlgorithmSize
*TempDigestSize
;
1433 UINT8
*VendorInfoSize
;
1434 UINT32 NumberOfAlgorithms
;
1435 EFI_CC_EVENT_LOG_FORMAT LogFormat
;
1436 EFI_PEI_HOB_POINTERS GuidHob
;
1437 CC_EVENT_HDR NoActionEvent
;
1439 Status
= EFI_SUCCESS
;
1440 DEBUG ((DEBUG_INFO
, "SetupCcEventLog\n"));
1443 LogFormat
= EFI_CC_EVENT_LOG_FORMAT_TCG_2
;
1446 // 1. Create Log Area
1448 mTdxDxeData
.EventLogAreaStruct
[Index
].EventLogFormat
= LogFormat
;
1450 // allocate pages for TD Event log
1451 Status
= gBS
->AllocatePages (
1454 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen
)),
1457 if (EFI_ERROR (Status
)) {
1461 mTdxDxeData
.EventLogAreaStruct
[Index
].Lasa
= Lasa
;
1462 mTdxDxeData
.EventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
1463 mTdxDxeData
.EventLogAreaStruct
[Index
].Next800155EventOffset
= 0;
1466 // Report TD event log address and length, so that they can be reported in
1467 // TD ACPI table. Ignore the return status, because those fields are optional.
1469 PcdSet32S (PcdCcEventlogAcpiTableLaml
, (UINT32
)mTdxDxeData
.EventLogAreaStruct
[Index
].Laml
);
1470 PcdSet64S (PcdCcEventlogAcpiTableLasa
, mTdxDxeData
.EventLogAreaStruct
[Index
].Lasa
);
1473 // To initialize them as 0xFF is recommended
1474 // because the OS can know the last entry for that.
1476 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcgLogAreaMinLen
), 0xFF);
1479 // Create first entry for Log Header Entry Data
1483 // TcgEfiSpecIdEventStruct
1485 TcgEfiSpecIdEventStruct
= (TCG_EfiSpecIDEventStruct
*)TempBuf
;
1486 CopyMem (TcgEfiSpecIdEventStruct
->signature
, TCG_EfiSpecIDEventStruct_SIGNATURE_03
, sizeof (TcgEfiSpecIdEventStruct
->signature
));
1488 TcgEfiSpecIdEventStruct
->platformClass
= PcdGet8 (PcdTpmPlatformClass
);
1490 TcgEfiSpecIdEventStruct
->specVersionMajor
= TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2
;
1491 TcgEfiSpecIdEventStruct
->specVersionMinor
= TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2
;
1492 TcgEfiSpecIdEventStruct
->specErrata
= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2
;
1493 TcgEfiSpecIdEventStruct
->uintnSize
= sizeof (UINTN
)/sizeof (UINT32
);
1494 NumberOfAlgorithms
= 0;
1495 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
1496 + sizeof (*TcgEfiSpecIdEventStruct
)
1497 + sizeof (NumberOfAlgorithms
));
1499 TempDigestSize
= DigestSize
;
1500 TempDigestSize
+= NumberOfAlgorithms
;
1501 TempDigestSize
->algorithmId
= TPM_ALG_SHA384
;
1502 TempDigestSize
->digestSize
= SHA384_DIGEST_SIZE
;
1503 NumberOfAlgorithms
++;
1505 CopyMem (TcgEfiSpecIdEventStruct
+ 1, &NumberOfAlgorithms
, sizeof (NumberOfAlgorithms
));
1506 TempDigestSize
= DigestSize
;
1507 TempDigestSize
+= NumberOfAlgorithms
;
1508 VendorInfoSize
= (UINT8
*)TempDigestSize
;
1509 *VendorInfoSize
= 0;
1511 SpecIdEvent
.PCRIndex
= 1; // PCRIndex 0 maps to MrIndex 1
1512 SpecIdEvent
.EventType
= EV_NO_ACTION
;
1513 ZeroMem (&SpecIdEvent
.Digest
, sizeof (SpecIdEvent
.Digest
));
1514 SpecIdEvent
.EventSize
= (UINT32
)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct
);
1517 // TD Event log re-use the spec of TCG2 Event log.
1518 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.
1519 // TCG EFI Protocol Spec. Section 5.3 Event Log Header
1520 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log
1522 Status
= TdxDxeLogEvent (
1525 sizeof (SpecIdEvent
),
1526 (UINT8
*)TcgEfiSpecIdEventStruct
,
1527 SpecIdEvent
.EventSize
1530 // record the offset at the end of 800-155 event.
1531 // the future 800-155 event can be inserted here.
1533 mTdxDxeData
.EventLogAreaStruct
[Index
].Next800155EventOffset
= mTdxDxeData
.EventLogAreaStruct
[Index
].EventLogSize
;
1536 // Tcg800155PlatformIdEvent. Event format is TCG_PCR_EVENT2
1538 GuidHob
.Guid
= GetFirstGuidHob (&gTcg800155PlatformIdEventHobGuid
);
1539 while (GuidHob
.Guid
!= NULL
) {
1540 InitNoActionEvent (&NoActionEvent
, GET_GUID_HOB_DATA_SIZE (GuidHob
.Guid
));
1542 Status
= TdxDxeLogEvent (
1545 sizeof (NoActionEvent
.MrIndex
) + sizeof (NoActionEvent
.EventType
) + GetDigestListBinSize (&NoActionEvent
.Digests
) + sizeof (NoActionEvent
.EventSize
),
1546 GET_GUID_HOB_DATA (GuidHob
.Guid
),
1547 GET_GUID_HOB_DATA_SIZE (GuidHob
.Guid
)
1550 GuidHob
.Guid
= GET_NEXT_HOB (GuidHob
);
1551 GuidHob
.Guid
= GetNextGuidHob (&gTcg800155PlatformIdEventHobGuid
, GuidHob
.Guid
);
1555 // 2. Create Final Log Area
1557 Status
= gBS
->AllocatePages (
1560 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen
)),
1563 if (EFI_ERROR (Status
)) {
1567 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcg2FinalLogAreaLen
), 0xFF);
1572 mTdxDxeData
.FinalEventsTable
[Index
] = (VOID
*)(UINTN
)Lasa
;
1573 (mTdxDxeData
.FinalEventsTable
[Index
])->Version
= EFI_TCG2_FINAL_EVENTS_TABLE_VERSION
;
1574 (mTdxDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
= 0;
1576 mTdxDxeData
.FinalEventLogAreaStruct
[Index
].EventLogFormat
= LogFormat
;
1577 mTdxDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
= Lasa
+ sizeof (EFI_CC_FINAL_EVENTS_TABLE
);
1578 mTdxDxeData
.FinalEventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcg2FinalLogAreaLen
) - sizeof (EFI_CC_FINAL_EVENTS_TABLE
);
1579 mTdxDxeData
.FinalEventLogAreaStruct
[Index
].EventLogSize
= 0;
1580 mTdxDxeData
.FinalEventLogAreaStruct
[Index
].LastEvent
= (VOID
*)(UINTN
)mTdxDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
;
1581 mTdxDxeData
.FinalEventLogAreaStruct
[Index
].EventLogStarted
= FALSE
;
1582 mTdxDxeData
.FinalEventLogAreaStruct
[Index
].EventLogTruncated
= FALSE
;
1583 mTdxDxeData
.FinalEventLogAreaStruct
[Index
].Next800155EventOffset
= 0;
1586 // Install to configuration table for EFI_CC_EVENT_LOG_FORMAT_TCG_2
1588 Status
= gBS
->InstallConfigurationTable (&gEfiCcFinalEventsTableGuid
, (VOID
*)mTdxDxeData
.FinalEventsTable
[Index
]);
1589 if (EFI_ERROR (Status
)) {
1597 Measure and log an action string, and extend the measurement result into RTMR.
1599 @param[in] MrIndex MrIndex to extend
1600 @param[in] String A specific string that indicates an Action event.
1602 @retval EFI_SUCCESS Operation completed successfully.
1603 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1612 CC_EVENT_HDR CcEvent
;
1614 CcEvent
.MrIndex
= MrIndex
;
1615 CcEvent
.EventType
= EV_EFI_ACTION
;
1616 CcEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
1617 return TdxDxeHashLogExtendEvent (
1627 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1629 @retval EFI_SUCCESS Operation completed successfully.
1630 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1634 MeasureHandoffTables (
1639 CC_EVENT_HDR CcEvent
;
1640 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
1642 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
1644 ProcessorLocBuf
= NULL
;
1645 Status
= EFI_SUCCESS
;
1647 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
1650 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1652 Status
= GetProcessorsCpuLocation (&ProcessorLocBuf
, &ProcessorNum
);
1654 if (!EFI_ERROR (Status
)) {
1655 CcEvent
.MrIndex
= MapPcrToMrIndex (1);
1656 CcEvent
.EventType
= EV_TABLE_OF_DEVICES
;
1657 CcEvent
.EventSize
= sizeof (HandoffTables
);
1659 HandoffTables
.NumberOfTables
= 1;
1660 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
1661 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
1663 Status
= TdxDxeHashLogExtendEvent (
1665 (UINT8
*)(UINTN
)ProcessorLocBuf
,
1666 sizeof (EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
1668 (UINT8
*)&HandoffTables
1671 FreePool (ProcessorLocBuf
);
1679 Measure and log Separator event, and extend the measurement result into a specific PCR.
1681 @param[in] PCRIndex PCR index.
1683 @retval EFI_SUCCESS Operation completed successfully.
1684 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1688 MeasureSeparatorEvent (
1692 CC_EVENT_HDR CcEvent
;
1695 DEBUG ((DEBUG_INFO
, "MeasureSeparatorEvent to Rtmr - %d\n", MrIndex
));
1698 CcEvent
.MrIndex
= MrIndex
;
1699 CcEvent
.EventType
= EV_SEPARATOR
;
1700 CcEvent
.EventSize
= (UINT32
)sizeof (EventData
);
1702 return TdxDxeHashLogExtendEvent (
1704 (UINT8
*)&EventData
,
1712 Measure and log an EFI variable, and extend the measurement result into a specific RTMR.
1714 @param[in] MrIndex RTMR Index.
1715 @param[in] EventType Event type.
1716 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1717 @param[in] VendorGuid A unique identifier for the vendor.
1718 @param[in] VarData The content of the variable data.
1719 @param[in] VarSize The size of the variable data.
1721 @retval EFI_SUCCESS Operation completed successfully.
1722 @retval EFI_OUT_OF_RESOURCES Out of memory.
1723 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1729 IN TCG_EVENTTYPE EventType
,
1731 IN EFI_GUID
*VendorGuid
,
1737 CC_EVENT_HDR CcEvent
;
1738 UINTN VarNameLength
;
1739 UEFI_VARIABLE_DATA
*VarLog
;
1741 DEBUG ((DEBUG_INFO
, "TdTcg2Dxe: MeasureVariable (Rtmr - %x, EventType - %x, ", (UINTN
)MrIndex
, (UINTN
)EventType
));
1742 DEBUG ((DEBUG_INFO
, "VariableName - %s, VendorGuid - %g)\n", VarName
, VendorGuid
));
1744 VarNameLength
= StrLen (VarName
);
1745 CcEvent
.MrIndex
= MrIndex
;
1746 CcEvent
.EventType
= EventType
;
1748 CcEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
1749 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
1751 VarLog
= (UEFI_VARIABLE_DATA
*)AllocatePool (CcEvent
.EventSize
);
1752 if (VarLog
== NULL
) {
1753 return EFI_OUT_OF_RESOURCES
;
1756 VarLog
->VariableName
= *VendorGuid
;
1757 VarLog
->UnicodeNameLength
= VarNameLength
;
1758 VarLog
->VariableDataLength
= VarSize
;
1760 VarLog
->UnicodeName
,
1762 VarNameLength
* sizeof (*VarName
)
1764 if ((VarSize
!= 0) && (VarData
!= NULL
)) {
1766 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
1772 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1774 // Digest is the event data (UEFI_VARIABLE_DATA)
1776 Status
= TdxDxeHashLogExtendEvent (
1784 ASSERT (VarData
!= NULL
);
1785 Status
= TdxDxeHashLogExtendEvent (
1799 Read then Measure and log an EFI variable, and extend the measurement result into a specific RTMR.
1801 @param[in] MrIndex RTMR Index.
1802 @param[in] EventType Event type.
1803 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1804 @param[in] VendorGuid A unique identifier for the vendor.
1805 @param[out] VarSize The size of the variable data.
1806 @param[out] VarData Pointer to the content of the variable.
1808 @retval EFI_SUCCESS Operation completed successfully.
1809 @retval EFI_OUT_OF_RESOURCES Out of memory.
1810 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1814 ReadAndMeasureVariable (
1816 IN TCG_EVENTTYPE EventType
,
1818 IN EFI_GUID
*VendorGuid
,
1825 Status
= GetVariable2 (VarName
, VendorGuid
, VarData
, VarSize
);
1826 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1827 if (EFI_ERROR (Status
)) {
1829 // It is valid case, so we need handle it.
1836 // if status error, VarData is freed and set NULL by GetVariable2
1838 if (EFI_ERROR (Status
)) {
1839 return EFI_NOT_FOUND
;
1843 Status
= MeasureVariable (
1855 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].
1856 according to TCG PC Client PFP spec 0021 Section 2.4.4.2
1858 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1859 @param[in] VendorGuid A unique identifier for the vendor.
1860 @param[out] VarSize The size of the variable data.
1861 @param[out] VarData Pointer to the content of the variable.
1863 @retval EFI_SUCCESS Operation completed successfully.
1864 @retval EFI_OUT_OF_RESOURCES Out of memory.
1865 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1869 ReadAndMeasureBootVariable (
1871 IN EFI_GUID
*VendorGuid
,
1876 return ReadAndMeasureVariable (
1877 MapPcrToMrIndex (1),
1878 EV_EFI_VARIABLE_BOOT
,
1887 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1889 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1890 @param[in] VendorGuid A unique identifier for the vendor.
1891 @param[out] VarSize The size of the variable data.
1892 @param[out] VarData Pointer to the content of the variable.
1894 @retval EFI_SUCCESS Operation completed successfully.
1895 @retval EFI_OUT_OF_RESOURCES Out of memory.
1896 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1900 ReadAndMeasureSecureVariable (
1902 IN EFI_GUID
*VendorGuid
,
1907 return ReadAndMeasureVariable (
1908 MapPcrToMrIndex (7),
1909 EV_EFI_VARIABLE_DRIVER_CONFIG
,
1918 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1920 The EFI boot variables are BootOrder and Boot#### variables.
1922 @retval EFI_SUCCESS Operation completed successfully.
1923 @retval EFI_OUT_OF_RESOURCES Out of memory.
1924 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1928 MeasureAllBootVariables (
1939 Status
= ReadAndMeasureBootVariable (
1941 &gEfiGlobalVariableGuid
,
1945 if ((Status
== EFI_NOT_FOUND
) || (BootOrder
== NULL
)) {
1949 if (EFI_ERROR (Status
)) {
1951 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1953 FreePool (BootOrder
);
1957 BootCount
/= sizeof (*BootOrder
);
1958 for (Index
= 0; Index
< BootCount
; Index
++) {
1959 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
1960 Status
= ReadAndMeasureBootVariable (
1962 &gEfiGlobalVariableGuid
,
1966 if (!EFI_ERROR (Status
)) {
1967 FreePool (BootVarData
);
1971 FreePool (BootOrder
);
1976 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1978 The EFI boot variables are BootOrder and Boot#### variables.
1980 @retval EFI_SUCCESS Operation completed successfully.
1981 @retval EFI_OUT_OF_RESOURCES Out of memory.
1982 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1986 MeasureAllSecureVariables (
1995 Status
= EFI_NOT_FOUND
;
1996 for (Index
= 0; Index
< sizeof (mVariableType
)/sizeof (mVariableType
[0]); Index
++) {
1997 Status
= ReadAndMeasureSecureVariable (
1998 mVariableType
[Index
].VariableName
,
1999 mVariableType
[Index
].VendorGuid
,
2003 if (!EFI_ERROR (Status
)) {
2011 // Measure DBT if present and not empty
2013 Status
= GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2
, &gEfiImageSecurityDatabaseGuid
, &Data
, &DataSize
);
2014 if (!EFI_ERROR (Status
)) {
2015 Status
= MeasureVariable (
2016 MapPcrToMrIndex (7),
2017 EV_EFI_VARIABLE_DRIVER_CONFIG
,
2018 EFI_IMAGE_SECURITY_DATABASE2
,
2019 &gEfiImageSecurityDatabaseGuid
,
2025 DEBUG ((DEBUG_INFO
, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2
));
2032 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
2034 @retval EFI_SUCCESS Operation completed successfully.
2035 @retval EFI_OUT_OF_RESOURCES Out of memory.
2036 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2040 MeasureLaunchOfFirmwareDebugger (
2044 CC_EVENT_HDR CcEvent
;
2046 CcEvent
.MrIndex
= MapPcrToMrIndex (7);
2047 CcEvent
.EventType
= EV_EFI_ACTION
;
2048 CcEvent
.EventSize
= sizeof (FIRMWARE_DEBUGGER_EVENT_STRING
) - 1;
2049 return TdxDxeHashLogExtendEvent (
2051 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
,
2052 sizeof (FIRMWARE_DEBUGGER_EVENT_STRING
) - 1,
2054 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
2059 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
2061 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
2062 - The contents of the SecureBoot variable
2063 - The contents of the PK variable
2064 - The contents of the KEK variable
2065 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
2066 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
2068 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
2070 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
2071 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
2073 @param[in] Event Event whose notification function is being invoked
2074 @param[in] Context Pointer to the notification function's context
2078 MeasureSecureBootPolicy (
2086 Status
= gBS
->LocateProtocol (&gEfiVariableWriteArchProtocolGuid
, NULL
, (VOID
**)&Protocol
);
2087 if (EFI_ERROR (Status
)) {
2091 if (PcdGetBool (PcdFirmwareDebuggerInitialized
)) {
2092 Status
= MeasureLaunchOfFirmwareDebugger ();
2093 DEBUG ((DEBUG_INFO
, "MeasureLaunchOfFirmwareDebugger - %r\n", Status
));
2096 Status
= MeasureAllSecureVariables ();
2097 DEBUG ((DEBUG_INFO
, "MeasureAllSecureVariables - %r\n", Status
));
2100 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
2101 // and ImageVerification (Authority)
2102 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
2103 // the Authority measurement happen before ReadToBoot event.
2105 Status
= MeasureSeparatorEvent (MapPcrToMrIndex (7));
2106 DEBUG ((DEBUG_INFO
, "MeasureSeparatorEvent - %r\n", Status
));
2111 Ready to Boot Event notification handler.
2113 Sequence of OS boot events is measured in this event notification handler.
2115 @param[in] Event Event whose notification function is being invoked
2116 @param[in] Context Pointer to the notification function's context
2128 PERF_START_EX (mImageHandle
, "EventRec", "TdTcg2Dxe", 0, PERF_ID_CC_TCG2_DXE
);
2129 if (mBootAttempts
== 0) {
2131 // Measure handoff tables.
2133 Status
= MeasureHandoffTables ();
2134 if (EFI_ERROR (Status
)) {
2135 DEBUG ((DEBUG_ERROR
, "HOBs not Measured. Error!\n"));
2139 // Measure BootOrder & Boot#### variables.
2141 Status
= MeasureAllBootVariables ();
2142 if (EFI_ERROR (Status
)) {
2143 DEBUG ((DEBUG_ERROR
, "Boot Variables not Measured. Error!\n"));
2147 // 1. This is the first boot attempt.
2149 Status
= TdMeasureAction (
2150 MapPcrToMrIndex (4),
2151 EFI_CALLING_EFI_APPLICATION
2153 if (EFI_ERROR (Status
)) {
2154 DEBUG ((DEBUG_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
2158 // 2. Draw a line between pre-boot env and entering post-boot env.
2159 // PCR[7] (is RTMR[0]) is already done.
2161 Status
= MeasureSeparatorEvent (1);
2162 if (EFI_ERROR (Status
)) {
2163 DEBUG ((DEBUG_ERROR
, "Separator Event not Measured. Error!\n"));
2167 // 3. Measure GPT. It would be done in SAP driver.
2171 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
2175 // 5. Read & Measure variable. BootOrder already measured.
2179 // 6. Not first attempt, meaning a return from last attempt
2181 Status
= TdMeasureAction (
2182 MapPcrToMrIndex (4),
2183 EFI_RETURNING_FROM_EFI_APPLICATION
2185 if (EFI_ERROR (Status
)) {
2186 DEBUG ((DEBUG_ERROR
, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION
));
2190 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
2191 // TCG PC Client PFP spec Section 2.4.4.5 Step 4
2193 Status
= TdMeasureAction (
2194 MapPcrToMrIndex (4),
2195 EFI_CALLING_EFI_APPLICATION
2197 if (EFI_ERROR (Status
)) {
2198 DEBUG ((DEBUG_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
2202 DEBUG ((DEBUG_INFO
, "TdTcg2Dxe Measure Data when ReadyToBoot\n"));
2204 // Increase boot attempt counter.
2207 PERF_END_EX (mImageHandle
, "EventRec", "Tcg2Dxe", 0, PERF_ID_CC_TCG2_DXE
+ 1);
2211 Exit Boot Services Event notification handler.
2213 Measure invocation and success of ExitBootServices.
2215 @param[in] Event Event whose notification function is being invoked
2216 @param[in] Context Pointer to the notification function's context
2221 OnExitBootServices (
2229 // Measure invocation of ExitBootServices,
2231 Status
= TdMeasureAction (
2232 MapPcrToMrIndex (5),
2233 EFI_EXIT_BOOT_SERVICES_INVOCATION
2235 if (EFI_ERROR (Status
)) {
2236 DEBUG ((DEBUG_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION
));
2240 // Measure success of ExitBootServices
2242 Status
= TdMeasureAction (
2243 MapPcrToMrIndex (5),
2244 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
2246 if (EFI_ERROR (Status
)) {
2247 DEBUG ((DEBUG_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED
));
2252 Exit Boot Services Failed Event notification handler.
2254 Measure Failure of ExitBootServices.
2256 @param[in] Event Event whose notification function is being invoked
2257 @param[in] Context Pointer to the notification function's context
2262 OnExitBootServicesFailed (
2270 // Measure Failure of ExitBootServices,
2272 Status
= TdMeasureAction (
2273 MapPcrToMrIndex (5),
2274 EFI_EXIT_BOOT_SERVICES_FAILED
2276 if (EFI_ERROR (Status
)) {
2277 DEBUG ((DEBUG_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED
));
2287 EFI_PEI_HOB_POINTERS GuidHob
;
2289 VOID
*DigestListBin
;
2290 UINT32 DigestListBinSize
;
2293 EFI_CC_EVENT_LOG_FORMAT LogFormat
;
2295 DEBUG ((DEBUG_INFO
, "Sync Cc event from SEC\n"));
2297 Status
= EFI_SUCCESS
;
2298 LogFormat
= EFI_CC_EVENT_LOG_FORMAT_TCG_2
;
2299 GuidHob
.Guid
= GetFirstGuidHob (&gCcEventEntryHobGuid
);
2301 while (!EFI_ERROR (Status
) && GuidHob
.Guid
!= NULL
) {
2302 CcEvent
= AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob
.Guid
), GET_GUID_HOB_DATA (GuidHob
.Guid
));
2303 if (CcEvent
== NULL
) {
2304 return EFI_OUT_OF_RESOURCES
;
2307 GuidHob
.Guid
= GET_NEXT_HOB (GuidHob
);
2308 GuidHob
.Guid
= GetNextGuidHob (&gCcEventEntryHobGuid
, GuidHob
.Guid
);
2310 DigestListBin
= (UINT8
*)CcEvent
+ sizeof (UINT32
) + sizeof (TCG_EVENTTYPE
);
2311 DigestListBinSize
= GetDigestListBinSize (DigestListBin
);
2316 EventSize
= *(UINT32
*)((UINT8
*)DigestListBin
+ DigestListBinSize
);
2317 Event
= (UINT8
*)DigestListBin
+ DigestListBinSize
+ sizeof (UINT32
);
2322 Status
= TdxDxeLogEvent (
2325 sizeof (UINT32
) + sizeof (TCG_EVENTTYPE
) + DigestListBinSize
+ sizeof (UINT32
),
2330 DumpCcEvent ((CC_EVENT
*)CcEvent
);
2338 Install TDVF ACPI Table when ACPI Table Protocol is available.
2340 @param[in] Event Event whose notification function is being invoked
2341 @param[in] Context Pointer to the notification function's context
2352 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
2355 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
2356 if (EFI_ERROR (Status
)) {
2357 DEBUG ((DEBUG_ERROR
, "TD: AcpiTableProtocol is not installed. %r\n", Status
));
2361 mTdxEventlogAcpiTemplate
.Laml
= (UINT64
)PcdGet32 (PcdCcEventlogAcpiTableLaml
);
2362 mTdxEventlogAcpiTemplate
.Lasa
= PcdGet64 (PcdCcEventlogAcpiTableLasa
);
2363 CopyMem (mTdxEventlogAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTdxEventlogAcpiTemplate
.Header
.OemId
));
2364 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
2365 CopyMem (&mTdxEventlogAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
2366 mTdxEventlogAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
2367 mTdxEventlogAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
2368 mTdxEventlogAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
2371 // Construct ACPI Table
2372 Status
= AcpiTable
->InstallAcpiTable (
2374 &mTdxEventlogAcpiTemplate
,
2375 mTdxEventlogAcpiTemplate
.Header
.Length
,
2378 ASSERT_EFI_ERROR (Status
);
2380 DEBUG ((DEBUG_INFO
, "TDVF Eventlog ACPI Table is installed.\n"));
2384 The function install TdTcg2 protocol.
2386 @retval EFI_SUCCESS TdTcg2 protocol is installed.
2387 @retval other Some error occurs.
2390 InstallCcMeasurementProtocol (
2398 Status
= gBS
->InstallMultipleProtocolInterfaces (
2400 &gEfiCcMeasurementProtocolGuid
,
2404 DEBUG ((DEBUG_INFO
, "CcProtocol: Install %r\n", Status
));
2409 The driver's entry point. It publishes EFI Tcg2 Protocol.
2411 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2412 @param[in] SystemTable A pointer to the EFI System Table.
2414 @retval EFI_SUCCESS The entry point is executed successfully.
2415 @retval other Some error occurs when executing this entry point.
2420 IN EFI_HANDLE ImageHandle
,
2421 IN EFI_SYSTEM_TABLE
*SystemTable
2428 if (!TdIsEnabled ()) {
2429 return EFI_UNSUPPORTED
;
2432 mImageHandle
= ImageHandle
;
2437 // ASSERT (TD_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTEventInfo)/sizeof(mTcg2EventInfo[0]));
2439 mTdxDxeData
.BsCap
.Size
= sizeof (EFI_CC_BOOT_SERVICE_CAPABILITY
);
2440 mTdxDxeData
.BsCap
.ProtocolVersion
.Major
= 1;
2441 mTdxDxeData
.BsCap
.ProtocolVersion
.Minor
= 0;
2442 mTdxDxeData
.BsCap
.StructureVersion
.Major
= 1;
2443 mTdxDxeData
.BsCap
.StructureVersion
.Minor
= 0;
2446 // Get supported PCR and current Active PCRs
2447 // For TD gueset HA384 is supported.
2449 mTdxDxeData
.BsCap
.HashAlgorithmBitmap
= HASH_ALG_SHA384
;
2451 // TD guest only supports EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
2452 mTdxDxeData
.BsCap
.SupportedEventLogs
= EFI_CC_EVENT_LOG_FORMAT_TCG_2
;
2455 // Setup the log area and copy event log from hob list to it
2457 Status
= SetupCcEventLog ();
2458 ASSERT_EFI_ERROR (Status
);
2460 if (!EFI_ERROR (Status
)) {
2461 Status
= SyncCcEvent ();
2462 ASSERT_EFI_ERROR (Status
);
2466 // Measure handoff tables, Boot#### variables etc.
2468 Status
= EfiCreateEventReadyToBootEx (
2475 Status
= gBS
->CreateEventEx (
2480 &gEfiEventExitBootServicesGuid
,
2485 // Measure Exit Boot Service failed
2487 Status
= gBS
->CreateEventEx (
2490 OnExitBootServicesFailed
,
2492 &gEventExitBootServicesFailedGuid
,
2497 // Create event callback, because we need access variable on SecureBootPolicyVariable
2498 // We should use VariableWriteArch instead of VariableArch, because Variable driver
2499 // may update SecureBoot value based on last setting.
2501 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid
, TPL_CALLBACK
, MeasureSecureBootPolicy
, NULL
, &Registration
);
2504 // Install CcMeasurementProtocol
2506 Status
= InstallCcMeasurementProtocol ();
2507 DEBUG ((DEBUG_INFO
, "InstallCcMeasurementProtocol - %r\n", Status
));
2509 if (Status
== EFI_SUCCESS
) {
2511 // Create event callback to install CC EventLog ACPI Table
2512 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid
, TPL_CALLBACK
, InstallAcpiTable
, NULL
, &Registration
);