From 1abfa4ce4835639c66ae82cc0d72cffcf3f28b6b Mon Sep 17 00:00:00 2001 From: "Yao, Jiewen" Date: Thu, 13 Aug 2015 08:24:17 +0000 Subject: Add TPM2 support defined in trusted computing group. TCG EFI Protocol Specification for TPM Family 2.0 Revision 1.0 Version 9 at http://www.trustedcomputinggroup.org/resources/tcg_efi_protocol_specification TCG Physical Presence Interface Specification Version 1.30, Revision 00.52 at http://www.trustedcomputinggroup.org/resources/tcg_physical_presence_interface_specification Add Tcg2XXX, similar file/directory as TrEEXXX. Old TrEE driver/library can be deprecated. 1) Add Tcg2Pei/Dxe/Smm driver to log event and provide services. 2) Add Dxe/Pei/SmmTcg2PhysicalPresenceLib to support TCG PP. 3) Update Tpm2 library to use TCG2 protocol instead of TrEE protocol. Test Win8/Win10 with SecureBoot enabled, PCR7 shows bound. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" Reviewed-by: "Zhang, Chao B" git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18219 6f19259b-4bc3-4df7-8a09-765794883524 --- SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr | 167 ++++++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c | 280 ++++++++++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf | 87 +++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.uni | Bin 0 -> 2124 bytes SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxeExtra.uni | Bin 0 -> 1382 bytes SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c | 610 ++++++++++++++++++++++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.h | 197 +++++++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h | 94 ++++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf | 78 +++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni | Bin 0 -> 2206 bytes SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni | Bin 0 -> 1382 bytes SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c | 158 ++++++ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigStrings.uni | Bin 0 -> 13376 bytes SecurityPkg/Tcg/Tcg2Config/TpmDetection.c | 129 +++++ 14 files changed, 1800 insertions(+) create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.uni create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxeExtra.uni create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.h create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c create mode 100644 SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigStrings.uni create mode 100644 SecurityPkg/Tcg/Tcg2Config/TpmDetection.c (limited to 'SecurityPkg/Tcg/Tcg2Config') diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr b/SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr new file mode 100644 index 0000000000..fe0ef14c2f --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr @@ -0,0 +1,167 @@ +/** @file + VFR file used by the TCG2 configuration component. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Tcg2ConfigNvData.h" + +formset + guid = TCG2_CONFIG_FORM_SET_GUID, + title = STRING_TOKEN(STR_TCG2_TITLE), + help = STRING_TOKEN(STR_TCG2_HELP), + classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID, + + efivarstore TCG2_CONFIGURATION, + varid = TCG2_CONFIGURATION_VARSTORE_ID, + attribute = 0x03, // EFI variable attribures EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE + name = TCG2_CONFIGURATION, + guid = TCG2_CONFIG_FORM_SET_GUID; + + form formid = TCG2_CONFIGURATION_FORM_ID, + title = STRING_TOKEN(STR_TCG2_TITLE); + + subtitle text = STRING_TOKEN(STR_NULL); + + text + help = STRING_TOKEN(STR_TCG2_DEVICE_STATE_HELP), + text = STRING_TOKEN(STR_TCG2_DEVICE_STATE_PROMPT), + text = STRING_TOKEN(STR_TCG2_DEVICE_STATE_CONTENT); + + oneof varid = TCG2_CONFIGURATION.TpmDevice, + questionid = KEY_TPM_DEVICE, + prompt = STRING_TOKEN(STR_TCG2_DEVICE_PROMPT), + help = STRING_TOKEN(STR_TCG2_DEVICE_HELP), + flags = INTERACTIVE, + option text = STRING_TOKEN(STR_TCG2_TPM_1_2), value = TPM_DEVICE_1_2, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_TPM_2_0_DTPM), value = TPM_DEVICE_2_0_DTPM, flags = RESET_REQUIRED; + endoneof; + + subtitle text = STRING_TOKEN(STR_NULL); + + suppressif ideqvallist TCG2_CONFIGURATION.TpmDevice == TPM_DEVICE_NULL TPM_DEVICE_1_2; + text + help = STRING_TOKEN(STR_TPM2_ACTIVE_HASH_ALGO_HELP), + text = STRING_TOKEN(STR_TPM2_ACTIVE_HASH_ALGO), + text = STRING_TOKEN(STR_TPM2_ACTIVE_HASH_ALGO_CONTENT); + text + help = STRING_TOKEN(STR_TPM2_SUPPORTED_HASH_ALGO_HELP), + text = STRING_TOKEN(STR_TPM2_SUPPORTED_HASH_ALGO), + text = STRING_TOKEN(STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT); + text + help = STRING_TOKEN(STR_BIOS_HASH_ALGO_HELP), + text = STRING_TOKEN(STR_BIOS_HASH_ALGO), + text = STRING_TOKEN(STR_BIOS_HASH_ALGO_CONTENT); + + subtitle text = STRING_TOKEN(STR_NULL); + subtitle text = STRING_TOKEN(STR_TCG2_PP_OPERATION); + + oneof name = Tpm2Operation, + questionid = KEY_TPM2_OPERATION, + prompt = STRING_TOKEN(STR_TCG2_OPERATION), + help = STRING_TOKEN(STR_TCG2_OPERATION_HELP), + flags = INTERACTIVE | NUMERIC_SIZE_1, + option text = STRING_TOKEN(STR_TCG2_NO_ACTION), value = TCG2_PHYSICAL_PRESENCE_NO_ACTION, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_ENABLE), value = TCG2_PHYSICAL_PRESENCE_ENABLE, flags = RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_DISABLE), value = TCG2_PHYSICAL_PRESENCE_DISABLE, flags = RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_CLEAR), value = TCG2_PHYSICAL_PRESENCE_CLEAR, flags = RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_SET_PCD_BANKS), value = TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, flags = RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_CHANGE_EPS), value = TCG2_PHYSICAL_PRESENCE_CHANGE_EPS, flags = RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_LOG_ALL_DIGESTS), value = TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS, flags = RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_DISABLE_ENDORSEMENT_ENABLE_STORAGE_HIERARCHY), value = TCG2_PHYSICAL_PRESENCE_DISABLE_ENDORSEMENT_ENABLE_STORAGE_HIERARCHY, flags = RESET_REQUIRED; + + option text = STRING_TOKEN(STR_TCG2_ENABLE_BLOCK_SID), value = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID, flags = RESET_REQUIRED; + option text = STRING_TOKEN(STR_TCG2_DISABLE_BLOCK_SID), value = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID, flags = RESET_REQUIRED; + endoneof; + + suppressif NOT questionref(Tpm2Operation) == TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS; + numeric name = Tpm2OperationParameter, + questionid = KEY_TPM2_OPERATION_PARAMETER, + prompt = STRING_TOKEN(STR_TCG2_OPERATION_PARAMETER), + help = STRING_TOKEN(STR_TCG2_OPERATION_PARAMETER_HELP), + flags = DISPLAY_UINT_HEX | INTERACTIVE | NUMERIC_SIZE_4, + minimum = 0, + maximum = 0xFFFFFFFF, + step = 0, + default = 0, + endnumeric; + endif; + + subtitle text = STRING_TOKEN(STR_NULL); + subtitle text = STRING_TOKEN(STR_TCG2_CONFIGURATION); + + text + help = STRING_TOKEN(STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_HELP), + text = STRING_TOKEN(STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT), + text = STRING_TOKEN(STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_CONTENT); + + text + help = STRING_TOKEN(STR_TCG2_HASH_ALGO_BITMAP_HELP), + text = STRING_TOKEN(STR_TCG2_HASH_ALGO_BITMAP), + text = STRING_TOKEN(STR_TCG2_HASH_ALGO_BITMAP_CONTENT); + + text + help = STRING_TOKEN(STR_TCG2_NUMBER_OF_PCR_BANKS_HELP), + text = STRING_TOKEN(STR_TCG2_NUMBER_OF_PCR_BANKS), + text = STRING_TOKEN(STR_TCG2_NUMBER_OF_PCR_BANKS_CONTENT); + + text + help = STRING_TOKEN(STR_TCG2_ACTIVE_PCR_BANKS_HELP), + text = STRING_TOKEN(STR_TCG2_ACTIVE_PCR_BANKS), + text = STRING_TOKEN(STR_TCG2_ACTIVE_PCR_BANKS_CONTENT); + + subtitle text = STRING_TOKEN(STR_NULL); + + checkbox name = TCG2ActivatePCRBank0, + questionid = KEY_TPM2_PCR_BANKS_REQUEST_0, + prompt = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA1), + help = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA1_HELP), + flags = INTERACTIVE, + default = 1, + endcheckbox; + + checkbox name = TCG2ActivatePCRBank1, + questionid = KEY_TPM2_PCR_BANKS_REQUEST_1, + prompt = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA256), + help = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA256_HELP), + flags = INTERACTIVE, + default = 0, + endcheckbox; + + checkbox name = TCG2ActivatePCRBank2, + questionid = KEY_TPM2_PCR_BANKS_REQUEST_2, + prompt = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA384), + help = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA384_HELP), + flags = INTERACTIVE, + default = 0, + endcheckbox; + + checkbox name = TCG2ActivatePCRBank3, + questionid = KEY_TPM2_PCR_BANKS_REQUEST_3, + prompt = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA512), + help = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA512_HELP), + flags = INTERACTIVE, + default = 0, + endcheckbox; + + checkbox name = TCG2ActivatePCRBank4, + questionid = KEY_TPM2_PCR_BANKS_REQUEST_4, + prompt = STRING_TOKEN(STR_TCG2_PCR_BANK_SM3_256), + help = STRING_TOKEN(STR_TCG2_PCR_BANK_SM3_256_HELP), + flags = INTERACTIVE, + default = 0, + endcheckbox; + + endif; + + endform; + +endformset; diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c new file mode 100644 index 0000000000..881368345b --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c @@ -0,0 +1,280 @@ +/** @file + The module entry point for Tcg2 configuration module. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Tcg2ConfigImpl.h" + +extern TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1]; + +/** + Update default PCR banks data. + + @param[in] HiiPackage HII Package. + @param[in] HiiPackageSize HII Package size. + @param[in] PCRBanks PCR Banks data. + +**/ +VOID +UpdateDefaultPCRBanks ( + IN VOID *HiiPackage, + IN UINTN HiiPackageSize, + IN UINT32 PCRBanks + ) +{ + EFI_HII_PACKAGE_HEADER *HiiPackageHeader; + EFI_IFR_OP_HEADER *IfrOpCodeHeader; + EFI_IFR_CHECKBOX *IfrCheckBox; + EFI_IFR_DEFAULT *IfrDefault; + + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage; + + switch (HiiPackageHeader->Type) { + case EFI_HII_PACKAGE_FORMS: + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1); + while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) { + switch (IfrOpCodeHeader->OpCode) { + case EFI_IFR_CHECKBOX_OP: + IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader; + if ((IfrCheckBox->Question.QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (IfrCheckBox->Question.QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) { + IfrDefault = (EFI_IFR_DEFAULT *)(IfrCheckBox + 1); + ASSERT (IfrDefault->Header.OpCode == EFI_IFR_DEFAULT_OP); + ASSERT (IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN); + IfrDefault->Value.b = (BOOLEAN)((PCRBanks >> (IfrCheckBox->Question.QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0)) & 0x1); + } + break; + } + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length); + } + break; + } + return ; +} + +/** + The entry point for Tcg2 configuration driver. + + @param[in] ImageHandle The image handle of the driver. + @param[in] SystemTable The system table. + + @retval EFI_ALREADY_STARTED The driver already exists in system. + @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of resources. + @retval EFI_SUCCES All the related protocols are installed on the driver. + @retval Others Fail to install protocols as indicated. + +**/ +EFI_STATUS +EFIAPI +Tcg2ConfigDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + TCG2_CONFIG_PRIVATE_DATA *PrivateData; + TCG2_CONFIGURATION Tcg2Configuration; + TCG2_DEVICE_DETECTION Tcg2DeviceDetection; + UINTN Index; + UINTN DataSize; + EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol; + UINT32 CurrentActivePCRBanks; + + Status = gBS->OpenProtocol ( + ImageHandle, + &gEfiCallerIdGuid, + NULL, + ImageHandle, + ImageHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + return EFI_ALREADY_STARTED; + } + + // + // Create a private data structure. + // + PrivateData = AllocateCopyPool (sizeof (TCG2_CONFIG_PRIVATE_DATA), &mTcg2ConfigPrivateDateTemplate); + ASSERT (PrivateData != NULL); + mTcg2ConfigPrivateDate = PrivateData; + // + // Install private GUID. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiCallerIdGuid, + PrivateData, + NULL + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &PrivateData->Tcg2Protocol); + ASSERT_EFI_ERROR (Status); + + PrivateData->ProtocolCapability.Size = sizeof(PrivateData->ProtocolCapability); + Status = PrivateData->Tcg2Protocol->GetCapability ( + PrivateData->Tcg2Protocol, + &PrivateData->ProtocolCapability + ); + ASSERT_EFI_ERROR (Status); + + DataSize = sizeof(Tcg2Configuration); + Status = gRT->GetVariable ( + TCG2_STORAGE_NAME, + &gTcg2ConfigFormSetGuid, + NULL, + &DataSize, + &Tcg2Configuration + ); + if (EFI_ERROR (Status)) { + // + // Variable not ready, set default value + // + Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT; + } + + // + // Validation + // + if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) { + Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT; + } + + // + // Set value for Tcg2CurrentActivePCRBanks + // Search Tcg2ConfigBin[] and update default value there + // + Status = PrivateData->Tcg2Protocol->GetActivePcrBanks (PrivateData->Tcg2Protocol, &CurrentActivePCRBanks); + ASSERT_EFI_ERROR (Status); + PrivateData->PCRBanksDesired = CurrentActivePCRBanks; + UpdateDefaultPCRBanks (Tcg2ConfigBin + sizeof(UINT32), ReadUnaligned32((UINT32 *)Tcg2ConfigBin) - sizeof(UINT32), CurrentActivePCRBanks); + + // + // Save to variable so platform driver can get it. + // + Status = gRT->SetVariable ( + TCG2_STORAGE_NAME, + &gTcg2ConfigFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(Tcg2Configuration), + &Tcg2Configuration + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_NAME\n")); + } + + // + // Sync data from PCD to variable, so that we do not need detect again in S3 phase. + // + Tcg2DeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL; + for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) { + if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) { + Tcg2DeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice; + break; + } + } + + PrivateData->TpmDeviceDetected = Tcg2DeviceDetection.TpmDeviceDetected; + + // + // Save to variable so platform driver can get it. + // + Status = gRT->SetVariable ( + TCG2_DEVICE_DETECTION_NAME, + &gTcg2ConfigFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(Tcg2DeviceDetection), + &Tcg2DeviceDetection + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_DEVICE_DETECTION_NAME\n")); + Status = gRT->SetVariable ( + TCG2_DEVICE_DETECTION_NAME, + &gTcg2ConfigFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + 0, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + + // + // We should lock Tcg2DeviceDetection, because it contains information needed at S3. + // + Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol); + if (!EFI_ERROR (Status)) { + Status = VariableLockProtocol->RequestToLock ( + VariableLockProtocol, + TCG2_DEVICE_DETECTION_NAME, + &gTcg2ConfigFormSetGuid + ); + ASSERT_EFI_ERROR (Status); + } + + // + // Install Tcg2 configuration form + // + Status = InstallTcg2ConfigForm (PrivateData); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + return EFI_SUCCESS; + +ErrorExit: + if (PrivateData != NULL) { + UninstallTcg2ConfigForm (PrivateData); + } + + return Status; +} + +/** + Unload the Tcg2 configuration form. + + @param[in] ImageHandle The driver's image handle. + + @retval EFI_SUCCESS The Tcg2 configuration form is unloaded. + @retval Others Failed to unload the form. + +**/ +EFI_STATUS +EFIAPI +Tcg2ConfigDriverUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + TCG2_CONFIG_PRIVATE_DATA *PrivateData; + + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiCallerIdGuid, + (VOID **) &PrivateData + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (PrivateData->Signature == TCG2_CONFIG_PRIVATE_DATA_SIGNATURE); + + gBS->UninstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiCallerIdGuid, + PrivateData, + NULL + ); + + UninstallTcg2ConfigForm (PrivateData); + + return EFI_SUCCESS; +} diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf new file mode 100644 index 0000000000..ba76541bd9 --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf @@ -0,0 +1,87 @@ +## @file +# TPM device configuration for TPM 2.0 +# +# By this module, user may select TPM device, clear TPM state, etc. +# NOTE: This module is only for reference only, each platform should have its own setup page. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Tcg2ConfigDxe + MODULE_UNI_FILE = Tcg2ConfigDxe.uni + FILE_GUID = 4D9CBEF0-15A0-4D0C-83DB-5213E710C23F + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Tcg2ConfigDriverEntryPoint + UNLOAD_IMAGE = Tcg2ConfigDriverUnload + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + Tcg2ConfigDriver.c + Tcg2ConfigImpl.c + Tcg2ConfigImpl.h + Tcg2Config.vfr + Tcg2ConfigStrings.uni + Tcg2ConfigNvData.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + UefiHiiServicesLib + DebugLib + HiiLib + PcdLib + PrintLib + Tpm2DeviceLib + Tpm2CommandLib + Tcg2PhysicalPresenceLib + +[Guids] + ## PRODUCES ## HII + ## SOMETIMES_PRODUCES ## Variable:L"TCG2_CONFIGURATION" + ## SOMETIMES_CONSUMES ## Variable:L"TCG2_CONFIGURATION" + ## PRODUCES ## Variable:L"TCG2_DEVICE_DETECTION" + ## SOMETIMES_CONSUMES ## Variable:L"TCG2_DEVICE_DETECTION" + gTcg2ConfigFormSetGuid + +[Protocols] + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiDevicePathProtocolGuid ## PRODUCES + gEdkiiVariableLockProtocolGuid ## CONSUMES + gEfiTcg2ProtocolGuid ## CONSUMES + +[Pcd] + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap ## CONSUMES + +[Depex] + gEfiTcg2ProtocolGuid AND + gEfiHiiConfigRoutingProtocolGuid AND + gEfiHiiDatabaseProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + Tcg2ConfigDxeExtra.uni diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.uni b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.uni new file mode 100644 index 0000000000..a5b2040b49 Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.uni differ diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxeExtra.uni b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxeExtra.uni new file mode 100644 index 0000000000..c2571d74be Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxeExtra.uni differ diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c new file mode 100644 index 0000000000..e1835b9613 --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c @@ -0,0 +1,610 @@ +/** @file + HII Config Access protocol implementation of TCG2 configuration module. + NOTE: This module is only for reference only, each platform should have its own setup page. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Tcg2ConfigImpl.h" +#include +#include +#include + +#define EFI_TCG2_EVENT_LOG_FORMAT_ALL (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) + +TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1] = TPM_INSTANCE_ID_LIST; + +TCG2_CONFIG_PRIVATE_DATA *mTcg2ConfigPrivateDate; +TCG2_CONFIG_PRIVATE_DATA mTcg2ConfigPrivateDateTemplate = { + TCG2_CONFIG_PRIVATE_DATA_SIGNATURE, + { + Tcg2ExtractConfig, + Tcg2RouteConfig, + Tcg2Callback + } +}; + +HII_VENDOR_DEVICE_PATH mTcg2HiiVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + TCG2_CONFIG_FORM_SET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH), + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +UINT8 mCurrentPpRequest; + +/** + This function allows a caller to extract the current configuration for one + or more named elements from the target driver. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Request A null-terminated Unicode string in + format. + @param[out] Progress On return, points to a character in the Request + string. Points to the string's null terminator if + request was successful. Points to the most recent + '&' before the first failing name/value pair (or + the beginning of the string if the failure is in + the first name/value pair) if the request was not + successful. + @param[out] Results A null-terminated Unicode string in + format which has all values filled + in for the names in the Request string. String to + be allocated by the called function. + + @retval EFI_SUCCESS The Results is filled with the requested values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this + driver. + +**/ +EFI_STATUS +EFIAPI +Tcg2ExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + if (Progress == NULL || Results == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Progress = Request; + return EFI_NOT_FOUND; +} + +/** + Save TPM request to variable space. + + @param[in] PpRequest Physical Presence request command. + + @retval EFI_SUCCESS The operation is finished successfully. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +SaveTcg2PpRequest ( + IN UINT8 PpRequest + ) +{ + UINT32 ReturnCode; + EFI_STATUS Status; + + ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0); + if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) { + mCurrentPpRequest = PpRequest; + Status = EFI_SUCCESS; + } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) { + Status = EFI_OUT_OF_RESOURCES; + } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) { + Status = EFI_UNSUPPORTED; + } else { + Status = EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Save TPM request to variable space. + + @param[in] PpRequestParameter Physical Presence request parameter. + + @retval EFI_SUCCESS The operation is finished successfully. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +SaveTcg2PpRequestParameter ( + IN UINT32 PpRequestParameter + ) +{ + UINT32 ReturnCode; + EFI_STATUS Status; + + ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (mCurrentPpRequest, PpRequestParameter); + if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) { + Status = EFI_SUCCESS; + } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) { + Status = EFI_OUT_OF_RESOURCES; + } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) { + Status = EFI_UNSUPPORTED; + } else { + Status = EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Save Tcg2 PCR Banks request request to variable space. + + @param[in] PCRBankIndex PCR Bank Index. + @param[in] Enable Enable or disable this PCR Bank. + + @retval EFI_SUCCESS The operation is finished successfully. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +SaveTcg2PCRBanksRequest ( + IN UINTN PCRBankIndex, + IN BOOLEAN Enable + ) +{ + UINT32 ReturnCode; + EFI_STATUS Status; + + if (Enable) { + mTcg2ConfigPrivateDate->PCRBanksDesired |= (0x1 << PCRBankIndex); + } else { + mTcg2ConfigPrivateDate->PCRBanksDesired &= ~(0x1 << PCRBankIndex); + } + + ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, mTcg2ConfigPrivateDate->PCRBanksDesired); + if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) { + Status = EFI_SUCCESS; + } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) { + Status = EFI_OUT_OF_RESOURCES; + } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) { + Status = EFI_UNSUPPORTED; + } else { + Status = EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + This function processes the results of changes in configuration. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Configuration A null-terminated Unicode string in + format. + @param[out] Progress A pointer to a string filled in with the offset of + the most recent '&' before the first failing + name/value pair (or the beginning of the string if + the failure is in the first name/value pair) or + the terminating NULL if all was successful. + + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this + driver. + +**/ +EFI_STATUS +EFIAPI +Tcg2RouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ) +{ + if (Configuration == NULL || Progress == NULL) { + return EFI_INVALID_PARAMETER; + } + + return EFI_NOT_FOUND; +} + +/** + This function processes the results of changes in configuration. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Action Specifies the type of action taken by the browser. + @param[in] QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. + @param[in] Type The type of value for the question. + @param[in] Value A pointer to the data being sent to the original + exporting driver. + @param[out] ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the + callback. + +**/ +EFI_STATUS +EFIAPI +Tcg2Callback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (Action == EFI_BROWSER_ACTION_CHANGED) { + if (QuestionId == KEY_TPM_DEVICE) { + return EFI_SUCCESS; + } + if (QuestionId == KEY_TPM2_OPERATION) { + return SaveTcg2PpRequest (Value->u8); + } + if (QuestionId == KEY_TPM2_OPERATION_PARAMETER) { + return SaveTcg2PpRequestParameter (Value->u32); + } + if ((QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) { + SaveTcg2PCRBanksRequest (QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0, Value->b); + } + } + + return EFI_UNSUPPORTED; +} + +/** + Append Buffer With TpmAlgHash. + + @param[in] Buffer Buffer to be appended. + @param[in] BufferSize Size of buffer. + @param[in] TpmAlgHash TpmAlgHash. + +**/ +VOID +AppendBufferWithTpmAlgHash ( + IN UINT16 *Buffer, + IN UINTN BufferSize, + IN UINT32 TpmAlgHash + ) +{ + switch (TpmAlgHash) { + case TPM_ALG_SHA1: + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + break; + case TPM_ALG_SHA256: + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + break; + case TPM_ALG_SHA384: + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + break; + case TPM_ALG_SHA512: + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + break; + case TPM_ALG_SM3_256: + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + break; + } +} + +/** + Fill Buffer With BootHashAlg. + + @param[in] Buffer Buffer to be filled. + @param[in] BufferSize Size of buffer. + @param[in] BootHashAlg BootHashAlg. + +**/ +VOID +FillBufferWithBootHashAlg ( + IN UINT16 *Buffer, + IN UINTN BufferSize, + IN UINT32 BootHashAlg + ) +{ + Buffer[0] = 0; + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) { + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) { + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) { + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) { + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) { + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } +} + +/** + Fill Buffer With TCG2EventLogFormat. + + @param[in] Buffer Buffer to be filled. + @param[in] BufferSize Size of buffer. + @param[in] TCG2EventLogFormat TCG2EventLogFormat. + +**/ +VOID +FillBufferWithTCG2EventLogFormat ( + IN UINT16 *Buffer, + IN UINTN BufferSize, + IN UINT32 TCG2EventLogFormat + ) +{ + Buffer[0] = 0; + if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) != 0) { + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"TCG_1_2", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) != 0) { + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"TCG_2", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + if ((TCG2EventLogFormat & (~EFI_TCG2_EVENT_LOG_FORMAT_ALL)) != 0) { + if (Buffer[0] != 0) { + StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + StrnCat (Buffer, L"UNKNOWN", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } +} + +/** + Check if buffer is all zero. + + @param[in] Buffer Buffer to be checked. + @param[in] BufferSize Size of buffer to be checked. + + @retval TRUE Buffer is all zero. + @retval FALSE Buffer is not all zero. +**/ +BOOLEAN +IsZeroBuffer ( + IN VOID *Buffer, + IN UINTN BufferSize + ) +{ + UINT8 *BufferData; + UINTN Index; + + BufferData = Buffer; + for (Index = 0; Index < BufferSize; Index++) { + if (BufferData[Index] != 0) { + return FALSE; + } + } + return TRUE; +} + +/** + This function publish the TCG2 configuration Form for TPM device. + + @param[in, out] PrivateData Points to TCG2 configuration private data. + + @retval EFI_SUCCESS HII Form is installed for this network device. + @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +InstallTcg2ConfigForm ( + IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData + ) +{ + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; + EFI_HANDLE DriverHandle; + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; + UINTN Index; + TPML_PCR_SELECTION Pcrs; + CHAR16 TempBuffer[1024]; + + DriverHandle = NULL; + ConfigAccess = &PrivateData->ConfigAccess; + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle, + &gEfiDevicePathProtocolGuid, + &mTcg2HiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + ConfigAccess, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + PrivateData->DriverHandle = DriverHandle; + + // + // Publish the HII package list + // + HiiHandle = HiiAddPackages ( + &gTcg2ConfigFormSetGuid, + DriverHandle, + Tcg2ConfigDxeStrings, + Tcg2ConfigBin, + NULL + ); + if (HiiHandle == NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + DriverHandle, + &gEfiDevicePathProtocolGuid, + &mTcg2HiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + ConfigAccess, + NULL + ); + + return EFI_OUT_OF_RESOURCES; + } + + PrivateData->HiiHandle = HiiHandle; + + // + // Update static data + // + switch (PrivateData->TpmDeviceDetected) { + case TPM_DEVICE_NULL: + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Not Found", NULL); + break; + case TPM_DEVICE_1_2: + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 1.2", NULL); + break; + case TPM_DEVICE_2_0_DTPM: + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 2.0 (DTPM)", NULL); + break; + default: + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Unknown", NULL); + break; + } + + Status = Tpm2GetCapabilityPcrs (&Pcrs); + if (EFI_ERROR (Status)) { + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), L"[Unknown]", NULL); + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), L"[Unknown]", NULL); + } else { + TempBuffer[0] = 0; + for (Index = 0; Index < Pcrs.count; Index++) { + if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { + AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash); + } + } + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), TempBuffer, NULL); + + TempBuffer[0] = 0; + for (Index = 0; Index < Pcrs.count; Index++) { + AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash); + } + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), TempBuffer, NULL); + } + + FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PcdGet32 (PcdTcg2HashAlgorithmBitmap)); + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_BIOS_HASH_ALGO_CONTENT), TempBuffer, NULL); + + // + // Tcg2 Capability + // + FillBufferWithTCG2EventLogFormat (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.SupportedEventLogs); + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_CONTENT), TempBuffer, NULL); + + FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.HashAlgorithmBitmap); + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_HASH_ALGO_BITMAP_CONTENT), TempBuffer, NULL); + + UnicodeSPrint (TempBuffer, sizeof (TempBuffer), L"%d", PrivateData->ProtocolCapability.NumberOfPCRBanks); + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_NUMBER_OF_PCR_BANKS_CONTENT), TempBuffer, NULL); + + FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.ActivePcrBanks); + HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_ACTIVE_PCR_BANKS_CONTENT), TempBuffer, NULL); + + return EFI_SUCCESS; +} + +/** + This function removes TCG2 configuration Form. + + @param[in, out] PrivateData Points to TCG2 configuration private data. + +**/ +VOID +UninstallTcg2ConfigForm ( + IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData + ) +{ + // + // Uninstall HII package list + // + if (PrivateData->HiiHandle != NULL) { + HiiRemovePackages (PrivateData->HiiHandle); + PrivateData->HiiHandle = NULL; + } + + // + // Uninstall HII Config Access Protocol + // + if (PrivateData->DriverHandle != NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + PrivateData->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mTcg2HiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &PrivateData->ConfigAccess, + NULL + ); + PrivateData->DriverHandle = NULL; + } + + FreePool (PrivateData); +} diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.h b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.h new file mode 100644 index 0000000000..1b9a8452e0 --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.h @@ -0,0 +1,197 @@ +/** @file + The header file of HII Config Access protocol implementation of TCG2 + configuration module. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __TCG2_CONFIG_IMPL_H__ +#define __TCG2_CONFIG_IMPL_H__ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "Tcg2ConfigNvData.h" + +// +// Tool generated IFR binary data and String package data +// +extern UINT8 Tcg2ConfigBin[]; +extern UINT8 Tcg2ConfigDxeStrings[]; + +/// +/// HII specific Vendor Device Path definition. +/// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; + +typedef struct { + UINTN Signature; + + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; + EFI_HII_HANDLE HiiHandle; + EFI_HANDLE DriverHandle; + + UINT8 TpmDeviceDetected; + EFI_TCG2_PROTOCOL *Tcg2Protocol; + EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability; + UINT32 PCRBanksDesired; +} TCG2_CONFIG_PRIVATE_DATA; + +extern TCG2_CONFIG_PRIVATE_DATA mTcg2ConfigPrivateDateTemplate; +extern TCG2_CONFIG_PRIVATE_DATA *mTcg2ConfigPrivateDate; +#define TCG2_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('T', 'r', 'E', 'D') +#define TCG2_CONFIG_PRIVATE_DATA_FROM_THIS(a) CR (a, TCG2_CONFIG_PRIVATE_DATA, ConfigAccess, TCG2_CONFIG_PRIVATE_DATA_SIGNATURE) + + +/** + This function publish the TCG2 configuration Form for TPM device. + + @param[in, out] PrivateData Points to TCG2 configuration private data. + + @retval EFI_SUCCESS HII Form is installed for this network device. + @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +InstallTcg2ConfigForm ( + IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData + ); + +/** + This function removes TCG2 configuration Form. + + @param[in, out] PrivateData Points to TCG2 configuration private data. + +**/ +VOID +UninstallTcg2ConfigForm ( + IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData + ); + +/** + This function allows a caller to extract the current configuration for one + or more named elements from the target driver. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Request A null-terminated Unicode string in + format. + @param[out] Progress On return, points to a character in the Request + string. Points to the string's null terminator if + request was successful. Points to the most recent + '&' before the first failing name/value pair (or + the beginning of the string if the failure is in + the first name/value pair) if the request was not + successful. + @param[out] Results A null-terminated Unicode string in + format which has all values filled + in for the names in the Request string. String to + be allocated by the called function. + + @retval EFI_SUCCESS The Results is filled with the requested values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this + driver. + +**/ +EFI_STATUS +EFIAPI +Tcg2ExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ); + +/** + This function processes the results of changes in configuration. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Configuration A null-terminated Unicode string in + format. + @param[out] Progress A pointer to a string filled in with the offset of + the most recent '&' before the first failing + name/value pair (or the beginning of the string if + the failure is in the first name/value pair) or + the terminating NULL if all was successful. + + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this + driver. + +**/ +EFI_STATUS +EFIAPI +Tcg2RouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ); + +/** + This function processes the results of changes in configuration. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Action Specifies the type of action taken by the browser. + @param[in] QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. + @param[in] Type The type of value for the question. + @param[in] Value A pointer to the data being sent to the original + exporting driver. + @param[out] ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the + callback. + +**/ +EFI_STATUS +EFIAPI +Tcg2Callback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ); + +#endif diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h new file mode 100644 index 0000000000..65044c2bd5 --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h @@ -0,0 +1,94 @@ +/** @file + Header file for NV data structure definition. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __TCG2_CONFIG_NV_DATA_H__ +#define __TCG2_CONFIG_NV_DATA_H__ + +#include +#include +#include + +// +// BUGBUG: In order to pass VfrCompiler, we have to redefine below MACRO, which already in . +// +#ifndef __TCG2_H__ +#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001 +#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002 +#endif +#define EFI_TCG2_EVENT_LOG_FORMAT_ALL (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) + +#define TCG2_CONFIGURATION_VARSTORE_ID 0x0001 +#define TCG2_CONFIGURATION_FORM_ID 0x0001 + +#define KEY_TPM_DEVICE 0x2000 +#define KEY_TPM2_OPERATION 0x2001 +#define KEY_TPM2_OPERATION_PARAMETER 0x2002 +#define KEY_TPM2_PCR_BANKS_REQUEST_0 0x2003 +#define KEY_TPM2_PCR_BANKS_REQUEST_1 0x2004 +#define KEY_TPM2_PCR_BANKS_REQUEST_2 0x2005 +#define KEY_TPM2_PCR_BANKS_REQUEST_3 0x2006 +#define KEY_TPM2_PCR_BANKS_REQUEST_4 0x2007 + +#define TPM_DEVICE_NULL 0 +#define TPM_DEVICE_1_2 1 +#define TPM_DEVICE_2_0_DTPM 2 +#define TPM_DEVICE_MIN TPM_DEVICE_1_2 +#define TPM_DEVICE_MAX TPM_DEVICE_2_0_DTPM +#define TPM_DEVICE_DEFAULT TPM_DEVICE_1_2 + +#define TCG2_PROTOCOL_VERSION_DEFAULT 0x0001 +#define EFI_TCG2_EVENT_LOG_FORMAT_DEFAULT EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 + +// +// Nv Data structure referenced by IFR, TPM device user desired +// +typedef struct { + UINT8 TpmDevice; +} TCG2_CONFIGURATION; + +// +// Variable saved for S3, TPM detected, only valid in S3 path. +// This variable is ReadOnly. +// +typedef struct { + UINT8 TpmDeviceDetected; +} TCG2_DEVICE_DETECTION; + +#define TCG2_STORAGE_NAME L"TCG2_CONFIGURATION" +#define TCG2_DEVICE_DETECTION_NAME L"TCG2_DEVICE_DETECTION" + +#define TPM_INSTANCE_ID_LIST { \ + {TPM_DEVICE_INTERFACE_NONE, TPM_DEVICE_NULL}, \ + {TPM_DEVICE_INTERFACE_TPM12, TPM_DEVICE_1_2}, \ + {TPM_DEVICE_INTERFACE_TPM20_DTPM, TPM_DEVICE_2_0_DTPM}, \ +} + +// +// BUGBUG: In order to pass VfrCompiler, we have to redefine GUID here. +// +#ifndef __BASE_H__ +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} GUID; +#endif + +typedef struct { + GUID TpmInstanceGuid; + UINT8 TpmDevice; +} TPM_INSTANCE_ID; + +#endif diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf new file mode 100644 index 0000000000..cd6a92da1c --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf @@ -0,0 +1,78 @@ +## @file +# Set TPM device type +# +# This module initializes TPM device type based on variable and detection. +# NOTE: This module is only for reference only, each platform should have its own setup page. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Tcg2ConfigPei + MODULE_UNI_FILE = Tcg2ConfigPei.uni + FILE_GUID = EADD5061-93EF-4CCC-8450-F78A7F0820F0 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = Tcg2ConfigPeimEntryPoint + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# +# [BootMode] +# S3_RESUME ## SOMETIMES_CONSUMES +# + +[Sources] + Tcg2ConfigPeim.c + Tcg2ConfigNvData.h + TpmDetection.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + PeiServicesLib + PeimEntryPoint + DebugLib + PcdLib + TimerLib + IoLib + Tpm12CommandLib + Tpm12DeviceLib + +[Guids] + ## SOMETIMES_CONSUMES ## Variable:L"TCG2_CONFIGURATION" + ## SOMETIMES_CONSUMES ## Variable:L"TCG2_DEVICE_DETECTION" + gTcg2ConfigFormSetGuid + gEfiTpmDeviceSelectedGuid ## PRODUCES ## GUID # Used as a PPI GUID + gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_CONSUMES ## GUID # TPM device identifier + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES + gPeiTpmInitializationDonePpiGuid ## SOMETIMES_PRODUCES + +[Pcd] + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## PRODUCES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy ## PRODUCES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## SOMETIMES_CONSUMES + +[Depex] + gEfiPeiMasterBootModePpiGuid AND + gEfiPeiReadOnlyVariable2PpiGuid + +[UserExtensions.TianoCore."ExtraFiles"] + Tcg2ConfigPeiExtra.uni diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni new file mode 100644 index 0000000000..c3095564a2 Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni differ diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni new file mode 100644 index 0000000000..c2571d74be Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni differ diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c new file mode 100644 index 0000000000..34767c0f49 --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c @@ -0,0 +1,158 @@ +/** @file + The module entry point for Tcg2 configuration module. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "Tcg2ConfigNvData.h" + +TPM_INSTANCE_ID mTpmInstanceId[] = TPM_INSTANCE_ID_LIST; + +CONST EFI_PEI_PPI_DESCRIPTOR gTpmSelectedPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTpmDeviceSelectedGuid, + NULL +}; + +EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gPeiTpmInitializationDonePpiGuid, + NULL +}; + +/** + This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration. + + @param SetupTpmDevice TpmDevice configuration in setup driver + + @return TpmDevice configuration +**/ +UINT8 +DetectTpmDevice ( + IN UINT8 SetupTpmDevice + ); + +/** + The entry point for Tcg2 configuration driver. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCES Convert variable to PCD successfully. + @retval Others Fail to convert variable to PCD. +**/ +EFI_STATUS +EFIAPI +Tcg2ConfigPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + UINTN Size; + EFI_STATUS Status; + EFI_STATUS Status2; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; + TCG2_CONFIGURATION Tcg2Configuration; + UINTN Index; + UINT8 TpmDevice; + + Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); + ASSERT_EFI_ERROR (Status); + + Size = sizeof(Tcg2Configuration); + Status = VariablePpi->GetVariable ( + VariablePpi, + TCG2_STORAGE_NAME, + &gTcg2ConfigFormSetGuid, + NULL, + &Size, + &Tcg2Configuration + ); + if (EFI_ERROR (Status)) { + // + // Variable not ready, set default value + // + Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT; + } + + // + // Validation + // + if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) { + Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT; + } + + // + // Although we have SetupVariable info, we still need detect TPM device manually. + // + DEBUG ((EFI_D_INFO, "Tcg2Configuration.TpmDevice from Setup: %x\n", Tcg2Configuration.TpmDevice)); + + if (PcdGetBool (PcdTpmAutoDetection)) { + TpmDevice = DetectTpmDevice (Tcg2Configuration.TpmDevice); + DEBUG ((EFI_D_INFO, "TpmDevice final: %x\n", TpmDevice)); + if (TpmDevice != TPM_DEVICE_NULL) { + Tcg2Configuration.TpmDevice = TpmDevice; + } + } else { + TpmDevice = Tcg2Configuration.TpmDevice; + } + + // + // Convert variable to PCD. + // This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase. + // Using DynamicPcd instead. + // + // NOTE: Tcg2Configuration variable contains the desired TpmDevice type, + // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice type + // + for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) { + if (TpmDevice == mTpmInstanceId[Index].TpmDevice) { + Size = sizeof(mTpmInstanceId[Index].TpmInstanceGuid); + PcdSetPtr (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid); + DEBUG ((EFI_D_INFO, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid)); + break; + } + } + + // + // Selection done + // + Status = PeiServicesInstallPpi (&gTpmSelectedPpi); + ASSERT_EFI_ERROR (Status); + + // + // Even if no TPM is selected or detected, we still need intall TpmInitializationDonePpi. + // Because TcgPei or Tcg2Pei will not run, but we still need a way to notify other driver. + // Other driver can know TPM initialization state by TpmInitializedPpi. + // + if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid)) { + Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList); + ASSERT_EFI_ERROR (Status2); + } + + return Status; +} diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigStrings.uni b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigStrings.uni new file mode 100644 index 0000000000..be548b86ff Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigStrings.uni differ diff --git a/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c b/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c new file mode 100644 index 0000000000..9e93e9c2d9 --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c @@ -0,0 +1,129 @@ +/** @file + TPM1.2/dTPM2.0 auto detection. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Tcg2ConfigNvData.h" + +/** + This routine return if dTPM (1.2 or 2.0) present. + + @retval TRUE dTPM present + @retval FALSE dTPM not present +**/ +BOOLEAN +IsDtpmPresent ( + VOID + ) +{ + UINT8 RegRead; + + RegRead = MmioRead8 ((UINTN)PcdGet64 (PcdTpmBaseAddress)); + if (RegRead == 0xFF) { + DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Dtpm not present\n")); + return FALSE; + } else { + DEBUG ((EFI_D_INFO, "DetectTpmDevice: Dtpm present\n")); + return TRUE; + } +} + +/** + This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration. + + @param SetupTpmDevice TpmDevice configuration in setup driver + + @return TpmDevice configuration +**/ +UINT8 +DetectTpmDevice ( + IN UINT8 SetupTpmDevice + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + TCG2_DEVICE_DETECTION Tcg2DeviceDetection; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; + UINTN Size; + + Status = PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + // + // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot. + // + if (BootMode == BOOT_ON_S3_RESUME) { + DEBUG ((EFI_D_INFO, "DetectTpmDevice: S3 mode\n")); + + Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); + ASSERT_EFI_ERROR (Status); + + Size = sizeof(TCG2_DEVICE_DETECTION); + ZeroMem (&Tcg2DeviceDetection, sizeof(Tcg2DeviceDetection)); + Status = VariablePpi->GetVariable ( + VariablePpi, + TCG2_DEVICE_DETECTION_NAME, + &gTcg2ConfigFormSetGuid, + NULL, + &Size, + &Tcg2DeviceDetection + ); + if (!EFI_ERROR (Status) && + (Tcg2DeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) && + (Tcg2DeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX)) { + DEBUG ((EFI_D_ERROR, "TpmDevice from DeviceDetection: %x\n", Tcg2DeviceDetection.TpmDeviceDetected)); + return Tcg2DeviceDetection.TpmDeviceDetected; + } + } + + DEBUG ((EFI_D_INFO, "DetectTpmDevice:\n")); + if (!IsDtpmPresent ()) { + // dTPM not available + return TPM_DEVICE_NULL; + } + + // dTPM available and not disabled by setup + // We need check if it is TPM1.2 or TPM2.0 + // So try TPM1.2 command at first + + Status = Tpm12RequestUseTpm (); + if (EFI_ERROR (Status)) { + return TPM_DEVICE_2_0_DTPM; + } + + if (BootMode == BOOT_ON_S3_RESUME) { + Status = Tpm12Startup (TPM_ST_STATE); + } else { + Status = Tpm12Startup (TPM_ST_CLEAR); + } + if (EFI_ERROR (Status)) { + return TPM_DEVICE_2_0_DTPM; + } + + // NO initialization needed again. + PcdSet8 (PcdTpmInitializationPolicy, 0); + return TPM_DEVICE_1_2; +} -- cgit v1.2.3