2 This module implements Tcg2 Protocol.
4 Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <IndustryStandard/Acpi.h>
12 #include <IndustryStandard/PeImage.h>
13 #include <IndustryStandard/TcpaAcpi.h>
15 #include <Guid/GlobalVariable.h>
16 #include <Guid/HobList.h>
17 #include <Guid/TcgEventHob.h>
18 #include <Guid/EventGroup.h>
19 #include <Guid/EventExitBootServiceFailed.h>
20 #include <Guid/ImageAuthentication.h>
21 #include <Guid/TpmInstance.h>
23 #include <Protocol/DevicePath.h>
24 #include <Protocol/MpService.h>
25 #include <Protocol/VariableWrite.h>
26 #include <Protocol/Tcg2Protocol.h>
27 #include <Protocol/TrEEProtocol.h>
28 #include <Protocol/ResetNotification.h>
30 #include <Library/DebugLib.h>
31 #include <Library/BaseMemoryLib.h>
32 #include <Library/UefiRuntimeServicesTableLib.h>
33 #include <Library/UefiDriverEntryPoint.h>
34 #include <Library/HobLib.h>
35 #include <Library/UefiBootServicesTableLib.h>
36 #include <Library/BaseLib.h>
37 #include <Library/MemoryAllocationLib.h>
38 #include <Library/PrintLib.h>
39 #include <Library/Tpm2CommandLib.h>
40 #include <Library/PcdLib.h>
41 #include <Library/UefiLib.h>
42 #include <Library/Tpm2DeviceLib.h>
43 #include <Library/HashLib.h>
44 #include <Library/PerformanceLib.h>
45 #include <Library/ReportStatusCodeLib.h>
46 #include <Library/Tcg2PhysicalPresenceLib.h>
48 #define PERF_ID_TCG2_DXE 0x3120
55 #define TCG2_DEFAULT_MAX_COMMAND_SIZE 0x1000
56 #define TCG2_DEFAULT_MAX_RESPONSE_SIZE 0x1000
60 EFI_TCG2_EVENT_LOG_FORMAT LogFormat
;
61 } TCG2_EVENT_INFO_STRUCT
;
63 TCG2_EVENT_INFO_STRUCT mTcg2EventInfo
[] = {
64 {&gTcgEventEntryHobGuid
, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
},
65 {&gTcgEvent2EntryHobGuid
, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
},
68 #define TCG_EVENT_LOG_AREA_COUNT_MAX 2
71 EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
;
72 EFI_PHYSICAL_ADDRESS Lasa
;
76 BOOLEAN EventLogStarted
;
77 BOOLEAN EventLogTruncated
;
78 } TCG_EVENT_LOG_AREA_STRUCT
;
80 typedef struct _TCG_DXE_DATA
{
81 EFI_TCG2_BOOT_SERVICE_CAPABILITY BsCap
;
82 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
83 BOOLEAN GetEventLogCalled
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
84 TCG_EVENT_LOG_AREA_STRUCT FinalEventLogAreaStruct
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
85 EFI_TCG2_FINAL_EVENTS_TABLE
*FinalEventsTable
[TCG_EVENT_LOG_AREA_COUNT_MAX
];
88 TCG_DXE_DATA mTcgDxeData
= {
90 sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY
), // Size
91 { 1, 1 }, // StructureVersion
92 { 1, 1 }, // ProtocolVersion
93 EFI_TCG2_BOOT_HASH_ALG_SHA1
, // HashAlgorithmBitmap
94 EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
, // SupportedEventLogs
95 TRUE
, // TPMPresentFlag
96 TCG2_DEFAULT_MAX_COMMAND_SIZE
, // MaxCommandSize
97 TCG2_DEFAULT_MAX_RESPONSE_SIZE
, // MaxResponseSize
99 0, // NumberOfPCRBanks
104 UINTN mBootAttempts
= 0;
105 CHAR16 mBootVarName
[] = L
"BootOrder";
107 VARIABLE_TYPE mVariableType
[] = {
108 {EFI_SECURE_BOOT_MODE_NAME
, &gEfiGlobalVariableGuid
},
109 {EFI_PLATFORM_KEY_NAME
, &gEfiGlobalVariableGuid
},
110 {EFI_KEY_EXCHANGE_KEY_NAME
, &gEfiGlobalVariableGuid
},
111 {EFI_IMAGE_SECURITY_DATABASE
, &gEfiImageSecurityDatabaseGuid
},
112 {EFI_IMAGE_SECURITY_DATABASE1
, &gEfiImageSecurityDatabaseGuid
},
115 EFI_HANDLE mImageHandle
;
118 Measure PE image into TPM log based on the authenticode image hashing in
119 PE/COFF Specification 8.0 Appendix A.
121 Caution: This function may receive untrusted input.
122 PE/COFF image is external input, so this function will validate its data structure
123 within this image buffer before use.
125 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
127 @param[in] PCRIndex TPM PCR index
128 @param[in] ImageAddress Start address of image buffer.
129 @param[in] ImageSize Image size
130 @param[out] DigestList Digest list of this image.
132 @retval EFI_SUCCESS Successfully measure image.
133 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
134 @retval other error value
137 MeasurePeImageAndExtend (
139 IN EFI_PHYSICAL_ADDRESS ImageAddress
,
141 OUT TPML_DIGEST_VALUES
*DigestList
146 This function dump raw data.
149 @param Size raw data size
159 for (Index
= 0; Index
< Size
; Index
++) {
160 DEBUG ((EFI_D_INFO
, "%02x", (UINTN
)Data
[Index
]));
166 This function initialize TCG_PCR_EVENT2_HDR for EV_NO_ACTION Event Type other than EFI Specification ID event
167 The behavior is defined by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types
169 @param[in, out] NoActionEvent Event Header of EV_NO_ACTION Event
170 @param[in] EventSize Event Size of the EV_NO_ACTION Event
175 IN OUT TCG_PCR_EVENT2_HDR
*NoActionEvent
,
179 UINT32 DigestListCount
;
180 TPMI_ALG_HASH HashAlgId
;
183 DigestBuffer
= (UINT8
*)NoActionEvent
->Digests
.digests
;
186 NoActionEvent
->PCRIndex
= 0;
187 NoActionEvent
->EventType
= EV_NO_ACTION
;
190 // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0
192 ZeroMem (&NoActionEvent
->Digests
, sizeof(NoActionEvent
->Digests
));
194 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 0) {
195 HashAlgId
= TPM_ALG_SHA1
;
196 CopyMem (DigestBuffer
, &HashAlgId
, sizeof(TPMI_ALG_HASH
));
197 DigestBuffer
+= sizeof(TPMI_ALG_HASH
) + GetHashSizeFromAlgo (HashAlgId
);
201 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
202 HashAlgId
= TPM_ALG_SHA256
;
203 CopyMem (DigestBuffer
, &HashAlgId
, sizeof(TPMI_ALG_HASH
));
204 DigestBuffer
+= sizeof(TPMI_ALG_HASH
) + GetHashSizeFromAlgo (HashAlgId
);
208 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
209 HashAlgId
= TPM_ALG_SHA384
;
210 CopyMem (DigestBuffer
, &HashAlgId
, sizeof(TPMI_ALG_HASH
));
211 DigestBuffer
+= sizeof(TPMI_ALG_HASH
) + GetHashSizeFromAlgo (HashAlgId
);
215 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
216 HashAlgId
= TPM_ALG_SHA512
;
217 CopyMem (DigestBuffer
, &HashAlgId
, sizeof(TPMI_ALG_HASH
));
218 DigestBuffer
+= sizeof(TPMI_ALG_HASH
) + GetHashSizeFromAlgo (HashAlgId
);
222 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
223 HashAlgId
= TPM_ALG_SM3_256
;
224 CopyMem (DigestBuffer
, &HashAlgId
, sizeof(TPMI_ALG_HASH
));
225 DigestBuffer
+= sizeof(TPMI_ALG_HASH
) + GetHashSizeFromAlgo (HashAlgId
);
232 WriteUnaligned32 ((UINT32
*)&NoActionEvent
->Digests
.count
, DigestListCount
);
237 WriteUnaligned32((UINT32
*)DigestBuffer
, EventSize
);
242 This function dump raw data with colume format.
245 @param Size raw data size
258 #define COLUME_SIZE (16 * 2)
260 Count
= Size
/ COLUME_SIZE
;
261 Left
= Size
% COLUME_SIZE
;
262 for (Index
= 0; Index
< Count
; Index
++) {
263 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
264 InternalDumpData (Data
+ Index
* COLUME_SIZE
, COLUME_SIZE
);
265 DEBUG ((EFI_D_INFO
, "\n"));
269 DEBUG ((EFI_D_INFO
, "%04x: ", Index
* COLUME_SIZE
));
270 InternalDumpData (Data
+ Index
* COLUME_SIZE
, Left
);
271 DEBUG ((EFI_D_INFO
, "\n"));
276 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
277 Caller is responsible to free LocationBuf.
279 @param[out] LocationBuf Returns Processor Location Buffer.
280 @param[out] Num Returns processor number.
282 @retval EFI_SUCCESS Operation completed successfully.
283 @retval EFI_UNSUPPORTED MpService protocol not found.
287 GetProcessorsCpuLocation (
288 OUT EFI_CPU_PHYSICAL_LOCATION
**LocationBuf
,
293 EFI_MP_SERVICES_PROTOCOL
*MpProtocol
;
295 UINTN EnabledProcessorNum
;
296 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
297 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
300 Status
= gBS
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**) &MpProtocol
);
301 if (EFI_ERROR (Status
)) {
303 // MP protocol is not installed
305 return EFI_UNSUPPORTED
;
308 Status
= MpProtocol
->GetNumberOfProcessors(
313 if (EFI_ERROR(Status
)){
317 Status
= gBS
->AllocatePool(
319 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
320 (VOID
**) &ProcessorLocBuf
322 if (EFI_ERROR(Status
)){
327 // Get each processor Location info
329 for (Index
= 0; Index
< ProcessorNum
; Index
++) {
330 Status
= MpProtocol
->GetProcessorInfo(
335 if (EFI_ERROR(Status
)){
336 FreePool(ProcessorLocBuf
);
341 // Get all Processor Location info & measure
344 &ProcessorLocBuf
[Index
],
345 &ProcessorInfo
.Location
,
346 sizeof(EFI_CPU_PHYSICAL_LOCATION
)
350 *LocationBuf
= ProcessorLocBuf
;
357 The EFI_TCG2_PROTOCOL GetCapability function call provides protocol
358 capability information and state information.
360 @param[in] This Indicates the calling context
361 @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY
362 structure and sets the size field to the size of the structure allocated.
363 The callee fills in the fields with the EFI protocol capability information
364 and the current EFI TCG2 state information up to the number of fields which
365 fit within the size of the structure passed in.
367 @retval EFI_SUCCESS Operation completed successfully.
368 @retval EFI_DEVICE_ERROR The command was unsuccessful.
369 The ProtocolCapability variable will not be populated.
370 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
371 The ProtocolCapability variable will not be populated.
372 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
373 It will be partially populated (required Size field will be set).
378 IN EFI_TCG2_PROTOCOL
*This
,
379 IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
382 DEBUG ((DEBUG_VERBOSE
, "Tcg2GetCapability ...\n"));
384 if ((This
== NULL
) || (ProtocolCapability
== NULL
)) {
385 return EFI_INVALID_PARAMETER
;
388 DEBUG ((DEBUG_VERBOSE
, "Size - 0x%x\n", ProtocolCapability
->Size
));
389 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
)));
391 if (ProtocolCapability
->Size
< mTcgDxeData
.BsCap
.Size
) {
393 // Handle the case that firmware support 1.1 but OS only support 1.0.
395 if ((mTcgDxeData
.BsCap
.ProtocolVersion
.Major
> 0x01) ||
396 ((mTcgDxeData
.BsCap
.ProtocolVersion
.Major
== 0x01) && ((mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
> 0x00)))) {
397 if (ProtocolCapability
->Size
>= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0
)) {
398 CopyMem (ProtocolCapability
, &mTcgDxeData
.BsCap
, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0
));
399 ProtocolCapability
->Size
= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0
);
400 ProtocolCapability
->StructureVersion
.Major
= 1;
401 ProtocolCapability
->StructureVersion
.Minor
= 0;
402 ProtocolCapability
->ProtocolVersion
.Major
= 1;
403 ProtocolCapability
->ProtocolVersion
.Minor
= 0;
404 DEBUG ((EFI_D_ERROR
, "TreeGetCapability (Compatible) - %r\n", EFI_SUCCESS
));
408 ProtocolCapability
->Size
= mTcgDxeData
.BsCap
.Size
;
409 return EFI_BUFFER_TOO_SMALL
;
412 CopyMem (ProtocolCapability
, &mTcgDxeData
.BsCap
, mTcgDxeData
.BsCap
.Size
);
413 DEBUG ((DEBUG_VERBOSE
, "Tcg2GetCapability - %r\n", EFI_SUCCESS
));
418 This function dump PCR event.
420 @param[in] EventHdr TCG PCR event structure.
424 IN TCG_PCR_EVENT_HDR
*EventHdr
429 DEBUG ((EFI_D_INFO
, " Event:\n"));
430 DEBUG ((EFI_D_INFO
, " PCRIndex - %d\n", EventHdr
->PCRIndex
));
431 DEBUG ((EFI_D_INFO
, " EventType - 0x%08x\n", EventHdr
->EventType
));
432 DEBUG ((EFI_D_INFO
, " Digest - "));
433 for (Index
= 0; Index
< sizeof(TCG_DIGEST
); Index
++) {
434 DEBUG ((EFI_D_INFO
, "%02x ", EventHdr
->Digest
.digest
[Index
]));
436 DEBUG ((EFI_D_INFO
, "\n"));
437 DEBUG ((EFI_D_INFO
, " EventSize - 0x%08x\n", EventHdr
->EventSize
));
438 InternalDumpHex ((UINT8
*)(EventHdr
+ 1), EventHdr
->EventSize
);
442 This function dump TCG_EfiSpecIDEventStruct.
444 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
447 DumpTcgEfiSpecIdEventStruct (
448 IN TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
451 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
453 UINT8
*VendorInfoSize
;
455 UINT32 NumberOfAlgorithms
;
457 DEBUG ((EFI_D_INFO
, " TCG_EfiSpecIDEventStruct:\n"));
458 DEBUG ((EFI_D_INFO
, " signature - '"));
459 for (Index
= 0; Index
< sizeof(TcgEfiSpecIdEventStruct
->signature
); Index
++) {
460 DEBUG ((EFI_D_INFO
, "%c", TcgEfiSpecIdEventStruct
->signature
[Index
]));
462 DEBUG ((EFI_D_INFO
, "'\n"));
463 DEBUG ((EFI_D_INFO
, " platformClass - 0x%08x\n", TcgEfiSpecIdEventStruct
->platformClass
));
464 DEBUG ((EFI_D_INFO
, " specVersion - %d.%d%d\n", TcgEfiSpecIdEventStruct
->specVersionMajor
, TcgEfiSpecIdEventStruct
->specVersionMinor
, TcgEfiSpecIdEventStruct
->specErrata
));
465 DEBUG ((EFI_D_INFO
, " uintnSize - 0x%02x\n", TcgEfiSpecIdEventStruct
->uintnSize
));
467 CopyMem (&NumberOfAlgorithms
, TcgEfiSpecIdEventStruct
+ 1, sizeof(NumberOfAlgorithms
));
468 DEBUG ((EFI_D_INFO
, " NumberOfAlgorithms - 0x%08x\n", NumberOfAlgorithms
));
470 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof(*TcgEfiSpecIdEventStruct
) + sizeof(NumberOfAlgorithms
));
471 for (Index
= 0; Index
< NumberOfAlgorithms
; Index
++) {
472 DEBUG ((EFI_D_INFO
, " digest(%d)\n", Index
));
473 DEBUG ((EFI_D_INFO
, " algorithmId - 0x%04x\n", DigestSize
[Index
].algorithmId
));
474 DEBUG ((EFI_D_INFO
, " digestSize - 0x%04x\n", DigestSize
[Index
].digestSize
));
476 VendorInfoSize
= (UINT8
*)&DigestSize
[NumberOfAlgorithms
];
477 DEBUG ((EFI_D_INFO
, " VendorInfoSize - 0x%02x\n", *VendorInfoSize
));
478 VendorInfo
= VendorInfoSize
+ 1;
479 DEBUG ((EFI_D_INFO
, " VendorInfo - "));
480 for (Index
= 0; Index
< *VendorInfoSize
; Index
++) {
481 DEBUG ((EFI_D_INFO
, "%02x ", VendorInfo
[Index
]));
483 DEBUG ((EFI_D_INFO
, "\n"));
487 This function get size of TCG_EfiSpecIDEventStruct.
489 @param[in] TcgEfiSpecIdEventStruct A pointer to TCG_EfiSpecIDEventStruct.
492 GetTcgEfiSpecIdEventStructSize (
493 IN TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
496 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
497 UINT8
*VendorInfoSize
;
498 UINT32 NumberOfAlgorithms
;
500 CopyMem (&NumberOfAlgorithms
, TcgEfiSpecIdEventStruct
+ 1, sizeof(NumberOfAlgorithms
));
502 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof(*TcgEfiSpecIdEventStruct
) + sizeof(NumberOfAlgorithms
));
503 VendorInfoSize
= (UINT8
*)&DigestSize
[NumberOfAlgorithms
];
504 return sizeof(TCG_EfiSpecIDEventStruct
) + sizeof(UINT32
) + (NumberOfAlgorithms
* sizeof(TCG_EfiSpecIdEventAlgorithmSize
)) + sizeof(UINT8
) + (*VendorInfoSize
);
508 This function dump PCR event 2.
510 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.
514 IN TCG_PCR_EVENT2
*TcgPcrEvent2
520 TPMI_ALG_HASH HashAlgo
;
526 DEBUG ((EFI_D_INFO
, " Event:\n"));
527 DEBUG ((EFI_D_INFO
, " PCRIndex - %d\n", TcgPcrEvent2
->PCRIndex
));
528 DEBUG ((EFI_D_INFO
, " EventType - 0x%08x\n", TcgPcrEvent2
->EventType
));
530 DEBUG ((EFI_D_INFO
, " DigestCount: 0x%08x\n", TcgPcrEvent2
->Digest
.count
));
532 DigestCount
= TcgPcrEvent2
->Digest
.count
;
533 HashAlgo
= TcgPcrEvent2
->Digest
.digests
[0].hashAlg
;
534 DigestBuffer
= (UINT8
*)&TcgPcrEvent2
->Digest
.digests
[0].digest
;
535 for (DigestIndex
= 0; DigestIndex
< DigestCount
; DigestIndex
++) {
536 DEBUG ((EFI_D_INFO
, " HashAlgo : 0x%04x\n", HashAlgo
));
537 DEBUG ((EFI_D_INFO
, " Digest(%d): ", DigestIndex
));
538 DigestSize
= GetHashSizeFromAlgo (HashAlgo
);
539 for (Index
= 0; Index
< DigestSize
; Index
++) {
540 DEBUG ((EFI_D_INFO
, "%02x ", DigestBuffer
[Index
]));
542 DEBUG ((EFI_D_INFO
, "\n"));
546 CopyMem (&HashAlgo
, DigestBuffer
+ DigestSize
, sizeof(TPMI_ALG_HASH
));
547 DigestBuffer
= DigestBuffer
+ DigestSize
+ sizeof(TPMI_ALG_HASH
);
549 DEBUG ((EFI_D_INFO
, "\n"));
550 DigestBuffer
= DigestBuffer
- sizeof(TPMI_ALG_HASH
);
552 CopyMem (&EventSize
, DigestBuffer
, sizeof(TcgPcrEvent2
->EventSize
));
553 DEBUG ((EFI_D_INFO
, " EventSize - 0x%08x\n", EventSize
));
554 EventBuffer
= DigestBuffer
+ sizeof(TcgPcrEvent2
->EventSize
);
555 InternalDumpHex (EventBuffer
, EventSize
);
559 This function returns size of TCG PCR event 2.
561 @param[in] TcgPcrEvent2 TCG PCR event 2 structure.
563 @return size of TCG PCR event 2.
567 IN TCG_PCR_EVENT2
*TcgPcrEvent2
572 TPMI_ALG_HASH HashAlgo
;
578 DigestCount
= TcgPcrEvent2
->Digest
.count
;
579 HashAlgo
= TcgPcrEvent2
->Digest
.digests
[0].hashAlg
;
580 DigestBuffer
= (UINT8
*)&TcgPcrEvent2
->Digest
.digests
[0].digest
;
581 for (DigestIndex
= 0; DigestIndex
< DigestCount
; DigestIndex
++) {
582 DigestSize
= GetHashSizeFromAlgo (HashAlgo
);
586 CopyMem (&HashAlgo
, DigestBuffer
+ DigestSize
, sizeof(TPMI_ALG_HASH
));
587 DigestBuffer
= DigestBuffer
+ DigestSize
+ sizeof(TPMI_ALG_HASH
);
589 DigestBuffer
= DigestBuffer
- sizeof(TPMI_ALG_HASH
);
591 CopyMem (&EventSize
, DigestBuffer
, sizeof(TcgPcrEvent2
->EventSize
));
592 EventBuffer
= DigestBuffer
+ sizeof(TcgPcrEvent2
->EventSize
);
594 return (UINTN
)EventBuffer
+ EventSize
- (UINTN
)TcgPcrEvent2
;
598 This function dump event log.
600 @param[in] EventLogFormat The type of the event log for which the information is requested.
601 @param[in] EventLogLocation A pointer to the memory address of the event log.
602 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
603 address of the start of the last entry in the event log in memory.
604 @param[in] FinalEventsTable A pointer to the memory address of the final event table.
608 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
,
609 IN EFI_PHYSICAL_ADDRESS EventLogLocation
,
610 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry
,
611 IN EFI_TCG2_FINAL_EVENTS_TABLE
*FinalEventsTable
614 TCG_PCR_EVENT_HDR
*EventHdr
;
615 TCG_PCR_EVENT2
*TcgPcrEvent2
;
616 TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
;
617 UINTN NumberOfEvents
;
619 DEBUG ((EFI_D_INFO
, "EventLogFormat: (0x%x)\n", EventLogFormat
));
621 switch (EventLogFormat
) {
622 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
:
623 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)EventLogLocation
;
624 while ((UINTN
)EventHdr
<= EventLogLastEntry
) {
625 DumpEvent (EventHdr
);
626 EventHdr
= (TCG_PCR_EVENT_HDR
*)((UINTN
)EventHdr
+ sizeof(TCG_PCR_EVENT_HDR
) + EventHdr
->EventSize
);
628 if (FinalEventsTable
== NULL
) {
629 DEBUG ((EFI_D_INFO
, "FinalEventsTable: NOT FOUND\n"));
631 DEBUG ((EFI_D_INFO
, "FinalEventsTable: (0x%x)\n", FinalEventsTable
));
632 DEBUG ((EFI_D_INFO
, " Version: (0x%x)\n", FinalEventsTable
->Version
));
633 DEBUG ((EFI_D_INFO
, " NumberOfEvents: (0x%x)\n", FinalEventsTable
->NumberOfEvents
));
635 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)(FinalEventsTable
+ 1);
636 for (NumberOfEvents
= 0; NumberOfEvents
< FinalEventsTable
->NumberOfEvents
; NumberOfEvents
++) {
637 DumpEvent (EventHdr
);
638 EventHdr
= (TCG_PCR_EVENT_HDR
*)((UINTN
)EventHdr
+ sizeof(TCG_PCR_EVENT_HDR
) + EventHdr
->EventSize
);
642 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
:
646 EventHdr
= (TCG_PCR_EVENT_HDR
*)(UINTN
)EventLogLocation
;
647 DumpEvent (EventHdr
);
649 TcgEfiSpecIdEventStruct
= (TCG_EfiSpecIDEventStruct
*)(EventHdr
+ 1);
650 DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct
);
652 TcgPcrEvent2
= (TCG_PCR_EVENT2
*)((UINTN
)TcgEfiSpecIdEventStruct
+ GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct
));
653 while ((UINTN
)TcgPcrEvent2
<= EventLogLastEntry
) {
654 DumpEvent2 (TcgPcrEvent2
);
655 TcgPcrEvent2
= (TCG_PCR_EVENT2
*)((UINTN
)TcgPcrEvent2
+ GetPcrEvent2Size (TcgPcrEvent2
));
658 if (FinalEventsTable
== NULL
) {
659 DEBUG ((EFI_D_INFO
, "FinalEventsTable: NOT FOUND\n"));
661 DEBUG ((EFI_D_INFO
, "FinalEventsTable: (0x%x)\n", FinalEventsTable
));
662 DEBUG ((EFI_D_INFO
, " Version: (0x%x)\n", FinalEventsTable
->Version
));
663 DEBUG ((EFI_D_INFO
, " NumberOfEvents: (0x%x)\n", FinalEventsTable
->NumberOfEvents
));
665 TcgPcrEvent2
= (TCG_PCR_EVENT2
*)(UINTN
)(FinalEventsTable
+ 1);
666 for (NumberOfEvents
= 0; NumberOfEvents
< FinalEventsTable
->NumberOfEvents
; NumberOfEvents
++) {
667 DumpEvent2 (TcgPcrEvent2
);
668 TcgPcrEvent2
= (TCG_PCR_EVENT2
*)((UINTN
)TcgPcrEvent2
+ GetPcrEvent2Size (TcgPcrEvent2
));
678 The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to
679 retrieve the address of a given event log and its last entry.
681 @param[in] This Indicates the calling context
682 @param[in] EventLogFormat The type of the event log for which the information is requested.
683 @param[out] EventLogLocation A pointer to the memory address of the event log.
684 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
685 address of the start of the last entry in the event log in memory.
686 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
687 have exceeded the area allocated for events, this value is set to TRUE.
688 Otherwise, the value will be FALSE and the Event Log will be complete.
690 @retval EFI_SUCCESS Operation completed successfully.
691 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
692 (e.g. asking for an event log whose format is not supported).
697 IN EFI_TCG2_PROTOCOL
*This
,
698 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
,
699 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
700 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
,
701 OUT BOOLEAN
*EventLogTruncated
706 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog ... (0x%x)\n", EventLogFormat
));
709 return EFI_INVALID_PARAMETER
;
712 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
713 if (EventLogFormat
== mTcg2EventInfo
[Index
].LogFormat
) {
718 if (Index
== sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0])) {
719 return EFI_INVALID_PARAMETER
;
722 if ((mTcg2EventInfo
[Index
].LogFormat
& mTcgDxeData
.BsCap
.SupportedEventLogs
) == 0) {
723 return EFI_INVALID_PARAMETER
;
726 if (!mTcgDxeData
.BsCap
.TPMPresentFlag
) {
727 if (EventLogLocation
!= NULL
) {
728 *EventLogLocation
= 0;
730 if (EventLogLastEntry
!= NULL
) {
731 *EventLogLastEntry
= 0;
733 if (EventLogTruncated
!= NULL
) {
734 *EventLogTruncated
= FALSE
;
739 if (EventLogLocation
!= NULL
) {
740 *EventLogLocation
= mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
;
741 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog (EventLogLocation - %x)\n", *EventLogLocation
));
744 if (EventLogLastEntry
!= NULL
) {
745 if (!mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogStarted
) {
746 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
748 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)mTcgDxeData
.EventLogAreaStruct
[Index
].LastEvent
;
750 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry
));
753 if (EventLogTruncated
!= NULL
) {
754 *EventLogTruncated
= mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogTruncated
;
755 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated
));
758 DEBUG ((EFI_D_INFO
, "Tcg2GetEventLog - %r\n", EFI_SUCCESS
));
760 // Dump Event Log for debug purpose
761 if ((EventLogLocation
!= NULL
) && (EventLogLastEntry
!= NULL
)) {
762 DumpEventLog (EventLogFormat
, *EventLogLocation
, *EventLogLastEntry
, mTcgDxeData
.FinalEventsTable
[Index
]);
766 // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored
767 // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.
769 mTcgDxeData
.GetEventLogCalled
[Index
] = TRUE
;
775 Add a new entry to the Event Log.
777 @param[in, out] EventLogPtr Pointer to the Event Log data.
778 @param[in, out] LogSize Size of the Event Log.
779 @param[in] MaxSize Maximum size of the Event Log.
780 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
781 @param[in] NewEventHdrSize New event header size.
782 @param[in] NewEventData Pointer to the new event data.
783 @param[in] NewEventSize New event data size.
785 @retval EFI_SUCCESS The new event log entry was added.
786 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
791 IN OUT UINT8
**EventLogPtr
,
792 IN OUT UINTN
*LogSize
,
794 IN VOID
*NewEventHdr
,
795 IN UINT32 NewEventHdrSize
,
796 IN UINT8
*NewEventData
,
797 IN UINT32 NewEventSize
802 if (NewEventSize
> MAX_ADDRESS
- NewEventHdrSize
) {
803 return EFI_OUT_OF_RESOURCES
;
806 NewLogSize
= NewEventHdrSize
+ NewEventSize
;
808 if (NewLogSize
> MAX_ADDRESS
- *LogSize
) {
809 return EFI_OUT_OF_RESOURCES
;
812 if (NewLogSize
+ *LogSize
> MaxSize
) {
813 DEBUG ((EFI_D_INFO
, " MaxSize - 0x%x\n", MaxSize
));
814 DEBUG ((EFI_D_INFO
, " NewLogSize - 0x%x\n", NewLogSize
));
815 DEBUG ((EFI_D_INFO
, " LogSize - 0x%x\n", *LogSize
));
816 DEBUG ((EFI_D_INFO
, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES
));
817 return EFI_OUT_OF_RESOURCES
;
820 *EventLogPtr
+= *LogSize
;
821 *LogSize
+= NewLogSize
;
822 CopyMem (*EventLogPtr
, NewEventHdr
, NewEventHdrSize
);
824 *EventLogPtr
+ NewEventHdrSize
,
832 Add a new entry to the Event Log.
834 @param[in] EventLogFormat The type of the event log for which the information is requested.
835 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
836 @param[in] NewEventHdrSize New event header size.
837 @param[in] NewEventData Pointer to the new event data.
838 @param[in] NewEventSize New event data size.
840 @retval EFI_SUCCESS The new event log entry was added.
841 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
846 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat
,
847 IN VOID
*NewEventHdr
,
848 IN UINT32 NewEventHdrSize
,
849 IN UINT8
*NewEventData
,
850 IN UINT32 NewEventSize
855 TCG_EVENT_LOG_AREA_STRUCT
*EventLogAreaStruct
;
857 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
858 if (EventLogFormat
== mTcg2EventInfo
[Index
].LogFormat
) {
863 if (Index
== sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0])) {
864 return EFI_INVALID_PARAMETER
;
868 // Record to normal event log
870 EventLogAreaStruct
= &mTcgDxeData
.EventLogAreaStruct
[Index
];
872 if (EventLogAreaStruct
->EventLogTruncated
) {
873 return EFI_VOLUME_FULL
;
876 EventLogAreaStruct
->LastEvent
= (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
;
877 Status
= TcgCommLogEvent (
878 &EventLogAreaStruct
->LastEvent
,
879 &EventLogAreaStruct
->EventLogSize
,
880 (UINTN
)EventLogAreaStruct
->Laml
,
887 if (Status
== EFI_OUT_OF_RESOURCES
) {
888 EventLogAreaStruct
->EventLogTruncated
= TRUE
;
889 return EFI_VOLUME_FULL
;
890 } else if (Status
== EFI_SUCCESS
) {
891 EventLogAreaStruct
->EventLogStarted
= TRUE
;
895 // If GetEventLog is called, record to FinalEventsTable, too.
897 if (mTcgDxeData
.GetEventLogCalled
[Index
]) {
898 if (mTcgDxeData
.FinalEventsTable
[Index
] == NULL
) {
900 // no need for FinalEventsTable
904 EventLogAreaStruct
= &mTcgDxeData
.FinalEventLogAreaStruct
[Index
];
906 if (EventLogAreaStruct
->EventLogTruncated
) {
907 return EFI_VOLUME_FULL
;
910 EventLogAreaStruct
->LastEvent
= (UINT8
*)(UINTN
)EventLogAreaStruct
->Lasa
;
911 Status
= TcgCommLogEvent (
912 &EventLogAreaStruct
->LastEvent
,
913 &EventLogAreaStruct
->EventLogSize
,
914 (UINTN
)EventLogAreaStruct
->Laml
,
920 if (Status
== EFI_OUT_OF_RESOURCES
) {
921 EventLogAreaStruct
->EventLogTruncated
= TRUE
;
922 return EFI_VOLUME_FULL
;
923 } else if (Status
== EFI_SUCCESS
) {
924 EventLogAreaStruct
->EventLogStarted
= TRUE
;
926 // Increase the NumberOfEvents in FinalEventsTable
928 (mTcgDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
++;
929 DEBUG ((EFI_D_INFO
, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
));
930 DEBUG ((EFI_D_INFO
, " Size - 0x%x\n", (UINTN
)EventLogAreaStruct
->EventLogSize
));
938 Get TPML_DIGEST_VALUES compact binary buffer size.
940 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
942 @return TPML_DIGEST_VALUES compact binary buffer size.
945 GetDigestListBinSize (
946 IN VOID
*DigestListBin
953 TPMI_ALG_HASH HashAlg
;
955 Count
= ReadUnaligned32 (DigestListBin
);
956 TotalSize
= sizeof(Count
);
957 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof(Count
);
958 for (Index
= 0; Index
< Count
; Index
++) {
959 HashAlg
= ReadUnaligned16 (DigestListBin
);
960 TotalSize
+= sizeof(HashAlg
);
961 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof(HashAlg
);
963 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
964 TotalSize
+= DigestSize
;
965 DigestListBin
= (UINT8
*)DigestListBin
+ DigestSize
;
972 Copy TPML_DIGEST_VALUES compact binary into a buffer
974 @param[in,out] Buffer Buffer to hold copied TPML_DIGEST_VALUES compact binary.
975 @param[in] DigestListBin TPML_DIGEST_VALUES compact binary buffer.
976 @param[in] HashAlgorithmMask HASH bits corresponding to the desired digests to copy.
977 @param[out] HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.
979 @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.
982 CopyDigestListBinToBuffer (
984 IN VOID
*DigestListBin
,
985 IN UINT32 HashAlgorithmMask
,
986 OUT UINT32
*HashAlgorithmMaskCopied
992 TPMI_ALG_HASH HashAlg
;
993 UINT32 DigestListCount
;
994 UINT32
*DigestListCountPtr
;
996 DigestListCountPtr
= (UINT32
*) Buffer
;
998 (*HashAlgorithmMaskCopied
) = 0;
1000 Count
= ReadUnaligned32 (DigestListBin
);
1001 Buffer
= (UINT8
*)Buffer
+ sizeof(Count
);
1002 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof(Count
);
1003 for (Index
= 0; Index
< Count
; Index
++) {
1004 HashAlg
= ReadUnaligned16 (DigestListBin
);
1005 DigestListBin
= (UINT8
*)DigestListBin
+ sizeof(HashAlg
);
1006 DigestSize
= GetHashSizeFromAlgo (HashAlg
);
1008 if (IsHashAlgSupportedInHashAlgorithmMask(HashAlg
, HashAlgorithmMask
)) {
1009 CopyMem (Buffer
, &HashAlg
, sizeof(HashAlg
));
1010 Buffer
= (UINT8
*)Buffer
+ sizeof(HashAlg
);
1011 CopyMem (Buffer
, DigestListBin
, DigestSize
);
1012 Buffer
= (UINT8
*)Buffer
+ DigestSize
;
1014 (*HashAlgorithmMaskCopied
) |= GetHashMaskFromAlgo (HashAlg
);
1016 DEBUG ((DEBUG_ERROR
, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg
));
1018 DigestListBin
= (UINT8
*)DigestListBin
+ DigestSize
;
1020 WriteUnaligned32 (DigestListCountPtr
, DigestListCount
);
1026 Add a new entry to the Event Log.
1028 @param[in] DigestList A list of digest.
1029 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
1030 @param[in] NewEventData Pointer to the new event data.
1032 @retval EFI_SUCCESS The new event log entry was added.
1033 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1036 TcgDxeLogHashEvent (
1037 IN TPML_DIGEST_VALUES
*DigestList
,
1038 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
1039 IN UINT8
*NewEventData
1045 EFI_STATUS RetStatus
;
1046 TCG_PCR_EVENT2 TcgPcrEvent2
;
1047 UINT8
*DigestBuffer
;
1048 UINT32
*EventSizePtr
;
1050 DEBUG ((EFI_D_INFO
, "SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
1052 RetStatus
= EFI_SUCCESS
;
1053 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1054 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1055 DEBUG ((EFI_D_INFO
, " LogFormat - 0x%08x\n", mTcg2EventInfo
[Index
].LogFormat
));
1056 switch (mTcg2EventInfo
[Index
].LogFormat
) {
1057 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
:
1058 Status
= GetDigestFromDigestList (TPM_ALG_SHA1
, DigestList
, &NewEventHdr
->Digest
);
1059 if (!EFI_ERROR (Status
)) {
1061 // Enter critical region
1063 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
1064 Status
= TcgDxeLogEvent (
1065 mTcg2EventInfo
[Index
].LogFormat
,
1067 sizeof(TCG_PCR_EVENT_HDR
),
1069 NewEventHdr
->EventSize
1071 if (Status
!= EFI_SUCCESS
) {
1074 gBS
->RestoreTPL (OldTpl
);
1076 // Exit critical region
1080 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
:
1081 ZeroMem (&TcgPcrEvent2
, sizeof(TcgPcrEvent2
));
1082 TcgPcrEvent2
.PCRIndex
= NewEventHdr
->PCRIndex
;
1083 TcgPcrEvent2
.EventType
= NewEventHdr
->EventType
;
1084 DigestBuffer
= (UINT8
*)&TcgPcrEvent2
.Digest
;
1085 EventSizePtr
= CopyDigestListToBuffer (DigestBuffer
, DigestList
, mTcgDxeData
.BsCap
.ActivePcrBanks
);
1086 CopyMem (EventSizePtr
, &NewEventHdr
->EventSize
, sizeof(NewEventHdr
->EventSize
));
1089 // Enter critical region
1091 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
1092 Status
= TcgDxeLogEvent (
1093 mTcg2EventInfo
[Index
].LogFormat
,
1095 sizeof(TcgPcrEvent2
.PCRIndex
) + sizeof(TcgPcrEvent2
.EventType
) + GetDigestListBinSize (DigestBuffer
) + sizeof(TcgPcrEvent2
.EventSize
),
1097 NewEventHdr
->EventSize
1099 if (Status
!= EFI_SUCCESS
) {
1102 gBS
->RestoreTPL (OldTpl
);
1104 // Exit critical region
1115 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
1116 and add an entry to the Event Log.
1118 @param[in] Flags Bitmap providing additional information.
1119 @param[in] HashData Physical address of the start of the data buffer
1120 to be hashed, extended, and logged.
1121 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
1122 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
1123 @param[in] NewEventData Pointer to the new event data.
1125 @retval EFI_SUCCESS Operation completed successfully.
1126 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
1127 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1131 TcgDxeHashLogExtendEvent (
1134 IN UINT64 HashDataLen
,
1135 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
1136 IN UINT8
*NewEventData
1140 TPML_DIGEST_VALUES DigestList
;
1142 if (!mTcgDxeData
.BsCap
.TPMPresentFlag
) {
1143 return EFI_DEVICE_ERROR
;
1146 Status
= HashAndExtend (
1147 NewEventHdr
->PCRIndex
,
1152 if (!EFI_ERROR (Status
)) {
1153 if ((Flags
& EFI_TCG2_EXTEND_ONLY
) == 0) {
1154 Status
= TcgDxeLogHashEvent (&DigestList
, NewEventHdr
, NewEventData
);
1158 if (Status
== EFI_DEVICE_ERROR
) {
1159 DEBUG ((EFI_D_ERROR
, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status
));
1160 mTcgDxeData
.BsCap
.TPMPresentFlag
= FALSE
;
1161 REPORT_STATUS_CODE (
1162 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1163 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
1171 The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with
1172 an opportunity to extend and optionally log events without requiring
1173 knowledge of actual TPM commands.
1174 The extend operation will occur even if this function cannot create an event
1175 log entry (e.g. due to the event log being full).
1177 @param[in] This Indicates the calling context
1178 @param[in] Flags Bitmap providing additional information.
1179 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
1180 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
1181 @param[in] Event Pointer to data buffer containing information about the event.
1183 @retval EFI_SUCCESS Operation completed successfully.
1184 @retval EFI_DEVICE_ERROR The command was unsuccessful.
1185 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
1186 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1187 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
1191 Tcg2HashLogExtendEvent (
1192 IN EFI_TCG2_PROTOCOL
*This
,
1194 IN EFI_PHYSICAL_ADDRESS DataToHash
,
1195 IN UINT64 DataToHashLen
,
1196 IN EFI_TCG2_EVENT
*Event
1200 TCG_PCR_EVENT_HDR NewEventHdr
;
1201 TPML_DIGEST_VALUES DigestList
;
1203 DEBUG ((DEBUG_VERBOSE
, "Tcg2HashLogExtendEvent ...\n"));
1205 if ((This
== NULL
) || (DataToHash
== 0) || (Event
== NULL
)) {
1206 return EFI_INVALID_PARAMETER
;
1209 if (!mTcgDxeData
.BsCap
.TPMPresentFlag
) {
1210 return EFI_DEVICE_ERROR
;
1213 if (Event
->Size
< Event
->Header
.HeaderSize
+ sizeof(UINT32
)) {
1214 return EFI_INVALID_PARAMETER
;
1217 if (Event
->Header
.PCRIndex
> MAX_PCR_INDEX
) {
1218 return EFI_INVALID_PARAMETER
;
1221 NewEventHdr
.PCRIndex
= Event
->Header
.PCRIndex
;
1222 NewEventHdr
.EventType
= Event
->Header
.EventType
;
1223 NewEventHdr
.EventSize
= Event
->Size
- sizeof(UINT32
) - Event
->Header
.HeaderSize
;
1224 if ((Flags
& PE_COFF_IMAGE
) != 0) {
1225 Status
= MeasurePeImageAndExtend (
1226 NewEventHdr
.PCRIndex
,
1228 (UINTN
)DataToHashLen
,
1231 if (!EFI_ERROR (Status
)) {
1232 if ((Flags
& EFI_TCG2_EXTEND_ONLY
) == 0) {
1233 Status
= TcgDxeLogHashEvent (&DigestList
, &NewEventHdr
, Event
->Event
);
1236 if (Status
== EFI_DEVICE_ERROR
) {
1237 DEBUG ((EFI_D_ERROR
, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status
));
1238 mTcgDxeData
.BsCap
.TPMPresentFlag
= FALSE
;
1239 REPORT_STATUS_CODE (
1240 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1241 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
1245 Status
= TcgDxeHashLogExtendEvent (
1247 (UINT8
*) (UINTN
) DataToHash
,
1253 DEBUG ((DEBUG_VERBOSE
, "Tcg2HashLogExtendEvent - %r\n", Status
));
1258 This service enables the sending of commands to the TPM.
1260 @param[in] This Indicates the calling context
1261 @param[in] InputParameterBlockSize Size of the TPM input parameter block.
1262 @param[in] InputParameterBlock Pointer to the TPM input parameter block.
1263 @param[in] OutputParameterBlockSize Size of the TPM output parameter block.
1264 @param[in] OutputParameterBlock Pointer to the TPM output parameter block.
1266 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
1267 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
1268 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1269 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
1274 IN EFI_TCG2_PROTOCOL
*This
,
1275 IN UINT32 InputParameterBlockSize
,
1276 IN UINT8
*InputParameterBlock
,
1277 IN UINT32 OutputParameterBlockSize
,
1278 IN UINT8
*OutputParameterBlock
1283 DEBUG ((EFI_D_INFO
, "Tcg2SubmitCommand ...\n"));
1285 if ((This
== NULL
) ||
1286 (InputParameterBlockSize
== 0) || (InputParameterBlock
== NULL
) ||
1287 (OutputParameterBlockSize
== 0) || (OutputParameterBlock
== NULL
)) {
1288 return EFI_INVALID_PARAMETER
;
1291 if (!mTcgDxeData
.BsCap
.TPMPresentFlag
) {
1292 return EFI_DEVICE_ERROR
;
1295 if (InputParameterBlockSize
> mTcgDxeData
.BsCap
.MaxCommandSize
) {
1296 return EFI_INVALID_PARAMETER
;
1298 if (OutputParameterBlockSize
> mTcgDxeData
.BsCap
.MaxResponseSize
) {
1299 return EFI_INVALID_PARAMETER
;
1302 Status
= Tpm2SubmitCommand (
1303 InputParameterBlockSize
,
1304 InputParameterBlock
,
1305 &OutputParameterBlockSize
,
1306 OutputParameterBlock
1308 DEBUG ((EFI_D_INFO
, "Tcg2SubmitCommand - %r\n", Status
));
1313 This service returns the currently active PCR banks.
1315 @param[in] This Indicates the calling context
1316 @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.
1318 @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.
1319 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1323 Tcg2GetActivePCRBanks (
1324 IN EFI_TCG2_PROTOCOL
*This
,
1325 OUT UINT32
*ActivePcrBanks
1328 if (ActivePcrBanks
== NULL
) {
1329 return EFI_INVALID_PARAMETER
;
1331 *ActivePcrBanks
= mTcgDxeData
.BsCap
.ActivePcrBanks
;
1336 This service sets the currently active PCR banks.
1338 @param[in] This Indicates the calling context
1339 @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.
1341 @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.
1342 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1346 Tcg2SetActivePCRBanks (
1347 IN EFI_TCG2_PROTOCOL
*This
,
1348 IN UINT32 ActivePcrBanks
1354 DEBUG ((EFI_D_INFO
, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks
));
1356 if (ActivePcrBanks
== 0) {
1357 return EFI_INVALID_PARAMETER
;
1359 if ((ActivePcrBanks
& (~mTcgDxeData
.BsCap
.HashAlgorithmBitmap
)) != 0) {
1360 return EFI_INVALID_PARAMETER
;
1362 if (ActivePcrBanks
== mTcgDxeData
.BsCap
.ActivePcrBanks
) {
1364 // Need clear previous SET_PCR_BANKS setting
1366 ReturnCode
= Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION
, 0);
1368 ReturnCode
= Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
, ActivePcrBanks
);
1371 if (ReturnCode
== TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
) {
1372 Status
= EFI_SUCCESS
;
1373 } else if (ReturnCode
== TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
) {
1374 Status
= EFI_OUT_OF_RESOURCES
;
1375 } else if (ReturnCode
== TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
) {
1376 Status
= EFI_UNSUPPORTED
;
1378 Status
= EFI_DEVICE_ERROR
;
1381 DEBUG ((EFI_D_INFO
, "Tcg2SetActivePCRBanks - %r\n", Status
));
1387 This service retrieves the result of a previous invocation of SetActivePcrBanks.
1389 @param[in] This Indicates the calling context
1390 @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.
1391 @param[out] Response The response from the SetActivePcrBank request.
1393 @retval EFI_SUCCESS The result value could be returned.
1394 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
1398 Tcg2GetResultOfSetActivePcrBanks (
1399 IN EFI_TCG2_PROTOCOL
*This
,
1400 OUT UINT32
*OperationPresent
,
1401 OUT UINT32
*Response
1406 if ((OperationPresent
== NULL
) || (Response
== NULL
)) {
1407 return EFI_INVALID_PARAMETER
;
1410 ReturnCode
= Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent
, Response
);
1411 if (ReturnCode
== TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
) {
1414 return EFI_UNSUPPORTED
;
1418 EFI_TCG2_PROTOCOL mTcg2Protocol
= {
1421 Tcg2HashLogExtendEvent
,
1423 Tcg2GetActivePCRBanks
,
1424 Tcg2SetActivePCRBanks
,
1425 Tcg2GetResultOfSetActivePcrBanks
,
1429 Initialize the Event Log and log events passed from the PEI phase.
1431 @retval EFI_SUCCESS Operation completed successfully.
1432 @retval EFI_OUT_OF_RESOURCES Out of memory.
1442 EFI_PEI_HOB_POINTERS GuidHob
;
1443 EFI_PHYSICAL_ADDRESS Lasa
;
1445 VOID
*DigestListBin
;
1446 TPML_DIGEST_VALUES TempDigestListBin
;
1447 UINT32 DigestListBinSize
;
1450 UINT32
*EventSizePtr
;
1451 UINT32 HashAlgorithmMaskCopied
;
1452 TCG_EfiSpecIDEventStruct
*TcgEfiSpecIdEventStruct
;
1453 UINT8 TempBuf
[sizeof(TCG_EfiSpecIDEventStruct
) + sizeof(UINT32
) + (HASH_COUNT
* sizeof(TCG_EfiSpecIdEventAlgorithmSize
)) + sizeof(UINT8
)];
1454 TCG_PCR_EVENT_HDR SpecIdEvent
;
1455 TCG_PCR_EVENT2_HDR NoActionEvent
;
1456 TCG_EfiSpecIdEventAlgorithmSize
*DigestSize
;
1457 TCG_EfiSpecIdEventAlgorithmSize
*TempDigestSize
;
1458 UINT8
*VendorInfoSize
;
1459 UINT32 NumberOfAlgorithms
;
1460 TCG_EfiStartupLocalityEvent StartupLocalityEvent
;
1462 DEBUG ((EFI_D_INFO
, "SetupEventLog\n"));
1465 // 1. Create Log Area
1467 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1468 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1469 mTcgDxeData
.EventLogAreaStruct
[Index
].EventLogFormat
= mTcg2EventInfo
[Index
].LogFormat
;
1470 if (PcdGet8(PcdTpm2AcpiTableRev
) >= 4) {
1471 Status
= gBS
->AllocatePages (
1474 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen
)),
1478 Status
= gBS
->AllocatePages (
1480 EfiBootServicesData
,
1481 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen
)),
1485 if (EFI_ERROR (Status
)) {
1488 mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
= Lasa
;
1489 mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
1491 if ((PcdGet8(PcdTpm2AcpiTableRev
) >= 4) ||
1492 (mTcg2EventInfo
[Index
].LogFormat
== EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
)) {
1494 // Report TCG2 event log address and length, so that they can be reported in TPM2 ACPI table.
1495 // Ignore the return status, because those fields are optional.
1497 PcdSet32S(PcdTpm2AcpiTableLaml
, (UINT32
)mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
);
1498 PcdSet64S(PcdTpm2AcpiTableLasa
, mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
);
1502 // To initialize them as 0xFF is recommended
1503 // because the OS can know the last entry for that.
1505 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcgLogAreaMinLen
), 0xFF);
1507 // Create first entry for Log Header Entry Data
1509 if (mTcg2EventInfo
[Index
].LogFormat
!= EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
) {
1511 // TcgEfiSpecIdEventStruct
1513 TcgEfiSpecIdEventStruct
= (TCG_EfiSpecIDEventStruct
*)TempBuf
;
1514 CopyMem (TcgEfiSpecIdEventStruct
->signature
, TCG_EfiSpecIDEventStruct_SIGNATURE_03
, sizeof(TcgEfiSpecIdEventStruct
->signature
));
1515 TcgEfiSpecIdEventStruct
->platformClass
= PcdGet8 (PcdTpmPlatformClass
);
1516 TcgEfiSpecIdEventStruct
->specVersionMajor
= TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2
;
1517 TcgEfiSpecIdEventStruct
->specVersionMinor
= TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2
;
1518 TcgEfiSpecIdEventStruct
->specErrata
= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2
;
1519 TcgEfiSpecIdEventStruct
->uintnSize
= sizeof(UINTN
)/sizeof(UINT32
);
1520 NumberOfAlgorithms
= 0;
1521 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof(*TcgEfiSpecIdEventStruct
) + sizeof(NumberOfAlgorithms
));
1522 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 0) {
1523 TempDigestSize
= DigestSize
;
1524 TempDigestSize
+= NumberOfAlgorithms
;
1525 TempDigestSize
->algorithmId
= TPM_ALG_SHA1
;
1526 TempDigestSize
->digestSize
= SHA1_DIGEST_SIZE
;
1527 NumberOfAlgorithms
++;
1529 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
1530 TempDigestSize
= DigestSize
;
1531 TempDigestSize
+= NumberOfAlgorithms
;
1532 TempDigestSize
->algorithmId
= TPM_ALG_SHA256
;
1533 TempDigestSize
->digestSize
= SHA256_DIGEST_SIZE
;
1534 NumberOfAlgorithms
++;
1536 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
1537 TempDigestSize
= DigestSize
;
1538 TempDigestSize
+= NumberOfAlgorithms
;
1539 TempDigestSize
->algorithmId
= TPM_ALG_SHA384
;
1540 TempDigestSize
->digestSize
= SHA384_DIGEST_SIZE
;
1541 NumberOfAlgorithms
++;
1543 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
1544 TempDigestSize
= DigestSize
;
1545 TempDigestSize
+= NumberOfAlgorithms
;
1546 TempDigestSize
->algorithmId
= TPM_ALG_SHA512
;
1547 TempDigestSize
->digestSize
= SHA512_DIGEST_SIZE
;
1548 NumberOfAlgorithms
++;
1550 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
1551 TempDigestSize
= DigestSize
;
1552 TempDigestSize
+= NumberOfAlgorithms
;
1553 TempDigestSize
->algorithmId
= TPM_ALG_SM3_256
;
1554 TempDigestSize
->digestSize
= SM3_256_DIGEST_SIZE
;
1555 NumberOfAlgorithms
++;
1557 CopyMem (TcgEfiSpecIdEventStruct
+ 1, &NumberOfAlgorithms
, sizeof(NumberOfAlgorithms
));
1558 TempDigestSize
= DigestSize
;
1559 TempDigestSize
+= NumberOfAlgorithms
;
1560 VendorInfoSize
= (UINT8
*)TempDigestSize
;
1561 *VendorInfoSize
= 0;
1563 SpecIdEvent
.PCRIndex
= 0;
1564 SpecIdEvent
.EventType
= EV_NO_ACTION
;
1565 ZeroMem (&SpecIdEvent
.Digest
, sizeof(SpecIdEvent
.Digest
));
1566 SpecIdEvent
.EventSize
= (UINT32
)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct
);
1569 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.
1570 // TCG EFI Protocol Spec. Section 5.3 Event Log Header
1571 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log
1573 Status
= TcgDxeLogEvent (
1574 mTcg2EventInfo
[Index
].LogFormat
,
1576 sizeof(SpecIdEvent
),
1577 (UINT8
*)TcgEfiSpecIdEventStruct
,
1578 SpecIdEvent
.EventSize
1582 // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2
1584 GuidHob
.Guid
= GetFirstGuidHob (&gTpm2StartupLocalityHobGuid
);
1585 if (GuidHob
.Guid
!= NULL
) {
1587 // Get Locality Indicator from StartupLocality HOB
1589 StartupLocalityEvent
.StartupLocality
= *(UINT8
*)(GET_GUID_HOB_DATA (GuidHob
.Guid
));
1590 CopyMem (StartupLocalityEvent
.Signature
, TCG_EfiStartupLocalityEvent_SIGNATURE
, sizeof(StartupLocalityEvent
.Signature
));
1591 DEBUG ((DEBUG_INFO
, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent
.StartupLocality
));
1594 // Initialize StartupLocalityEvent
1596 InitNoActionEvent(&NoActionEvent
, sizeof(StartupLocalityEvent
));
1599 // Log EfiStartupLocalityEvent as the second Event
1600 // TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event
1602 Status
= TcgDxeLogEvent (
1603 mTcg2EventInfo
[Index
].LogFormat
,
1605 sizeof(NoActionEvent
.PCRIndex
) + sizeof(NoActionEvent
.EventType
) + GetDigestListBinSize (&NoActionEvent
.Digests
) + sizeof(NoActionEvent
.EventSize
),
1606 (UINT8
*)&StartupLocalityEvent
,
1607 sizeof(StartupLocalityEvent
)
1616 // 2. Create Final Log Area
1618 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1619 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1620 if (mTcg2EventInfo
[Index
].LogFormat
== EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
) {
1621 Status
= gBS
->AllocatePages (
1624 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen
)),
1627 if (EFI_ERROR (Status
)) {
1630 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcg2FinalLogAreaLen
), 0xFF);
1635 mTcgDxeData
.FinalEventsTable
[Index
] = (VOID
*)(UINTN
)Lasa
;
1636 (mTcgDxeData
.FinalEventsTable
[Index
])->Version
= EFI_TCG2_FINAL_EVENTS_TABLE_VERSION
;
1637 (mTcgDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
= 0;
1639 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogFormat
= mTcg2EventInfo
[Index
].LogFormat
;
1640 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
= Lasa
+ sizeof(EFI_TCG2_FINAL_EVENTS_TABLE
);
1641 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcg2FinalLogAreaLen
) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE
);
1642 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogSize
= 0;
1643 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].LastEvent
= (VOID
*)(UINTN
)mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
;
1644 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogStarted
= FALSE
;
1645 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogTruncated
= FALSE
;
1648 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
1650 Status
= gBS
->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid
, (VOID
*)mTcgDxeData
.FinalEventsTable
[Index
]);
1651 if (EFI_ERROR (Status
)) {
1656 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
1658 mTcgDxeData
.FinalEventsTable
[Index
] = NULL
;
1659 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogFormat
= mTcg2EventInfo
[Index
].LogFormat
;
1660 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
= 0;
1661 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Laml
= 0;
1662 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogSize
= 0;
1663 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].LastEvent
= 0;
1664 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogStarted
= FALSE
;
1665 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogTruncated
= FALSE
;
1671 // 3. Sync data from PEI to DXE
1673 Status
= EFI_SUCCESS
;
1674 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1675 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1676 GuidHob
.Raw
= GetHobList ();
1677 Status
= EFI_SUCCESS
;
1678 while (!EFI_ERROR (Status
) &&
1679 (GuidHob
.Raw
= GetNextGuidHob (mTcg2EventInfo
[Index
].EventGuid
, GuidHob
.Raw
)) != NULL
) {
1680 TcgEvent
= AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob
.Guid
), GET_GUID_HOB_DATA (GuidHob
.Guid
));
1681 ASSERT (TcgEvent
!= NULL
);
1682 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
1683 switch (mTcg2EventInfo
[Index
].LogFormat
) {
1684 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
:
1685 Status
= TcgDxeLogEvent (
1686 mTcg2EventInfo
[Index
].LogFormat
,
1688 sizeof(TCG_PCR_EVENT_HDR
),
1689 ((TCG_PCR_EVENT
*)TcgEvent
)->Event
,
1690 ((TCG_PCR_EVENT_HDR
*)TcgEvent
)->EventSize
1693 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
:
1694 DigestListBin
= (UINT8
*)TcgEvent
+ sizeof(TCG_PCRINDEX
) + sizeof(TCG_EVENTTYPE
);
1695 DigestListBinSize
= GetDigestListBinSize (DigestListBin
);
1699 CopyMem (&EventSize
, (UINT8
*)DigestListBin
+ DigestListBinSize
, sizeof(UINT32
));
1700 Event
= (UINT8
*)DigestListBin
+ DigestListBinSize
+ sizeof(UINT32
);
1702 // Filter inactive digest in the event2 log from PEI HOB.
1704 CopyMem (&TempDigestListBin
, DigestListBin
, GetDigestListBinSize (DigestListBin
));
1705 EventSizePtr
= CopyDigestListBinToBuffer (
1708 mTcgDxeData
.BsCap
.ActivePcrBanks
,
1709 &HashAlgorithmMaskCopied
1711 if (HashAlgorithmMaskCopied
!= mTcgDxeData
.BsCap
.ActivePcrBanks
) {
1714 "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",
1715 HashAlgorithmMaskCopied
,
1716 mTcgDxeData
.BsCap
.ActivePcrBanks
1720 // Restore event size.
1722 CopyMem (EventSizePtr
, &EventSize
, sizeof(UINT32
));
1723 DigestListBinSize
= GetDigestListBinSize (DigestListBin
);
1725 Status
= TcgDxeLogEvent (
1726 mTcg2EventInfo
[Index
].LogFormat
,
1728 sizeof(TCG_PCRINDEX
) + sizeof(TCG_EVENTTYPE
) + DigestListBinSize
+ sizeof(UINT32
),
1734 FreePool (TcgEvent
);
1743 Measure and log an action string, and extend the measurement result into PCR[PCRIndex].
1745 @param[in] PCRIndex PCRIndex to extend
1746 @param[in] String A specific string that indicates an Action event.
1748 @retval EFI_SUCCESS Operation completed successfully.
1749 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1754 IN TPM_PCRINDEX PCRIndex
,
1758 TCG_PCR_EVENT_HDR TcgEvent
;
1760 TcgEvent
.PCRIndex
= PCRIndex
;
1761 TcgEvent
.EventType
= EV_EFI_ACTION
;
1762 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
1763 return TcgDxeHashLogExtendEvent (
1773 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1775 @retval EFI_SUCCESS Operation completed successfully.
1776 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1780 MeasureHandoffTables (
1785 TCG_PCR_EVENT_HDR TcgEvent
;
1786 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
1788 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
1790 ProcessorLocBuf
= NULL
;
1791 Status
= EFI_SUCCESS
;
1793 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
1796 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1798 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
1800 if (!EFI_ERROR(Status
)){
1801 TcgEvent
.PCRIndex
= 1;
1802 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
1803 TcgEvent
.EventSize
= sizeof (HandoffTables
);
1805 HandoffTables
.NumberOfTables
= 1;
1806 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
1807 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
1809 Status
= TcgDxeHashLogExtendEvent (
1811 (UINT8
*)(UINTN
)ProcessorLocBuf
,
1812 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
1814 (UINT8
*)&HandoffTables
1817 FreePool(ProcessorLocBuf
);
1825 Measure and log Separator event, and extend the measurement result into a specific PCR.
1827 @param[in] PCRIndex PCR index.
1829 @retval EFI_SUCCESS Operation completed successfully.
1830 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1834 MeasureSeparatorEvent (
1835 IN TPM_PCRINDEX PCRIndex
1838 TCG_PCR_EVENT_HDR TcgEvent
;
1841 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex
));
1844 TcgEvent
.PCRIndex
= PCRIndex
;
1845 TcgEvent
.EventType
= EV_SEPARATOR
;
1846 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
1847 return TcgDxeHashLogExtendEvent (
1849 (UINT8
*)&EventData
,
1857 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1859 @param[in] PCRIndex PCR Index.
1860 @param[in] EventType Event type.
1861 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1862 @param[in] VendorGuid A unique identifier for the vendor.
1863 @param[in] VarData The content of the variable data.
1864 @param[in] VarSize The size of the variable data.
1866 @retval EFI_SUCCESS Operation completed successfully.
1867 @retval EFI_OUT_OF_RESOURCES Out of memory.
1868 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1873 IN TPM_PCRINDEX PCRIndex
,
1874 IN TCG_EVENTTYPE EventType
,
1876 IN EFI_GUID
*VendorGuid
,
1882 TCG_PCR_EVENT_HDR TcgEvent
;
1883 UINTN VarNameLength
;
1884 UEFI_VARIABLE_DATA
*VarLog
;
1886 DEBUG ((EFI_D_INFO
, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN
)PCRIndex
, (UINTN
)EventType
));
1887 DEBUG ((EFI_D_INFO
, "VariableName - %s, VendorGuid - %g)\n", VarName
, VendorGuid
));
1889 VarNameLength
= StrLen (VarName
);
1890 TcgEvent
.PCRIndex
= PCRIndex
;
1891 TcgEvent
.EventType
= EventType
;
1893 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
1894 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
1896 VarLog
= (UEFI_VARIABLE_DATA
*)AllocatePool (TcgEvent
.EventSize
);
1897 if (VarLog
== NULL
) {
1898 return EFI_OUT_OF_RESOURCES
;
1901 VarLog
->VariableName
= *VendorGuid
;
1902 VarLog
->UnicodeNameLength
= VarNameLength
;
1903 VarLog
->VariableDataLength
= VarSize
;
1905 VarLog
->UnicodeName
,
1907 VarNameLength
* sizeof (*VarName
)
1909 if (VarSize
!= 0 && VarData
!= NULL
) {
1911 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
1917 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1919 // Digest is the event data (UEFI_VARIABLE_DATA)
1921 Status
= TcgDxeHashLogExtendEvent (
1929 ASSERT (VarData
!= NULL
);
1930 Status
= TcgDxeHashLogExtendEvent (
1943 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1945 @param[in] PCRIndex PCR Index.
1946 @param[in] EventType Event type.
1947 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1948 @param[in] VendorGuid A unique identifier for the vendor.
1949 @param[out] VarSize The size of the variable data.
1950 @param[out] VarData Pointer to the content of the variable.
1952 @retval EFI_SUCCESS Operation completed successfully.
1953 @retval EFI_OUT_OF_RESOURCES Out of memory.
1954 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1958 ReadAndMeasureVariable (
1959 IN TPM_PCRINDEX PCRIndex
,
1960 IN TCG_EVENTTYPE EventType
,
1962 IN EFI_GUID
*VendorGuid
,
1969 Status
= GetVariable2 (VarName
, VendorGuid
, VarData
, VarSize
);
1970 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1971 if (EFI_ERROR (Status
)) {
1973 // It is valid case, so we need handle it.
1980 // if status error, VarData is freed and set NULL by GetVariable2
1982 if (EFI_ERROR (Status
)) {
1983 return EFI_NOT_FOUND
;
1987 Status
= MeasureVariable (
1999 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].
2000 according to TCG PC Client PFP spec 0021 Section 2.4.4.2
2002 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
2003 @param[in] VendorGuid A unique identifier for the vendor.
2004 @param[out] VarSize The size of the variable data.
2005 @param[out] VarData Pointer to the content of the variable.
2007 @retval EFI_SUCCESS Operation completed successfully.
2008 @retval EFI_OUT_OF_RESOURCES Out of memory.
2009 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2013 ReadAndMeasureBootVariable (
2015 IN EFI_GUID
*VendorGuid
,
2020 return ReadAndMeasureVariable (
2022 EV_EFI_VARIABLE_BOOT
,
2031 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
2033 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
2034 @param[in] VendorGuid A unique identifier for the vendor.
2035 @param[out] VarSize The size of the variable data.
2036 @param[out] VarData Pointer to the content of the variable.
2038 @retval EFI_SUCCESS Operation completed successfully.
2039 @retval EFI_OUT_OF_RESOURCES Out of memory.
2040 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2044 ReadAndMeasureSecureVariable (
2046 IN EFI_GUID
*VendorGuid
,
2051 return ReadAndMeasureVariable (
2053 EV_EFI_VARIABLE_DRIVER_CONFIG
,
2062 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
2064 The EFI boot variables are BootOrder and Boot#### variables.
2066 @retval EFI_SUCCESS Operation completed successfully.
2067 @retval EFI_OUT_OF_RESOURCES Out of memory.
2068 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2072 MeasureAllBootVariables (
2083 Status
= ReadAndMeasureBootVariable (
2085 &gEfiGlobalVariableGuid
,
2087 (VOID
**) &BootOrder
2089 if (Status
== EFI_NOT_FOUND
|| BootOrder
== NULL
) {
2093 if (EFI_ERROR (Status
)) {
2095 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
2097 FreePool (BootOrder
);
2101 BootCount
/= sizeof (*BootOrder
);
2102 for (Index
= 0; Index
< BootCount
; Index
++) {
2103 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
2104 Status
= ReadAndMeasureBootVariable (
2106 &gEfiGlobalVariableGuid
,
2110 if (!EFI_ERROR (Status
)) {
2111 FreePool (BootVarData
);
2115 FreePool (BootOrder
);
2120 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
2122 The EFI boot variables are BootOrder and Boot#### variables.
2124 @retval EFI_SUCCESS Operation completed successfully.
2125 @retval EFI_OUT_OF_RESOURCES Out of memory.
2126 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2130 MeasureAllSecureVariables (
2139 Status
= EFI_NOT_FOUND
;
2140 for (Index
= 0; Index
< sizeof(mVariableType
)/sizeof(mVariableType
[0]); Index
++) {
2141 Status
= ReadAndMeasureSecureVariable (
2142 mVariableType
[Index
].VariableName
,
2143 mVariableType
[Index
].VendorGuid
,
2147 if (!EFI_ERROR (Status
)) {
2155 // Measure DBT if present and not empty
2157 Status
= GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2
, &gEfiImageSecurityDatabaseGuid
, &Data
, &DataSize
);
2158 if (!EFI_ERROR(Status
)) {
2159 Status
= MeasureVariable (
2161 EV_EFI_VARIABLE_DRIVER_CONFIG
,
2162 EFI_IMAGE_SECURITY_DATABASE2
,
2163 &gEfiImageSecurityDatabaseGuid
,
2169 DEBUG((DEBUG_INFO
, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2
));
2176 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
2178 @retval EFI_SUCCESS Operation completed successfully.
2179 @retval EFI_OUT_OF_RESOURCES Out of memory.
2180 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2184 MeasureLaunchOfFirmwareDebugger (
2188 TCG_PCR_EVENT_HDR TcgEvent
;
2190 TcgEvent
.PCRIndex
= 7;
2191 TcgEvent
.EventType
= EV_EFI_ACTION
;
2192 TcgEvent
.EventSize
= sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1;
2193 return TcgDxeHashLogExtendEvent (
2195 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
,
2196 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1,
2198 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
2203 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
2205 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
2206 - The contents of the SecureBoot variable
2207 - The contents of the PK variable
2208 - The contents of the KEK variable
2209 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
2210 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
2212 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
2214 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
2215 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
2217 @param[in] Event Event whose notification function is being invoked
2218 @param[in] Context Pointer to the notification function's context
2222 MeasureSecureBootPolicy (
2230 Status
= gBS
->LocateProtocol (&gEfiVariableWriteArchProtocolGuid
, NULL
, (VOID
**)&Protocol
);
2231 if (EFI_ERROR (Status
)) {
2235 if (PcdGetBool (PcdFirmwareDebuggerInitialized
)) {
2236 Status
= MeasureLaunchOfFirmwareDebugger ();
2237 DEBUG ((EFI_D_INFO
, "MeasureLaunchOfFirmwareDebugger - %r\n", Status
));
2240 Status
= MeasureAllSecureVariables ();
2241 DEBUG ((EFI_D_INFO
, "MeasureAllSecureVariables - %r\n", Status
));
2244 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
2245 // and ImageVerification (Authority)
2246 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
2247 // the Authority measurement happen before ReadToBoot event.
2249 Status
= MeasureSeparatorEvent (7);
2250 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent - %r\n", Status
));
2255 Ready to Boot Event notification handler.
2257 Sequence of OS boot events is measured in this event notification handler.
2259 @param[in] Event Event whose notification function is being invoked
2260 @param[in] Context Pointer to the notification function's context
2271 TPM_PCRINDEX PcrIndex
;
2273 PERF_START_EX (mImageHandle
, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE
);
2274 if (mBootAttempts
== 0) {
2277 // Measure handoff tables.
2279 Status
= MeasureHandoffTables ();
2280 if (EFI_ERROR (Status
)) {
2281 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
2285 // Measure BootOrder & Boot#### variables.
2287 Status
= MeasureAllBootVariables ();
2288 if (EFI_ERROR (Status
)) {
2289 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
2293 // 1. This is the first boot attempt.
2295 Status
= TcgMeasureAction (
2297 EFI_CALLING_EFI_APPLICATION
2299 if (EFI_ERROR (Status
)) {
2300 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
2304 // 2. Draw a line between pre-boot env and entering post-boot env.
2305 // PCR[7] is already done.
2307 for (PcrIndex
= 0; PcrIndex
< 7; PcrIndex
++) {
2308 Status
= MeasureSeparatorEvent (PcrIndex
);
2309 if (EFI_ERROR (Status
)) {
2310 DEBUG ((DEBUG_ERROR
, "Separator Event not Measured. Error!\n"));
2315 // 3. Measure GPT. It would be done in SAP driver.
2319 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
2323 // 5. Read & Measure variable. BootOrder already measured.
2327 // 6. Not first attempt, meaning a return from last attempt
2329 Status
= TcgMeasureAction (
2331 EFI_RETURNING_FROM_EFI_APPLICATION
2333 if (EFI_ERROR (Status
)) {
2334 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION
));
2338 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
2339 // TCG PC Client PFP spec Section 2.4.4.5 Step 4
2341 Status
= TcgMeasureAction (
2343 EFI_CALLING_EFI_APPLICATION
2345 if (EFI_ERROR (Status
)) {
2346 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
2350 DEBUG ((EFI_D_INFO
, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));
2352 // Increase boot attempt counter.
2355 PERF_END_EX (mImageHandle
, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE
+ 1);
2359 Exit Boot Services Event notification handler.
2361 Measure invocation and success of ExitBootServices.
2363 @param[in] Event Event whose notification function is being invoked
2364 @param[in] Context Pointer to the notification function's context
2369 OnExitBootServices (
2377 // Measure invocation of ExitBootServices,
2379 Status
= TcgMeasureAction (
2381 EFI_EXIT_BOOT_SERVICES_INVOCATION
2383 if (EFI_ERROR (Status
)) {
2384 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION
));
2388 // Measure success of ExitBootServices
2390 Status
= TcgMeasureAction (
2392 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
2394 if (EFI_ERROR (Status
)) {
2395 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED
));
2400 Exit Boot Services Failed Event notification handler.
2402 Measure Failure of ExitBootServices.
2404 @param[in] Event Event whose notification function is being invoked
2405 @param[in] Context Pointer to the notification function's context
2410 OnExitBootServicesFailed (
2418 // Measure Failure of ExitBootServices,
2420 Status
= TcgMeasureAction (
2422 EFI_EXIT_BOOT_SERVICES_FAILED
2424 if (EFI_ERROR (Status
)) {
2425 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED
));
2431 This routine is called to properly shutdown the TPM before system reset.
2432 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
2433 Part 1: Architecture, Revision 01.16.
2435 @param[in] ResetType The type of reset to perform.
2436 @param[in] ResetStatus The status code for the reset.
2437 @param[in] DataSize The size, in bytes, of ResetData.
2438 @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
2439 EfiResetShutdown the data buffer starts with a Null-terminated
2440 string, optionally followed by additional binary data.
2441 The string is a description that the caller may use to further
2442 indicate the reason for the system reset.
2443 For a ResetType of EfiResetPlatformSpecific the data buffer
2444 also starts with a Null-terminated string that is followed
2445 by an EFI_GUID that describes the specific type of reset to perform.
2449 ShutdownTpmOnReset (
2450 IN EFI_RESET_TYPE ResetType
,
2451 IN EFI_STATUS ResetStatus
,
2453 IN VOID
*ResetData OPTIONAL
2457 Status
= Tpm2Shutdown (TPM_SU_CLEAR
);
2458 DEBUG ((DEBUG_VERBOSE
, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status
));
2462 Hook the system reset to properly shutdown TPM.
2463 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
2464 Part 1: Architecture, Revision 01.16.
2466 @param[in] Event Event whose notification function is being invoked
2467 @param[in] Context Pointer to the notification function's context
2471 OnResetNotificationInstall (
2477 EFI_RESET_NOTIFICATION_PROTOCOL
*ResetNotify
;
2479 Status
= gBS
->LocateProtocol (&gEfiResetNotificationProtocolGuid
, NULL
, (VOID
**) &ResetNotify
);
2480 if (!EFI_ERROR (Status
)) {
2481 Status
= ResetNotify
->RegisterResetNotify (ResetNotify
, ShutdownTpmOnReset
);
2482 ASSERT_EFI_ERROR (Status
);
2483 DEBUG ((DEBUG_VERBOSE
, "TCG2: Hook system reset to properly shutdown TPM.\n"));
2485 gBS
->CloseEvent (Event
);
2490 The function install Tcg2 protocol.
2492 @retval EFI_SUCCESS Tcg2 protocol is installed.
2493 @retval other Some error occurs.
2504 Status
= gBS
->InstallMultipleProtocolInterfaces (
2506 &gEfiTcg2ProtocolGuid
,
2514 The driver's entry point. It publishes EFI Tcg2 Protocol.
2516 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2517 @param[in] SystemTable A pointer to the EFI System Table.
2519 @retval EFI_SUCCESS The entry point is executed successfully.
2520 @retval other Some error occurs when executing this entry point.
2525 IN EFI_HANDLE ImageHandle
,
2526 IN EFI_SYSTEM_TABLE
*SystemTable
2532 UINT32 MaxCommandSize
;
2533 UINT32 MaxResponseSize
;
2535 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap
;
2536 UINT32 ActivePCRBanks
;
2537 UINT32 NumberOfPCRBanks
;
2539 mImageHandle
= ImageHandle
;
2541 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceNoneGuid
) ||
2542 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
2543 DEBUG ((DEBUG_INFO
, "No TPM2 instance required!\n"));
2544 return EFI_UNSUPPORTED
;
2547 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
2548 DEBUG ((EFI_D_ERROR
, "TPM2 error!\n"));
2549 return EFI_DEVICE_ERROR
;
2552 Status
= Tpm2RequestUseTpm ();
2553 if (EFI_ERROR (Status
)) {
2554 DEBUG ((EFI_D_ERROR
, "TPM2 not detected!\n"));
2561 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX
== sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]));
2563 mTcgDxeData
.BsCap
.Size
= sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY
);
2564 mTcgDxeData
.BsCap
.ProtocolVersion
.Major
= 1;
2565 mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
= 1;
2566 mTcgDxeData
.BsCap
.StructureVersion
.Major
= 1;
2567 mTcgDxeData
.BsCap
.StructureVersion
.Minor
= 1;
2569 DEBUG ((EFI_D_INFO
, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.ProtocolVersion
.Major
, mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
));
2570 DEBUG ((EFI_D_INFO
, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.StructureVersion
.Major
, mTcgDxeData
.BsCap
.StructureVersion
.Minor
));
2572 Status
= Tpm2GetCapabilityManufactureID (&mTcgDxeData
.BsCap
.ManufacturerID
);
2573 if (EFI_ERROR (Status
)) {
2574 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityManufactureID fail!\n"));
2576 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData
.BsCap
.ManufacturerID
));
2580 UINT32 FirmwareVersion1
;
2581 UINT32 FirmwareVersion2
;
2583 Status
= Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1
, &FirmwareVersion2
);
2584 if (EFI_ERROR (Status
)) {
2585 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
2587 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1
, FirmwareVersion2
));
2591 Status
= Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize
, &MaxResponseSize
);
2592 if (EFI_ERROR (Status
)) {
2593 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
2595 mTcgDxeData
.BsCap
.MaxCommandSize
= (UINT16
)MaxCommandSize
;
2596 mTcgDxeData
.BsCap
.MaxResponseSize
= (UINT16
)MaxResponseSize
;
2597 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize
, MaxResponseSize
));
2601 // Get supported PCR and current Active PCRs
2603 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePCRBanks
);
2604 ASSERT_EFI_ERROR (Status
);
2606 mTcgDxeData
.BsCap
.HashAlgorithmBitmap
= TpmHashAlgorithmBitmap
& PcdGet32 (PcdTcg2HashAlgorithmBitmap
);
2607 mTcgDxeData
.BsCap
.ActivePcrBanks
= ActivePCRBanks
& PcdGet32 (PcdTcg2HashAlgorithmBitmap
);
2610 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.
2612 NumberOfPCRBanks
= 0;
2613 for (Index
= 0; Index
< 32; Index
++) {
2614 if ((mTcgDxeData
.BsCap
.HashAlgorithmBitmap
& (1u << Index
)) != 0) {
2619 if (PcdGet32 (PcdTcg2NumberOfPCRBanks
) == 0) {
2620 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= NumberOfPCRBanks
;
2622 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= PcdGet32 (PcdTcg2NumberOfPCRBanks
);
2623 if (PcdGet32 (PcdTcg2NumberOfPCRBanks
) > NumberOfPCRBanks
) {
2624 DEBUG ((EFI_D_ERROR
, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks
), NumberOfPCRBanks
));
2625 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= NumberOfPCRBanks
;
2629 mTcgDxeData
.BsCap
.SupportedEventLogs
= EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
| EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
;
2630 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) == 0) {
2632 // No need to expose TCG1.2 event log if SHA1 bank does not exist.
2634 mTcgDxeData
.BsCap
.SupportedEventLogs
&= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
;
2637 DEBUG ((EFI_D_INFO
, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
2638 DEBUG ((EFI_D_INFO
, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData
.BsCap
.HashAlgorithmBitmap
));
2639 DEBUG ((EFI_D_INFO
, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData
.BsCap
.NumberOfPCRBanks
));
2640 DEBUG ((EFI_D_INFO
, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData
.BsCap
.ActivePcrBanks
));
2642 if (mTcgDxeData
.BsCap
.TPMPresentFlag
) {
2644 // Setup the log area and copy event log from hob list to it
2646 Status
= SetupEventLog ();
2647 ASSERT_EFI_ERROR (Status
);
2650 // Measure handoff tables, Boot#### variables etc.
2652 Status
= EfiCreateEventReadyToBootEx (
2659 Status
= gBS
->CreateEventEx (
2664 &gEfiEventExitBootServicesGuid
,
2669 // Measure Exit Boot Service failed
2671 Status
= gBS
->CreateEventEx (
2674 OnExitBootServicesFailed
,
2676 &gEventExitBootServicesFailedGuid
,
2681 // Create event callback, because we need access variable on SecureBootPolicyVariable
2682 // We should use VariableWriteArch instead of VariableArch, because Variable driver
2683 // may update SecureBoot value based on last setting.
2685 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid
, TPL_CALLBACK
, MeasureSecureBootPolicy
, NULL
, &Registration
);
2688 // Hook the system reset to properly shutdown TPM.
2690 EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid
, TPL_CALLBACK
, OnResetNotificationInstall
, NULL
, &Registration
);
2694 // Install Tcg2Protocol
2696 Status
= InstallTcg2 ();
2697 DEBUG ((EFI_D_INFO
, "InstallTcg2 - %r\n", Status
));