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 - 2012, 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>
28 #include <Guid/GlobalVariable.h>
29 #include <Guid/SmBios.h>
30 #include <Guid/HobList.h>
31 #include <Guid/TcgEventHob.h>
32 #include <Guid/EventGroup.h>
33 #include <Guid/EventExitBootServiceFailed.h>
34 #include <Protocol/DevicePath.h>
35 #include <Protocol/TcgService.h>
36 #include <Protocol/AcpiTable.h>
37 #include <Protocol/MpService.h>
39 #include <Library/DebugLib.h>
40 #include <Library/BaseMemoryLib.h>
41 #include <Library/UefiRuntimeServicesTableLib.h>
42 #include <Library/UefiDriverEntryPoint.h>
43 #include <Library/HobLib.h>
44 #include <Library/UefiBootServicesTableLib.h>
45 #include <Library/BaseLib.h>
46 #include <Library/MemoryAllocationLib.h>
47 #include <Library/PrintLib.h>
48 #include <Library/TpmCommLib.h>
49 #include <Library/PcdLib.h>
50 #include <Library/UefiLib.h>
54 #define EFI_TCG_LOG_AREA_SIZE 0x10000
58 typedef struct _EFI_TCG_CLIENT_ACPI_TABLE
{
59 EFI_ACPI_DESCRIPTION_HEADER Header
;
62 EFI_PHYSICAL_ADDRESS Lasa
;
63 } EFI_TCG_CLIENT_ACPI_TABLE
;
65 typedef struct _EFI_TCG_SERVER_ACPI_TABLE
{
66 EFI_ACPI_DESCRIPTION_HEADER Header
;
70 EFI_PHYSICAL_ADDRESS Lasa
;
77 EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE BaseAddress
;
79 EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ConfigAddress
;
84 } EFI_TCG_SERVER_ACPI_TABLE
;
88 #define TCG_DXE_DATA_FROM_THIS(this) \
89 BASE_CR (this, TCG_DXE_DATA, TcgProtocol)
91 typedef struct _TCG_DXE_DATA
{
92 EFI_TCG_PROTOCOL TcgProtocol
;
93 TCG_EFI_BOOT_SERVICE_CAPABILITY BsCap
;
94 EFI_TCG_CLIENT_ACPI_TABLE
*TcgClientAcpiTable
;
95 EFI_TCG_SERVER_ACPI_TABLE
*TcgServerAcpiTable
;
98 TIS_TPM_HANDLE TpmHandle
;
103 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate
= {
105 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
106 sizeof (mTcgClientAcpiTemplate
),
109 // Compiler initializes the remaining bytes to 0
110 // These fields should be filled in in production
113 0, // 0 for PC Client Platform Class
114 0, // Log Area Max Length
115 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1) // Log Area Start Address
119 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,
120 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,
121 // this _UID can be changed and should match with the _UID setting of the TPM
122 // ACPI device object
124 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate
= {
126 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
127 sizeof (mTcgServerAcpiTemplate
),
130 // Compiler initializes the remaining bytes to 0
131 // These fields should be filled in in production
134 1, // 1 for Server Platform Class
136 0, // Log Area Max Length
137 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1), // Log Area Start Address
138 0x0100, // TCG Specification revision 1.0
140 0, // Interrupt Flags
142 {0}, // Reserved 3 bytes
143 0, // Global System Interrupt
145 EFI_ACPI_3_0_SYSTEM_MEMORY
,
149 TPM_BASE_ADDRESS
// Base Address
152 {0}, // Configuration Address
153 0xFF, // ACPI _UID value of the device, can be changed for different platforms
154 0, // ACPI _UID value of the device, can be changed for different platforms
155 0, // ACPI _UID value of the device, can be changed for different platforms
156 0 // ACPI _UID value of the device, can be changed for different platforms
159 UINTN mBootAttempts
= 0;
160 CHAR16 mBootVarName
[] = L
"BootOrder";
163 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
164 Caller is responsible to free LocationBuf.
166 @param[out] LocationBuf Returns Processor Location Buffer.
167 @param[out] Num Returns processor number.
169 @retval EFI_SUCCESS Operation completed successfully.
170 @retval EFI_UNSUPPORTED MpService protocol not found.
174 GetProcessorsCpuLocation (
175 OUT EFI_CPU_PHYSICAL_LOCATION
**LocationBuf
,
180 EFI_MP_SERVICES_PROTOCOL
*MpProtocol
;
182 UINTN EnabledProcessorNum
;
183 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
184 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
187 Status
= gBS
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**) &MpProtocol
);
188 if (EFI_ERROR (Status
)) {
190 // MP protocol is not installed
192 return EFI_UNSUPPORTED
;
195 Status
= MpProtocol
->GetNumberOfProcessors(
200 if (EFI_ERROR(Status
)){
204 Status
= gBS
->AllocatePool(
206 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
209 if (EFI_ERROR(Status
)){
214 // Get each processor Location info
216 for (Index
= 0; Index
< ProcessorNum
; Index
++) {
217 Status
= MpProtocol
->GetProcessorInfo(
222 if (EFI_ERROR(Status
)){
223 FreePool(ProcessorLocBuf
);
228 // Get all Processor Location info & measure
231 &ProcessorLocBuf
[Index
],
232 &ProcessorInfo
.Location
,
233 sizeof(EFI_CPU_PHYSICAL_LOCATION
)
237 *LocationBuf
= ProcessorLocBuf
;
244 This service provides EFI protocol capability information, state information
245 about the TPM, and Event Log state information.
247 @param[in] This Indicates the calling context
248 @param[out] ProtocolCapability The callee allocates memory for a TCG_BOOT_SERVICE_CAPABILITY
249 structure and fills in the fields with the EFI protocol
250 capability information and the current TPM state information.
251 @param[out] TCGFeatureFlags This is a pointer to the feature flags. No feature
252 flags are currently defined so this parameter
253 MUST be set to 0. However, in the future,
254 feature flags may be defined that, for example,
255 enable hash algorithm agility.
256 @param[out] EventLogLocation This is a pointer to the address of the event log in memory.
257 @param[out] EventLogLastEntry If the Event Log contains more than one entry,
258 this is a pointer to the address of the start of
259 the last entry in the event log in memory.
261 @retval EFI_SUCCESS Operation completed successfully.
262 @retval EFI_INVALID_PARAMETER ProtocolCapability does not match TCG capability.
268 IN EFI_TCG_PROTOCOL
*This
,
269 OUT TCG_EFI_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
,
270 OUT UINT32
*TCGFeatureFlags
,
271 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
272 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
275 TCG_DXE_DATA
*TcgData
;
277 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
279 if (ProtocolCapability
!= NULL
) {
280 *ProtocolCapability
= TcgData
->BsCap
;
283 if (TCGFeatureFlags
!= NULL
) {
284 *TCGFeatureFlags
= 0;
287 if (EventLogLocation
!= NULL
) {
288 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
289 *EventLogLocation
= TcgData
->TcgClientAcpiTable
->Lasa
;
291 *EventLogLocation
= TcgData
->TcgServerAcpiTable
->Lasa
;
295 if (EventLogLastEntry
!= NULL
) {
296 if (TcgData
->BsCap
.TPMDeactivatedFlag
) {
297 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
299 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)TcgData
->LastEvent
;
307 This service abstracts the capability to do a hash operation on a data buffer.
309 @param[in] This Indicates the calling context
310 @param[in] HashData Pointer to the data buffer to be hashed
311 @param[in] HashDataLen Length of the data buffer to be hashed
312 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation
313 @param[in, out] HashedDataLen Resultant length of the hashed data
314 @param[in, out] HashedDataResult Resultant buffer of the hashed data
316 @retval EFI_SUCCESS Operation completed successfully.
317 @retval EFI_INVALID_PARAMETER HashDataLen is NULL.
318 @retval EFI_INVALID_PARAMETER HashDataLenResult is NULL.
319 @retval EFI_OUT_OF_RESOURCES Cannot allocate buffer of size *HashedDataLen.
320 @retval EFI_UNSUPPORTED AlgorithmId not supported.
321 @retval EFI_BUFFER_TOO_SMALL *HashedDataLen < sizeof (TCG_DIGEST).
327 IN EFI_TCG_PROTOCOL
*This
,
329 IN UINT64 HashDataLen
,
330 IN TCG_ALGORITHM_ID AlgorithmId
,
331 IN OUT UINT64
*HashedDataLen
,
332 IN OUT UINT8
**HashedDataResult
335 if (HashedDataLen
== NULL
|| HashedDataResult
== NULL
) {
336 return EFI_INVALID_PARAMETER
;
339 switch (AlgorithmId
) {
341 if (*HashedDataLen
== 0) {
342 *HashedDataLen
= sizeof (TPM_DIGEST
);
343 *HashedDataResult
= AllocatePool ((UINTN
) *HashedDataLen
);
344 if (*HashedDataResult
== NULL
) {
345 return EFI_OUT_OF_RESOURCES
;
349 if (*HashedDataLen
< sizeof (TPM_DIGEST
)) {
350 *HashedDataLen
= sizeof (TPM_DIGEST
);
351 return EFI_BUFFER_TOO_SMALL
;
353 *HashedDataLen
= sizeof (TPM_DIGEST
);
355 if (*HashedDataResult
== NULL
) {
356 *HashedDataResult
= AllocatePool ((UINTN
) *HashedDataLen
);
359 return TpmCommHashAll (
362 (TPM_DIGEST
*)*HashedDataResult
365 return EFI_UNSUPPORTED
;
370 Add a new entry to the Event Log.
372 @param[in] TcgData TCG_DXE_DATA structure.
373 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
374 @param[in] NewEventData Pointer to the new event data.
376 @retval EFI_SUCCESS The new event log entry was added.
377 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
383 IN TCG_DXE_DATA
*TcgData
,
384 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
385 IN UINT8
*NewEventData
388 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
389 TcgData
->LastEvent
= (UINT8
*)(UINTN
)TcgData
->TcgClientAcpiTable
->Lasa
;
390 return TpmCommLogEvent (
392 &TcgData
->EventLogSize
,
393 (UINTN
)TcgData
->TcgClientAcpiTable
->Laml
,
398 TcgData
->LastEvent
= (UINT8
*)(UINTN
)TcgData
->TcgServerAcpiTable
->Lasa
;
399 return TpmCommLogEvent (
401 &TcgData
->EventLogSize
,
402 (UINTN
)TcgData
->TcgServerAcpiTable
->Laml
,
410 This service abstracts the capability to add an entry to the Event Log.
412 @param[in] This Indicates the calling context
413 @param[in] TCGLogData Pointer to the start of the data buffer containing
414 the TCG_PCR_EVENT data structure. All fields in
415 this structure are properly filled by the caller.
416 @param[in, out] EventNumber The event number of the event just logged
417 @param[in] Flags Indicate additional flags. Only one flag has been
418 defined at this time, which is 0x01 and means the
419 extend operation should not be performed. All
420 other bits are reserved.
422 @retval EFI_SUCCESS Operation completed successfully.
423 @retval EFI_OUT_OF_RESOURCES Insufficient memory in the event log to complete this action.
429 IN EFI_TCG_PROTOCOL
*This
,
430 IN TCG_PCR_EVENT
*TCGLogData
,
431 IN OUT UINT32
*EventNumber
,
435 TCG_DXE_DATA
*TcgData
;
437 if (TCGLogData
== NULL
){
438 return EFI_INVALID_PARAMETER
;
441 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
443 if (TcgData
->BsCap
.TPMDeactivatedFlag
) {
444 return EFI_DEVICE_ERROR
;
446 return TcgDxeLogEventI (
448 (TCG_PCR_EVENT_HDR
*)TCGLogData
,
454 This service is a proxy for commands to the TPM.
456 @param[in] This Indicates the calling context
457 @param[in] TpmInputParameterBlockSize Size of the TPM input parameter block
458 @param[in] TpmInputParameterBlock Pointer to the TPM input parameter block
459 @param[in] TpmOutputParameterBlockSize Size of the TPM output parameter block
460 @param[in] TpmOutputParameterBlock Pointer to the TPM output parameter block
462 @retval EFI_SUCCESS Operation completed successfully.
463 @retval EFI_INVALID_PARAMETER Invalid ordinal.
464 @retval EFI_UNSUPPORTED Current Task Priority Level >= EFI_TPL_CALLBACK.
465 @retval EFI_TIMEOUT The TIS timed-out.
470 TcgDxePassThroughToTpm (
471 IN EFI_TCG_PROTOCOL
*This
,
472 IN UINT32 TpmInputParameterBlockSize
,
473 IN UINT8
*TpmInputParameterBlock
,
474 IN UINT32 TpmOutputParameterBlockSize
,
475 IN UINT8
*TpmOutputParameterBlock
478 TCG_DXE_DATA
*TcgData
;
480 if (TpmInputParameterBlock
== NULL
||
481 TpmOutputParameterBlock
== NULL
||
482 TpmInputParameterBlockSize
== 0 ||
483 TpmOutputParameterBlockSize
== 0) {
484 return EFI_INVALID_PARAMETER
;
487 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
489 return TisPcExecute (
492 TpmInputParameterBlock
,
493 (UINTN
) TpmInputParameterBlockSize
,
494 TpmOutputParameterBlock
,
495 (UINTN
) TpmOutputParameterBlockSize
500 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
501 and add an entry to the Event Log.
503 @param[in] TcgData TCG_DXE_DATA structure.
504 @param[in] HashData Physical address of the start of the data buffer
505 to be hashed, extended, and logged.
506 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
507 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
508 @param[in] NewEventData Pointer to the new event data.
510 @retval EFI_SUCCESS Operation completed successfully.
511 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
512 @retval EFI_DEVICE_ERROR The command was unsuccessful.
517 TcgDxeHashLogExtendEventI (
518 IN TCG_DXE_DATA
*TcgData
,
520 IN UINT64 HashDataLen
,
521 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
522 IN UINT8
*NewEventData
527 if (HashData
== NULL
&& HashDataLen
> 0) {
528 return EFI_INVALID_PARAMETER
;
531 if (HashDataLen
> 0 || HashData
!= NULL
) {
532 Status
= TpmCommHashAll (
537 ASSERT_EFI_ERROR (Status
);
540 Status
= TpmCommExtend (
542 &NewEventHdr
->Digest
,
543 NewEventHdr
->PCRIndex
,
546 if (!EFI_ERROR (Status
)) {
547 Status
= TcgDxeLogEventI (TcgData
, NewEventHdr
, NewEventData
);
554 This service abstracts the capability to do a hash operation on a data buffer,
555 extend a specific TPM PCR with the hash result, and add an entry to the Event Log
557 @param[in] This Indicates the calling context
558 @param[in] HashData Physical address of the start of the data buffer
559 to be hashed, extended, and logged.
560 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
561 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation
562 @param[in, out] TCGLogData The physical address of the start of the data
563 buffer containing the TCG_PCR_EVENT data structure.
564 @param[in, out] EventNumber The event number of the event just logged.
565 @param[out] EventLogLastEntry Physical address of the first byte of the entry
566 just placed in the Event Log. If the Event Log was
567 empty when this function was called then this physical
568 address will be the same as the physical address of
569 the start of the Event Log.
571 @retval EFI_SUCCESS Operation completed successfully.
572 @retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA.
573 @retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK.
574 @retval EFI_DEVICE_ERROR The command was unsuccessful.
579 TcgDxeHashLogExtendEvent (
580 IN EFI_TCG_PROTOCOL
*This
,
581 IN EFI_PHYSICAL_ADDRESS HashData
,
582 IN UINT64 HashDataLen
,
583 IN TPM_ALGORITHM_ID AlgorithmId
,
584 IN OUT TCG_PCR_EVENT
*TCGLogData
,
585 IN OUT UINT32
*EventNumber
,
586 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
589 TCG_DXE_DATA
*TcgData
;
592 if (TCGLogData
== NULL
|| EventLogLastEntry
== NULL
){
593 return EFI_INVALID_PARAMETER
;
596 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
598 if (TcgData
->BsCap
.TPMDeactivatedFlag
) {
599 return EFI_DEVICE_ERROR
;
602 if (AlgorithmId
!= TPM_ALG_SHA
) {
603 return EFI_UNSUPPORTED
;
606 Status
= TcgDxeHashLogExtendEventI (
608 (UINT8
*) (UINTN
) HashData
,
610 (TCG_PCR_EVENT_HDR
*)TCGLogData
,
614 if (!EFI_ERROR(Status
)){
615 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) TcgData
->LastEvent
;
621 TCG_DXE_DATA mTcgDxeData
= {
626 TcgDxePassThroughToTpm
,
627 TcgDxeHashLogExtendEvent
630 sizeof (mTcgDxeData
.BsCap
),
637 &mTcgClientAcpiTemplate
,
638 &mTcgServerAcpiTemplate
,
645 Initialize the Event Log and log events passed from the PEI phase.
647 @retval EFI_SUCCESS Operation completed successfully.
648 @retval EFI_OUT_OF_RESOURCES Out of memory.
658 TCG_PCR_EVENT
*TcgEvent
;
659 EFI_PEI_HOB_POINTERS GuidHob
;
660 EFI_PHYSICAL_ADDRESS Lasa
;
662 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
663 Lasa
= mTcgClientAcpiTemplate
.Lasa
;
665 Status
= gBS
->AllocatePages (
668 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE
),
671 if (EFI_ERROR (Status
)) {
674 mTcgClientAcpiTemplate
.Lasa
= Lasa
;
676 // To initialize them as 0xFF is recommended
677 // because the OS can know the last entry for that.
679 SetMem ((VOID
*)(UINTN
)mTcgClientAcpiTemplate
.Lasa
, EFI_TCG_LOG_AREA_SIZE
, 0xFF);
680 mTcgClientAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
683 Lasa
= mTcgServerAcpiTemplate
.Lasa
;
685 Status
= gBS
->AllocatePages (
688 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE
),
691 if (EFI_ERROR (Status
)) {
694 mTcgServerAcpiTemplate
.Lasa
= Lasa
;
696 // To initialize them as 0xFF is recommended
697 // because the OS can know the last entry for that.
699 SetMem ((VOID
*)(UINTN
)mTcgServerAcpiTemplate
.Lasa
, EFI_TCG_LOG_AREA_SIZE
, 0xFF);
700 mTcgServerAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
703 GuidHob
.Raw
= GetHobList ();
704 while (!EFI_ERROR (Status
) &&
705 (GuidHob
.Raw
= GetNextGuidHob (&gTcgEventEntryHobGuid
, GuidHob
.Raw
)) != NULL
) {
706 TcgEvent
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
707 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
708 Status
= TcgDxeLogEventI (
710 (TCG_PCR_EVENT_HDR
*)TcgEvent
,
719 Measure and log an action string, and extend the measurement result into PCR[5].
721 @param[in] String A specific string that indicates an Action event.
723 @retval EFI_SUCCESS Operation completed successfully.
724 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
733 TCG_PCR_EVENT_HDR TcgEvent
;
735 TcgEvent
.PCRIndex
= 5;
736 TcgEvent
.EventType
= EV_EFI_ACTION
;
737 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
738 return TcgDxeHashLogExtendEventI (
748 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
750 @retval EFI_SUCCESS Operation completed successfully.
751 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
756 MeasureHandoffTables (
761 SMBIOS_TABLE_ENTRY_POINT
*SmbiosTable
;
762 TCG_PCR_EVENT_HDR TcgEvent
;
763 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
765 EFI_CPU_PHYSICAL_LOCATION
*ProcessorLocBuf
;
768 // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]
770 Status
= EfiGetSystemConfigurationTable (
771 &gEfiSmbiosTableGuid
,
772 (VOID
**) &SmbiosTable
775 if (!EFI_ERROR (Status
)) {
776 ASSERT (SmbiosTable
!= NULL
);
778 TcgEvent
.PCRIndex
= 1;
779 TcgEvent
.EventType
= EV_EFI_HANDOFF_TABLES
;
780 TcgEvent
.EventSize
= sizeof (HandoffTables
);
782 HandoffTables
.NumberOfTables
= 1;
783 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiSmbiosTableGuid
;
784 HandoffTables
.TableEntry
[0].VendorTable
= SmbiosTable
;
786 DEBUG ((DEBUG_INFO
, "The Smbios Table starts at: 0x%x\n", SmbiosTable
->TableAddress
));
787 DEBUG ((DEBUG_INFO
, "The Smbios Table size: 0x%x\n", SmbiosTable
->TableLength
));
789 Status
= TcgDxeHashLogExtendEventI (
791 (UINT8
*)(UINTN
)SmbiosTable
->TableAddress
,
792 SmbiosTable
->TableLength
,
794 (UINT8
*)&HandoffTables
798 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_SERVER
) {
801 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
803 Status
= GetProcessorsCpuLocation(&ProcessorLocBuf
, &ProcessorNum
);
805 if (!EFI_ERROR(Status
)){
806 TcgEvent
.PCRIndex
= 1;
807 TcgEvent
.EventType
= EV_TABLE_OF_DEVICES
;
808 TcgEvent
.EventSize
= sizeof (HandoffTables
);
810 HandoffTables
.NumberOfTables
= 1;
811 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiMpServiceProtocolGuid
;
812 HandoffTables
.TableEntry
[0].VendorTable
= ProcessorLocBuf
;
814 Status
= TcgDxeHashLogExtendEventI (
816 (UINT8
*)(UINTN
)ProcessorLocBuf
,
817 sizeof(EFI_CPU_PHYSICAL_LOCATION
) * ProcessorNum
,
819 (UINT8
*)&HandoffTables
822 FreePool(ProcessorLocBuf
);
830 Measure and log Separator event, and extend the measurement result into a specific PCR.
832 @param[in] PCRIndex PCR index.
834 @retval EFI_SUCCESS Operation completed successfully.
835 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
840 MeasureSeparatorEvent (
841 IN TPM_PCRINDEX PCRIndex
844 TCG_PCR_EVENT_HDR TcgEvent
;
848 TcgEvent
.PCRIndex
= PCRIndex
;
849 TcgEvent
.EventType
= EV_SEPARATOR
;
850 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
851 return TcgDxeHashLogExtendEventI (
861 Read an EFI Variable.
863 This function allocates a buffer to return the contents of the variable. The caller is
864 responsible for freeing the buffer.
866 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
867 @param[in] VendorGuid A unique identifier for the vendor.
868 @param[out] VarSize The size of the variable data.
870 @return A pointer to the buffer to return the contents of the variable.Otherwise NULL.
877 IN EFI_GUID
*VendorGuid
,
885 Status
= gRT
->GetVariable (
892 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
896 VarData
= AllocatePool (*VarSize
);
897 if (VarData
!= NULL
) {
898 Status
= gRT
->GetVariable (
905 if (EFI_ERROR (Status
)) {
915 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
917 @param[in] PCRIndex PCR Index.
918 @param[in] EventType Event type.
919 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
920 @param[in] VendorGuid A unique identifier for the vendor.
921 @param[in] VarData The content of the variable data.
922 @param[in] VarSize The size of the variable data.
924 @retval EFI_SUCCESS Operation completed successfully.
925 @retval EFI_OUT_OF_RESOURCES Out of memory.
926 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
932 IN TPM_PCRINDEX PCRIndex
,
933 IN TCG_EVENTTYPE EventType
,
935 IN EFI_GUID
*VendorGuid
,
941 TCG_PCR_EVENT_HDR TcgEvent
;
943 EFI_VARIABLE_DATA
*VarLog
;
945 VarNameLength
= StrLen (VarName
);
946 TcgEvent
.PCRIndex
= PCRIndex
;
947 TcgEvent
.EventType
= EventType
;
948 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
949 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
951 VarLog
= (EFI_VARIABLE_DATA
*)AllocatePool (TcgEvent
.EventSize
);
952 if (VarLog
== NULL
) {
953 return EFI_OUT_OF_RESOURCES
;
956 VarLog
->VariableName
= *VendorGuid
;
957 VarLog
->UnicodeNameLength
= VarNameLength
;
958 VarLog
->VariableDataLength
= VarSize
;
962 VarNameLength
* sizeof (*VarName
)
965 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
970 Status
= TcgDxeHashLogExtendEventI (
982 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
984 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
985 @param[in] VendorGuid A unique identifier for the vendor.
986 @param[out] VarSize The size of the variable data.
987 @param[out] VarData Pointer to the content of the variable.
989 @retval EFI_SUCCESS Operation completed successfully.
990 @retval EFI_OUT_OF_RESOURCES Out of memory.
991 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
996 ReadAndMeasureBootVariable (
998 IN EFI_GUID
*VendorGuid
,
1005 *VarData
= ReadVariable (VarName
, VendorGuid
, VarSize
);
1006 if (*VarData
== NULL
) {
1007 return EFI_NOT_FOUND
;
1010 Status
= MeasureVariable (
1012 EV_EFI_VARIABLE_BOOT
,
1022 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1024 The EFI boot variables are BootOrder and Boot#### variables.
1026 @retval EFI_SUCCESS Operation completed successfully.
1027 @retval EFI_OUT_OF_RESOURCES Out of memory.
1028 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1033 MeasureAllBootVariables (
1044 Status
= ReadAndMeasureBootVariable (
1046 &gEfiGlobalVariableGuid
,
1048 (VOID
**) &BootOrder
1050 if (Status
== EFI_NOT_FOUND
) {
1053 ASSERT (BootOrder
!= NULL
);
1055 if (EFI_ERROR (Status
)) {
1056 FreePool (BootOrder
);
1060 BootCount
/= sizeof (*BootOrder
);
1061 for (Index
= 0; Index
< BootCount
; Index
++) {
1062 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
1063 Status
= ReadAndMeasureBootVariable (
1065 &gEfiGlobalVariableGuid
,
1069 if (!EFI_ERROR (Status
)) {
1070 FreePool (BootVarData
);
1074 FreePool (BootOrder
);
1079 Ready to Boot Event notification handler.
1081 Sequence of OS boot events is measured in this event notification handler.
1083 @param[in] Event Event whose notification function is being invoked
1084 @param[in] Context Pointer to the notification function's context
1095 TPM_PCRINDEX PcrIndex
;
1097 if (mBootAttempts
== 0) {
1100 // Measure handoff tables.
1102 Status
= MeasureHandoffTables ();
1103 if (EFI_ERROR (Status
)) {
1104 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
1108 // Measure BootOrder & Boot#### variables.
1110 Status
= MeasureAllBootVariables ();
1111 if (EFI_ERROR (Status
)) {
1112 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
1116 // 1. This is the first boot attempt.
1118 Status
= TcgMeasureAction (
1119 EFI_CALLING_EFI_APPLICATION
1121 ASSERT_EFI_ERROR (Status
);
1124 // 2. Draw a line between pre-boot env and entering post-boot env.
1126 for (PcrIndex
= 0; PcrIndex
< 8; PcrIndex
++) {
1127 Status
= MeasureSeparatorEvent (PcrIndex
);
1128 ASSERT_EFI_ERROR (Status
);
1132 // 3. Measure GPT. It would be done in SAP driver.
1136 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1140 // 5. Read & Measure variable. BootOrder already measured.
1144 // 6. Not first attempt, meaning a return from last attempt
1146 Status
= TcgMeasureAction (
1147 EFI_RETURNING_FROM_EFI_APPLICATOIN
1149 ASSERT_EFI_ERROR (Status
);
1152 DEBUG ((EFI_D_INFO
, "TPM TcgDxe Measure Data when ReadyToBoot\n"));
1154 // Increase boot attempt counter.
1160 Install TCG ACPI Table when ACPI Table Protocol is available.
1162 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1163 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1164 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1166 @param[in] Event Event whose notification function is being invoked
1167 @param[in] Context Pointer to the notification function's context
1178 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
1181 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
1182 if (EFI_ERROR (Status
)) {
1186 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
1189 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1190 // service of the ACPI table protocol to install it.
1192 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgClientAcpiTemplate
, sizeof (mTcgClientAcpiTemplate
));
1193 mTcgClientAcpiTemplate
.Header
.Checksum
= Checksum
;
1195 Status
= AcpiTable
->InstallAcpiTable (
1197 &mTcgClientAcpiTemplate
,
1198 sizeof (mTcgClientAcpiTemplate
),
1204 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1205 // service of the ACPI table protocol to install it.
1207 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgServerAcpiTemplate
, sizeof (mTcgServerAcpiTemplate
));
1208 mTcgServerAcpiTemplate
.Header
.Checksum
= Checksum
;
1210 Status
= AcpiTable
->InstallAcpiTable (
1212 &mTcgServerAcpiTemplate
,
1213 sizeof (mTcgServerAcpiTemplate
),
1217 ASSERT_EFI_ERROR (Status
);
1221 Exit Boot Services Event notification handler.
1223 Measure invocation and success of ExitBootServices.
1225 @param[in] Event Event whose notification function is being invoked
1226 @param[in] Context Pointer to the notification function's context
1231 OnExitBootServices (
1239 // Measure invocation of ExitBootServices,
1241 Status
= TcgMeasureAction (
1242 EFI_EXIT_BOOT_SERVICES_INVOCATION
1244 ASSERT_EFI_ERROR (Status
);
1247 // Measure success of ExitBootServices
1249 Status
= TcgMeasureAction (
1250 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1252 ASSERT_EFI_ERROR (Status
);
1256 Exit Boot Services Failed Event notification handler.
1258 Measure Failure of ExitBootServices.
1260 @param[in] Event Event whose notification function is being invoked
1261 @param[in] Context Pointer to the notification function's context
1266 OnExitBootServicesFailed (
1274 // Measure Failure of ExitBootServices,
1276 Status
= TcgMeasureAction (
1277 EFI_EXIT_BOOT_SERVICES_FAILED
1279 ASSERT_EFI_ERROR (Status
);
1284 Get TPM Deactivated state.
1286 @param[out] TPMDeactivatedFlag Returns TPM Deactivated state.
1288 @retval EFI_SUCCESS Operation completed successfully.
1289 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1294 OUT BOOLEAN
*TPMDeactivatedFlag
1298 TPM_STCLEAR_FLAGS VFlags
;
1300 Status
= TpmCommGetFlags (
1301 mTcgDxeData
.TpmHandle
,
1302 TPM_CAP_FLAG_VOLATILE
,
1306 if (!EFI_ERROR (Status
)) {
1307 *TPMDeactivatedFlag
= VFlags
.deactivated
;
1314 The driver's entry point.
1316 It publishes EFI TCG Protocol.
1318 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1319 @param[in] SystemTable A pointer to the EFI System Table.
1321 @retval EFI_SUCCESS The entry point is executed successfully.
1322 @retval other Some error occurs when executing this entry point.
1328 IN EFI_HANDLE ImageHandle
,
1329 IN EFI_SYSTEM_TABLE
*SystemTable
1336 mTcgDxeData
.TpmHandle
= (TIS_TPM_HANDLE
)(UINTN
)TPM_BASE_ADDRESS
;
1337 Status
= TisPcRequestUseTpm (mTcgDxeData
.TpmHandle
);
1338 if (EFI_ERROR (Status
)) {
1339 DEBUG ((EFI_D_ERROR
, "TPM not detected!\n"));
1343 Status
= GetTpmStatus (&mTcgDxeData
.BsCap
.TPMDeactivatedFlag
);
1344 if (EFI_ERROR (Status
)) {
1347 "Line %d in file " __FILE__
":\n "
1348 "DriverEntry: TPM not working properly\n",
1354 Status
= gBS
->InstallProtocolInterface (
1356 &gEfiTcgProtocolGuid
,
1357 EFI_NATIVE_INTERFACE
,
1358 &mTcgDxeData
.TcgProtocol
1360 if (!EFI_ERROR (Status
) && !mTcgDxeData
.BsCap
.TPMDeactivatedFlag
) {
1362 // Setup the log area and copy event log from hob list to it
1364 Status
= SetupEventLog ();
1365 ASSERT_EFI_ERROR (Status
);
1368 // Measure handoff tables, Boot#### variables etc.
1370 Status
= EfiCreateEventReadyToBootEx (
1377 Status
= gBS
->CreateEventEx (
1382 &gEfiEventExitBootServicesGuid
,
1387 // Measure Exit Boot Service failed
1389 Status
= gBS
->CreateEventEx (
1392 OnExitBootServicesFailed
,
1394 &gEventExitBootServicesFailedGuid
,
1400 // Install ACPI Table
1402 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid
, TPL_CALLBACK
, InstallAcpiTable
, NULL
, &Registration
);