2 This module implements TCG EFI Protocol.
4 Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <IndustryStandard/Tpm12.h>
17 #include <IndustryStandard/Acpi.h>
18 #include <IndustryStandard/PeImage.h>
19 #include <IndustryStandard/SmBios.h>
21 #include <Guid/GlobalVariable.h>
22 #include <Guid/SmBios.h>
23 #include <Guid/HobList.h>
24 #include <Guid/TcgEventHob.h>
25 #include <Guid/EventGroup.h>
26 #include <Guid/EventExitBootServiceFailed.h>
27 #include <Protocol/DevicePath.h>
28 #include <Protocol/TcgService.h>
29 #include <Protocol/AcpiTable.h>
31 #include <Library/DebugLib.h>
32 #include <Library/BaseMemoryLib.h>
33 #include <Library/UefiRuntimeServicesTableLib.h>
34 #include <Library/UefiDriverEntryPoint.h>
35 #include <Library/HobLib.h>
36 #include <Library/UefiBootServicesTableLib.h>
37 #include <Library/BaseLib.h>
38 #include <Library/MemoryAllocationLib.h>
39 #include <Library/PrintLib.h>
40 #include <Library/TpmCommLib.h>
41 #include <Library/PcdLib.h>
42 #include <Library/UefiLib.h>
46 #define EFI_TCG_LOG_AREA_SIZE 0x10000
50 typedef struct _EFI_TCG_CLIENT_ACPI_TABLE
{
51 EFI_ACPI_DESCRIPTION_HEADER Header
;
54 EFI_PHYSICAL_ADDRESS Lasa
;
55 } EFI_TCG_CLIENT_ACPI_TABLE
;
57 typedef struct _EFI_TCG_SERVER_ACPI_TABLE
{
58 EFI_ACPI_DESCRIPTION_HEADER Header
;
62 EFI_PHYSICAL_ADDRESS Lasa
;
69 EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE BaseAddress
;
71 EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ConfigAddress
;
76 } EFI_TCG_SERVER_ACPI_TABLE
;
80 #define TCG_DXE_DATA_FROM_THIS(this) \
81 BASE_CR (this, TCG_DXE_DATA, TcgProtocol)
83 typedef struct _TCG_DXE_DATA
{
84 EFI_TCG_PROTOCOL TcgProtocol
;
85 TCG_EFI_BOOT_SERVICE_CAPABILITY BsCap
;
86 EFI_TCG_CLIENT_ACPI_TABLE
*TcgClientAcpiTable
;
87 EFI_TCG_SERVER_ACPI_TABLE
*TcgServerAcpiTable
;
90 TIS_TPM_HANDLE TpmHandle
;
95 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate
= {
97 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
98 sizeof (mTcgClientAcpiTemplate
),
101 // Compiler initializes the remaining bytes to 0
102 // These fields should be filled in in production
105 0, // 0 for PC Client Platform Class
106 0, // Log Area Max Length
107 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1) // Log Area Start Address
111 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,
112 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,
113 // this _UID can be changed and should match with the _UID setting of the TPM
114 // ACPI device object
116 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate
= {
118 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE
,
119 sizeof (mTcgServerAcpiTemplate
),
122 // Compiler initializes the remaining bytes to 0
123 // These fields should be filled in in production
126 1, // 1 for Server Platform Class
128 0, // Log Area Max Length
129 (EFI_PHYSICAL_ADDRESS
) (SIZE_4GB
- 1), // Log Area Start Address
130 0x0100, // TCG Specification revision 1.0
132 0, // Interrupt Flags
134 {0}, // Reserved 3 bytes
135 0, // Global System Interrupt
137 EFI_ACPI_3_0_SYSTEM_MEMORY
,
141 TPM_BASE_ADDRESS
// Base Address
144 {0}, // Configuration Address
145 0xFF, // ACPI _UID value of the device, can be changed for different platforms
146 0, // ACPI _UID value of the device, can be changed for different platforms
147 0, // ACPI _UID value of the device, can be changed for different platforms
148 0 // ACPI _UID value of the device, can be changed for different platforms
151 UINTN mBootAttempts
= 0;
152 CHAR16 mBootVarName
[] = L
"BootOrder";
155 This service provides EFI protocol capability information, state information
156 about the TPM, and Event Log state information.
158 @param[in] This Indicates the calling context
159 @param[out] ProtocolCapability The callee allocates memory for a TCG_BOOT_SERVICE_CAPABILITY
160 structure and fills in the fields with the EFI protocol
161 capability information and the current TPM state information.
162 @param[out] TCGFeatureFlags This is a pointer to the feature flags. No feature
163 flags are currently defined so this parameter
164 MUST be set to 0. However, in the future,
165 feature flags may be defined that, for example,
166 enable hash algorithm agility.
167 @param[out] EventLogLocation This is a pointer to the address of the event log in memory.
168 @param[out] EventLogLastEntry If the Event Log contains more than one entry,
169 this is a pointer to the address of the start of
170 the last entry in the event log in memory.
172 @retval EFI_SUCCESS Operation completed successfully.
173 @retval EFI_INVALID_PARAMETER ProtocolCapability does not match TCG capability.
179 IN EFI_TCG_PROTOCOL
*This
,
180 OUT TCG_EFI_BOOT_SERVICE_CAPABILITY
*ProtocolCapability
,
181 OUT UINT32
*TCGFeatureFlags
,
182 OUT EFI_PHYSICAL_ADDRESS
*EventLogLocation
,
183 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
186 TCG_DXE_DATA
*TcgData
;
188 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
190 if (ProtocolCapability
!= NULL
) {
191 *ProtocolCapability
= TcgData
->BsCap
;
194 if (TCGFeatureFlags
!= NULL
) {
195 *TCGFeatureFlags
= 0;
198 if (EventLogLocation
!= NULL
) {
199 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
200 *EventLogLocation
= TcgData
->TcgClientAcpiTable
->Lasa
;
202 *EventLogLocation
= TcgData
->TcgServerAcpiTable
->Lasa
;
206 if (EventLogLastEntry
!= NULL
) {
207 if (TcgData
->BsCap
.TPMDeactivatedFlag
) {
208 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)0;
210 *EventLogLastEntry
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)TcgData
->LastEvent
;
218 This service abstracts the capability to do a hash operation on a data buffer.
220 @param[in] This Indicates the calling context
221 @param[in] HashData Pointer to the data buffer to be hashed
222 @param[in] HashDataLen Length of the data buffer to be hashed
223 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation
224 @param[in, out] HashedDataLen Resultant length of the hashed data
225 @param[in, out] HashedDataResult Resultant buffer of the hashed data
227 @retval EFI_SUCCESS Operation completed successfully.
228 @retval EFI_INVALID_PARAMETER HashDataLen is NULL.
229 @retval EFI_INVALID_PARAMETER HashDataLenResult is NULL.
230 @retval EFI_OUT_OF_RESOURCES Cannot allocate buffer of size *HashedDataLen.
231 @retval EFI_UNSUPPORTED AlgorithmId not supported.
232 @retval EFI_BUFFER_TOO_SMALL *HashedDataLen < sizeof (TCG_DIGEST).
238 IN EFI_TCG_PROTOCOL
*This
,
240 IN UINT64 HashDataLen
,
241 IN TCG_ALGORITHM_ID AlgorithmId
,
242 IN OUT UINT64
*HashedDataLen
,
243 IN OUT UINT8
**HashedDataResult
246 if (HashedDataLen
== NULL
|| HashedDataResult
== NULL
) {
247 return EFI_INVALID_PARAMETER
;
250 switch (AlgorithmId
) {
252 if (*HashedDataLen
== 0) {
253 *HashedDataLen
= sizeof (TPM_DIGEST
);
254 *HashedDataResult
= AllocatePool ((UINTN
) *HashedDataLen
);
255 if (*HashedDataResult
== NULL
) {
256 return EFI_OUT_OF_RESOURCES
;
260 if (*HashedDataLen
< sizeof (TPM_DIGEST
)) {
261 *HashedDataLen
= sizeof (TPM_DIGEST
);
262 return EFI_BUFFER_TOO_SMALL
;
264 *HashedDataLen
= sizeof (TPM_DIGEST
);
266 if (*HashedDataResult
== NULL
) {
267 *HashedDataResult
= AllocatePool ((UINTN
) *HashedDataLen
);
270 return TpmCommHashAll (
273 (TPM_DIGEST
*)*HashedDataResult
276 return EFI_UNSUPPORTED
;
281 Add a new entry to the Event Log.
283 @param[in] TcgData TCG_DXE_DATA structure.
284 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
285 @param[in] NewEventData Pointer to the new event data.
287 @retval EFI_SUCCESS The new event log entry was added.
288 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
294 IN TCG_DXE_DATA
*TcgData
,
295 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
296 IN UINT8
*NewEventData
299 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
300 TcgData
->LastEvent
= (UINT8
*)(UINTN
)TcgData
->TcgClientAcpiTable
->Lasa
;
301 return TpmCommLogEvent (
303 &TcgData
->EventLogSize
,
304 (UINTN
)TcgData
->TcgClientAcpiTable
->Laml
,
309 TcgData
->LastEvent
= (UINT8
*)(UINTN
)TcgData
->TcgServerAcpiTable
->Lasa
;
310 return TpmCommLogEvent (
312 &TcgData
->EventLogSize
,
313 (UINTN
)TcgData
->TcgServerAcpiTable
->Laml
,
321 This service abstracts the capability to add an entry to the Event Log.
323 @param[in] This Indicates the calling context
324 @param[in] TCGLogData Pointer to the start of the data buffer containing
325 the TCG_PCR_EVENT data structure. All fields in
326 this structure are properly filled by the caller.
327 @param[in, out] EventNumber The event number of the event just logged
328 @param[in] Flags Indicate additional flags. Only one flag has been
329 defined at this time, which is 0x01 and means the
330 extend operation should not be performed. All
331 other bits are reserved.
333 @retval EFI_SUCCESS Operation completed successfully.
334 @retval EFI_OUT_OF_RESOURCES Insufficient memory in the event log to complete this action.
340 IN EFI_TCG_PROTOCOL
*This
,
341 IN TCG_PCR_EVENT
*TCGLogData
,
342 IN OUT UINT32
*EventNumber
,
346 TCG_DXE_DATA
*TcgData
;
348 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
350 if (TcgData
->BsCap
.TPMDeactivatedFlag
) {
351 return EFI_DEVICE_ERROR
;
353 return TcgDxeLogEventI (
355 (TCG_PCR_EVENT_HDR
*)TCGLogData
,
361 This service is a proxy for commands to the TPM.
363 @param[in] This Indicates the calling context
364 @param[in] TpmInputParameterBlockSize Size of the TPM input parameter block
365 @param[in] TpmInputParameterBlock Pointer to the TPM input parameter block
366 @param[in] TpmOutputParameterBlockSize Size of the TPM output parameter block
367 @param[in] TpmOutputParameterBlock Pointer to the TPM output parameter block
369 @retval EFI_SUCCESS Operation completed successfully.
370 @retval EFI_INVALID_PARAMETER Invalid ordinal.
371 @retval EFI_UNSUPPORTED Current Task Priority Level >= EFI_TPL_CALLBACK.
372 @retval EFI_TIMEOUT The TIS timed-out.
377 TcgDxePassThroughToTpm (
378 IN EFI_TCG_PROTOCOL
*This
,
379 IN UINT32 TpmInputParameterBlockSize
,
380 IN UINT8
*TpmInputParameterBlock
,
381 IN UINT32 TpmOutputParameterBlockSize
,
382 IN UINT8
*TpmOutputParameterBlock
385 TCG_DXE_DATA
*TcgData
;
387 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
389 return TisPcExecute (
392 TpmInputParameterBlock
,
393 (UINTN
) TpmInputParameterBlockSize
,
394 TpmOutputParameterBlock
,
395 (UINTN
) TpmOutputParameterBlockSize
400 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
401 and add an entry to the Event Log.
403 @param[in] TcgData TCG_DXE_DATA structure.
404 @param[in] HashData Physical address of the start of the data buffer
405 to be hashed, extended, and logged.
406 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
407 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
408 @param[in] NewEventData Pointer to the new event data.
410 @retval EFI_SUCCESS Operation completed successfully.
411 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
412 @retval EFI_DEVICE_ERROR The command was unsuccessful.
417 TcgDxeHashLogExtendEventI (
418 IN TCG_DXE_DATA
*TcgData
,
420 IN UINT64 HashDataLen
,
421 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
422 IN UINT8
*NewEventData
427 if (HashDataLen
> 0) {
428 Status
= TpmCommHashAll (
433 ASSERT_EFI_ERROR (Status
);
436 Status
= TpmCommExtend (
438 &NewEventHdr
->Digest
,
439 NewEventHdr
->PCRIndex
,
442 if (!EFI_ERROR (Status
)) {
443 Status
= TcgDxeLogEventI (TcgData
, NewEventHdr
, NewEventData
);
450 This service abstracts the capability to do a hash operation on a data buffer,
451 extend a specific TPM PCR with the hash result, and add an entry to the Event Log
453 @param[in] This Indicates the calling context
454 @param[in] HashData Physical address of the start of the data buffer
455 to be hashed, extended, and logged.
456 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
457 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation
458 @param[in, out] TCGLogData The physical address of the start of the data
459 buffer containing the TCG_PCR_EVENT data structure.
460 @param[in, out] EventNumber The event number of the event just logged.
461 @param[out] EventLogLastEntry Physical address of the first byte of the entry
462 just placed in the Event Log. If the Event Log was
463 empty when this function was called then this physical
464 address will be the same as the physical address of
465 the start of the Event Log.
467 @retval EFI_SUCCESS Operation completed successfully.
468 @retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA.
469 @retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK.
470 @retval EFI_DEVICE_ERROR The command was unsuccessful.
475 TcgDxeHashLogExtendEvent (
476 IN EFI_TCG_PROTOCOL
*This
,
477 IN EFI_PHYSICAL_ADDRESS HashData
,
478 IN UINT64 HashDataLen
,
479 IN TPM_ALGORITHM_ID AlgorithmId
,
480 IN OUT TCG_PCR_EVENT
*TCGLogData
,
481 IN OUT UINT32
*EventNumber
,
482 OUT EFI_PHYSICAL_ADDRESS
*EventLogLastEntry
485 TCG_DXE_DATA
*TcgData
;
487 TcgData
= TCG_DXE_DATA_FROM_THIS (This
);
489 if (TcgData
->BsCap
.TPMDeactivatedFlag
) {
490 return EFI_DEVICE_ERROR
;
493 if (AlgorithmId
!= TPM_ALG_SHA
) {
494 return EFI_UNSUPPORTED
;
497 return TcgDxeHashLogExtendEventI (
499 (UINT8
*) (UINTN
) HashData
,
501 (TCG_PCR_EVENT_HDR
*)TCGLogData
,
506 TCG_DXE_DATA mTcgDxeData
= {
511 TcgDxePassThroughToTpm
,
512 TcgDxeHashLogExtendEvent
515 sizeof (mTcgDxeData
.BsCap
),
522 &mTcgClientAcpiTemplate
,
523 &mTcgServerAcpiTemplate
,
530 Initialize the Event Log and log events passed from the PEI phase.
532 @retval EFI_SUCCESS Operation completed successfully.
533 @retval EFI_OUT_OF_RESOURCES Out of memory.
543 TCG_PCR_EVENT
*TcgEvent
;
544 EFI_PEI_HOB_POINTERS GuidHob
;
545 EFI_PHYSICAL_ADDRESS Lasa
;
547 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
548 Lasa
= mTcgClientAcpiTemplate
.Lasa
;
550 Status
= gBS
->AllocatePages (
553 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE
),
556 if (EFI_ERROR (Status
)) {
559 mTcgClientAcpiTemplate
.Lasa
= Lasa
;
561 // To initialize them as 0xFF is recommended
562 // because the OS can know the last entry for that.
564 SetMem ((VOID
*)(UINTN
)mTcgClientAcpiTemplate
.Lasa
, EFI_TCG_LOG_AREA_SIZE
, 0xFF);
565 mTcgClientAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
568 Lasa
= mTcgServerAcpiTemplate
.Lasa
;
570 Status
= gBS
->AllocatePages (
573 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE
),
576 if (EFI_ERROR (Status
)) {
579 mTcgServerAcpiTemplate
.Lasa
= Lasa
;
581 // To initialize them as 0xFF is recommended
582 // because the OS can know the last entry for that.
584 SetMem ((VOID
*)(UINTN
)mTcgServerAcpiTemplate
.Lasa
, EFI_TCG_LOG_AREA_SIZE
, 0xFF);
585 mTcgServerAcpiTemplate
.Laml
= EFI_TCG_LOG_AREA_SIZE
;
588 GuidHob
.Raw
= GetHobList ();
589 while (!EFI_ERROR (Status
) &&
590 (GuidHob
.Raw
= GetNextGuidHob (&gTcgEventEntryHobGuid
, GuidHob
.Raw
)) != NULL
) {
591 TcgEvent
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
592 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
593 Status
= TcgDxeLogEventI (
595 (TCG_PCR_EVENT_HDR
*)TcgEvent
,
604 Measure and log an action string, and extend the measurement result into PCR[5].
606 @param[in] String A specific string that indicates an Action event.
608 @retval EFI_SUCCESS Operation completed successfully.
609 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
618 TCG_PCR_EVENT_HDR TcgEvent
;
620 TcgEvent
.PCRIndex
= 5;
621 TcgEvent
.EventType
= EV_EFI_ACTION
;
622 TcgEvent
.EventSize
= (UINT32
)AsciiStrLen (String
);
623 return TcgDxeHashLogExtendEventI (
633 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
635 @retval EFI_SUCCESS Operation completed successfully.
636 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
641 MeasureHandoffTables (
646 SMBIOS_TABLE_ENTRY_POINT
*SmbiosTable
;
647 TCG_PCR_EVENT_HDR TcgEvent
;
648 EFI_HANDOFF_TABLE_POINTERS HandoffTables
;
650 Status
= EfiGetSystemConfigurationTable (
651 &gEfiSmbiosTableGuid
,
652 (VOID
**) &SmbiosTable
655 if (!EFI_ERROR (Status
)) {
656 ASSERT (SmbiosTable
!= NULL
);
658 TcgEvent
.PCRIndex
= 1;
659 TcgEvent
.EventType
= EV_EFI_HANDOFF_TABLES
;
660 TcgEvent
.EventSize
= sizeof (HandoffTables
);
662 HandoffTables
.NumberOfTables
= 1;
663 HandoffTables
.TableEntry
[0].VendorGuid
= gEfiSmbiosTableGuid
;
664 HandoffTables
.TableEntry
[0].VendorTable
= SmbiosTable
;
666 DEBUG ((DEBUG_INFO
, "The Smbios Table starts at: 0x%x\n", SmbiosTable
->TableAddress
));
667 DEBUG ((DEBUG_INFO
, "The Smbios Table size: 0x%x\n", SmbiosTable
->TableLength
));
669 Status
= TcgDxeHashLogExtendEventI (
671 (UINT8
*)(UINTN
)SmbiosTable
->TableAddress
,
672 SmbiosTable
->TableLength
,
674 (UINT8
*)&HandoffTables
682 Measure and log Separator event, and extend the measurement result into a specific PCR.
684 @param[in] PCRIndex PCR index.
686 @retval EFI_SUCCESS Operation completed successfully.
687 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
692 MeasureSeparatorEvent (
693 IN TPM_PCRINDEX PCRIndex
696 TCG_PCR_EVENT_HDR TcgEvent
;
700 TcgEvent
.PCRIndex
= PCRIndex
;
701 TcgEvent
.EventType
= EV_SEPARATOR
;
702 TcgEvent
.EventSize
= (UINT32
)sizeof (EventData
);
703 return TcgDxeHashLogExtendEventI (
713 Read an EFI Variable.
715 This function allocates a buffer to return the contents of the variable. The caller is
716 responsible for freeing the buffer.
718 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
719 @param[in] VendorGuid A unique identifier for the vendor.
720 @param[out] VarSize The size of the variable data.
722 @return A pointer to the buffer to return the contents of the variable.Otherwise NULL.
729 IN EFI_GUID
*VendorGuid
,
737 Status
= gRT
->GetVariable (
744 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
748 VarData
= AllocatePool (*VarSize
);
749 if (VarData
!= NULL
) {
750 Status
= gRT
->GetVariable (
757 if (EFI_ERROR (Status
)) {
767 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
769 @param[in] PCRIndex PCR Index.
770 @param[in] EventType Event type.
771 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
772 @param[in] VendorGuid A unique identifier for the vendor.
773 @param[in] VarData The content of the variable data.
774 @param[in] VarSize The size of the variable data.
776 @retval EFI_SUCCESS Operation completed successfully.
777 @retval EFI_OUT_OF_RESOURCES Out of memory.
778 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
784 IN TPM_PCRINDEX PCRIndex
,
785 IN TCG_EVENTTYPE EventType
,
787 IN EFI_GUID
*VendorGuid
,
793 TCG_PCR_EVENT_HDR TcgEvent
;
795 EFI_VARIABLE_DATA
*VarLog
;
797 VarNameLength
= StrLen (VarName
);
798 TcgEvent
.PCRIndex
= PCRIndex
;
799 TcgEvent
.EventType
= EventType
;
800 TcgEvent
.EventSize
= (UINT32
)(sizeof (*VarLog
) + VarNameLength
* sizeof (*VarName
) + VarSize
801 - sizeof (VarLog
->UnicodeName
) - sizeof (VarLog
->VariableData
));
803 VarLog
= (EFI_VARIABLE_DATA
*)AllocatePool (TcgEvent
.EventSize
);
804 if (VarLog
== NULL
) {
805 return EFI_OUT_OF_RESOURCES
;
808 VarLog
->VariableName
= *VendorGuid
;
809 VarLog
->UnicodeNameLength
= VarNameLength
;
810 VarLog
->VariableDataLength
= VarSize
;
814 VarNameLength
* sizeof (*VarName
)
817 (CHAR16
*)VarLog
->UnicodeName
+ VarNameLength
,
822 Status
= TcgDxeHashLogExtendEventI (
834 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
836 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
837 @param[in] VendorGuid A unique identifier for the vendor.
838 @param[out] VarSize The size of the variable data.
839 @param[out] VarData Pointer to the content of the variable.
841 @retval EFI_SUCCESS Operation completed successfully.
842 @retval EFI_OUT_OF_RESOURCES Out of memory.
843 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
848 ReadAndMeasureBootVariable (
850 IN EFI_GUID
*VendorGuid
,
857 *VarData
= ReadVariable (VarName
, VendorGuid
, VarSize
);
858 if (*VarData
== NULL
) {
859 return EFI_NOT_FOUND
;
862 Status
= MeasureVariable (
864 EV_EFI_VARIABLE_BOOT
,
874 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
876 The EFI boot variables are BootOrder and Boot#### variables.
878 @retval EFI_SUCCESS Operation completed successfully.
879 @retval EFI_OUT_OF_RESOURCES Out of memory.
880 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
885 MeasureAllBootVariables (
896 Status
= ReadAndMeasureBootVariable (
898 &gEfiGlobalVariableGuid
,
902 if (Status
== EFI_NOT_FOUND
) {
905 ASSERT (BootOrder
!= NULL
);
907 if (EFI_ERROR (Status
)) {
908 FreePool (BootOrder
);
912 BootCount
/= sizeof (*BootOrder
);
913 for (Index
= 0; Index
< BootCount
; Index
++) {
914 UnicodeSPrint (mBootVarName
, sizeof (mBootVarName
), L
"Boot%04x", BootOrder
[Index
]);
915 Status
= ReadAndMeasureBootVariable (
917 &gEfiGlobalVariableGuid
,
921 if (!EFI_ERROR (Status
)) {
922 FreePool (BootVarData
);
926 FreePool (BootOrder
);
931 Ready to Boot Event notification handler.
933 Sequence of OS boot events is measured in this event notification handler.
935 @param[in] Event Event whose notification function is being invoked
936 @param[in] Context Pointer to the notification function's context
947 TPM_PCRINDEX PcrIndex
;
949 if (mBootAttempts
== 0) {
952 // Measure handoff tables.
954 Status
= MeasureHandoffTables ();
955 if (EFI_ERROR (Status
)) {
956 DEBUG ((EFI_D_ERROR
, "HOBs not Measured. Error!\n"));
960 // Measure BootOrder & Boot#### variables.
962 Status
= MeasureAllBootVariables ();
963 if (EFI_ERROR (Status
)) {
964 DEBUG ((EFI_D_ERROR
, "Boot Variables not Measured. Error!\n"));
968 // 1. This is the first boot attempt.
970 Status
= TcgMeasureAction (
971 EFI_CALLING_EFI_APPLICATION
973 ASSERT_EFI_ERROR (Status
);
976 // 2. Draw a line between pre-boot env and entering post-boot env.
978 for (PcrIndex
= 0; PcrIndex
< 8; PcrIndex
++) {
979 Status
= MeasureSeparatorEvent (PcrIndex
);
980 ASSERT_EFI_ERROR (Status
);
984 // 3. Measure GPT. It would be done in SAP driver.
988 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
992 // 5. Read & Measure variable. BootOrder already measured.
996 // 6. Not first attempt, meaning a return from last attempt
998 Status
= TcgMeasureAction (
999 EFI_RETURNING_FROM_EFI_APPLICATOIN
1001 ASSERT_EFI_ERROR (Status
);
1004 DEBUG ((EFI_D_INFO
, "TPM TcgDxe Measure Data when ReadyToBoot\n"));
1006 // Increase boot attempt counter.
1012 Install TCG ACPI Table when ACPI Table Protocol is available.
1014 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1015 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1016 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1018 @param[in] Event Event whose notification function is being invoked
1019 @param[in] Context Pointer to the notification function's context
1030 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
1033 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
1034 if (EFI_ERROR (Status
)) {
1038 if (PcdGet8 (PcdTpmPlatformClass
) == TCG_PLATFORM_TYPE_CLIENT
) {
1041 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1042 // service of the ACPI table protocol to install it.
1044 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgClientAcpiTemplate
, sizeof (mTcgClientAcpiTemplate
));
1045 mTcgClientAcpiTemplate
.Header
.Checksum
= Checksum
;
1047 Status
= AcpiTable
->InstallAcpiTable (
1049 &mTcgClientAcpiTemplate
,
1050 sizeof (mTcgClientAcpiTemplate
),
1056 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1057 // service of the ACPI table protocol to install it.
1059 Checksum
= CalculateCheckSum8 ((UINT8
*)&mTcgServerAcpiTemplate
, sizeof (mTcgServerAcpiTemplate
));
1060 mTcgServerAcpiTemplate
.Header
.Checksum
= Checksum
;
1062 Status
= AcpiTable
->InstallAcpiTable (
1064 &mTcgServerAcpiTemplate
,
1065 sizeof (mTcgServerAcpiTemplate
),
1069 ASSERT_EFI_ERROR (Status
);
1073 Exit Boot Services Event notification handler.
1075 Measure invocation and success of ExitBootServices.
1077 @param[in] Event Event whose notification function is being invoked
1078 @param[in] Context Pointer to the notification function's context
1083 OnExitBootServices (
1091 // Measure invocation of ExitBootServices,
1093 Status
= TcgMeasureAction (
1094 EFI_EXIT_BOOT_SERVICES_INVOCATION
1096 ASSERT_EFI_ERROR (Status
);
1099 // Measure success of ExitBootServices
1101 Status
= TcgMeasureAction (
1102 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1104 ASSERT_EFI_ERROR (Status
);
1108 Exit Boot Services Failed Event notification handler.
1110 Measure Failure of ExitBootServices.
1112 @param[in] Event Event whose notification function is being invoked
1113 @param[in] Context Pointer to the notification function's context
1118 OnExitBootServicesFailed (
1126 // Measure Failure of ExitBootServices,
1128 Status
= TcgMeasureAction (
1129 EFI_EXIT_BOOT_SERVICES_FAILED
1131 ASSERT_EFI_ERROR (Status
);
1136 Get TPM Deactivated state.
1138 @param[out] TPMDeactivatedFlag Returns TPM Deactivated state.
1140 @retval EFI_SUCCESS Operation completed successfully.
1141 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1146 OUT BOOLEAN
*TPMDeactivatedFlag
1150 TPM_STCLEAR_FLAGS VFlags
;
1152 Status
= TpmCommGetFlags (
1153 mTcgDxeData
.TpmHandle
,
1154 TPM_CAP_FLAG_VOLATILE
,
1158 if (!EFI_ERROR (Status
)) {
1159 *TPMDeactivatedFlag
= VFlags
.deactivated
;
1166 The driver's entry point.
1168 It publishes EFI TCG Protocol.
1170 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1171 @param[in] SystemTable A pointer to the EFI System Table.
1173 @retval EFI_SUCCESS The entry point is executed successfully.
1174 @retval other Some error occurs when executing this entry point.
1180 IN EFI_HANDLE ImageHandle
,
1181 IN EFI_SYSTEM_TABLE
*SystemTable
1188 mTcgDxeData
.TpmHandle
= (TIS_TPM_HANDLE
)(UINTN
)TPM_BASE_ADDRESS
;
1189 Status
= TisPcRequestUseTpm (mTcgDxeData
.TpmHandle
);
1190 if (EFI_ERROR (Status
)) {
1191 DEBUG ((EFI_D_ERROR
, "TPM not detected!\n"));
1195 Status
= GetTpmStatus (&mTcgDxeData
.BsCap
.TPMDeactivatedFlag
);
1196 if (EFI_ERROR (Status
)) {
1199 "Line %d in file " __FILE__
":\n "
1200 "DriverEntry: TPM not working properly\n",
1206 Status
= gBS
->InstallProtocolInterface (
1208 &gEfiTcgProtocolGuid
,
1209 EFI_NATIVE_INTERFACE
,
1210 &mTcgDxeData
.TcgProtocol
1212 if (!EFI_ERROR (Status
) && !mTcgDxeData
.BsCap
.TPMDeactivatedFlag
) {
1214 // Setup the log area and copy event log from hob list to it
1216 Status
= SetupEventLog ();
1217 ASSERT_EFI_ERROR (Status
);
1220 // Measure handoff tables, Boot#### variables etc.
1222 Status
= EfiCreateEventReadyToBootEx (
1229 Status
= gBS
->CreateEventEx (
1234 &gEfiEventExitBootServicesGuid
,
1239 // Measure Exit Boot Service failed
1241 Status
= gBS
->CreateEventEx (
1244 OnExitBootServicesFailed
,
1246 &gEventExitBootServicesFailedGuid
,
1252 // Install ACPI Table
1254 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid
, TPL_CALLBACK
, InstallAcpiTable
, NULL
, &Registration
);