Add TPM2 support defined in trusted computing group.
authorYao, Jiewen <Jiewen.Yao@intel.com>
Thu, 13 Aug 2015 08:24:17 +0000 (08:24 +0000)
committerjyao1 <jyao1@Edk2>
Thu, 13 Aug 2015 08:24:17 +0000 (08:24 +0000)
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" <Jiewen.Yao@intel.com>
Reviewed-by: "Zhang, Chao B" <chao.b.zhang@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18219 6f19259b-4bc3-4df7-8a09-765794883524

62 files changed:
SecurityPkg/Include/Guid/Tcg2ConfigHii.h [new file with mode: 0644]
SecurityPkg/Include/Guid/Tcg2PhysicalPresenceData.h [new file with mode: 0644]
SecurityPkg/Include/Guid/TcgEventHob.h
SecurityPkg/Include/Library/Tcg2PhysicalPresenceLib.h [new file with mode: 0644]
SecurityPkg/Include/Library/Tcg2PpVendorLib.h [new file with mode: 0644]
SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c [new file with mode: 0644]
SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf [new file with mode: 0644]
SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni [new file with mode: 0644]
SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni [new file with mode: 0644]
SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.c
SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.c
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c
SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.c [new file with mode: 0644]
SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.inf [new file with mode: 0644]
SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.uni [new file with mode: 0644]
SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c [new file with mode: 0644]
SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.inf [new file with mode: 0644]
SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.uni [new file with mode: 0644]
SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.c [new file with mode: 0644]
SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf [new file with mode: 0644]
SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.uni [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.uni [new file with mode: 0644]
SecurityPkg/SecurityPkg.dec
SecurityPkg/SecurityPkg.dsc
SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxeExtra.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.h [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigStrings.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Config/TpmDetection.c [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Dxe/Tcg2DxeExtra.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Pei/Tcg2PeiExtra.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Smm/Tcg2SmmExtra.uni [new file with mode: 0644]
SecurityPkg/Tcg/Tcg2Smm/Tpm.asl [new file with mode: 0644]

diff --git a/SecurityPkg/Include/Guid/Tcg2ConfigHii.h b/SecurityPkg/Include/Guid/Tcg2ConfigHii.h
new file mode 100644 (file)
index 0000000..28e31e3
--- /dev/null
@@ -0,0 +1,25 @@
+/** @file\r
+  GUIDs used as HII FormSet and HII Package list GUID in Tcg2Config driver. \r
+  \r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under \r
+the terms and conditions of the BSD License that accompanies this distribution.  \r
+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
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __TCG2_CONFIG_HII_GUID_H__\r
+#define __TCG2_CONFIG_HII_GUID_H__\r
+\r
+#define TCG2_CONFIG_FORM_SET_GUID \\r
+  { \\r
+    0x6339d487, 0x26ba, 0x424b, { 0x9a, 0x5d, 0x68, 0x7e, 0x25, 0xd7, 0x40, 0xbc } \\r
+  }\r
+\r
+extern EFI_GUID gTcg2ConfigFormSetGuid;\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Guid/Tcg2PhysicalPresenceData.h b/SecurityPkg/Include/Guid/Tcg2PhysicalPresenceData.h
new file mode 100644 (file)
index 0000000..df43fd9
--- /dev/null
@@ -0,0 +1,47 @@
+/** @file\r
+  Define the variable data structures used for TCG2 physical presence.\r
+  The TPM2 request from firmware or OS is saved to variable. And it is\r
+  cleared after it is processed in the next boot cycle. The TPM2 response \r
+  is saved to variable.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#ifndef __TCG2_PHYSICAL_PRESENCE_DATA_GUID_H__\r
+#define __TCG2_PHYSICAL_PRESENCE_DATA_GUID_H__\r
+\r
+#define EFI_TCG2_PHYSICAL_PRESENCE_DATA_GUID \\r
+  { \\r
+    0xaeb9c5c1, 0x94f1, 0x4d02, { 0xbf, 0xd9, 0x46, 0x2, 0xdb, 0x2d, 0x3c, 0x54 } \\r
+  }\r
+\r
+#define TCG2_PHYSICAL_PRESENCE_VARIABLE  L"Tcg2PhysicalPresence"\r
+\r
+typedef struct {\r
+  UINT8   PPRequest;      ///< Physical Presence request command.\r
+  UINT32  PPRequestParameter; ///< Physical Presence request Parameter.\r
+  UINT8   LastPPRequest;\r
+  UINT32  PPResponse;\r
+} EFI_TCG2_PHYSICAL_PRESENCE;\r
+\r
+//\r
+// This variable is used to save TCG2 Management Flags and corresponding operations.\r
+// It should be protected from malicious software (e.g. Set it as read-only variable). \r
+//\r
+#define TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE  L"Tcg2PhysicalPresenceFlags"\r
+typedef struct {\r
+  UINT32  PPFlags;\r
+} EFI_TCG2_PHYSICAL_PRESENCE_FLAGS;\r
+\r
+extern EFI_GUID  gEfiTcg2PhysicalPresenceGuid;\r
+\r
+#endif\r
+\r
index c92ee8c..1082807 100644 (file)
@@ -1,5 +1,5 @@
 /** @file\r
-  Defines the HOB GUID used to pass a TCG_PCR_EVENT from a TPM PEIM to \r
+  Defines the HOB GUID used to pass a TCG_PCR_EVENT or TCG_PCR_EVENT2 from a TPM PEIM to \r
   a TPM DXE Driver. A GUIDed HOB is generated for each measurement \r
   made in the PEI Phase.\r
     \r
@@ -27,6 +27,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 extern EFI_GUID gTcgEventEntryHobGuid;\r
 \r
+#define EFI_TCG_EVENT2_HOB_GUID \\r
+  { \\r
+    0xd26c221e, 0x2430, 0x4c8a, { 0x91, 0x70, 0x3f, 0xcb, 0x45, 0x0, 0x41, 0x3f } \\r
+  }\r
+\r
+extern EFI_GUID gTcgEvent2EntryHobGuid;\r
+\r
 ///\r
 /// The Global ID of a GUIDed HOB used to record TPM device error.\r
 ///\r
diff --git a/SecurityPkg/Include/Library/Tcg2PhysicalPresenceLib.h b/SecurityPkg/Include/Library/Tcg2PhysicalPresenceLib.h
new file mode 100644 (file)
index 0000000..ce45f17
--- /dev/null
@@ -0,0 +1,160 @@
+/** @file\r
+  Ihis library is intended to be used by BDS modules.\r
+  This library will execute TPM2 request.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#ifndef _TCG2_PHYSICAL_PRESENCE_LIB_H_\r
+#define _TCG2_PHYSICAL_PRESENCE_LIB_H_\r
+\r
+#include <IndustryStandard/Tpm20.h>\r
+#include <IndustryStandard/TcgPhysicalPresence.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
+\r
+//\r
+// UEFI TCG2 library definition bit of the BIOS TPM Management Flags\r
+//\r
+// BIT0 is reserved\r
+#define TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR               BIT1\r
+// BIT2 is reserved\r
+#define TCG2_LIB_PP_FLAG_RESET_TRACK                                      BIT3\r
+#define TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_TURN_ON             BIT4\r
+#define TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_TURN_OFF            BIT5\r
+#define TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS          BIT6\r
+#define TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS         BIT7\r
+\r
+//\r
+// UEFI TCG2 library definition bit of the BIOS Information Flags\r
+//\r
+#define TCG2_BIOS_INFORMATION_FLAG_HIERACHY_CONTROL_STORAGE_DISABLE      BIT8\r
+#define TCG2_BIOS_INFORMATION_FLAG_HIERACHY_CONTROL_ENDORSEMENT_DISABLE  BIT9\r
+\r
+//\r
+// UEFI TCG2 library definition bit of the BIOS Storage Management Flags\r
+//\r
+#define TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID   BIT16\r
+#define TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID  BIT17\r
+\r
+//\r
+// Default value\r
+//\r
+#define TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT  (TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_TURN_OFF | \\r
+                                                TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR | \\r
+                                                TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS | \\r
+                                                TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS)\r
+\r
+/**\r
+  Check and execute the pending TPM request.\r
+\r
+  The TPM request may come from OS or BIOS. This API will display request information and wait \r
+  for user confirmation if TPM request exists. The TPM request will be sent to TPM device after\r
+  the TPM request is confirmed, and one or more reset may be required to make TPM request to \r
+  take effect.\r
+  \r
+  This API should be invoked after console in and console out are all ready as they are required\r
+  to display request information and get user input to confirm the request.  \r
+\r
+  @param  PlatformAuth                   platform auth value. NULL means no platform auth change.\r
+**/\r
+VOID\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibProcessRequest (\r
+  IN      TPM2B_AUTH                     *PlatformAuth  OPTIONAL\r
+  );\r
+\r
+/**\r
+  Check if the pending TPM request needs user input to confirm.\r
+\r
+  The TPM request may come from OS. This API will check if TPM request exists and need user\r
+  input to confirmation.\r
+  \r
+  @retval    TRUE        TPM needs input to confirm user physical presence.\r
+  @retval    FALSE       TPM doesn't need input to confirm user physical presence.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibNeedUserConfirm (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Return TPM2 ManagementFlags set by PP interface.\r
+\r
+  @retval    ManagementFlags    TPM2 Management Flags.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibGetManagementFlags (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Return TPM Operation Response to OS Environment.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  @param[out]     MostRecentRequest Most recent operation request.\r
+  @param[out]     Response          Response to the most recent operation request.\r
+\r
+  @return Return Code for Return TPM Operation Response to OS Environment.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
+  OUT UINT32                *MostRecentRequest,\r
+  OUT UINT32                *Response\r
+  );\r
+\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Submit TPM Operation Request to Pre-OS Environment and\r
+  Submit TPM Operation Request to Pre-OS Environment 2.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      RequestParameter TPM physical presence operation request parameter.\r
+\r
+  @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
+          Submit TPM Operation Request to Pre-OS Environment 2.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 RequestParameter\r
+  );\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Get User Confirmation Status for Operation.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+\r
+  @return Return Code for Get User Confirmation Status for Operation.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (\r
+  IN UINT32                 OperationRequest\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Library/Tcg2PpVendorLib.h b/SecurityPkg/Include/Library/Tcg2PpVendorLib.h
new file mode 100644 (file)
index 0000000..2434750
--- /dev/null
@@ -0,0 +1,129 @@
+/** @file\r
+  Ihis library is to support TCG PC Client Platform Physical Presence Interface Specification\r
+  Family "2.0" part, >= 128 Vendor Specific PPI Operation.\r
+\r
+  The Vendor Specific PPI operation may change TPM state, BIOS TPM management\r
+  flags, and may need additional boot cycle.\r
+  \r
+  Caution: This function may receive untrusted input.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#ifndef _TCG2_PP_VENDOR_LIB_H_\r
+#define _TCG2_PP_VENDOR_LIB_H_\r
+\r
+#include <IndustryStandard/Tpm20.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+\r
+/**\r
+  Check and execute the requested physical presence command.\r
+\r
+  This API should be invoked in BIOS boot phase to process pending request.\r
+  \r
+  Caution: This function may receive untrusted input.\r
+  \r
+  If OperationRequest < 128, then ASSERT().\r
+\r
+  @param[in]      PlatformAuth     platform auth value. NULL means no platform auth change.\r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in, out] ManagementFlags  BIOS TPM Management Flags.\r
+  @param[out]     ResetRequired    If reset is required to vendor settings in effect.\r
+                                   True, it indicates the reset is required.\r
+                                   False, it indicates the reset is not required.\r
+\r
+  @return TPM Operation Response to OS Environment.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PpVendorLibExecutePendingRequest (\r
+  IN TPM2B_AUTH             *PlatformAuth,  OPTIONAL\r
+  IN UINT32                 OperationRequest,\r
+  IN OUT UINT32             *ManagementFlags,\r
+  OUT BOOLEAN               *ResetRequired\r
+  );\r
+\r
+/**\r
+  Check if there is a valid physical presence command request.\r
+\r
+  This API should be invoked in BIOS boot phase to process pending request.\r
+  \r
+  Caution: This function may receive untrusted input.\r
+\r
+  If OperationRequest < 128, then ASSERT().\r
+\r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      ManagementFlags  BIOS TPM Management Flags.\r
+  @param[out]     RequestConfirmed If the physical presence operation command required user confirm from UI.\r
+                                   True, it indicates the command doesn't require user confirm.\r
+                                   False, it indicates the command need user confirm from UI.\r
+\r
+  @retval  TRUE        Physical Presence operation command is valid.\r
+  @retval  FALSE       Physical Presence operation command is invalid.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Tcg2PpVendorLibHasValidRequest (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 ManagementFlags,\r
+  OUT BOOLEAN               *RequestConfirmed\r
+  );\r
+\r
+/**\r
+  The callback for TPM vendor specific physical presence which is called for\r
+  Submit TPM Operation Request to Pre-OS Environment and\r
+  Submit TPM Operation Request to Pre-OS Environment 2.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  If OperationRequest < 128, then ASSERT().\r
+\r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      ManagementFlags  BIOS TPM Management Flags.\r
+  @param[in]      RequestParameter Extra parameter from the passed package.\r
+\r
+  @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
+          Submit TPM Operation Request to Pre-OS Environment 2.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PpVendorLibSubmitRequestToPreOSFunction (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 ManagementFlags,\r
+  IN UINT32                 RequestParameter\r
+  );\r
+\r
+/**\r
+  The callback for TPM vendor specific physical presence which is called for\r
+  Get User Confirmation Status for Operation.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  If OperationRequest < 128, then ASSERT().\r
+\r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      ManagementFlags  BIOS TPM Management Flags.\r
+\r
+  @return Return Code for Get User Confirmation Status for Operation.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PpVendorLibGetUserConfirmationStatusFunction (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 ManagementFlags\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c b/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c
new file mode 100644 (file)
index 0000000..46fc616
--- /dev/null
@@ -0,0 +1,1245 @@
+/** @file\r
+  Execute pending TPM2 requests from OS or BIOS.\r
+\r
+  Caution: This module requires additional review when modified.\r
+  This driver will have external input - variable.\r
+  This external input must be validated carefully to avoid security issue.\r
+\r
+  Tpm2ExecutePendingTpmRequest() will receive untrusted input and do validation.\r
+\r
+Copyright (c) 2013 - 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/Tcg2Protocol.h>\r
+#include <Protocol/VariableLock.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Guid/EventGroup.h>\r
+#include <Guid/Tcg2PhysicalPresenceData.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+#include <Library/Tcg2PpVendorLib.h>\r
+\r
+#define CONFIRM_BUFFER_SIZE         4096\r
+\r
+EFI_HII_HANDLE mTcg2PpStringPackHandle;\r
+\r
+/**\r
+  Get string by string id from HII Interface.\r
+\r
+  @param[in] Id          String ID.\r
+\r
+  @retval    CHAR16 *    String from ID.\r
+  @retval    NULL        If error occurs.\r
+\r
+**/\r
+CHAR16 *\r
+Tcg2PhysicalPresenceGetStringById (\r
+  IN  EFI_STRING_ID   Id\r
+  )\r
+{\r
+  return HiiGetString (mTcg2PpStringPackHandle, Id, NULL);\r
+}\r
+\r
+/**\r
+  Send ClearControl and Clear command to TPM.\r
+\r
+  @param[in]  PlatformAuth      platform auth value. NULL means no platform auth change.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_TIMEOUT           The register can't run into the expected status in time.\r
+  @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.\r
+  @retval EFI_DEVICE_ERROR      Unexpected device behavior.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2CommandClear (\r
+  IN TPM2B_AUTH                *PlatformAuth  OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  TPMS_AUTH_COMMAND         *AuthSession;\r
+  TPMS_AUTH_COMMAND         LocalAuthSession;\r
+\r
+  if (PlatformAuth == NULL) {\r
+    AuthSession = NULL;\r
+  } else {\r
+    AuthSession = &LocalAuthSession;\r
+    ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));\r
+    LocalAuthSession.sessionHandle = TPM_RS_PW;\r
+    LocalAuthSession.hmac.size = PlatformAuth->size;\r
+    CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "Tpm2ClearControl ... \n"));\r
+  Status = Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO);\r
+  DEBUG ((EFI_D_INFO, "Tpm2ClearControl - %r\n", Status));\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  DEBUG ((EFI_D_INFO, "Tpm2Clear ... \n"));\r
+  Status = Tpm2Clear (TPM_RH_PLATFORM, AuthSession);\r
+  DEBUG ((EFI_D_INFO, "Tpm2Clear - %r\n", Status));\r
+\r
+Done:\r
+  ZeroMem (&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Alloc PCR data.\r
+\r
+  @param[in]  PlatformAuth      platform auth value. NULL means no platform auth change.\r
+  @param[in]  SupportedPCRBanks Supported PCR banks\r
+  @param[in]  PCRBanks          PCR banks\r
+  \r
+  @retval EFI_SUCCESS Operation completed successfully.\r
+**/\r
+EFI_STATUS\r
+Tpm2CommandAllocPcr (\r
+  IN TPM2B_AUTH                *PlatformAuth,  OPTIONAL\r
+  IN UINT32                    SupportedPCRBanks,\r
+  IN UINT32                    PCRBanks\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  TPMS_AUTH_COMMAND         *AuthSession;\r
+  TPMS_AUTH_COMMAND         LocalAuthSession;\r
+  TPML_PCR_SELECTION        PcrAllocation;\r
+  TPMI_YES_NO               AllocationSuccess;\r
+  UINT32                    MaxPCR;\r
+  UINT32                    SizeNeeded;\r
+  UINT32                    SizeAvailable;\r
+\r
+  if (PlatformAuth == NULL) {\r
+    AuthSession = NULL;\r
+  } else {\r
+    AuthSession = &LocalAuthSession;\r
+    ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));\r
+    LocalAuthSession.sessionHandle = TPM_RS_PW;\r
+    LocalAuthSession.hmac.size = PlatformAuth->size;\r
+    CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
+  }\r
+\r
+  //\r
+  // Fill input\r
+  //\r
+  ZeroMem (&PcrAllocation, sizeof(PcrAllocation));\r
+  if ((EFI_TCG2_BOOT_HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((EFI_TCG2_BOOT_HASH_ALG_SHA1 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+    PcrAllocation.count++;\r
+  }\r
+  if ((EFI_TCG2_BOOT_HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((EFI_TCG2_BOOT_HASH_ALG_SHA256 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+    PcrAllocation.count++;\r
+  }\r
+  if ((EFI_TCG2_BOOT_HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((EFI_TCG2_BOOT_HASH_ALG_SHA384 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+    PcrAllocation.count++;\r
+  }\r
+  if ((EFI_TCG2_BOOT_HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((EFI_TCG2_BOOT_HASH_ALG_SHA512 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+    PcrAllocation.count++;\r
+  }\r
+  if ((EFI_TCG2_BOOT_HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((EFI_TCG2_BOOT_HASH_ALG_SM3_256 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+    PcrAllocation.count++;\r
+  }\r
+  Status = Tpm2PcrAllocate (\r
+             TPM_RH_PLATFORM,\r
+             AuthSession,\r
+             &PcrAllocation,\r
+             &AllocationSuccess,\r
+             &MaxPCR,\r
+             &SizeNeeded,\r
+             &SizeAvailable\r
+             );\r
+  DEBUG ((EFI_D_INFO, "Tpm2PcrAllocate - %r\n", Status));\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));\r
+  DEBUG ((EFI_D_INFO, "MaxPCR            - %08x\n", MaxPCR));\r
+  DEBUG ((EFI_D_INFO, "SizeNeeded        - %08x\n", SizeNeeded));\r
+  DEBUG ((EFI_D_INFO, "SizeAvailable     - %08x\n", SizeAvailable));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Change EPS.\r
+\r
+  @param[in]  PlatformAuth      platform auth value. NULL means no platform auth change.\r
+  \r
+  @retval EFI_SUCCESS Operation completed successfully.\r
+**/\r
+EFI_STATUS\r
+Tpm2CommandChangeEps (\r
+  IN TPM2B_AUTH                *PlatformAuth  OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  TPMS_AUTH_COMMAND         *AuthSession;\r
+  TPMS_AUTH_COMMAND         LocalAuthSession;\r
+\r
+  if (PlatformAuth == NULL) {\r
+    AuthSession = NULL;\r
+  } else {\r
+    AuthSession = &LocalAuthSession;\r
+    ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));\r
+    LocalAuthSession.sessionHandle = TPM_RS_PW;\r
+    LocalAuthSession.hmac.size = PlatformAuth->size;\r
+    CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
+  }\r
+\r
+  Status = Tpm2ChangeEPS (TPM_RH_PLATFORM, AuthSession);\r
+  DEBUG ((EFI_D_INFO, "Tpm2ChangeEPS - %r\n", Status));\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Execute physical presence operation requested by the OS.\r
+\r
+  @param[in]      PlatformAuth        platform auth value. NULL means no platform auth change.\r
+  @param[in]      CommandCode         Physical presence operation value.\r
+  @param[in]      CommandParameter    Physical presence operation parameter.\r
+  @param[in, out] PpiFlags            The physical presence interface flags.\r
+  \r
+  @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE   Unknown physical presence operation.\r
+  @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE   Error occurred during sending command to TPM or \r
+                                                   receiving response from TPM.\r
+  @retval Others                                   Return code from the TPM device after command execution.\r
+**/\r
+UINT32\r
+Tcg2ExecutePhysicalPresence (\r
+  IN      TPM2B_AUTH                       *PlatformAuth,  OPTIONAL\r
+  IN      UINT32                           CommandCode,\r
+  IN      UINT32                           CommandParameter,\r
+  IN OUT  EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *PpiFlags\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_TCG2_PROTOCOL                 *Tcg2Protocol;\r
+  EFI_TCG2_BOOT_SERVICE_CAPABILITY  ProtocolCapability;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  ProtocolCapability.Size = sizeof(ProtocolCapability);\r
+  Status = Tcg2Protocol->GetCapability (\r
+                           Tcg2Protocol,\r
+                           &ProtocolCapability\r
+                           );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  switch (CommandCode) {\r
+    case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
+      Status = Tpm2CommandClear (PlatformAuth);\r
+      if (EFI_ERROR (Status)) {\r
+        return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
+      } else {\r
+        return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
+      }\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
+      PpiFlags->PPFlags |= TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;\r
+      return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
+      PpiFlags->PPFlags &= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;\r
+      return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
+      Status = Tpm2CommandAllocPcr (PlatformAuth, ProtocolCapability.HashAlgorithmBitmap, CommandParameter);\r
+      if (EFI_ERROR (Status)) {\r
+        return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
+      } else {\r
+        return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
+      }\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
+      Status = Tpm2CommandChangeEps (PlatformAuth);\r
+      if (EFI_ERROR (Status)) {\r
+        return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
+      } else {\r
+        return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
+      }\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
+      Status = Tpm2CommandAllocPcr (PlatformAuth, ProtocolCapability.HashAlgorithmBitmap, ProtocolCapability.HashAlgorithmBitmap);\r
+      if (EFI_ERROR (Status)) {\r
+        return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
+      } else {\r
+        return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
+      }\r
+\r
+    default:\r
+      if (CommandCode <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
+        return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
+      } else {\r
+        return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
+      }\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Read the specified key for user confirmation.\r
+\r
+  @param[in]  CautionKey  If true,  F12 is used as confirm key;\r
+                          If false, F10 is used as confirm key.\r
+\r
+  @retval     TRUE        User confirmed the changes by input.\r
+  @retval     FALSE       User discarded the changes.\r
+**/\r
+BOOLEAN\r
+Tcg2ReadUserKey (\r
+  IN     BOOLEAN                    CautionKey\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_INPUT_KEY                     Key;\r
+  UINT16                            InputKey;\r
+      \r
+  InputKey = 0; \r
+  do {\r
+    Status = gBS->CheckEvent (gST->ConIn->WaitForKey);\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+      if (Key.ScanCode == SCAN_ESC) {\r
+        InputKey = Key.ScanCode;\r
+      }\r
+      if ((Key.ScanCode == SCAN_F10) && !CautionKey) {\r
+        InputKey = Key.ScanCode;\r
+      }\r
+      if ((Key.ScanCode == SCAN_F12) && CautionKey) {\r
+        InputKey = Key.ScanCode;\r
+      }\r
+    }      \r
+  } while (InputKey == 0);\r
+\r
+  if (InputKey != SCAN_ESC) {\r
+    return TRUE;\r
+  }\r
+  \r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Fill Buffer With BootHashAlg.\r
+\r
+  @param[in] Buffer               Buffer to be filled.\r
+  @param[in] BufferSize           Size of buffer.\r
+  @param[in] BootHashAlg          BootHashAlg.\r
+\r
+**/\r
+VOID\r
+Tcg2FillBufferWithBootHashAlg (\r
+  IN UINT16  *Buffer,\r
+  IN UINTN   BufferSize,\r
+  IN UINT32  BootHashAlg\r
+  )\r
+{\r
+  Buffer[0] = 0;\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+}\r
+\r
+/**\r
+  Display the confirm text and get user confirmation.\r
+\r
+  @param[in] TpmPpCommand             The requested TPM physical presence command.\r
+  @param[in] TpmPpCommandParameter    The requested TPM physical presence command parameter.\r
+\r
+  @retval    TRUE          The user has confirmed the changes.\r
+  @retval    FALSE         The user doesn't confirm the changes.\r
+**/\r
+BOOLEAN\r
+Tcg2UserConfirm (\r
+  IN      UINT32                    TpmPpCommand,\r
+  IN      UINT32                    TpmPpCommandParameter\r
+  )\r
+{\r
+  CHAR16                            *ConfirmText;\r
+  CHAR16                            *TmpStr1;\r
+  CHAR16                            *TmpStr2; \r
+  UINTN                             BufSize;\r
+  BOOLEAN                           CautionKey;\r
+  BOOLEAN                           NoPpiInfo;\r
+  UINT16                            Index;\r
+  CHAR16                            DstStr[81];\r
+  CHAR16                            TempBuffer[1024];\r
+  CHAR16                            TempBuffer2[1024];\r
+  EFI_TCG2_PROTOCOL                 *Tcg2Protocol;\r
+  EFI_TCG2_BOOT_SERVICE_CAPABILITY  ProtocolCapability;\r
+  UINT32                            CurrentPCRBanks;\r
+  EFI_STATUS                        Status;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  ProtocolCapability.Size = sizeof(ProtocolCapability);\r
+  Status = Tcg2Protocol->GetCapability (\r
+                           Tcg2Protocol,\r
+                           &ProtocolCapability\r
+                           );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = Tcg2Protocol->GetActivePcrBanks (\r
+                           Tcg2Protocol,\r
+                           &CurrentPCRBanks\r
+                           );\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  TmpStr2     = NULL;\r
+  CautionKey  = FALSE;\r
+  NoPpiInfo   = FALSE;\r
+  BufSize     = CONFIRM_BUFFER_SIZE;\r
+  ConfirmText = AllocateZeroPool (BufSize);\r
+  ASSERT (ConfirmText != NULL);\r
+\r
+  switch (TpmPpCommand) {\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);      \r
+\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
+      CautionKey = TRUE;\r
+      NoPpiInfo  = TRUE;\r
+      TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1); \r
+\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS));\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);      \r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);      \r
+\r
+      Tcg2FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), TpmPpCommandParameter);\r
+      Tcg2FillBufferWithBootHashAlg (TempBuffer2, sizeof(TempBuffer2), CurrentPCRBanks);\r
+\r
+      TmpStr1 = AllocateZeroPool (BufSize);\r
+      ASSERT (TmpStr1 != NULL);\r
+      UnicodeSPrint (TmpStr1, BufSize, L"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks, TempBuffer2, TpmPpCommandParameter, TempBuffer);\r
+\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);      \r
+\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS));\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);      \r
+      \r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);      \r
+\r
+      break;\r
+      \r
+\r
+    default:\r
+      ;\r
+  }\r
+\r
+  if (TmpStr2 == NULL) {\r
+    FreePool (ConfirmText);\r
+    return FALSE;\r
+  }\r
+\r
+  if (TpmPpCommand < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) {\r
+    if (CautionKey) {\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
+    } else {\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
+    }\r
+    StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+    FreePool (TmpStr1);\r
+\r
+    if (NoPpiInfo) {\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+    }\r
+\r
+    TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));\r
+  } else {\r
+    if (CautionKey) {\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY));\r
+    } else {\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY));\r
+    }\r
+    StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+    FreePool (TmpStr1);\r
+\r
+    if (NoPpiInfo) {\r
+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO));\r
+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+    }\r
+\r
+    TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY));\r
+  }\r
+  BufSize -= StrSize (ConfirmText);\r
+  UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);\r
+\r
+  DstStr[80] = L'\0';\r
+  for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {\r
+    StrnCpyS (DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, sizeof (DstStr) / sizeof (CHAR16) - 1);    \r
+    Print (DstStr);    \r
+  }\r
+  \r
+  FreePool (TmpStr1);\r
+  FreePool (TmpStr2);\r
+  FreePool (ConfirmText);\r
+\r
+  if (Tcg2ReadUserKey (CautionKey)) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;  \r
+}\r
+\r
+/**\r
+  Check if there is a valid physical presence command request. Also updates parameter value \r
+  to whether the requested physical presence command already confirmed by user\r
\r
+   @param[in]  TcgPpData                 EFI Tcg2 Physical Presence request data. \r
+   @param[in]  Flags                     The physical presence interface flags.\r
+   @param[out] RequestConfirmed            If the physical presence operation command required user confirm from UI.\r
+                                             True, it indicates the command doesn't require user confirm, or already confirmed \r
+                                                   in last boot cycle by user.\r
+                                             False, it indicates the command need user confirm from UI.\r
+\r
+   @retval  TRUE        Physical Presence operation command is valid.\r
+   @retval  FALSE       Physical Presence operation command is invalid.\r
+\r
+**/\r
+BOOLEAN\r
+Tcg2HaveValidTpmRequest  (\r
+  IN      EFI_TCG2_PHYSICAL_PRESENCE       *TcgPpData,\r
+  IN      EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags,\r
+  OUT     BOOLEAN                          *RequestConfirmed\r
+  )\r
+{\r
+  BOOLEAN  IsRequestValid;\r
+\r
+  *RequestConfirmed = FALSE;\r
+\r
+  switch (TcgPpData->PPRequest) {\r
+    case TCG2_PHYSICAL_PRESENCE_NO_ACTION:\r
+      *RequestConfirmed = TRUE;\r
+      return TRUE;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
+      if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {\r
+        *RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
+      *RequestConfirmed = TRUE;\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
+      if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {\r
+        *RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
+      if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {\r
+        *RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+      \r
+    case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
+      *RequestConfirmed = TRUE;\r
+      break;\r
+\r
+    default:\r
+      if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+        IsRequestValid = Tcg2PpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed);\r
+        if (!IsRequestValid) {\r
+          return FALSE;\r
+        } else {\r
+          break;\r
+        }\r
+      } else {\r
+        //\r
+        // Wrong Physical Presence command\r
+        //\r
+        return FALSE;\r
+      }\r
+  }\r
+\r
+  if ((Flags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) != 0) {\r
+    //\r
+    // It had been confirmed in last boot, it doesn't need confirm again.\r
+    //\r
+    *RequestConfirmed = TRUE;\r
+  }\r
+\r
+  //\r
+  // Physical Presence command is correct\r
+  //\r
+  return TRUE;\r
+}\r
+\r
+\r
+/**\r
+  Check and execute the requested physical presence command.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  TcgPpData variable is external input, so this function will validate\r
+  its data structure to be valid value.\r
+\r
+  @param[in] PlatformAuth         platform auth value. NULL means no platform auth change.\r
+  @param[in] TcgPpData            Point to the physical presence NV variable.\r
+  @param[in] Flags                The physical presence interface flags.\r
+**/\r
+VOID\r
+Tcg2ExecutePendingTpmRequest (\r
+  IN      TPM2B_AUTH                       *PlatformAuth,  OPTIONAL\r
+  IN      EFI_TCG2_PHYSICAL_PRESENCE       *TcgPpData,\r
+  IN      EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  BOOLEAN                           RequestConfirmed;\r
+  EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  NewFlags;\r
+  BOOLEAN                           ResetRequired;\r
+  UINT32                            NewPPFlags;\r
+\r
+  if (TcgPpData->PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
+    //\r
+    // No operation request\r
+    //\r
+    return;\r
+  }\r
+\r
+  if (!Tcg2HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {\r
+    //\r
+    // Invalid operation request.\r
+    //\r
+    if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
+      TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
+    } else {\r
+      TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
+    }\r
+    TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
+    TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;\r
+    TcgPpData->PPRequestParameter = 0;\r
+\r
+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+    Status = gRT->SetVariable (\r
+                    TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                    &gEfiTcg2PhysicalPresenceGuid,\r
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                    DataSize,\r
+                    TcgPpData\r
+                    );\r
+    return;\r
+  }\r
+\r
+  ResetRequired = FALSE;\r
+  if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+    NewFlags = Flags;\r
+    NewPPFlags = NewFlags.PPFlags;\r
+    TcgPpData->PPResponse = Tcg2PpVendorLibExecutePendingRequest (PlatformAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);\r
+    NewFlags.PPFlags = NewPPFlags;\r
+  } else {\r
+    if (!RequestConfirmed) {\r
+      //\r
+      // Print confirm text and wait for approval. \r
+      //\r
+      RequestConfirmed = Tcg2UserConfirm (TcgPpData->PPRequest, TcgPpData->PPRequestParameter);\r
+    }\r
+\r
+    //\r
+    // Execute requested physical presence command\r
+    //\r
+    TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT;\r
+    NewFlags = Flags;\r
+    if (RequestConfirmed) {\r
+      TcgPpData->PPResponse = Tcg2ExecutePhysicalPresence (\r
+                                PlatformAuth,\r
+                                TcgPpData->PPRequest, \r
+                                TcgPpData->PPRequestParameter, \r
+                                &NewFlags\r
+                                );\r
+    }\r
+  }\r
+\r
+  //\r
+  // Save the flags if it is updated.\r
+  //\r
+  if (CompareMem (&Flags, &NewFlags, sizeof(EFI_TCG2_PHYSICAL_PRESENCE_FLAGS)) != 0) {\r
+    Status   = gRT->SetVariable (\r
+                      TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                      &gEfiTcg2PhysicalPresenceGuid,\r
+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                      sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),\r
+                      &NewFlags\r
+                      ); \r
+  }\r
+\r
+  //\r
+  // Clear request\r
+  //\r
+  if ((NewFlags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) == 0) {\r
+    TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
+    TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;    \r
+    TcgPpData->PPRequestParameter = 0;\r
+  }\r
+\r
+  //\r
+  // Save changes\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+  Status = gRT->SetVariable (\r
+                  TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiTcg2PhysicalPresenceGuid,\r
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                  DataSize,\r
+                  TcgPpData\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Reset system to make new TPM settings in effect\r
+  //\r
+  switch (TcgPpData->LastPPRequest) {\r
+    case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
+    case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
+    case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
+      break;\r
+\r
+    default:\r
+      if (TcgPpData->LastPPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+        if (ResetRequired) {\r
+          break;\r
+        } else {\r
+          return ;\r
+        }\r
+      }\r
+      if (TcgPpData->PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
+        break;\r
+      }\r
+      return;\r
+  }\r
+\r
+  Print (L"Rebooting system to make TPM2 settings in effect\n");\r
+  gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
+  ASSERT (FALSE);  \r
+}\r
+\r
+/**\r
+  Check and execute the pending TPM request.\r
+\r
+  The TPM request may come from OS or BIOS. This API will display request information and wait \r
+  for user confirmation if TPM request exists. The TPM request will be sent to TPM device after\r
+  the TPM request is confirmed, and one or more reset may be required to make TPM request to \r
+  take effect.\r
+  \r
+  This API should be invoked after console in and console out are all ready as they are required\r
+  to display request information and get user input to confirm the request.  \r
+\r
+  @param[in]  PlatformAuth                   platform auth value. NULL means no platform auth change.\r
+**/\r
+VOID\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibProcessRequest (\r
+  IN      TPM2B_AUTH                     *PlatformAuth  OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  EFI_TCG2_PHYSICAL_PRESENCE        TcgPpData;\r
+  EFI_TCG2_PROTOCOL                 *Tcg2Protocol;\r
+  EDKII_VARIABLE_LOCK_PROTOCOL      *VariableLockProtocol;\r
+  EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  PpiFlags;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return ;\r
+  }\r
+  \r
+  //\r
+  // Check S4 resume\r
+  //\r
+  if (GetBootModeHob () == BOOT_ON_S4_RESUME) {\r
+    DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));\r
+    return ;\r
+  }\r
+\r
+  mTcg2PpStringPackHandle = HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid, gImageHandle, DxeTcg2PhysicalPresenceLibStrings, NULL);\r
+  ASSERT (mTcg2PpStringPackHandle != NULL);\r
+\r
+  //\r
+  // Initialize physical presence flags.\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
+  Status = gRT->GetVariable (\r
+                  TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                  &gEfiTcg2PhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &PpiFlags\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    PpiFlags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
+    Status   = gRT->SetVariable (\r
+                      TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                      &gEfiTcg2PhysicalPresenceGuid,\r
+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                      sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),\r
+                      &PpiFlags\r
+                      );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence flag failed, Status = %r\n", Status));\r
+      return ;\r
+    }\r
+  }\r
+  DEBUG ((EFI_D_INFO, "[TPM2] PpiFlags = %x\n", PpiFlags.PPFlags));\r
+\r
+  //\r
+  // This flags variable controls whether physical presence is required for TPM command. \r
+  // It should be protected from malicious software. We set it as read-only variable here.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = VariableLockProtocol->RequestToLock (\r
+                                     VariableLockProtocol,\r
+                                     TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                                     &gEfiTcg2PhysicalPresenceGuid\r
+                                     );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "[TPM2] Error when lock variable %s, Status = %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Initialize physical presence variable.\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+  Status = gRT->GetVariable (\r
+                  TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiTcg2PhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &TcgPpData\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));\r
+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+    Status   = gRT->SetVariable (\r
+                      TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                      &gEfiTcg2PhysicalPresenceGuid,\r
+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                      DataSize,\r
+                      &TcgPpData\r
+                      );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status));\r
+      return ;\r
+    }\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));\r
+\r
+  //\r
+  // Execute pending TPM request.\r
+  //  \r
+  Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, PpiFlags);\r
+  DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags));\r
+\r
+}\r
+\r
+/**\r
+  Check if the pending TPM request needs user input to confirm.\r
+\r
+  The TPM request may come from OS. This API will check if TPM request exists and need user\r
+  input to confirmation.\r
+  \r
+  @retval    TRUE        TPM needs input to confirm user physical presence.\r
+  @retval    FALSE       TPM doesn't need input to confirm user physical presence.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibNeedUserConfirm(\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_TCG2_PHYSICAL_PRESENCE        TcgPpData;\r
+  UINTN                             DataSize;\r
+  BOOLEAN                           RequestConfirmed;\r
+  EFI_TCG2_PROTOCOL                 *Tcg2Protocol;\r
+  EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  PpiFlags;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check S4 resume\r
+  //\r
+  if (GetBootModeHob () == BOOT_ON_S4_RESUME) {\r
+    DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check Tpm requests\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+  Status = gRT->GetVariable (\r
+                  TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiTcg2PhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &TcgPpData\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
+  Status = gRT->GetVariable (\r
+                  TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                  &gEfiTcg2PhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &PpiFlags\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+  \r
+  if (TcgPpData.PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
+    //\r
+    // No operation request\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  if (!Tcg2HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {\r
+    //\r
+    // Invalid operation request.\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  if (!RequestConfirmed) {\r
+    //\r
+    // Need UI to confirm\r
+    //\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Return TPM Operation Response to OS Environment.\r
+\r
+  @param[out]     MostRecentRequest Most recent operation request.\r
+  @param[out]     Response          Response to the most recent operation request.\r
+\r
+  @return Return Code for Return TPM Operation Response to OS Environment.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
+  OUT UINT32                *MostRecentRequest,\r
+  OUT UINT32                *Response\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  EFI_TCG2_PHYSICAL_PRESENCE        PpData;\r
+  \r
+  DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));\r
+\r
+  //\r
+  // Get the Physical Presence variable\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+  Status = gRT->GetVariable (\r
+                  TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiTcg2PhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &PpData\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    *MostRecentRequest = 0;\r
+    *Response          = 0;\r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
+    return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
+  }\r
+  \r
+  *MostRecentRequest = PpData.LastPPRequest;\r
+  *Response          = PpData.PPResponse;\r
+\r
+  return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
+}\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Submit TPM Operation Request to Pre-OS Environment and\r
+  Submit TPM Operation Request to Pre-OS Environment 2.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      RequestParameter TPM physical presence operation request parameter.\r
+\r
+  @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
+          Submit TPM Operation Request to Pre-OS Environment 2.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 RequestParameter\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  EFI_TCG2_PHYSICAL_PRESENCE        PpData;\r
+  EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  Flags;\r
+  \r
+  DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));\r
+  \r
+  //\r
+  // Get the Physical Presence variable\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+  Status = gRT->GetVariable (\r
+                  TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiTcg2PhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &PpData\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
+    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+  }\r
+\r
+  if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
+      (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {\r
+    //\r
+    // This command requires UI to prompt user for Auth data.\r
+    //\r
+    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
+  }\r
+\r
+  if (PpData.PPRequest != OperationRequest) {\r
+    PpData.PPRequest = (UINT8)OperationRequest;\r
+    PpData.PPRequestParameter = RequestParameter;\r
+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+    Status = gRT->SetVariable (\r
+                    TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                    &gEfiTcg2PhysicalPresenceGuid,\r
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                    DataSize,\r
+                    &PpData\r
+                    );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) { \r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
+    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+  }\r
+\r
+  if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
+    Status = gRT->GetVariable (\r
+                    TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                    &gEfiTcg2PhysicalPresenceGuid,\r
+                    NULL,\r
+                    &DataSize,\r
+                    &Flags\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
+    }\r
+    return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);\r
+  }\r
+\r
+  return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
+}\r
diff --git a/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf b/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
new file mode 100644 (file)
index 0000000..bad4fe4
--- /dev/null
@@ -0,0 +1,69 @@
+## @file\r
+#  Executes TPM 2.0 requests from OS or BIOS\r
+#\r
+#  This library will check and execute TPM 2.0 request from OS or BIOS. The request may\r
+#  ask for user confirmation before execution.\r
+#\r
+#  Caution: This module requires additional review when modified.\r
+#  This driver will have external input - variable.\r
+#  This external input must be validated carefully to avoid security issue.\r
+#\r
+# Copyright (c) 2013 - 2015, 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
+# http://opensource.org/licenses/bsd-license.php\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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeTcg2PhysicalPresenceLib\r
+  MODULE_UNI_FILE                = DxeTcg2PhysicalPresenceLib.uni\r
+  FILE_GUID                      = 7E507A86-DE8B-4AD3-BC4C-0498389098D3\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tcg2PhysicalPresenceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_APPLICATION UEFI_DRIVER \r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  DxeTcg2PhysicalPresenceLib.c\r
+  PhysicalPresenceStrings.uni\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+  UefiRuntimeServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  PrintLib\r
+  HiiLib\r
+  HobLib\r
+  Tpm2CommandLib\r
+  Tcg2PpVendorLib\r
+\r
+[Protocols]\r
+  gEfiTcg2ProtocolGuid                 ## CONSUMES\r
+  gEdkiiVariableLockProtocolGuid       ## CONSUMES\r
+\r
+[Guids]\r
+  ## CONSUMES           ## HII\r
+  ## SOMETIMES_PRODUCES ## Variable:L"Tcg2PhysicalPresence"\r
+  ## SOMETIMES_CONSUMES ## Variable:L"Tcg2PhysicalPresence"\r
+  ## SOMETIMES_PRODUCES ## Variable:L"Tcg2PhysicalPresenceFlags"\r
+  ## SOMETIMES_CONSUMES ## Variable:L"Tcg2PhysicalPresenceFlags"\r
+  gEfiTcg2PhysicalPresenceGuid\r
diff --git a/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni b/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni
new file mode 100644 (file)
index 0000000..9794792
Binary files /dev/null and b/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni differ
diff --git a/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni b/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni
new file mode 100644 (file)
index 0000000..30f21a3
Binary files /dev/null and b/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni differ
index a5d7fe5..26bf6fb 100644 (file)
@@ -9,10 +9,10 @@
   DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content\r
   read is within the image buffer.\r
 \r
-  TrEEMeasurePeImage() function will accept untrusted PE/COFF image and validate its\r
+  Tcg2MeasurePeImage() function will accept untrusted PE/COFF image and validate its\r
   data structure within this image buffer before use.\r
 \r
-  TrEEMeasureGptTable() function will receive untrusted GPT partition table, and parse\r
+  Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse\r
   partition data carefully.\r
 \r
 Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>\r
@@ -28,7 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include <PiDxe.h>\r
 \r
-#include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
 #include <Protocol/BlockIo.h>\r
 #include <Protocol/DiskIo.h>\r
 #include <Protocol/DevicePathToText.h>\r
@@ -51,15 +51,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 // Flag to check GPT partition. It only need be measured once.\r
 //\r
-BOOLEAN                           mTrEEMeasureGptTableFlag = FALSE;\r
-UINTN                             mTrEEMeasureGptCount = 0;\r
-VOID                              *mTrEEFileBuffer;\r
-UINTN                             mTrEEImageSize;\r
+BOOLEAN                           mTcg2MeasureGptTableFlag = FALSE;\r
+UINTN                             mTcg2MeasureGptCount = 0;\r
+VOID                              *mTcg2FileBuffer;\r
+UINTN                             mTcg2ImageSize;\r
 //\r
 // Measured FV handle cache\r
 //\r
-EFI_HANDLE                        mTrEECacheMeasuredHandle  = NULL;\r
-MEASURED_HOB_DATA                 *mTrEEMeasuredHobData     = NULL;\r
+EFI_HANDLE                        mTcg2CacheMeasuredHandle  = NULL;\r
+MEASURED_HOB_DATA                 *mTcg2MeasuredHobData     = NULL;\r
 \r
 /**\r
   Reads contents of a PE/COFF image in memory buffer.\r
@@ -96,11 +96,11 @@ DxeTpm2MeasureBootLibImageRead (
   }\r
 \r
   EndPosition = FileOffset + *ReadSize;\r
-  if (EndPosition > mTrEEImageSize) {\r
-    *ReadSize = (UINT32)(mTrEEImageSize - FileOffset);\r
+  if (EndPosition > mTcg2ImageSize) {\r
+    *ReadSize = (UINT32)(mTcg2ImageSize - FileOffset);\r
   }\r
 \r
-  if (FileOffset >= mTrEEImageSize) {\r
+  if (FileOffset >= mTcg2ImageSize) {\r
     *ReadSize = 0;\r
   }\r
 \r
@@ -115,7 +115,7 @@ DxeTpm2MeasureBootLibImageRead (
   Caution: This function may receive untrusted input.\r
   The GPT partition table is external input, so this function should parse partition data carefully.\r
 \r
-  @param TreeProtocol            Pointer to the located TREE protocol instance.\r
+  @param Tcg2Protocol            Pointer to the located TCG2 protocol instance.\r
   @param GptHandle               Handle that GPT partition was installed.\r
 \r
   @retval EFI_SUCCESS            Successfully measure GPT table.\r
@@ -126,8 +126,8 @@ DxeTpm2MeasureBootLibImageRead (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-TrEEMeasureGptTable (\r
-  IN  EFI_TREE_PROTOCOL  *TreeProtocol,\r
+Tcg2MeasureGptTable (\r
+  IN  EFI_TCG2_PROTOCOL  *Tcg2Protocol,\r
   IN  EFI_HANDLE         GptHandle\r
   )\r
 {\r
@@ -139,11 +139,11 @@ TrEEMeasureGptTable (
   UINT8                             *EntryPtr;\r
   UINTN                             NumberOfPartition;\r
   UINT32                            Index;\r
-  TrEE_EVENT                        *TreeEvent;\r
+  EFI_TCG2_EVENT                    *Tcg2Event;\r
   EFI_GPT_DATA                      *GptData;\r
   UINT32                            EventSize;\r
 \r
-  if (mTrEEMeasureGptCount > 0) {\r
+  if (mTcg2MeasureGptCount > 0) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -212,19 +212,19 @@ TrEEMeasureGptTable (
   // \r
   EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) \r
                         + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry);\r
-  TreeEvent = (TrEE_EVENT *) AllocateZeroPool (EventSize + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event));\r
-  if (TreeEvent == NULL) {\r
+  Tcg2Event = (EFI_TCG2_EVENT *) AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event));\r
+  if (Tcg2Event == NULL) {\r
     FreePool (PrimaryHeader);\r
     FreePool (EntryPtr);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  TreeEvent->Size = EventSize + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event);\r
-  TreeEvent->Header.HeaderSize    = sizeof(TrEE_EVENT_HEADER);\r
-  TreeEvent->Header.HeaderVersion = TREE_EVENT_HEADER_VERSION;\r
-  TreeEvent->Header.PCRIndex      = 5;\r
-  TreeEvent->Header.EventType     = EV_EFI_GPT_EVENT;\r
-  GptData = (EFI_GPT_DATA *) TreeEvent->Event;  \r
+  Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event);\r
+  Tcg2Event->Header.HeaderSize    = sizeof(EFI_TCG2_EVENT_HEADER);\r
+  Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;\r
+  Tcg2Event->Header.PCRIndex      = 5;\r
+  Tcg2Event->Header.EventType     = EV_EFI_GPT_EVENT;\r
+  GptData = (EFI_GPT_DATA *) Tcg2Event->Event;  \r
 \r
   //\r
   // Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition\r
@@ -251,20 +251,20 @@ TrEEMeasureGptTable (
   //\r
   // Measure the GPT data\r
   //\r
-  Status = TreeProtocol->HashLogExtendEvent (\r
-             TreeProtocol,\r
+  Status = Tcg2Protocol->HashLogExtendEvent (\r
+             Tcg2Protocol,\r
              0,\r
              (EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) GptData,\r
              (UINT64) EventSize,\r
-             TreeEvent\r
+             Tcg2Event\r
              );\r
   if (!EFI_ERROR (Status)) {\r
-    mTrEEMeasureGptCount++;\r
+    mTcg2MeasureGptCount++;\r
   }\r
 \r
   FreePool (PrimaryHeader);\r
   FreePool (EntryPtr);\r
-  FreePool (TreeEvent);\r
+  FreePool (Tcg2Event);\r
 \r
   return Status;\r
 }\r
@@ -277,7 +277,7 @@ TrEEMeasureGptTable (
   PE/COFF image is external input, so this function will validate its data structure\r
   within this image buffer before use.\r
 \r
-  @param[in] TreeProtocol   Pointer to the located TREE protocol instance.\r
+  @param[in] Tcg2Protocol   Pointer to the located TCG2 protocol instance.\r
   @param[in] ImageAddress   Start address of image buffer.\r
   @param[in] ImageSize      Image size\r
   @param[in] LinkTimeBase   Address that the image is loaded into memory.\r
@@ -292,8 +292,8 @@ TrEEMeasureGptTable (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-TrEEMeasurePeImage (\r
-  IN  EFI_TREE_PROTOCOL         *TreeProtocol,\r
+Tcg2MeasurePeImage (\r
+  IN  EFI_TCG2_PROTOCOL         *Tcg2Protocol,\r
   IN  EFI_PHYSICAL_ADDRESS      ImageAddress,\r
   IN  UINTN                     ImageSize,\r
   IN  UINTN                     LinkTimeBase,\r
@@ -302,7 +302,7 @@ TrEEMeasurePeImage (
   )\r
 {\r
   EFI_STATUS                        Status;\r
-  TrEE_EVENT                        *TreeEvent;\r
+  EFI_TCG2_EVENT                    *Tcg2Event;\r
   EFI_IMAGE_LOAD_EVENT              *ImageLoad;\r
   UINT32                            FilePathSize;\r
   UINT32                            EventSize;\r
@@ -315,33 +315,33 @@ TrEEMeasurePeImage (
   // Determine destination PCR by BootPolicy\r
   //\r
   EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize;\r
-  TreeEvent = AllocateZeroPool (EventSize + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event));\r
-  if (TreeEvent == NULL) {\r
+  Tcg2Event = AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event));\r
+  if (Tcg2Event == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  TreeEvent->Size = EventSize + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event);\r
-  TreeEvent->Header.HeaderSize    = sizeof(TrEE_EVENT_HEADER);\r
-  TreeEvent->Header.HeaderVersion = TREE_EVENT_HEADER_VERSION;\r
-  ImageLoad           = (EFI_IMAGE_LOAD_EVENT *) TreeEvent->Event;\r
+  Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event);\r
+  Tcg2Event->Header.HeaderSize    = sizeof(EFI_TCG2_EVENT_HEADER);\r
+  Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;\r
+  ImageLoad           = (EFI_IMAGE_LOAD_EVENT *) Tcg2Event->Event;\r
 \r
   switch (ImageType) {\r
     case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:\r
-      TreeEvent->Header.EventType = EV_EFI_BOOT_SERVICES_APPLICATION;\r
-      TreeEvent->Header.PCRIndex  = 4;\r
+      Tcg2Event->Header.EventType = EV_EFI_BOOT_SERVICES_APPLICATION;\r
+      Tcg2Event->Header.PCRIndex  = 4;\r
       break;\r
     case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:\r
-      TreeEvent->Header.EventType = EV_EFI_BOOT_SERVICES_DRIVER;\r
-      TreeEvent->Header.PCRIndex  = 2;\r
+      Tcg2Event->Header.EventType = EV_EFI_BOOT_SERVICES_DRIVER;\r
+      Tcg2Event->Header.PCRIndex  = 2;\r
       break;\r
     case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
-      TreeEvent->Header.EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;\r
-      TreeEvent->Header.PCRIndex  = 2;\r
+      Tcg2Event->Header.EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;\r
+      Tcg2Event->Header.PCRIndex  = 2;\r
       break;\r
     default:\r
       DEBUG ((\r
         EFI_D_ERROR,\r
-        "TrEEMeasurePeImage: Unknown subsystem type %d",\r
+        "Tcg2MeasurePeImage: Unknown subsystem type %d",\r
         ImageType\r
         ));\r
       goto Finish;\r
@@ -358,12 +358,12 @@ TrEEMeasurePeImage (
   //\r
   // Log the PE data\r
   //\r
-  Status = TreeProtocol->HashLogExtendEvent (\r
-             TreeProtocol,\r
+  Status = Tcg2Protocol->HashLogExtendEvent (\r
+             Tcg2Protocol,\r
              PE_COFF_IMAGE,\r
              ImageAddress,\r
              ImageSize,\r
-             TreeEvent\r
+             Tcg2Event\r
              );\r
   if (Status == EFI_VOLUME_FULL) {\r
     //\r
@@ -375,7 +375,7 @@ TrEEMeasurePeImage (
   }\r
 \r
 Finish:\r
-  FreePool (TreeEvent);\r
+  FreePool (Tcg2Event);\r
 \r
   return Status;\r
 }\r
@@ -428,9 +428,9 @@ DxeTpm2MeasureBootHandler (
   IN  BOOLEAN                          BootPolicy\r
   )\r
 {\r
-  EFI_TREE_PROTOCOL                   *TreeProtocol;\r
+  EFI_TCG2_PROTOCOL                   *Tcg2Protocol;\r
   EFI_STATUS                          Status;\r
-  TREE_BOOT_SERVICE_CAPABILITY        ProtocolCapability;\r
+  EFI_TCG2_BOOT_SERVICE_CAPABILITY    ProtocolCapability;\r
   EFI_DEVICE_PATH_PROTOCOL            *DevicePathNode;\r
   EFI_DEVICE_PATH_PROTOCOL            *OrigDevicePathNode;\r
   EFI_HANDLE                          Handle;\r
@@ -441,26 +441,26 @@ DxeTpm2MeasureBootHandler (
   EFI_PHYSICAL_ADDRESS                FvAddress;\r
   UINT32                              Index;\r
 \r
-  Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);\r
+  Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
   if (EFI_ERROR (Status)) {\r
     //\r
-    // TrEE protocol is not installed. So, TPM2 is not present.\r
+    // Tcg2 protocol is not installed. So, TPM2 is not present.\r
     // Don't do any measurement, and directly return EFI_SUCCESS.\r
     //\r
-    DEBUG ((EFI_D_INFO, "DxeTpm2MeasureBootHandler - TrEE - %r\n", Status));\r
+    DEBUG ((EFI_D_INFO, "DxeTpm2MeasureBootHandler - Tcg2 - %r\n", Status));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   ProtocolCapability.Size = (UINT8) sizeof (ProtocolCapability);\r
-  Status = TreeProtocol->GetCapability (\r
-                           TreeProtocol, \r
+  Status = Tcg2Protocol->GetCapability (\r
+                           Tcg2Protocol, \r
                            &ProtocolCapability\r
                            );\r
-  if (EFI_ERROR (Status) || (!ProtocolCapability.TrEEPresentFlag)) {\r
+  if (EFI_ERROR (Status) || (!ProtocolCapability.TPMPresentFlag)) {\r
     //\r
     // TPM device doesn't work or activate.\r
     //\r
-    DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler (%r) - TrEEPresentFlag - %x\n", Status, ProtocolCapability.TrEEPresentFlag));\r
+    DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler (%r) - TPMPresentFlag - %x\n", Status, ProtocolCapability.TPMPresentFlag));\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -475,7 +475,7 @@ DxeTpm2MeasureBootHandler (
   //\r
   DevicePathNode = OrigDevicePathNode;\r
   Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);\r
-  if (!EFI_ERROR (Status) && !mTrEEMeasureGptTableFlag) {\r
+  if (!EFI_ERROR (Status) && !mTcg2MeasureGptTableFlag) {\r
     //\r
     // Find the gpt partion on the given devicepath\r
     //\r
@@ -508,13 +508,13 @@ DxeTpm2MeasureBootHandler (
             //\r
             // Measure GPT disk.\r
             //\r
-            Status = TrEEMeasureGptTable (TreeProtocol, Handle);\r
-            DEBUG ((EFI_D_INFO, "DxeTpm2MeasureBootHandler - TrEEMeasureGptTable - %r\n", Status));\r
+            Status = Tcg2MeasureGptTable (Tcg2Protocol, Handle);\r
+            DEBUG ((EFI_D_INFO, "DxeTpm2MeasureBootHandler - Tcg2MeasureGptTable - %r\n", Status));\r
             if (!EFI_ERROR (Status)) {\r
               //\r
               // GPT disk check done.\r
               //\r
-              mTrEEMeasureGptTableFlag = TRUE;\r
+              mTcg2MeasureGptTableFlag = TRUE;\r
             }\r
           }\r
           FreePool (OrigDevicePathNode);\r
@@ -553,7 +553,7 @@ DxeTpm2MeasureBootHandler (
     //\r
     ApplicationRequired = TRUE;\r
 \r
-    if (mTrEECacheMeasuredHandle != Handle && mTrEEMeasuredHobData != NULL) {\r
+    if (mTcg2CacheMeasuredHandle != Handle && mTcg2MeasuredHobData != NULL) {\r
       //\r
       // Search for Root FV of this PE image\r
       //\r
@@ -577,12 +577,12 @@ DxeTpm2MeasureBootHandler (
 \r
       ApplicationRequired = FALSE;\r
 \r
-      for (Index = 0; Index < mTrEEMeasuredHobData->Num; Index++) {\r
-        if(mTrEEMeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) {\r
+      for (Index = 0; Index < mTcg2MeasuredHobData->Num; Index++) {\r
+        if(mTcg2MeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) {\r
           //\r
           // Cache measured FV for next measurement\r
           //\r
-          mTrEECacheMeasuredHandle = Handle;\r
+          mTcg2CacheMeasuredHandle = Handle;\r
           ApplicationRequired  = TRUE;\r
           break;\r
         }\r
@@ -598,8 +598,8 @@ DxeTpm2MeasureBootHandler (
     goto Finish;\r
   }\r
 \r
-  mTrEEImageSize  = FileSize;\r
-  mTrEEFileBuffer = FileBuffer;\r
+  mTcg2ImageSize  = FileSize;\r
+  mTcg2FileBuffer = FileBuffer;\r
 \r
   //\r
   // Measure PE Image\r
@@ -645,15 +645,15 @@ DxeTpm2MeasureBootHandler (
     //\r
     // Measure PE image into TPM log.\r
     //\r
-    Status = TrEEMeasurePeImage (\r
-               TreeProtocol,\r
+    Status = Tcg2MeasurePeImage (\r
+               Tcg2Protocol,\r
                (EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer, \r
                FileSize, \r
                (UINTN) ImageContext.ImageAddress, \r
                ImageContext.ImageType, \r
                DevicePathNode\r
                );\r
-    DEBUG ((EFI_D_INFO, "DxeTpm2MeasureBootHandler - TrEEMeasurePeImage - %r\n", Status));\r
+    DEBUG ((EFI_D_INFO, "DxeTpm2MeasureBootHandler - Tcg2MeasurePeImage - %r\n", Status));\r
   }\r
 \r
   //\r
@@ -692,7 +692,7 @@ DxeTpm2MeasureBootLibConstructor (
   GuidHob = GetFirstGuidHob (&gMeasuredFvHobGuid);\r
 \r
   if (GuidHob != NULL) {\r
-    mTrEEMeasuredHobData = GET_GUID_HOB_DATA (GuidHob);\r
+    mTcg2MeasuredHobData = GET_GUID_HOB_DATA (GuidHob);\r
   }\r
 \r
   return RegisterSecurity2Handler (\r
index 14bf190..1296c97 100644 (file)
@@ -61,7 +61,7 @@
   gZeroGuid                             ## SOMETIMES_CONSUMES ## GUID\r
 \r
 [Protocols]\r
-  gEfiTrEEProtocolGuid                  ## SOMETIMES_CONSUMES\r
+  gEfiTcg2ProtocolGuid                  ## SOMETIMES_CONSUMES\r
   gEfiFirmwareVolumeBlockProtocolGuid   ## SOMETIMES_CONSUMES\r
   gEfiBlockIoProtocolGuid               ## SOMETIMES_CONSUMES\r
   gEfiDiskIoProtocolGuid                ## SOMETIMES_CONSUMES\r
index ffeac59..7a2ec7f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This library is used by other modules to measure data to TPM.\r
 \r
-Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2012 - 2015, 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
@@ -15,7 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <PiDxe.h>\r
 \r
 #include <Protocol/TcgService.h>\r
-#include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
 \r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
@@ -120,37 +120,37 @@ Tpm20MeasureAndLogData (
   )\r
 {\r
   EFI_STATUS                Status;\r
-  EFI_TREE_PROTOCOL         *TreeProtocol;\r
-  TrEE_EVENT                *TreeEvent;\r
+  EFI_TCG2_PROTOCOL         *Tcg2Protocol;\r
+  EFI_TCG2_EVENT            *Tcg2Event;\r
 \r
   //\r
-  // TrEEPresentFlag is checked in HashLogExtendEvent\r
+  // TPMPresentFlag is checked in HashLogExtendEvent\r
   //\r
-  Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);\r
+  Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  TreeEvent = (TrEE_EVENT *) AllocateZeroPool (LogLen + sizeof (TrEE_EVENT));\r
-  if(TreeEvent == NULL) {\r
+  Tcg2Event = (EFI_TCG2_EVENT *) AllocateZeroPool (LogLen + sizeof (EFI_TCG2_EVENT));\r
+  if(Tcg2Event == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  TreeEvent->Size = (UINT32)LogLen + sizeof (TrEE_EVENT) - sizeof(TreeEvent->Event);\r
-  TreeEvent->Header.HeaderSize    = sizeof(TrEE_EVENT_HEADER);\r
-  TreeEvent->Header.HeaderVersion = TREE_EVENT_HEADER_VERSION;\r
-  TreeEvent->Header.PCRIndex      = PcrIndex;\r
-  TreeEvent->Header.EventType     = EventType;\r
-  CopyMem (&TreeEvent->Event[0], EventLog, LogLen);\r
+  Tcg2Event->Size = (UINT32)LogLen + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event);\r
+  Tcg2Event->Header.HeaderSize    = sizeof(EFI_TCG2_EVENT_HEADER);\r
+  Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;\r
+  Tcg2Event->Header.PCRIndex      = PcrIndex;\r
+  Tcg2Event->Header.EventType     = EventType;\r
+  CopyMem (&Tcg2Event->Event[0], EventLog, LogLen);\r
 \r
-  Status = TreeProtocol->HashLogExtendEvent (\r
-                           TreeProtocol,\r
+  Status = Tcg2Protocol->HashLogExtendEvent (\r
+                           Tcg2Protocol,\r
                            0,\r
                            (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,\r
                            HashDataLen,\r
-                           TreeEvent\r
+                           Tcg2Event\r
                            );\r
-  FreePool (TreeEvent);\r
+  FreePool (Tcg2Event);\r
 \r
   return Status;\r
 }\r
index 4c61d9a..410eb78 100644 (file)
@@ -46,4 +46,4 @@
 \r
 [Protocols]\r
   gEfiTcgProtocolGuid           ## SOMETIMES_CONSUMES\r
-  gEfiTrEEProtocolGuid          ## SOMETIMES_CONSUMES\r
+  gEfiTcg2ProtocolGuid          ## SOMETIMES_CONSUMES\r
index 833cce2..7fb5f3d 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Ihis is BaseCrypto router support function.\r
 \r
-Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2013 - 2015, 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
@@ -19,7 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/DebugLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/HashLib.h>\r
-#include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
 \r
 typedef struct {\r
   EFI_GUID  Guid;\r
@@ -27,10 +27,10 @@ typedef struct {
 } TPM2_HASH_MASK;\r
 \r
 TPM2_HASH_MASK mTpm2HashMask[] = {\r
-  {HASH_ALGORITHM_SHA1_GUID,         TREE_BOOT_HASH_ALG_SHA1},\r
-  {HASH_ALGORITHM_SHA256_GUID,       TREE_BOOT_HASH_ALG_SHA256},\r
-  {HASH_ALGORITHM_SHA384_GUID,       TREE_BOOT_HASH_ALG_SHA384},\r
-  {HASH_ALGORITHM_SHA512_GUID,       TREE_BOOT_HASH_ALG_SHA512},\r
+  {HASH_ALGORITHM_SHA1_GUID,         HASH_ALG_SHA1},\r
+  {HASH_ALGORITHM_SHA256_GUID,       HASH_ALG_SHA256},\r
+  {HASH_ALGORITHM_SHA384_GUID,       HASH_ALG_SHA384},\r
+  {HASH_ALGORITHM_SHA512_GUID,       HASH_ALG_SHA512},\r
 };\r
 \r
 /**\r
index d93b33b..8967337 100644 (file)
@@ -3,7 +3,7 @@
   hash handler registerd, such as SHA1, SHA256.\r
   Platform can use PcdTpm2HashMask to mask some hash engines.\r
 \r
-Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2013 - 2015, 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
@@ -44,6 +44,7 @@ HashStart (
 {\r
   HASH_HANDLE  *HashCtx;\r
   UINTN        Index;\r
+  UINT32       HashMask;\r
 \r
   if (mHashInterfaceCount == 0) {\r
     return EFI_UNSUPPORTED;\r
@@ -53,7 +54,10 @@ HashStart (
   ASSERT (HashCtx != NULL);\r
 \r
   for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
-    mHashInterface[Index].HashInit (&HashCtx[Index]);\r
+    HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);\r
+    if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
+      mHashInterface[Index].HashInit (&HashCtx[Index]);\r
+    }\r
   }\r
 \r
   *HashHandle = (HASH_HANDLE)HashCtx;\r
@@ -80,6 +84,7 @@ HashUpdate (
 {\r
   HASH_HANDLE  *HashCtx;\r
   UINTN        Index;\r
+  UINT32       HashMask;\r
 \r
   if (mHashInterfaceCount == 0) {\r
     return EFI_UNSUPPORTED;\r
@@ -88,7 +93,10 @@ HashUpdate (
   HashCtx = (HASH_HANDLE *)HashHandle;\r
 \r
   for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
-    mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+    HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);\r
+    if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
+      mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -119,6 +127,7 @@ HashCompleteAndExtend (
   HASH_HANDLE        *HashCtx;\r
   UINTN              Index;\r
   EFI_STATUS         Status;\r
+  UINT32             HashMask;\r
 \r
   if (mHashInterfaceCount == 0) {\r
     return EFI_UNSUPPORTED;\r
@@ -128,9 +137,12 @@ HashCompleteAndExtend (
   ZeroMem (DigestList, sizeof(*DigestList));\r
 \r
   for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
-    mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
-    mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);\r
-    Tpm2SetHashToDigestList (DigestList, &Digest);\r
+    HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);\r
+    if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
+      mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+      mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);\r
+      Tpm2SetHashToDigestList (DigestList, &Digest);\r
+    }\r
   }\r
 \r
   FreePool (HashCtx);\r
@@ -192,6 +204,7 @@ RegisterHashInterfaceLib (
 {\r
   UINTN              Index;\r
   UINT32             HashMask;\r
+  UINT32             BiosSupportedHashMask;\r
 \r
   //\r
   // Check allow\r
@@ -204,6 +217,8 @@ RegisterHashInterfaceLib (
   if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+  BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
+  PcdSet32 (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);\r
 \r
   //\r
   // Check duplication\r
index 133ef09..7c38ea6 100644 (file)
@@ -5,7 +5,7 @@
 #  hash handler registered, such as SHA1, SHA256. Platform can use PcdTpm2HashMask to \r
 #  mask some hash engines.\r
 #\r
-# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2013 - 2015, 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
@@ -48,5 +48,6 @@
   PcdLib\r
 \r
 [Pcd]\r
-  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask       ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask             ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap  ## CONSUMES\r
 \r
index 5bc8d01..98c0793 100644 (file)
@@ -3,7 +3,7 @@
   hash handler registerd, such as SHA1, SHA256.\r
   Platform can use PcdTpm2HashMask to mask some hash engines.\r
 \r
-Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2013 - 2015, 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
@@ -72,6 +72,7 @@ HashStart (
   HASH_INTERFACE_HOB *HashInterfaceHob;\r
   HASH_HANDLE        *HashCtx;\r
   UINTN              Index;\r
+  UINT32             HashMask;\r
 \r
   HashInterfaceHob = InternalGetHashInterface ();\r
   if (HashInterfaceHob == NULL) {\r
@@ -86,7 +87,10 @@ HashStart (
   ASSERT (HashCtx != NULL);\r
 \r
   for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
-    HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);\r
+    HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
+    if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
+      HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);\r
+    }\r
   }\r
 \r
   *HashHandle = (HASH_HANDLE)HashCtx;\r
@@ -114,6 +118,7 @@ HashUpdate (
   HASH_INTERFACE_HOB *HashInterfaceHob;\r
   HASH_HANDLE        *HashCtx;\r
   UINTN              Index;\r
+  UINT32             HashMask;\r
 \r
   HashInterfaceHob = InternalGetHashInterface ();\r
   if (HashInterfaceHob == NULL) {\r
@@ -127,7 +132,10 @@ HashUpdate (
   HashCtx = (HASH_HANDLE *)HashHandle;\r
 \r
   for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
-    HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+    HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
+    if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
+      HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -159,6 +167,7 @@ HashCompleteAndExtend (
   HASH_HANDLE        *HashCtx;\r
   UINTN              Index;\r
   EFI_STATUS         Status;\r
+  UINT32             HashMask;\r
 \r
   HashInterfaceHob = InternalGetHashInterface ();\r
   if (HashInterfaceHob == NULL) {\r
@@ -173,9 +182,12 @@ HashCompleteAndExtend (
   ZeroMem (DigestList, sizeof(*DigestList));\r
 \r
   for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
-    HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
-    HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);\r
-    Tpm2SetHashToDigestList (DigestList, &Digest);\r
+    HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);\r
+    if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {\r
+      HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+      HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);\r
+      Tpm2SetHashToDigestList (DigestList, &Digest);\r
+    }\r
   }\r
 \r
   FreePool (HashCtx);\r
@@ -245,6 +257,7 @@ RegisterHashInterfaceLib (
   HASH_INTERFACE_HOB *HashInterfaceHob;\r
   HASH_INTERFACE_HOB LocalHashInterfaceHob;\r
   UINT32             HashMask;\r
+  UINT32             BiosSupportedHashMask;\r
 \r
   //\r
   // Check allow\r
@@ -266,6 +279,8 @@ RegisterHashInterfaceLib (
   if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+  BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
+  PcdSet32 (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);\r
 \r
   //\r
   // Check duplication\r
index 13067ee..c1a699f 100644 (file)
@@ -5,7 +5,7 @@
 #  hash handler registered, such as SHA1, SHA256. Platform can use PcdTpm2HashMask to \r
 #  mask some hash engines.\r
 #\r
-# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2013 - 2015, 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
@@ -49,5 +49,6 @@
   HobLib\r
 \r
 [Pcd]\r
-  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask        ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask             ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap  ## CONSUMES\r
 \r
index b2e01af..379f2f7 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Ihis library uses TPM2 device to calculation hash.\r
 \r
-Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2013 - 2015, 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
@@ -20,7 +20,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/HashLib.h>\r
 #include <Library/PcdLib.h>\r
-#include <Protocol/TrEEProtocol.h>\r
 \r
 typedef struct {\r
   TPM_ALG_ID AlgoId;\r
@@ -28,10 +27,10 @@ typedef struct {
 } TPM2_HASH_MASK;\r
 \r
 TPM2_HASH_MASK mTpm2HashMask[] = {\r
-  {TPM_ALG_SHA1,         TREE_BOOT_HASH_ALG_SHA1},\r
-  {TPM_ALG_SHA256,       TREE_BOOT_HASH_ALG_SHA256},\r
-  {TPM_ALG_SHA384,       TREE_BOOT_HASH_ALG_SHA384},\r
-  {TPM_ALG_SHA512,       TREE_BOOT_HASH_ALG_SHA512},\r
+  {TPM_ALG_SHA1,         HASH_ALG_SHA1},\r
+  {TPM_ALG_SHA256,       HASH_ALG_SHA256},\r
+  {TPM_ALG_SHA384,       HASH_ALG_SHA384},\r
+  {TPM_ALG_SHA512,       HASH_ALG_SHA512},\r
 };\r
 \r
 /**\r
diff --git a/SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.c b/SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.c
new file mode 100644 (file)
index 0000000..81fe1b4
--- /dev/null
@@ -0,0 +1,59 @@
+/** @file\r
+  Get TPM 2.0 physical presence information.\r
+  \r
+  This library will get TPM 2.0 physical presence information.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include <PiPei.h>\r
+\r
+#include <Guid/Tcg2PhysicalPresenceData.h>\r
+#include <Ppi/ReadOnlyVariable2.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+\r
+/**\r
+  Return TPM2 ManagementFlags set by PP interface.\r
+\r
+  @retval    ManagementFlags    TPM2 Management Flags.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibGetManagementFlags (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *VariablePpi;\r
+  EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  PpiFlags;\r
+  UINTN                             DataSize;\r
+  \r
+  Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
+  Status = VariablePpi->GetVariable (\r
+                          VariablePpi,\r
+                          TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                          &gEfiTcg2PhysicalPresenceGuid,\r
+                          NULL,\r
+                          &DataSize,\r
+                          &PpiFlags\r
+                          );\r
+  if (EFI_ERROR (Status)) {\r
+    PpiFlags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
+  }\r
+  return PpiFlags.PPFlags;\r
+}\r
diff --git a/SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.inf b/SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.inf
new file mode 100644 (file)
index 0000000..6d0b7a0
--- /dev/null
@@ -0,0 +1,52 @@
+## @file\r
+#  Get TPM 2.0 physical presence information.\r
+#\r
+#  This library will get TPM 2.0 physical presence information.\r
+#\r
+# Copyright (c) 2015, 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
+# http://opensource.org/licenses/bsd-license.php\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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PeiTcg2PhysicalPresenceLib\r
+  MODULE_UNI_FILE                = PeiTcg2PhysicalPresenceLib.uni\r
+  FILE_GUID                      = AB82E7BE-0970-480b-93EB-3D332B89F99E\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tcg2PhysicalPresenceLib|PEIM\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  PeiTcg2PhysicalPresenceLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+  PeiServicesLib\r
+  PeiServicesTablePointerLib\r
+  \r
+[Guids]\r
+  ## SOMETIMES_CONSUMES ## Variable:L"PhysicalPresenceFlags"\r
+  gEfiTcg2PhysicalPresenceGuid\r
+\r
+[Ppis]\r
+  gEfiPeiReadOnlyVariable2PpiGuid       ## CONSUMES\r
+\r
+[Depex]\r
+  gEfiPeiReadOnlyVariable2PpiGuid
\ No newline at end of file
diff --git a/SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.uni b/SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.uni
new file mode 100644 (file)
index 0000000..d4492f6
Binary files /dev/null and b/SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.uni differ
diff --git a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
new file mode 100644 (file)
index 0000000..360df72
--- /dev/null
@@ -0,0 +1,314 @@
+/** @file\r
+  Handle TPM 2.0 physical presence requests from OS.\r
+  \r
+  This library will handle TPM 2.0 physical presence request from OS.\r
+\r
+  Caution: This module requires additional review when modified.\r
+  This driver will have external input - variable.\r
+  This external input must be validated carefully to avoid security issue.\r
+\r
+  Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction()\r
+  will receive untrusted input and do validation.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include <PiSmm.h>\r
+\r
+#include <Guid/Tcg2PhysicalPresenceData.h>\r
+\r
+#include <Protocol/SmmVariable.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/Tcg2PpVendorLib.h>\r
+#include <Library/SmmServicesTableLib.h>\r
+\r
+EFI_SMM_VARIABLE_PROTOCOL  *mTcg2PpSmmVariable;\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Return TPM Operation Response to OS Environment.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  @param[out]     MostRecentRequest Most recent operation request.\r
+  @param[out]     Response          Response to the most recent operation request.\r
+\r
+  @return Return Code for Return TPM Operation Response to OS Environment.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
+  OUT UINT32                *MostRecentRequest,\r
+  OUT UINT32                *Response\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  EFI_TCG2_PHYSICAL_PRESENCE        PpData;\r
+\r
+  DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));\r
+\r
+  //\r
+  // Get the Physical Presence variable\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+  Status = mTcg2PpSmmVariable->SmmGetVariable (\r
+                                 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                                 &gEfiTcg2PhysicalPresenceGuid,\r
+                                 NULL,\r
+                                 &DataSize,\r
+                                 &PpData\r
+                                 );\r
+  if (EFI_ERROR (Status)) {\r
+    *MostRecentRequest = 0;\r
+    *Response          = 0;\r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
+    return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
+  }\r
+\r
+  *MostRecentRequest = PpData.LastPPRequest;\r
+  *Response          = PpData.PPResponse;\r
+\r
+  return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
+}\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Submit TPM Operation Request to Pre-OS Environment and\r
+  Submit TPM Operation Request to Pre-OS Environment 2.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      RequestParameter TPM physical presence operation request parameter.\r
+\r
+  @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
+          Submit TPM Operation Request to Pre-OS Environment 2.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 RequestParameter\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  EFI_TCG2_PHYSICAL_PRESENCE        PpData;\r
+  EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  Flags;\r
+\r
+  DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));\r
+\r
+  //\r
+  // Get the Physical Presence variable\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+  Status = mTcg2PpSmmVariable->SmmGetVariable (\r
+                                 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                                 &gEfiTcg2PhysicalPresenceGuid,\r
+                                 NULL,\r
+                                 &DataSize,\r
+                                 &PpData\r
+                                 );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
+    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+  }\r
+\r
+  if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
+      (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {\r
+    //\r
+    // This command requires UI to prompt user for Auth data.\r
+    //\r
+    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
+  }\r
+\r
+  if (PpData.PPRequest != OperationRequest) {\r
+    PpData.PPRequest = (UINT8)OperationRequest;\r
+    PpData.PPRequestParameter = RequestParameter;\r
+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+    Status = mTcg2PpSmmVariable->SmmSetVariable (\r
+                                   TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                                   &gEfiTcg2PhysicalPresenceGuid,\r
+                                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                                   DataSize,\r
+                                   &PpData\r
+                                   );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) { \r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
+    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+  }\r
+\r
+  if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
+    Status = mTcg2PpSmmVariable->SmmGetVariable (\r
+                                   TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                                   &gEfiTcg2PhysicalPresenceGuid,\r
+                                   NULL,\r
+                                   &DataSize,\r
+                                   &Flags\r
+                                   );\r
+    if (EFI_ERROR (Status)) {\r
+      Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
+    }\r
+    return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);\r
+  }\r
+\r
+  return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
+}\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Get User Confirmation Status for Operation.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+\r
+  @return Return Code for Get User Confirmation Status for Operation.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (\r
+  IN UINT32                 OperationRequest\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  EFI_TCG2_PHYSICAL_PRESENCE        PpData;\r
+  EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  Flags;\r
+  BOOLEAN                           RequestConfirmed;\r
+  \r
+  DEBUG ((EFI_D_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));\r
+\r
+  //\r
+  // Get the Physical Presence variable\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+  Status = mTcg2PpSmmVariable->SmmGetVariable (\r
+                                 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                                 &gEfiTcg2PhysicalPresenceGuid,\r
+                                 NULL,\r
+                                 &DataSize,\r
+                                 &PpData\r
+                                 );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
+    return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
+  }\r
+  //\r
+  // Get the Physical Presence flags\r
+  //\r
+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
+  Status = mTcg2PpSmmVariable->SmmGetVariable (\r
+                                 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                                 &gEfiTcg2PhysicalPresenceGuid,\r
+                                 NULL,\r
+                                 &DataSize,\r
+                                 &Flags\r
+                                 );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));\r
+    return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
+  }\r
+\r
+  RequestConfirmed = FALSE;\r
+\r
+  switch (OperationRequest) {\r
+    case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
+      if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {\r
+        RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
+      RequestConfirmed = TRUE;\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
+      if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {\r
+        RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
+      if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {\r
+        RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+      \r
+    case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
+      RequestConfirmed = TRUE;\r
+      break;\r
+\r
+    default:\r
+      if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
+        RequestConfirmed = TRUE;\r
+      } else {\r
+        if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+          return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
+        }\r
+      }\r
+      break;\r
+  }\r
+\r
+  if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+    return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);\r
+  }\r
+\r
+  if (RequestConfirmed) {\r
+    return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;\r
+  } else {\r
+    return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;\r
+  }    \r
+}\r
+\r
+/**\r
+  The constructor function register UNI strings into imageHandle.\r
+  \r
+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
+\r
+  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param  SystemTable   A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS   The constructor successfully added string package.\r
+  @retval Other value   The constructor can't add string package.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Locate SmmVariableProtocol.\r
+  //\r
+  Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mTcg2PpSmmVariable);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.inf b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.inf
new file mode 100644 (file)
index 0000000..a351dcb
--- /dev/null
@@ -0,0 +1,56 @@
+## @file\r
+#  Handle TPM 2.0 physical presence requests from OS.\r
+#\r
+#  This library will handle TPM 2.0 physical presence request from OS.\r
+#\r
+#  Caution: This module requires additional review when modified.\r
+#  This driver will have external input - variable.\r
+#  This external input must be validated carefully to avoid security issue.\r
+#\r
+# Copyright (c) 2015, 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
+# http://opensource.org/licenses/bsd-license.php\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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SmmTcg2PhysicalPresenceLib\r
+  MODULE_UNI_FILE                = SmmTcg2PhysicalPresenceLib.uni\r
+  FILE_GUID                      = AAE02741-858B-4964-9887-CA870489D944\r
+  MODULE_TYPE                    = DXE_SMM_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tcg2PhysicalPresenceLib|DXE_SMM_DRIVER\r
+  CONSTRUCTOR                    = Tcg2PhysicalPresenceLibConstructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  SmmTcg2PhysicalPresenceLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+  Tcg2PpVendorLib\r
+  SmmServicesTableLib\r
+  \r
+[Guids]\r
+  ## SOMETIMES_PRODUCES ## Variable:L"PhysicalPresence"\r
+  ## SOMETIMES_CONSUMES ## Variable:L"PhysicalPresence"\r
+  ## SOMETIMES_CONSUMES ## Variable:L"PhysicalPresenceFlags"\r
+  gEfiTcg2PhysicalPresenceGuid\r
+  \r
+[Depex]\r
+  gEfiSmmVariableProtocolGuid
\ No newline at end of file
diff --git a/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.uni b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.uni
new file mode 100644 (file)
index 0000000..c0a7809
Binary files /dev/null and b/SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.uni differ
diff --git a/SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.c b/SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.c
new file mode 100644 (file)
index 0000000..93cb312
--- /dev/null
@@ -0,0 +1,133 @@
+/** @file\r
+  NULL Tcg2 PP Vendor library instance that does not support any vendor specific PPI.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/Tcg2PpVendorLib.h>\r
+\r
+/**\r
+  Check and execute the requested physical presence command.\r
+\r
+  This API should be invoked in BIOS boot phase to process pending request.\r
+  \r
+  Caution: This function may receive untrusted input.\r
+  \r
+  If OperationRequest < 128, then ASSERT().\r
+\r
+  @param[in]      PlatformAuth     platform auth value. NULL means no platform auth change.\r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in, out] ManagementFlags  BIOS TPM Management Flags.\r
+  @param[out]     ResetRequired    If reset is required to vendor settings in effect.\r
+                                   True, it indicates the reset is required.\r
+                                   False, it indicates the reset is not required.\r
+\r
+  @return TPM Operation Response to OS Environment.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PpVendorLibExecutePendingRequest (\r
+  IN TPM2B_AUTH             *PlatformAuth,  OPTIONAL\r
+  IN UINT32                 OperationRequest,\r
+  IN OUT UINT32             *ManagementFlags,\r
+  OUT BOOLEAN               *ResetRequired\r
+  )\r
+{\r
+  ASSERT (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION);\r
+  return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
+}\r
+\r
+/**\r
+  Check if there is a valid physical presence command request.\r
+\r
+  This API should be invoked in BIOS boot phase to process pending request.\r
+  \r
+  Caution: This function may receive untrusted input.\r
+\r
+  If OperationRequest < 128, then ASSERT().\r
+\r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      ManagementFlags  BIOS TPM Management Flags.\r
+  @param[out]     RequestConfirmed If the physical presence operation command required user confirm from UI.\r
+                                   True, it indicates the command doesn't require user confirm.\r
+                                   False, it indicates the command need user confirm from UI.\r
+\r
+  @retval  TRUE        Physical Presence operation command is valid.\r
+  @retval  FALSE       Physical Presence operation command is invalid.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Tcg2PpVendorLibHasValidRequest (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 ManagementFlags,\r
+  OUT BOOLEAN               *RequestConfirmed\r
+  )\r
+{\r
+  ASSERT (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION);\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  The callback for TPM vendor specific physical presence which is called for\r
+  Submit TPM Operation Request to Pre-OS Environment and\r
+  Submit TPM Operation Request to Pre-OS Environment 2.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  If OperationRequest < 128, then ASSERT().\r
+\r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      ManagementFlags  BIOS TPM Management Flags.\r
+  @param[in]      RequestParameter Extra parameter from the passed package.\r
+\r
+  @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
+          Submit TPM Operation Request to Pre-OS Environment 2.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PpVendorLibSubmitRequestToPreOSFunction (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 ManagementFlags,\r
+  IN UINT32                 RequestParameter\r
+  )\r
+{\r
+  ASSERT (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION);\r
+  return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
+}\r
+\r
+/**\r
+  The callback for TPM vendor specific physical presence which is called for\r
+  Get User Confirmation Status for Operation.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  If OperationRequest < 128, then ASSERT().\r
+\r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      ManagementFlags  BIOS TPM Management Flags.\r
+\r
+  @return Return Code for Get User Confirmation Status for Operation.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PpVendorLibGetUserConfirmationStatusFunction (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 ManagementFlags\r
+  )\r
+{\r
+  ASSERT (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION);\r
+  return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
+}\r
diff --git a/SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf b/SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
new file mode 100644 (file)
index 0000000..f953fe9
--- /dev/null
@@ -0,0 +1,37 @@
+## @file\r
+#  NULL Tcg PP Vendor library instance that does not support any vendor specific PPI\r
+#\r
+# Copyright (c) 2015, 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
+# http://opensource.org/licenses/bsd-license.php\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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = Tcg2PpVendorLibNull\r
+  MODULE_UNI_FILE                = Tcg2PpVendorLibNull.uni\r
+  FILE_GUID                      = 51924AE9-BE81-4820-94BA-7C9546E702D0\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tcg2PpVendorLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_DRIVER\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  Tcg2PpVendorLibNull.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  \r
+[LibraryClasses]\r
+  DebugLib
\ No newline at end of file
diff --git a/SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.uni b/SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.uni
new file mode 100644 (file)
index 0000000..905a89f
Binary files /dev/null and b/SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.uni differ
diff --git a/SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.c b/SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.c
new file mode 100644 (file)
index 0000000..e1a92c3
--- /dev/null
@@ -0,0 +1,125 @@
+/** @file\r
+  Ihis library is TPM2 TCG2 protocol lib.\r
+\r
+Copyright (c) 2013, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
+#include <IndustryStandard/Tpm20.h>\r
+\r
+EFI_TCG2_PROTOCOL  *mTcg2Protocol = NULL; \r
+\r
+/**\r
+  This service enables the sending of commands to the TPM2.\r
+\r
+  @param[in]      InputParameterBlockSize  Size of the TPM2 input parameter block.\r
+  @param[in]      InputParameterBlock      Pointer to the TPM2 input parameter block.\r
+  @param[in,out]  OutputParameterBlockSize Size of the TPM2 output parameter block.\r
+  @param[in]      OutputParameterBlock     Pointer to the TPM2 output parameter block.\r
+\r
+  @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.\r
+  @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.\r
+  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small. \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2SubmitCommand (\r
+  IN UINT32            InputParameterBlockSize,\r
+  IN UINT8             *InputParameterBlock,\r
+  IN OUT UINT32        *OutputParameterBlockSize,\r
+  IN UINT8             *OutputParameterBlock\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  TPM2_RESPONSE_HEADER      *Header;\r
+\r
+  if (mTcg2Protocol == NULL) {\r
+    Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &mTcg2Protocol);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Tcg2 protocol is not installed. So, TPM2 is not present.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Tpm2SubmitCommand - Tcg2 - %r\n", Status));\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+  //\r
+  // Assume when Tcg2 Protocol is ready, RequestUseTpm already done.\r
+  //\r
+  Status = mTcg2Protocol->SubmitCommand (\r
+                            mTcg2Protocol,\r
+                            InputParameterBlockSize,\r
+                            InputParameterBlock,\r
+                            *OutputParameterBlockSize,\r
+                            OutputParameterBlock\r
+                            );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Header = (TPM2_RESPONSE_HEADER *)OutputParameterBlock;\r
+  *OutputParameterBlockSize = SwapBytes32 (Header->paramSize);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This service requests use TPM2.\r
+\r
+  @retval EFI_SUCCESS      Get the control of TPM2 chip.\r
+  @retval EFI_NOT_FOUND    TPM2 not found.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2RequestUseTpm (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS   Status;\r
+\r
+  if (mTcg2Protocol == NULL) {\r
+    Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &mTcg2Protocol);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Tcg2 protocol is not installed. So, TPM2 is not present.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Tpm2RequestUseTpm - Tcg2 - %r\n", Status));\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+  //\r
+  // Assume when Tcg2 Protocol is ready, RequestUseTpm already done.\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This service register TPM2 device.\r
+\r
+  @param Tpm2Device  TPM2 device\r
+\r
+  @retval EFI_SUCCESS          This TPM2 device is registered successfully.\r
+  @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.\r
+  @retval EFI_ALREADY_STARTED  System already register this TPM2 device.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2RegisterTpm2DeviceLib (\r
+  IN TPM2_DEVICE_INTERFACE   *Tpm2Device\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
diff --git a/SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf b/SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
new file mode 100644 (file)
index 0000000..6d95ebd
--- /dev/null
@@ -0,0 +1,46 @@
+## @file\r
+#  Provides function interfaces to communicate with TPM 2.0 device\r
+#\r
+#  This library helps to use TPM 2.0 device in library function API\r
+#  based on TPM2 protocol.\r
+#\r
+# Copyright (c) 2013 - 2014, 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
+# http://opensource.org/licenses/bsd-license.php\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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = Tpm2DeviceLibTcg2\r
+  MODULE_UNI_FILE                = Tpm2DeviceLibTcg2.uni\r
+  FILE_GUID                      = A1B0B230-67DC-431E-A94A-A96AF1EBE637\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tpm2DeviceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER \r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF\r
+#\r
+\r
+[Sources]\r
+  Tpm2DeviceLibTcg2.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  UefiBootServicesTableLib\r
+\r
+[Protocols]\r
+  gEfiTcg2ProtocolGuid                           ## CONSUMES\r
diff --git a/SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.uni b/SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.uni
new file mode 100644 (file)
index 0000000..27e390d
Binary files /dev/null and b/SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.uni differ
index b0ef20b..48f714f 100644 (file)
   #  Include/Guid/TcgEventHob.h\r
   gTcgEventEntryHobGuid              = { 0x2b9ffb52, 0x1b13, 0x416f, { 0xa8, 0x7b, 0xbc, 0x93, 0xd, 0xef, 0x92, 0xa8 }}\r
 \r
+  ## Hob GUID used to pass a TCG_PCR_EVENT_2 from a TPM2 PEIM to a TPM2 DXE Driver.\r
+  ## Include/Guid/TcgEventHob.h\r
+  gTcgEvent2EntryHobGuid             = { 0xd26c221e, 0x2430, 0x4c8a, { 0x91, 0x70, 0x3f, 0xcb, 0x45, 0x0, 0x41, 0x3f }}\r
+\r
   ## HOB GUID used to record TPM device error.\r
   #  Include/Guid/TcgEventHob.h\r
   gTpmErrorHobGuid                   = { 0xef598499, 0xb25e, 0x473a, { 0xbf, 0xaf, 0xe7, 0xe5, 0x7d, 0xce, 0x82, 0xc4 }}\r
   #  Include/Guid/PhysicalPresenceData.h\r
   gEfiPhysicalPresenceGuid           = { 0xf6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc }}\r
   \r
+  ## GUID used to "Tcg2PhysicalPresence" variable and "Tcg2PhysicalPresenceFlags" variable for TPM2 request and response.\r
+  #  Include/Guid/Tcg2PhysicalPresenceData.h\r
+  gEfiTcg2PhysicalPresenceGuid = { 0xaeb9c5c1, 0x94f1, 0x4d02, { 0xbf, 0xd9, 0x46, 0x2, 0xdb, 0x2d, 0x3c, 0x54 }}\r
+\r
   ## GUID used for form browser, password credential and provider identifier.\r
   # Include/Guid/PwdCredentialProviderHii.h\r
   gPwdCredentialProviderGuid         = { 0x78b9ec8b, 0xc000, 0x46c5, { 0xac, 0x93, 0x24, 0xa0, 0xc1, 0xbb, 0x0, 0xce }}\r
   #  Include/Guid/TcgConfigHii.h\r
   gTcgConfigFormSetGuid              = { 0xb0f901e4, 0xc424, 0x45de, { 0x90, 0x81, 0x95, 0xe2, 0xb, 0xde, 0x6f, 0xb5 }}\r
   \r
+  ## GUID used for FormSet and config variable.\r
+  #  Include/Guid/Tcg2ConfigHii.h\r
+  gTcg2ConfigFormSetGuid    = {0x6339d487, 0x26ba, 0x424b, { 0x9a, 0x5d, 0x68, 0x7e, 0x25, 0xd7, 0x40, 0xbc }}\r
+  \r
   ## GUID used for FormSet.\r
   #  Include/Guid/SecureBootConfigHii.h\r
   gSecureBootConfigFormSetGuid       = { 0x5daf50a5, 0xea81, 0x4de2, {0x8f, 0x9b, 0xca, 0xbd, 0xa9, 0xcf, 0x5c, 0x14}}\r
   # @Prompt TPM device address.\r
   gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0xFED40000|UINT64|0x00010012\r
 \r
+  ## This PCD indicated final BIOS supported Hash mask.\r
+  #    Bios may choose to register a subset of PcdTpm2HashMask.\r
+  #    So this PCD is final value of how many hash algo is extended to PCR.\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap|0xFFFFFFFF|UINT32|0x00010016\r
+\r
+  ## This PCR means the OEM configurated number of PCR banks.\r
+  #  0 means dynamic get from supported HASH algorithm\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2NumberOfPCRBanks|0x0|UINT32|0x00010015\r
+  \r
   ## Provides one or more SHA 256 Hashes of the RSA 2048 public keys used to verify Recovery and Capsule Update images\r
   #\r
   # @Prompt One or more SHA 256 Hashes of RSA 2048 bit public keys used to verify Recovery and Capsule Update images\r
index 2d464a0..09e8daf 100644 (file)
   TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf\r
   Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf\r
   Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf\r
+  Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf\r
   TrEEPhysicalPresenceLib|SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.inf\r
   TcgPpVendorLib|SecurityPkg/Library/TcgPpVendorLibNull/TcgPpVendorLibNull.inf\r
+  Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf\r
   TrEEPpVendorLib|SecurityPkg/Library/TrEEPpVendorLibNull/TrEEPpVendorLibNull.inf\r
 \r
 [LibraryClasses.common.PEIM]\r
@@ -71,6 +73,7 @@
   ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf\r
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf\r
   Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf\r
+  Tcg2PhysicalPresenceLib|SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.inf\r
 \r
 [LibraryClasses.common.DXE_DRIVER]\r
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf\r
   HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf\r
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf\r
-  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf\r
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
 \r
 [LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER,]\r
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
   DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf\r
   HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf\r
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf\r
-  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf\r
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
 \r
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]\r
   ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf\r
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf\r
   HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf\r
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf\r
-  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf\r
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
 \r
 [LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]\r
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf\r
   HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf\r
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf\r
-  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf\r
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
 \r
 [LibraryClasses.IPF.DXE_SAL_DRIVER]\r
   ExtendedSalLib|MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf\r
   BaseCryptLib|CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/BaseCryptLibRuntimeCryptProtocol.inf\r
   HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf\r
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf\r
-  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf\r
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
 \r
 [LibraryClasses.common.DXE_SMM_DRIVER]\r
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
   SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf\r
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf\r
   Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf\r
-  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf\r
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
+  Tcg2PhysicalPresenceLib|SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.inf\r
     \r
 [PcdsDynamicDefault.common.DEFAULT]\r
   gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0xb6, 0xe5, 0x01, 0x8b, 0x19, 0x4f, 0xe8, 0x46, 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc}\r
   gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy|1\r
   gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1\r
   gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|3\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap|3\r
 \r
 [Components]\r
   SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf\r
   # TPM2\r
   #\r
   SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf\r
+  SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf\r
+  SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.inf\r
+  #\r
+  # TrEE - to be deprecated\r
+  #\r
   SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.inf\r
 \r
   SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf\r
   SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf\r
 \r
   SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf\r
+  SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
+  #\r
+  # TrEE - to be deprecated\r
+  #\r
   SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf\r
   SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf\r
   SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf\r
   SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf\r
   SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf\r
 \r
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf {\r
+    <LibraryClasses>\r
+      Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf\r
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf\r
+  }\r
+  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {\r
+    <LibraryClasses>\r
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.inf\r
+      NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf\r
+  }\r
+\r
+  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {\r
+    <LibraryClasses>\r
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf\r
+      NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf\r
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  }\r
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf {\r
+    <LibraryClasses>\r
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
+  }\r
+\r
+  #\r
+  # TrEE - to be deprecated\r
+  #\r
   SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf {\r
     <LibraryClasses>\r
       Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf\r
 \r
   SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf\r
   SecurityPkg/Tcg/TcgSmm/TcgSmm.inf\r
+  SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf\r
+  SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.inf\r
+  #\r
+  # TrEE - to be deprecated\r
+  #\r
   SecurityPkg/Tcg/TrEESmm/TrEESmm.inf\r
   #\r
   # Random Number Generator\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr b/SecurityPkg/Tcg/Tcg2Config/Tcg2Config.vfr
new file mode 100644 (file)
index 0000000..fe0ef14
--- /dev/null
@@ -0,0 +1,167 @@
+/** @file\r
+  VFR file used by the TCG2 configuration component.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include "Tcg2ConfigNvData.h"\r
+\r
+formset\r
+  guid      = TCG2_CONFIG_FORM_SET_GUID,\r
+  title     = STRING_TOKEN(STR_TCG2_TITLE),\r
+  help      = STRING_TOKEN(STR_TCG2_HELP),\r
+  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,\r
+\r
+  efivarstore TCG2_CONFIGURATION,\r
+    varid = TCG2_CONFIGURATION_VARSTORE_ID,\r
+    attribute = 0x03,  // EFI variable attribures  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE\r
+    name  = TCG2_CONFIGURATION,\r
+    guid  = TCG2_CONFIG_FORM_SET_GUID;\r
+\r
+  form formid = TCG2_CONFIGURATION_FORM_ID,\r
+    title = STRING_TOKEN(STR_TCG2_TITLE);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    text\r
+      help   = STRING_TOKEN(STR_TCG2_DEVICE_STATE_HELP),\r
+      text   = STRING_TOKEN(STR_TCG2_DEVICE_STATE_PROMPT),\r
+        text   = STRING_TOKEN(STR_TCG2_DEVICE_STATE_CONTENT);\r
+\r
+    oneof varid  = TCG2_CONFIGURATION.TpmDevice,\r
+          questionid = KEY_TPM_DEVICE,\r
+          prompt = STRING_TOKEN(STR_TCG2_DEVICE_PROMPT),\r
+          help   = STRING_TOKEN(STR_TCG2_DEVICE_HELP),\r
+          flags  = INTERACTIVE,\r
+            option text = STRING_TOKEN(STR_TCG2_TPM_1_2),          value = TPM_DEVICE_1_2,          flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_TPM_2_0_DTPM),     value = TPM_DEVICE_2_0_DTPM,     flags = RESET_REQUIRED;\r
+    endoneof;\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    suppressif ideqvallist TCG2_CONFIGURATION.TpmDevice == TPM_DEVICE_NULL TPM_DEVICE_1_2;\r
+    text\r
+      help   = STRING_TOKEN(STR_TPM2_ACTIVE_HASH_ALGO_HELP),\r
+      text   = STRING_TOKEN(STR_TPM2_ACTIVE_HASH_ALGO),\r
+        text   = STRING_TOKEN(STR_TPM2_ACTIVE_HASH_ALGO_CONTENT);\r
+    text\r
+      help   = STRING_TOKEN(STR_TPM2_SUPPORTED_HASH_ALGO_HELP),\r
+      text   = STRING_TOKEN(STR_TPM2_SUPPORTED_HASH_ALGO),\r
+        text   = STRING_TOKEN(STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT);\r
+    text\r
+      help   = STRING_TOKEN(STR_BIOS_HASH_ALGO_HELP),\r
+      text   = STRING_TOKEN(STR_BIOS_HASH_ALGO),\r
+        text   = STRING_TOKEN(STR_BIOS_HASH_ALGO_CONTENT);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+    subtitle text = STRING_TOKEN(STR_TCG2_PP_OPERATION);\r
+\r
+    oneof name = Tpm2Operation,\r
+          questionid = KEY_TPM2_OPERATION,\r
+          prompt = STRING_TOKEN(STR_TCG2_OPERATION),\r
+          help   = STRING_TOKEN(STR_TCG2_OPERATION_HELP),\r
+          flags  = INTERACTIVE | NUMERIC_SIZE_1,\r
+            option text = STRING_TOKEN(STR_TCG2_NO_ACTION), value = TCG2_PHYSICAL_PRESENCE_NO_ACTION, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_ENABLE), value = TCG2_PHYSICAL_PRESENCE_ENABLE, flags = RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_DISABLE), value = TCG2_PHYSICAL_PRESENCE_DISABLE, flags = RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_CLEAR), value = TCG2_PHYSICAL_PRESENCE_CLEAR, flags = RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_SET_PCD_BANKS), value = TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, flags = RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_CHANGE_EPS), value = TCG2_PHYSICAL_PRESENCE_CHANGE_EPS, flags = RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_LOG_ALL_DIGESTS), value = TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS, flags = RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_DISABLE_ENDORSEMENT_ENABLE_STORAGE_HIERARCHY), value = TCG2_PHYSICAL_PRESENCE_DISABLE_ENDORSEMENT_ENABLE_STORAGE_HIERARCHY, flags = RESET_REQUIRED;\r
+\r
+            option text = STRING_TOKEN(STR_TCG2_ENABLE_BLOCK_SID), value = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID, flags = RESET_REQUIRED;\r
+            option text = STRING_TOKEN(STR_TCG2_DISABLE_BLOCK_SID), value = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID, flags = RESET_REQUIRED;\r
+    endoneof;\r
+    \r
+    suppressif NOT questionref(Tpm2Operation) == TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS;\r
+    numeric name = Tpm2OperationParameter,\r
+            questionid = KEY_TPM2_OPERATION_PARAMETER,\r
+            prompt  = STRING_TOKEN(STR_TCG2_OPERATION_PARAMETER),\r
+            help    = STRING_TOKEN(STR_TCG2_OPERATION_PARAMETER_HELP),\r
+            flags   = DISPLAY_UINT_HEX | INTERACTIVE | NUMERIC_SIZE_4,\r
+            minimum = 0,\r
+            maximum = 0xFFFFFFFF,\r
+            step    = 0,\r
+            default = 0,\r
+    endnumeric;\r
+    endif;\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+    subtitle text = STRING_TOKEN(STR_TCG2_CONFIGURATION);\r
+\r
+    text\r
+      help   = STRING_TOKEN(STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_HELP),\r
+      text   = STRING_TOKEN(STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT),\r
+        text   = STRING_TOKEN(STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_CONTENT);\r
+\r
+    text\r
+      help   = STRING_TOKEN(STR_TCG2_HASH_ALGO_BITMAP_HELP),\r
+      text   = STRING_TOKEN(STR_TCG2_HASH_ALGO_BITMAP),\r
+        text   = STRING_TOKEN(STR_TCG2_HASH_ALGO_BITMAP_CONTENT);\r
+\r
+    text\r
+      help   = STRING_TOKEN(STR_TCG2_NUMBER_OF_PCR_BANKS_HELP),\r
+      text   = STRING_TOKEN(STR_TCG2_NUMBER_OF_PCR_BANKS),\r
+        text   = STRING_TOKEN(STR_TCG2_NUMBER_OF_PCR_BANKS_CONTENT);\r
+\r
+    text\r
+      help   = STRING_TOKEN(STR_TCG2_ACTIVE_PCR_BANKS_HELP),\r
+      text   = STRING_TOKEN(STR_TCG2_ACTIVE_PCR_BANKS),\r
+        text   = STRING_TOKEN(STR_TCG2_ACTIVE_PCR_BANKS_CONTENT);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    checkbox name = TCG2ActivatePCRBank0,\r
+            questionid = KEY_TPM2_PCR_BANKS_REQUEST_0,\r
+            prompt     = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA1),\r
+            help       = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA1_HELP),\r
+            flags      = INTERACTIVE,\r
+            default    = 1,\r
+    endcheckbox;\r
+\r
+    checkbox name = TCG2ActivatePCRBank1,\r
+            questionid = KEY_TPM2_PCR_BANKS_REQUEST_1,\r
+            prompt     = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA256),\r
+            help       = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA256_HELP),\r
+            flags      = INTERACTIVE,\r
+            default    = 0,\r
+    endcheckbox;\r
+\r
+    checkbox name = TCG2ActivatePCRBank2,\r
+            questionid = KEY_TPM2_PCR_BANKS_REQUEST_2,\r
+            prompt     = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA384),\r
+            help       = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA384_HELP),\r
+            flags      = INTERACTIVE,\r
+            default    = 0,\r
+    endcheckbox;\r
+\r
+    checkbox name = TCG2ActivatePCRBank3,\r
+            questionid = KEY_TPM2_PCR_BANKS_REQUEST_3,\r
+            prompt     = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA512),\r
+            help       = STRING_TOKEN(STR_TCG2_PCR_BANK_SHA512_HELP),\r
+            flags      = INTERACTIVE,\r
+            default    = 0,\r
+    endcheckbox;\r
+\r
+    checkbox name = TCG2ActivatePCRBank4,\r
+            questionid = KEY_TPM2_PCR_BANKS_REQUEST_4,\r
+            prompt     = STRING_TOKEN(STR_TCG2_PCR_BANK_SM3_256),\r
+            help       = STRING_TOKEN(STR_TCG2_PCR_BANK_SM3_256_HELP),\r
+            flags      = INTERACTIVE,\r
+            default    = 0,\r
+    endcheckbox;\r
+\r
+    endif;\r
+\r
+  endform;\r
+\r
+endformset;\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c
new file mode 100644 (file)
index 0000000..8813683
--- /dev/null
@@ -0,0 +1,280 @@
+/** @file\r
+  The module entry point for Tcg2 configuration module.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include "Tcg2ConfigImpl.h"\r
+\r
+extern TPM_INSTANCE_ID  mTpmInstanceId[TPM_DEVICE_MAX + 1];\r
+\r
+/**\r
+  Update default PCR banks data.\r
+\r
+  @param[in]  HiiPackage        HII Package.\r
+  @param[in]  HiiPackageSize    HII Package size.\r
+  @param[in]  PCRBanks          PCR Banks data.\r
+\r
+**/\r
+VOID\r
+UpdateDefaultPCRBanks (\r
+  IN VOID                           *HiiPackage,\r
+  IN UINTN                          HiiPackageSize,\r
+  IN UINT32                         PCRBanks\r
+  )\r
+{\r
+  EFI_HII_PACKAGE_HEADER        *HiiPackageHeader;\r
+  EFI_IFR_OP_HEADER             *IfrOpCodeHeader;\r
+  EFI_IFR_CHECKBOX              *IfrCheckBox;\r
+  EFI_IFR_DEFAULT               *IfrDefault;\r
+\r
+  HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;\r
+\r
+  switch (HiiPackageHeader->Type) {\r
+  case EFI_HII_PACKAGE_FORMS:\r
+    IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);\r
+    while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) {\r
+      switch (IfrOpCodeHeader->OpCode) {\r
+      case EFI_IFR_CHECKBOX_OP:\r
+        IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader;\r
+        if ((IfrCheckBox->Question.QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (IfrCheckBox->Question.QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) {\r
+          IfrDefault = (EFI_IFR_DEFAULT *)(IfrCheckBox + 1);\r
+          ASSERT (IfrDefault->Header.OpCode == EFI_IFR_DEFAULT_OP);\r
+          ASSERT (IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN);\r
+          IfrDefault->Value.b = (BOOLEAN)((PCRBanks >> (IfrCheckBox->Question.QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0)) & 0x1);\r
+        }\r
+        break;\r
+      }\r
+      IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);\r
+    }\r
+    break;\r
+  }\r
+  return ;\r
+}\r
+\r
+/**\r
+  The entry point for Tcg2 configuration driver.\r
+\r
+  @param[in]  ImageHandle        The image handle of the driver.\r
+  @param[in]  SystemTable        The system table.\r
+\r
+  @retval EFI_ALREADY_STARTED    The driver already exists in system.\r
+  @retval EFI_OUT_OF_RESOURCES   Fail to execute entry point due to lack of resources.\r
+  @retval EFI_SUCCES             All the related protocols are installed on the driver.\r
+  @retval Others                 Fail to install protocols as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2ConfigDriverEntryPoint (\r
+  IN EFI_HANDLE          ImageHandle,\r
+  IN EFI_SYSTEM_TABLE    *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  TCG2_CONFIG_PRIVATE_DATA      *PrivateData;\r
+  TCG2_CONFIGURATION            Tcg2Configuration;\r
+  TCG2_DEVICE_DETECTION         Tcg2DeviceDetection;\r
+  UINTN                         Index;\r
+  UINTN                         DataSize;\r
+  EDKII_VARIABLE_LOCK_PROTOCOL  *VariableLockProtocol;\r
+  UINT32                        CurrentActivePCRBanks;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  ImageHandle,\r
+                  &gEfiCallerIdGuid,\r
+                  NULL,\r
+                  ImageHandle,\r
+                  ImageHandle,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+  \r
+  //\r
+  // Create a private data structure.\r
+  //\r
+  PrivateData = AllocateCopyPool (sizeof (TCG2_CONFIG_PRIVATE_DATA), &mTcg2ConfigPrivateDateTemplate);\r
+  ASSERT (PrivateData != NULL);\r
+  mTcg2ConfigPrivateDate = PrivateData;\r
+  //\r
+  // Install private GUID.\r
+  //    \r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &ImageHandle,\r
+                  &gEfiCallerIdGuid,\r
+                  PrivateData,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &PrivateData->Tcg2Protocol);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  PrivateData->ProtocolCapability.Size = sizeof(PrivateData->ProtocolCapability);\r
+  Status = PrivateData->Tcg2Protocol->GetCapability (\r
+                                        PrivateData->Tcg2Protocol,\r
+                                        &PrivateData->ProtocolCapability\r
+                                        );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  DataSize = sizeof(Tcg2Configuration);\r
+  Status = gRT->GetVariable (\r
+                  TCG2_STORAGE_NAME,\r
+                  &gTcg2ConfigFormSetGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &Tcg2Configuration\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Variable not ready, set default value\r
+    //\r
+    Tcg2Configuration.TpmDevice           = TPM_DEVICE_DEFAULT;\r
+  }\r
+\r
+  //\r
+  // Validation\r
+  //\r
+  if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) {\r
+    Tcg2Configuration.TpmDevice   = TPM_DEVICE_DEFAULT;\r
+  }\r
+\r
+  //\r
+  // Set value for Tcg2CurrentActivePCRBanks\r
+  // Search Tcg2ConfigBin[] and update default value there\r
+  //\r
+  Status = PrivateData->Tcg2Protocol->GetActivePcrBanks (PrivateData->Tcg2Protocol, &CurrentActivePCRBanks);\r
+  ASSERT_EFI_ERROR (Status);\r
+  PrivateData->PCRBanksDesired = CurrentActivePCRBanks;\r
+  UpdateDefaultPCRBanks (Tcg2ConfigBin + sizeof(UINT32), ReadUnaligned32((UINT32 *)Tcg2ConfigBin) - sizeof(UINT32), CurrentActivePCRBanks);\r
+\r
+  //\r
+  // Save to variable so platform driver can get it.\r
+  //\r
+  Status = gRT->SetVariable (\r
+                  TCG2_STORAGE_NAME,\r
+                  &gTcg2ConfigFormSetGuid,\r
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+                  sizeof(Tcg2Configuration),\r
+                  &Tcg2Configuration\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_NAME\n"));\r
+  }\r
+\r
+  //\r
+  // Sync data from PCD to variable, so that we do not need detect again in S3 phase.\r
+  //\r
+  Tcg2DeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL;\r
+  for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {\r
+    if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {\r
+      Tcg2DeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice;\r
+      break;\r
+    }\r
+  }\r
+\r
+  PrivateData->TpmDeviceDetected = Tcg2DeviceDetection.TpmDeviceDetected;\r
+\r
+  //\r
+  // Save to variable so platform driver can get it.\r
+  //\r
+  Status = gRT->SetVariable (\r
+                  TCG2_DEVICE_DETECTION_NAME,\r
+                  &gTcg2ConfigFormSetGuid,\r
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+                  sizeof(Tcg2DeviceDetection),\r
+                  &Tcg2DeviceDetection\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_DEVICE_DETECTION_NAME\n"));\r
+    Status = gRT->SetVariable (\r
+                    TCG2_DEVICE_DETECTION_NAME,\r
+                    &gTcg2ConfigFormSetGuid,\r
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+                    0,\r
+                    NULL\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  //\r
+  // We should lock Tcg2DeviceDetection, because it contains information needed at S3.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = VariableLockProtocol->RequestToLock (\r
+                                     VariableLockProtocol,\r
+                                     TCG2_DEVICE_DETECTION_NAME,\r
+                                     &gTcg2ConfigFormSetGuid\r
+                                     );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+  \r
+  //\r
+  // Install Tcg2 configuration form\r
+  //\r
+  Status = InstallTcg2ConfigForm (PrivateData);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ErrorExit;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+  if (PrivateData != NULL) {\r
+    UninstallTcg2ConfigForm (PrivateData);\r
+  }  \r
+  \r
+  return Status;\r
+}\r
+\r
+/**\r
+  Unload the Tcg2 configuration form.\r
+\r
+  @param[in]  ImageHandle         The driver's image handle.\r
+\r
+  @retval     EFI_SUCCESS         The Tcg2 configuration form is unloaded.\r
+  @retval     Others              Failed to unload the form.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2ConfigDriverUnload (\r
+  IN EFI_HANDLE  ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  TCG2_CONFIG_PRIVATE_DATA    *PrivateData;\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  ImageHandle,\r
+                  &gEfiCallerIdGuid,\r
+                  (VOID **) &PrivateData\r
+                  );  \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;  \r
+  }\r
+  \r
+  ASSERT (PrivateData->Signature == TCG2_CONFIG_PRIVATE_DATA_SIGNATURE);\r
+\r
+  gBS->UninstallMultipleProtocolInterfaces (\r
+         &ImageHandle,\r
+         &gEfiCallerIdGuid,\r
+         PrivateData,\r
+         NULL\r
+         );\r
+  \r
+  UninstallTcg2ConfigForm (PrivateData);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
new file mode 100644 (file)
index 0000000..ba76541
--- /dev/null
@@ -0,0 +1,87 @@
+## @file\r
+#  TPM device configuration for TPM 2.0\r
+#  \r
+#  By this module, user may select TPM device, clear TPM state, etc.\r
+#  NOTE: This module is only for reference only, each platform should have its own setup page.\r
+#\r
+# Copyright (c) 2015, 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
+# http://opensource.org/licenses/bsd-license.php\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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = Tcg2ConfigDxe\r
+  MODULE_UNI_FILE                = Tcg2ConfigDxe.uni\r
+  FILE_GUID                      = 4D9CBEF0-15A0-4D0C-83DB-5213E710C23F\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = Tcg2ConfigDriverEntryPoint\r
+  UNLOAD_IMAGE                   = Tcg2ConfigDriverUnload\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  Tcg2ConfigDriver.c\r
+  Tcg2ConfigImpl.c\r
+  Tcg2ConfigImpl.h\r
+  Tcg2Config.vfr\r
+  Tcg2ConfigStrings.uni\r
+  Tcg2ConfigNvData.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiDriverEntryPoint\r
+  UefiHiiServicesLib\r
+  DebugLib\r
+  HiiLib\r
+  PcdLib\r
+  PrintLib\r
+  Tpm2DeviceLib\r
+  Tpm2CommandLib\r
+  Tcg2PhysicalPresenceLib\r
+\r
+[Guids]\r
+  ## PRODUCES           ## HII\r
+  ## SOMETIMES_PRODUCES ## Variable:L"TCG2_CONFIGURATION"\r
+  ## SOMETIMES_CONSUMES ## Variable:L"TCG2_CONFIGURATION"\r
+  ## PRODUCES           ## Variable:L"TCG2_DEVICE_DETECTION"\r
+  ## SOMETIMES_CONSUMES ## Variable:L"TCG2_DEVICE_DETECTION"\r
+  gTcg2ConfigFormSetGuid\r
+\r
+[Protocols]\r
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES\r
+  gEfiDevicePathProtocolGuid                    ## PRODUCES\r
+  gEdkiiVariableLockProtocolGuid                ## CONSUMES\r
+  gEfiTcg2ProtocolGuid                          ## CONSUMES\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid            ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap    ## CONSUMES\r
+\r
+[Depex]\r
+  gEfiTcg2ProtocolGuid              AND\r
+  gEfiHiiConfigRoutingProtocolGuid  AND\r
+  gEfiHiiDatabaseProtocolGuid       AND\r
+  gEfiVariableArchProtocolGuid      AND\r
+  gEfiVariableWriteArchProtocolGuid\r
+  \r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+  Tcg2ConfigDxeExtra.uni\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.uni b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.uni
new file mode 100644 (file)
index 0000000..a5b2040
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 (file)
index 0000000..c2571d7
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 (file)
index 0000000..e1835b9
--- /dev/null
@@ -0,0 +1,610 @@
+/** @file\r
+  HII Config Access protocol implementation of TCG2 configuration module.\r
+  NOTE: This module is only for reference only, each platform should have its own setup page.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include "Tcg2ConfigImpl.h"\r
+#include <Library/PcdLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Guid/TpmInstance.h>\r
+\r
+#define EFI_TCG2_EVENT_LOG_FORMAT_ALL   (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)\r
+\r
+TPM_INSTANCE_ID  mTpmInstanceId[TPM_DEVICE_MAX + 1] = TPM_INSTANCE_ID_LIST;\r
+\r
+TCG2_CONFIG_PRIVATE_DATA         *mTcg2ConfigPrivateDate;\r
+TCG2_CONFIG_PRIVATE_DATA         mTcg2ConfigPrivateDateTemplate = {\r
+  TCG2_CONFIG_PRIVATE_DATA_SIGNATURE,\r
+  {\r
+    Tcg2ExtractConfig,\r
+    Tcg2RouteConfig,\r
+    Tcg2Callback\r
+  }\r
+};\r
+\r
+HII_VENDOR_DEVICE_PATH          mTcg2HiiVendorDevicePath = {\r
+  {\r
+    {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_VENDOR_DP,\r
+      {\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    TCG2_CONFIG_FORM_SET_GUID\r
+  },\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    { \r
+      (UINT8) (END_DEVICE_PATH_LENGTH),\r
+      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
+    }\r
+  }\r
+};\r
+\r
+UINT8  mCurrentPpRequest;\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+  @param[in]   This              Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]   Request           A null-terminated Unicode string in\r
+                                 <ConfigRequest> format.\r
+  @param[out]  Progress          On return, points to a character in the Request\r
+                                 string. Points to the string's null terminator if\r
+                                 request was successful. Points to the most recent\r
+                                 '&' before the first failing name/value pair (or\r
+                                 the beginning of the string if the failure is in\r
+                                 the first name/value pair) if the request was not\r
+                                 successful.\r
+  @param[out]  Results           A null-terminated Unicode string in\r
+                                 <ConfigAltResp> format which has all values filled\r
+                                 in for the names in the Request string. String to\r
+                                 be allocated by the called function.\r
+\r
+  @retval EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2ExtractConfig (\r
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL        *This,\r
+  IN CONST EFI_STRING                            Request,\r
+       OUT EFI_STRING                            *Progress,\r
+       OUT EFI_STRING                            *Results\r
+  )\r
+{\r
+  if (Progress == NULL || Results == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Progress = Request;\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Save TPM request to variable space.\r
+\r
+  @param[in] PpRequest             Physical Presence request command.\r
+\r
+  @retval    EFI_SUCCESS           The operation is finished successfully.\r
+  @retval    Others                Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+SaveTcg2PpRequest (\r
+  IN UINT8                         PpRequest\r
+  )\r
+{\r
+  UINT32      ReturnCode;\r
+  EFI_STATUS  Status;\r
+\r
+  ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);\r
+  if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
+    mCurrentPpRequest = PpRequest;\r
+    Status = EFI_SUCCESS;\r
+  } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+  } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
+    Status = EFI_UNSUPPORTED;\r
+  } else {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Save TPM request to variable space.\r
+\r
+  @param[in] PpRequestParameter    Physical Presence request parameter.\r
+\r
+  @retval    EFI_SUCCESS           The operation is finished successfully.\r
+  @retval    Others                Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+SaveTcg2PpRequestParameter (\r
+  IN UINT32                        PpRequestParameter\r
+  )\r
+{\r
+  UINT32      ReturnCode;\r
+  EFI_STATUS  Status;\r
+\r
+  ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (mCurrentPpRequest, PpRequestParameter);\r
+  if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
+    Status = EFI_SUCCESS;\r
+  } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+  } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
+    Status = EFI_UNSUPPORTED;\r
+  } else {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Save Tcg2 PCR Banks request request to variable space.\r
+\r
+  @param[in] PCRBankIndex     PCR Bank Index.\r
+  @param[in] Enable           Enable or disable this PCR Bank.\r
+\r
+  @retval    EFI_SUCCESS           The operation is finished successfully.\r
+  @retval    Others                Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+SaveTcg2PCRBanksRequest (\r
+  IN UINTN   PCRBankIndex,\r
+  IN BOOLEAN Enable\r
+  )\r
+{\r
+  UINT32      ReturnCode;\r
+  EFI_STATUS  Status;\r
+\r
+  if (Enable) {\r
+    mTcg2ConfigPrivateDate->PCRBanksDesired |= (0x1 << PCRBankIndex);\r
+  } else {\r
+    mTcg2ConfigPrivateDate->PCRBanksDesired &= ~(0x1 << PCRBankIndex);\r
+  }\r
+  \r
+  ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, mTcg2ConfigPrivateDate->PCRBanksDesired);\r
+  if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
+    Status = EFI_SUCCESS;\r
+  } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+  } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {\r
+    Status = EFI_UNSUPPORTED;\r
+  } else {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>\r
+                                 format.\r
+  @param[out] Progress           A pointer to a string filled in with the offset of\r
+                                 the most recent '&' before the first failing\r
+                                 name/value pair (or the beginning of the string if\r
+                                 the failure is in the first name/value pair) or\r
+                                 the terminating NULL if all was successful.\r
+\r
+  @retval EFI_SUCCESS            The Results is processed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2RouteConfig (\r
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
+  IN CONST EFI_STRING                          Configuration,\r
+       OUT EFI_STRING                          *Progress\r
+  )\r
+{\r
+  if (Configuration == NULL || Progress == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Action             Specifies the type of action taken by the browser.\r
+  @param[in]  QuestionId         A unique value which is sent to the original\r
+                                 exporting driver so that it can identify the type\r
+                                 of data to expect.\r
+  @param[in]  Type               The type of value for the question.\r
+  @param[in]  Value              A pointer to the data being sent to the original\r
+                                 exporting driver.\r
+  @param[out] ActionRequest      On return, points to the action requested by the\r
+                                 callback function.\r
+\r
+  @retval EFI_SUCCESS            The callback successfully handled the action.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the\r
+                                 variable and its data.\r
+  @retval EFI_DEVICE_ERROR       The variable could not be saved.\r
+  @retval EFI_UNSUPPORTED        The specified Action is not supported by the\r
+                                 callback.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2Callback (\r
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
+  IN     EFI_BROWSER_ACTION                    Action,\r
+  IN     EFI_QUESTION_ID                       QuestionId,\r
+  IN     UINT8                                 Type,\r
+  IN     EFI_IFR_TYPE_VALUE                    *Value,\r
+     OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest\r
+  )\r
+{\r
+  if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+    if (QuestionId == KEY_TPM_DEVICE) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    if (QuestionId == KEY_TPM2_OPERATION) {\r
+      return SaveTcg2PpRequest (Value->u8);\r
+    }\r
+    if (QuestionId == KEY_TPM2_OPERATION_PARAMETER) {\r
+      return SaveTcg2PpRequestParameter (Value->u32);\r
+    }\r
+    if ((QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) {\r
+      SaveTcg2PCRBanksRequest (QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0, Value->b);\r
+    }\r
+  }\r
+\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Append Buffer With TpmAlgHash.\r
+\r
+  @param[in] Buffer               Buffer to be appended.\r
+  @param[in] BufferSize           Size of buffer.\r
+  @param[in] TpmAlgHash           TpmAlgHash.\r
+\r
+**/\r
+VOID\r
+AppendBufferWithTpmAlgHash (\r
+  IN UINT16  *Buffer,\r
+  IN UINTN   BufferSize,\r
+  IN UINT32  TpmAlgHash\r
+  )\r
+{\r
+  switch (TpmAlgHash) {\r
+  case TPM_ALG_SHA1:\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    break;\r
+  case TPM_ALG_SHA256:\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    break;\r
+  case TPM_ALG_SHA384:\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    break;\r
+  case TPM_ALG_SHA512:\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    break;\r
+  case TPM_ALG_SM3_256:\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    break;\r
+  }\r
+}\r
+\r
+/**\r
+  Fill Buffer With BootHashAlg.\r
+\r
+  @param[in] Buffer               Buffer to be filled.\r
+  @param[in] BufferSize           Size of buffer.\r
+  @param[in] BootHashAlg          BootHashAlg.\r
+\r
+**/\r
+VOID\r
+FillBufferWithBootHashAlg (\r
+  IN UINT16  *Buffer,\r
+  IN UINTN   BufferSize,\r
+  IN UINT32  BootHashAlg\r
+  )\r
+{\r
+  Buffer[0] = 0;\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+}\r
+\r
+/**\r
+  Fill Buffer With TCG2EventLogFormat.\r
+\r
+  @param[in] Buffer               Buffer to be filled.\r
+  @param[in] BufferSize           Size of buffer.\r
+  @param[in] TCG2EventLogFormat   TCG2EventLogFormat.\r
+\r
+**/\r
+VOID\r
+FillBufferWithTCG2EventLogFormat (\r
+  IN UINT16  *Buffer,\r
+  IN UINTN   BufferSize,\r
+  IN UINT32  TCG2EventLogFormat\r
+  )\r
+{\r
+  Buffer[0] = 0;\r
+  if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"TCG_1_2", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"TCG_2", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+  if ((TCG2EventLogFormat & (~EFI_TCG2_EVENT_LOG_FORMAT_ALL)) != 0) {\r
+    if (Buffer[0] != 0) {\r
+      StrnCat (Buffer, L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+    }\r
+    StrnCat (Buffer, L"UNKNOWN", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
+  }\r
+}\r
+\r
+/**\r
+  Check if buffer is all zero.\r
+\r
+  @param[in] Buffer      Buffer to be checked.\r
+  @param[in] BufferSize  Size of buffer to be checked.\r
+\r
+  @retval TRUE  Buffer is all zero.\r
+  @retval FALSE Buffer is not all zero.\r
+**/\r
+BOOLEAN\r
+IsZeroBuffer (\r
+  IN VOID  *Buffer,\r
+  IN UINTN BufferSize\r
+  )\r
+{\r
+  UINT8 *BufferData;\r
+  UINTN Index;\r
+\r
+  BufferData = Buffer;\r
+  for (Index = 0; Index < BufferSize; Index++) {\r
+    if (BufferData[Index] != 0) {\r
+      return FALSE;\r
+    }\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  This function publish the TCG2 configuration Form for TPM device.\r
+\r
+  @param[in, out]  PrivateData   Points to TCG2 configuration private data.\r
+\r
+  @retval EFI_SUCCESS            HII Form is installed for this network device.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough resource for HII Form installation.\r
+  @retval Others                 Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+InstallTcg2ConfigForm (\r
+  IN OUT TCG2_CONFIG_PRIVATE_DATA  *PrivateData\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_HII_HANDLE                  HiiHandle;\r
+  EFI_HANDLE                      DriverHandle;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  UINTN                           Index;\r
+  TPML_PCR_SELECTION              Pcrs;\r
+  CHAR16                          TempBuffer[1024];\r
+\r
+  DriverHandle = NULL;\r
+  ConfigAccess = &PrivateData->ConfigAccess;\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &DriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &mTcg2HiiVendorDevicePath,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  ConfigAccess,\r
+                  NULL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  PrivateData->DriverHandle = DriverHandle;\r
+\r
+  //\r
+  // Publish the HII package list\r
+  //\r
+  HiiHandle = HiiAddPackages (\r
+                &gTcg2ConfigFormSetGuid,\r
+                DriverHandle,\r
+                Tcg2ConfigDxeStrings,\r
+                Tcg2ConfigBin,\r
+                NULL\r
+                );\r
+  if (HiiHandle == NULL) {\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+           DriverHandle,\r
+           &gEfiDevicePathProtocolGuid,\r
+           &mTcg2HiiVendorDevicePath,\r
+           &gEfiHiiConfigAccessProtocolGuid,\r
+           ConfigAccess,\r
+           NULL\r
+           );  \r
+\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  PrivateData->HiiHandle = HiiHandle;\r
+\r
+  //\r
+  // Update static data\r
+  //\r
+  switch (PrivateData->TpmDeviceDetected) {\r
+  case TPM_DEVICE_NULL:\r
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Not Found", NULL);\r
+    break;\r
+  case TPM_DEVICE_1_2:\r
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 1.2", NULL);\r
+    break;\r
+  case TPM_DEVICE_2_0_DTPM:\r
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 2.0 (DTPM)", NULL);\r
+    break;\r
+  default:\r
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Unknown", NULL);\r
+    break;\r
+  }\r
+\r
+  Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
+  if (EFI_ERROR (Status)) {\r
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), L"[Unknown]", NULL);\r
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), L"[Unknown]", NULL);\r
+  } else {\r
+    TempBuffer[0] = 0;\r
+    for (Index = 0; Index < Pcrs.count; Index++) {\r
+      if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+        AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash);\r
+      }\r
+    }\r
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), TempBuffer, NULL);\r
+\r
+    TempBuffer[0] = 0;\r
+    for (Index = 0; Index < Pcrs.count; Index++) {\r
+      AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash);\r
+    }\r
+    HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), TempBuffer, NULL);\r
+  }\r
+\r
+  FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PcdGet32 (PcdTcg2HashAlgorithmBitmap));\r
+  HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_BIOS_HASH_ALGO_CONTENT), TempBuffer, NULL);\r
+\r
+  //\r
+  // Tcg2 Capability\r
+  //\r
+  FillBufferWithTCG2EventLogFormat (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.SupportedEventLogs);\r
+  HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_CONTENT), TempBuffer, NULL);\r
+\r
+  FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.HashAlgorithmBitmap);\r
+  HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_HASH_ALGO_BITMAP_CONTENT), TempBuffer, NULL);\r
+\r
+  UnicodeSPrint (TempBuffer, sizeof (TempBuffer), L"%d", PrivateData->ProtocolCapability.NumberOfPCRBanks);\r
+  HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_NUMBER_OF_PCR_BANKS_CONTENT), TempBuffer, NULL);\r
+\r
+  FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.ActivePcrBanks);\r
+  HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_ACTIVE_PCR_BANKS_CONTENT), TempBuffer, NULL);\r
+\r
+  return EFI_SUCCESS;  \r
+}\r
+\r
+/**\r
+  This function removes TCG2 configuration Form.\r
+\r
+  @param[in, out]  PrivateData   Points to TCG2 configuration private data.\r
+\r
+**/\r
+VOID\r
+UninstallTcg2ConfigForm (\r
+  IN OUT TCG2_CONFIG_PRIVATE_DATA    *PrivateData\r
+  )\r
+{\r
+  //\r
+  // Uninstall HII package list\r
+  //\r
+  if (PrivateData->HiiHandle != NULL) {\r
+    HiiRemovePackages (PrivateData->HiiHandle);\r
+    PrivateData->HiiHandle = NULL;\r
+  }\r
+\r
+  //\r
+  // Uninstall HII Config Access Protocol\r
+  //\r
+  if (PrivateData->DriverHandle != NULL) {\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+           PrivateData->DriverHandle,\r
+           &gEfiDevicePathProtocolGuid,\r
+           &mTcg2HiiVendorDevicePath,\r
+           &gEfiHiiConfigAccessProtocolGuid,\r
+           &PrivateData->ConfigAccess,\r
+           NULL\r
+           );\r
+    PrivateData->DriverHandle = NULL;\r
+  }\r
+  \r
+  FreePool (PrivateData);\r
+}\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.h b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.h
new file mode 100644 (file)
index 0000000..1b9a845
--- /dev/null
@@ -0,0 +1,197 @@
+/** @file\r
+  The header file of HII Config Access protocol implementation of TCG2\r
+  configuration module.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#ifndef __TCG2_CONFIG_IMPL_H__\r
+#define __TCG2_CONFIG_IMPL_H__\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiConfigRouting.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
+#include <Protocol/VariableLock.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiHiiServicesLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+\r
+#include <Guid/MdeModuleHii.h>\r
+\r
+#include "Tcg2ConfigNvData.h"\r
+\r
+//\r
+// Tool generated IFR binary data and String package data\r
+//\r
+extern UINT8                        Tcg2ConfigBin[];\r
+extern UINT8                        Tcg2ConfigDxeStrings[];\r
+\r
+///\r
+/// HII specific Vendor Device Path definition.\r
+///\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH                VendorDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL          End;\r
+} HII_VENDOR_DEVICE_PATH;\r
+\r
+typedef struct {\r
+  UINTN                             Signature;\r
+\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL    ConfigAccess;\r
+  EFI_HII_HANDLE                    HiiHandle;\r
+  EFI_HANDLE                        DriverHandle;  \r
+\r
+  UINT8                             TpmDeviceDetected;\r
+  EFI_TCG2_PROTOCOL                 *Tcg2Protocol;\r
+  EFI_TCG2_BOOT_SERVICE_CAPABILITY  ProtocolCapability;\r
+  UINT32                            PCRBanksDesired;\r
+} TCG2_CONFIG_PRIVATE_DATA;\r
+\r
+extern TCG2_CONFIG_PRIVATE_DATA      mTcg2ConfigPrivateDateTemplate;\r
+extern TCG2_CONFIG_PRIVATE_DATA      *mTcg2ConfigPrivateDate;\r
+#define TCG2_CONFIG_PRIVATE_DATA_SIGNATURE     SIGNATURE_32 ('T', 'r', 'E', 'D')\r
+#define TCG2_CONFIG_PRIVATE_DATA_FROM_THIS(a)  CR (a, TCG2_CONFIG_PRIVATE_DATA, ConfigAccess, TCG2_CONFIG_PRIVATE_DATA_SIGNATURE)\r
+\r
+\r
+/**\r
+  This function publish the TCG2 configuration Form for TPM device.\r
+\r
+  @param[in, out]  PrivateData   Points to TCG2 configuration private data.\r
+\r
+  @retval EFI_SUCCESS            HII Form is installed for this network device.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough resource for HII Form installation.\r
+  @retval Others                 Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+InstallTcg2ConfigForm (\r
+  IN OUT TCG2_CONFIG_PRIVATE_DATA  *PrivateData\r
+  );\r
+\r
+/**\r
+  This function removes TCG2 configuration Form.\r
+\r
+  @param[in, out]  PrivateData   Points to TCG2 configuration private data.\r
+\r
+**/\r
+VOID\r
+UninstallTcg2ConfigForm (\r
+  IN OUT TCG2_CONFIG_PRIVATE_DATA    *PrivateData\r
+  );\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+  @param[in]   This              Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]   Request           A null-terminated Unicode string in\r
+                                 <ConfigRequest> format.\r
+  @param[out]  Progress          On return, points to a character in the Request\r
+                                 string. Points to the string's null terminator if\r
+                                 request was successful. Points to the most recent\r
+                                 '&' before the first failing name/value pair (or\r
+                                 the beginning of the string if the failure is in\r
+                                 the first name/value pair) if the request was not\r
+                                 successful.\r
+  @param[out]  Results           A null-terminated Unicode string in\r
+                                 <ConfigAltResp> format which has all values filled\r
+                                 in for the names in the Request string. String to\r
+                                 be allocated by the called function.\r
+\r
+  @retval EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2ExtractConfig (\r
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL        *This,\r
+  IN CONST EFI_STRING                            Request,\r
+       OUT EFI_STRING                            *Progress,\r
+       OUT EFI_STRING                            *Results\r
+  );\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>\r
+                                 format.\r
+  @param[out] Progress           A pointer to a string filled in with the offset of\r
+                                 the most recent '&' before the first failing\r
+                                 name/value pair (or the beginning of the string if\r
+                                 the failure is in the first name/value pair) or\r
+                                 the terminating NULL if all was successful.\r
+\r
+  @retval EFI_SUCCESS            The Results is processed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2RouteConfig (\r
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
+  IN CONST EFI_STRING                          Configuration,\r
+       OUT EFI_STRING                          *Progress\r
+  );\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Action             Specifies the type of action taken by the browser.\r
+  @param[in]  QuestionId         A unique value which is sent to the original\r
+                                 exporting driver so that it can identify the type\r
+                                 of data to expect.\r
+  @param[in]  Type               The type of value for the question.\r
+  @param[in]  Value              A pointer to the data being sent to the original\r
+                                 exporting driver.\r
+  @param[out] ActionRequest      On return, points to the action requested by the\r
+                                 callback function.\r
+\r
+  @retval EFI_SUCCESS            The callback successfully handled the action.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the\r
+                                 variable and its data.\r
+  @retval EFI_DEVICE_ERROR       The variable could not be saved.\r
+  @retval EFI_UNSUPPORTED        The specified Action is not supported by the\r
+                                 callback.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2Callback (\r
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
+  IN     EFI_BROWSER_ACTION                    Action,\r
+  IN     EFI_QUESTION_ID                       QuestionId,\r
+  IN     UINT8                                 Type,\r
+  IN     EFI_IFR_TYPE_VALUE                    *Value,\r
+     OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h
new file mode 100644 (file)
index 0000000..65044c2
--- /dev/null
@@ -0,0 +1,94 @@
+/** @file\r
+  Header file for NV data structure definition.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#ifndef __TCG2_CONFIG_NV_DATA_H__\r
+#define __TCG2_CONFIG_NV_DATA_H__\r
+\r
+#include <Guid/HiiPlatformSetupFormset.h>\r
+#include <Guid/Tcg2ConfigHii.h>\r
+#include <IndustryStandard/TcgPhysicalPresence.h>\r
+\r
+//\r
+// BUGBUG: In order to pass VfrCompiler, we have to redefine below MACRO, which already in <Protocol/Tcg2Protocol.h>.\r
+//\r
+#ifndef __TCG2_H__\r
+#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2       0x00000001\r
+#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2         0x00000002\r
+#endif\r
+#define EFI_TCG2_EVENT_LOG_FORMAT_ALL           (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)\r
+\r
+#define TCG2_CONFIGURATION_VARSTORE_ID  0x0001\r
+#define TCG2_CONFIGURATION_FORM_ID      0x0001\r
+\r
+#define KEY_TPM_DEVICE                                 0x2000\r
+#define KEY_TPM2_OPERATION                             0x2001\r
+#define KEY_TPM2_OPERATION_PARAMETER            0x2002\r
+#define KEY_TPM2_PCR_BANKS_REQUEST_0            0x2003\r
+#define KEY_TPM2_PCR_BANKS_REQUEST_1            0x2004\r
+#define KEY_TPM2_PCR_BANKS_REQUEST_2            0x2005\r
+#define KEY_TPM2_PCR_BANKS_REQUEST_3            0x2006\r
+#define KEY_TPM2_PCR_BANKS_REQUEST_4            0x2007\r
+\r
+#define TPM_DEVICE_NULL           0\r
+#define TPM_DEVICE_1_2            1\r
+#define TPM_DEVICE_2_0_DTPM       2\r
+#define TPM_DEVICE_MIN            TPM_DEVICE_1_2\r
+#define TPM_DEVICE_MAX            TPM_DEVICE_2_0_DTPM\r
+#define TPM_DEVICE_DEFAULT        TPM_DEVICE_1_2\r
+\r
+#define TCG2_PROTOCOL_VERSION_DEFAULT        0x0001\r
+#define EFI_TCG2_EVENT_LOG_FORMAT_DEFAULT    EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2\r
+\r
+//\r
+// Nv Data structure referenced by IFR, TPM device user desired\r
+//\r
+typedef struct {\r
+  UINT8   TpmDevice;\r
+} TCG2_CONFIGURATION;\r
+\r
+//\r
+// Variable saved for S3, TPM detected, only valid in S3 path.\r
+// This variable is ReadOnly.\r
+//\r
+typedef struct {\r
+  UINT8   TpmDeviceDetected;\r
+} TCG2_DEVICE_DETECTION;\r
+\r
+#define TCG2_STORAGE_NAME  L"TCG2_CONFIGURATION"\r
+#define TCG2_DEVICE_DETECTION_NAME  L"TCG2_DEVICE_DETECTION"\r
+\r
+#define TPM_INSTANCE_ID_LIST  { \\r
+  {TPM_DEVICE_INTERFACE_NONE,           TPM_DEVICE_NULL},      \\r
+  {TPM_DEVICE_INTERFACE_TPM12,          TPM_DEVICE_1_2},       \\r
+  {TPM_DEVICE_INTERFACE_TPM20_DTPM,     TPM_DEVICE_2_0_DTPM},  \\r
+}\r
+\r
+//\r
+// BUGBUG: In order to pass VfrCompiler, we have to redefine GUID here.\r
+//\r
+#ifndef __BASE_H__\r
+typedef struct {\r
+  UINT32  Data1;\r
+  UINT16  Data2;\r
+  UINT16  Data3;\r
+  UINT8   Data4[8];\r
+} GUID;\r
+#endif\r
+\r
+typedef struct {\r
+  GUID       TpmInstanceGuid;\r
+  UINT8      TpmDevice;\r
+} TPM_INSTANCE_ID;\r
+\r
+#endif\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
new file mode 100644 (file)
index 0000000..cd6a92d
--- /dev/null
@@ -0,0 +1,78 @@
+## @file\r
+#  Set TPM device type\r
+#\r
+#  This module initializes TPM device type based on variable and detection.\r
+#  NOTE: This module is only for reference only, each platform should have its own setup page.\r
+#\r
+# Copyright (c) 2015, 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
+# http://opensource.org/licenses/bsd-license.php\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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = Tcg2ConfigPei\r
+  MODULE_UNI_FILE                = Tcg2ConfigPei.uni\r
+  FILE_GUID                      = EADD5061-93EF-4CCC-8450-F78A7F0820F0\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = Tcg2ConfigPeimEntryPoint\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+# [BootMode]\r
+#   S3_RESUME                 ## SOMETIMES_CONSUMES\r
+#\r
+\r
+[Sources]\r
+  Tcg2ConfigPeim.c\r
+  Tcg2ConfigNvData.h\r
+  TpmDetection.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  PeiServicesLib\r
+  PeimEntryPoint\r
+  DebugLib\r
+  PcdLib\r
+  TimerLib\r
+  IoLib\r
+  Tpm12CommandLib\r
+  Tpm12DeviceLib\r
+\r
+[Guids]\r
+  ## SOMETIMES_CONSUMES ## Variable:L"TCG2_CONFIGURATION"\r
+  ## SOMETIMES_CONSUMES ## Variable:L"TCG2_DEVICE_DETECTION"\r
+  gTcg2ConfigFormSetGuid\r
+  gEfiTpmDeviceSelectedGuid           ## PRODUCES             ## GUID    # Used as a PPI GUID\r
+  gEfiTpmDeviceInstanceNoneGuid       ## SOMETIMES_CONSUMES   ## GUID    # TPM device identifier\r
+\r
+[Ppis]\r
+  gEfiPeiReadOnlyVariable2PpiGuid     ## CONSUMES\r
+  gPeiTpmInitializationDonePpiGuid    ## SOMETIMES_PRODUCES\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid                 ## PRODUCES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy         ## PRODUCES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection                ## CONSUMES \r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress                  ## SOMETIMES_CONSUMES\r
+\r
+[Depex]\r
+  gEfiPeiMasterBootModePpiGuid AND\r
+  gEfiPeiReadOnlyVariable2PpiGuid\r
+  \r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+  Tcg2ConfigPeiExtra.uni\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni
new file mode 100644 (file)
index 0000000..c309556
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 (file)
index 0000000..c2571d7
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 (file)
index 0000000..34767c0
--- /dev/null
@@ -0,0 +1,158 @@
+/** @file\r
+  The module entry point for Tcg2 configuration module.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Guid/TpmInstance.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <Ppi/ReadOnlyVariable2.h>\r
+#include <Ppi/TpmInitialized.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
+\r
+#include "Tcg2ConfigNvData.h"\r
+\r
+TPM_INSTANCE_ID  mTpmInstanceId[] = TPM_INSTANCE_ID_LIST;\r
+\r
+CONST EFI_PEI_PPI_DESCRIPTOR gTpmSelectedPpi = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiTpmDeviceSelectedGuid,\r
+  NULL\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR  mTpmInitializationDonePpiList = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gPeiTpmInitializationDonePpiGuid,\r
+  NULL\r
+};\r
+\r
+/**\r
+  This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.\r
+\r
+  @param  SetupTpmDevice  TpmDevice configuration in setup driver\r
+\r
+  @return TpmDevice configuration\r
+**/\r
+UINT8\r
+DetectTpmDevice (\r
+  IN UINT8 SetupTpmDevice\r
+  );\r
+\r
+/**\r
+  The entry point for Tcg2 configuration driver.\r
+\r
+  @param  FileHandle  Handle of the file being invoked.\r
+  @param  PeiServices Describes the list of possible PEI Services.\r
+\r
+  @retval EFI_SUCCES             Convert variable to PCD successfully.\r
+  @retval Others                 Fail to convert variable to PCD.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2ConfigPeimEntryPoint (\r
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices\r
+  )\r
+{\r
+  UINTN                           Size;\r
+  EFI_STATUS                      Status;\r
+  EFI_STATUS                      Status2;\r
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;\r
+  TCG2_CONFIGURATION              Tcg2Configuration;\r
+  UINTN                           Index;\r
+  UINT8                           TpmDevice;\r
+\r
+  Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Size = sizeof(Tcg2Configuration);\r
+  Status = VariablePpi->GetVariable (\r
+                          VariablePpi,\r
+                          TCG2_STORAGE_NAME,\r
+                          &gTcg2ConfigFormSetGuid,\r
+                          NULL,\r
+                          &Size,\r
+                          &Tcg2Configuration\r
+                          );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Variable not ready, set default value\r
+    //\r
+    Tcg2Configuration.TpmDevice           = TPM_DEVICE_DEFAULT;\r
+  }\r
+\r
+  //\r
+  // Validation\r
+  //\r
+  if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) {\r
+    Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;\r
+  }\r
+\r
+  //\r
+  // Although we have SetupVariable info, we still need detect TPM device manually.\r
+  //\r
+  DEBUG ((EFI_D_INFO, "Tcg2Configuration.TpmDevice from Setup: %x\n", Tcg2Configuration.TpmDevice));\r
+\r
+  if (PcdGetBool (PcdTpmAutoDetection)) {\r
+    TpmDevice = DetectTpmDevice (Tcg2Configuration.TpmDevice);\r
+    DEBUG ((EFI_D_INFO, "TpmDevice final: %x\n", TpmDevice));\r
+    if (TpmDevice != TPM_DEVICE_NULL) {\r
+      Tcg2Configuration.TpmDevice = TpmDevice;\r
+    }\r
+  } else {\r
+    TpmDevice = Tcg2Configuration.TpmDevice;\r
+  }\r
+\r
+  //\r
+  // Convert variable to PCD.\r
+  // This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase.\r
+  // Using DynamicPcd instead.\r
+  //\r
+  // NOTE: Tcg2Configuration variable contains the desired TpmDevice type,\r
+  // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice type\r
+  //\r
+  for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {\r
+    if (TpmDevice == mTpmInstanceId[Index].TpmDevice) {\r
+      Size = sizeof(mTpmInstanceId[Index].TpmInstanceGuid);\r
+      PcdSetPtr (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid);\r
+      DEBUG ((EFI_D_INFO, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Selection done\r
+  //\r
+  Status = PeiServicesInstallPpi (&gTpmSelectedPpi);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Even if no TPM is selected or detected, we still need intall TpmInitializationDonePpi.\r
+  // Because TcgPei or Tcg2Pei will not run, but we still need a way to notify other driver.\r
+  // Other driver can know TPM initialization state by TpmInitializedPpi.\r
+  //\r
+  if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid)) {\r
+    Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);\r
+    ASSERT_EFI_ERROR (Status2);\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigStrings.uni b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigStrings.uni
new file mode 100644 (file)
index 0000000..be548b8
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 (file)
index 0000000..9e93e9c
--- /dev/null
@@ -0,0 +1,129 @@
+/** @file\r
+  TPM1.2/dTPM2.0 auto detection.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+\r
+#include <PiPei.h>\r
+#include <Ppi/ReadOnlyVariable2.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/Tpm12DeviceLib.h>\r
+#include <Library/Tpm12CommandLib.h>\r
+#include <IndustryStandard/Tpm12.h>\r
+\r
+#include "Tcg2ConfigNvData.h"\r
+\r
+/**\r
+  This routine return if dTPM (1.2 or 2.0) present.\r
+\r
+  @retval TRUE  dTPM present\r
+  @retval FALSE dTPM not present\r
+**/\r
+BOOLEAN\r
+IsDtpmPresent (\r
+  VOID\r
+  )\r
+{\r
+  UINT8                             RegRead;\r
+  \r
+  RegRead = MmioRead8 ((UINTN)PcdGet64 (PcdTpmBaseAddress));\r
+  if (RegRead == 0xFF) {\r
+    DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Dtpm not present\n"));\r
+    return FALSE;\r
+  } else {\r
+    DEBUG ((EFI_D_INFO, "DetectTpmDevice: Dtpm present\n"));\r
+    return TRUE;\r
+  }\r
+}\r
+\r
+/**\r
+  This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.\r
+\r
+  @param  SetupTpmDevice  TpmDevice configuration in setup driver\r
+\r
+  @return TpmDevice configuration\r
+**/\r
+UINT8\r
+DetectTpmDevice (\r
+  IN UINT8 SetupTpmDevice\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_BOOT_MODE                     BootMode;\r
+  TCG2_DEVICE_DETECTION             Tcg2DeviceDetection;\r
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *VariablePpi;\r
+  UINTN                             Size;\r
+\r
+  Status = PeiServicesGetBootMode (&BootMode);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot.\r
+  //\r
+  if (BootMode == BOOT_ON_S3_RESUME) {\r
+    DEBUG ((EFI_D_INFO, "DetectTpmDevice: S3 mode\n"));\r
+\r
+    Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Size = sizeof(TCG2_DEVICE_DETECTION);\r
+    ZeroMem (&Tcg2DeviceDetection, sizeof(Tcg2DeviceDetection));\r
+    Status = VariablePpi->GetVariable (\r
+                            VariablePpi,\r
+                            TCG2_DEVICE_DETECTION_NAME,\r
+                            &gTcg2ConfigFormSetGuid,\r
+                            NULL,\r
+                            &Size,\r
+                            &Tcg2DeviceDetection\r
+                            );\r
+    if (!EFI_ERROR (Status) &&\r
+        (Tcg2DeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) &&\r
+        (Tcg2DeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX)) {\r
+      DEBUG ((EFI_D_ERROR, "TpmDevice from DeviceDetection: %x\n", Tcg2DeviceDetection.TpmDeviceDetected));\r
+      return Tcg2DeviceDetection.TpmDeviceDetected;\r
+    }\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "DetectTpmDevice:\n"));\r
+  if (!IsDtpmPresent ()) {\r
+    // dTPM not available\r
+    return TPM_DEVICE_NULL;\r
+  }\r
+\r
+  // dTPM available and not disabled by setup\r
+  // We need check if it is TPM1.2 or TPM2.0\r
+  // So try TPM1.2 command at first\r
+\r
+  Status = Tpm12RequestUseTpm ();\r
+  if (EFI_ERROR (Status)) {\r
+    return TPM_DEVICE_2_0_DTPM;\r
+  }\r
+\r
+  if (BootMode == BOOT_ON_S3_RESUME) {\r
+    Status = Tpm12Startup (TPM_ST_STATE);\r
+  } else {\r
+    Status = Tpm12Startup (TPM_ST_CLEAR);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return TPM_DEVICE_2_0_DTPM;\r
+  }\r
+\r
+  // NO initialization needed again.\r
+  PcdSet8 (PcdTpmInitializationPolicy, 0);\r
+  return TPM_DEVICE_1_2;\r
+}\r
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c b/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c
new file mode 100644 (file)
index 0000000..e2d763a
--- /dev/null
@@ -0,0 +1,357 @@
+/** @file\r
+  This module implements measuring PeCoff image for Tcg2 Protocol.\r
+  \r
+  Caution: This file requires additional review when modified.\r
+  This driver will have external input - PE/COFF image.\r
+  This external input must be validated carefully to avoid security issue like\r
+  buffer overflow, integer overflow.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include <PiDxe.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PeCoffLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/HashLib.h>\r
+\r
+/**\r
+  Measure PE image into TPM log based on the authenticode image hashing in\r
+  PE/COFF Specification 8.0 Appendix A.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  PE/COFF image is external input, so this function will validate its data structure\r
+  within this image buffer before use.\r
+\r
+  @param[in]  PCRIndex       TPM PCR index\r
+  @param[in]  ImageAddress   Start address of image buffer.\r
+  @param[in]  ImageSize      Image size\r
+  @param[out] DigestList     Digeest list of this image.\r
+\r
+  @retval EFI_SUCCESS            Successfully measure image.\r
+  @retval EFI_OUT_OF_RESOURCES   No enough resource to measure image.\r
+  @retval other error value\r
+**/\r
+EFI_STATUS\r
+MeasurePeImageAndExtend (\r
+  IN  UINT32                    PCRIndex,\r
+  IN  EFI_PHYSICAL_ADDRESS      ImageAddress,\r
+  IN  UINTN                     ImageSize,\r
+  OUT TPML_DIGEST_VALUES        *DigestList\r
+  )\r
+{\r
+  EFI_STATUS                           Status;\r
+  EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
+  UINT32                               PeCoffHeaderOffset;\r
+  EFI_IMAGE_SECTION_HEADER             *Section;\r
+  UINT8                                *HashBase;\r
+  UINTN                                HashSize;\r
+  UINTN                                SumOfBytesHashed;\r
+  EFI_IMAGE_SECTION_HEADER             *SectionHeader;\r
+  UINTN                                Index;\r
+  UINTN                                Pos;\r
+  UINT16                               Magic;\r
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;\r
+  UINT32                               NumberOfRvaAndSizes;\r
+  UINT32                               CertSize;\r
+  HASH_HANDLE                          HashHandle;\r
+\r
+  HashHandle = 0xFFFFFFFF; // Know bad value\r
+\r
+  Status        = EFI_UNSUPPORTED;\r
+  SectionHeader = NULL;\r
+\r
+  //\r
+  // Check PE/COFF image\r
+  //\r
+  DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress;\r
+  PeCoffHeaderOffset = 0;\r
+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+    PeCoffHeaderOffset = DosHdr->e_lfanew;\r
+  }\r
+\r
+  Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset);\r
+  if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // PE/COFF Image Measurement\r
+  //\r
+  //    NOTE: The following codes/steps are based upon the authenticode image hashing in\r
+  //      PE/COFF Specification 8.0 Appendix A.\r
+  //\r
+  //\r
+\r
+  // 1.  Load the image header into memory.\r
+\r
+  // 2.  Initialize a SHA hash context.\r
+\r
+  Status = HashStart (&HashHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // Measuring PE/COFF Image Header;\r
+  // But CheckSum field and SECURITY data directory (certificate) are excluded\r
+  //\r
+  if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value \r
+    //       in the PE/COFF Header. If the MachineType is Itanium(IA64) and the \r
+    //       Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
+    //       then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
+    //\r
+    Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+  } else {\r
+    //\r
+    // Get the magic value from the PE/COFF Optional Header\r
+    //\r
+    Magic = Hdr.Pe32->OptionalHeader.Magic;\r
+  }\r
+  \r
+  //\r
+  // 3.  Calculate the distance from the base of the image header to the image checksum address.\r
+  // 4.  Hash the image header from its base to beginning of the image checksum.\r
+  //\r
+  HashBase = (UINT8 *) (UINTN) ImageAddress;\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset\r
+    //\r
+    NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+    HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.CheckSum) - HashBase);\r
+  } else {\r
+    //\r
+    // Use PE32+ offset\r
+    //\r
+    NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+    HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - HashBase);\r
+  }\r
+\r
+  Status = HashUpdate (HashHandle, HashBase, HashSize);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
+  }  \r
+\r
+  //\r
+  // 5.  Skip over the image checksum (it occupies a single ULONG).\r
+  //\r
+  if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
+    //\r
+    // 6.  Since there is no Cert Directory in optional header, hash everything\r
+    //     from the end of the checksum to the end of image header.\r
+    //\r
+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+      //\r
+      // Use PE32 offset.\r
+      //\r
+      HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
+      HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);\r
+    } else {\r
+      //\r
+      // Use PE32+ offset.\r
+      //\r
+      HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
+      HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);\r
+    }\r
+\r
+    if (HashSize != 0) {\r
+      Status  = HashUpdate (HashHandle, HashBase, HashSize);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Finish;\r
+      }\r
+    }    \r
+  } else {\r
+    //\r
+    // 7.  Hash everything from the end of the checksum to the start of the Cert Directory.\r
+    //\r
+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+      //\r
+      // Use PE32 offset\r
+      //\r
+      HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
+      HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+    } else {\r
+      //\r
+      // Use PE32+ offset\r
+      //    \r
+      HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
+      HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+    }\r
+\r
+    if (HashSize != 0) {\r
+      Status  = HashUpdate (HashHandle, HashBase, HashSize);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Finish;\r
+      }\r
+    }\r
+\r
+    //\r
+    // 8.  Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)\r
+    // 9.  Hash everything from the end of the Cert Directory to the end of image header.\r
+    //\r
+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+      //\r
+      // Use PE32 offset\r
+      //\r
+      HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
+      HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);\r
+    } else {\r
+      //\r
+      // Use PE32+ offset\r
+      //\r
+      HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
+      HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);\r
+    }\r
+    \r
+    if (HashSize != 0) {\r
+      Status  = HashUpdate (HashHandle, HashBase, HashSize);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Finish;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // 10. Set the SUM_OF_BYTES_HASHED to the size of the header\r
+  //\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset\r
+    //\r
+    SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
+  } else {\r
+    //\r
+    // Use PE32+ offset\r
+    //\r
+    SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;\r
+  }\r
+\r
+  //\r
+  // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER\r
+  //     structures in the image. The 'NumberOfSections' field of the image\r
+  //     header indicates how big the table should be. Do not include any\r
+  //     IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.\r
+  //\r
+  SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections);\r
+  if (SectionHeader == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // 12.  Using the 'PointerToRawData' in the referenced section headers as\r
+  //      a key, arrange the elements in the table in ascending order. In other\r
+  //      words, sort the section headers according to the disk-file offset of\r
+  //      the section.\r
+  //\r
+  Section = (EFI_IMAGE_SECTION_HEADER *) (\r
+               (UINT8 *) (UINTN) ImageAddress +\r
+               PeCoffHeaderOffset +\r
+               sizeof(UINT32) +\r
+               sizeof(EFI_IMAGE_FILE_HEADER) +\r
+               Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
+               );\r
+  for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
+    Pos = Index;\r
+    while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {\r
+      CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof(EFI_IMAGE_SECTION_HEADER));\r
+      Pos--;\r
+    }\r
+    CopyMem (&SectionHeader[Pos], Section, sizeof(EFI_IMAGE_SECTION_HEADER));\r
+    Section += 1;\r
+  }\r
+\r
+  //\r
+  // 13.  Walk through the sorted table, bring the corresponding section\r
+  //      into memory, and hash the entire section (using the 'SizeOfRawData'\r
+  //      field in the section header to determine the amount of data to hash).\r
+  // 14.  Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .\r
+  // 15.  Repeat steps 13 and 14 for all the sections in the sorted table.\r
+  //\r
+  for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
+    Section  = (EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index];\r
+    if (Section->SizeOfRawData == 0) {\r
+      continue;\r
+    }\r
+    HashBase = (UINT8 *) (UINTN) ImageAddress + Section->PointerToRawData;\r
+    HashSize = (UINTN) Section->SizeOfRawData;\r
+\r
+    Status = HashUpdate (HashHandle, HashBase, HashSize);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Finish;\r
+    }\r
+\r
+    SumOfBytesHashed += HashSize;\r
+  }\r
+\r
+  //\r
+  // 16.  If the file size is greater than SUM_OF_BYTES_HASHED, there is extra\r
+  //      data in the file that needs to be added to the hash. This data begins\r
+  //      at file offset SUM_OF_BYTES_HASHED and its length is:\r
+  //             FileSize  -  (CertDirectory->Size)\r
+  //\r
+  if (ImageSize > SumOfBytesHashed) {\r
+    HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;\r
+\r
+    if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
+      CertSize = 0;\r
+    } else {\r
+      if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+        //\r
+        // Use PE32 offset.\r
+        //\r
+        CertSize = Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;\r
+      } else {\r
+        //\r
+        // Use PE32+ offset.\r
+        //\r
+        CertSize = Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;\r
+      }\r
+    }\r
+\r
+    if (ImageSize > CertSize + SumOfBytesHashed) {\r
+      HashSize = (UINTN) (ImageSize - CertSize - SumOfBytesHashed);\r
+\r
+      Status = HashUpdate (HashHandle, HashBase, HashSize);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Finish;\r
+      }\r
+    } else if (ImageSize < CertSize + SumOfBytesHashed) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Finish;\r
+    }\r
+  }\r
+\r
+  //\r
+  // 17.  Finalize the SHA hash.\r
+  //\r
+  Status = HashCompleteAndExtend (HashHandle, PCRIndex, NULL, 0, DigestList);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
+  }\r
+\r
+Finish:\r
+  if (SectionHeader != NULL) {\r
+    FreePool (SectionHeader);\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
new file mode 100644 (file)
index 0000000..cb2a65b
--- /dev/null
@@ -0,0 +1,2563 @@
+/** @file\r
+  This module implements Tcg2 Protocol.\r
+  \r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\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
+\r
+#include <PiDxe.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/ImageAuthentication.h>\r
+#include <Guid/TpmInstance.h>\r
+\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/MpService.h>\r
+#include <Protocol/VariableWrite.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
+#include <Protocol/TrEEProtocol.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/HashLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+\r
+#define PERF_ID_TCG2_DXE  0x3120\r
+\r
+typedef struct {\r
+  CHAR16                                 *VariableName;\r
+  EFI_GUID                               *VendorGuid;\r
+} VARIABLE_TYPE;\r
+\r
+#define  EFI_TCG_LOG_AREA_SIZE        0x10000\r
+#define  EFI_TCG_FINAL_LOG_AREA_SIZE  0x1000\r
+\r
+#define  TCG2_DEFAULT_MAX_COMMAND_SIZE        0x1000\r
+#define  TCG2_DEFAULT_MAX_RESPONSE_SIZE       0x1000\r
+\r
+typedef struct {\r
+  EFI_GUID               *EventGuid;\r
+  EFI_TCG2_EVENT_LOG_FORMAT  LogFormat;\r
+} TCG2_EVENT_INFO_STRUCT;\r
+\r
+TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = {\r
+  {&gTcgEventEntryHobGuid,             EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2},\r
+  {&gTcgEvent2EntryHobGuid,            EFI_TCG2_EVENT_LOG_FORMAT_TCG_2},\r
+};\r
+\r
+#define TCG_EVENT_LOG_AREA_COUNT_MAX   2\r
+\r
+typedef struct {\r
+  EFI_TCG2_EVENT_LOG_FORMAT         EventLogFormat;\r
+  EFI_PHYSICAL_ADDRESS              Lasa;\r
+  UINT64                            Laml;\r
+  UINTN                             EventLogSize;\r
+  UINT8                             *LastEvent;\r
+  BOOLEAN                           EventLogStarted;\r
+  BOOLEAN                           EventLogTruncated;\r
+} TCG_EVENT_LOG_AREA_STRUCT;\r
+\r
+typedef struct _TCG_DXE_DATA {\r
+  EFI_TCG2_BOOT_SERVICE_CAPABILITY  BsCap;\r
+  TCG_EVENT_LOG_AREA_STRUCT         EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
+  BOOLEAN                           GetEventLogCalled[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
+  TCG_EVENT_LOG_AREA_STRUCT         FinalEventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
+  EFI_TCG2_FINAL_EVENTS_TABLE       *FinalEventsTable[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
+} TCG_DXE_DATA;\r
+\r
+TCG_DXE_DATA                 mTcgDxeData = {\r
+  {\r
+    sizeof (EFI_TCG2_BOOT_SERVICE_CAPABILITY),     // Size\r
+    { 1, 1 },                           // StructureVersion\r
+    { 1, 1 },                           // ProtocolVersion\r
+    EFI_TCG2_BOOT_HASH_ALG_SHA1,        // HashAlgorithmBitmap\r
+    EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2,  // SupportedEventLogs\r
+    TRUE,                               // TPMPresentFlag\r
+    TCG2_DEFAULT_MAX_COMMAND_SIZE,      // MaxCommandSize\r
+    TCG2_DEFAULT_MAX_RESPONSE_SIZE,     // MaxResponseSize\r
+    0,                                  // ManufacturerID\r
+    0,  // NumberOfPCRBanks\r
+    0,  // ActivePcrBanks\r
+  },\r
+};\r
+\r
+UINTN  mBootAttempts  = 0;\r
+CHAR16 mBootVarName[] = L"BootOrder";\r
+\r
+VARIABLE_TYPE  mVariableType[] = {\r
+  {EFI_SECURE_BOOT_MODE_NAME,    &gEfiGlobalVariableGuid},\r
+  {EFI_PLATFORM_KEY_NAME,        &gEfiGlobalVariableGuid},\r
+  {EFI_KEY_EXCHANGE_KEY_NAME,    &gEfiGlobalVariableGuid},\r
+  {EFI_IMAGE_SECURITY_DATABASE,  &gEfiImageSecurityDatabaseGuid},\r
+  {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},\r
+};\r
+\r
+EFI_HANDLE mImageHandle;\r
+\r
+/**\r
+  Measure PE image into TPM log based on the authenticode image hashing in\r
+  PE/COFF Specification 8.0 Appendix A.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  PE/COFF image is external input, so this function will validate its data structure\r
+  within this image buffer before use.\r
+\r
+  @param[in]  PCRIndex       TPM PCR index\r
+  @param[in]  ImageAddress   Start address of image buffer.\r
+  @param[in]  ImageSize      Image size\r
+  @param[out] DigestList     Digeest list of this image.\r
+\r
+  @retval EFI_SUCCESS            Successfully measure image.\r
+  @retval EFI_OUT_OF_RESOURCES   No enough resource to measure image.\r
+  @retval other error value\r
+**/\r
+EFI_STATUS\r
+MeasurePeImageAndExtend (\r
+  IN  UINT32                    PCRIndex,\r
+  IN  EFI_PHYSICAL_ADDRESS      ImageAddress,\r
+  IN  UINTN                     ImageSize,\r
+  OUT TPML_DIGEST_VALUES        *DigestList\r
+  );\r
+\r
+/**\r
+\r
+  This function dump raw data.\r
+\r
+  @param  Data  raw data\r
+  @param  Size  raw data size\r
+\r
+**/\r
+VOID\r
+InternalDumpData (\r
+  IN UINT8  *Data,\r
+  IN UINTN  Size\r
+  )\r
+{\r
+  UINTN  Index;\r
+  for (Index = 0; Index < Size; Index++) {\r
+    DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index]));\r
+  }\r
+}\r
+\r
+/**\r
+\r
+  This function dump raw data with colume format.\r
+\r
+  @param  Data  raw data\r
+  @param  Size  raw data size\r
+\r
+**/\r
+VOID\r
+InternalDumpHex (\r
+  IN UINT8  *Data,\r
+  IN UINTN  Size\r
+  )\r
+{\r
+  UINTN   Index;\r
+  UINTN   Count;\r
+  UINTN   Left;\r
+\r
+#define COLUME_SIZE  (16 * 2)\r
+\r
+  Count = Size / COLUME_SIZE;\r
+  Left  = Size % COLUME_SIZE;\r
+  for (Index = 0; Index < Count; Index++) {\r
+    DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));\r
+    InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);\r
+    DEBUG ((EFI_D_INFO, "\n"));\r
+  }\r
+\r
+  if (Left != 0) {\r
+    DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));\r
+    InternalDumpData (Data + Index * COLUME_SIZE, Left);\r
+    DEBUG ((EFI_D_INFO, "\n"));\r
+  }\r
+}\r
+\r
+/**\r
+  Check if buffer is all zero.\r
+\r
+  @param[in] Buffer      Buffer to be checked.\r
+  @param[in] BufferSize  Size of buffer to be checked.\r
+\r
+  @retval TRUE  Buffer is all zero.\r
+  @retval FALSE Buffer is not all zero.\r
+**/\r
+BOOLEAN\r
+IsZeroBuffer (\r
+  IN VOID  *Buffer,\r
+  IN UINTN BufferSize\r
+  )\r
+{\r
+  UINT8 *BufferData;\r
+  UINTN Index;\r
+\r
+  BufferData = Buffer;\r
+  for (Index = 0; Index < BufferSize; Index++) {\r
+    if (BufferData[Index] != 0) {\r
+      return FALSE;\r
+    }\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+/**\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
+  The EFI_TCG2_PROTOCOL GetCapability function call provides protocol\r
+  capability information and state information.\r
+\r
+  @param[in]      This               Indicates the calling context\r
+  @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY\r
+                                     structure and sets the size field to the size of the structure allocated.\r
+                                     The callee fills in the fields with the EFI protocol capability information\r
+                                     and the current EFI TCG2 state information up to the number of fields which\r
+                                     fit within the size of the structure passed in.\r
+\r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+                                 The ProtocolCapability variable will not be populated. \r
+  @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
+                                 The ProtocolCapability variable will not be populated.\r
+  @retval EFI_BUFFER_TOO_SMALL   The ProtocolCapability variable is too small to hold the full response.\r
+                                 It will be partially populated (required Size field will be set). \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2GetCapability (\r
+  IN EFI_TCG2_PROTOCOL                    *This,\r
+  IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability\r
+  )\r
+{\r
+  DEBUG ((EFI_D_INFO, "Tcg2GetCapability ...\n"));\r
+\r
+  if ((This == NULL) || (ProtocolCapability == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  DEBUG ((EFI_D_INFO, "Size - 0x%x\n", ProtocolCapability->Size));\r
+  DEBUG ((EFI_D_INFO, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));\r
+\r
+  if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {\r
+    //\r
+    // Handle the case that firmware support 1.1 but OS only support 1.0.\r
+    //\r
+    if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) || \r
+        ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {\r
+      if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {\r
+        CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));\r
+        ProtocolCapability->Size = sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0);\r
+        ProtocolCapability->StructureVersion.Major = 1;\r
+        ProtocolCapability->StructureVersion.Minor = 0;\r
+        ProtocolCapability->ProtocolVersion.Major = 1;\r
+        ProtocolCapability->ProtocolVersion.Minor = 0;\r
+        DEBUG ((EFI_D_ERROR, "TreeGetCapability (Compatible) - %r\n", EFI_SUCCESS));\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+    ProtocolCapability->Size = mTcgDxeData.BsCap.Size;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);\r
+  DEBUG ((EFI_D_INFO, "Tcg2GetCapability - %r\n", EFI_SUCCESS));\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function dump PCR event.\r
+\r
+  @param[in]  EventHdr     TCG PCR event structure.\r
+**/\r
+VOID\r
+DumpEvent (\r
+  IN TCG_PCR_EVENT_HDR         *EventHdr\r
+  )\r
+{\r
+  UINTN                     Index;\r
+\r
+  DEBUG ((EFI_D_INFO, "  Event:\n"));\r
+  DEBUG ((EFI_D_INFO, "    PCRIndex  - %d\n", EventHdr->PCRIndex));\r
+  DEBUG ((EFI_D_INFO, "    EventType - 0x%08x\n", EventHdr->EventType));\r
+  DEBUG ((EFI_D_INFO, "    Digest    - "));\r
+  for (Index = 0; Index < sizeof(TCG_DIGEST); Index++) {\r
+    DEBUG ((EFI_D_INFO, "%02x ", EventHdr->Digest.digest[Index]));\r
+  }\r
+  DEBUG ((EFI_D_INFO, "\n"));\r
+  DEBUG ((EFI_D_INFO, "    EventSize - 0x%08x\n", EventHdr->EventSize));\r
+  InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);\r
+}\r
+\r
+/**\r
+  This function dump TCG_EfiSpecIDEventStruct.\r
+\r
+  @param[in]  TcgEfiSpecIdEventStruct     A pointer to TCG_EfiSpecIDEventStruct.\r
+**/\r
+VOID\r
+DumpTcgEfiSpecIdEventStruct (\r
+  IN TCG_EfiSpecIDEventStruct   *TcgEfiSpecIdEventStruct\r
+  )\r
+{\r
+  TCG_EfiSpecIdEventAlgorithmSize  *digestSize;\r
+  UINTN                            Index;\r
+  UINT8                            *vendorInfoSize;\r
+  UINT8                            *vendorInfo;\r
+  UINT32                           numberOfAlgorithms;\r
+\r
+  DEBUG ((EFI_D_INFO, "  TCG_EfiSpecIDEventStruct:\n"));\r
+  DEBUG ((EFI_D_INFO, "    signature          - '"));\r
+  for (Index = 0; Index < sizeof(TcgEfiSpecIdEventStruct->signature); Index++) {\r
+    DEBUG ((EFI_D_INFO, "%c", TcgEfiSpecIdEventStruct->signature[Index]));\r
+  }\r
+  DEBUG ((EFI_D_INFO, "'\n"));\r
+  DEBUG ((EFI_D_INFO, "    platformClass      - 0x%08x\n", TcgEfiSpecIdEventStruct->platformClass));\r
+  DEBUG ((EFI_D_INFO, "    specVersion        - %d.%d%d\n", TcgEfiSpecIdEventStruct->specVersionMajor, TcgEfiSpecIdEventStruct->specVersionMinor, TcgEfiSpecIdEventStruct->specErrata));\r
+  DEBUG ((EFI_D_INFO, "    uintnSize          - 0x%02x\n", TcgEfiSpecIdEventStruct->uintnSize));\r
+\r
+  CopyMem (&numberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(numberOfAlgorithms));\r
+  DEBUG ((EFI_D_INFO, "    numberOfAlgorithms - 0x%08x\n", numberOfAlgorithms));\r
+\r
+  digestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(numberOfAlgorithms));\r
+  for (Index = 0; Index < numberOfAlgorithms; Index++) {\r
+    DEBUG ((EFI_D_INFO, "    digest(%d)\n", Index));\r
+    DEBUG ((EFI_D_INFO, "      algorithmId      - 0x%04x\n", digestSize[Index].algorithmId));\r
+    DEBUG ((EFI_D_INFO, "      digestSize       - 0x%04x\n", digestSize[Index].digestSize));\r
+  }\r
+  vendorInfoSize = (UINT8 *)&digestSize[numberOfAlgorithms];\r
+  DEBUG ((EFI_D_INFO, "    vendorInfoSize     - 0x%02x\n", *vendorInfoSize));\r
+  vendorInfo = vendorInfoSize + 1;\r
+  DEBUG ((EFI_D_INFO, "    vendorInfo         - "));\r
+  for (Index = 0; Index < *vendorInfoSize; Index++) {\r
+    DEBUG ((EFI_D_INFO, "%02x ", vendorInfo[Index]));\r
+  }\r
+  DEBUG ((EFI_D_INFO, "\n"));\r
+}\r
+\r
+/**\r
+  This function get size of TCG_EfiSpecIDEventStruct.\r
+\r
+  @param[in]  TcgEfiSpecIdEventStruct     A pointer to TCG_EfiSpecIDEventStruct.\r
+**/\r
+UINTN\r
+GetTcgEfiSpecIdEventStructSize (\r
+  IN TCG_EfiSpecIDEventStruct   *TcgEfiSpecIdEventStruct\r
+  )\r
+{\r
+  TCG_EfiSpecIdEventAlgorithmSize  *digestSize;\r
+  UINT8                            *vendorInfoSize;\r
+  UINT32                           numberOfAlgorithms;\r
+\r
+  CopyMem (&numberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof(numberOfAlgorithms));\r
+\r
+  digestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(numberOfAlgorithms));\r
+  vendorInfoSize = (UINT8 *)&digestSize[numberOfAlgorithms];\r
+  return sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (numberOfAlgorithms * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8) + (*vendorInfoSize);\r
+}\r
+\r
+/**\r
+  This function dump PCR event 2.\r
+\r
+  @param[in]  TcgPcrEvent2     TCG PCR event 2 structure.\r
+**/\r
+VOID\r
+DumpEvent2 (\r
+  IN TCG_PCR_EVENT2        *TcgPcrEvent2\r
+  )\r
+{\r
+  UINTN                     Index;\r
+  UINT32                    DigestIndex;\r
+  UINT32                    DigestCount;\r
+  TPMI_ALG_HASH             HashAlgo;\r
+  UINT32                    DigestSize;\r
+  UINT8                     *DigestBuffer;\r
+  UINT32                    EventSize;\r
+  UINT8                     *EventBuffer;\r
+\r
+  DEBUG ((EFI_D_INFO, "  Event:\n"));\r
+  DEBUG ((EFI_D_INFO, "    PCRIndex  - %d\n", TcgPcrEvent2->PCRIndex));\r
+  DEBUG ((EFI_D_INFO, "    EventType - 0x%08x\n", TcgPcrEvent2->EventType));\r
+\r
+  DEBUG ((EFI_D_INFO, "    DigestCount: 0x%08x\n", TcgPcrEvent2->Digest.count));\r
+\r
+  DigestCount = TcgPcrEvent2->Digest.count;\r
+  HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;\r
+  DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;\r
+  for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {\r
+    DEBUG ((EFI_D_INFO, "      HashAlgo : 0x%04x\n", HashAlgo));\r
+    DEBUG ((EFI_D_INFO, "      Digest(%d): ", DigestIndex));\r
+    DigestSize = GetHashSizeFromAlgo (HashAlgo);\r
+    for (Index = 0; Index < DigestSize; Index++) {\r
+      DEBUG ((EFI_D_INFO, "%02x ", DigestBuffer[Index]));\r
+    }\r
+    DEBUG ((EFI_D_INFO, "\n"));\r
+    //\r
+    // Prepare next\r
+    //\r
+    CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH));\r
+    DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH);\r
+  }\r
+  DEBUG ((EFI_D_INFO, "\n"));\r
+  DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH);\r
+\r
+  CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize));\r
+  DEBUG ((EFI_D_INFO, "    EventSize - 0x%08x\n", EventSize));\r
+  EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);\r
+  InternalDumpHex (EventBuffer, EventSize);\r
+}\r
+\r
+/**\r
+  This function returns size of TCG PCR event 2.\r
+  \r
+  @param[in]  TcgPcrEvent2     TCG PCR event 2 structure.\r
+\r
+  @return size of TCG PCR event 2.\r
+**/\r
+UINTN\r
+GetPcrEvent2Size (\r
+  IN TCG_PCR_EVENT2        *TcgPcrEvent2\r
+  )\r
+{\r
+  UINT32                    DigestIndex;\r
+  UINT32                    DigestCount;\r
+  TPMI_ALG_HASH             HashAlgo;\r
+  UINT32                    DigestSize;\r
+  UINT8                     *DigestBuffer;\r
+  UINT32                    EventSize;\r
+  UINT8                     *EventBuffer;\r
+\r
+  DigestCount = TcgPcrEvent2->Digest.count;\r
+  HashAlgo = TcgPcrEvent2->Digest.digests[0].hashAlg;\r
+  DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest.digests[0].digest;\r
+  for (DigestIndex = 0; DigestIndex < DigestCount; DigestIndex++) {\r
+    DigestSize = GetHashSizeFromAlgo (HashAlgo);\r
+    //\r
+    // Prepare next\r
+    //\r
+    CopyMem (&HashAlgo, DigestBuffer + DigestSize, sizeof(TPMI_ALG_HASH));\r
+    DigestBuffer = DigestBuffer + DigestSize + sizeof(TPMI_ALG_HASH);\r
+  }\r
+  DigestBuffer = DigestBuffer - sizeof(TPMI_ALG_HASH);\r
+\r
+  CopyMem (&EventSize, DigestBuffer, sizeof(TcgPcrEvent2->EventSize));\r
+  EventBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);\r
+\r
+  return (UINTN)EventBuffer + EventSize - (UINTN)TcgPcrEvent2;\r
+}\r
+\r
+/**\r
+  This function dump event log.\r
+\r
+  @param[in]  EventLogFormat     The type of the event log for which the information is requested.\r
+  @param[in]  EventLogLocation   A pointer to the memory address of the event log.\r
+  @param[in]  EventLogLastEntry  If the Event Log contains more than one entry, this is a pointer to the\r
+                                 address of the start of the last entry in the event log in memory.\r
+  @param[in]  FinalEventsTable   A pointer to the memory address of the final event table.\r
+**/\r
+VOID\r
+DumpEventLog (\r
+  IN EFI_TCG2_EVENT_LOG_FORMAT   EventLogFormat,\r
+  IN EFI_PHYSICAL_ADDRESS        EventLogLocation,\r
+  IN EFI_PHYSICAL_ADDRESS        EventLogLastEntry,\r
+  IN EFI_TCG2_FINAL_EVENTS_TABLE *FinalEventsTable\r
+  )\r
+{\r
+  TCG_PCR_EVENT_HDR         *EventHdr;\r
+  TCG_PCR_EVENT2            *TcgPcrEvent2;\r
+  TCG_EfiSpecIDEventStruct  *TcgEfiSpecIdEventStruct;\r
+  UINTN                     NumberOfEvents;\r
+\r
+  DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));\r
+  \r
+  switch (EventLogFormat) {\r
+  case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
+    EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
+    while ((UINTN)EventHdr <= EventLogLastEntry) {\r
+      DumpEvent (EventHdr);\r
+      EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);\r
+    }\r
+    if (FinalEventsTable == NULL) {\r
+      DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n"));\r
+    } else {\r
+      DEBUG ((EFI_D_INFO, "FinalEventsTable:    (0x%x)\n", FinalEventsTable));\r
+      DEBUG ((EFI_D_INFO, "  Version:           (0x%x)\n", FinalEventsTable->Version));\r
+      DEBUG ((EFI_D_INFO, "  NumberOfEvents:    (0x%x)\n", FinalEventsTable->NumberOfEvents));\r
+\r
+      EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)(FinalEventsTable + 1);\r
+      for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {\r
+        DumpEvent (EventHdr);\r
+        EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);\r
+      }\r
+    }\r
+    break;\r
+  case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
+    //\r
+    // Dump first event        \r
+    //\r
+    EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
+    DumpEvent (EventHdr);\r
+\r
+    TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)(EventHdr + 1);\r
+    DumpTcgEfiSpecIdEventStruct (TcgEfiSpecIdEventStruct);\r
+\r
+    TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgEfiSpecIdEventStruct + GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct));\r
+    while ((UINTN)TcgPcrEvent2 <= EventLogLastEntry) {\r
+      DumpEvent2 (TcgPcrEvent2);\r
+      TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));\r
+    }\r
+\r
+    if (FinalEventsTable == NULL) {\r
+      DEBUG ((EFI_D_INFO, "FinalEventsTable: NOT FOUND\n"));\r
+    } else {\r
+      DEBUG ((EFI_D_INFO, "FinalEventsTable:    (0x%x)\n", FinalEventsTable));\r
+      DEBUG ((EFI_D_INFO, "  Version:           (0x%x)\n", FinalEventsTable->Version));\r
+      DEBUG ((EFI_D_INFO, "  NumberOfEvents:    (0x%x)\n", FinalEventsTable->NumberOfEvents));\r
+\r
+      TcgPcrEvent2 = (TCG_PCR_EVENT2 *)(UINTN)(FinalEventsTable + 1);\r
+      for (NumberOfEvents = 0; NumberOfEvents < FinalEventsTable->NumberOfEvents; NumberOfEvents++) {\r
+        DumpEvent2 (TcgPcrEvent2);\r
+        TcgPcrEvent2 = (TCG_PCR_EVENT2 *)((UINTN)TcgPcrEvent2 + GetPcrEvent2Size (TcgPcrEvent2));\r
+      }\r
+    }\r
+    break;\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+/**\r
+  The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to\r
+  retrieve the address of a given event log and its last entry. \r
+\r
+  @param[in]  This               Indicates the calling context\r
+  @param[in]  EventLogFormat     The type of the event log for which the information is requested.\r
+  @param[out] EventLogLocation   A pointer to the memory address of the event log.\r
+  @param[out] EventLogLastEntry  If the Event Log contains more than one entry, this is a pointer to the\r
+                                 address of the start of the last entry in the event log in memory.\r
+  @param[out] EventLogTruncated  If the Event Log is missing at least one entry because an event would\r
+                                 have exceeded the area allocated for events, this value is set to TRUE.\r
+                                 Otherwise, the value will be FALSE and the Event Log will be complete.\r
+\r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect\r
+                                 (e.g. asking for an event log whose format is not supported).\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2GetEventLog (\r
+  IN EFI_TCG2_PROTOCOL         *This,\r
+  IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,\r
+  OUT EFI_PHYSICAL_ADDRESS     *EventLogLocation,\r
+  OUT EFI_PHYSICAL_ADDRESS     *EventLogLastEntry,\r
+  OUT BOOLEAN                  *EventLogTruncated\r
+  )\r
+{\r
+  UINTN  Index;\r
+\r
+  DEBUG ((EFI_D_INFO, "Tcg2GetEventLog ... (0x%x)\n", EventLogFormat));\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
+    if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((mTcg2EventInfo[Index].LogFormat & mTcgDxeData.BsCap.SupportedEventLogs) == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
+    if (EventLogLocation != NULL) {\r
+      *EventLogLocation = 0;\r
+    }\r
+    if (EventLogLastEntry != NULL) {\r
+      *EventLogLastEntry = 0;\r
+    }\r
+    if (EventLogTruncated != NULL) {\r
+      *EventLogTruncated = FALSE;\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (EventLogLocation != NULL) {\r
+    *EventLogLocation = mTcgDxeData.EventLogAreaStruct[Index].Lasa;\r
+    DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLocation - %x)\n", *EventLogLocation));\r
+  }\r
+\r
+  if (EventLogLastEntry != NULL) {\r
+    if (!mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted) {\r
+      *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;\r
+    } else {\r
+      *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].LastEvent;\r
+    }\r
+    DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));\r
+  }\r
+\r
+  if (EventLogTruncated != NULL) {\r
+    *EventLogTruncated = mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated;\r
+    DEBUG ((EFI_D_INFO, "Tcg2GetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "Tcg2GetEventLog - %r\n", EFI_SUCCESS));\r
+\r
+  // Dump Event Log for debug purpose\r
+  if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {\r
+    DumpEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry, mTcgDxeData.FinalEventsTable[Index]);\r
+  }\r
+\r
+  //\r
+  // All events generated after the invocation of EFI_TCG2_GET_EVENT_LOG SHALL be stored\r
+  // in an instance of an EFI_CONFIGURATION_TABLE named by the VendorGuid of EFI_TCG2_FINAL_EVENTS_TABLE_GUID.\r
+  //\r
+  mTcgDxeData.GetEventLogCalled[Index] = TRUE;\r
+\r
+  return EFI_SUCCESS;\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/TCG_PCR_EVENT_EX data structure.  \r
+  @param[in]      NewEventHdrSize New event header size.\r
+  @param[in]      NewEventData    Pointer to the new event data.  \r
+  @param[in]      NewEventSize    New event data size.\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
+TcgCommLogEvent (\r
+  IN OUT  UINT8                     **EventLogPtr,\r
+  IN OUT  UINTN                     *LogSize,\r
+  IN      UINTN                     MaxSize,\r
+  IN      VOID                      *NewEventHdr,\r
+  IN      UINT32                    NewEventHdrSize,\r
+  IN      UINT8                     *NewEventData,\r
+  IN      UINT32                    NewEventSize\r
+  )\r
+{\r
+  UINTN                            NewLogSize;\r
+\r
+  if (NewEventSize > MAX_ADDRESS -  NewEventHdrSize) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  NewLogSize = NewEventHdrSize + NewEventSize;\r
+\r
+  if (NewLogSize > MAX_ADDRESS -  *LogSize) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (NewLogSize + *LogSize > MaxSize) {\r
+    DEBUG ((EFI_D_INFO, "  MaxSize    - 0x%x\n", MaxSize));\r
+    DEBUG ((EFI_D_INFO, "  NewLogSize - 0x%x\n", NewLogSize));\r
+    DEBUG ((EFI_D_INFO, "  LogSize    - 0x%x\n", *LogSize));\r
+    DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *EventLogPtr += *LogSize;\r
+  *LogSize += NewLogSize;\r
+  CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize);\r
+  CopyMem (\r
+    *EventLogPtr + NewEventHdrSize,\r
+    NewEventData,\r
+    NewEventSize\r
+    );\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Add a new entry to the Event Log.\r
+\r
+  @param[in] EventLogFormat  The type of the event log for which the information is requested.\r
+  @param[in] NewEventHdr     Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.  \r
+  @param[in] NewEventHdrSize New event header size.\r
+  @param[in] NewEventData    Pointer to the new event data.  \r
+  @param[in] NewEventSize    New event data size.\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
+TcgDxeLogEvent (\r
+  IN      EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,\r
+  IN      VOID                      *NewEventHdr,\r
+  IN      UINT32                    NewEventHdrSize,\r
+  IN      UINT8                     *NewEventData,\r
+  IN      UINT32                    NewEventSize\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UINTN                     Index;\r
+  TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;\r
+  \r
+  for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
+    if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Index == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!mTcgDxeData.GetEventLogCalled[Index]) {\r
+    EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];\r
+  } else {\r
+    EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];\r
+  }\r
+\r
+  if (EventLogAreaStruct->EventLogTruncated) {\r
+    return EFI_VOLUME_FULL;\r
+  }\r
+\r
+  EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;\r
+  Status = TcgCommLogEvent (\r
+             &EventLogAreaStruct->LastEvent,\r
+             &EventLogAreaStruct->EventLogSize,\r
+             (UINTN)EventLogAreaStruct->Laml,\r
+             NewEventHdr,\r
+             NewEventHdrSize,\r
+             NewEventData,\r
+             NewEventSize\r
+             );\r
+  \r
+  if (Status == EFI_DEVICE_ERROR) {\r
+    return EFI_DEVICE_ERROR;\r
+  } else if (Status == EFI_OUT_OF_RESOURCES) {\r
+    EventLogAreaStruct->EventLogTruncated = TRUE;\r
+    return EFI_VOLUME_FULL;\r
+  } else if (Status == EFI_SUCCESS) {\r
+    EventLogAreaStruct->EventLogStarted = TRUE;\r
+    if (mTcgDxeData.GetEventLogCalled[Index]) {\r
+      (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function get digest from digest list.\r
+\r
+  @param HashAlg    digest algorithm\r
+  @param DigestList digest list\r
+  @param Digest     digest\r
+\r
+  @retval EFI_SUCCESS   Sha1Digest is found and returned.\r
+  @retval EFI_NOT_FOUND Sha1Digest is not found.\r
+**/\r
+EFI_STATUS\r
+Tpm2GetDigestFromDigestList (\r
+  IN TPMI_ALG_HASH      HashAlg,\r
+  IN TPML_DIGEST_VALUES *DigestList,\r
+  IN VOID               *Digest\r
+  )\r
+{\r
+  UINTN  Index;\r
+  UINT16 DigestSize;\r
+\r
+  DigestSize = GetHashSizeFromAlgo (HashAlg);\r
+  for (Index = 0; Index < DigestList->count; Index++) {\r
+    if (DigestList->digests[Index].hashAlg == HashAlg) {\r
+      CopyMem (\r
+        Digest,\r
+        &DigestList->digests[Index].digest,\r
+        DigestSize\r
+        );\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Get TPML_DIGEST_VALUES data size.\r
+\r
+  @param[in]     DigestList    TPML_DIGEST_VALUES data.\r
+\r
+  @return TPML_DIGEST_VALUES data size.\r
+**/\r
+UINT32\r
+GetDigestListSize (\r
+  IN TPML_DIGEST_VALUES             *DigestList\r
+  )\r
+{\r
+  UINTN  Index;\r
+  UINT16 DigestSize;\r
+  UINT32 TotalSize;\r
+\r
+  TotalSize = sizeof(DigestList->count);\r
+  for (Index = 0; Index < DigestList->count; Index++) {\r
+    DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
+    TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize;\r
+  }\r
+\r
+  return TotalSize;\r
+}\r
+\r
+/**\r
+  Get TPML_DIGEST_VALUES compact binary buffer size.\r
+\r
+  @param[in]     DigestListBin    TPML_DIGEST_VALUES compact binary buffer.\r
+\r
+  @return TPML_DIGEST_VALUES compact binary buffer size.\r
+**/\r
+UINT32\r
+GetDigestListBinSize (\r
+  IN VOID   *DigestListBin\r
+  )\r
+{\r
+  UINTN         Index;\r
+  UINT16        DigestSize;\r
+  UINT32        TotalSize;\r
+  UINT32        Count;\r
+  TPMI_ALG_HASH HashAlg;\r
+\r
+  Count = ReadUnaligned32 (DigestListBin);\r
+  TotalSize = sizeof(Count);\r
+  DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);\r
+  for (Index = 0; Index < Count; Index++) {\r
+    HashAlg = ReadUnaligned16 (DigestListBin);\r
+    TotalSize += sizeof(HashAlg);\r
+    DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);\r
+\r
+    DigestSize = GetHashSizeFromAlgo (HashAlg);\r
+    TotalSize += DigestSize;\r
+    DigestListBin = (UINT8 *)DigestListBin + DigestSize;\r
+  }\r
+\r
+  return TotalSize;\r
+}\r
+\r
+/**\r
+  Return if hash alg is supported in TPM PCR bank.\r
+\r
+  @param HashAlg  Hash algorithm to be checked.\r
+\r
+  @retval TRUE  Hash algorithm is supported.\r
+  @retval FALSE Hash algorithm is not supported.\r
+**/\r
+BOOLEAN\r
+IsHashAlgSupportedInPcrBank (\r
+  IN TPMI_ALG_HASH  HashAlg\r
+  )\r
+{\r
+  switch (HashAlg) {\r
+  case TPM_ALG_SHA1:\r
+    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  case TPM_ALG_SHA256:\r
+    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  case TPM_ALG_SHA384:\r
+    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  case TPM_ALG_SHA512:\r
+    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  case TPM_ALG_SM3_256:\r
+    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Copy TPML_DIGEST_VALUES into a buffer\r
+\r
+  @param[in,out] Buffer        Buffer to hold TPML_DIGEST_VALUES.\r
+  @param[in]     DigestList    TPML_DIGEST_VALUES to be copied.\r
+\r
+  @return The end of buffer to hold TPML_DIGEST_VALUES.\r
+**/\r
+VOID *\r
+CopyDigestListToBuffer (\r
+  IN OUT VOID                       *Buffer,\r
+  IN TPML_DIGEST_VALUES             *DigestList\r
+  )\r
+{\r
+  UINTN  Index;\r
+  UINT16 DigestSize;\r
+\r
+  CopyMem (Buffer, &DigestList->count, sizeof(DigestList->count));\r
+  Buffer = (UINT8 *)Buffer + sizeof(DigestList->count);\r
+  for (Index = 0; Index < DigestList->count; Index++) {\r
+    if (!IsHashAlgSupportedInPcrBank (DigestList->digests[Index].hashAlg)) {\r
+      DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));\r
+      continue;\r
+    }\r
+    CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg));\r
+    Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg);\r
+    DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
+    CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);\r
+    Buffer = (UINT8 *)Buffer + DigestSize;\r
+  }\r
+\r
+  return Buffer;\r
+}\r
+\r
+/**\r
+  Add a new entry to the Event Log.\r
+\r
+  @param[in]     DigestList    A list of digest.\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           The new event log entry was added.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+**/\r
+EFI_STATUS\r
+TcgDxeLogHashEvent (\r
+  IN TPML_DIGEST_VALUES             *DigestList,\r
+  IN OUT  TCG_PCR_EVENT_HDR         *NewEventHdr,\r
+  IN      UINT8                     *NewEventData\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_TPL                           OldTpl;\r
+  UINTN                             Index;\r
+  EFI_STATUS                        RetStatus;\r
+  TCG_PCR_EVENT2                    TcgPcrEvent2;\r
+  UINT8                             *DigestBuffer;\r
+\r
+  DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
+\r
+  RetStatus = EFI_SUCCESS;\r
+  for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
+    if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
+      DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));\r
+      switch (mTcg2EventInfo[Index].LogFormat) {\r
+      case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
+        Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
+        if (!EFI_ERROR (Status)) {\r
+          //\r
+          // Enter critical region\r
+          //\r
+          OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+          Status = TcgDxeLogEvent (\r
+                     mTcg2EventInfo[Index].LogFormat,\r
+                     NewEventHdr,\r
+                     sizeof(TCG_PCR_EVENT_HDR),\r
+                     NewEventData,\r
+                     NewEventHdr->EventSize\r
+                     );\r
+          if (Status != EFI_SUCCESS) {\r
+            RetStatus = Status;\r
+          }\r
+          gBS->RestoreTPL (OldTpl);\r
+          //\r
+          // Exit critical region\r
+          //\r
+        }\r
+        break;\r
+      case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
+        ZeroMem (&TcgPcrEvent2, sizeof(TcgPcrEvent2));\r
+        TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;\r
+        TcgPcrEvent2.EventType = NewEventHdr->EventType;\r
+        DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;\r
+        DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList);\r
+        CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));\r
+        DigestBuffer = DigestBuffer + sizeof(NewEventHdr->EventSize);\r
+\r
+        //\r
+        // Enter critical region\r
+        //\r
+        OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+        Status = TcgDxeLogEvent (\r
+                   mTcg2EventInfo[Index].LogFormat,\r
+                   &TcgPcrEvent2,\r
+                   sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2.EventSize),\r
+                   NewEventData,\r
+                   NewEventHdr->EventSize\r
+                   );\r
+        if (Status != EFI_SUCCESS) {\r
+          RetStatus = Status;\r
+        }\r
+        gBS->RestoreTPL (OldTpl);\r
+        //\r
+        // Exit critical region\r
+        //\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  return RetStatus;\r
+}\r
+\r
+/**\r
+  Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
+  and add an entry to the Event Log.\r
+\r
+  @param[in]      Flags         Bitmap providing additional information.\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
+\r
+ &n