]> git.proxmox.com Git - mirror_edk2.git/commitdiff
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 c92ee8c0293b7c272075ff1e5ecede65e269777c..1082807c360c7d116a1537cbaeecee82adc90cbc 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 a5d7fe5fa8f7a9e7bfdaf5e3cb257167b3939588..26bf6fb0008656ddd51e4bf987437ba107b06c6b 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 14bf190317be9c885f21f039d6fd6cf206cac1cc..1296c977b4571fb5820ae3fc32e27c6801a7ea72 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 ffeac59ba4d5f5d7d420bd386bc1cc6a6602070c..7a2ec7f221e5fd04d01552a81f2223c21a560853 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 4c61d9a21720657268f767389d478f8da9aa6ee9..410eb788db38f545e3ed9c79808c7516d42e798c 100644 (file)
@@ -46,4 +46,4 @@
 \r
 [Protocols]\r
   gEfiTcgProtocolGuid           ## SOMETIMES_CONSUMES\r
-  gEfiTrEEProtocolGuid          ## SOMETIMES_CONSUMES\r
+  gEfiTcg2ProtocolGuid          ## SOMETIMES_CONSUMES\r
index 833cce2d7aefc588577b46f1b4470e9ca6797d4e..7fb5f3d1f823ef396f4d1d29e78813d22bfb3870 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 d93b33bfcfb009dbc41180ef58f32a19f0023da2..89673373c41f7371e1efbffb2f0781b9035404d6 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 133ef09ba5013306bc50d6bce7d01ce06197c9ca..7c38ea6bc24270d5dae81ec9e6e9f6a84c6c84b7 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 5bc8d01ad56028bfcf81b40f86e5b580dfac1c59..98c07933d827d27ada6757be272f6e1c870b0059 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 13067ee36c38941d299e4a3f9b60a320c36c89fa..c1a699fd0f33a2a4f66798e8e1b3167c525c8057 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 b2e01af37e6a55392c2aac69c65b1897bd7967e1..379f2f7e7e63c63b3e28a698eab65e5c875c8389 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 b0ef20b05b33df2da69cecd54e892a5675bb0c65..48f714f28973d9fa6b2ab9820a04492172c810b5 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 2d464a05178848193d46442f60cc1492cc899ce8..09e8daf79c7fbc1c31131ec41c824c809b1a4817 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
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+TcgDxeHashLogExtendEvent (\r
+  IN      UINT64                    Flags,\r
+  IN      UINT8                     *HashData,\r
+  IN      UINT64                    HashDataLen,\r
+  IN OUT  TCG_PCR_EVENT_HDR         *NewEventHdr,\r
+  IN      UINT8                     *NewEventData\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TPML_DIGEST_VALUES                DigestList;\r
+\r
+  if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  Status = HashAndExtend (\r
+             NewEventHdr->PCRIndex,\r
+             HashData,\r
+             (UINTN)HashDataLen,\r
+             &DigestList\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
+      Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
+    }\r
+  }\r
+\r
+  if (Status == EFI_DEVICE_ERROR) {\r
+    DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));\r
+    mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with\r
+  an opportunity to extend and optionally log events without requiring\r
+  knowledge of actual TPM commands. \r
+  The extend operation will occur even if this function cannot create an event\r
+  log entry (e.g. due to the event log being full). \r
+\r
+  @param[in]  This               Indicates the calling context\r
+  @param[in]  Flags              Bitmap providing additional information.\r
+  @param[in]  DataToHash         Physical address of the start of the data buffer to be hashed. \r
+  @param[in]  DataToHashLen      The length in bytes of the buffer referenced by DataToHash.\r
+  @param[in]  Event              Pointer to data buffer containing information about the event.\r
+\r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+  @retval EFI_VOLUME_FULL        The extend operation occurred, but the event could not be written to one or more event logs.\r
+  @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
+  @retval EFI_UNSUPPORTED        The PE/COFF image type is not supported.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2HashLogExtendEvent (\r
+  IN EFI_TCG2_PROTOCOL    *This,\r
+  IN UINT64               Flags,\r
+  IN EFI_PHYSICAL_ADDRESS DataToHash,\r
+  IN UINT64               DataToHashLen,\r
+  IN EFI_TCG2_EVENT       *Event\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  TCG_PCR_EVENT_HDR  NewEventHdr;\r
+  TPML_DIGEST_VALUES DigestList;\r
+\r
+  DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent ...\n"));\r
+\r
+  if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Header.PCRIndex > MAX_PCR_INDEX) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  NewEventHdr.PCRIndex  = Event->Header.PCRIndex;\r
+  NewEventHdr.EventType = Event->Header.EventType;\r
+  NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;\r
+  if ((Flags & PE_COFF_IMAGE) != 0) {\r
+    Status = MeasurePeImageAndExtend (\r
+               NewEventHdr.PCRIndex,\r
+               DataToHash,\r
+               (UINTN)DataToHashLen,\r
+               &DigestList\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
+        Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);\r
+      }\r
+    }\r
+    if (Status == EFI_DEVICE_ERROR) {\r
+      DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));\r
+      mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
+      REPORT_STATUS_CODE (\r
+        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+        (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
+        );\r
+    }\r
+  } else {\r
+    Status = TcgDxeHashLogExtendEvent (\r
+               Flags,\r
+               (UINT8 *) (UINTN) DataToHash,\r
+               DataToHashLen,\r
+               &NewEventHdr,\r
+               Event->Event\r
+               );\r
+  }\r
+  DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent - %r\n", Status));\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This service enables the sending of commands to the TPM.\r
+\r
+  @param[in]  This                     Indicates the calling context\r
+  @param[in]  InputParameterBlockSize  Size of the TPM input parameter block.\r
+  @param[in]  InputParameterBlock      Pointer to the TPM input parameter block.\r
+  @param[in]  OutputParameterBlockSize Size of the TPM output parameter block.\r
+  @param[in]  OutputParameterBlock     Pointer to the TPM 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_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
+  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small. \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2SubmitCommand (\r
+  IN EFI_TCG2_PROTOCOL *This,\r
+  IN UINT32            InputParameterBlockSize,\r
+  IN UINT8             *InputParameterBlock,\r
+  IN UINT32            OutputParameterBlockSize,\r
+  IN UINT8             *OutputParameterBlock\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand ...\n"));\r
+\r
+  if ((This == NULL) ||\r
+      (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||\r
+      (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  if (InputParameterBlockSize >= mTcgDxeData.BsCap.MaxCommandSize) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  if (OutputParameterBlockSize >= mTcgDxeData.BsCap.MaxResponseSize) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = Tpm2SubmitCommand (\r
+             InputParameterBlockSize,\r
+             InputParameterBlock,\r
+             &OutputParameterBlockSize,\r
+             OutputParameterBlock\r
+             );\r
+  DEBUG ((EFI_D_INFO, "Tcg2SubmitCommand - %r\n", Status));\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This service returns the currently active PCR banks.\r
+\r
+  @param[in]  This            Indicates the calling context\r
+  @param[out] ActivePcrBanks  Pointer to the variable receiving the bitmap of currently active PCR banks.\r
+\r
+  @retval EFI_SUCCESS           The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.\r
+  @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2GetActivePCRBanks (\r
+  IN  EFI_TCG2_PROTOCOL *This,\r
+  OUT UINT32            *ActivePcrBanks\r
+  )\r
+{\r
+  if (ActivePcrBanks == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  *ActivePcrBanks = mTcgDxeData.BsCap.ActivePcrBanks;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This service sets the currently active PCR banks.\r
+\r
+  @param[in]  This            Indicates the calling context\r
+  @param[in]  ActivePcrBanks  Bitmap of the requested active PCR banks. At least one bit SHALL be set.\r
+\r
+  @retval EFI_SUCCESS           The bitmap in ActivePcrBank parameter is already active.\r
+  @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2SetActivePCRBanks (\r
+  IN EFI_TCG2_PROTOCOL *This,\r
+  IN UINT32            ActivePcrBanks\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      ReturnCode;\r
+\r
+  DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks ... (0x%x)\n", ActivePcrBanks));\r
+\r
+  if (ActivePcrBanks == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  if ((ActivePcrBanks & (~mTcgDxeData.BsCap.HashAlgorithmBitmap)) != 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  if (ActivePcrBanks == mTcgDxeData.BsCap.ActivePcrBanks) {\r
+    //\r
+    // Need clear previous SET_PCR_BANKS setting\r
+    //\r
+    ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_NO_ACTION, 0);\r
+  } else {\r
+    ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, ActivePcrBanks);\r
+  }\r
+\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
+  DEBUG ((EFI_D_INFO, "Tcg2SetActivePCRBanks - %r\n", Status));\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This service retrieves the result of a previous invocation of SetActivePcrBanks.\r
+\r
+  @param[in]  This              Indicates the calling context\r
+  @param[out] OperationPresent  Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.\r
+  @param[out] Response          The response from the SetActivePcrBank request.\r
+\r
+  @retval EFI_SUCCESS           The result value could be returned.\r
+  @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tcg2GetResultOfSetActivePcrBanks (\r
+  IN  EFI_TCG2_PROTOCOL  *This,\r
+  OUT UINT32             *OperationPresent,\r
+  OUT UINT32             *Response\r
+  )\r
+{\r
+  UINT32  ReturnCode;\r
+\r
+  if ((OperationPresent == NULL) || (Response == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);\r
+  if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+}\r
+\r
+EFI_TCG2_PROTOCOL mTcg2Protocol = {\r
+    Tcg2GetCapability,\r
+    Tcg2GetEventLog,\r
+    Tcg2HashLogExtendEvent,\r
+    Tcg2SubmitCommand,\r
+    Tcg2GetActivePCRBanks,\r
+    Tcg2SetActivePCRBanks,\r
+    Tcg2GetResultOfSetActivePcrBanks,\r
+};\r
+\r
+/**\r
+  Initialize the Event Log and log events passed from the PEI phase.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+\r
+**/\r
+EFI_STATUS\r
+SetupEventLog (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  VOID                            *TcgEvent;\r
+  EFI_PEI_HOB_POINTERS            GuidHob;\r
+  EFI_PHYSICAL_ADDRESS            Lasa;\r
+  UINTN                           Index;\r
+  UINT32                          DigestListBinSize;\r
+  UINT32                          EventSize;\r
+  TCG_EfiSpecIDEventStruct        *TcgEfiSpecIdEventStruct;\r
+  UINT8                           TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
+  TCG_PCR_EVENT_HDR               FirstPcrEvent;\r
+  TCG_EfiSpecIdEventAlgorithmSize *digestSize;\r
+  UINT8                           *vendorInfoSize;\r
+  UINT32                          numberOfAlgorithms;\r
+\r
+  DEBUG ((EFI_D_INFO, "SetupEventLog\n"));\r
+\r
+  //\r
+  // 1. Create Log Area\r
+  //\r
+  for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
+    if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
+      mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
+      Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
+      Status = gBS->AllocatePages (\r
+                      AllocateMaxAddress,\r
+                      EfiACPIMemoryNVS,\r
+                      EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),\r
+                      &Lasa\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
+      mTcgDxeData.EventLogAreaStruct[Index].Laml = EFI_TCG_LOG_AREA_SIZE;\r
+      //\r
+      // To initialize them as 0xFF is recommended \r
+      // because the OS can know the last entry for that.\r
+      //\r
+      SetMem ((VOID *)(UINTN)Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF);\r
+      //\r
+      // Create first entry for Log Header Entry Data\r
+      //\r
+      if (mTcg2EventInfo[Index].LogFormat != EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {\r
+        //\r
+        // TcgEfiSpecIdEventStruct\r
+        //\r
+        TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *)TempBuf;\r
+        CopyMem (TcgEfiSpecIdEventStruct->signature, TCG_EfiSpecIDEventStruct_SIGNATURE_03, sizeof(TcgEfiSpecIdEventStruct->signature));\r
+        TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);\r
+        TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;\r
+        TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;\r
+        TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;\r
+        TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);\r
+        numberOfAlgorithms = 0;\r
+        digestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(numberOfAlgorithms));\r
+        if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
+          digestSize[numberOfAlgorithms].algorithmId = TPM_ALG_SHA1;\r
+          digestSize[numberOfAlgorithms].digestSize = SHA1_DIGEST_SIZE;\r
+          numberOfAlgorithms++;\r
+        }\r
+        if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
+          digestSize[numberOfAlgorithms].algorithmId = TPM_ALG_SHA256;\r
+          digestSize[numberOfAlgorithms].digestSize = SHA256_DIGEST_SIZE;\r
+          numberOfAlgorithms++;\r
+        }\r
+        if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
+          digestSize[numberOfAlgorithms].algorithmId = TPM_ALG_SHA384;\r
+          digestSize[numberOfAlgorithms].digestSize = SHA384_DIGEST_SIZE;\r
+          numberOfAlgorithms++;\r
+        }\r
+        if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
+          digestSize[numberOfAlgorithms].algorithmId = TPM_ALG_SHA512;\r
+          digestSize[numberOfAlgorithms].digestSize = SHA512_DIGEST_SIZE;\r
+          numberOfAlgorithms++;\r
+        }\r
+        if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
+          digestSize[numberOfAlgorithms].algorithmId = TPM_ALG_SM3_256;\r
+          digestSize[numberOfAlgorithms].digestSize = SM3_256_DIGEST_SIZE;\r
+          numberOfAlgorithms++;\r
+        }\r
+        CopyMem (TcgEfiSpecIdEventStruct + 1, &numberOfAlgorithms, sizeof(numberOfAlgorithms));\r
+        vendorInfoSize = (UINT8 *)&digestSize[numberOfAlgorithms];\r
+        *vendorInfoSize = 0;\r
+\r
+        //\r
+        // FirstPcrEvent\r
+        //\r
+        FirstPcrEvent.PCRIndex = 0;\r
+        FirstPcrEvent.EventType = EV_NO_ACTION;\r
+        ZeroMem (&FirstPcrEvent.Digest, sizeof(FirstPcrEvent.Digest));\r
+        FirstPcrEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
+\r
+        //\r
+        // Record\r
+        //\r
+        Status = TcgDxeLogEvent (\r
+                   mTcg2EventInfo[Index].LogFormat,\r
+                   &FirstPcrEvent,\r
+                   sizeof(FirstPcrEvent),\r
+                   (UINT8 *)TcgEfiSpecIdEventStruct,\r
+                   FirstPcrEvent.EventSize\r
+                   );\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // 2. Create Final Log Area\r
+  //\r
+  for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
+    if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
+      Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
+      Status = gBS->AllocatePages (\r
+                      AllocateMaxAddress,\r
+                      EfiACPIMemoryNVS,\r
+                      EFI_SIZE_TO_PAGES (EFI_TCG_FINAL_LOG_AREA_SIZE),\r
+                      &Lasa\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      SetMem ((VOID *)(UINTN)Lasa, EFI_TCG_FINAL_LOG_AREA_SIZE, 0xFF);\r
+\r
+      //\r
+      // Initialize\r
+      //\r
+      mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;\r
+      (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;\r
+      (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;\r
+\r
+      mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
+      mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
+      mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = EFI_TCG_FINAL_LOG_AREA_SIZE - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
+      mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
+      mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
+      mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
+      mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
+\r
+      if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
+        //\r
+        // Install to configuration table\r
+        //\r
+        Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[1]);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  \r
+  //\r
+  // 3. Sync data from PEI to DXE\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
+    if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
+      GuidHob.Raw = GetHobList ();\r
+      Status = EFI_SUCCESS;\r
+      while (!EFI_ERROR (Status) && \r
+             (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
+        TcgEvent    = GET_GUID_HOB_DATA (GuidHob.Guid);\r
+        GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
+        switch (mTcg2EventInfo[Index].LogFormat) {\r
+        case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
+          Status = TcgDxeLogEvent (\r
+                     mTcg2EventInfo[Index].LogFormat,\r
+                     TcgEvent,\r
+                     sizeof(TCG_PCR_EVENT_HDR),\r
+                     ((TCG_PCR_EVENT*)TcgEvent)->Event,\r
+                     ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize\r
+                     );\r
+          break;\r
+        case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
+          DigestListBinSize = GetDigestListBinSize ((UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE));\r
+          CopyMem (&EventSize, (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize, sizeof(UINT32));\r
+          Status = TcgDxeLogEvent (\r
+                     mTcg2EventInfo[Index].LogFormat,\r
+                     TcgEvent,\r
+                     sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
+                     (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
+                     EventSize\r
+                     );\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Measure and log an action string, and extend the measurement result into PCR[5].\r
+\r
+  @param[in] String           A specific string that indicates an Action event.  \r
+  \r
+  @retval EFI_SUCCESS         Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+TcgMeasureAction (\r
+  IN      CHAR8                     *String\r
+  )\r
+{\r
+  TCG_PCR_EVENT_HDR                 TcgEvent;\r
+\r
+  TcgEvent.PCRIndex  = 5;\r
+  TcgEvent.EventType = EV_EFI_ACTION;\r
+  TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
+  return TcgDxeHashLogExtendEvent (\r
+           0,\r
+           (UINT8*)String,\r
+           TcgEvent.EventSize,\r
+           &TcgEvent,\r
+           (UINT8 *) String\r
+           );\r
+}\r
+\r
+/**\r
+  Measure and log EFI handoff tables, and extend the measurement result into PCR[1].\r
+\r
+  @retval EFI_SUCCESS         Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureHandoffTables (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  SMBIOS_TABLE_ENTRY_POINT          *SmbiosTable;\r
+  TCG_PCR_EVENT_HDR                 TcgEvent;\r
+  EFI_HANDOFF_TABLE_POINTERS        HandoffTables;\r
+  UINTN                             ProcessorNum;\r
+  EFI_CPU_PHYSICAL_LOCATION         *ProcessorLocBuf;\r
+\r
+  ProcessorLocBuf = NULL;\r
+\r
+  //\r
+  // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]\r
+  //\r
+  Status = EfiGetSystemConfigurationTable (\r
+             &gEfiSmbiosTableGuid,\r
+             (VOID **) &SmbiosTable\r
+             );\r
+\r
+  if (!EFI_ERROR (Status) && SmbiosTable != NULL) {\r
+    TcgEvent.PCRIndex  = 1;\r
+    TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;\r
+    TcgEvent.EventSize = sizeof (HandoffTables);\r
+\r
+    HandoffTables.NumberOfTables = 1;\r
+    HandoffTables.TableEntry[0].VendorGuid  = gEfiSmbiosTableGuid;\r
+    HandoffTables.TableEntry[0].VendorTable = SmbiosTable;\r
+\r
+    DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress));\r
+    DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength));\r
+\r
+    Status = TcgDxeHashLogExtendEvent (\r
+               0,\r
+               (UINT8*)(UINTN)SmbiosTable->TableAddress,\r
+               SmbiosTable->TableLength,\r
+               &TcgEvent,\r
+               (UINT8*)&HandoffTables\r
+               );\r
+  }\r
+\r
+  if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
+    //\r
+    // Tcg Server spec. \r
+    // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
+    //\r
+    Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
+\r
+    if (!EFI_ERROR(Status)){\r
+      TcgEvent.PCRIndex  = 1;\r
+      TcgEvent.EventType = EV_TABLE_OF_DEVICES;\r
+      TcgEvent.EventSize = sizeof (HandoffTables);\r
+\r
+      HandoffTables.NumberOfTables = 1;\r
+      HandoffTables.TableEntry[0].VendorGuid  = gEfiMpServiceProtocolGuid;\r
+      HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;\r
+\r
+      Status = TcgDxeHashLogExtendEvent (\r
+                 0,\r
+                 (UINT8*)(UINTN)ProcessorLocBuf,\r
+                 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
+                 &TcgEvent,\r
+                 (UINT8*)&HandoffTables\r
+                 );\r
+\r
+      FreePool(ProcessorLocBuf);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Measure and log Separator event, and extend the measurement result into a specific PCR.\r
+\r
+  @param[in] PCRIndex         PCR index.  \r
+\r
+  @retval EFI_SUCCESS         Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureSeparatorEvent (\r
+  IN      TPM_PCRINDEX              PCRIndex\r
+  )\r
+{\r
+  TCG_PCR_EVENT_HDR                 TcgEvent;\r
+  UINT32                            EventData;\r
+\r
+  DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));\r
+\r
+  EventData = 0;\r
+  TcgEvent.PCRIndex  = PCRIndex;\r
+  TcgEvent.EventType = EV_SEPARATOR;\r
+  TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
+  return TcgDxeHashLogExtendEvent (\r
+           0,\r
+           (UINT8 *)&EventData,\r
+           sizeof (EventData),\r
+           &TcgEvent,\r
+           (UINT8 *)&EventData\r
+           );\r
+}\r
+\r
+/**\r
+  Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
+\r
+  @param[in]  PCRIndex          PCR Index.  \r
+  @param[in]  EventType         Event type.  \r
+  @param[in]  VarName           A Null-terminated string that is the name of the vendor's variable.\r
+  @param[in]  VendorGuid        A unique identifier for the vendor.\r
+  @param[in]  VarData           The content of the variable data.  \r
+  @param[in]  VarSize           The size of the variable data.  \r
\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureVariable (\r
+  IN      TPM_PCRINDEX              PCRIndex,\r
+  IN      TCG_EVENTTYPE             EventType,\r
+  IN      CHAR16                    *VarName,\r
+  IN      EFI_GUID                  *VendorGuid,\r
+  IN      VOID                      *VarData,\r
+  IN      UINTN                     VarSize\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TCG_PCR_EVENT_HDR                 TcgEvent;\r
+  UINTN                             VarNameLength;\r
+  EFI_VARIABLE_DATA_TREE            *VarLog;\r
+\r
+  DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
+  DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
+\r
+  VarNameLength      = StrLen (VarName);\r
+  TcgEvent.PCRIndex  = PCRIndex;\r
+  TcgEvent.EventType = EventType;\r
+\r
+  TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
+                        - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
+\r
+  VarLog = (EFI_VARIABLE_DATA_TREE *)AllocatePool (TcgEvent.EventSize);\r
+  if (VarLog == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  VarLog->VariableName       = *VendorGuid;\r
+  VarLog->UnicodeNameLength  = VarNameLength;\r
+  VarLog->VariableDataLength = VarSize;\r
+  CopyMem (\r
+     VarLog->UnicodeName,\r
+     VarName,\r
+     VarNameLength * sizeof (*VarName)\r
+     );\r
+  if (VarSize != 0 && VarData != NULL) {\r
+    CopyMem (\r
+       (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
+       VarData,\r
+       VarSize\r
+       );\r
+  }\r
+\r
+  if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
+    //\r
+    // Digest is the event data (EFI_VARIABLE_DATA)\r
+    //\r
+    Status = TcgDxeHashLogExtendEvent (\r
+               0,\r
+               (UINT8*)VarLog,\r
+               TcgEvent.EventSize,\r
+               &TcgEvent,\r
+               (UINT8*)VarLog\r
+               );\r
+  } else {\r
+    Status = TcgDxeHashLogExtendEvent (\r
+               0,\r
+               (UINT8*)VarData,\r
+               VarSize,\r
+               &TcgEvent,\r
+               (UINT8*)VarLog\r
+               );\r
+  }\r
+  FreePool (VarLog);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
+\r
+  @param[in]  PCRIndex          PCR Index.  \r
+  @param[in]  EventType         Event type.  \r
+  @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
+  @param[in]   VendorGuid       A unique identifier for the vendor.\r
+  @param[out]  VarSize          The size of the variable data.  \r
+  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+ReadAndMeasureVariable (\r
+  IN      TPM_PCRINDEX              PCRIndex,\r
+  IN      TCG_EVENTTYPE             EventType,\r
+  IN      CHAR16                    *VarName,\r
+  IN      EFI_GUID                  *VendorGuid,\r
+  OUT     UINTN                     *VarSize,\r
+  OUT     VOID                      **VarData\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+\r
+  Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);\r
+  if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // It is valid case, so we need handle it.\r
+      //\r
+      *VarData = NULL;\r
+      *VarSize = 0;\r
+    }\r
+  } else {\r
+    //\r
+    // if status error, VarData is freed and set NULL by GetVariable2\r
+    //\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  Status = MeasureVariable (\r
+             PCRIndex,\r
+             EventType,\r
+             VarName,\r
+             VendorGuid,\r
+             *VarData,\r
+             *VarSize\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].\r
+\r
+  @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
+  @param[in]   VendorGuid       A unique identifier for the vendor.\r
+  @param[out]  VarSize          The size of the variable data.  \r
+  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+ReadAndMeasureBootVariable (\r
+  IN      CHAR16                    *VarName,\r
+  IN      EFI_GUID                  *VendorGuid,\r
+  OUT     UINTN                     *VarSize,\r
+  OUT     VOID                      **VarData\r
+  )\r
+{\r
+  return ReadAndMeasureVariable (\r
+           5,\r
+           EV_EFI_VARIABLE_BOOT,\r
+           VarName,\r
+           VendorGuid,\r
+           VarSize,\r
+           VarData\r
+           );\r
+}\r
+\r
+/**\r
+  Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].\r
+\r
+  @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
+  @param[in]   VendorGuid       A unique identifier for the vendor.\r
+  @param[out]  VarSize          The size of the variable data.  \r
+  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+ReadAndMeasureSecureVariable (\r
+  IN      CHAR16                    *VarName,\r
+  IN      EFI_GUID                  *VendorGuid,\r
+  OUT     UINTN                     *VarSize,\r
+  OUT     VOID                      **VarData\r
+  )\r
+{\r
+  return ReadAndMeasureVariable (\r
+           7,\r
+           EV_EFI_VARIABLE_DRIVER_CONFIG,\r
+           VarName,\r
+           VendorGuid,\r
+           VarSize,\r
+           VarData\r
+           );\r
+}\r
+\r
+/**\r
+  Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.\r
+\r
+  The EFI boot variables are BootOrder and Boot#### variables.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureAllBootVariables (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINT16                            *BootOrder;\r
+  UINTN                             BootCount;\r
+  UINTN                             Index;\r
+  VOID                              *BootVarData;\r
+  UINTN                             Size;\r
+\r
+  Status = ReadAndMeasureBootVariable (\r
+             mBootVarName,\r
+             &gEfiGlobalVariableGuid,\r
+             &BootCount,\r
+             (VOID **) &BootOrder\r
+             );\r
+  if (Status == EFI_NOT_FOUND || BootOrder == NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // BootOrder can't be NULL if status is not EFI_NOT_FOUND\r
+    //\r
+    FreePool (BootOrder);\r
+    return Status;\r
+  }\r
+\r
+  BootCount /= sizeof (*BootOrder);\r
+  for (Index = 0; Index < BootCount; Index++) {\r
+    UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);\r
+    Status = ReadAndMeasureBootVariable (\r
+               mBootVarName,\r
+               &gEfiGlobalVariableGuid,\r
+               &Size,\r
+               &BootVarData\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      FreePool (BootVarData);\r
+    }\r
+  }\r
+\r
+  FreePool (BootOrder);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.\r
+\r
+  The EFI boot variables are BootOrder and Boot#### variables.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureAllSecureVariables (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  VOID                              *Data;\r
+  UINTN                             DataSize;\r
+  UINTN                             Index;\r
+\r
+  Status = EFI_NOT_FOUND;\r
+  for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
+    Status = ReadAndMeasureSecureVariable (\r
+               mVariableType[Index].VariableName,\r
+               mVariableType[Index].VendorGuid,\r
+               &DataSize,\r
+               &Data\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      if (Data != NULL) {\r
+        FreePool (Data);\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureLaunchOfFirmwareDebugger (\r
+  VOID\r
+  )\r
+{\r
+  TCG_PCR_EVENT_HDR                 TcgEvent;\r
+\r
+  TcgEvent.PCRIndex  = 7;\r
+  TcgEvent.EventType = EV_EFI_ACTION;\r
+  TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;\r
+  return TcgDxeHashLogExtendEvent (\r
+           0,\r
+           (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,\r
+           sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,\r
+           &TcgEvent,\r
+           (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING\r
+           );\r
+}\r
+\r
+/**\r
+  Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.\r
+\r
+  Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)\r
+   - The contents of the SecureBoot variable\r
+   - The contents of the PK variable\r
+   - The contents of the KEK variable\r
+   - The contents of the EFI_IMAGE_SECURITY_DATABASE variable\r
+   - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable\r
+   - Separator\r
+   - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path\r
+\r
+  NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,\r
+  EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].\r
+\r
+  @param[in]  Event     Event whose notification function is being invoked\r
+  @param[in]  Context   Pointer to the notification function's context\r
+**/\r
+VOID\r
+EFIAPI\r
+MeasureSecureBootPolicy (\r
+  IN EFI_EVENT                      Event,\r
+  IN VOID                           *Context\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  VOID        *Protocol;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {\r
+    Status = MeasureLaunchOfFirmwareDebugger ();\r
+    DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));\r
+  }\r
+\r
+  Status = MeasureAllSecureVariables ();\r
+  DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));\r
+\r
+  //\r
+  // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)\r
+  // and ImageVerification (Authority)\r
+  // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So\r
+  // the Authority measurement happen before ReadToBoot event.\r
+  //\r
+  Status = MeasureSeparatorEvent (7);\r
+  DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));\r
+  return ;\r
+}\r
+\r
+/**\r
+  Ready to Boot Event notification handler.\r
+\r
+  Sequence of OS boot events is measured in this event notification handler.\r
+\r
+  @param[in]  Event     Event whose notification function is being invoked\r
+  @param[in]  Context   Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnReadyToBoot (\r
+  IN      EFI_EVENT                 Event,\r
+  IN      VOID                      *Context\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TPM_PCRINDEX                      PcrIndex;\r
+\r
+  PERF_START_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE);\r
+  if (mBootAttempts == 0) {\r
+\r
+    //\r
+    // Measure handoff tables.\r
+    //\r
+    Status = MeasureHandoffTables ();\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));\r
+    }\r
+\r
+    //\r
+    // Measure BootOrder & Boot#### variables.\r
+    //\r
+    Status = MeasureAllBootVariables ();\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));\r
+    }\r
+\r
+    //\r
+    // 1. This is the first boot attempt.\r
+    //\r
+    Status = TcgMeasureAction (\r
+               EFI_CALLING_EFI_APPLICATION\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
+    }\r
+\r
+    //\r
+    // 2. Draw a line between pre-boot env and entering post-boot env.\r
+    // PCR[7] is already done.\r
+    //\r
+    for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
+      Status = MeasureSeparatorEvent (PcrIndex);\r
+      if (EFI_ERROR (Status)) {\r
+        DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));\r
+      }\r
+    }\r
+\r
+    //\r
+    // 3. Measure GPT. It would be done in SAP driver.\r
+    //\r
+\r
+    //\r
+    // 4. Measure PE/COFF OS loader. It would be done in SAP driver.\r
+    //\r
+\r
+    //\r
+    // 5. Read & Measure variable. BootOrder already measured.\r
+    //\r
+  } else {\r
+    //\r
+    // 6. Not first attempt, meaning a return from last attempt\r
+    //\r
+    Status = TcgMeasureAction (\r
+               EFI_RETURNING_FROM_EFI_APPLICATOIN\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
+    }\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));\r
+  //\r
+  // Increase boot attempt counter.\r
+  //\r
+  mBootAttempts++;\r
+  PERF_END_EX (mImageHandle, "EventRec", "Tcg2Dxe", 0, PERF_ID_TCG2_DXE + 1);\r
+}\r
+\r
+/**\r
+  Exit Boot Services Event notification handler.\r
+\r
+  Measure invocation and success of ExitBootServices.\r
+\r
+  @param[in]  Event     Event whose notification function is being invoked\r
+  @param[in]  Context   Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnExitBootServices (\r
+  IN      EFI_EVENT                 Event,\r
+  IN      VOID                      *Context\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  //\r
+  // Measure invocation of ExitBootServices,\r
+  //\r
+  Status = TcgMeasureAction (\r
+             EFI_EXIT_BOOT_SERVICES_INVOCATION\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));\r
+  }\r
+\r
+  //\r
+  // Measure success of ExitBootServices\r
+  //\r
+  Status = TcgMeasureAction (\r
+             EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));\r
+  }\r
+}\r
+\r
+/**\r
+  Exit Boot Services Failed Event notification handler.\r
+\r
+  Measure Failure of ExitBootServices.\r
+\r
+  @param[in]  Event     Event whose notification function is being invoked\r
+  @param[in]  Context   Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnExitBootServicesFailed (\r
+  IN      EFI_EVENT                 Event,\r
+  IN      VOID                      *Context\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  //\r
+  // Measure Failure of ExitBootServices,\r
+  //\r
+  Status = TcgMeasureAction (\r
+             EFI_EXIT_BOOT_SERVICES_FAILED\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));\r
+  }\r
+\r
+}\r
+\r
+/**\r
+  The function install Tcg2 protocol.\r
+  \r
+  @retval EFI_SUCCESS     Tcg2 protocol is installed.\r
+  @retval other           Some error occurs.\r
+**/\r
+EFI_STATUS\r
+InstallTcg2 (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS        Status;\r
+  EFI_HANDLE        Handle;\r
+\r
+  Handle = NULL;\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Handle,\r
+                  &gEfiTcg2ProtocolGuid,\r
+                  &mTcg2Protocol,\r
+                  NULL\r
+                  );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  The driver's entry point. It publishes EFI Tcg2 Protocol.\r
+\r
+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable  A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS     The entry point is executed successfully.\r
+  @retval other           Some error occurs when executing this entry point.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverEntry (\r
+  IN    EFI_HANDLE                  ImageHandle,\r
+  IN    EFI_SYSTEM_TABLE            *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_EVENT                         Event;\r
+  VOID                              *Registration;\r
+  UINT32                            MaxCommandSize;\r
+  UINT32                            MaxResponseSize;\r
+  TPML_PCR_SELECTION                Pcrs;\r
+  UINTN                             Index;\r
+  EFI_TCG2_EVENT_ALGORITHM_BITMAP   TpmHashAlgorithmBitmap;\r
+  UINT32                            ActivePCRBanks;\r
+  UINT32                            NumberOfPCRBanks;\r
+\r
+  mImageHandle = ImageHandle;\r
+\r
+  if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
+      CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
+    DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
+    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  \r
+  Status = Tpm2RequestUseTpm ();\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
+    return Status;\r
+  }\r
+  \r
+  //\r
+  // Fill information\r
+  //\r
+  ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));\r
+  \r
+  mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
+  mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
+  mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
+  mTcgDxeData.BsCap.StructureVersion.Major = 1;\r
+  mTcgDxeData.BsCap.StructureVersion.Minor = 1;\r
+\r
+  DEBUG ((EFI_D_INFO, "Tcg2.ProtocolVersion  - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));\r
+  DEBUG ((EFI_D_INFO, "Tcg2.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));\r
+\r
+  Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));\r
+  } else {\r
+    DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));\r
+  }\r
+\r
+  DEBUG_CODE (\r
+    UINT32                    FirmwareVersion1;\r
+    UINT32                    FirmwareVersion2;\r
+\r
+    Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));\r
+    } else {\r
+      DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));\r
+    }\r
+  );\r
+\r
+  Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));\r
+  } else {\r
+    mTcgDxeData.BsCap.MaxCommandSize  = (UINT16)MaxCommandSize;\r
+    mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;\r
+    DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));\r
+  }\r
+\r
+  //\r
+  // Get supported PCR and current Active PCRs\r
+  //\r
+  Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));\r
+    TpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
+    NumberOfPCRBanks = 1;\r
+    ActivePCRBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
+  } else {\r
+    DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));\r
+    NumberOfPCRBanks = 0;\r
+    TpmHashAlgorithmBitmap = 0;\r
+    ActivePCRBanks = 0;\r
+    for (Index = 0; Index < Pcrs.count; Index++) {\r
+      DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));\r
+      switch (Pcrs.pcrSelections[Index].hash) {\r
+      case TPM_ALG_SHA1:\r
+        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
+        NumberOfPCRBanks ++;\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
+        }        \r
+        break;\r
+      case TPM_ALG_SHA256:\r
+        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
+        NumberOfPCRBanks ++;\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
+        }\r
+        break;\r
+      case TPM_ALG_SHA384:\r
+        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
+        NumberOfPCRBanks ++;\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
+        }\r
+        break;\r
+      case TPM_ALG_SHA512:\r
+        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
+        NumberOfPCRBanks ++;\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
+        }\r
+        break;\r
+      case TPM_ALG_SM3_256:\r
+        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
+        NumberOfPCRBanks ++;\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
+        }\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
+  mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
+\r
+  if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {\r
+    mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
+  } else {\r
+    mTcgDxeData.BsCap.NumberOfPCRBanks = PcdGet32 (PcdTcg2NumberOfPCRBanks);\r
+    if (PcdGet32 (PcdTcg2NumberOfPCRBanks) > NumberOfPCRBanks) {\r
+      DEBUG ((EFI_D_ERROR, "ERROR: PcdTcg2NumberOfPCRBanks(0x%x) > NumberOfPCRBanks(0x%x)\n", PcdGet32 (PcdTcg2NumberOfPCRBanks), NumberOfPCRBanks));\r
+      mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
+    }\r
+  }\r
+\r
+  mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & TREE_BOOT_HASH_ALG_SHA1) == 0) {\r
+    //\r
+    // No need to expose TCG1.2 event log if SHA1 bank does not exist.\r
+    //\r
+    mTcgDxeData.BsCap.SupportedEventLogs &= ~TREE_EVENT_LOG_FORMAT_TCG_1_2;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
+  DEBUG ((EFI_D_INFO, "Tcg2.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));\r
+  DEBUG ((EFI_D_INFO, "Tcg2.NumberOfPCRBanks      - 0x%08x\n", mTcgDxeData.BsCap.NumberOfPCRBanks));\r
+  DEBUG ((EFI_D_INFO, "Tcg2.ActivePcrBanks        - 0x%08x\n", mTcgDxeData.BsCap.ActivePcrBanks));\r
+\r
+  if (mTcgDxeData.BsCap.TPMPresentFlag) {\r
+    //\r
+    // Setup the log area and copy event log from hob list to it\r
+    //\r
+    Status = SetupEventLog ();\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Measure handoff tables, Boot#### variables etc.\r
+    //\r
+    Status = EfiCreateEventReadyToBootEx (\r
+               TPL_CALLBACK,\r
+               OnReadyToBoot,\r
+               NULL,\r
+               &Event\r
+               );\r
+\r
+    Status = gBS->CreateEventEx (\r
+                    EVT_NOTIFY_SIGNAL,\r
+                    TPL_NOTIFY,\r
+                    OnExitBootServices,\r
+                    NULL,\r
+                    &gEfiEventExitBootServicesGuid,\r
+                    &Event\r
+                    );\r
+\r
+    //\r
+    // Measure Exit Boot Service failed \r
+    //\r
+    Status = gBS->CreateEventEx (\r
+                    EVT_NOTIFY_SIGNAL,\r
+                    TPL_NOTIFY,\r
+                    OnExitBootServicesFailed,\r
+                    NULL,\r
+                    &gEventExitBootServicesFailedGuid,\r
+                    &Event\r
+                    );\r
+\r
+    //\r
+    // Create event callback, because we need access variable on SecureBootPolicyVariable\r
+    // We should use VariableWriteArch instead of VariableArch, because Variable driver\r
+    // may update SecureBoot value based on last setting.\r
+    //\r
+    EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
+  }\r
+\r
+  //\r
+  // Install Tcg2Protocol\r
+  //\r
+  Status = InstallTcg2 ();\r
+  DEBUG ((EFI_D_INFO, "InstallTcg2 - %r\n", Status));\r
+\r
+  return Status;\r
+}\r
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
new file mode 100644 (file)
index 0000000..d6ac07e
--- /dev/null
@@ -0,0 +1,112 @@
+## @file\r
+#  Produces Tcg2 protocol and measure boot environment\r
+#  This module will produce Tcg2 protocol and measure boot environment.\r
+#\r
+#  Caution: This module 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
+# 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                      = Tcg2Dxe\r
+  MODULE_UNI_FILE                = Tcg2Dxe.uni\r
+  FILE_GUID                      = FDFF263D-5F68-4591-87BA-B768F445A9AF\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = DriverEntry\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
+  Tcg2Dxe.c\r
+  MeasureBootPeCoff.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  CryptoPkg/CryptoPkg.dec\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  BaseLib\r
+  UefiBootServicesTableLib\r
+  HobLib\r
+  UefiDriverEntryPoint\r
+  UefiRuntimeServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  Tpm2CommandLib\r
+  PrintLib\r
+  UefiLib\r
+  Tpm2DeviceLib\r
+  HashLib\r
+  PerformanceLib\r
+  ReportStatusCodeLib\r
+  Tcg2PhysicalPresenceLib\r
+\r
+[Guids]\r
+  ## SOMETIMES_CONSUMES     ## SystemTable           # Smbios Table\r
+  ## SOMETIMES_CONSUMES     ## GUID                  # Handoff Table for measurement.\r
+  gEfiSmbiosTableGuid\r
+  \r
+  ## SOMETIMES_CONSUMES     ## Variable:L"SecureBoot"\r
+  ## SOMETIMES_CONSUMES     ## Variable:L"PK"\r
+  ## SOMETIMES_CONSUMES     ## Variable:L"KEK"\r
+  ## SOMETIMES_CONSUMES     ## Variable:L"BootXXXX"\r
+  gEfiGlobalVariableGuid\r
+\r
+  ## SOMETIMES_CONSUMES      ## Variable:L"db"\r
+  ## SOMETIMES_CONSUMES      ## Variable:L"dbx"\r
+  gEfiImageSecurityDatabaseGuid\r
+    \r
+  gTcgEventEntryHobGuid                              ## SOMETIMES_CONSUMES  ## HOB\r
+  gTpmErrorHobGuid                                   ## SOMETIMES_CONSUMES  ## HOB\r
+  gEfiEventExitBootServicesGuid                      ## CONSUMES            ## Event\r
+  gEventExitBootServicesFailedGuid                   ## SOMETIMES_CONSUMES  ## Event\r
+  gEfiTpmDeviceInstanceNoneGuid                      ## SOMETIMES_CONSUMES  ## GUID       # TPM device identifier\r
+  gEfiTpmDeviceInstanceTpm12Guid                     ## SOMETIMES_CONSUMES  ## GUID       # TPM device identifier\r
+\r
+  gTcgEvent2EntryHobGuid                             ## SOMETIMES_CONSUMES  ## HOB\r
+\r
+[Protocols]\r
+  gEfiTcg2ProtocolGuid                               ## PRODUCES\r
+  gEfiTcg2FinalEventsTableGuid                       ## PRODUCES\r
+  gEfiAcpiTableProtocolGuid                          ## NOTIFY\r
+  gEfiMpServiceProtocolGuid                          ## SOMETIMES_CONSUMES\r
+  gEfiVariableWriteArchProtocolGuid                  ## NOTIFY\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass                         ## SOMETIMES_CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdFirmwareDebuggerInitialized              ## SOMETIMES_CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid                          ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress                           ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId                        ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId                   ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision                  ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId                    ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision              ## SOMETIMES_CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeSubClassTpmDevice              ## SOMETIMES_CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap                  ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2NumberOfPCRBanks                     ## CONSUMES\r
+\r
+[Depex]\r
+  TRUE\r
+\r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+  Tcg2DxeExtra.uni\r
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.uni b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.uni
new file mode 100644 (file)
index 0000000..8fd8b2a
Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.uni differ
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2DxeExtra.uni b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2DxeExtra.uni
new file mode 100644 (file)
index 0000000..dbc5251
Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2DxeExtra.uni differ
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
new file mode 100644 (file)
index 0000000..ec94c24
--- /dev/null
@@ -0,0 +1,946 @@
+/** @file\r
+  Initialize TPM2 device and measure FVs before handing off control to DXE.\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 <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Ppi/FirmwareVolumeInfo.h>\r
+#include <Ppi/FirmwareVolumeInfo2.h>\r
+#include <Ppi/LockPhysicalPresence.h>\r
+#include <Ppi/TpmInitialized.h>\r
+#include <Ppi/FirmwareVolume.h>\r
+#include <Ppi/EndOfPeiPhase.h>\r
+#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>\r
+\r
+#include <Guid/TcgEventHob.h>\r
+#include <Guid/MeasuredFvHob.h>\r
+#include <Guid/TpmInstance.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/HashLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+\r
+#define PERF_ID_TCG2_PEI  0x3080\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
+BOOLEAN                 mImageInMemory  = FALSE;\r
+EFI_PEI_FILE_HANDLE     mFileHandle;\r
+\r
+EFI_PEI_PPI_DESCRIPTOR  mTpmInitializedPpiList = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gPeiTpmInitializedPpiGuid,\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
+EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredBaseFvInfo;\r
+UINT32 mMeasuredBaseFvIndex = 0;\r
+\r
+EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;\r
+UINT32 mMeasuredChildFvIndex = 0;\r
+\r
+/**\r
+  Measure and record the Firmware Volum Information once FvInfoPPI install.\r
+\r
+  @param[in] PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+  @param[in] NotifyDescriptor  Address of the notification descriptor data structure.\r
+  @param[in] Ppi               Address of the PPI that was installed.\r
+\r
+  @retval EFI_SUCCESS          The FV Info is measured and recorded to TPM.\r
+  @return Others               Fail to measure FV.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FirmwareVolmeInfoPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES              **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
+  IN VOID                          *Ppi\r
+  );\r
+\r
+/**\r
+  Record all measured Firmware Volum Information into a Guid Hob\r
+\r
+  @param[in] PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+  @param[in] NotifyDescriptor  Address of the notification descriptor data structure.\r
+  @param[in] Ppi               Address of the PPI that was installed.\r
+\r
+  @retval EFI_SUCCESS          The FV Info is measured and recorded to TPM.\r
+  @return Others               Fail to measure FV.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndofPeiSignalNotifyCallBack (\r
+  IN EFI_PEI_SERVICES              **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
+  IN VOID                          *Ppi\r
+  );\r
+\r
+EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
+    &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
+    FirmwareVolmeInfoPpiNotifyCallback \r
+  },\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
+    &gEfiPeiFirmwareVolumeInfo2PpiGuid,\r
+    FirmwareVolmeInfoPpiNotifyCallback \r
+  },\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiEndOfPeiSignalPpiGuid,\r
+    EndofPeiSignalNotifyCallBack\r
+  }\r
+};\r
+\r
+EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;\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
+  Record all measured Firmware Volum Information into a Guid Hob\r
+  Guid Hob payload layout is \r
+\r
+     UINT32 *************************** FIRMWARE_BLOB number\r
+     EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array\r
+\r
+  @param[in] PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+  @param[in] NotifyDescriptor  Address of the notification descriptor data structure.\r
+  @param[in] Ppi               Address of the PPI that was installed.\r
+\r
+  @retval EFI_SUCCESS          The FV Info is measured and recorded to TPM.\r
+  @return Others               Fail to measure FV.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndofPeiSignalNotifyCallBack (\r
+  IN EFI_PEI_SERVICES              **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
+  IN VOID                          *Ppi\r
+  )\r
+{  \r
+  MEASURED_HOB_DATA *MeasuredHobData;\r
+\r
+  MeasuredHobData = NULL;\r
+\r
+  //\r
+  // Create a Guid hob to save all measured Fv \r
+  //\r
+  MeasuredHobData = BuildGuidHob(\r
+                      &gMeasuredFvHobGuid,\r
+                      sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)\r
+                      );\r
+\r
+  if (MeasuredHobData != NULL){\r
+    //\r
+    // Save measured FV info enty number\r
+    //\r
+    MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;\r
+\r
+    //\r
+    // Save measured base Fv info\r
+    //\r
+    CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));\r
+\r
+    //\r
+    // Save measured child Fv info\r
+    //\r
+    CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));\r
+  }\r
+\r
+  return EFI_SUCCESS;\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 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
+  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
+  UINT32  ActivePcrBanks;\r
+\r
+  ActivePcrBanks = PcdGet32 (PcdTpm2HashMask);\r
+  switch (HashAlg) {\r
+  case TPM_ALG_SHA1:\r
+    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  case TPM_ALG_SHA256:\r
+    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  case TPM_ALG_SHA384:\r
+    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  case TPM_ALG_SHA512:\r
+    if ((ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
+      return TRUE;\r
+    }\r
+    break;\r
+  case TPM_ALG_SM3_256:\r
+    if ((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
+  Set Tpm2HashMask PCD value accroding to TPM2 PCR bank.\r
+**/\r
+VOID\r
+SetTpm2HashMask (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+  UINT32               ActivePcrBanks;\r
+  TPML_PCR_SELECTION   Pcrs;\r
+  UINTN                Index;\r
+\r
+  DEBUG ((EFI_D_ERROR, "SetTpm2HashMask!\n"));\r
+\r
+  Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));\r
+    ActivePcrBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
+  } else {\r
+    DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));\r
+    ActivePcrBanks = 0;\r
+    for (Index = 0; Index < Pcrs.count; Index++) {\r
+      DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));\r
+      switch (Pcrs.pcrSelections[Index].hash) {\r
+      case TPM_ALG_SHA1:\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
+        }        \r
+        break;\r
+      case TPM_ALG_SHA256:\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
+        }\r
+        break;\r
+      case TPM_ALG_SHA384:\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
+        }\r
+        break;\r
+      case TPM_ALG_SHA512:\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
+        }\r
+        break;\r
+      case TPM_ALG_SM3_256:\r
+        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
+          ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
+        }\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  PcdSet32 (PcdTpm2HashMask, ActivePcrBanks);\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
+LogHashEvent (\r
+  IN TPML_DIGEST_VALUES             *DigestList,\r
+  IN OUT  TCG_PCR_EVENT_HDR         *NewEventHdr,\r
+  IN      UINT8                     *NewEventData\r
+  )\r
+{\r
+  VOID                              *HobData;\r
+  EFI_STATUS                        Status;\r
+  UINTN                             Index;\r
+  EFI_STATUS                        RetStatus;\r
+  UINT32                            SupportedEventLogs;\r
+  TCG_PCR_EVENT2                    *TcgPcrEvent2;\r
+  UINT8                             *DigestBuffer;\r
+\r
+  SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;\r
+\r
+  RetStatus = EFI_SUCCESS;\r
+  for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
+    if ((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
+          HobData = BuildGuidHob (\r
+                     &gTcgEventEntryHobGuid,\r
+                     sizeof (*NewEventHdr) + NewEventHdr->EventSize\r
+                     );\r
+          if (HobData == NULL) {\r
+            RetStatus = EFI_OUT_OF_RESOURCES;\r
+            break;\r
+          }\r
+\r
+          CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));\r
+          HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));\r
+          CopyMem (HobData, NewEventData, NewEventHdr->EventSize);\r
+        }\r
+        break;\r
+      case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
+        HobData = BuildGuidHob (\r
+                   &gTcgEvent2EntryHobGuid,\r
+                   sizeof(TcgPcrEvent2->PCRIndex) + sizeof(TcgPcrEvent2->EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2->EventSize) + NewEventHdr->EventSize\r
+                   );\r
+        if (HobData == NULL) {\r
+          RetStatus = EFI_OUT_OF_RESOURCES;\r
+          break;\r
+        }\r
+\r
+        TcgPcrEvent2 = HobData;\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(TcgPcrEvent2->EventSize));\r
+        DigestBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize);\r
+        CopyMem (DigestBuffer, NewEventData, NewEventHdr->EventSize);\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 build a GUIDed HOB recording the event which will be passed to the DXE phase and\r
+  added into 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]      NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.  \r
+  @param[in]      NewEventData  Pointer to the new event data.  \r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+HashLogExtendEvent (\r
+  IN      UINT64                    Flags,\r
+  IN      UINT8                     *HashData,\r
+  IN      UINTN                     HashDataLen,\r
+  IN      TCG_PCR_EVENT_HDR         *NewEventHdr,\r
+  IN      UINT8                     *NewEventData\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TPML_DIGEST_VALUES                DigestList;\r
+\r
+  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  Status = HashAndExtend (\r
+             NewEventHdr->PCRIndex,\r
+             HashData,\r
+             HashDataLen,\r
+             &DigestList\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
+      Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
+    }\r
+  }\r
+  \r
+  if (Status == EFI_DEVICE_ERROR) {\r
+    DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));\r
+    BuildGuidHob (&gTpmErrorHobGuid,0);\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Measure CRTM version.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureCRTMVersion (\r
+  VOID\r
+  )\r
+{\r
+  TCG_PCR_EVENT_HDR                 TcgEventHdr;\r
+\r
+  //\r
+  // Use FirmwareVersion string to represent CRTM version.\r
+  // OEMs should get real CRTM version string and measure it.\r
+  //\r
+\r
+  TcgEventHdr.PCRIndex  = 0;\r
+  TcgEventHdr.EventType = EV_S_CRTM_VERSION;\r
+  TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));\r
+\r
+  return HashLogExtendEvent (\r
+           0,\r
+           (UINT8*)PcdGetPtr (PcdFirmwareVersionString),\r
+           TcgEventHdr.EventSize,\r
+           &TcgEventHdr,\r
+           (UINT8*)PcdGetPtr (PcdFirmwareVersionString)\r
+           );\r
+}\r
+\r
+/**\r
+  Measure FV image. \r
+  Add it into the measured FV list after the FV is measured successfully. \r
+\r
+  @param[in]  FvBase            Base address of FV image.\r
+  @param[in]  FvLength          Length of FV image.\r
+\r
+  @retval EFI_SUCCESS           Fv image is measured successfully \r
+                                or it has been already measured.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureFvImage (\r
+  IN EFI_PHYSICAL_ADDRESS           FvBase,\r
+  IN UINT64                         FvLength\r
+  )\r
+{\r
+  UINT32                            Index;\r
+  EFI_STATUS                        Status;\r
+  EFI_PLATFORM_FIRMWARE_BLOB        FvBlob;\r
+  TCG_PCR_EVENT_HDR                 TcgEventHdr;\r
+\r
+  //\r
+  // Check if it is in Excluded FV list\r
+  //\r
+  if (mMeasurementExcludedFvPpi != NULL) {\r
+    for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {\r
+      if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {\r
+        DEBUG ((DEBUG_INFO, "The FV which is excluded by Tcg2Pei starts at: 0x%x\n", FvBase));\r
+        DEBUG ((DEBUG_INFO, "The FV which is excluded by Tcg2Pei has the size: 0x%x\n", FvLength));\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Check whether FV is in the measured FV list.\r
+  //\r
+  for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {\r
+    if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Measure and record the FV to the TPM\r
+  //\r
+  FvBlob.BlobBase   = FvBase;\r
+  FvBlob.BlobLength = FvLength;\r
+\r
+  DEBUG ((DEBUG_INFO, "The FV which is measured by Tcg2Pei starts at: 0x%x\n", FvBlob.BlobBase));\r
+  DEBUG ((DEBUG_INFO, "The FV which is measured by Tcg2Pei has the size: 0x%x\n", FvBlob.BlobLength));\r
+\r
+  TcgEventHdr.PCRIndex = 0;\r
+  TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
+  TcgEventHdr.EventSize = sizeof (FvBlob);\r
+\r
+  Status = HashLogExtendEvent (\r
+             0,\r
+             (UINT8*) (UINTN) FvBlob.BlobBase,\r
+             (UINTN) FvBlob.BlobLength,\r
+             &TcgEventHdr,\r
+             (UINT8*) &FvBlob\r
+             );\r
+\r
+  //\r
+  // Add new FV into the measured FV list.\r
+  //\r
+  ASSERT (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
+  if (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
+    mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase   = FvBase;\r
+    mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;\r
+    mMeasuredBaseFvIndex++;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Measure main BIOS.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+MeasureMainBios (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINT32                            FvInstances;\r
+  EFI_PEI_FV_HANDLE                 VolumeHandle;\r
+  EFI_FV_INFO                       VolumeInfo;\r
+  EFI_PEI_FIRMWARE_VOLUME_PPI       *FvPpi;\r
+\r
+  PERF_START_EX (mFileHandle, "EventRec", "Tcg2Pei", 0, PERF_ID_TCG2_PEI);\r
+  FvInstances    = 0;\r
+  while (TRUE) {\r
+    //\r
+    // Traverse all firmware volume instances of Static Core Root of Trust for Measurement\r
+    // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special\r
+    // platform for special CRTM TPM measuring.\r
+    //\r
+    Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+  \r
+    //\r
+    // Measure and record the firmware volume that is dispatched by PeiCore\r
+    //\r
+    Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);\r
+    ASSERT_EFI_ERROR (Status);\r
+    //\r
+    // Locate the corresponding FV_PPI according to founded FV's format guid\r
+    //\r
+    Status = PeiServicesLocatePpi (\r
+               &VolumeInfo.FvFormat, \r
+               0, \r
+               NULL,\r
+               (VOID**)&FvPpi\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);\r
+    }\r
+\r
+    FvInstances++;\r
+  }\r
+  PERF_END_EX (mFileHandle, "EventRec", "Tcg2Pei", 0, PERF_ID_TCG2_PEI + 1);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Measure and record the Firmware Volum Information once FvInfoPPI install.\r
+\r
+  @param[in] PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+  @param[in] NotifyDescriptor  Address of the notification descriptor data structure.\r
+  @param[in] Ppi               Address of the PPI that was installed.\r
+\r
+  @retval EFI_SUCCESS          The FV Info is measured and recorded to TPM.\r
+  @return Others               Fail to measure FV.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FirmwareVolmeInfoPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES               **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR      *NotifyDescriptor,\r
+  IN VOID                           *Ppi\r
+  )\r
+{\r
+  EFI_PEI_FIRMWARE_VOLUME_INFO_PPI  *Fv;\r
+  EFI_STATUS                        Status;\r
+  EFI_PEI_FIRMWARE_VOLUME_PPI       *FvPpi;\r
+  UINTN                             Index;\r
+\r
+  Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;\r
+\r
+  //\r
+  // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &Fv->FvFormat, \r
+             0, \r
+             NULL,\r
+             (VOID**)&FvPpi\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+  \r
+  //\r
+  // This is an FV from an FFS file, and the parent FV must have already been measured,\r
+  // No need to measure twice, so just record the FV and return\r
+  //\r
+  if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {\r
+    \r
+    ASSERT (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
+    if (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
+      //\r
+      // Check whether FV is in the measured child FV list.\r
+      //\r
+      for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {\r
+        if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) {\r
+          return EFI_SUCCESS;\r
+        }\r
+      }\r
+      mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase   = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;\r
+      mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;\r
+      mMeasuredChildFvIndex++;\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);\r
+}\r
+\r
+/**\r
+  Do measurement after memory is ready.\r
+\r
+  @param[in]      PeiServices   Describes the list of possible PEI Services.\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+PeimEntryMP (\r
+  IN      EFI_PEI_SERVICES          **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+\r
+  Status = PeiServicesLocatePpi (\r
+               &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, \r
+               0, \r
+               NULL,\r
+               (VOID**)&mMeasurementExcludedFvPpi\r
+               );\r
+  // Do not check status, because it is optional\r
+\r
+  mMeasuredBaseFvInfo  = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
+  ASSERT (mMeasuredBaseFvInfo != NULL);\r
+  mMeasuredChildFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
+  ASSERT (mMeasuredChildFvInfo != NULL);\r
+  \r
+  if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) {\r
+    Status = MeasureCRTMVersion ();\r
+  }\r
+\r
+  Status = MeasureMainBios ();\r
+\r
+  //\r
+  // Post callbacks:\r
+  // for the FvInfoPpi services to measure and record\r
+  // the additional Fvs to TPM\r
+  //\r
+  Status = PeiServicesNotifyPpi (&mNotifyList[0]);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Entry point of this module.\r
+\r
+  @param[in] FileHandle   Handle of the file being invoked.\r
+  @param[in] PeiServices  Describes the list of possible PEI Services.\r
+\r
+  @return Status.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeimEntryMA (\r
+  IN       EFI_PEI_FILE_HANDLE      FileHandle,\r
+  IN CONST EFI_PEI_SERVICES         **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_STATUS                        Status2;\r
+  EFI_BOOT_MODE                     BootMode;\r
+\r
+  if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
+      CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
+    DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
+    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  Status = PeiServicesGetBootMode (&BootMode);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // In S3 path, skip shadow logic. no measurement is required\r
+  //\r
+  if (BootMode != BOOT_ON_S3_RESUME) {\r
+    Status = (**PeiServices).RegisterForShadow(FileHandle);\r
+    if (Status == EFI_ALREADY_STARTED) {\r
+      mImageInMemory = TRUE;\r
+      mFileHandle = FileHandle;\r
+    } else if (Status == EFI_NOT_FOUND) {\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+  }\r
+\r
+  if (!mImageInMemory) {\r
+    //\r
+    // Initialize TPM device\r
+    //\r
+    Status = Tpm2RequestUseTpm ();\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "TPM2 not detected!\n"));\r
+      goto Done;\r
+    }\r
+\r
+    if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {\r
+      if (BootMode == BOOT_ON_S3_RESUME) {\r
+        Status = Tpm2Startup (TPM_SU_STATE);\r
+        if (EFI_ERROR (Status) ) {\r
+          Status = Tpm2Startup (TPM_SU_CLEAR);\r
+        }\r
+      } else {\r
+        Status = Tpm2Startup (TPM_SU_CLEAR);\r
+      }\r
+      if (EFI_ERROR (Status) ) {\r
+        goto Done;\r
+      }\r
+    }\r
+    \r
+    //\r
+    // Update Tpm2HashMask according to PCR bank.\r
+    //\r
+    SetTpm2HashMask ();\r
+    //\r
+    // TpmSelfTest is optional on S3 path, skip it to save S3 time\r
+    //\r
+    if (BootMode != BOOT_ON_S3_RESUME) {\r
+      if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) {\r
+        Status = Tpm2SelfTest (NO);\r
+        if (EFI_ERROR (Status)) {\r
+          goto Done;\r
+        }\r
+      }\r
+    }\r
+\r
+    //\r
+    // Only intall TpmInitializedPpi on success\r
+    //\r
+    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  if (mImageInMemory) {\r
+    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);\r
+    return Status;\r
+  }\r
+\r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));\r
+    BuildGuidHob (&gTpmErrorHobGuid,0);\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
+      );\r
+  }\r
+  //\r
+  // Always intall TpmInitializationDonePpi no matter success or fail.\r
+  // Other driver can know TPM initialization state by TpmInitializedPpi.\r
+  //\r
+  Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);\r
+  ASSERT_EFI_ERROR (Status2);\r
+\r
+  return Status;\r
+}\r
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
new file mode 100644 (file)
index 0000000..29ca3aa
--- /dev/null
@@ -0,0 +1,89 @@
+## @file\r
+#  Initializes TPM 2.0 device and measure FVs in PEI phase\r
+#\r
+#  This module will initialize TPM device, measure reported FVs and BIOS version.\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                      = Tcg2Pei\r
+  MODULE_UNI_FILE                = Tcg2Pei.uni\r
+  FILE_GUID                      = A0C98B77-CBA5-4BB8-993B-4AF6CE33ECE4\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = PeimEntryMA\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
+# [BootMode]\r
+#   S3_RESUME                 ## SOMETIMES_CONSUMES\r
+#\r
+\r
+[Sources]\r
+  Tcg2Pei.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  HobLib\r
+  PeimEntryPoint\r
+  PeiServicesLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  Tpm2CommandLib\r
+  PeiServicesTablePointerLib\r
+  Tpm2DeviceLib\r
+  HashLib\r
+  PerformanceLib\r
+  MemoryAllocationLib\r
+  ReportStatusCodeLib\r
+  Tcg2PhysicalPresenceLib\r
+\r
+[Guids]\r
+  gTcgEventEntryHobGuid                                                ## PRODUCES               ## HOB\r
+  gTpmErrorHobGuid                                                     ## SOMETIMES_PRODUCES     ## HOB\r
+  gMeasuredFvHobGuid                                                   ## PRODUCES               ## HOB\r
+  gTcgEvent2EntryHobGuid                                               ## PRODUCES               ## HOB\r
+  gEfiTpmDeviceInstanceNoneGuid                                        ## SOMETIMES_PRODUCES     ## GUID       # TPM device identifier\r
+  gEfiTpmDeviceInstanceTpm12Guid                                       ## SOMETIMES_PRODUCES     ## GUID       # TPM device identifier\r
+\r
+[Ppis]\r
+  gEfiPeiFirmwareVolumeInfoPpiGuid                                     ## SOMETIMES_CONSUMES     ## NOTIFY\r
+  gEfiPeiFirmwareVolumeInfo2PpiGuid                                    ## SOMETIMES_CONSUMES     ## NOTIFY\r
+  gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid                  ## SOMETIMES_CONSUMES\r
+  gPeiTpmInitializedPpiGuid                                            ## SOMETIMES_PRODUCES\r
+  gPeiTpmInitializationDonePpiGuid                                     ## PRODUCES\r
+  gEfiEndOfPeiSignalPpiGuid                                            ## SOMETIMES_CONSUMES     ## NOTIFY\r
+\r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString              ## SOMETIMES_CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid                     ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy            ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy                  ## SOMETIMES_CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy                     ## CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported              ## CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeSubClassTpmDevice         ## SOMETIMES_CONSUMES\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask                        ## CONSUMES\r
+\r
+[Depex]\r
+  gEfiPeiMasterBootModePpiGuid AND\r
+  gEfiPeiReadOnlyVariable2PpiGuid AND\r
+  gEfiTpmDeviceSelectedGuid\r
+\r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+  Tcg2PeiExtra.uni\r
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.uni b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.uni
new file mode 100644 (file)
index 0000000..5a226bc
Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.uni differ
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2PeiExtra.uni b/SecurityPkg/Tcg/Tcg2Pei/Tcg2PeiExtra.uni
new file mode 100644 (file)
index 0000000..426fc77
Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Pei/Tcg2PeiExtra.uni differ
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c
new file mode 100644 (file)
index 0000000..503cc18
--- /dev/null
@@ -0,0 +1,397 @@
+/** @file\r
+  It updates TPM2 items in ACPI table and registers SMI2 callback\r
+  functions for Tcg2 physical presence, ClearMemory, and sample\r
+  for dTPM StartMethod.\r
+\r
+  Caution: This module requires additional review when modified.\r
+  This driver will have external input - variable and ACPINvs data in SMM mode.\r
+  This external input must be validated carefully to avoid security issue.\r
+\r
+  PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.\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 "Tcg2Smm.h"\r
+\r
+EFI_TPM2_ACPI_TABLE  mTpm2AcpiTemplate = {\r
+  {\r
+    EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE,\r
+    sizeof (mTpm2AcpiTemplate),\r
+    EFI_TPM2_ACPI_TABLE_REVISION,\r
+    //\r
+    // Compiler initializes the remaining bytes to 0\r
+    // These fields should be filled in in production\r
+    //\r
+  },\r
+  0, // Flags\r
+  0, // Control Area\r
+  EFI_TPM2_ACPI_TABLE_START_METHOD_TIS, // StartMethod\r
+};\r
+\r
+EFI_SMM_VARIABLE_PROTOCOL  *mSmmVariable;\r
+TCG_NVS                    *mTcgNvs;\r
+\r
+/**\r
+  Software SMI callback for TPM physical presence which is called from ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  Variable and ACPINvs are external input, so this function will validate\r
+  its data structure to be valid value.\r
+\r
+  @param[in]      DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().\r
+  @param[in]      Context         Points to an optional handler context which was specified when the\r
+                                  handler was registered.\r
+  @param[in, out] CommBuffer      A pointer to a collection of data in memory that will\r
+                                  be conveyed from a non-SMM environment into an SMM environment.\r
+  @param[in, out] CommBufferSize  The size of the CommBuffer.\r
+\r
+  @retval EFI_SUCCESS             The interrupt was handled successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PhysicalPresenceCallback (\r
+  IN EFI_HANDLE                  DispatchHandle,\r
+  IN CONST VOID                  *Context,\r
+  IN OUT VOID                    *CommBuffer,\r
+  IN OUT UINTN                   *CommBufferSize\r
+  )\r
+{\r
+  UINT32                MostRecentRequest;\r
+  UINT32                Response;\r
+\r
+  if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {\r
+    mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
+                                             &MostRecentRequest,\r
+                                             &Response\r
+                                             );\r
+    mTcgNvs->PhysicalPresence.LastRequest = MostRecentRequest;\r
+    mTcgNvs->PhysicalPresence.Response = Response;\r
+    return EFI_SUCCESS;\r
+  } else if ((mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS) \r
+          || (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2)) {\r
+    mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
+                                             mTcgNvs->PhysicalPresence.Request,\r
+                                             mTcgNvs->PhysicalPresence.RequestParameter\r
+                                             );\r
+  } else if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {\r
+    mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (mTcgNvs->PhysicalPresence.Request);\r
+  } \r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Software SMI callback for MemoryClear which is called from ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  Variable and ACPINvs are external input, so this function will validate\r
+  its data structure to be valid value.\r
+\r
+  @param[in]      DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().\r
+  @param[in]      Context         Points to an optional handler context which was specified when the\r
+                                  handler was registered.\r
+  @param[in, out] CommBuffer      A pointer to a collection of data in memory that will\r
+                                  be conveyed from a non-SMM environment into an SMM environment.\r
+  @param[in, out] CommBufferSize  The size of the CommBuffer.\r
+\r
+  @retval EFI_SUCCESS             The interrupt was handled successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MemoryClearCallback (\r
+  IN EFI_HANDLE                  DispatchHandle,\r
+  IN CONST VOID                  *Context,\r
+  IN OUT VOID                    *CommBuffer,\r
+  IN OUT UINTN                   *CommBufferSize\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  UINTN                          DataSize;\r
+  UINT8                          MorControl;\r
+\r
+  mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS;\r
+  if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) {\r
+    MorControl = (UINT8) mTcgNvs->MemoryClear.Request;\r
+  } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) {\r
+    DataSize = sizeof (UINT8);\r
+    Status = mSmmVariable->SmmGetVariable (\r
+                             MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
+                             &gEfiMemoryOverwriteControlDataGuid,\r
+                             NULL,\r
+                             &DataSize,\r
+                             &MorControl\r
+                             );\r
+    if (EFI_ERROR (Status)) {\r
+      mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
+      DEBUG ((EFI_D_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", Status));\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;\r
+  }\r
+\r
+  DataSize = sizeof (UINT8);\r
+  Status = mSmmVariable->SmmSetVariable (\r
+                           MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
+                           &gEfiMemoryOverwriteControlDataGuid,\r
+                           EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                           DataSize,\r
+                           &MorControl\r
+                           );\r
+  if (EFI_ERROR (Status)) { \r
+    mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
+    DEBUG ((EFI_D_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status));\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Find the operation region in TCG ACPI table by given Name and Size,\r
+  and initialize it if the region is found.\r
+\r
+  @param[in, out] Table          The TPM item in ACPI table.\r
+  @param[in]      Name           The name string to find in TPM table.\r
+  @param[in]      Size           The size of the region to find.\r
+\r
+  @return                        The allocated address for the found region.\r
+\r
+**/\r
+VOID *\r
+AssignOpRegion (\r
+  EFI_ACPI_DESCRIPTION_HEADER    *Table,\r
+  UINT32                         Name,\r
+  UINT16                         Size\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  AML_OP_REGION_32_8             *OpRegion;\r
+  EFI_PHYSICAL_ADDRESS           MemoryAddress;\r
+\r
+  MemoryAddress = SIZE_4GB - 1;\r
+\r
+  //\r
+  // Patch some pointers for the ASL code before loading the SSDT.\r
+  //\r
+  for (OpRegion  = (AML_OP_REGION_32_8 *) (Table + 1);\r
+       OpRegion <= (AML_OP_REGION_32_8 *) ((UINT8 *) Table + Table->Length);\r
+       OpRegion  = (AML_OP_REGION_32_8 *) ((UINT8 *) OpRegion + 1)) {\r
+    if ((OpRegion->OpRegionOp  == AML_EXT_REGION_OP) && \r
+        (OpRegion->NameString  == Name) &&\r
+        (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&\r
+        (OpRegion->BytePrefix  == AML_BYTE_PREFIX)) {\r
+\r
+      Status = gBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);\r
+      ASSERT_EFI_ERROR (Status);\r
+      ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);\r
+      OpRegion->RegionOffset = (UINT32) (UINTN) MemoryAddress;\r
+      OpRegion->RegionLen    = (UINT8) Size;\r
+      break;\r
+    }\r
+  }\r
+\r
+  return (VOID *) (UINTN) MemoryAddress;\r
+}\r
+\r
+/**\r
+  Initialize and publish TPM items in ACPI table.\r
+\r
+  @retval   EFI_SUCCESS     The TCG ACPI table is published successfully.\r
+  @retval   Others          The TCG ACPI table is not published.\r
+\r
+**/\r
+EFI_STATUS\r
+PublishAcpiTable (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;\r
+  UINTN                          TableKey;\r
+  EFI_ACPI_DESCRIPTION_HEADER    *Table;\r
+  UINTN                          TableSize;\r
+\r
+  Status = GetSectionFromFv (\r
+             &gEfiCallerIdGuid,\r
+             EFI_SECTION_RAW,\r
+             0,\r
+             (VOID **) &Table,\r
+             &TableSize\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  //\r
+  // Measure to PCR[0] with event EV_POST_CODE ACPI DATA\r
+  //\r
+  TpmMeasureAndLogData(\r
+    0,\r
+    EV_POST_CODE,\r
+    EV_POSTCODE_INFO_ACPI_DATA,\r
+    ACPI_DATA_LEN,\r
+    Table,\r
+    TableSize\r
+    );\r
+\r
+\r
+  ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l'));\r
+  CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) );\r
+  mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS));\r
+  ASSERT (mTcgNvs != NULL);\r
+\r
+  //\r
+  // Publish the TPM ACPI table\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  TableKey = 0;\r
+  Status = AcpiTable->InstallAcpiTable (\r
+                        AcpiTable,\r
+                        Table,\r
+                        TableSize,\r
+                        &TableKey\r
+                        );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Publish TPM2 ACPI table\r
+\r
+  @retval   EFI_SUCCESS     The TPM2 ACPI table is published successfully.\r
+  @retval   Others          The TPM2 ACPI table is not published.\r
+\r
+**/\r
+EFI_STATUS\r
+PublishTpm2 (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;\r
+  UINTN                          TableKey;\r
+  UINT64                         OemTableId;\r
+\r
+  //\r
+  // Measure to PCR[0] with event EV_POST_CODE ACPI DATA\r
+  //\r
+  TpmMeasureAndLogData(\r
+    0,\r
+    EV_POST_CODE,\r
+    EV_POSTCODE_INFO_ACPI_DATA,\r
+    ACPI_DATA_LEN,\r
+    &mTpm2AcpiTemplate,\r
+    sizeof(mTpm2AcpiTemplate)\r
+    );\r
+\r
+  CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId));\r
+  OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
+  CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
+  mTpm2AcpiTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);\r
+  mTpm2AcpiTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);\r
+  mTpm2AcpiTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
+\r
+  //\r
+  // Construct ACPI table\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = AcpiTable->InstallAcpiTable (\r
+                        AcpiTable,\r
+                        &mTpm2AcpiTemplate,\r
+                        sizeof(mTpm2AcpiTemplate),\r
+                        &TableKey\r
+                        );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  The driver's entry point.\r
+\r
+  It install callbacks for TPM physical presence and MemoryClear, and locate \r
+  SMM variable to be used in the callback function.\r
+\r
+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable  A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS     The entry point is executed successfully.\r
+  @retval Others          Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeTcgSmm (\r
+  IN EFI_HANDLE                  ImageHandle,\r
+  IN EFI_SYSTEM_TABLE            *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_SMM_SW_DISPATCH2_PROTOCOL  *SwDispatch;\r
+  EFI_SMM_SW_REGISTER_CONTEXT    SwContext;\r
+  EFI_HANDLE                     SwHandle;\r
+\r
+  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid)){\r
+    DEBUG ((EFI_D_ERROR, "No TPM2 DTPM instance required!\n"));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PublishAcpiTable ();\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Get the Sw dispatch protocol and register SMI callback functions.\r
+  //\r
+  Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID**)&SwDispatch);\r
+  ASSERT_EFI_ERROR (Status);\r
+  SwContext.SwSmiInputValue = (UINTN) -1;\r
+  Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);\r
+  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;\r
+\r
+  SwContext.SwSmiInputValue = (UINTN) -1;\r
+  Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);\r
+  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;\r
+  \r
+  //\r
+  // Locate SmmVariableProtocol.\r
+  //\r
+  Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mSmmVariable);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Set TPM2 ACPI table\r
+  //\r
+  Status = PublishTpm2 ();\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h
new file mode 100644 (file)
index 0000000..ebd71ed
--- /dev/null
@@ -0,0 +1,87 @@
+/** @file\r
+  The header file for Tcg2 SMM driver.\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_SMM_H__\r
+#define __TCG2_SMM_H__\r
+\r
+#include <PiDxe.h>\r
+#include <IndustryStandard/Acpi.h>\r
+#include <IndustryStandard/Tpm2Acpi.h>\r
+\r
+#include <Guid/MemoryOverwriteControl.h>\r
+#include <Guid/TpmInstance.h>\r
+\r
+#include <Protocol/SmmSwDispatch2.h>\r
+#include <Protocol/AcpiTable.h>\r
+#include <Protocol/SmmVariable.h>\r
+#include <Protocol/Tcg2Protocol.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/SmmServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DxeServicesLib.h>\r
+#include <Library/TpmMeasurementLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+\r
+#pragma pack(1)\r
+typedef struct {\r
+  UINT8                  SoftwareSmi;\r
+  UINT32                 Parameter;\r
+  UINT32                 Response;\r
+  UINT32                 Request;\r
+  UINT32                 RequestParameter;\r
+  UINT32                 LastRequest;\r
+  UINT32                 ReturnCode;\r
+} PHYSICAL_PRESENCE_NVS;\r
+\r
+typedef struct {\r
+  UINT8                  SoftwareSmi;\r
+  UINT32                 Parameter;\r
+  UINT32                 Request;\r
+  UINT32                 ReturnCode;\r
+} MEMORY_CLEAR_NVS;\r
+\r
+typedef struct {\r
+  PHYSICAL_PRESENCE_NVS  PhysicalPresence;\r
+  MEMORY_CLEAR_NVS       MemoryClear;\r
+} TCG_NVS;\r
+\r
+typedef struct {\r
+  UINT8                  OpRegionOp;\r
+  UINT32                 NameString;\r
+  UINT8                  RegionSpace;\r
+  UINT8                  DWordPrefix;\r
+  UINT32                 RegionOffset;\r
+  UINT8                  BytePrefix;\r
+  UINT8                  RegionLen;\r
+} AML_OP_REGION_32_8;\r
+#pragma pack()\r
+\r
+//\r
+// The definition for TCG MOR\r
+//\r
+#define ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE                   1\r
+#define ACPI_FUNCTION_PTS_CLEAR_MOR_BIT                            2\r
+\r
+//\r
+// The return code for Memory Clear Interface Functions\r
+//\r
+#define MOR_REQUEST_SUCCESS                                        0\r
+#define MOR_REQUEST_GENERAL_FAILURE                                1\r
+\r
+#endif  // __TCG_SMM_H__\r
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.inf
new file mode 100644 (file)
index 0000000..ef30ec7
--- /dev/null
@@ -0,0 +1,80 @@
+## @file\r
+#  Provides ACPI metholds for TPM 2.0 support\r
+#\r
+#  This driver implements TPM 2.0 definition block in ACPI table and \r
+#  registers SMI callback functions for Tcg2 physical presence and \r
+#  MemoryClear to handle the requests from ACPI method.\r
+#\r
+#  Caution: This module requires additional review when modified.\r
+#  This driver will have external input - variable and ACPINvs data in SMM mode.\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                      = Tcg2Smm\r
+  MODULE_UNI_FILE                = Tcg2Smm.uni\r
+  FILE_GUID                      = 44A20657-10B8-4049-A148-ACD8812AF257\r
+  MODULE_TYPE                    = DXE_SMM_DRIVER\r
+  PI_SPECIFICATION_VERSION       = 0x0001000A\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = InitializeTcgSmm\r
+\r
+[Sources]\r
+  Tcg2Smm.h\r
+  Tcg2Smm.c\r
+  Tpm.asl\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  UefiDriverEntryPoint\r
+  SmmServicesTableLib\r
+  UefiBootServicesTableLib\r
+  DebugLib\r
+  DxeServicesLib\r
+  TpmMeasurementLib\r
+  Tpm2DeviceLib\r
+  Tcg2PhysicalPresenceLib\r
+\r
+[Guids]\r
+  ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControl"\r
+  ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl"  \r
+  gEfiMemoryOverwriteControlDataGuid\r
+  \r
+  gEfiTpmDeviceInstanceTpm20DtpmGuid                            ## PRODUCES           ## GUID       # TPM device identifier\r
+\r
+[Protocols]\r
+  gEfiSmmSwDispatch2ProtocolGuid                                ## CONSUMES\r
+  gEfiSmmVariableProtocolGuid                                   ## CONSUMES\r
+  gEfiAcpiTableProtocolGuid                                     ## CONSUMES\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid              ## CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId            ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId       ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision      ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId        ## SOMETIMES_CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision  ## SOMETIMES_CONSUMES\r
+\r
+[Depex]\r
+  gEfiAcpiTableProtocolGuid AND\r
+  gEfiSmmSwDispatch2ProtocolGuid AND\r
+  gEfiSmmVariableProtocolGuid\r
+\r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+  Tcg2SmmExtra.uni\r
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.uni b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.uni
new file mode 100644 (file)
index 0000000..3d9dcac
Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.uni differ
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2SmmExtra.uni b/SecurityPkg/Tcg/Tcg2Smm/Tcg2SmmExtra.uni
new file mode 100644 (file)
index 0000000..173c4eb
Binary files /dev/null and b/SecurityPkg/Tcg/Tcg2Smm/Tcg2SmmExtra.uni differ
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl b/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl
new file mode 100644 (file)
index 0000000..80dfb3b
--- /dev/null
@@ -0,0 +1,359 @@
+/** @file\r
+  The TPM2 definition block in ACPI table for TCG2 physical presence  \r
+  and MemoryClear.\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
+DefinitionBlock (\r
+  "Tpm.aml",\r
+  "SSDT",\r
+  2,\r
+  "INTEL ",\r
+  "Tpm2Tabl",\r
+  0x1000\r
+  )\r
+{\r
+  Scope (\_SB)\r
+  {\r
+    Device (TPM)\r
+    {\r
+      //\r
+      // TCG2\r
+      //\r
+      Name (_HID, "MSFT0101")\r
+      \r
+      //\r
+      // Readable name of this device, don't know if this way is correct yet\r
+      //\r
+      Name (_STR, Unicode ("TPM 2.0 Device"))\r
+\r
+      //\r
+      // Return the resource consumed by TPM device\r
+      //\r
+      Name (_CRS, ResourceTemplate () {\r
+        Memory32Fixed (ReadOnly, 0xfed40000, 0x5000)\r
+      })\r
+\r
+      //\r
+      // Operational region for Smi port access\r
+      //\r
+      OperationRegion (SMIP, SystemIO, 0xB2, 1)\r
+      Field (SMIP, ByteAcc, NoLock, Preserve)\r
+      { \r
+          IOB2, 8\r
+      }\r
+\r
+      //\r
+      // Operational region for TPM access\r
+      //\r
+      OperationRegion (TPMR, SystemMemory, 0xfed40000, 0x5000)\r
+      Field (TPMR, AnyAcc, NoLock, Preserve)\r
+      {\r
+        ACC0, 8,\r
+      }\r
+\r
+      //\r
+      // Operational region for TPM support, TPM Physical Presence and TPM Memory Clear\r
+      // Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code.\r
+      //\r
+      OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0xF0)\r
+      Field (TNVS, AnyAcc, NoLock, Preserve)\r
+      {\r
+        PPIN,   8,  //   Software SMI for Physical Presence Interface\r
+        PPIP,   32, //   Used for save physical presence paramter\r
+        PPRP,   32, //   Physical Presence request operation response\r
+        PPRQ,   32, //   Physical Presence request operation\r
+        PPRM,   32, //   Physical Presence request operation parameter\r
+        LPPR,   32, //   Last Physical Presence request operation\r
+        FRET,   32, //   Physical Presence function return code\r
+        MCIN,   8,  //   Software SMI for Memory Clear Interface\r
+        MCIP,   32, //   Used for save the Mor paramter\r
+        MORD,   32, //   Memory Overwrite Request Data\r
+        MRET,   32  //   Memory Overwrite function return code\r
+      }\r
+\r
+      Method (PTS, 1, Serialized)\r
+      {  \r
+        //\r
+        // Detect Sx state for MOR, only S4, S5 need to handle\r
+        //\r
+        If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3)))\r
+        {   \r
+          //\r
+          // Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect.\r
+          //\r
+          If (LNot (And (MORD, 0x10)))\r
+          {\r
+            //\r
+            // Triggle the SMI through ACPI _PTS method.\r
+            //\r
+            Store (0x02, MCIP)\r
+              \r
+            //\r
+            // Triggle the SMI interrupt\r
+            //\r
+            Store (MCIN, IOB2)\r
+          }\r
+        }\r
+        Return (0)\r
+      }   \r
+\r
+      Method (_STA, 0)\r
+      {\r
+        if (LEqual (ACC0, 0xff))\r
+        {\r
+            Return (0)\r
+        }\r
+        Return (0x0f)\r
+      }\r
+\r
+      //\r
+      // TCG Hardware Information\r
+      //\r
+      Method (HINF, 3, Serialized, 0, {BuffObj, PkgObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj\r
+      {\r
+        //\r
+        // Switch by function index\r
+        //\r
+        Switch (ToInteger(Arg1))\r
+        {\r
+          Case (0)\r
+          {\r
+            //\r
+            // Standard query\r
+            //\r
+            Return (Buffer () {0x03})\r
+          }\r
+          Case (1)\r
+          {\r
+            //\r
+            // Return failure if no TPM present\r
+            //\r
+            Name(TPMV, Package () {0x01, Package () {0x2, 0x0}})\r
+            if (LEqual (_STA (), 0x00))\r
+            {\r
+              Return (Package () {0x00})\r
+            }\r
+\r
+            //\r
+            // Return TPM version\r
+            //\r
+            Return (TPMV)\r
+          }\r
+          Default {BreakPoint}\r
+        }\r
+        Return (Buffer () {0})\r
+      }\r
+\r
+      Name(TPM2, Package (0x02){\r
+        Zero, \r
+        Zero\r
+      })\r
+\r
+      Name(TPM3, Package (0x03){\r
+        Zero, \r
+        Zero,\r
+        Zero\r
+      })\r
+\r
+      //\r
+      // TCG Physical Presence Interface\r
+      //\r
+      Method (TPPI, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj\r
+      {        \r
+        //\r
+        // Switch by function index\r
+        //\r
+        Switch (ToInteger(Arg1))\r
+        {\r
+          Case (0)\r
+          {\r
+            //\r
+            // Standard query, supports function 1-8\r
+            //\r
+            Return (Buffer () {0xFF, 0x01})\r
+          }\r
+          Case (1)\r
+          {\r
+            //\r
+            // a) Get Physical Presence Interface Version\r
+            //\r
+            Return ("1.2")\r
+          }\r
+          Case (2)\r
+          {\r
+            //\r
+            // b) Submit TPM Operation Request to Pre-OS Environment\r
+            //\r
+                  \r
+            Store (DerefOf (Index (Arg2, 0x00)), PPRQ)\r
+            Store (0x02, PPIP)\r
+              \r
+            //\r
+            // Triggle the SMI interrupt\r
+            //\r
+            Store (PPIN, IOB2)\r
+            Return (FRET)\r
+\r
+\r
+          }\r
+          Case (3)\r
+          {\r
+            //\r
+            // c) Get Pending TPM Operation Requested By the OS\r
+            //\r
+                  \r
+            Store (PPRQ, Index (TPM2, 0x01))\r
+            Return (TPM2)\r
+          }\r
+          Case (4)\r
+          {\r
+            //\r
+            // d) Get Platform-Specific Action to Transition to Pre-OS Environment\r
+            //\r
+            Return (2)\r
+          }\r
+          Case (5)\r
+          {\r
+            //\r
+            // e) Return TPM Operation Response to OS Environment\r
+            //\r
+            Store (0x05, PPIP)\r
+                  \r
+            //\r
+            // Triggle the SMI interrupt\r
+            //\r
+            Store (PPIN, IOB2)\r
+                  \r
+            Store (LPPR, Index (TPM3, 0x01))\r
+            Store (PPRP, Index (TPM3, 0x02))\r
+\r
+            Return (TPM3)\r
+          }\r
+          Case (6)\r
+          {\r
+\r
+            //\r
+            // f) Submit preferred user language (Not implemented)\r
+            //\r
+\r
+            Return (3)\r
+\r
+          }\r
+          Case (7)\r
+          {\r
+            //\r
+            // g) Submit TPM Operation Request to Pre-OS Environment 2\r
+            //\r
+            Store (7, PPIP)\r
+            Store (DerefOf (Index (Arg2, 0x00)), PPRQ)\r
+            Store (0, PPRM)\r
+            If (LEqual (PPRQ, 23)) {\r
+              Store (DerefOf (Index (Arg2, 0x01)), PPRM)\r
+            }\r
+                \r
+            //\r
+            // Triggle the SMI interrupt \r
+            //\r
+            Store (PPIN, IOB2)  \r
+            Return (FRET)\r
+          }\r
+          Case (8)\r
+          {\r
+            //\r
+            // e) Get User Confirmation Status for Operation\r
+            //\r
+            Store (8, PPIP)\r
+            Store (DerefOf (Index (Arg2, 0x00)), PPRQ)\r
+                  \r
+            //\r
+            // Triggle the SMI interrupt\r
+            //\r
+            Store (PPIN, IOB2)\r
+                  \r
+            Return (FRET)\r
+          }\r
+\r
+          Default {BreakPoint}\r
+        }\r
+        Return (1)\r
+      }\r
+\r
+      Method (TMCI, 3, Serialized, 0, IntObj, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj\r
+      {\r
+        //\r
+        // Switch by function index\r
+        //\r
+        Switch (ToInteger (Arg1))\r
+        {\r
+          Case (0)\r
+          {\r
+            //\r
+            // Standard query, supports function 1-1\r
+            //\r
+            Return (Buffer () {0x03})\r
+          }\r
+          Case (1)\r
+          {\r
+            //\r
+            // Save the Operation Value of the Request to MORD (reserved memory)\r
+            //\r
+            Store (DerefOf (Index (Arg2, 0x00)), MORD)\r
+                  \r
+            //\r
+            // Triggle the SMI through ACPI _DSM method.\r
+            //\r
+            Store (0x01, MCIP)\r
+                  \r
+            //\r
+            // Triggle the SMI interrupt\r
+            //\r
+            Store (MCIN, IOB2)\r
+            Return (MRET)\r
+          }\r
+          Default {BreakPoint}\r
+        }\r
+        Return (1)        \r
+      }\r
+\r
+      Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})\r
+      {\r
+\r
+        //\r
+        // TCG Hardware Information\r
+        //\r
+        If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8")))\r
+        {\r
+          Return (HINF (Arg1, Arg2, Arg3))\r
+        }\r
+\r
+        //\r
+        // TCG Physical Presence Interface\r
+        //\r
+        If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653")))\r
+        {\r
+          Return (TPPI (Arg1, Arg2, Arg3))\r
+        }\r
+\r
+        //\r
+        // TCG Memory Clear Interface\r
+        //\r
+        If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d")))\r
+        {\r
+          Return (TMCI (Arg1, Arg2, Arg3))\r
+        }\r
+\r
+        Return (Buffer () {0})\r
+      }\r
+    }\r
+  }\r
+}\r