-/** @file \r
+/** @file\r
This module implements TCG EFI Protocol.\r
- \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
+\r
+Caution: This module requires additional review when modified.\r
+This driver will have external input - TcgDxePassThroughToTpm\r
+This external input must be validated carefully to avoid security issue like\r
+buffer overflow, integer overflow.\r
+\r
+TcgDxePassThroughToTpm() will receive untrusted input and do basic validation.\r
+\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
**/\r
#include <IndustryStandard/Tpm12.h>\r
#include <IndustryStandard/Acpi.h>\r
#include <IndustryStandard/PeImage.h>\r
-#include <IndustryStandard/SmBios.h>\r
+#include <IndustryStandard/TcpaAcpi.h>\r
\r
#include <Guid/GlobalVariable.h>\r
-#include <Guid/SmBios.h>\r
#include <Guid/HobList.h>\r
#include <Guid/TcgEventHob.h>\r
#include <Guid/EventGroup.h>\r
+#include <Guid/EventExitBootServiceFailed.h>\r
+#include <Guid/TpmInstance.h>\r
+\r
#include <Protocol/DevicePath.h>\r
#include <Protocol/TcgService.h>\r
#include <Protocol/AcpiTable.h>\r
+#include <Protocol/MpService.h>\r
\r
#include <Library/DebugLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/BaseLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/PrintLib.h>\r
-#include <Library/TpmCommLib.h>\r
+#include <Library/Tpm12DeviceLib.h>\r
#include <Library/PcdLib.h>\r
#include <Library/UefiLib.h>\r
-\r
-#include "TpmComm.h"\r
-\r
-#define EFI_TCG_LOG_AREA_SIZE 0x10000\r
-\r
-#pragma pack (1)\r
-\r
-typedef struct _EFI_TCG_CLIENT_ACPI_TABLE {\r
- EFI_ACPI_DESCRIPTION_HEADER Header;\r
- UINT16 PlatformClass;\r
- UINT32 Laml;\r
- EFI_PHYSICAL_ADDRESS Lasa;\r
-} EFI_TCG_CLIENT_ACPI_TABLE;\r
-\r
-typedef struct _EFI_TCG_SERVER_ACPI_TABLE {\r
- EFI_ACPI_DESCRIPTION_HEADER Header;\r
- UINT16 PlatformClass;\r
- UINT16 Reserved0;\r
- UINT64 Laml;\r
- EFI_PHYSICAL_ADDRESS Lasa;\r
- UINT16 SpecRev;\r
- UINT8 DeviceFlags;\r
- UINT8 InterruptFlags;\r
- UINT8 Gpe;\r
- UINT8 Reserved1[3];\r
- UINT32 GlobalSysInt;\r
- EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE BaseAddress;\r
- UINT32 Reserved2;\r
- EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ConfigAddress;\r
- UINT8 PciSegNum;\r
- UINT8 PciBusNum;\r
- UINT8 PciDevNum;\r
- UINT8 PciFuncNum;\r
-} EFI_TCG_SERVER_ACPI_TABLE;\r
-\r
-#pragma pack ()\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/Tpm12CommandLib.h>\r
+#include <Library/BaseCryptLib.h>\r
\r
#define TCG_DXE_DATA_FROM_THIS(this) \\r
BASE_CR (this, TCG_DXE_DATA, TcgProtocol)\r
EFI_TCG_SERVER_ACPI_TABLE *TcgServerAcpiTable;\r
UINTN EventLogSize;\r
UINT8 *LastEvent;\r
- TIS_TPM_HANDLE TpmHandle;\r
} TCG_DXE_DATA;\r
\r
\r
//\r
// The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,\r
// the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,\r
-// this _UID can be changed and should match with the _UID setting of the TPM \r
-// ACPI device object \r
+// this _UID can be changed and should match with the _UID setting of the TPM\r
+// ACPI device object\r
//\r
EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate = {\r
{\r
0, // Reserved\r
0, // Log Area Max Length\r
(EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1), // Log Area Start Address\r
- 0x0100, // TCG Specification revision 1.0\r
- 2, // Device Flags\r
+ 0x0120, // TCG Specification revision 1.2\r
+ 0, // Device Flags\r
0, // Interrupt Flags\r
0, // GPE\r
{0}, // Reserved 3 bytes\r
0,\r
0,\r
EFI_ACPI_3_0_BYTE,\r
- TPM_BASE_ADDRESS // Base Address\r
+ 0 // Base Address\r
},\r
0, // Reserved\r
{0}, // Configuration Address\r
CHAR16 mBootVarName[] = L"BootOrder";\r
\r
/**\r
- This service provides EFI protocol capability information, state information \r
+ Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function\r
+ Caller is responsible to free LocationBuf.\r
+\r
+ @param[out] LocationBuf Returns Processor Location Buffer.\r
+ @param[out] Num Returns processor number.\r
+\r
+ @retval EFI_SUCCESS Operation completed successfully.\r
+ @retval EFI_UNSUPPORTED MpService protocol not found.\r
+\r
+**/\r
+EFI_STATUS\r
+GetProcessorsCpuLocation (\r
+ OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,\r
+ OUT UINTN *Num\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_MP_SERVICES_PROTOCOL *MpProtocol;\r
+ UINTN ProcessorNum;\r
+ UINTN EnabledProcessorNum;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfo;\r
+ EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
+ UINTN Index;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // MP protocol is not installed\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = MpProtocol->GetNumberOfProcessors(\r
+ MpProtocol,\r
+ &ProcessorNum,\r
+ &EnabledProcessorNum\r
+ );\r
+ if (EFI_ERROR(Status)){\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->AllocatePool(\r
+ EfiBootServicesData,\r
+ sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
+ (VOID **) &ProcessorLocBuf\r
+ );\r
+ if (EFI_ERROR(Status)){\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get each processor Location info\r
+ //\r
+ for (Index = 0; Index < ProcessorNum; Index++) {\r
+ Status = MpProtocol->GetProcessorInfo(\r
+ MpProtocol,\r
+ Index,\r
+ &ProcessorInfo\r
+ );\r
+ if (EFI_ERROR(Status)){\r
+ FreePool(ProcessorLocBuf);\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get all Processor Location info & measure\r
+ //\r
+ CopyMem(\r
+ &ProcessorLocBuf[Index],\r
+ &ProcessorInfo.Location,\r
+ sizeof(EFI_CPU_PHYSICAL_LOCATION)\r
+ );\r
+ }\r
+\r
+ *LocationBuf = ProcessorLocBuf;\r
+ *Num = ProcessorNum;\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This service provides EFI protocol capability information, state information\r
about the TPM, and Event Log state information.\r
\r
@param[in] This Indicates the calling context\r
- @param[out] ProtocolCapability The callee allocates memory for a TCG_BOOT_SERVICE_CAPABILITY \r
- structure and fills in the fields with the EFI protocol \r
+ @param[out] ProtocolCapability The callee allocates memory for a TCG_BOOT_SERVICE_CAPABILITY\r
+ structure and fills in the fields with the EFI protocol\r
capability information and the current TPM state information.\r
- @param[out] TCGFeatureFlags This is a pointer to the feature flags. No feature \r
- flags are currently defined so this parameter \r
- MUST be set to 0. However, in the future, \r
- feature flags may be defined that, for example, \r
+ @param[out] TCGFeatureFlags This is a pointer to the feature flags. No feature\r
+ flags are currently defined so this parameter\r
+ MUST be set to 0. However, in the future,\r
+ feature flags may be defined that, for example,\r
enable hash algorithm agility.\r
@param[out] EventLogLocation This is a pointer to the address of the event log in memory.\r
- @param[out] EventLogLastEntry If the Event Log contains more than one entry, \r
- this is a pointer to the address of the start of \r
- the last entry in the event log in memory. \r
+ @param[out] EventLogLastEntry If the Event Log contains more than one entry,\r
+ this is a pointer to the address of the start of\r
+ the last entry in the event log in memory.\r
\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_INVALID_PARAMETER ProtocolCapability does not match TCG capability.\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
}\r
\r
if (EventLogLastEntry != NULL) {\r
- if (TcgData->BsCap.TPMDeactivatedFlag) {\r
+ if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) {\r
*EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;\r
} else {\r
*EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)TcgData->LastEvent;\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+Single function calculates SHA1 digest value for all raw data. It\r
+combines Sha1Init(), Sha1Update() and Sha1Final().\r
+\r
+@param[in] Data Raw data to be digested.\r
+@param[in] DataLen Size of the raw data.\r
+@param[out] Digest Pointer to a buffer that stores the final digest.\r
+\r
+@retval EFI_SUCCESS Always successfully calculate the final digest.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TpmCommHashAll (\r
+ IN CONST UINT8 *Data,\r
+ IN UINTN DataLen,\r
+ OUT TPM_DIGEST *Digest\r
+ )\r
+{\r
+ VOID *Sha1Ctx;\r
+ UINTN CtxSize;\r
+\r
+ CtxSize = Sha1GetContextSize ();\r
+ Sha1Ctx = AllocatePool (CtxSize);\r
+ ASSERT (Sha1Ctx != NULL);\r
+\r
+ Sha1Init (Sha1Ctx);\r
+ Sha1Update (Sha1Ctx, Data, DataLen);\r
+ Sha1Final (Sha1Ctx, (UINT8 *)Digest);\r
+\r
+ FreePool (Sha1Ctx);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
This service abstracts the capability to do a hash operation on a data buffer.\r
- \r
+\r
@param[in] This Indicates the calling context\r
@param[in] HashData Pointer to the data buffer to be hashed\r
@param[in] HashDataLen Length of the data buffer to be hashed\r
@param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation\r
@param[in, out] HashedDataLen Resultant length of the hashed data\r
- @param[in, out] HashedDataResult Resultant buffer of the hashed data \r
- \r
+ @param[in, out] HashedDataResult Resultant buffer of the hashed data\r
+\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_INVALID_PARAMETER HashDataLen is NULL.\r
@retval EFI_INVALID_PARAMETER HashDataLenResult is NULL.\r
@retval EFI_OUT_OF_RESOURCES Cannot allocate buffer of size *HashedDataLen.\r
@retval EFI_UNSUPPORTED AlgorithmId not supported.\r
@retval EFI_BUFFER_TOO_SMALL *HashedDataLen < sizeof (TCG_DIGEST).\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
}\r
*HashedDataLen = sizeof (TPM_DIGEST);\r
\r
+ if (*HashedDataResult == NULL) {\r
+ *HashedDataResult = AllocatePool ((UINTN) *HashedDataLen);\r
+ }\r
+\r
return TpmCommHashAll (\r
HashData,\r
(UINTN) HashDataLen,\r
}\r
}\r
\r
+/**\r
+Add a new entry to the Event Log.\r
+\r
+@param[in, out] EventLogPtr Pointer to the Event Log data.\r
+@param[in, out] LogSize Size of the Event Log.\r
+@param[in] MaxSize Maximum size of the Event Log.\r
+@param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
+@param[in] NewEventData Pointer to the new event data.\r
+\r
+@retval EFI_SUCCESS The new event log entry was added.\r
+@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
+\r
+**/\r
+EFI_STATUS\r
+TpmCommLogEvent (\r
+ IN OUT UINT8 **EventLogPtr,\r
+ IN OUT UINTN *LogSize,\r
+ IN UINTN MaxSize,\r
+ IN TCG_PCR_EVENT_HDR *NewEventHdr,\r
+ IN UINT8 *NewEventData\r
+ )\r
+{\r
+ UINTN NewLogSize;\r
+\r
+ //\r
+ // Prevent Event Overflow\r
+ //\r
+ if ((UINTN) NewEventHdr->EventSize > MAX_UINTN - sizeof (*NewEventHdr)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ NewLogSize = sizeof (*NewEventHdr) + NewEventHdr->EventSize;\r
+ if (NewLogSize > MaxSize - *LogSize) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ *EventLogPtr += *LogSize;\r
+ *LogSize += NewLogSize;\r
+ CopyMem (*EventLogPtr, NewEventHdr, sizeof (*NewEventHdr));\r
+ CopyMem (\r
+ *EventLogPtr + sizeof (*NewEventHdr),\r
+ NewEventData,\r
+ NewEventHdr->EventSize\r
+ );\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Add a new entry to the Event Log.\r
\r
@param[in] TcgData TCG_DXE_DATA structure.\r
- @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
- @param[in] NewEventData Pointer to the new event data. \r
- \r
+ @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
+ @param[in] NewEventData Pointer to the new event data.\r
+\r
@retval EFI_SUCCESS The new event log entry was added.\r
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
\r
This service abstracts the capability to add an entry to the Event Log.\r
\r
@param[in] This Indicates the calling context\r
- @param[in] TCGLogData Pointer to the start of the data buffer containing \r
- the TCG_PCR_EVENT data structure. All fields in \r
+ @param[in] TCGLogData Pointer to the start of the data buffer containing\r
+ the TCG_PCR_EVENT data structure. All fields in\r
this structure are properly filled by the caller.\r
@param[in, out] EventNumber The event number of the event just logged\r
- @param[in] Flags Indicate additional flags. Only one flag has been \r
- defined at this time, which is 0x01 and means the \r
- extend operation should not be performed. All \r
- other bits are reserved. \r
- \r
+ @param[in] Flags Indicate additional flags. Only one flag has been\r
+ defined at this time, which is 0x01 and means the\r
+ extend operation should not be performed. All\r
+ other bits are reserved.\r
+\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_OUT_OF_RESOURCES Insufficient memory in the event log to complete this action.\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
{\r
TCG_DXE_DATA *TcgData;\r
\r
+ if (TCGLogData == NULL){\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
- \r
- if (TcgData->BsCap.TPMDeactivatedFlag) {\r
+\r
+ if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) {\r
return EFI_DEVICE_ERROR;\r
}\r
return TcgDxeLogEventI (\r
@retval EFI_INVALID_PARAMETER Invalid ordinal.\r
@retval EFI_UNSUPPORTED Current Task Priority Level >= EFI_TPL_CALLBACK.\r
@retval EFI_TIMEOUT The TIS timed-out.\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
IN UINT8 *TpmOutputParameterBlock\r
)\r
{\r
- TCG_DXE_DATA *TcgData;\r
-\r
- TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
+ if (TpmInputParameterBlock == NULL ||\r
+ TpmOutputParameterBlock == NULL ||\r
+ TpmInputParameterBlockSize == 0 ||\r
+ TpmOutputParameterBlockSize == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
- return TisPcExecute (\r
- TcgData->TpmHandle,\r
- "%r%/%r",\r
+ return Tpm12SubmitCommand (\r
+ TpmInputParameterBlockSize,\r
TpmInputParameterBlock,\r
- (UINTN) TpmInputParameterBlockSize,\r
- TpmOutputParameterBlock,\r
- (UINTN) TpmOutputParameterBlockSize\r
+ &TpmOutputParameterBlockSize,\r
+ TpmOutputParameterBlock\r
);\r
}\r
\r
and add an entry to the Event Log.\r
\r
@param[in] TcgData TCG_DXE_DATA structure.\r
- @param[in] HashData Physical address of the start of the data buffer \r
+ @param[in] HashData Physical address of the start of the data buffer\r
to be hashed, extended, and logged.\r
@param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
- @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
- @param[in] NewEventData Pointer to the new event data. \r
+ @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
+ @param[in] NewEventData Pointer to the new event data.\r
\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
{\r
EFI_STATUS Status;\r
\r
- if (HashDataLen > 0) {\r
+ if (!TcgData->BsCap.TPMPresentFlag) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (HashDataLen > 0 || HashData != NULL) {\r
Status = TpmCommHashAll (\r
HashData,\r
(UINTN) HashDataLen,\r
&NewEventHdr->Digest\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((DEBUG_ERROR, "TpmCommHashAll Failed. %x\n", Status));\r
+ goto Done;\r
+ }\r
}\r
\r
- Status = TpmCommExtend (\r
- TcgData->TpmHandle,\r
+ Status = Tpm12Extend (\r
&NewEventHdr->Digest,\r
NewEventHdr->PCRIndex,\r
NULL\r
Status = TcgDxeLogEventI (TcgData, NewEventHdr, NewEventData);\r
}\r
\r
+Done:\r
+ if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) {\r
+ DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEventI - %r. Disable TPM.\n", Status));\r
+ TcgData->BsCap.TPMPresentFlag = FALSE;\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
+ );\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
return Status;\r
}\r
\r
extend a specific TPM PCR with the hash result, and add an entry to the Event Log\r
\r
@param[in] This Indicates the calling context\r
- @param[in] HashData Physical address of the start of the data buffer \r
+ @param[in] HashData Physical address of the start of the data buffer\r
to be hashed, extended, and logged.\r
@param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
@param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation\r
- @param[in, out] TCGLogData The physical address of the start of the data \r
+ @param[in, out] TCGLogData The physical address of the start of the data\r
buffer containing the TCG_PCR_EVENT data structure.\r
@param[in, out] EventNumber The event number of the event just logged.\r
- @param[out] EventLogLastEntry Physical address of the first byte of the entry \r
- just placed in the Event Log. If the Event Log was \r
- empty when this function was called then this physical \r
- address will be the same as the physical address of \r
+ @param[out] EventLogLastEntry Physical address of the first byte of the entry\r
+ just placed in the Event Log. If the Event Log was\r
+ empty when this function was called then this physical\r
+ address will be the same as the physical address of\r
the start of the Event Log.\r
\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA.\r
@retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK.\r
@retval EFI_DEVICE_ERROR The command was unsuccessful.\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
)\r
{\r
TCG_DXE_DATA *TcgData;\r
+ EFI_STATUS Status;\r
+\r
+ if (TCGLogData == NULL || EventLogLastEntry == NULL){\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
- \r
- if (TcgData->BsCap.TPMDeactivatedFlag) {\r
+\r
+ if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) {\r
return EFI_DEVICE_ERROR;\r
}\r
- \r
+\r
if (AlgorithmId != TPM_ALG_SHA) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
- return TcgDxeHashLogExtendEventI (\r
- TcgData,\r
- (UINT8 *) (UINTN) HashData,\r
- HashDataLen,\r
- (TCG_PCR_EVENT_HDR*)TCGLogData,\r
- TCGLogData->Event\r
- );\r
+ if (HashData == 0 && HashDataLen > 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = TcgDxeHashLogExtendEventI (\r
+ TcgData,\r
+ (UINT8 *) (UINTN) HashData,\r
+ HashDataLen,\r
+ (TCG_PCR_EVENT_HDR*)TCGLogData,\r
+ TCGLogData->Event\r
+ );\r
+\r
+ if (!EFI_ERROR(Status)){\r
+ *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN) TcgData->LastEvent;\r
+ }\r
+\r
+ return Status;\r
}\r
\r
TCG_DXE_DATA mTcgDxeData = {\r
&mTcgClientAcpiTemplate,\r
&mTcgServerAcpiTemplate,\r
0,\r
- NULL,\r
NULL\r
};\r
\r
TCG_PCR_EVENT *TcgEvent;\r
EFI_PEI_HOB_POINTERS GuidHob;\r
EFI_PHYSICAL_ADDRESS Lasa;\r
- \r
+\r
if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
Lasa = mTcgClientAcpiTemplate.Lasa;\r
- \r
+\r
Status = gBS->AllocatePages (\r
AllocateMaxAddress,\r
EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),\r
+ EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
&Lasa\r
);\r
if (EFI_ERROR (Status)) {\r
}\r
mTcgClientAcpiTemplate.Lasa = Lasa;\r
//\r
- // To initialize them as 0xFF is recommended \r
+ // To initialize them as 0xFF is recommended\r
// because the OS can know the last entry for that.\r
//\r
- SetMem ((VOID *)(UINTN)mTcgClientAcpiTemplate.Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF);\r
- mTcgClientAcpiTemplate.Laml = EFI_TCG_LOG_AREA_SIZE;\r
- \r
+ SetMem ((VOID *)(UINTN)mTcgClientAcpiTemplate.Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
+ mTcgClientAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
+\r
} else {\r
Lasa = mTcgServerAcpiTemplate.Lasa;\r
- \r
+\r
Status = gBS->AllocatePages (\r
AllocateMaxAddress,\r
EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),\r
+ EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
&Lasa\r
);\r
if (EFI_ERROR (Status)) {\r
}\r
mTcgServerAcpiTemplate.Lasa = Lasa;\r
//\r
- // To initialize them as 0xFF is recommended \r
+ // To initialize them as 0xFF is recommended\r
// because the OS can know the last entry for that.\r
//\r
- SetMem ((VOID *)(UINTN)mTcgServerAcpiTemplate.Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF);\r
- mTcgServerAcpiTemplate.Laml = EFI_TCG_LOG_AREA_SIZE;\r
+ SetMem ((VOID *)(UINTN)mTcgServerAcpiTemplate.Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
+ mTcgServerAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
}\r
\r
GuidHob.Raw = GetHobList ();\r
- while (!EFI_ERROR (Status) && \r
+ while (!EFI_ERROR (Status) &&\r
(GuidHob.Raw = GetNextGuidHob (&gTcgEventEntryHobGuid, GuidHob.Raw)) != NULL) {\r
TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);\r
GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
/**\r
Measure and log an action string, and extend the measurement result into PCR[5].\r
\r
- @param[in] String A specific string that indicates an Action event. \r
- \r
+ @param[in] String A specific string that indicates an Action event.\r
+\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
\r
)\r
{\r
EFI_STATUS Status;\r
- SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;\r
TCG_PCR_EVENT_HDR TcgEvent;\r
EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
+ UINTN ProcessorNum;\r
+ EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
\r
- Status = EfiGetSystemConfigurationTable (\r
- &gEfiSmbiosTableGuid,\r
- (VOID **) &SmbiosTable\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- ASSERT (SmbiosTable != NULL);\r
-\r
- TcgEvent.PCRIndex = 1;\r
- TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;\r
- TcgEvent.EventSize = sizeof (HandoffTables);\r
-\r
- HandoffTables.NumberOfTables = 1;\r
- HandoffTables.TableEntry[0].VendorGuid = gEfiSmbiosTableGuid;\r
- HandoffTables.TableEntry[0].VendorTable = SmbiosTable;\r
-\r
- DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress));\r
- DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength));\r
+ ProcessorLocBuf = NULL;\r
+ Status = EFI_SUCCESS;\r
\r
- Status = TcgDxeHashLogExtendEventI (\r
- &mTcgDxeData,\r
- (UINT8*)(UINTN)SmbiosTable->TableAddress,\r
- SmbiosTable->TableLength,\r
- &TcgEvent,\r
- (UINT8*)&HandoffTables\r
- );\r
+ if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
+ //\r
+ // Tcg Server spec.\r
+ // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
+ //\r
+ Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
+\r
+ if (!EFI_ERROR(Status)){\r
+ TcgEvent.PCRIndex = 1;\r
+ TcgEvent.EventType = EV_TABLE_OF_DEVICES;\r
+ TcgEvent.EventSize = sizeof (HandoffTables);\r
+\r
+ HandoffTables.NumberOfTables = 1;\r
+ HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;\r
+ HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;\r
+\r
+ Status = TcgDxeHashLogExtendEventI (\r
+ &mTcgDxeData,\r
+ (UINT8*)(UINTN)ProcessorLocBuf,\r
+ sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
+ &TcgEvent,\r
+ (UINT8*)&HandoffTables\r
+ );\r
+\r
+ FreePool(ProcessorLocBuf);\r
+ }\r
}\r
\r
return Status;\r
/**\r
Measure and log Separator event, and extend the measurement result into a specific PCR.\r
\r
- @param[in] PCRIndex PCR index. \r
+ @param[in] PCRIndex PCR index.\r
\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
\r
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
@param[in] VendorGuid A unique identifier for the vendor.\r
- @param[out] VarSize The size of the variable data. \r
+ @param[out] VarSize The size of the variable data.\r
\r
@return A pointer to the buffer to return the contents of the variable.Otherwise NULL.\r
\r
/**\r
Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
\r
- @param[in] PCRIndex PCR Index. \r
- @param[in] EventType Event type. \r
+ @param[in] PCRIndex PCR Index.\r
+ @param[in] EventType Event type.\r
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
@param[in] VendorGuid A unique identifier for the vendor.\r
- @param[in] VarData The content of the variable data. \r
- @param[in] VarSize The size of the variable data. \r
- \r
+ @param[in] VarData The content of the variable data.\r
+ @param[in] VarSize The size of the variable data.\r
+\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_OUT_OF_RESOURCES Out of memory.\r
@retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
\r
Status = TcgDxeHashLogExtendEventI (\r
&mTcgDxeData,\r
- (UINT8*)VarData,\r
- VarSize,\r
+ (UINT8*)VarLog,\r
+ TcgEvent.EventSize,\r
&TcgEvent,\r
(UINT8*)VarLog\r
);\r
\r
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
@param[in] VendorGuid A unique identifier for the vendor.\r
- @param[out] VarSize The size of the variable data. \r
- @param[out] VarData Pointer to the content of the variable. \r
- \r
+ @param[out] VarSize The size of the variable data.\r
+ @param[out] VarData Pointer to the content of the variable.\r
+\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_OUT_OF_RESOURCES Out of memory.\r
@retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
&BootCount,\r
(VOID **) &BootOrder\r
);\r
- if (Status == EFI_NOT_FOUND) {\r
+ if (Status == EFI_NOT_FOUND || BootOrder == NULL) {\r
return EFI_SUCCESS;\r
}\r
- ASSERT (BootOrder != NULL);\r
\r
if (EFI_ERROR (Status)) {\r
+ //\r
+ // BootOrder can't be NULL if status is not EFI_NOT_FOUND\r
+ //\r
FreePool (BootOrder);\r
return Status;\r
}\r
Status = TcgMeasureAction (\r
EFI_CALLING_EFI_APPLICATION\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
+ }\r
\r
//\r
// 2. Draw a line between pre-boot env and entering post-boot env.\r
//\r
for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {\r
Status = MeasureSeparatorEvent (PcrIndex);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));\r
+ }\r
}\r
\r
//\r
Status = TcgMeasureAction (\r
EFI_RETURNING_FROM_EFI_APPLICATOIN\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
+ }\r
}\r
\r
DEBUG ((EFI_D_INFO, "TPM TcgDxe Measure Data when ReadyToBoot\n"));\r
/**\r
Install TCG ACPI Table when ACPI Table Protocol is available.\r
\r
- A system's firmware uses an ACPI table to identify the system's TCG capabilities \r
- to the Post-Boot environment. The information in this ACPI table is not guaranteed \r
- to be valid until the Host Platform transitions from pre-boot state to post-boot state. \r
+ A system's firmware uses an ACPI table to identify the system's TCG capabilities\r
+ to the Post-Boot environment. The information in this ACPI table is not guaranteed\r
+ to be valid until the Host Platform transitions from pre-boot state to post-boot state.\r
\r
@param[in] Event Event whose notification function is being invoked\r
@param[in] Context Pointer to the notification function's context\r
EFI_STATUS Status;\r
EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
UINT8 Checksum;\r
+ UINT64 OemTableId;\r
\r
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);\r
if (EFI_ERROR (Status)) {\r
}\r
\r
if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
- \r
+ CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));\r
+ OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
+ CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
+ mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
+ mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
+ mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
//\r
- // The ACPI table must be checksumed before calling the InstallAcpiTable() \r
+ // The ACPI table must be checksumed before calling the InstallAcpiTable()\r
// service of the ACPI table protocol to install it.\r
//\r
Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));\r
&TableKey\r
);\r
} else {\r
-\r
+ CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));\r
+ OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
+ CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
+ mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
+ mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
+ mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
//\r
- // The ACPI table must be checksumed before calling the InstallAcpiTable() \r
+ // The ACPI table must be checksumed before calling the InstallAcpiTable()\r
// service of the ACPI table protocol to install it.\r
//\r
Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));\r
mTcgServerAcpiTemplate.Header.Checksum = Checksum;\r
\r
+ mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress);\r
Status = AcpiTable->InstallAcpiTable (\r
AcpiTable,\r
&mTcgServerAcpiTemplate,\r
&TableKey\r
);\r
}\r
- ASSERT_EFI_ERROR (Status);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure"));\r
+ }\r
}\r
\r
/**\r
Status = TcgMeasureAction (\r
EFI_EXIT_BOOT_SERVICES_INVOCATION\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));\r
+ }\r
\r
//\r
// Measure success of ExitBootServices\r
Status = TcgMeasureAction (\r
EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)){\r
+ DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));\r
+ }\r
+}\r
+\r
+/**\r
+ Exit Boot Services Failed Event notification handler.\r
+\r
+ Measure Failure of ExitBootServices.\r
+\r
+ @param[in] Event Event whose notification function is being invoked\r
+ @param[in] Context Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnExitBootServicesFailed (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Measure Failure of ExitBootServices,\r
+ //\r
+ Status = TcgMeasureAction (\r
+ EFI_EXIT_BOOT_SERVICES_FAILED\r
+ );\r
+ if (EFI_ERROR (Status)){\r
+ DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));\r
+ }\r
}\r
\r
/**\r
Get TPM Deactivated state.\r
\r
- @param[out] TPMDeactivatedFlag Returns TPM Deactivated state. \r
+ @param[out] TPMDeactivatedFlag Returns TPM Deactivated state.\r
\r
@retval EFI_SUCCESS Operation completed successfully.\r
@retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
**/\r
EFI_STATUS\r
GetTpmStatus (\r
- OUT BOOLEAN *TPMDeactivatedFlag\r
+ OUT BOOLEAN *TPMDeactivatedFlag\r
)\r
{\r
- EFI_STATUS Status;\r
- TPM_STCLEAR_FLAGS VFlags;\r
+ EFI_STATUS Status;\r
+ TPM_STCLEAR_FLAGS VolatileFlags;\r
\r
- Status = TpmCommGetFlags (\r
- mTcgDxeData.TpmHandle,\r
- TPM_CAP_FLAG_VOLATILE,\r
- &VFlags,\r
- sizeof (VFlags)\r
- );\r
+ Status = Tpm12GetCapabilityFlagVolatile (&VolatileFlags);\r
if (!EFI_ERROR (Status)) {\r
- *TPMDeactivatedFlag = VFlags.deactivated;\r
+ *TPMDeactivatedFlag = VolatileFlags.deactivated;\r
}\r
\r
return Status;\r
\r
It publishes EFI TCG Protocol.\r
\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
@param[in] SystemTable A pointer to the EFI System Table.\r
- \r
+\r
@retval EFI_SUCCESS The entry point is executed successfully.\r
@retval other Some error occurs when executing this entry point.\r
\r
EFI_EVENT Event;\r
VOID *Registration;\r
\r
- mTcgDxeData.TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
- Status = TisPcRequestUseTpm (mTcgDxeData.TpmHandle);\r
+ if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
+ DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
+ DEBUG ((EFI_D_ERROR, "TPM error!\n"));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Status = Tpm12RequestUseTpm ();\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "TPM not detected!\n"));\r
return Status;\r
if (EFI_ERROR (Status)) {\r
DEBUG ((\r
EFI_D_ERROR,\r
- "Line %d in file " __FILE__ ":\n "\r
- "DriverEntry: TPM not working properly\n",\r
- __LINE__\r
+ "DriverEntry: TPM not working properly\n"\r
));\r
return Status;\r
}\r
EFI_NATIVE_INTERFACE,\r
&mTcgDxeData.TcgProtocol\r
);\r
- //\r
- // Install ACPI Table\r
- //\r
- EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);\r
- \r
- if (!EFI_ERROR (Status) && !mTcgDxeData.BsCap.TPMDeactivatedFlag) {\r
+ if (!EFI_ERROR (Status) && (!mTcgDxeData.BsCap.TPMDeactivatedFlag) && mTcgDxeData.BsCap.TPMPresentFlag) {\r
//\r
// Setup the log area and copy event log from hob list to it\r
//\r
&gEfiEventExitBootServicesGuid,\r
&Event\r
);\r
+\r
+ //\r
+ // Measure Exit Boot Service failed\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ OnExitBootServicesFailed,\r
+ NULL,\r
+ &gEventExitBootServicesFailedGuid,\r
+ &Event\r
+ );\r
}\r
\r
+ //\r
+ // Install ACPI Table\r
+ //\r
+ EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);\r
+\r
return Status;\r
}\r