2 This module implements TCG EFI Protocol.
4 Caution: This module requires additional review when modified.
5 This driver will have external input - TcgDxePassThroughToTpm
6 This external input must be validated carefully to avoid security issue like
7 buffer overflow, integer overflow.
9 TcgDxePassThroughToTpm() will receive untrusted input and do basic validation.
11 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
12 This program and the accompanying materials
13 are licensed and made available under the terms and conditions of the BSD License
14 which accompanies this distribution. The full text of the license may be found at
15 http://opensource.org/licenses/bsd-license.php
17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 #include <IndustryStandard/Tpm12.h>
24 #include <IndustryStandard/Acpi.h>
25 #include <IndustryStandard/PeImage.h>
26 #include <IndustryStandard/SmBios.h>
27 #include <IndustryStandard/TcpaAcpi.h>
29 #include <Guid/GlobalVariable.h>
30 #include <Guid/SmBios.h>
31 #include <Guid/HobList.h>
32 #include <Guid/TcgEventHob.h>
33 #include <Guid/EventGroup.h>
34 #include <Guid/EventExitBootServiceFailed.h>
35 #include <Guid/TpmInstance.h>
37 #include <Protocol/DevicePath.h>
38 #include <Protocol/TcgService.h>
39 #include <Protocol/AcpiTable.h>
40 #include <Protocol/MpService.h>
42 #include <Library/DebugLib.h>
43 #include <Library/BaseMemoryLib.h>
44 #include <Library/UefiRuntimeServicesTableLib.h>
45 #include <Library/UefiDriverEntryPoint.h>
46 #include <Library/HobLib.h>
47 #include <Library/UefiBootServicesTableLib.h>
48 #include <Library/BaseLib.h>
49 #include <Library/MemoryAllocationLib.h>
50 #include <Library/PrintLib.h>
51 #include <Library/TpmCommLib.h>
52 #include <Library/PcdLib.h>
53 #include <Library/UefiLib.h>
54 #include <Library/ReportStatusCodeLib.h>
58 #define EFI_TCG_LOG_AREA_SIZE 0x10000
60 #define TCG_DXE_DATA_FROM_THIS(this) \
61 BASE_CR (this, TCG_DXE_DATA, TcgProtocol)
63 typedef struct _TCG_DXE_DATA
{
64 EFI_TCG_PROTOCOL TcgProtocol
;
65 TCG_EFI_BOOT_SERVICE_CAPABILITY BsCap
;
66 EFI_TCG_CLIENT_ACPI_TABLE
*TcgClientAcpiTable
;
67 EFI_TCG_SERVER_ACPI_TABLE
*TcgServerAcpiTable
;
70 TIS_TPM_HANDLE TpmHandle
;
75 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate
= {
77 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
78 sizeof (mTcgClientAcpiTemplate
),
81 // Compiler initializes the remaining bytes to 0
82 // These fields should be filled in in production
85 0, // 0 for PC Client Platform Class
86 0, // Log Area Max Length
87 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1) // Log Area Start Address
91 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,
92 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,
93 // this _UID can be changed and should match with the _UID setting of the TPM
96 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate
= {
98 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
99 sizeof (mTcgServerAcpiTemplate
),
102 // Compiler initializes the remaining bytes to 0
103 // These fields should be filled in in production
106 1, // 1 for Server Platform Class
108 0, // Log Area Max Length
109 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1), // Log Area Start Address
110 0x0100, // TCG Specification revision 1.0
112 0, // Interrupt Flags
114 {0}, // Reserved 3 bytes
115 0, // Global System Interrupt
117 EFI_ACPI_3_0_SYSTEM_MEMORY
,
121 TPM_BASE_ADDRESS
// Base Address
124 {0}, // Configuration Address
125 0xFF, // ACPI _UID value of the device, can be changed for different platforms
126 0, // ACPI _UID value of the device, can be changed for different platforms
127 0, // ACPI _UID value of the device, can be changed for different platforms
128 0 // ACPI _UID value of the device, can be changed for different platforms
131 UINTN mBootAttempts
= 0;
132 CHAR16 mBootVarName
[] = L
"BootOrder";
135 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
136 Caller is responsible to free LocationBuf.
138 @param[out] LocationBuf Returns Processor Location Buffer.
139 @param[out] Num Returns processor number.
141 @retval EFI_SUCCESS Operation completed successfully.
142 @retval EFI_UNSUPPORTED MpService protocol not found.
146 GetProcessorsCpuLocation (
147 OUT EFI_CPU_PHYSICAL_LOCATION
**LocationBuf
,
152 EFI_MP_SERVICES_PROTOCOL
*MpProtocol
;
154 UINTN EnabledProcessorNum
;
155 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
156 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
159 Status
= gBS
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**) &MpProtocol
);
160 if (EFI_ERROR (Status
)) {
162 // MP protocol is not installed
164 return EFI_UNSUPPORTED
;
167 Status
= MpProtocol
->GetNumberOfProcessors(
172 if (EFI_ERROR(Status
)){
176 Status
= gBS
->AllocatePool(
178 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
179 (VOID
**) &ProcessorLocBuf
181 if (EFI_ERROR(Status
)){
186 // Get each processor Location info
188 for (Index
= 0; Index
< ProcessorNum
; Index
++) {
189 Status
= MpProtocol
->GetProcessorInfo(
194 if (EFI_ERROR(Status
)){
195 FreePool(ProcessorLocBuf
);
200 // Get all Processor Location info & measure
203 &ProcessorLocBuf
[Index
],
204 &ProcessorInfo
.Location
,
205 sizeof(EFI_CPU_PHYSICAL_LOCATION
)
209 *LocationBuf
= ProcessorLocBuf
;
216 This service provides EFI protocol capability information, state information
217 about the TPM, and Event Log state information.
219 @param[in] This Indicates the calling context
220 @param[out] ProtocolCapability The callee allocates memory for a TCG_BOOT_SERVICE_CAPABILITY
221 structure and fills in the fields with the EFI protocol
222 capability information and the current TPM state information.
223 @param[out] TCGFeatureFlags This is a pointer to the feature flags. No feature
224 flags are currently defined so this parameter
225 MUST be set to 0. However, in the future,
226 feature flags may be defined that, for example,
227 enable hash algorithm agility.
228 @param[out] EventLogLocation This is a pointer to the address of the event log in memory.
229 @param[out] EventLogLastEntry If the Event Log contains more than one entry,
230 this is a pointer to the address of the start of
231 the last entry in the event log in memory.
233 @retval EFI_SUCCESS Operation completed successfully.
234 @retval EFI_INVALID_PARAMETER ProtocolCapability does not match TCG capability.
240 IN EFI_TCG_PROTOCOL
*This
,
241 OUT TCG_EFI_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
,
242 OUT UINT32
*TCGFeatureFlags
,
243 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
244 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
247 TCG_DXE_DATA
*TcgData
;
249 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
251 if (ProtocolCapability
!= NULL
) {
252 *ProtocolCapability
= TcgData
->BsCap
;
255 if (TCGFeatureFlags
!= NULL
) {
256 *TCGFeatureFlags
= 0;
259 if (EventLogLocation
!= NULL
) {
260 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
261 *EventLogLocation
= TcgData
->TcgClientAcpiTable
->Lasa
;
263 *EventLogLocation
= TcgData
->TcgServerAcpiTable
->Lasa
;
267 if (EventLogLastEntry
!= NULL
) {
268 if (TcgData
->BsCap
.TPMDeactivatedFlag
|| (!TcgData
->BsCap
.TPMPresentFlag
)) {
269 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
271 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)TcgData
->LastEvent
;
279 This service abstracts the capability to do a hash operation on a data buffer.
281 @param[in] This Indicates the calling context
282 @param[in] HashData Pointer to the data buffer to be hashed
283 @param[in] HashDataLen Length of the data buffer to be hashed
284 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation
285 @param[in, out] HashedDataLen Resultant length of the hashed data
286 @param[in, out] HashedDataResult Resultant buffer of the hashed data
288 @retval EFI_SUCCESS Operation completed successfully.
289 @retval EFI_INVALID_PARAMETER HashDataLen is NULL.
290 @retval EFI_INVALID_PARAMETER HashDataLenResult is NULL.
291 @retval EFI_OUT_OF_RESOURCES Cannot allocate buffer of size *HashedDataLen.
292 @retval EFI_UNSUPPORTED AlgorithmId not supported.
293 @retval EFI_BUFFER_TOO_SMALL *HashedDataLen < sizeof (TCG_DIGEST).
299 IN EFI_TCG_PROTOCOL
*This
,
301 IN UINT64 HashDataLen
,
302 IN TCG_ALGORITHM_ID AlgorithmId
,
303 IN OUT UINT64
*HashedDataLen
,
304 IN OUT UINT8
**HashedDataResult
307 if (HashedDataLen
== NULL
|| HashedDataResult
== NULL
) {
308 return EFI_INVALID_PARAMETER
;
311 switch (AlgorithmId
) {
313 if (*HashedDataLen
== 0) {
314 *HashedDataLen
= sizeof (TPM_DIGEST
);
315 *HashedDataResult
= AllocatePool ((UINTN
) *HashedDataLen
);
316 if (*HashedDataResult
== NULL
) {
317 return EFI_OUT_OF_RESOURCES
;
321 if (*HashedDataLen
< sizeof (TPM_DIGEST
)) {
322 *HashedDataLen
= sizeof (TPM_DIGEST
);
323 return EFI_BUFFER_TOO_SMALL
;
325 *HashedDataLen
= sizeof (TPM_DIGEST
);
327 if (*HashedDataResult
== NULL
) {
328 *HashedDataResult
= AllocatePool ((UINTN
) *HashedDataLen
);
331 return TpmCommHashAll (
334 (TPM_DIGEST
*)*HashedDataResult
337 return EFI_UNSUPPORTED
;
342 Add a new entry to the Event Log.
344 @param[in] TcgData TCG_DXE_DATA structure.
345 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
346 @param[in] NewEventData Pointer to the new event data.
348 @retval EFI_SUCCESS The new event log entry was added.
349 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
355 IN TCG_DXE_DATA
*TcgData
,
356 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
357 IN UINT8
*NewEventData
360 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
361 TcgData
->LastEvent
= (UINT8
*)(UINTN
)TcgData
->TcgClientAcpiTable
->Lasa
;
362 return TpmCommLogEvent (
364 &TcgData
->EventLogSize
,
365 (UINTN
)TcgData
->TcgClientAcpiTable
->Laml
,
370 TcgData
->LastEvent
= (UINT8
*)(UINTN
)TcgData
->TcgServerAcpiTable
->Lasa
;
371 return TpmCommLogEvent (
373 &TcgData
->EventLogSize
,
374 (UINTN
)TcgData
->TcgServerAcpiTable
->Laml
,
382 This service abstracts the capability to add an entry to the Event Log.
384 @param[in] This Indicates the calling context
385 @param[in] TCGLogData Pointer to the start of the data buffer containing
386 the TCG_PCR_EVENT data structure. All fields in
387 this structure are properly filled by the caller.
388 @param[in, out] EventNumber The event number of the event just logged
389 @param[in] Flags Indicate additional flags. Only one flag has been
390 defined at this time, which is 0x01 and means the
391 extend operation should not be performed. All
392 other bits are reserved.
394 @retval EFI_SUCCESS Operation completed successfully.
395 @retval EFI_OUT_OF_RESOURCES Insufficient memory in the event log to complete this action.
401 IN EFI_TCG_PROTOCOL
*This
,
402 IN TCG_PCR_EVENT
*TCGLogData
,
403 IN OUT UINT32
*EventNumber
,
407 TCG_DXE_DATA
*TcgData
;
409 if (TCGLogData
== NULL
){
410 return EFI_INVALID_PARAMETER
;
413 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
415 if (TcgData
->BsCap
.TPMDeactivatedFlag
|| (!TcgData
->BsCap
.TPMPresentFlag
)) {
416 return EFI_DEVICE_ERROR
;
418 return TcgDxeLogEventI (
420 (TCG_PCR_EVENT_HDR
*)TCGLogData
,
426 This service is a proxy for commands to the TPM.
428 @param[in] This Indicates the calling context
429 @param[in] TpmInputParameterBlockSize Size of the TPM input parameter block
430 @param[in] TpmInputParameterBlock Pointer to the TPM input parameter block
431 @param[in] TpmOutputParameterBlockSize Size of the TPM output parameter block
432 @param[in] TpmOutputParameterBlock Pointer to the TPM output parameter block
434 @retval EFI_SUCCESS Operation completed successfully.
435 @retval EFI_INVALID_PARAMETER Invalid ordinal.
436 @retval EFI_UNSUPPORTED Current Task Priority Level >= EFI_TPL_CALLBACK.
437 @retval EFI_TIMEOUT The TIS timed-out.
442 TcgDxePassThroughToTpm (
443 IN EFI_TCG_PROTOCOL
*This
,
444 IN UINT32 TpmInputParameterBlockSize
,
445 IN UINT8
*TpmInputParameterBlock
,
446 IN UINT32 TpmOutputParameterBlockSize
,
447 IN UINT8
*TpmOutputParameterBlock
450 TCG_DXE_DATA
*TcgData
;
452 if (TpmInputParameterBlock
== NULL
||
453 TpmOutputParameterBlock
== NULL
||
454 TpmInputParameterBlockSize
== 0 ||
455 TpmOutputParameterBlockSize
== 0) {
456 return EFI_INVALID_PARAMETER
;
459 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
461 return TisPcExecute (
464 TpmInputParameterBlock
,
465 (UINTN
) TpmInputParameterBlockSize
,
466 TpmOutputParameterBlock
,
467 (UINTN
) TpmOutputParameterBlockSize
472 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
473 and add an entry to the Event Log.
475 @param[in] TcgData TCG_DXE_DATA structure.
476 @param[in] HashData Physical address of the start of the data buffer
477 to be hashed, extended, and logged.
478 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
479 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
480 @param[in] NewEventData Pointer to the new event data.
482 @retval EFI_SUCCESS Operation completed successfully.
483 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
484 @retval EFI_DEVICE_ERROR The command was unsuccessful.
489 TcgDxeHashLogExtendEventI (
490 IN TCG_DXE_DATA
*TcgData
,
492 IN UINT64 HashDataLen
,
493 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
494 IN UINT8
*NewEventData
499 if (!TcgData
->BsCap
.TPMPresentFlag
) {
500 return EFI_DEVICE_ERROR
;
503 if (HashDataLen
> 0 || HashData
!= NULL
) {
504 Status
= TpmCommHashAll (
509 if (EFI_ERROR(Status
)) {
510 DEBUG ((DEBUG_ERROR
, "TpmCommHashAll Failed. %x\n", Status
));
515 Status
= TpmCommExtend (
517 &NewEventHdr
->Digest
,
518 NewEventHdr
->PCRIndex
,
521 if (!EFI_ERROR (Status
)) {
522 Status
= TcgDxeLogEventI (TcgData
, NewEventHdr
, NewEventData
);
526 if ((Status
== EFI_DEVICE_ERROR
) || (Status
== EFI_TIMEOUT
)) {
527 DEBUG ((EFI_D_ERROR
, "TcgDxeHashLogExtendEventI - %r. Disable TPM.\n", Status
));
528 TcgData
->BsCap
.TPMPresentFlag
= FALSE
;
530 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
531 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
533 Status
= EFI_DEVICE_ERROR
;
540 This service abstracts the capability to do a hash operation on a data buffer,
541 extend a specific TPM PCR with the hash result, and add an entry to the Event Log
543 @param[in] This Indicates the calling context
544 @param[in] HashData Physical address of the start of the data buffer
545 to be hashed, extended, and logged.
546 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
547 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation
548 @param[in, out] TCGLogData The physical address of the start of the data
549 buffer containing the TCG_PCR_EVENT data structure.
550 @param[in, out] EventNumber The event number of the event just logged.
551 @param[out] EventLogLastEntry Physical address of the first byte of the entry
552 just placed in the Event Log. If the Event Log was
553 empty when this function was called then this physical
554 address will be the same as the physical address of
555 the start of the Event Log.
557 @retval EFI_SUCCESS Operation completed successfully.
558 @retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA.
559 @retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK.
560 @retval EFI_DEVICE_ERROR The command was unsuccessful.
565 TcgDxeHashLogExtendEvent (
566 IN EFI_TCG_PROTOCOL
*This
,
567 IN EFI_PHYSICAL_ADDRESS HashData
,
568 IN UINT64 HashDataLen
,
569 IN TPM_ALGORITHM_ID AlgorithmId
,
570 IN OUT TCG_PCR_EVENT
*TCGLogData
,
571 IN OUT UINT32
*EventNumber
,
572 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
575 TCG_DXE_DATA
*TcgData
;
578 if (TCGLogData
== NULL
|| EventLogLastEntry
== NULL
){
579 return EFI_INVALID_PARAMETER
;
582 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
584 if (TcgData
->BsCap
.TPMDeactivatedFlag
|| (!TcgData
->BsCap
.TPMPresentFlag
)) {
585 return EFI_DEVICE_ERROR
;
588 if (AlgorithmId
!= TPM_ALG_SHA
) {
589 return EFI_UNSUPPORTED
;
592 if (HashData
== 0 && HashDataLen
> 0) {
593 return EFI_INVALID_PARAMETER
;
596 Status
= TcgDxeHashLogExtendEventI (
598 (UINT8
*) (UINTN
) HashData
,
600 (TCG_PCR_EVENT_HDR
*)TCGLogData
,
604 if (!EFI_ERROR(Status
)){
605 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) TcgData
->LastEvent
;
611 TCG_DXE_DATA mTcgDxeData
= {
616 TcgDxePassThroughToTpm
,
617 TcgDxeHashLogExtendEvent
620 sizeof (mTcgDxeData
.BsCap
),
627 &mTcgClientAcpiTemplate
,
628 &mTcgServerAcpiTemplate
,
635 Initialize the Event Log and log events passed from the PEI phase.
637 @retval EFI_SUCCESS Operation completed successfully.
638 @retval EFI_OUT_OF_RESOURCES Out of memory.
648 TCG_PCR_EVENT
*TcgEvent
;
649 EFI_PEI_HOB_POINTERS GuidHob
;
650 EFI_PHYSICAL_ADDRESS Lasa
;
652 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
653 Lasa
= mTcgClientAcpiTemplate
.Lasa
;
655 Status
= gBS
->AllocatePages (
658 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE
),
661 if (EFI_ERROR (Status
)) {
664 mTcgClientAcpiTemplate
.Lasa
= Lasa
;
666 // To initialize them as 0xFF is recommended
667 // because the OS can know the last entry for that.
669 SetMem ((VOID
*)(UINTN
)mTcgClientAcpiTemplate
.Lasa
, EFI_TCG_LOG_AREA_SIZE
, 0xFF);
670 mTcgClientAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
673 Lasa
= mTcgServerAcpiTemplate
.Lasa
;
675 Status
= gBS
->AllocatePages (
678 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE
),
681 if (EFI_ERROR (Status
)) {
684 mTcgServerAcpiTemplate
.Lasa
= Lasa
;
686 // To initialize them as 0xFF is recommended
687 // because the OS can know the last entry for that.
689 SetMem ((VOID
*)(UINTN
)mTcgServerAcpiTemplate
.Lasa
, EFI_TCG_LOG_AREA_SIZE
, 0xFF);
690 mTcgServerAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
693 GuidHob
.Raw
= GetHobList ();
694 while (!EFI_ERROR (Status
) &&
695 (GuidHob
.Raw
= GetNextGuidHob (&gTcgEventEntryHobGuid
, GuidHob
.Raw
)) != NULL
) {
696 TcgEvent
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
697 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
698 Status
= TcgDxeLogEventI (
700 (TCG_PCR_EVENT_HDR
*)TcgEvent
,
709 Measure and log an action string, and extend the measurement result into PCR[5].
711 @param[in] String A specific string that indicates an Action event.
713 @retval EFI_SUCCESS Operation completed successfully.
714 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
723 TCG_PCR_EVENT_HDR TcgEvent
;
725 TcgEvent
.PCRIndex
= 5;
726 TcgEvent
.EventType
= EV_EFI_ACTION
;
727 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
728 return TcgDxeHashLogExtendEventI (
738 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
740 @retval EFI_SUCCESS Operation completed successfully.
741 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
746 MeasureHandoffTables (
751 SMBIOS_TABLE_ENTRY_POINT
*SmbiosTable
;
752 TCG_PCR_EVENT_HDR TcgEvent
;
753 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
755 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
757 ProcessorLocBuf
= NULL
;
760 // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]
762 Status
= EfiGetSystemConfigurationTable (
763 &gEfiSmbiosTableGuid
,
764 (VOID
**) &SmbiosTable
767 if (!EFI_ERROR (Status
) && SmbiosTable
!= NULL
) {
768 TcgEvent
.PCRIndex
= 1;
769 TcgEvent
.EventType
= EV_EFI_HANDOFF_TABLES
;
770 TcgEvent
.EventSize
= sizeof (HandoffTables
);
772 HandoffTables
.NumberOfTables
= 1;
773 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiSmbiosTableGuid
;
774 HandoffTables
.TableEntry
[0].VendorTable
= SmbiosTable
;
776 DEBUG ((DEBUG_INFO
, "The Smbios Table starts at: 0x%x\n", SmbiosTable
->TableAddress
));
777 DEBUG ((DEBUG_INFO
, "The Smbios Table size: 0x%x\n", SmbiosTable
->TableLength
));
779 Status
= TcgDxeHashLogExtendEventI (
781 (UINT8
*)(UINTN
)SmbiosTable
->TableAddress
,
782 SmbiosTable
->TableLength
,
784 (UINT8
*)&HandoffTables
788 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
791 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
793 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
795 if (!EFI_ERROR(Status
)){
796 TcgEvent
.PCRIndex
= 1;
797 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
798 TcgEvent
.EventSize
= sizeof (HandoffTables
);
800 HandoffTables
.NumberOfTables
= 1;
801 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
802 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
804 Status
= TcgDxeHashLogExtendEventI (
806 (UINT8
*)(UINTN
)ProcessorLocBuf
,
807 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
809 (UINT8
*)&HandoffTables
812 FreePool(ProcessorLocBuf
);
820 Measure and log Separator event, and extend the measurement result into a specific PCR.
822 @param[in] PCRIndex PCR index.
824 @retval EFI_SUCCESS Operation completed successfully.
825 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
830 MeasureSeparatorEvent (
831 IN TPM_PCRINDEX PCRIndex
834 TCG_PCR_EVENT_HDR TcgEvent
;
838 TcgEvent
.PCRIndex
= PCRIndex
;
839 TcgEvent
.EventType
= EV_SEPARATOR
;
840 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
841 return TcgDxeHashLogExtendEventI (
851 Read an EFI Variable.
853 This function allocates a buffer to return the contents of the variable. The caller is
854 responsible for freeing the buffer.
856 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
857 @param[in] VendorGuid A unique identifier for the vendor.
858 @param[out] VarSize The size of the variable data.
860 @return A pointer to the buffer to return the contents of the variable.Otherwise NULL.
867 IN EFI_GUID
*VendorGuid
,
875 Status
= gRT
->GetVariable (
882 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
886 VarData
= AllocatePool (*VarSize
);
887 if (VarData
!= NULL
) {
888 Status
= gRT
->GetVariable (
895 if (EFI_ERROR (Status
)) {
905 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
907 @param[in] PCRIndex PCR Index.
908 @param[in] EventType Event type.
909 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
910 @param[in] VendorGuid A unique identifier for the vendor.
911 @param[in] VarData The content of the variable data.
912 @param[in] VarSize The size of the variable data.
914 @retval EFI_SUCCESS Operation completed successfully.
915 @retval EFI_OUT_OF_RESOURCES Out of memory.
916 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
922 IN TPM_PCRINDEX PCRIndex
,
923 IN TCG_EVENTTYPE EventType
,
925 IN EFI_GUID
*VendorGuid
,
931 TCG_PCR_EVENT_HDR TcgEvent
;
933 EFI_VARIABLE_DATA
*VarLog
;
935 VarNameLength
= StrLen (VarName
);
936 TcgEvent
.PCRIndex
= PCRIndex
;
937 TcgEvent
.EventType
= EventType
;
938 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
939 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
941 VarLog
= (EFI_VARIABLE_DATA
*)AllocatePool (TcgEvent
.EventSize
);
942 if (VarLog
== NULL
) {
943 return EFI_OUT_OF_RESOURCES
;
946 VarLog
->VariableName
= *VendorGuid
;
947 VarLog
->UnicodeNameLength
= VarNameLength
;
948 VarLog
->VariableDataLength
= VarSize
;
952 VarNameLength
* sizeof (*VarName
)
955 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
960 Status
= TcgDxeHashLogExtendEventI (
972 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
974 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
975 @param[in] VendorGuid A unique identifier for the vendor.
976 @param[out] VarSize The size of the variable data.
977 @param[out] VarData Pointer to the content of the variable.
979 @retval EFI_SUCCESS Operation completed successfully.
980 @retval EFI_OUT_OF_RESOURCES Out of memory.
981 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
986 ReadAndMeasureBootVariable (
988 IN EFI_GUID
*VendorGuid
,
995 *VarData
= ReadVariable (VarName
, VendorGuid
, VarSize
);
996 if (*VarData
== NULL
) {
997 return EFI_NOT_FOUND
;
1000 Status
= MeasureVariable (
1002 EV_EFI_VARIABLE_BOOT
,
1012 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1014 The EFI boot variables are BootOrder and Boot#### variables.
1016 @retval EFI_SUCCESS Operation completed successfully.
1017 @retval EFI_OUT_OF_RESOURCES Out of memory.
1018 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1023 MeasureAllBootVariables (
1034 Status
= ReadAndMeasureBootVariable (
1036 &gEfiGlobalVariableGuid
,
1038 (VOID
**) &BootOrder
1040 if (Status
== EFI_NOT_FOUND
|| BootOrder
== NULL
) {
1044 if (EFI_ERROR (Status
)) {
1046 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1048 FreePool (BootOrder
);
1052 BootCount
/= sizeof (*BootOrder
);
1053 for (Index
= 0; Index
< BootCount
; Index
++) {
1054 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
1055 Status
= ReadAndMeasureBootVariable (
1057 &gEfiGlobalVariableGuid
,
1061 if (!EFI_ERROR (Status
)) {
1062 FreePool (BootVarData
);
1066 FreePool (BootOrder
);
1071 Ready to Boot Event notification handler.
1073 Sequence of OS boot events is measured in this event notification handler.
1075 @param[in] Event Event whose notification function is being invoked
1076 @param[in] Context Pointer to the notification function's context
1087 TPM_PCRINDEX PcrIndex
;
1089 if (mBootAttempts
== 0) {
1092 // Measure handoff tables.
1094 Status
= MeasureHandoffTables ();
1095 if (EFI_ERROR (Status
)) {
1096 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
1100 // Measure BootOrder & Boot#### variables.
1102 Status
= MeasureAllBootVariables ();
1103 if (EFI_ERROR (Status
)) {
1104 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
1108 // 1. This is the first boot attempt.
1110 Status
= TcgMeasureAction (
1111 EFI_CALLING_EFI_APPLICATION
1113 if (EFI_ERROR (Status
)) {
1114 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION
));
1118 // 2. Draw a line between pre-boot env and entering post-boot env.
1120 for (PcrIndex
= 0; PcrIndex
< 8; PcrIndex
++) {
1121 Status
= MeasureSeparatorEvent (PcrIndex
);
1122 if (EFI_ERROR (Status
)) {
1123 DEBUG ((EFI_D_ERROR
, "Seperator Event not Measured. Error!\n"));
1128 // 3. Measure GPT. It would be done in SAP driver.
1132 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1136 // 5. Read & Measure variable. BootOrder already measured.
1140 // 6. Not first attempt, meaning a return from last attempt
1142 Status
= TcgMeasureAction (
1143 EFI_RETURNING_FROM_EFI_APPLICATOIN
1145 if (EFI_ERROR (Status
)) {
1146 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN
));
1150 DEBUG ((EFI_D_INFO
, "TPM TcgDxe Measure Data when ReadyToBoot\n"));
1152 // Increase boot attempt counter.
1158 Install TCG ACPI Table when ACPI Table Protocol is available.
1160 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1161 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1162 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1164 @param[in] Event Event whose notification function is being invoked
1165 @param[in] Context Pointer to the notification function's context
1176 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
1180 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
1181 if (EFI_ERROR (Status
)) {
1185 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
1186 CopyMem (mTcgClientAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgClientAcpiTemplate
.Header
.OemId
));
1187 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1188 CopyMem (&mTcgClientAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1189 mTcgClientAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1190 mTcgClientAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1191 mTcgClientAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1193 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1194 // service of the ACPI table protocol to install it.
1196 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgClientAcpiTemplate
, sizeof (mTcgClientAcpiTemplate
));
1197 mTcgClientAcpiTemplate
.Header
.Checksum
= Checksum
;
1199 Status
= AcpiTable
->InstallAcpiTable (
1201 &mTcgClientAcpiTemplate
,
1202 sizeof (mTcgClientAcpiTemplate
),
1206 CopyMem (mTcgServerAcpiTemplate
.Header
.OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (mTcgServerAcpiTemplate
.Header
.OemId
));
1207 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1208 CopyMem (&mTcgServerAcpiTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
1209 mTcgServerAcpiTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1210 mTcgServerAcpiTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1211 mTcgServerAcpiTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1213 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1214 // service of the ACPI table protocol to install it.
1216 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgServerAcpiTemplate
, sizeof (mTcgServerAcpiTemplate
));
1217 mTcgServerAcpiTemplate
.Header
.Checksum
= Checksum
;
1219 Status
= AcpiTable
->InstallAcpiTable (
1221 &mTcgServerAcpiTemplate
,
1222 sizeof (mTcgServerAcpiTemplate
),
1227 if (EFI_ERROR (Status
)) {
1228 DEBUG((EFI_D_ERROR
, "Tcg Acpi Table installation failure"));
1233 Exit Boot Services Event notification handler.
1235 Measure invocation and success of ExitBootServices.
1237 @param[in] Event Event whose notification function is being invoked
1238 @param[in] Context Pointer to the notification function's context
1243 OnExitBootServices (
1251 // Measure invocation of ExitBootServices,
1253 Status
= TcgMeasureAction (
1254 EFI_EXIT_BOOT_SERVICES_INVOCATION
1256 if (EFI_ERROR (Status
)) {
1257 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION
));
1261 // Measure success of ExitBootServices
1263 Status
= TcgMeasureAction (
1264 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1266 if (EFI_ERROR (Status
)){
1267 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED
));
1272 Exit Boot Services Failed Event notification handler.
1274 Measure Failure of ExitBootServices.
1276 @param[in] Event Event whose notification function is being invoked
1277 @param[in] Context Pointer to the notification function's context
1282 OnExitBootServicesFailed (
1290 // Measure Failure of ExitBootServices,
1292 Status
= TcgMeasureAction (
1293 EFI_EXIT_BOOT_SERVICES_FAILED
1295 if (EFI_ERROR (Status
)){
1296 DEBUG ((EFI_D_ERROR
, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED
));
1301 Get TPM Deactivated state.
1303 @param[out] TPMDeactivatedFlag Returns TPM Deactivated state.
1305 @retval EFI_SUCCESS Operation completed successfully.
1306 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1311 OUT BOOLEAN
*TPMDeactivatedFlag
1315 TPM_STCLEAR_FLAGS VFlags
;
1317 Status
= TpmCommGetFlags (
1318 mTcgDxeData
.TpmHandle
,
1319 TPM_CAP_FLAG_VOLATILE
,
1323 if (!EFI_ERROR (Status
)) {
1324 *TPMDeactivatedFlag
= VFlags
.deactivated
;
1331 The driver's entry point.
1333 It publishes EFI TCG Protocol.
1335 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1336 @param[in] SystemTable A pointer to the EFI System Table.
1338 @retval EFI_SUCCESS The entry point is executed successfully.
1339 @retval other Some error occurs when executing this entry point.
1345 IN EFI_HANDLE ImageHandle
,
1346 IN EFI_SYSTEM_TABLE
*SystemTable
1353 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
1354 DEBUG ((EFI_D_ERROR
, "No TPM12 instance required!\n"));
1355 return EFI_UNSUPPORTED
;
1358 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
1359 DEBUG ((EFI_D_ERROR
, "TPM error!\n"));
1360 return EFI_DEVICE_ERROR
;
1363 mTcgDxeData
.TpmHandle
= (TIS_TPM_HANDLE
)(UINTN
)TPM_BASE_ADDRESS
;
1364 Status
= TisPcRequestUseTpm (mTcgDxeData
.TpmHandle
);
1365 if (EFI_ERROR (Status
)) {
1366 DEBUG ((EFI_D_ERROR
, "TPM not detected!\n"));
1370 Status
= GetTpmStatus (&mTcgDxeData
.BsCap
.TPMDeactivatedFlag
);
1371 if (EFI_ERROR (Status
)) {
1374 "Line %d in file " __FILE__
":\n "
1375 "DriverEntry: TPM not working properly\n",
1381 Status
= gBS
->InstallProtocolInterface (
1383 &gEfiTcgProtocolGuid
,
1384 EFI_NATIVE_INTERFACE
,
1385 &mTcgDxeData
.TcgProtocol
1387 if (!EFI_ERROR (Status
) && (!mTcgDxeData
.BsCap
.TPMDeactivatedFlag
) && mTcgDxeData
.BsCap
.TPMPresentFlag
) {
1389 // Setup the log area and copy event log from hob list to it
1391 Status
= SetupEventLog ();
1392 ASSERT_EFI_ERROR (Status
);
1395 // Measure handoff tables, Boot#### variables etc.
1397 Status
= EfiCreateEventReadyToBootEx (
1404 Status
= gBS
->CreateEventEx (
1409 &gEfiEventExitBootServicesGuid
,
1414 // Measure Exit Boot Service failed
1416 Status
= gBS
->CreateEventEx (
1419 OnExitBootServicesFailed
,
1421 &gEventExitBootServicesFailedGuid
,
1427 // Install ACPI Table
1429 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid
, TPL_CALLBACK
, InstallAcpiTable
, NULL
, &Registration
);