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 Digeest 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 Status
= gBS
->AllocatePages (
1472 EfiBootServicesData
,
1473 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen
)),
1476 if (EFI_ERROR (Status
)) {
1479 mTcgDxeData
.EventLogAreaStruct
[Index
].Lasa
= Lasa
;
1480 mTcgDxeData
.EventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcgLogAreaMinLen
);
1482 // To initialize them as 0xFF is recommended
1483 // because the OS can know the last entry for that.
1485 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcgLogAreaMinLen
), 0xFF);
1487 // Create first entry for Log Header Entry Data
1489 if (mTcg2EventInfo
[Index
].LogFormat
!= EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
) {
1491 // TcgEfiSpecIdEventStruct
1493 TcgEfiSpecIdEventStruct
= (TCG_EfiSpecIDEventStruct
*)TempBuf
;
1494 CopyMem (TcgEfiSpecIdEventStruct
->signature
, TCG_EfiSpecIDEventStruct_SIGNATURE_03
, sizeof(TcgEfiSpecIdEventStruct
->signature
));
1495 TcgEfiSpecIdEventStruct
->platformClass
= PcdGet8 (PcdTpmPlatformClass
);
1496 TcgEfiSpecIdEventStruct
->specVersionMajor
= TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2
;
1497 TcgEfiSpecIdEventStruct
->specVersionMinor
= TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2
;
1498 TcgEfiSpecIdEventStruct
->specErrata
= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2
;
1499 TcgEfiSpecIdEventStruct
->uintnSize
= sizeof(UINTN
)/sizeof(UINT32
);
1500 NumberOfAlgorithms
= 0;
1501 DigestSize
= (TCG_EfiSpecIdEventAlgorithmSize
*)((UINT8
*)TcgEfiSpecIdEventStruct
+ sizeof(*TcgEfiSpecIdEventStruct
) + sizeof(NumberOfAlgorithms
));
1502 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 0) {
1503 TempDigestSize
= DigestSize
;
1504 TempDigestSize
+= NumberOfAlgorithms
;
1505 TempDigestSize
->algorithmId
= TPM_ALG_SHA1
;
1506 TempDigestSize
->digestSize
= SHA1_DIGEST_SIZE
;
1507 NumberOfAlgorithms
++;
1509 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
1510 TempDigestSize
= DigestSize
;
1511 TempDigestSize
+= NumberOfAlgorithms
;
1512 TempDigestSize
->algorithmId
= TPM_ALG_SHA256
;
1513 TempDigestSize
->digestSize
= SHA256_DIGEST_SIZE
;
1514 NumberOfAlgorithms
++;
1516 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
1517 TempDigestSize
= DigestSize
;
1518 TempDigestSize
+= NumberOfAlgorithms
;
1519 TempDigestSize
->algorithmId
= TPM_ALG_SHA384
;
1520 TempDigestSize
->digestSize
= SHA384_DIGEST_SIZE
;
1521 NumberOfAlgorithms
++;
1523 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
1524 TempDigestSize
= DigestSize
;
1525 TempDigestSize
+= NumberOfAlgorithms
;
1526 TempDigestSize
->algorithmId
= TPM_ALG_SHA512
;
1527 TempDigestSize
->digestSize
= SHA512_DIGEST_SIZE
;
1528 NumberOfAlgorithms
++;
1530 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
1531 TempDigestSize
= DigestSize
;
1532 TempDigestSize
+= NumberOfAlgorithms
;
1533 TempDigestSize
->algorithmId
= TPM_ALG_SM3_256
;
1534 TempDigestSize
->digestSize
= SM3_256_DIGEST_SIZE
;
1535 NumberOfAlgorithms
++;
1537 CopyMem (TcgEfiSpecIdEventStruct
+ 1, &NumberOfAlgorithms
, sizeof(NumberOfAlgorithms
));
1538 TempDigestSize
= DigestSize
;
1539 TempDigestSize
+= NumberOfAlgorithms
;
1540 VendorInfoSize
= (UINT8
*)TempDigestSize
;
1541 *VendorInfoSize
= 0;
1543 SpecIdEvent
.PCRIndex
= 0;
1544 SpecIdEvent
.EventType
= EV_NO_ACTION
;
1545 ZeroMem (&SpecIdEvent
.Digest
, sizeof(SpecIdEvent
.Digest
));
1546 SpecIdEvent
.EventSize
= (UINT32
)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct
);
1549 // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.
1550 // TCG EFI Protocol Spec. Section 5.3 Event Log Header
1551 // TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log
1553 Status
= TcgDxeLogEvent (
1554 mTcg2EventInfo
[Index
].LogFormat
,
1556 sizeof(SpecIdEvent
),
1557 (UINT8
*)TcgEfiSpecIdEventStruct
,
1558 SpecIdEvent
.EventSize
1562 // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2
1564 GuidHob
.Guid
= GetFirstGuidHob (&gTpm2StartupLocalityHobGuid
);
1565 if (GuidHob
.Guid
!= NULL
) {
1567 // Get Locality Indicator from StartupLocality HOB
1569 StartupLocalityEvent
.StartupLocality
= *(UINT8
*)(GET_GUID_HOB_DATA (GuidHob
.Guid
));
1570 CopyMem (StartupLocalityEvent
.Signature
, TCG_EfiStartupLocalityEvent_SIGNATURE
, sizeof(StartupLocalityEvent
.Signature
));
1571 DEBUG ((DEBUG_INFO
, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent
.StartupLocality
));
1574 // Initialize StartupLocalityEvent
1576 InitNoActionEvent(&NoActionEvent
, sizeof(StartupLocalityEvent
));
1579 // Log EfiStartupLocalityEvent as the second Event
1580 // TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event
1582 Status
= TcgDxeLogEvent (
1583 mTcg2EventInfo
[Index
].LogFormat
,
1585 sizeof(NoActionEvent
.PCRIndex
) + sizeof(NoActionEvent
.EventType
) + GetDigestListBinSize (&NoActionEvent
.Digests
) + sizeof(NoActionEvent
.EventSize
),
1586 (UINT8
*)&StartupLocalityEvent
,
1587 sizeof(StartupLocalityEvent
)
1596 // 2. Create Final Log Area
1598 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1599 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1600 if (mTcg2EventInfo
[Index
].LogFormat
== EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
) {
1601 Status
= gBS
->AllocatePages (
1604 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen
)),
1607 if (EFI_ERROR (Status
)) {
1610 SetMem ((VOID
*)(UINTN
)Lasa
, PcdGet32 (PcdTcg2FinalLogAreaLen
), 0xFF);
1615 mTcgDxeData
.FinalEventsTable
[Index
] = (VOID
*)(UINTN
)Lasa
;
1616 (mTcgDxeData
.FinalEventsTable
[Index
])->Version
= EFI_TCG2_FINAL_EVENTS_TABLE_VERSION
;
1617 (mTcgDxeData
.FinalEventsTable
[Index
])->NumberOfEvents
= 0;
1619 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogFormat
= mTcg2EventInfo
[Index
].LogFormat
;
1620 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
= Lasa
+ sizeof(EFI_TCG2_FINAL_EVENTS_TABLE
);
1621 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Laml
= PcdGet32 (PcdTcg2FinalLogAreaLen
) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE
);
1622 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogSize
= 0;
1623 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].LastEvent
= (VOID
*)(UINTN
)mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
;
1624 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogStarted
= FALSE
;
1625 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogTruncated
= FALSE
;
1628 // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
1630 Status
= gBS
->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid
, (VOID
*)mTcgDxeData
.FinalEventsTable
[Index
]);
1631 if (EFI_ERROR (Status
)) {
1636 // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
1638 mTcgDxeData
.FinalEventsTable
[Index
] = NULL
;
1639 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogFormat
= mTcg2EventInfo
[Index
].LogFormat
;
1640 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Lasa
= 0;
1641 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].Laml
= 0;
1642 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogSize
= 0;
1643 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].LastEvent
= 0;
1644 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogStarted
= FALSE
;
1645 mTcgDxeData
.FinalEventLogAreaStruct
[Index
].EventLogTruncated
= FALSE
;
1651 // 3. Sync data from PEI to DXE
1653 Status
= EFI_SUCCESS
;
1654 for (Index
= 0; Index
< sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]); Index
++) {
1655 if ((mTcgDxeData
.BsCap
.SupportedEventLogs
& mTcg2EventInfo
[Index
].LogFormat
) != 0) {
1656 GuidHob
.Raw
= GetHobList ();
1657 Status
= EFI_SUCCESS
;
1658 while (!EFI_ERROR (Status
) &&
1659 (GuidHob
.Raw
= GetNextGuidHob (mTcg2EventInfo
[Index
].EventGuid
, GuidHob
.Raw
)) != NULL
) {
1660 TcgEvent
= AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob
.Guid
), GET_GUID_HOB_DATA (GuidHob
.Guid
));
1661 ASSERT (TcgEvent
!= NULL
);
1662 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
1663 switch (mTcg2EventInfo
[Index
].LogFormat
) {
1664 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
:
1665 Status
= TcgDxeLogEvent (
1666 mTcg2EventInfo
[Index
].LogFormat
,
1668 sizeof(TCG_PCR_EVENT_HDR
),
1669 ((TCG_PCR_EVENT
*)TcgEvent
)->Event
,
1670 ((TCG_PCR_EVENT_HDR
*)TcgEvent
)->EventSize
1673 case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
:
1674 DigestListBin
= (UINT8
*)TcgEvent
+ sizeof(TCG_PCRINDEX
) + sizeof(TCG_EVENTTYPE
);
1675 DigestListBinSize
= GetDigestListBinSize (DigestListBin
);
1679 CopyMem (&EventSize
, (UINT8
*)DigestListBin
+ DigestListBinSize
, sizeof(UINT32
));
1680 Event
= (UINT8
*)DigestListBin
+ DigestListBinSize
+ sizeof(UINT32
);
1682 // Filter inactive digest in the event2 log from PEI HOB.
1684 CopyMem (&TempDigestListBin
, DigestListBin
, GetDigestListBinSize (DigestListBin
));
1685 EventSizePtr
= CopyDigestListBinToBuffer (
1688 mTcgDxeData
.BsCap
.ActivePcrBanks
,
1689 &HashAlgorithmMaskCopied
1691 if (HashAlgorithmMaskCopied
!= mTcgDxeData
.BsCap
.ActivePcrBanks
) {
1694 "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",
1695 HashAlgorithmMaskCopied
,
1696 mTcgDxeData
.BsCap
.ActivePcrBanks
1700 // Restore event size.
1702 CopyMem (EventSizePtr
, &EventSize
, sizeof(UINT32
));
1703 DigestListBinSize
= GetDigestListBinSize (DigestListBin
);
1705 Status
= TcgDxeLogEvent (
1706 mTcg2EventInfo
[Index
].LogFormat
,
1708 sizeof(TCG_PCRINDEX
) + sizeof(TCG_EVENTTYPE
) + DigestListBinSize
+ sizeof(UINT32
),
1714 FreePool (TcgEvent
);
1723 Measure and log an action string, and extend the measurement result into PCR[PCRIndex].
1725 @param[in] PCRIndex PCRIndex to extend
1726 @param[in] String A specific string that indicates an Action event.
1728 @retval EFI_SUCCESS Operation completed successfully.
1729 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1734 IN TPM_PCRINDEX PCRIndex
,
1738 TCG_PCR_EVENT_HDR TcgEvent
;
1740 TcgEvent
.PCRIndex
= PCRIndex
;
1741 TcgEvent
.EventType
= EV_EFI_ACTION
;
1742 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
1743 return TcgDxeHashLogExtendEvent (
1753 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1755 @retval EFI_SUCCESS Operation completed successfully.
1756 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1760 MeasureHandoffTables (
1765 TCG_PCR_EVENT_HDR TcgEvent
;
1766 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
1768 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
1770 ProcessorLocBuf
= NULL
;
1771 Status
= EFI_SUCCESS
;
1773 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
1776 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1778 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
1780 if (!EFI_ERROR(Status
)){
1781 TcgEvent
.PCRIndex
= 1;
1782 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
1783 TcgEvent
.EventSize
= sizeof (HandoffTables
);
1785 HandoffTables
.NumberOfTables
= 1;
1786 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
1787 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
1789 Status
= TcgDxeHashLogExtendEvent (
1791 (UINT8
*)(UINTN
)ProcessorLocBuf
,
1792 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
1794 (UINT8
*)&HandoffTables
1797 FreePool(ProcessorLocBuf
);
1805 Measure and log Separator event, and extend the measurement result into a specific PCR.
1807 @param[in] PCRIndex PCR index.
1809 @retval EFI_SUCCESS Operation completed successfully.
1810 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1814 MeasureSeparatorEvent (
1815 IN TPM_PCRINDEX PCRIndex
1818 TCG_PCR_EVENT_HDR TcgEvent
;
1821 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex
));
1824 TcgEvent
.PCRIndex
= PCRIndex
;
1825 TcgEvent
.EventType
= EV_SEPARATOR
;
1826 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
1827 return TcgDxeHashLogExtendEvent (
1829 (UINT8
*)&EventData
,
1837 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1839 @param[in] PCRIndex PCR Index.
1840 @param[in] EventType Event type.
1841 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1842 @param[in] VendorGuid A unique identifier for the vendor.
1843 @param[in] VarData The content of the variable data.
1844 @param[in] VarSize The size of the variable data.
1846 @retval EFI_SUCCESS Operation completed successfully.
1847 @retval EFI_OUT_OF_RESOURCES Out of memory.
1848 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1853 IN TPM_PCRINDEX PCRIndex
,
1854 IN TCG_EVENTTYPE EventType
,
1856 IN EFI_GUID
*VendorGuid
,
1862 TCG_PCR_EVENT_HDR TcgEvent
;
1863 UINTN VarNameLength
;
1864 UEFI_VARIABLE_DATA
*VarLog
;
1866 DEBUG ((EFI_D_INFO
, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN
)PCRIndex
, (UINTN
)EventType
));
1867 DEBUG ((EFI_D_INFO
, "VariableName - %s, VendorGuid - %g)\n", VarName
, VendorGuid
));
1869 VarNameLength
= StrLen (VarName
);
1870 TcgEvent
.PCRIndex
= PCRIndex
;
1871 TcgEvent
.EventType
= EventType
;
1873 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
1874 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
1876 VarLog
= (UEFI_VARIABLE_DATA
*)AllocatePool (TcgEvent
.EventSize
);
1877 if (VarLog
== NULL
) {
1878 return EFI_OUT_OF_RESOURCES
;
1881 VarLog
->VariableName
= *VendorGuid
;
1882 VarLog
->UnicodeNameLength
= VarNameLength
;
1883 VarLog
->VariableDataLength
= VarSize
;
1885 VarLog
->UnicodeName
,
1887 VarNameLength
* sizeof (*VarName
)
1889 if (VarSize
!= 0 && VarData
!= NULL
) {
1891 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
1897 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1899 // Digest is the event data (UEFI_VARIABLE_DATA)
1901 Status
= TcgDxeHashLogExtendEvent (
1909 ASSERT (VarData
!= NULL
);
1910 Status
= TcgDxeHashLogExtendEvent (
1923 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1925 @param[in] PCRIndex PCR Index.
1926 @param[in] EventType Event type.
1927 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1928 @param[in] VendorGuid A unique identifier for the vendor.
1929 @param[out] VarSize The size of the variable data.
1930 @param[out] VarData Pointer to the content of the variable.
1932 @retval EFI_SUCCESS Operation completed successfully.
1933 @retval EFI_OUT_OF_RESOURCES Out of memory.
1934 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1938 ReadAndMeasureVariable (
1939 IN TPM_PCRINDEX PCRIndex
,
1940 IN TCG_EVENTTYPE EventType
,
1942 IN EFI_GUID
*VendorGuid
,
1949 Status
= GetVariable2 (VarName
, VendorGuid
, VarData
, VarSize
);
1950 if (EventType
== EV_EFI_VARIABLE_DRIVER_CONFIG
) {
1951 if (EFI_ERROR (Status
)) {
1953 // It is valid case, so we need handle it.
1960 // if status error, VarData is freed and set NULL by GetVariable2
1962 if (EFI_ERROR (Status
)) {
1963 return EFI_NOT_FOUND
;
1967 Status
= MeasureVariable (
1979 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].
1980 according to TCG PC Client PFP spec 0021 Section 2.4.4.2
1982 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1983 @param[in] VendorGuid A unique identifier for the vendor.
1984 @param[out] VarSize The size of the variable data.
1985 @param[out] VarData Pointer to the content of the variable.
1987 @retval EFI_SUCCESS Operation completed successfully.
1988 @retval EFI_OUT_OF_RESOURCES Out of memory.
1989 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1993 ReadAndMeasureBootVariable (
1995 IN EFI_GUID
*VendorGuid
,
2000 return ReadAndMeasureVariable (
2002 EV_EFI_VARIABLE_BOOT
,
2011 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
2013 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
2014 @param[in] VendorGuid A unique identifier for the vendor.
2015 @param[out] VarSize The size of the variable data.
2016 @param[out] VarData Pointer to the content of the variable.
2018 @retval EFI_SUCCESS Operation completed successfully.
2019 @retval EFI_OUT_OF_RESOURCES Out of memory.
2020 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2024 ReadAndMeasureSecureVariable (
2026 IN EFI_GUID
*VendorGuid
,
2031 return ReadAndMeasureVariable (
2033 EV_EFI_VARIABLE_DRIVER_CONFIG
,
2042 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
2044 The EFI boot variables are BootOrder and Boot#### variables.
2046 @retval EFI_SUCCESS Operation completed successfully.
2047 @retval EFI_OUT_OF_RESOURCES Out of memory.
2048 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2052 MeasureAllBootVariables (
2063 Status
= ReadAndMeasureBootVariable (
2065 &gEfiGlobalVariableGuid
,
2067 (VOID
**) &BootOrder
2069 if (Status
== EFI_NOT_FOUND
|| BootOrder
== NULL
) {
2073 if (EFI_ERROR (Status
)) {
2075 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
2077 FreePool (BootOrder
);
2081 BootCount
/= sizeof (*BootOrder
);
2082 for (Index
= 0; Index
< BootCount
; Index
++) {
2083 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
2084 Status
= ReadAndMeasureBootVariable (
2086 &gEfiGlobalVariableGuid
,
2090 if (!EFI_ERROR (Status
)) {
2091 FreePool (BootVarData
);
2095 FreePool (BootOrder
);
2100 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
2102 The EFI boot variables are BootOrder and Boot#### variables.
2104 @retval EFI_SUCCESS Operation completed successfully.
2105 @retval EFI_OUT_OF_RESOURCES Out of memory.
2106 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2110 MeasureAllSecureVariables (
2119 Status
= EFI_NOT_FOUND
;
2120 for (Index
= 0; Index
< sizeof(mVariableType
)/sizeof(mVariableType
[0]); Index
++) {
2121 Status
= ReadAndMeasureSecureVariable (
2122 mVariableType
[Index
].VariableName
,
2123 mVariableType
[Index
].VendorGuid
,
2127 if (!EFI_ERROR (Status
)) {
2135 // Measure DBT if present and not empty
2137 Status
= GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2
, &gEfiImageSecurityDatabaseGuid
, &Data
, &DataSize
);
2138 if (!EFI_ERROR(Status
)) {
2139 Status
= MeasureVariable (
2141 EV_EFI_VARIABLE_DRIVER_CONFIG
,
2142 EFI_IMAGE_SECURITY_DATABASE2
,
2143 &gEfiImageSecurityDatabaseGuid
,
2149 DEBUG((DEBUG_INFO
, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2
));
2156 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
2158 @retval EFI_SUCCESS Operation completed successfully.
2159 @retval EFI_OUT_OF_RESOURCES Out of memory.
2160 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
2164 MeasureLaunchOfFirmwareDebugger (
2168 TCG_PCR_EVENT_HDR TcgEvent
;
2170 TcgEvent
.PCRIndex
= 7;
2171 TcgEvent
.EventType
= EV_EFI_ACTION
;
2172 TcgEvent
.EventSize
= sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1;
2173 return TcgDxeHashLogExtendEvent (
2175 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
,
2176 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING
) - 1,
2178 (UINT8
*)FIRMWARE_DEBUGGER_EVENT_STRING
2183 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
2185 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
2186 - The contents of the SecureBoot variable
2187 - The contents of the PK variable
2188 - The contents of the KEK variable
2189 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
2190 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
2192 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
2194 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
2195 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
2197 @param[in] Event Event whose notification function is being invoked
2198 @param[in] Context Pointer to the notification function's context
2202 MeasureSecureBootPolicy (
2210 Status
= gBS
->LocateProtocol (&gEfiVariableWriteArchProtocolGuid
, NULL
, (VOID
**)&Protocol
);
2211 if (EFI_ERROR (Status
)) {
2215 if (PcdGetBool (PcdFirmwareDebuggerInitialized
)) {
2216 Status
= MeasureLaunchOfFirmwareDebugger ();
2217 DEBUG ((EFI_D_INFO
, "MeasureLaunchOfFirmwareDebugger - %r\n", Status
));
2220 Status
= MeasureAllSecureVariables ();
2221 DEBUG ((EFI_D_INFO
, "MeasureAllSecureVariables - %r\n", Status
));
2224 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
2225 // and ImageVerification (Authority)
2226 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
2227 // the Authority measurement happen before ReadToBoot event.
2229 Status
= MeasureSeparatorEvent (7);
2230 DEBUG ((EFI_D_INFO
, "MeasureSeparatorEvent - %r\n", Status
));
2235 Ready to Boot Event notification handler.
2237 Sequence of OS boot events is measured in this event notification handler.
2239 @param[in] Event Event whose notification function is being invoked
2240 @param[in] Context Pointer to the notification function's context
2251 TPM_PCRINDEX PcrIndex
;
2253 PERF_START_EX (mImageHandle
, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE
);
2254 if (mBootAttempts
== 0) {
2257 // Measure handoff tables.
2259 Status
= MeasureHandoffTables ();
2260 if (EFI_ERROR (Status
)) {
2261 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
2265 // Measure BootOrder & Boot#### variables.
2267 Status
= MeasureAllBootVariables ();
2268 if (EFI_ERROR (Status
)) {
2269 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
2273 // 1. This is the first boot attempt.
2275 Status
= TcgMeasureAction (
2277 EFI_CALLING_EFI_APPLICATION
2279 if (EFI_ERROR (Status
)) {
2280 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
2284 // 2. Draw a line between pre-boot env and entering post-boot env.
2285 // PCR[7] is already done.
2287 for (PcrIndex
= 0; PcrIndex
< 7; PcrIndex
++) {
2288 Status
= MeasureSeparatorEvent (PcrIndex
);
2289 if (EFI_ERROR (Status
)) {
2290 DEBUG ((DEBUG_ERROR
, "Separator Event not Measured. Error!\n"));
2295 // 3. Measure GPT. It would be done in SAP driver.
2299 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
2303 // 5. Read & Measure variable. BootOrder already measured.
2307 // 6. Not first attempt, meaning a return from last attempt
2309 Status
= TcgMeasureAction (
2311 EFI_RETURNING_FROM_EFI_APPLICATION
2313 if (EFI_ERROR (Status
)) {
2314 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION
));
2318 // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
2319 // TCG PC Client PFP spec Section 2.4.4.5 Step 4
2321 Status
= TcgMeasureAction (
2323 EFI_CALLING_EFI_APPLICATION
2325 if (EFI_ERROR (Status
)) {
2326 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
2330 DEBUG ((EFI_D_INFO
, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));
2332 // Increase boot attempt counter.
2335 PERF_END_EX (mImageHandle
, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE
+ 1);
2339 Exit Boot Services Event notification handler.
2341 Measure invocation and success of ExitBootServices.
2343 @param[in] Event Event whose notification function is being invoked
2344 @param[in] Context Pointer to the notification function's context
2349 OnExitBootServices (
2357 // Measure invocation of ExitBootServices,
2359 Status
= TcgMeasureAction (
2361 EFI_EXIT_BOOT_SERVICES_INVOCATION
2363 if (EFI_ERROR (Status
)) {
2364 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION
));
2368 // Measure success of ExitBootServices
2370 Status
= TcgMeasureAction (
2372 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
2374 if (EFI_ERROR (Status
)) {
2375 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED
));
2380 Exit Boot Services Failed Event notification handler.
2382 Measure Failure of ExitBootServices.
2384 @param[in] Event Event whose notification function is being invoked
2385 @param[in] Context Pointer to the notification function's context
2390 OnExitBootServicesFailed (
2398 // Measure Failure of ExitBootServices,
2400 Status
= TcgMeasureAction (
2402 EFI_EXIT_BOOT_SERVICES_FAILED
2404 if (EFI_ERROR (Status
)) {
2405 DEBUG ((EFI_D_ERROR
, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED
));
2411 This routine is called to properly shutdown the TPM before system reset.
2412 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
2413 Part 1: Architecture, Revision 01.16.
2415 @param[in] ResetType The type of reset to perform.
2416 @param[in] ResetStatus The status code for the reset.
2417 @param[in] DataSize The size, in bytes, of ResetData.
2418 @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
2419 EfiResetShutdown the data buffer starts with a Null-terminated
2420 string, optionally followed by additional binary data.
2421 The string is a description that the caller may use to further
2422 indicate the reason for the system reset.
2423 For a ResetType of EfiResetPlatformSpecific the data buffer
2424 also starts with a Null-terminated string that is followed
2425 by an EFI_GUID that describes the specific type of reset to perform.
2429 ShutdownTpmOnReset (
2430 IN EFI_RESET_TYPE ResetType
,
2431 IN EFI_STATUS ResetStatus
,
2433 IN VOID
*ResetData OPTIONAL
2437 Status
= Tpm2Shutdown (TPM_SU_CLEAR
);
2438 DEBUG ((DEBUG_VERBOSE
, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status
));
2442 Hook the system reset to properly shutdown TPM.
2443 It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library
2444 Part 1: Architecture, Revision 01.16.
2446 @param[in] Event Event whose notification function is being invoked
2447 @param[in] Context Pointer to the notification function's context
2451 OnResetNotificationInstall (
2457 EFI_RESET_NOTIFICATION_PROTOCOL
*ResetNotify
;
2459 Status
= gBS
->LocateProtocol (&gEfiResetNotificationProtocolGuid
, NULL
, (VOID
**) &ResetNotify
);
2460 if (!EFI_ERROR (Status
)) {
2461 Status
= ResetNotify
->RegisterResetNotify (ResetNotify
, ShutdownTpmOnReset
);
2462 ASSERT_EFI_ERROR (Status
);
2463 DEBUG ((DEBUG_VERBOSE
, "TCG2: Hook system reset to properly shutdown TPM.\n"));
2465 gBS
->CloseEvent (Event
);
2470 The function install Tcg2 protocol.
2472 @retval EFI_SUCCESS Tcg2 protocol is installed.
2473 @retval other Some error occurs.
2484 Status
= gBS
->InstallMultipleProtocolInterfaces (
2486 &gEfiTcg2ProtocolGuid
,
2494 The driver's entry point. It publishes EFI Tcg2 Protocol.
2496 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2497 @param[in] SystemTable A pointer to the EFI System Table.
2499 @retval EFI_SUCCESS The entry point is executed successfully.
2500 @retval other Some error occurs when executing this entry point.
2505 IN EFI_HANDLE ImageHandle
,
2506 IN EFI_SYSTEM_TABLE
*SystemTable
2512 UINT32 MaxCommandSize
;
2513 UINT32 MaxResponseSize
;
2515 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap
;
2516 UINT32 ActivePCRBanks
;
2517 UINT32 NumberOfPCRBanks
;
2519 mImageHandle
= ImageHandle
;
2521 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceNoneGuid
) ||
2522 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
2523 DEBUG ((DEBUG_INFO
, "No TPM2 instance required!\n"));
2524 return EFI_UNSUPPORTED
;
2527 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
2528 DEBUG ((EFI_D_ERROR
, "TPM2 error!\n"));
2529 return EFI_DEVICE_ERROR
;
2532 Status
= Tpm2RequestUseTpm ();
2533 if (EFI_ERROR (Status
)) {
2534 DEBUG ((EFI_D_ERROR
, "TPM2 not detected!\n"));
2541 ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX
== sizeof(mTcg2EventInfo
)/sizeof(mTcg2EventInfo
[0]));
2543 mTcgDxeData
.BsCap
.Size
= sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY
);
2544 mTcgDxeData
.BsCap
.ProtocolVersion
.Major
= 1;
2545 mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
= 1;
2546 mTcgDxeData
.BsCap
.StructureVersion
.Major
= 1;
2547 mTcgDxeData
.BsCap
.StructureVersion
.Minor
= 1;
2549 DEBUG ((EFI_D_INFO
, "Tcg2.ProtocolVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.ProtocolVersion
.Major
, mTcgDxeData
.BsCap
.ProtocolVersion
.Minor
));
2550 DEBUG ((EFI_D_INFO
, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData
.BsCap
.StructureVersion
.Major
, mTcgDxeData
.BsCap
.StructureVersion
.Minor
));
2552 Status
= Tpm2GetCapabilityManufactureID (&mTcgDxeData
.BsCap
.ManufacturerID
);
2553 if (EFI_ERROR (Status
)) {
2554 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityManufactureID fail!\n"));
2556 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData
.BsCap
.ManufacturerID
));
2560 UINT32 FirmwareVersion1
;
2561 UINT32 FirmwareVersion2
;
2563 Status
= Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1
, &FirmwareVersion2
);
2564 if (EFI_ERROR (Status
)) {
2565 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
2567 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1
, FirmwareVersion2
));
2571 Status
= Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize
, &MaxResponseSize
);
2572 if (EFI_ERROR (Status
)) {
2573 DEBUG ((EFI_D_ERROR
, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
2575 mTcgDxeData
.BsCap
.MaxCommandSize
= (UINT16
)MaxCommandSize
;
2576 mTcgDxeData
.BsCap
.MaxResponseSize
= (UINT16
)MaxResponseSize
;
2577 DEBUG ((EFI_D_INFO
, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize
, MaxResponseSize
));
2581 // Get supported PCR and current Active PCRs
2583 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePCRBanks
);
2584 ASSERT_EFI_ERROR (Status
);
2586 mTcgDxeData
.BsCap
.HashAlgorithmBitmap
= TpmHashAlgorithmBitmap
& PcdGet32 (PcdTcg2HashAlgorithmBitmap
);
2587 mTcgDxeData
.BsCap
.ActivePcrBanks
= ActivePCRBanks
& PcdGet32 (PcdTcg2HashAlgorithmBitmap
);
2590 // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.
2592 NumberOfPCRBanks
= 0;
2593 for (Index
= 0; Index
< 32; Index
++) {
2594 if ((mTcgDxeData
.BsCap
.HashAlgorithmBitmap
& (1u << Index
)) != 0) {
2599 if (PcdGet32 (PcdTcg2NumberOfPCRBanks
) == 0) {
2600 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= NumberOfPCRBanks
;
2602 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= PcdGet32 (PcdTcg2NumberOfPCRBanks
);
2603 if (PcdGet32 (PcdTcg2NumberOfPCRBanks
) > NumberOfPCRBanks
) {
2604 DEBUG ((EFI_D_ERROR
, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks
), NumberOfPCRBanks
));
2605 mTcgDxeData
.BsCap
.NumberOfPCRBanks
= NumberOfPCRBanks
;
2609 mTcgDxeData
.BsCap
.SupportedEventLogs
= EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
| EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
;
2610 if ((mTcgDxeData
.BsCap
.ActivePcrBanks
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) == 0) {
2612 // No need to expose TCG1.2 event log if SHA1 bank does not exist.
2614 mTcgDxeData
.BsCap
.SupportedEventLogs
&= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
;
2617 DEBUG ((EFI_D_INFO
, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData
.BsCap
.SupportedEventLogs
));
2618 DEBUG ((EFI_D_INFO
, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData
.BsCap
.HashAlgorithmBitmap
));
2619 DEBUG ((EFI_D_INFO
, "Tcg2.NumberOfPCRBanks - 0x%08x\n", mTcgDxeData
.BsCap
.NumberOfPCRBanks
));
2620 DEBUG ((EFI_D_INFO
, "Tcg2.ActivePcrBanks - 0x%08x\n", mTcgDxeData
.BsCap
.ActivePcrBanks
));
2622 if (mTcgDxeData
.BsCap
.TPMPresentFlag
) {
2624 // Setup the log area and copy event log from hob list to it
2626 Status
= SetupEventLog ();
2627 ASSERT_EFI_ERROR (Status
);
2630 // Measure handoff tables, Boot#### variables etc.
2632 Status
= EfiCreateEventReadyToBootEx (
2639 Status
= gBS
->CreateEventEx (
2644 &gEfiEventExitBootServicesGuid
,
2649 // Measure Exit Boot Service failed
2651 Status
= gBS
->CreateEventEx (
2654 OnExitBootServicesFailed
,
2656 &gEventExitBootServicesFailedGuid
,
2661 // Create event callback, because we need access variable on SecureBootPolicyVariable
2662 // We should use VariableWriteArch instead of VariableArch, because Variable driver
2663 // may update SecureBoot value based on last setting.
2665 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid
, TPL_CALLBACK
, MeasureSecureBootPolicy
, NULL
, &Registration
);
2668 // Hook the system reset to properly shutdown TPM.
2670 EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid
, TPL_CALLBACK
, OnResetNotificationInstall
, NULL
, &Registration
);
2674 // Install Tcg2Protocol
2676 Status
= InstallTcg2 ();
2677 DEBUG ((EFI_D_INFO
, "InstallTcg2 - %r\n", Status
));