2 This module implements Tcg2 Protocol.
4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <IndustryStandard/Acpi.h>
18 #include <IndustryStandard/PeImage.h>
19 #include <IndustryStandard/TcpaAcpi.h>
21 #include <Guid/GlobalVariable.h>
22 #include <Guid/HobList.h>
23 #include <Guid/TcgEventHob.h>
24 #include <Guid/EventGroup.h>
25 #include <Guid/EventExitBootServiceFailed.h>
26 #include <Guid/ImageAuthentication.h>
27 #include <Guid/TpmInstance.h>
29 #include <Protocol/DevicePath.h>
30 #include <Protocol/MpService.h>
31 #include <Protocol/VariableWrite.h>
32 #include <Protocol/Tcg2Protocol.h>
33 #include <Protocol/TrEEProtocol.h>
35 #include <Library/DebugLib.h>
36 #include <Library/BaseMemoryLib.h>
37 #include <Library/UefiRuntimeServicesTableLib.h>
38 #include <Library/UefiDriverEntryPoint.h>
39 #include <Library/HobLib.h>
40 #include <Library/UefiBootServicesTableLib.h>
41 #include <Library/BaseLib.h>
42 #include <Library/MemoryAllocationLib.h>
43 #include <Library/PrintLib.h>
44 #include <Library/Tpm2CommandLib.h>
45 #include <Library/PcdLib.h>
46 #include <Library/UefiLib.h>
47 #include <Library/Tpm2DeviceLib.h>
48 #include <Library/HashLib.h>
49 #include <Library/PerformanceLib.h>
50 #include <Library/ReportStatusCodeLib.h>
51 #include <Library/Tcg2PhysicalPresenceLib.h>
53 #define PERF_ID_TCG2_DXE 0x3120
60 #define TCG2_DEFAULT_MAX_COMMAND_SIZE 0x1000
61 #define TCG2_DEFAULT_MAX_RESPONSE_SIZE 0x1000
65 EFI_TCG2_EVENT_LOG_FORMAT LogFormat
;
66 } TCG2_EVENT_INFO_STRUCT
;
68 TCG2_EVENT_INFO_STRUCT mTcg2EventInfo
[] = {
69 {&gTcgEventEntryHobGuid
, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
},
70 {&gTcgEvent2EntryHobGuid
, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
},
73 #define TCG_EVENT_LOG_AREA_COUNT_MAX 2
76 EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
;
77 EFI_PHYSICAL_ADDRESS Lasa
;
81 BOOLEAN EventLogStarted
;
82 BOOLEAN EventLogTruncated
;
83 } TCG_EVENT_LOG_AREA_STRUCT
;
85 typedef struct _TCG_DXE_DATA
{
86 EFI_TCG2_BOOT_SERVICE_CAPABILITY BsCap
;
87 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
88 BOOLEAN GetEventLogCalled
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
89 TCG_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
90 EFI_TCG2_FINAL_EVENTS_TABLE
*FinalEventsTable
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
93 TCG_DXE_DATA mTcgDxeData
= {
95 sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY
), // Size
96 { 1, 1 }, // StructureVersion
97 { 1, 1 }, // ProtocolVersion
98 EFI_TCG2_BOOT_HASH_ALG_SHA1
, // HashAlgorithmBitmap
99 EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
, // SupportedEventLogs
100 TRUE
, // TPMPresentFlag
101 TCG2_DEFAULT_MAX_COMMAND_SIZE
, // MaxCommandSize
102 TCG2_DEFAULT_MAX_RESPONSE_SIZE
, // MaxResponseSize
104 0, // NumberOfPCRBanks
109 UINTN mBootAttempts
= 0;
110 CHAR16 mBootVarName
[] = L
"BootOrder";
112 VARIABLE_TYPE mVariableType
[] = {
113 {EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
},
114 {EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
},
115 {EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
},
116 {EFI_IMAGE_SECURITY_DATABASE
, &gEfiImageSecurityDatabaseGuid
},
117 {EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
},
120 EFI_HANDLE mImageHandle
;
123 Measure PE image into TPM log based on the authenticode image hashing in
124 PE/COFF Specification 8.0 Appendix A.
126 Caution: This function may receive untrusted input.
127 PE/COFF image is external input, so this function will validate its data structure
128 within this image buffer before use.
130 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
132 @param[in] PCRIndex TPM PCR index
133 @param[in] ImageAddress Start address of image buffer.
134 @param[in] ImageSize Image size
135 @param[out] DigestList Digeest list of this image.
137 @retval EFI_SUCCESS Successfully measure image.
138 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
139 @retval other error value
142 MeasurePeImageAndExtend (
144 IN EFI_PHYSICAL_ADDRESS ImageAddress
,
146 OUT TPML_DIGEST_VALUES
*DigestList
151 This function dump raw data.
154 @param Size raw data size
164 for (Index
= 0; Index
< Size
; Index
++) {
165 DEBUG ((EFI_D_INFO
, "%02x", (UINTN
)Data
[Index
]));
171 This function dump raw data with colume format.
174 @param Size raw data size
187 #define COLUME_SIZE (16 * 2)
189 Count
= Size
/ COLUME_SIZE
;
190 Left
= Size
% COLUME_SIZE
;
191 for (Index
= 0; Index
< Count
; Index
++) {
192 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
193 InternalDumpData (Data
+ Index
* COLUME_SIZE
, COLUME_SIZE
);
194 DEBUG ((EFI_D_INFO
, "\n"));
198 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
199 InternalDumpData (Data
+ Index
* COLUME_SIZE
, Left
);
200 DEBUG ((EFI_D_INFO
, "\n"));
205 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
206 Caller is responsible to free LocationBuf.
208 @param[out] LocationBuf Returns Processor Location Buffer.
209 @param[out] Num Returns processor number.
211 @retval EFI_SUCCESS Operation completed successfully.
212 @retval EFI_UNSUPPORTED MpService protocol not found.
216 GetProcessorsCpuLocation (
217 OUT EFI_CPU_PHYSICAL_LOCATION
**LocationBuf
,
222 EFI_MP_SERVICES_PROTOCOL
*MpProtocol
;
224 UINTN EnabledProcessorNum
;
225 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
226 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
229 Status
= gBS
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**) &MpProtocol
);
230 if (EFI_ERROR (Status
)) {
232 // MP protocol is not installed
234 return EFI_UNSUPPORTED
;
237 Status
= MpProtocol
->GetNumberOfProcessors(
242 if (EFI_ERROR(Status
)){
246 Status
= gBS
->AllocatePool(
248 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
249 (VOID
**) &ProcessorLocBuf
251 if (EFI_ERROR(Status
)){
256 // Get each processor Location info
258 for (Index
= 0; Index
< ProcessorNum
; Index
++) {
259 Status
= MpProtocol
->GetProcessorInfo(
264 if (EFI_ERROR(Status
)){
265 FreePool(ProcessorLocBuf
);
270 // Get all Processor Location info & measure
273 &ProcessorLocBuf
[Index
],
274 &ProcessorInfo
.Location
,
275 sizeof(EFI_CPU_PHYSICAL_LOCATION
)
279 *LocationBuf
= ProcessorLocBuf
;
286 The EFI_TCG2_PROTOCOL GetCapability function call provides protocol
287 capability information and state information.
289 @param[in] This Indicates the calling context
290 @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY
291 structure and sets the size field to the size of the structure allocated.
292 The callee fills in the fields with the EFI protocol capability information
293 and the current EFI TCG2 state information up to the number of fields which
294 fit within the size of the structure passed in.
296 @retval EFI_SUCCESS Operation completed successfully.
297 @retval EFI_DEVICE_ERROR The command was unsuccessful.
298 The ProtocolCapability variable will not be populated.
299 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
300 The ProtocolCapability variable will not be populated.
301 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
302 It will be partially populated (required Size field will be set).
307 IN EFI_TCG2_PROTOCOL
*This
,
308 IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
311 DEBUG ((DEBUG_VERBOSE
, "Tcg2GetCapability ...\n"));
313 if ((This
== NULL
) || (ProtocolCapability
== NULL
)) {
314 return EFI_INVALID_PARAMETER
;
317 DEBUG ((DEBUG_VERBOSE
, "Size - 0x%x\n", ProtocolCapability
->Size
));
318 DEBUG ((DEBUG_VERBOSE
, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY
), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0
)));
320 if (ProtocolCapability
->Size
< mTcgDxeData
.BsCap
.Size
) {
322 // Handle the case that firmware support 1.1 but OS only support 1.0.
324 if ((mTcgDxeData
.BsCap
.ProtocolVersion
.Major
> 0x01) ||
325 ((mTcgDxeData
.BsCap
.ProtocolVersion
.Major
== 0x01) && ((mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
> 0x00)))) {
326 if (ProtocolCapability
->Size
>= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0
)) {
327 CopyMem (ProtocolCapability
, &mTcgDxeData
.BsCap
, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0
));
328 ProtocolCapability
->Size
= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0
);
329 ProtocolCapability
->StructureVersion
.Major
= 1;
330 ProtocolCapability
->StructureVersion
.Minor
= 0;
331 ProtocolCapability
->ProtocolVersion
.Major
= 1;
332 ProtocolCapability
->ProtocolVersion
.Minor
= 0;
333 DEBUG ((EFI_D_ERROR
, "TreeGetCapability (Compatible) - %r\n", EFI_SUCCESS
));
337 ProtocolCapability
->Size
= mTcgDxeData
.BsCap
.Size
;
338 return EFI_BUFFER_TOO_SMALL
;
341 CopyMem (ProtocolCapability
, &mTcgDxeData
.BsCap
, mTcgDxeData
.BsCap
.Size
);
342 DEBUG ((DEBUG_VERBOSE
, "Tcg2GetCapability - %r\n", EFI_SUCCESS
));
347 This function dump PCR event.
349 @param[in] EventHdr TCG PCR event structure.
353 IN TCG_PCR_EVENT_HDR
*EventHdr
358 DEBUG ((EFI_D_INFO
, " Event:\n"));
359 DEBUG ((EFI_D_INFO
, " PCRIndex - %d\n", EventHdr
->PCRIndex
));
360 DEBUG ((EFI_D_INFO
, " EventType - 0x%08x\n", EventHdr
->EventType
));
361 DEBUG ((EFI_D_INFO
, " Digest - "));
362 for (Index
= 0; Index
< sizeof(TCG_DIGEST
); Index
++) {
363 DEBUG ((EFI_D_INFO
, "%02x ", EventHdr
->Digest
.digest
[Index
]));
365 DEBUG ((EFI_D_INFO
, "\n"));
366 DEBUG ((EFI_D_INFO
, " EventSize - 0x%08x\n", EventHdr
->EventSize
));
367 InternalDumpHex ((UINT8
*)(EventHdr
+ 1), EventHdr
->EventSize
);
371 This function dump TCG_EfiSpecIDEventStruct.
373 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
376 DumpTcgEfiSpecIdEventStruct (
377 IN TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
380 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
382 UINT8
*VendorInfoSize
;
384 UINT32 NumberOfAlgorithms
;
386 DEBUG ((EFI_D_INFO
, " TCG_EfiSpecIDEventStruct:\n"));
387 DEBUG ((EFI_D_INFO
, " signature - '"));
388 for (Index
= 0; Index
< sizeof(TcgEfiSpecIdEventStruct
->signature
); Index
++) {
389 DEBUG ((EFI_D_INFO
, "%c", TcgEfiSpecIdEventStruct
->signature
[Index
]));
391 DEBUG ((EFI_D_INFO
, "'\n"));
392 DEBUG ((EFI_D_INFO
, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct
->platformClass
));
393 DEBUG ((EFI_D_INFO
, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct
->specVersionMajor
, TcgEfiSpecIdEventStruct
->specVersionMinor
, TcgEfiSpecIdEventStruct
->specErrata
));
394 DEBUG ((EFI_D_INFO
, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct
->uintnSize
));
396 CopyMem (&NumberOfAlgorithms
, TcgEfiSpecIdEventStruct
+ 1, sizeof(NumberOfAlgorithms
));
397 DEBUG ((EFI_D_INFO
, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms
));
399 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof(*TcgEfiSpecIdEventStruct
) + sizeof(NumberOfAlgorithms
));
400 for (Index
= 0; Index
< NumberOfAlgorithms
; Index
++) {
401 DEBUG ((EFI_D_INFO
, " digest(%d)\n", Index
));
402 DEBUG ((EFI_D_INFO
, " algorithmId - 0x%04x\n", DigestSize
[Index
].algorithmId
));
403 DEBUG ((EFI_D_INFO
, " digestSize - 0x%04x\n", DigestSize
[Index
].digestSize
));
405 VendorInfoSize
= (UINT8
*)&DigestSize
[NumberOfAlgorithms
];
406 DEBUG ((EFI_D_INFO
, " VendorInfoSize - 0x%02x\n", *VendorInfoSize
));
407 VendorInfo
= VendorInfoSize
+ 1;
408 DEBUG ((EFI_D_INFO
, " VendorInfo - "));
409 for (Index
= 0; Index
< *VendorInfoSize
; Index
++) {
410 DEBUG ((EFI_D_INFO
, "%02x ", VendorInfo
[Index
]));
412 DEBUG ((EFI_D_INFO
, "\n"));
416 This function get size of TCG_EfiSpecIDEventStruct.
418 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
421 GetTcgEfiSpecIdEventStructSize (
422 IN TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
425 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
426 UINT8
*VendorInfoSize
;
427 UINT32 NumberOfAlgorithms
;
429 CopyMem (&NumberOfAlgorithms
, TcgEfiSpecIdEventStruct
+ 1, sizeof(NumberOfAlgorithms
));
431 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof(*TcgEfiSpecIdEventStruct
) + sizeof(NumberOfAlgorithms
));
432 VendorInfoSize
= (UINT8
*)&DigestSize
[NumberOfAlgorithms
];
433 return sizeof(TCG_EfiSpecIDEventStruct
) + sizeof(UINT32
) + (NumberOfAlgorithms
* sizeof(TCG_EfiSpecIdEventAlgorithmSize
)) + sizeof(UINT8
) + (*VendorInfoSize
);
437 This function dump PCR event 2.
439 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.
443 IN TCG_PCR_EVENT2
*TcgPcrEvent2
449 TPMI_ALG_HASH HashAlgo
;
455 DEBUG ((EFI_D_INFO
, " Event:\n"));
456 DEBUG ((EFI_D_INFO
, " PCRIndex - %d\n", TcgPcrEvent2
->PCRIndex
));
457 DEBUG ((EFI_D_INFO
, " EventType - 0x%08x\n", TcgPcrEvent2
->EventType
));
459 DEBUG ((EFI_D_INFO
, " DigestCount: 0x%08x\n", TcgPcrEvent2
->Digest
.count
));
461 DigestCount
= TcgPcrEvent2
->Digest
.count
;
462 HashAlgo
= TcgPcrEvent2
->Digest
.digests
[0].hashAlg
;
463 DigestBuffer
= (UINT8
*)&TcgPcrEvent2
->Digest
.digests
[0].digest
;
464 for (DigestIndex
= 0; DigestIndex
< DigestCount
; DigestIndex
++) {
465 DEBUG ((EFI_D_INFO
, " HashAlgo : 0x%04x\n", HashAlgo
));
466 DEBUG ((EFI_D_INFO
, " Digest(%d): ", DigestIndex
));
467 DigestSize
= GetHashSizeFromAlgo (HashAlgo
);
468 for (Index
= 0; Index
< DigestSize
; Index
++) {
469 DEBUG ((EFI_D_INFO
, "%02x ", DigestBuffer
[Index
]));
471 DEBUG ((EFI_D_INFO
, "\n"));
475 CopyMem (&HashAlgo
, DigestBuffer
+ DigestSize
, sizeof(TPMI_ALG_HASH
));
476 DigestBuffer
= DigestBuffer
+ DigestSize
+ sizeof(TPMI_ALG_HASH
);
478 DEBUG ((EFI_D_INFO
, "\n"));
479 DigestBuffer
= DigestBuffer
- sizeof(TPMI_ALG_HASH
);
481 CopyMem (&EventSize
, DigestBuffer
, sizeof(TcgPcrEvent2
->EventSize
));
482 DEBUG ((EFI_D_INFO
, " EventSize - 0x%08x\n", EventSize
));
483 EventBuffer
= DigestBuffer
+ sizeof(TcgPcrEvent2
->EventSize
);
484 InternalDumpHex (EventBuffer
, EventSize
);
488 This function returns size of TCG PCR event 2.
490 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.
492 @return size of TCG PCR event 2.
496 IN TCG_PCR_EVENT2
*TcgPcrEvent2
501 TPMI_ALG_HASH HashAlgo
;
507 DigestCount
= TcgPcrEvent2
->Digest
.count
;
508 HashAlgo
= TcgPcrEvent2
->Digest
.digests
[0].hashAlg
;
509 DigestBuffer
= (UINT8
*)&TcgPcrEvent2
->Digest
.digests
[0].digest
;
510 for (DigestIndex
= 0; DigestIndex
< DigestCount
; DigestIndex
++) {
511 DigestSize
= GetHashSizeFromAlgo (HashAlgo
);
515 CopyMem (&HashAlgo
, DigestBuffer
+ DigestSize
, sizeof(TPMI_ALG_HASH
));
516 DigestBuffer
= DigestBuffer
+ DigestSize
+ sizeof(TPMI_ALG_HASH
);
518 DigestBuffer
= DigestBuffer
- sizeof(TPMI_ALG_HASH
);
520 CopyMem (&EventSize
, DigestBuffer
, sizeof(TcgPcrEvent2
->EventSize
));
521 EventBuffer
= DigestBuffer
+ sizeof(TcgPcrEvent2
->EventSize
);
523 return (UINTN
)EventBuffer
+ EventSize
- (UINTN
)TcgPcrEvent2
;
527 This function dump event log.
529 @param[in] EventLogFormat The type of the event log for which the information is requested.
530 @param[in] EventLogLocation A pointer to the memory address of the event log.
531 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
532 address of the start of the last entry in the event log in memory.
533 @param[in] FinalEventsTable A pointer to the memory address of the final event table.
537 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
,
538 IN EFI_PHYSICAL_ADDRESS EventLogLocation
,
539 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry
,
540 IN EFI_TCG2_FINAL_EVENTS_TABLE
*FinalEventsTable
543 TCG_PCR_EVENT_HDR
*EventHdr
;
544 TCG_PCR_EVENT2
*TcgPcrEvent2
;
545 TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
;
546 UINTN NumberOfEvents
;
548 DEBUG ((EFI_D_INFO
, "EventLogFormat: (0x%x)\n", EventLogFormat
));
550 switch (EventLogFormat
) {
551 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
:
552 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)EventLogLocation
;
553 while ((UINTN
)EventHdr
<= EventLogLastEntry
) {
554 DumpEvent (EventHdr
);
555 EventHdr
= (TCG_PCR_EVENT_HDR
*)((UINTN
)EventHdr
+ sizeof(TCG_PCR_EVENT_HDR
) + EventHdr
->EventSize
);
557 if (FinalEventsTable
== NULL
) {
558 DEBUG ((EFI_D_INFO
, "FinalEventsTable: NOT FOUND\n"));
560 DEBUG ((EFI_D_INFO
, "FinalEventsTable: (0x%x)\n", FinalEventsTable
));
561 DEBUG ((EFI_D_INFO
, " Version: (0x%x)\n", FinalEventsTable
->Version
));
562 DEBUG ((EFI_D_INFO
, " NumberOfEvents: (0x%x)\n", FinalEventsTable
->NumberOfEvents
));
564 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)(FinalEventsTable
+ 1);
565 for (NumberOfEvents
= 0; NumberOfEvents
< FinalEventsTable
->NumberOfEvents
; NumberOfEvents
++) {
566 DumpEvent (EventHdr
);
567 EventHdr
= (TCG_PCR_EVENT_HDR
*)((UINTN
)EventHdr
+ sizeof(TCG_PCR_EVENT_HDR
) + EventHdr
->EventSize
);
571 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
:
575 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)EventLogLocation
;
576 DumpEvent (EventHdr
);
578 TcgEfiSpecIdEventStruct
= (TCG_EfiSpecIDEventStruct
*)(EventHdr
+ 1);
579 DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct
);
581 TcgPcrEvent2
= (TCG_PCR_EVENT2
*)((UINTN
)TcgEfiSpecIdEventStruct
+ GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct
));
582 while ((UINTN
)TcgPcrEvent2
<= EventLogLastEntry
) {
583 DumpEvent2 (TcgPcrEvent2
);
584 TcgPcrEvent2
= (TCG_PCR_EVENT2
*)((UINTN
)TcgPcrEvent2
+ GetPcrEvent2Size (TcgPcrEvent2
));
587 if (FinalEventsTable
== NULL
) {
588 DEBUG ((EFI_D_INFO
, "FinalEventsTable: NOT FOUND\n"));
590 DEBUG ((EFI_D_INFO
, "FinalEventsTable: (0x%x)\n", FinalEventsTable
));
591 DEBUG ((EFI_D_INFO
, " Version: (0x%x)\n", FinalEventsTable
->Version
));
592 DEBUG ((EFI_D_INFO
, " NumberOfEvents: (0x%x)\n", FinalEventsTable
->NumberOfEvents
));
594 TcgPcrEvent2
= (TCG_PCR_EVENT2
*)(UINTN
)(FinalEventsTable
+ 1);
595 for (NumberOfEvents
= 0; NumberOfEvents
< FinalEventsTable
->NumberOfEvents
; NumberOfEvents
++) {
596 DumpEvent2 (TcgPcrEvent2
);
597 TcgPcrEvent2
= (TCG_PCR_EVENT2
*)((UINTN
)TcgPcrEvent2
+ GetPcrEvent2Size (TcgPcrEvent2
));
607 The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to
608 retrieve the address of a given event log and its last entry.
610 @param[in] This Indicates the calling context
611 @param[in] EventLogFormat The type of the event log for which the information is requested.
612 @param[out] EventLogLocation A pointer to the memory address of the event log.
613 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
614 address of the start of the last entry in the event log in memory.
615 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
616 have exceeded the area allocated for events, this value is set to TRUE.
617 Otherwise, the value will be FALSE and the Event Log will be complete.
619 @retval EFI_SUCCESS Operation completed successfully.
620 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
621 (e.g. asking for an event log whose format is not supported).
626 IN EFI_TCG2_PROTOCOL
*This
,
627 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
,
628 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
629 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
,
630 OUT BOOLEAN
*EventLogTruncated
635 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog ... (0x%x)\n", EventLogFormat
));
638 return EFI_INVALID_PARAMETER
;
641 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
642 if (EventLogFormat
== mTcg2EventInfo
[Index
].LogFormat
) {
647 if (Index
== sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0])) {
648 return EFI_INVALID_PARAMETER
;
651 if ((mTcg2EventInfo
[Index
].LogFormat
& mTcgDxeData
.BsCap
.SupportedEventLogs
) == 0) {
652 return EFI_INVALID_PARAMETER
;
655 if (!mTcgDxeData
.BsCap
.TPMPresentFlag
) {
656 if (EventLogLocation
!= NULL
) {
657 *EventLogLocation
= 0;
659 if (EventLogLastEntry
!= NULL
) {
660 *EventLogLastEntry
= 0;
662 if (EventLogTruncated
!= NULL
) {
663 *EventLogTruncated
= FALSE
;
668 if (EventLogLocation
!= NULL
) {
669 *EventLogLocation
= mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
;
670 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog (EventLogLocation - %x)\n", *EventLogLocation
));
673 if (EventLogLastEntry
!= NULL
) {
674 if (!mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
) {
675 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
677 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
;
679 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry
));
682 if (EventLogTruncated
!= NULL
) {
683 *EventLogTruncated
= mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
;
684 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated
));
687 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog - %r\n", EFI_SUCCESS
));
689 // Dump Event Log for debug purpose
690 if ((EventLogLocation
!= NULL
) && (EventLogLastEntry
!= NULL
)) {
691 DumpEventLog (EventLogFormat
, *EventLogLocation
, *EventLogLastEntry
, mTcgDxeData
.FinalEventsTable
[Index
]);
695 // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored
696 // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.
698 mTcgDxeData
.GetEventLogCalled
[Index
] = TRUE
;
704 Add a new entry to the Event Log.
706 @param[in, out] EventLogPtr Pointer to the Event Log data.
707 @param[in, out] LogSize Size of the Event Log.
708 @param[in] MaxSize Maximum size of the Event Log.
709 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
710 @param[in] NewEventHdrSize New event header size.
711 @param[in] NewEventData Pointer to the new event data.
712 @param[in] NewEventSize New event data size.
714 @retval EFI_SUCCESS The new event log entry was added.
715 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
720 IN OUT UINT8
**EventLogPtr
,
721 IN OUT UINTN
*LogSize
,
723 IN VOID
*NewEventHdr
,
724 IN UINT32 NewEventHdrSize
,
725 IN UINT8
*NewEventData
,
726 IN UINT32 NewEventSize
731 if (NewEventSize
> MAX_ADDRESS
- NewEventHdrSize
) {
732 return EFI_OUT_OF_RESOURCES
;
735 NewLogSize
= NewEventHdrSize
+ NewEventSize
;
737 if (NewLogSize
> MAX_ADDRESS
- *LogSize
) {
738 return EFI_OUT_OF_RESOURCES
;
741 if (NewLogSize
+ *LogSize
> MaxSize
) {
742 DEBUG ((EFI_D_INFO
, " MaxSize - 0x%x\n", MaxSize
));
743 DEBUG ((EFI_D_INFO
, " NewLogSize - 0x%x\n", NewLogSize
));
744 DEBUG ((EFI_D_INFO
, " LogSize - 0x%x\n", *LogSize
));
745 DEBUG ((EFI_D_INFO
, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES
));
746 return EFI_OUT_OF_RESOURCES
;
749 *EventLogPtr
+= *LogSize
;
750 *LogSize
+= NewLogSize
;
751 CopyMem (*EventLogPtr
, NewEventHdr
, NewEventHdrSize
);
753 *EventLogPtr
+ NewEventHdrSize
,
761 Add a new entry to the Event Log.
763 @param[in] EventLogFormat The type of the event log for which the information is requested.
764 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
765 @param[in] NewEventHdrSize New event header size.
766 @param[in] NewEventData Pointer to the new event data.
767 @param[in] NewEventSize New event data size.
769 @retval EFI_SUCCESS The new event log entry was added.
770 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
775 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
,
776 IN VOID
*NewEventHdr
,
777 IN UINT32 NewEventHdrSize
,
778 IN UINT8
*NewEventData
,
779 IN UINT32 NewEventSize
784 TCG_EVENT_LOG_AREA_STRUCT
*EventLogAreaStruct
;
786 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
787 if (EventLogFormat
== mTcg2EventInfo
[Index
].LogFormat
) {
792 if (Index
== sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0])) {
793 return EFI_INVALID_PARAMETER
;
797 // Record to normal event log
799 EventLogAreaStruct
= &mTcgDxeData
.EventLogAreaStruct
[Index
];
801 if (EventLogAreaStruct
->EventLogTruncated
) {
802 return EFI_VOLUME_FULL
;
805 EventLogAreaStruct
->LastEvent
= (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
;
806 Status
= TcgCommLogEvent (
807 &EventLogAreaStruct
->LastEvent
,
808 &EventLogAreaStruct
->EventLogSize
,
809 (UINTN
)EventLogAreaStruct
->Laml
,
816 if (Status
== EFI_OUT_OF_RESOURCES
) {
817 EventLogAreaStruct
->EventLogTruncated
= TRUE
;
818 return EFI_VOLUME_FULL
;
819 } else if (Status
== EFI_SUCCESS
) {
820 EventLogAreaStruct
->EventLogStarted
= TRUE
;
824 // If GetEventLog is called, record to FinalEventsTable, too.
826 if (mTcgDxeData
.GetEventLogCalled
[Index
]) {
827 if (mTcgDxeData
.FinalEventsTable
[Index
] == NULL
) {
829 // no need for FinalEventsTable
833 EventLogAreaStruct
= &mTcgDxeData
.FinalEventLogAreaStruct
[Index
];
835 if (EventLogAreaStruct
->EventLogTruncated
) {
836 return EFI_VOLUME_FULL
;
839 EventLogAreaStruct
->LastEvent
= (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
;
840 Status
= TcgCommLogEvent (
841 &EventLogAreaStruct
->LastEvent
,
842 &EventLogAreaStruct
->EventLogSize
,
843 (UINTN
)EventLogAreaStruct
->Laml
,
849 if (Status
== EFI_OUT_OF_RESOURCES
) {
850 EventLogAreaStruct
->EventLogTruncated
= TRUE
;
851 return EFI_VOLUME_FULL
;
852 } else if (Status
== EFI_SUCCESS
) {
853 EventLogAreaStruct
->EventLogStarted
= TRUE
;
855 // Increase the NumberOfEvents in FinalEventsTable
857 (mTcgDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
++;
858 DEBUG ((EFI_D_INFO
, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
));
859 DEBUG ((EFI_D_INFO
, " Size - 0x%x\n", (UINTN
)EventLogAreaStruct
->LastEvent
- (UINTN
)mTcgDxeData
.FinalEventsTable
[Index
]));
867 Get TPML_DIGEST_VALUES compact binary buffer size.
869 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
871 @return TPML_DIGEST_VALUES compact binary buffer size.
874 GetDigestListBinSize (
875 IN VOID
*DigestListBin
882 TPMI_ALG_HASH HashAlg
;
884 Count
= ReadUnaligned32 (DigestListBin
);
885 TotalSize
= sizeof(Count
);
886 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof(Count
);
887 for (Index
= 0; Index
< Count
; Index
++) {
888 HashAlg
= ReadUnaligned16 (DigestListBin
);
889 TotalSize
+= sizeof(HashAlg
);
890 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof(HashAlg
);
892 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
893 TotalSize
+= DigestSize
;
894 DigestListBin
= (UINT8
*)DigestListBin
+ DigestSize
;
901 Copy TPML_DIGEST_VALUES compact binary into a buffer
903 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
904 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
905 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
906 @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.
908 @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
911 CopyDigestListBinToBuffer (
913 IN VOID
*DigestListBin
,
914 IN UINT32 HashAlgorithmMask
,
915 OUT UINT32
*HashAlgorithmMaskCopied
921 TPMI_ALG_HASH HashAlg
;
922 UINT32 DigestListCount
;
923 UINT32
*DigestListCountPtr
;
925 DigestListCountPtr
= (UINT32
*) Buffer
;
927 (*HashAlgorithmMaskCopied
) = 0;
929 Count
= ReadUnaligned32 (DigestListBin
);
930 Buffer
= (UINT8
*)Buffer
+ sizeof(Count
);
931 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof(Count
);
932 for (Index
= 0; Index
< Count
; Index
++) {
933 HashAlg
= ReadUnaligned16 (DigestListBin
);
934 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof(HashAlg
);
935 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
937 if (IsHashAlgSupportedInHashAlgorithmMask(HashAlg
, HashAlgorithmMask
)) {
938 CopyMem (Buffer
, &HashAlg
, sizeof(HashAlg
));
939 Buffer
= (UINT8
*)Buffer
+ sizeof(HashAlg
);
940 CopyMem (Buffer
, DigestListBin
, DigestSize
);
941 Buffer
= (UINT8
*)Buffer
+ DigestSize
;
943 (*HashAlgorithmMaskCopied
) |= GetHashMaskFromAlgo (HashAlg
);
945 DEBUG ((DEBUG_ERROR
, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg
));
947 DigestListBin
= (UINT8
*)DigestListBin
+ DigestSize
;
949 WriteUnaligned32 (DigestListCountPtr
, DigestListCount
);
955 Add a new entry to the Event Log.
957 @param[in] DigestList A list of digest.
958 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
959 @param[in] NewEventData Pointer to the new event data.
961 @retval EFI_SUCCESS The new event log entry was added.
962 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
966 IN TPML_DIGEST_VALUES
*DigestList
,
967 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
968 IN UINT8
*NewEventData
974 EFI_STATUS RetStatus
;
975 TCG_PCR_EVENT2 TcgPcrEvent2
;
977 UINT32
*EventSizePtr
;
979 DEBUG ((EFI_D_INFO
, "SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
981 RetStatus
= EFI_SUCCESS
;
982 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
983 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
984 DEBUG ((EFI_D_INFO
, " LogFormat - 0x%08x\n", mTcg2EventInfo
[Index
].LogFormat
));
985 switch (mTcg2EventInfo
[Index
].LogFormat
) {
986 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
:
987 Status
= GetDigestFromDigestList (TPM_ALG_SHA1
, DigestList
, &NewEventHdr
->Digest
);
988 if (!EFI_ERROR (Status
)) {
990 // Enter critical region
992 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
993 Status
= TcgDxeLogEvent (
994 mTcg2EventInfo
[Index
].LogFormat
,
996 sizeof(TCG_PCR_EVENT_HDR
),
998 NewEventHdr
->EventSize
1000 if (Status
!= EFI_SUCCESS
) {
1003 gBS
->RestoreTPL (OldTpl
);
1005 // Exit critical region
1009 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
:
1010 ZeroMem (&TcgPcrEvent2
, sizeof(TcgPcrEvent2
));
1011 TcgPcrEvent2
.PCRIndex
= NewEventHdr
->PCRIndex
;
1012 TcgPcrEvent2
.EventType
= NewEventHdr
->EventType
;
1013 DigestBuffer
= (UINT8
*)&TcgPcrEvent2
.Digest
;
1014 EventSizePtr
= CopyDigestListToBuffer (DigestBuffer
, DigestList
, mTcgDxeData
.BsCap
.ActivePcrBanks
);
1015 CopyMem (EventSizePtr
, &NewEventHdr
->EventSize
, sizeof(NewEventHdr
->EventSize
));
1018 // Enter critical region
1020 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
1021 Status
= TcgDxeLogEvent (
1022 mTcg2EventInfo
[Index
].LogFormat
,
1024 sizeof(TcgPcrEvent2
.PCRIndex
) + sizeof(TcgPcrEvent2
.EventType
) + GetDigestListBinSize (DigestBuffer
) + sizeof(TcgPcrEvent2
.EventSize
),
1026 NewEventHdr
->EventSize
1028 if (Status
!= EFI_SUCCESS
) {
1031 gBS
->RestoreTPL (OldTpl
);
1033 // Exit critical region
1044 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
1045 and add an entry to the Event Log.
1047 @param[in] Flags Bitmap providing additional information.
1048 @param[in] HashData Physical address of the start of the data buffer
1049 to be hashed, extended, and logged.
1050 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
1051 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
1052 @param[in] NewEventData Pointer to the new event data.
1054 @retval EFI_SUCCESS Operation completed successfully.
1055 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1056 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1060 TcgDxeHashLogExtendEvent (
1063 IN UINT64 HashDataLen
,
1064 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
1065 IN UINT8
*NewEventData
1069 TPML_DIGEST_VALUES DigestList
;
1071 if (!mTcgDxeData
.BsCap
.TPMPresentFlag
) {
1072 return EFI_DEVICE_ERROR
;
1075 Status
= HashAndExtend (
1076 NewEventHdr
->PCRIndex
,
1081 if (!EFI_ERROR (Status
)) {
1082 if ((Flags
& EFI_TCG2_EXTEND_ONLY
) == 0) {
1083 Status
= TcgDxeLogHashEvent (&DigestList
, NewEventHdr
, NewEventData
);
1087 if (Status
== EFI_DEVICE_ERROR
) {
1088 DEBUG ((EFI_D_ERROR
, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status
));
1089 mTcgDxeData
.BsCap
.TPMPresentFlag
= FALSE
;
1090 REPORT_STATUS_CODE (
1091 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1092 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
1100 The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with
1101 an opportunity to extend and optionally log events without requiring
1102 knowledge of actual TPM commands.
1103 The extend operation will occur even if this function cannot create an event
1104 log entry (e.g. due to the event log being full).
1106 @param[in] This Indicates the calling context
1107 @param[in] Flags Bitmap providing additional information.
1108 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
1109 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
1110 @param[in] Event Pointer to data buffer containing information about the event.
1112 @retval EFI_SUCCESS Operation completed successfully.
1113 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1114 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
1115 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1116 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
1120 Tcg2HashLogExtendEvent (
1121 IN EFI_TCG2_PROTOCOL
*This
,
1123 IN EFI_PHYSICAL_ADDRESS DataToHash
,
1124 IN UINT64 DataToHashLen
,
1125 IN EFI_TCG2_EVENT
*Event
1129 TCG_PCR_EVENT_HDR NewEventHdr
;
1130 TPML_DIGEST_VALUES DigestList
;
1132 DEBUG ((DEBUG_VERBOSE
, "Tcg2HashLogExtendEvent ...\n"));
1134 if ((This
== NULL
) || (DataToHash
== 0) || (Event
== NULL
)) {
1135 return EFI_INVALID_PARAMETER
;
1138 if (!mTcgDxeData
.BsCap
.TPMPresentFlag
) {
1139 return EFI_DEVICE_ERROR
;
1142 if (Event
->Size
< Event
->Header
.HeaderSize
+ sizeof(UINT32
)) {
1143 return EFI_INVALID_PARAMETER
;
1146 if (Event
->Header
.PCRIndex
> MAX_PCR_INDEX
) {
1147 return EFI_INVALID_PARAMETER
;
1150 NewEventHdr
.PCRIndex
= Event
->Header
.PCRIndex
;
1151 NewEventHdr
.EventType
= Event
->Header
.EventType
;
1152 NewEventHdr
.EventSize
= Event
->Size
- sizeof(UINT32
) - Event
->Header
.HeaderSize
;
1153 if ((Flags
& PE_COFF_IMAGE
) != 0) {
1154 Status
= MeasurePeImageAndExtend (
1155 NewEventHdr
.PCRIndex
,
1157 (UINTN
)DataToHashLen
,
1160 if (!EFI_ERROR (Status
)) {
1161 if ((Flags
& EFI_TCG2_EXTEND_ONLY
) == 0) {
1162 Status
= TcgDxeLogHashEvent (&DigestList
, &NewEventHdr
, Event
->Event
);
1165 if (Status
== EFI_DEVICE_ERROR
) {
1166 DEBUG ((EFI_D_ERROR
, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status
));
1167 mTcgDxeData
.BsCap
.TPMPresentFlag
= FALSE
;
1168 REPORT_STATUS_CODE (
1169 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1170 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
1174 Status
= TcgDxeHashLogExtendEvent (
1176 (UINT8
*) (UINTN
) DataToHash
,
1182 DEBUG ((DEBUG_VERBOSE
, "Tcg2HashLogExtendEvent - %r\n", Status
));
1187 This service enables the sending of commands to the TPM.
1189 @param[in] This Indicates the calling context
1190 @param[in] InputParameterBlockSize Size of the TPM input parameter block.
1191 @param[in] InputParameterBlock Pointer to the TPM input parameter block.
1192 @param[in] OutputParameterBlockSize Size of the TPM output parameter block.
1193 @param[in] OutputParameterBlock Pointer to the TPM output parameter block.
1195 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
1196 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
1197 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1198 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
1203 IN EFI_TCG2_PROTOCOL
*This
,
1204 IN UINT32 InputParameterBlockSize
,
1205 IN UINT8
*InputParameterBlock
,
1206 IN UINT32 OutputParameterBlockSize
,
1207 IN UINT8
*OutputParameterBlock
1212 DEBUG ((EFI_D_INFO
, "Tcg2SubmitCommand ...\n"));
1214 if ((This
== NULL
) ||
1215 (InputParameterBlockSize
== 0) || (InputParameterBlock
== NULL
) ||
1216 (OutputParameterBlockSize
== 0) || (OutputParameterBlock
== NULL
)) {
1217 return EFI_INVALID_PARAMETER
;
1220 if (!mTcgDxeData
.BsCap
.TPMPresentFlag
) {
1221 return EFI_DEVICE_ERROR
;
1224 if (InputParameterBlockSize
> mTcgDxeData
.BsCap
.MaxCommandSize
) {
1225 return EFI_INVALID_PARAMETER
;
1227 if (OutputParameterBlockSize
> mTcgDxeData
.BsCap
.MaxResponseSize
) {
1228 return EFI_INVALID_PARAMETER
;
1231 Status
= Tpm2SubmitCommand (
1232 InputParameterBlockSize
,
1233 InputParameterBlock
,
1234 &OutputParameterBlockSize
,
1235 OutputParameterBlock
1237 DEBUG ((EFI_D_INFO
, "Tcg2SubmitCommand - %r\n", Status
));
1242 This service returns the currently active PCR banks.
1244 @param[in] This Indicates the calling context
1245 @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.
1247 @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.
1248 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1252 Tcg2GetActivePCRBanks (
1253 IN EFI_TCG2_PROTOCOL
*This
,
1254 OUT UINT32
*ActivePcrBanks
1257 if (ActivePcrBanks
== NULL
) {
1258 return EFI_INVALID_PARAMETER
;
1260 *ActivePcrBanks
= mTcgDxeData
.BsCap
.ActivePcrBanks
;
1265 This service sets the currently active PCR banks.
1267 @param[in] This Indicates the calling context
1268 @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.
1270 @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.
1271 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1275 Tcg2SetActivePCRBanks (
1276 IN EFI_TCG2_PROTOCOL
*This
,
1277 IN UINT32 ActivePcrBanks
1283 DEBUG ((EFI_D_INFO
, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks
));
1285 if (ActivePcrBanks
== 0) {
1286 return EFI_INVALID_PARAMETER
;
1288 if ((ActivePcrBanks
& (~mTcgDxeData
.BsCap
.HashAlgorithmBitmap
)) != 0) {
1289 return EFI_INVALID_PARAMETER
;
1291 if (ActivePcrBanks
== mTcgDxeData
.BsCap
.ActivePcrBanks
) {
1293 // Need clear previous SET_PCR_BANKS setting
1295 ReturnCode
= Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION
, 0);
1297 ReturnCode
= Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
, ActivePcrBanks
);
1300 if (ReturnCode
== TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
) {
1301 Status
= EFI_SUCCESS
;
1302 } else if (ReturnCode
== TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
) {
1303 Status
= EFI_OUT_OF_RESOURCES
;
1304 } else if (ReturnCode
== TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
) {
1305 Status
= EFI_UNSUPPORTED
;
1307 Status
= EFI_DEVICE_ERROR
;
1310 DEBUG ((EFI_D_INFO
, "Tcg2SetActivePCRBanks - %r\n", Status
));
1316 This service retrieves the result of a previous invocation of SetActivePcrBanks.
1318 @param[in] This Indicates the calling context
1319 @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.
1320 @param[out] Response The response from the SetActivePcrBank request.
1322 @retval EFI_SUCCESS The result value could be returned.
1323 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1327 Tcg2GetResultOfSetActivePcrBanks (
1328 IN EFI_TCG2_PROTOCOL
*This
,
1329 OUT UINT32
*OperationPresent
,
1330 OUT UINT32
*Response
1335 if ((OperationPresent
== NULL
) || (Response
== NULL
)) {
1336 return EFI_INVALID_PARAMETER
;
1339 ReturnCode
= Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent
, Response
);
1340 if (ReturnCode
== TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
) {
1343 return EFI_UNSUPPORTED
;
1347 EFI_TCG2_PROTOCOL mTcg2Protocol
= {
1350 Tcg2HashLogExtendEvent
,
1352 Tcg2GetActivePCRBanks
,
1353 Tcg2SetActivePCRBanks
,
1354 Tcg2GetResultOfSetActivePcrBanks
,
1358 Initialize the Event Log and log events passed from the PEI phase.
1360 @retval EFI_SUCCESS Operation completed successfully.
1361 @retval EFI_OUT_OF_RESOURCES Out of memory.
1371 EFI_PEI_HOB_POINTERS GuidHob
;
1372 EFI_PHYSICAL_ADDRESS Lasa
;
1374 VOID
*DigestListBin
;
1375 TPML_DIGEST_VALUES TempDigestListBin
;
1376 UINT32 DigestListBinSize
;
1379 UINT32
*EventSizePtr
;
1380 UINT32 HashAlgorithmMaskCopied
;
1381 TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
;
1382 UINT8 TempBuf
[sizeof(TCG_EfiSpecIDEventStruct
) + sizeof(UINT32
) + (HASH_COUNT
* sizeof(TCG_EfiSpecIdEventAlgorithmSize
)) + sizeof(UINT8
)];
1383 TCG_PCR_EVENT_HDR FirstPcrEvent
;
1384 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
1385 TCG_EfiSpecIdEventAlgorithmSize
*TempDigestSize
;
1386 UINT8
*VendorInfoSize
;
1387 UINT32 NumberOfAlgorithms
;
1389 DEBUG ((EFI_D_INFO
, "SetupEventLog\n"));
1392 // 1. Create Log Area
1394 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1395 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1396 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogFormat
= mTcg2EventInfo
[Index
].LogFormat
;
1397 Status
= gBS
->AllocatePages (
1399 EfiBootServicesData
,
1400 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen
)),
1403 if (EFI_ERROR (Status
)) {
1406 mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
= Lasa
;
1407 mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
1409 // To initialize them as 0xFF is recommended
1410 // because the OS can know the last entry for that.
1412 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcgLogAreaMinLen
), 0xFF);
1414 // Create first entry for Log Header Entry Data
1416 if (mTcg2EventInfo
[Index
].LogFormat
!= EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
) {
1418 // TcgEfiSpecIdEventStruct
1420 TcgEfiSpecIdEventStruct
= (TCG_EfiSpecIDEventStruct
*)TempBuf
;
1421 CopyMem (TcgEfiSpecIdEventStruct
->signature
, TCG_EfiSpecIDEventStruct_SIGNATURE_03
, sizeof(TcgEfiSpecIdEventStruct
->signature
));
1422 TcgEfiSpecIdEventStruct
->platformClass
= PcdGet8 (PcdTpmPlatformClass
);
1423 TcgEfiSpecIdEventStruct
->specVersionMajor
= TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2
;
1424 TcgEfiSpecIdEventStruct
->specVersionMinor
= TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2
;
1425 TcgEfiSpecIdEventStruct
->specErrata
= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2
;
1426 TcgEfiSpecIdEventStruct
->uintnSize
= sizeof(UINTN
)/sizeof(UINT32
);
1427 NumberOfAlgorithms
= 0;
1428 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof(*TcgEfiSpecIdEventStruct
) + sizeof(NumberOfAlgorithms
));
1429 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 0) {
1430 TempDigestSize
= DigestSize
;
1431 TempDigestSize
+= NumberOfAlgorithms
;
1432 TempDigestSize
->algorithmId
= TPM_ALG_SHA1
;
1433 TempDigestSize
->digestSize
= SHA1_DIGEST_SIZE
;
1434 NumberOfAlgorithms
++;
1436 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
1437 TempDigestSize
= DigestSize
;
1438 TempDigestSize
+= NumberOfAlgorithms
;
1439 TempDigestSize
->algorithmId
= TPM_ALG_SHA256
;
1440 TempDigestSize
->digestSize
= SHA256_DIGEST_SIZE
;
1441 NumberOfAlgorithms
++;
1443 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
1444 TempDigestSize
= DigestSize
;
1445 TempDigestSize
+= NumberOfAlgorithms
;
1446 TempDigestSize
->algorithmId
= TPM_ALG_SHA384
;
1447 TempDigestSize
->digestSize
= SHA384_DIGEST_SIZE
;
1448 NumberOfAlgorithms
++;
1450 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
1451 TempDigestSize
= DigestSize
;
1452 TempDigestSize
+= NumberOfAlgorithms
;
1453 TempDigestSize
->algorithmId
= TPM_ALG_SHA512
;
1454 TempDigestSize
->digestSize
= SHA512_DIGEST_SIZE
;
1455 NumberOfAlgorithms
++;
1457 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
1458 TempDigestSize
= DigestSize
;
1459 TempDigestSize
+= NumberOfAlgorithms
;
1460 TempDigestSize
->algorithmId
= TPM_ALG_SM3_256
;
1461 TempDigestSize
->digestSize
= SM3_256_DIGEST_SIZE
;
1462 NumberOfAlgorithms
++;
1464 CopyMem (TcgEfiSpecIdEventStruct
+ 1, &NumberOfAlgorithms
, sizeof(NumberOfAlgorithms
));
1465 TempDigestSize
= DigestSize
;
1466 TempDigestSize
+= NumberOfAlgorithms
;
1467 VendorInfoSize
= (UINT8
*)TempDigestSize
;
1468 *VendorInfoSize
= 0;
1473 FirstPcrEvent
.PCRIndex
= 0;
1474 FirstPcrEvent
.EventType
= EV_NO_ACTION
;
1475 ZeroMem (&FirstPcrEvent
.Digest
, sizeof(FirstPcrEvent
.Digest
));
1476 FirstPcrEvent
.EventSize
= (UINT32
)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct
);
1481 Status
= TcgDxeLogEvent (
1482 mTcg2EventInfo
[Index
].LogFormat
,
1484 sizeof(FirstPcrEvent
),
1485 (UINT8
*)TcgEfiSpecIdEventStruct
,
1486 FirstPcrEvent
.EventSize
1493 // 2. Create Final Log Area
1495 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1496 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1497 if (mTcg2EventInfo
[Index
].LogFormat
== EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
) {
1498 Status
= gBS
->AllocatePages (
1501 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen
)),
1504 if (EFI_ERROR (Status
)) {
1507 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcg2FinalLogAreaLen
), 0xFF);
1512 mTcgDxeData
.FinalEventsTable
[Index
] = (VOID
*)(UINTN
)Lasa
;
1513 (mTcgDxeData
.FinalEventsTable
[Index
])->Version
= EFI_TCG2_FINAL_EVENTS_TABLE_VERSION
;
1514 (mTcgDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
= 0;
1516 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogFormat
= mTcg2EventInfo
[Index
].LogFormat
;
1517 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
= Lasa
+ sizeof(EFI_TCG2_FINAL_EVENTS_TABLE
);
1518 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcg2FinalLogAreaLen
) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE
);
1519 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogSize
= 0;
1520 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].LastEvent
= (VOID
*)(UINTN
)mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
;
1521 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogStarted
= FALSE
;
1522 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogTruncated
= FALSE
;
1525 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
1527 Status
= gBS
->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid
, (VOID
*)mTcgDxeData
.FinalEventsTable
[Index
]);
1528 if (EFI_ERROR (Status
)) {
1533 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
1535 mTcgDxeData
.FinalEventsTable
[Index
] = NULL
;
1536 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogFormat
= mTcg2EventInfo
[Index
].LogFormat
;
1537 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
= 0;
1538 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Laml
= 0;
1539 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogSize
= 0;
1540 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].LastEvent
= 0;
1541 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogStarted
= FALSE
;
1542 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogTruncated
= FALSE
;
1548 // 3. Sync data from PEI to DXE
1550 Status
= EFI_SUCCESS
;
1551 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1552 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1553 GuidHob
.Raw
= GetHobList ();
1554 Status
= EFI_SUCCESS
;
1555 while (!EFI_ERROR (Status
) &&
1556 (GuidHob
.Raw
= GetNextGuidHob (mTcg2EventInfo
[Index
].EventGuid
, GuidHob
.Raw
)) != NULL
) {
1557 TcgEvent
= AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob
.Guid
), GET_GUID_HOB_DATA (GuidHob
.Guid
));
1558 ASSERT (TcgEvent
!= NULL
);
1559 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
1560 switch (mTcg2EventInfo
[Index
].LogFormat
) {
1561 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
:
1562 Status
= TcgDxeLogEvent (
1563 mTcg2EventInfo
[Index
].LogFormat
,
1565 sizeof(TCG_PCR_EVENT_HDR
),
1566 ((TCG_PCR_EVENT
*)TcgEvent
)->Event
,
1567 ((TCG_PCR_EVENT_HDR
*)TcgEvent
)->EventSize
1570 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
:
1571 DigestListBin
= (UINT8
*)TcgEvent
+ sizeof(TCG_PCRINDEX
) + sizeof(TCG_EVENTTYPE
);
1572 DigestListBinSize
= GetDigestListBinSize (DigestListBin
);
1576 CopyMem (&EventSize
, (UINT8
*)DigestListBin
+ DigestListBinSize
, sizeof(UINT32
));
1577 Event
= (UINT8
*)DigestListBin
+ DigestListBinSize
+ sizeof(UINT32
);
1579 // Filter inactive digest in the event2 log from PEI HOB.
1581 CopyMem (&TempDigestListBin
, DigestListBin
, GetDigestListBinSize (DigestListBin
));
1582 EventSizePtr
= CopyDigestListBinToBuffer (
1585 mTcgDxeData
.BsCap
.ActivePcrBanks
,
1586 &HashAlgorithmMaskCopied
1588 if (HashAlgorithmMaskCopied
!= mTcgDxeData
.BsCap
.ActivePcrBanks
) {
1591 "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",
1592 HashAlgorithmMaskCopied
,
1593 mTcgDxeData
.BsCap
.ActivePcrBanks
1597 // Restore event size.
1599 CopyMem (EventSizePtr
, &EventSize
, sizeof(UINT32
));
1600 DigestListBinSize
= GetDigestListBinSize (DigestListBin
);
1602 Status
= TcgDxeLogEvent (
1603 mTcg2EventInfo
[Index
].LogFormat
,
1605 sizeof(TCG_PCRINDEX
) + sizeof(TCG_EVENTTYPE
) + DigestListBinSize
+ sizeof(UINT32
),
1611 FreePool (TcgEvent
);
1620 Measure and log an action string, and extend the measurement result into PCR[5].
1622 @param[in] String A specific string that indicates an Action event.
1624 @retval EFI_SUCCESS Operation completed successfully.
1625 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1633 TCG_PCR_EVENT_HDR TcgEvent
;
1635 TcgEvent
.PCRIndex
= 5;
1636 TcgEvent
.EventType
= EV_EFI_ACTION
;
1637 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
1638 return TcgDxeHashLogExtendEvent (
1648 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1650 @retval EFI_SUCCESS Operation completed successfully.
1651 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1655 MeasureHandoffTables (
1660 TCG_PCR_EVENT_HDR TcgEvent
;
1661 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
1663 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
1665 ProcessorLocBuf
= NULL
;
1666 Status
= EFI_SUCCESS
;
1668 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
1671 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1673 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
1675 if (!EFI_ERROR(Status
)){
1676 TcgEvent
.PCRIndex
= 1;
1677 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
1678 TcgEvent
.EventSize
= sizeof (HandoffTables
);
1680 HandoffTables
.NumberOfTables
= 1;
1681 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
1682 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
1684 Status
= TcgDxeHashLogExtendEvent (
1686 (UINT8
*)(UINTN
)ProcessorLocBuf
,
1687 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
1689 (UINT8
*)&HandoffTables
1692 FreePool(ProcessorLocBuf
);
1700 Measure and log Separator event, and extend the measurement result into a specific PCR.
1702 @param[in] PCRIndex PCR index.
1704 @retval EFI_SUCCESS Operation completed successfully.
1705 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1709 MeasureSeparatorEvent (
1710 IN TPM_PCRINDEX PCRIndex
1713 TCG_PCR_EVENT_HDR TcgEvent
;
1716 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex
));
1719 TcgEvent
.PCRIndex
= PCRIndex
;
1720 TcgEvent
.EventType
= EV_SEPARATOR
;
1721 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
1722 return TcgDxeHashLogExtendEvent (
1724 (UINT8
*)&EventData
,
1732 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1734 @param[in] PCRIndex PCR Index.
1735 @param[in] EventType Event type.
1736 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1737 @param[in] VendorGuid A unique identifier for the vendor.
1738 @param[in] VarData The content of the variable data.
1739 @param[in] VarSize The size of the variable data.
1741 @retval EFI_SUCCESS Operation completed successfully.
1742 @retval EFI_OUT_OF_RESOURCES Out of memory.
1743 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1748 IN TPM_PCRINDEX PCRIndex
,
1749 IN TCG_EVENTTYPE EventType
,
1751 IN EFI_GUID
*VendorGuid
,
1757 TCG_PCR_EVENT_HDR TcgEvent
;
1758 UINTN VarNameLength
;
1759 EFI_VARIABLE_DATA_TREE
*VarLog
;
1761 DEBUG ((EFI_D_INFO
, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN
)PCRIndex
, (UINTN
)EventType
));
1762 DEBUG ((EFI_D_INFO
, "VariableName - %s, VendorGuid - %g)\n", VarName
, VendorGuid
));
1764 VarNameLength
= StrLen (VarName
);
1765 TcgEvent
.PCRIndex
= PCRIndex
;
1766 TcgEvent
.EventType
= EventType
;
1768 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
1769 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
1771 VarLog
= (EFI_VARIABLE_DATA_TREE
*)AllocatePool (TcgEvent
.EventSize
);
1772 if (VarLog
== NULL
) {
1773 return EFI_OUT_OF_RESOURCES
;
1776 VarLog
->VariableName
= *VendorGuid
;
1777 VarLog
->UnicodeNameLength
= VarNameLength
;
1778 VarLog
->VariableDataLength
= VarSize
;
1780 VarLog
->UnicodeName
,
1782 VarNameLength
* sizeof (*VarName
)
1784 if (VarSize
!= 0 && VarData
!= NULL
) {
1786 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
1792 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1794 // Digest is the event data (EFI_VARIABLE_DATA)
1796 Status
= TcgDxeHashLogExtendEvent (
1804 ASSERT (VarData
!= NULL
);
1805 Status
= TcgDxeHashLogExtendEvent (
1818 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1820 @param[in] PCRIndex PCR Index.
1821 @param[in] EventType Event type.
1822 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1823 @param[in] VendorGuid A unique identifier for the vendor.
1824 @param[out] VarSize The size of the variable data.
1825 @param[out] VarData Pointer to the content of the variable.
1827 @retval EFI_SUCCESS Operation completed successfully.
1828 @retval EFI_OUT_OF_RESOURCES Out of memory.
1829 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1833 ReadAndMeasureVariable (
1834 IN TPM_PCRINDEX PCRIndex
,
1835 IN TCG_EVENTTYPE EventType
,
1837 IN EFI_GUID
*VendorGuid
,
1844 Status
= GetVariable2 (VarName
, VendorGuid
, VarData
, VarSize
);
1845 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1846 if (EFI_ERROR (Status
)) {
1848 // It is valid case, so we need handle it.
1855 // if status error, VarData is freed and set NULL by GetVariable2
1857 if (EFI_ERROR (Status
)) {
1858 return EFI_NOT_FOUND
;
1862 Status
= MeasureVariable (
1874 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
1876 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1877 @param[in] VendorGuid A unique identifier for the vendor.
1878 @param[out] VarSize The size of the variable data.
1879 @param[out] VarData Pointer to the content of the variable.
1881 @retval EFI_SUCCESS Operation completed successfully.
1882 @retval EFI_OUT_OF_RESOURCES Out of memory.
1883 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1887 ReadAndMeasureBootVariable (
1889 IN EFI_GUID
*VendorGuid
,
1894 return ReadAndMeasureVariable (
1896 EV_EFI_VARIABLE_BOOT
,
1905 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1907 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1908 @param[in] VendorGuid A unique identifier for the vendor.
1909 @param[out] VarSize The size of the variable data.
1910 @param[out] VarData Pointer to the content of the variable.
1912 @retval EFI_SUCCESS Operation completed successfully.
1913 @retval EFI_OUT_OF_RESOURCES Out of memory.
1914 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1918 ReadAndMeasureSecureVariable (
1920 IN EFI_GUID
*VendorGuid
,
1925 return ReadAndMeasureVariable (
1927 EV_EFI_VARIABLE_DRIVER_CONFIG
,
1936 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1938 The EFI boot variables are BootOrder and Boot#### variables.
1940 @retval EFI_SUCCESS Operation completed successfully.
1941 @retval EFI_OUT_OF_RESOURCES Out of memory.
1942 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1946 MeasureAllBootVariables (
1957 Status
= ReadAndMeasureBootVariable (
1959 &gEfiGlobalVariableGuid
,
1961 (VOID
**) &BootOrder
1963 if (Status
== EFI_NOT_FOUND
|| BootOrder
== NULL
) {
1967 if (EFI_ERROR (Status
)) {
1969 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1971 FreePool (BootOrder
);
1975 BootCount
/= sizeof (*BootOrder
);
1976 for (Index
= 0; Index
< BootCount
; Index
++) {
1977 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
1978 Status
= ReadAndMeasureBootVariable (
1980 &gEfiGlobalVariableGuid
,
1984 if (!EFI_ERROR (Status
)) {
1985 FreePool (BootVarData
);
1989 FreePool (BootOrder
);
1994 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1996 The EFI boot variables are BootOrder and Boot#### variables.
1998 @retval EFI_SUCCESS Operation completed successfully.
1999 @retval EFI_OUT_OF_RESOURCES Out of memory.
2000 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2004 MeasureAllSecureVariables (
2013 Status
= EFI_NOT_FOUND
;
2014 for (Index
= 0; Index
< sizeof(mVariableType
)/sizeof(mVariableType
[0]); Index
++) {
2015 Status
= ReadAndMeasureSecureVariable (
2016 mVariableType
[Index
].VariableName
,
2017 mVariableType
[Index
].VendorGuid
,
2021 if (!EFI_ERROR (Status
)) {
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 TCG_PCR_EVENT_HDR TcgEvent
;
2046 TcgEvent
.PCRIndex
= 7;
2047 TcgEvent
.EventType
= EV_EFI_ACTION
;
2048 TcgEvent
.EventSize
= sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1;
2049 return TcgDxeHashLogExtendEvent (
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 ((EFI_D_INFO
, "MeasureLaunchOfFirmwareDebugger - %r\n", Status
));
2096 Status
= MeasureAllSecureVariables ();
2097 DEBUG ((EFI_D_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 (7);
2106 DEBUG ((EFI_D_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
2127 TPM_PCRINDEX PcrIndex
;
2129 PERF_START_EX (mImageHandle
, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE
);
2130 if (mBootAttempts
== 0) {
2133 // Measure handoff tables.
2135 Status
= MeasureHandoffTables ();
2136 if (EFI_ERROR (Status
)) {
2137 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
2141 // Measure BootOrder & Boot#### variables.
2143 Status
= MeasureAllBootVariables ();
2144 if (EFI_ERROR (Status
)) {
2145 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
2149 // 1. This is the first boot attempt.
2151 Status
= TcgMeasureAction (
2152 EFI_CALLING_EFI_APPLICATION
2154 if (EFI_ERROR (Status
)) {
2155 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
2159 // 2. Draw a line between pre-boot env and entering post-boot env.
2160 // PCR[7] is already done.
2162 for (PcrIndex
= 0; PcrIndex
< 7; PcrIndex
++) {
2163 Status
= MeasureSeparatorEvent (PcrIndex
);
2164 if (EFI_ERROR (Status
)) {
2165 DEBUG ((DEBUG_ERROR
, "Separator Event not Measured. Error!\n"));
2170 // 3. Measure GPT. It would be done in SAP driver.
2174 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
2178 // 5. Read & Measure variable. BootOrder already measured.
2182 // 6. Not first attempt, meaning a return from last attempt
2184 Status
= TcgMeasureAction (
2185 EFI_RETURNING_FROM_EFI_APPLICATOIN
2187 if (EFI_ERROR (Status
)) {
2188 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN
));
2192 DEBUG ((EFI_D_INFO
, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));
2194 // Increase boot attempt counter.
2197 PERF_END_EX (mImageHandle
, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE
+ 1);
2201 Exit Boot Services Event notification handler.
2203 Measure invocation and success of ExitBootServices.
2205 @param[in] Event Event whose notification function is being invoked
2206 @param[in] Context Pointer to the notification function's context
2211 OnExitBootServices (
2219 // Measure invocation of ExitBootServices,
2221 Status
= TcgMeasureAction (
2222 EFI_EXIT_BOOT_SERVICES_INVOCATION
2224 if (EFI_ERROR (Status
)) {
2225 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION
));
2229 // Measure success of ExitBootServices
2231 Status
= TcgMeasureAction (
2232 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
2234 if (EFI_ERROR (Status
)) {
2235 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED
));
2240 Exit Boot Services Failed Event notification handler.
2242 Measure Failure of ExitBootServices.
2244 @param[in] Event Event whose notification function is being invoked
2245 @param[in] Context Pointer to the notification function's context
2250 OnExitBootServicesFailed (
2258 // Measure Failure of ExitBootServices,
2260 Status
= TcgMeasureAction (
2261 EFI_EXIT_BOOT_SERVICES_FAILED
2263 if (EFI_ERROR (Status
)) {
2264 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED
));
2270 The function install Tcg2 protocol.
2272 @retval EFI_SUCCESS Tcg2 protocol is installed.
2273 @retval other Some error occurs.
2284 Status
= gBS
->InstallMultipleProtocolInterfaces (
2286 &gEfiTcg2ProtocolGuid
,
2294 The driver's entry point. It publishes EFI Tcg2 Protocol.
2296 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2297 @param[in] SystemTable A pointer to the EFI System Table.
2299 @retval EFI_SUCCESS The entry point is executed successfully.
2300 @retval other Some error occurs when executing this entry point.
2305 IN EFI_HANDLE ImageHandle
,
2306 IN EFI_SYSTEM_TABLE
*SystemTable
2312 UINT32 MaxCommandSize
;
2313 UINT32 MaxResponseSize
;
2315 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap
;
2316 UINT32 ActivePCRBanks
;
2317 UINT32 NumberOfPCRBanks
;
2319 mImageHandle
= ImageHandle
;
2321 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceNoneGuid
) ||
2322 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
2323 DEBUG ((EFI_D_ERROR
, "No TPM2 instance required!\n"));
2324 return EFI_UNSUPPORTED
;
2327 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
2328 DEBUG ((EFI_D_ERROR
, "TPM2 error!\n"));
2329 return EFI_DEVICE_ERROR
;
2332 Status
= Tpm2RequestUseTpm ();
2333 if (EFI_ERROR (Status
)) {
2334 DEBUG ((EFI_D_ERROR
, "TPM2 not detected!\n"));
2341 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX
== sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]));
2343 mTcgDxeData
.BsCap
.Size
= sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY
);
2344 mTcgDxeData
.BsCap
.ProtocolVersion
.Major
= 1;
2345 mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
= 1;
2346 mTcgDxeData
.BsCap
.StructureVersion
.Major
= 1;
2347 mTcgDxeData
.BsCap
.StructureVersion
.Minor
= 1;
2349 DEBUG ((EFI_D_INFO
, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.ProtocolVersion
.Major
, mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
));
2350 DEBUG ((EFI_D_INFO
, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.StructureVersion
.Major
, mTcgDxeData
.BsCap
.StructureVersion
.Minor
));
2352 Status
= Tpm2GetCapabilityManufactureID (&mTcgDxeData
.BsCap
.ManufacturerID
);
2353 if (EFI_ERROR (Status
)) {
2354 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityManufactureID fail!\n"));
2356 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData
.BsCap
.ManufacturerID
));
2360 UINT32 FirmwareVersion1
;
2361 UINT32 FirmwareVersion2
;
2363 Status
= Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1
, &FirmwareVersion2
);
2364 if (EFI_ERROR (Status
)) {
2365 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
2367 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1
, FirmwareVersion2
));
2371 Status
= Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize
, &MaxResponseSize
);
2372 if (EFI_ERROR (Status
)) {
2373 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
2375 mTcgDxeData
.BsCap
.MaxCommandSize
= (UINT16
)MaxCommandSize
;
2376 mTcgDxeData
.BsCap
.MaxResponseSize
= (UINT16
)MaxResponseSize
;
2377 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize
, MaxResponseSize
));
2381 // Get supported PCR and current Active PCRs
2383 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePCRBanks
);
2384 ASSERT_EFI_ERROR (Status
);
2386 mTcgDxeData
.BsCap
.HashAlgorithmBitmap
= TpmHashAlgorithmBitmap
& PcdGet32 (PcdTcg2HashAlgorithmBitmap
);
2387 mTcgDxeData
.BsCap
.ActivePcrBanks
= ActivePCRBanks
& PcdGet32 (PcdTcg2HashAlgorithmBitmap
);
2390 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.
2392 NumberOfPCRBanks
= 0;
2393 for (Index
= 0; Index
< 32; Index
++) {
2394 if ((mTcgDxeData
.BsCap
.HashAlgorithmBitmap
& (1u << Index
)) != 0) {
2399 if (PcdGet32 (PcdTcg2NumberOfPCRBanks
) == 0) {
2400 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= NumberOfPCRBanks
;
2402 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= PcdGet32 (PcdTcg2NumberOfPCRBanks
);
2403 if (PcdGet32 (PcdTcg2NumberOfPCRBanks
) > NumberOfPCRBanks
) {
2404 DEBUG ((EFI_D_ERROR
, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks
), NumberOfPCRBanks
));
2405 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= NumberOfPCRBanks
;
2409 mTcgDxeData
.BsCap
.SupportedEventLogs
= EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
| EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
;
2410 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) == 0) {
2412 // No need to expose TCG1.2 event log if SHA1 bank does not exist.
2414 mTcgDxeData
.BsCap
.SupportedEventLogs
&= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
;
2417 DEBUG ((EFI_D_INFO
, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
2418 DEBUG ((EFI_D_INFO
, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData
.BsCap
.HashAlgorithmBitmap
));
2419 DEBUG ((EFI_D_INFO
, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData
.BsCap
.NumberOfPCRBanks
));
2420 DEBUG ((EFI_D_INFO
, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData
.BsCap
.ActivePcrBanks
));
2422 if (mTcgDxeData
.BsCap
.TPMPresentFlag
) {
2424 // Setup the log area and copy event log from hob list to it
2426 Status
= SetupEventLog ();
2427 ASSERT_EFI_ERROR (Status
);
2430 // Measure handoff tables, Boot#### variables etc.
2432 Status
= EfiCreateEventReadyToBootEx (
2439 Status
= gBS
->CreateEventEx (
2444 &gEfiEventExitBootServicesGuid
,
2449 // Measure Exit Boot Service failed
2451 Status
= gBS
->CreateEventEx (
2454 OnExitBootServicesFailed
,
2456 &gEventExitBootServicesFailedGuid
,
2461 // Create event callback, because we need access variable on SecureBootPolicyVariable
2462 // We should use VariableWriteArch instead of VariableArch, because Variable driver
2463 // may update SecureBoot value based on last setting.
2465 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid
, TPL_CALLBACK
, MeasureSecureBootPolicy
, NULL
, &Registration
);
2469 // Install Tcg2Protocol
2471 Status
= InstallTcg2 ();
2472 DEBUG ((EFI_D_INFO
, "InstallTcg2 - %r\n", Status
));