Add TPM2 implementation.
authorjyao1 <jyao1>
Wed, 18 Sep 2013 05:31:18 +0000 (05:31 +0000)
committerjyao1 <jyao1@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 18 Sep 2013 05:31:18 +0000 (05:31 +0000)
signed off by: jiewen.yao@intel.com
reviewed by: guo.dong@intel.com

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14687 6f19259b-4bc3-4df7-8a09-765794883524

98 files changed:
SecurityPkg/Include/Guid/TpmInstance.h [new file with mode: 0644]
SecurityPkg/Include/Guid/TrEEConfigHii.h [new file with mode: 0644]
SecurityPkg/Include/Guid/TrEEPhysicalPresenceData.h [new file with mode: 0644]
SecurityPkg/Include/Library/HashLib.h [new file with mode: 0644]
SecurityPkg/Include/Library/Tpm12CommandLib.h [new file with mode: 0644]
SecurityPkg/Include/Library/Tpm12DeviceLib.h [new file with mode: 0644]
SecurityPkg/Include/Library/Tpm2CommandLib.h [new file with mode: 0644]
SecurityPkg/Include/Library/Tpm2DeviceLib.h [new file with mode: 0644]
SecurityPkg/Include/Library/TrEEPhysicalPresenceLib.h [new file with mode: 0644]
SecurityPkg/Include/Ppi/FirmwareVolumeInfoMeasurementExcluded.h [new file with mode: 0644]
SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
SecurityPkg/Library/DxeImageVerificationLib/Measurement.c [new file with mode: 0644]
SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c [new file with mode: 0644]
SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf [new file with mode: 0644]
SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.c
SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c [new file with mode: 0644]
SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.inf [new file with mode: 0644]
SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/PhysicalPresenceStrings.uni [new file with mode: 0644]
SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c [new file with mode: 0644]
SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf [new file with mode: 0644]
SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.c [new file with mode: 0644]
SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf [new file with mode: 0644]
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.c [new file with mode: 0644]
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.h [new file with mode: 0644]
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c [new file with mode: 0644]
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf [new file with mode: 0644]
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c [new file with mode: 0644]
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf [new file with mode: 0644]
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c [new file with mode: 0644]
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm12CommandLib/Tpm12Ownership.c [new file with mode: 0644]
SecurityPkg/Library/Tpm12CommandLib/Tpm12Startup.c [new file with mode: 0644]
SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12Tis.c [new file with mode: 0644]
SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.c [new file with mode: 0644]
SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2DictionaryAttack.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2Miscellaneous.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2Sequences.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2Startup.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2CommandLib/Tpm2Test.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Tis.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterPei.inf [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.c [new file with mode: 0644]
SecurityPkg/Library/Tpm2DeviceLibTrEE/Tpm2DeviceLibTrEE.inf [new file with mode: 0644]
SecurityPkg/SecurityPkg.dec
SecurityPkg/SecurityPkg.dsc
SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
SecurityPkg/Tcg/TcgDxe/TcgDxe.c
SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
SecurityPkg/Tcg/TcgPei/TcgPei.c
SecurityPkg/Tcg/TcgPei/TcgPei.inf
SecurityPkg/Tcg/TcgSmm/TcgSmm.c
SecurityPkg/Tcg/TcgSmm/TcgSmm.h
SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
SecurityPkg/Tcg/TrEEConfig/TpmDetection.c [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfig.vfr [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfigDriver.c [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.h [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfigNvData.h [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfigPeim.c [new file with mode: 0644]
SecurityPkg/Tcg/TrEEConfig/TrEEConfigStrings.uni [new file with mode: 0644]
SecurityPkg/Tcg/TrEEDxe/MeasureBootPeCoff.c [new file with mode: 0644]
SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c [new file with mode: 0644]
SecurityPkg/Tcg/TrEEDxe/TrEEDxe.inf [new file with mode: 0644]
SecurityPkg/Tcg/TrEEPei/TrEEPei.c [new file with mode: 0644]
SecurityPkg/Tcg/TrEEPei/TrEEPei.inf [new file with mode: 0644]
SecurityPkg/Tcg/TrEESmm/Tpm.asl [new file with mode: 0644]
SecurityPkg/Tcg/TrEESmm/TrEESmm.c [new file with mode: 0644]
SecurityPkg/Tcg/TrEESmm/TrEESmm.h [new file with mode: 0644]
SecurityPkg/Tcg/TrEESmm/TrEESmm.inf [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/Measurement.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf

diff --git a/SecurityPkg/Include/Guid/TpmInstance.h b/SecurityPkg/Include/Guid/TpmInstance.h
new file mode 100644 (file)
index 0000000..27c727b
--- /dev/null
@@ -0,0 +1,38 @@
+/** @file\r
+  TPM instance guid, used for PcdTpmInstanceGuid.\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
+#ifndef __TPM_INSTANCE_GUID_H__\r
+#define __TPM_INSTANCE_GUID_H__\r
+\r
+#define TPM_DEVICE_INTERFACE_NONE  \\r
+  { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }\r
+\r
+#define TPM_DEVICE_INTERFACE_TPM12  \\r
+  { 0x8b01e5b6, 0x4f19, 0x46e8, { 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc } }\r
+\r
+#define TPM_DEVICE_INTERFACE_TPM20_DTPM  \\r
+  { 0x286bf25a, 0xc2c3, 0x408c, { 0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17 } }\r
+\r
+extern EFI_GUID  gEfiTpmDeviceInstanceNoneGuid;\r
+extern EFI_GUID  gEfiTpmDeviceInstanceTpm12Guid;\r
+extern EFI_GUID  gEfiTpmDeviceInstanceTpm20DtpmGuid;\r
+\r
+\r
+#define TPM_DEVICE_SELECTED_GUID  \\r
+  { 0x7f4158d3, 0x74d, 0x456d, { 0x8c, 0xb2, 0x1, 0xf9, 0xc8, 0xf7, 0x9d, 0xaa } }\r
+\r
+extern EFI_GUID  gEfiTpmDeviceSelectedGuid;\r
+\r
+#endif\r
+\r
diff --git a/SecurityPkg/Include/Guid/TrEEConfigHii.h b/SecurityPkg/Include/Guid/TrEEConfigHii.h
new file mode 100644 (file)
index 0000000..b5d1de7
--- /dev/null
@@ -0,0 +1,25 @@
+/** @file\r
+  GUIDs used as HII FormSet and HII Package list GUID in TrEEConfig driver. \r
+  \r
+Copyright (c) 2013, 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 __TREE_CONFIG_HII_GUID_H__\r
+#define __TREE_CONFIG_HII_GUID_H__\r
+\r
+#define TREE_CONFIG_FORM_SET_GUID \\r
+  { \\r
+    0xc54b425f, 0xaa79, 0x48b4, { 0x98, 0x1f, 0x99, 0x8b, 0x3c, 0x4b, 0x64, 0x1c } \\r
+  }\r
+\r
+extern EFI_GUID gTrEEConfigFormSetGuid;\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Guid/TrEEPhysicalPresenceData.h b/SecurityPkg/Include/Guid/TrEEPhysicalPresenceData.h
new file mode 100644 (file)
index 0000000..65750cd
--- /dev/null
@@ -0,0 +1,62 @@
+/** @file\r
+  Define the variable data structures used for TrEE 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) 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
+#ifndef __TREE_PHYSICAL_PRESENCE_DATA_GUID_H__\r
+#define __TREE_PHYSICAL_PRESENCE_DATA_GUID_H__\r
+\r
+#define EFI_TREE_PHYSICAL_PRESENCE_DATA_GUID \\r
+  { \\r
+    0xf24643c2, 0xc622, 0x494e, { 0x8a, 0xd, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b }\\r
+  }\r
+\r
+#define TREE_PHYSICAL_PRESENCE_VARIABLE  L"TrEEPhysicalPresence"\r
+\r
+typedef struct {\r
+  UINT8   PPRequest;      ///< Physical Presence request command.\r
+  UINT8   LastPPRequest;\r
+  UINT32  PPResponse;\r
+} EFI_TREE_PHYSICAL_PRESENCE;\r
+\r
+//\r
+// The definition bit of the flags\r
+//\r
+#define TREE_FLAG_NO_PPI_CLEAR                        BIT1\r
+#define TREE_FLAG_RESET_TRACK                         BIT3\r
+\r
+//\r
+// This variable is used to save TPM Management Flags and corresponding operations.\r
+// It should be protected from malicious software (e.g. Set it as read-only variable). \r
+//\r
+#define TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE  L"TrEEPhysicalPresenceFlags"\r
+\r
+//\r
+// The definition of physical presence operation actions\r
+//\r
+#define TREE_PHYSICAL_PRESENCE_NO_ACTION                               0\r
+#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR                     5\r
+#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2                   14\r
+#define TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE                  17\r
+#define TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE                   18\r
+#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3                   21\r
+#define TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4                   22\r
+\r
+#define TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX                           22\r
+\r
+extern EFI_GUID  gEfiTrEEPhysicalPresenceGuid;\r
+\r
+#endif\r
+\r
diff --git a/SecurityPkg/Include/Library/HashLib.h b/SecurityPkg/Include/Library/HashLib.h
new file mode 100644 (file)
index 0000000..b857569
--- /dev/null
@@ -0,0 +1,169 @@
+/** @file\r
+  Ihis library abstract TPM2 hash calculation.\r
+  The platform can choose multiply hash, while caller just need invoke these API.\r
+  Then all hash value will be returned and/or extended.\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
+#ifndef _HASH_LIB_H_\r
+#define _HASH_LIB_H_\r
+\r
+#include <Uefi.h>\r
+#include <Protocol/Hash.h>\r
+\r
+typedef UINTN  HASH_HANDLE;\r
+\r
+/**\r
+  Start hash sequence.\r
+\r
+  @param HashHandle Hash handle.\r
+\r
+  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.\r
+  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashStart (\r
+  OUT HASH_HANDLE    *HashHandle\r
+  );\r
+\r
+/**\r
+  Update hash sequence data.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence updated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashUpdate (\r
+  IN HASH_HANDLE    HashHandle,\r
+  IN VOID           *DataToHash,\r
+  IN UINTN          DataToHashLen\r
+  );\r
+\r
+/**\r
+  Hash sequence complete and extend to PCR.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashCompleteAndExtend (\r
+  IN HASH_HANDLE         HashHandle,\r
+  IN TPMI_DH_PCR         PcrIndex,\r
+  IN VOID                *DataToHash,\r
+  IN UINTN               DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES *DigestList\r
+  );\r
+\r
+/**\r
+  Hash data and extend to PCR.\r
+\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash data and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashAndExtend (\r
+  IN TPMI_DH_PCR                    PcrIndex,\r
+  IN VOID                           *DataToHash,\r
+  IN UINTN                          DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES            *DigestList\r
+  );\r
+\r
+/**\r
+  Start hash sequence.\r
+\r
+  @param HashHandle Hash handle.\r
+\r
+  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.\r
+  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *HASH_INIT) (\r
+  OUT HASH_HANDLE    *HashHandle\r
+  );\r
+\r
+/**\r
+  Update hash sequence data.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence updated.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *HASH_UPDATE) (\r
+  IN HASH_HANDLE    HashHandle,\r
+  IN VOID           *DataToHash,\r
+  IN UINTN          DataToHashLen\r
+  );\r
+\r
+/**\r
+  Complete hash sequence complete.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *HASH_FINAL) (\r
+  IN HASH_HANDLE         HashHandle,\r
+  OUT TPML_DIGEST_VALUES *DigestList\r
+  );\r
+\r
+#define HASH_ALGORITHM_SHA1_GUID    EFI_HASH_ALGORITHM_SHA1_GUID\r
+#define HASH_ALGORITHM_SHA256_GUID  EFI_HASH_ALGORITHM_SHA256_GUID\r
+#define HASH_ALGORITHM_SHA384_GUID  EFI_HASH_ALGORITHM_SHA384_GUID\r
+#define HASH_ALGORITHM_SHA512_GUID  EFI_HASH_ALGORITHM_SHA512_GUID\r
+\r
+typedef struct {\r
+  EFI_GUID                           HashGuid;\r
+  HASH_INIT                          HashInit;\r
+  HASH_UPDATE                        HashUpdate;\r
+  HASH_FINAL                         HashFinal;\r
+} HASH_INTERFACE;\r
+\r
+/**\r
+  This service register Hash.\r
+\r
+  @param HashInterface  Hash interface\r
+\r
+  @retval EFI_SUCCESS          This hash interface is registered successfully.\r
+  @retval EFI_UNSUPPORTED      System does not support register this interface.\r
+  @retval EFI_ALREADY_STARTED  System already register this interface.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterHashInterfaceLib (\r
+  IN HASH_INTERFACE   *HashInterface\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Library/Tpm12CommandLib.h b/SecurityPkg/Include/Library/Tpm12CommandLib.h
new file mode 100644 (file)
index 0000000..8b62823
--- /dev/null
@@ -0,0 +1,46 @@
+/** @file\r
+  This library is used by other modules to send TPM12 command.\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
+#ifndef _TPM12_COMMAND_LIB_H_\r
+#define _TPM12_COMMAND_LIB_H_\r
+\r
+#include <IndustryStandard/Tpm12.h>\r
+\r
+/**\r
+  Send Startup command to TPM1.2.\r
+\r
+  @param TpmSt           Startup Type.\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12Startup (\r
+  IN TPM_STARTUP_TYPE          TpmSt\r
+  );\r
+\r
+/**\r
+  Send ForceClear command to TPM1.2.\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12ForceClear (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Library/Tpm12DeviceLib.h b/SecurityPkg/Include/Library/Tpm12DeviceLib.h
new file mode 100644 (file)
index 0000000..ab1f522
--- /dev/null
@@ -0,0 +1,54 @@
+/** @file\r
+  This library abstract how to access TPM12 hardware device.\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
+#ifndef _TPM12_DEVICE_LIB_H_\r
+#define _TPM12_DEVICE_LIB_H_\r
+\r
+#include <IndustryStandard/Tpm12.h>\r
+\r
+/**\r
+  This service enables the sending of commands to the TPM12.\r
+\r
+  @param[in]      InputParameterBlockSize  Size of the TPM12 input parameter block.\r
+  @param[in]      InputParameterBlock      Pointer to the TPM12 input parameter block.\r
+  @param[in,out]  OutputParameterBlockSize Size of the TPM12 output parameter block.\r
+  @param[in]      OutputParameterBlock     Pointer to the TPM12 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
+Tpm12SubmitCommand (\r
+  IN UINT32            InputParameterBlockSize,\r
+  IN UINT8             *InputParameterBlock,\r
+  IN OUT UINT32        *OutputParameterBlockSize,\r
+  IN UINT8             *OutputParameterBlock\r
+  );\r
+\r
+/**\r
+  This service requests use TPM12.\r
+\r
+  @retval EFI_SUCCESS      Get the control of TPM12 chip.\r
+  @retval EFI_NOT_FOUND    TPM12 not found.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12RequestUseTpm (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Include/Library/Tpm2CommandLib.h
new file mode 100644 (file)
index 0000000..5ec3ead
--- /dev/null
@@ -0,0 +1,824 @@
+/** @file\r
+  This library is used by other modules to send TPM2 command.\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
+#ifndef _TPM2_COMMAND_LIB_H_\r
+#define _TPM2_COMMAND_LIB_H_\r
+\r
+#include <IndustryStandard/Tpm20.h>\r
+\r
+/**\r
+  This command starts a hash or an Event sequence.\r
+  If hashAlg is an implemented hash, then a hash sequence is started.\r
+  If hashAlg is TPM_ALG_NULL, then an Event sequence is started.\r
+\r
+  @param[in]  HashAlg           The hash algorithm to use for the hash sequence\r
+                                An Event sequence starts if this is TPM_ALG_NULL.\r
+  @param[out] SequenceHandle    A handle to reference the sequence\r
\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2HashSequenceStart (\r
+  IN TPMI_ALG_HASH   HashAlg,\r
+  OUT TPMI_DH_OBJECT *SequenceHandle\r
+  );\r
+\r
+/**\r
+  This command is used to add data to a hash or HMAC sequence.\r
+  The amount of data in buffer may be any size up to the limits of the TPM.\r
+  NOTE: In all TPM, a buffer size of 1,024 octets is allowed.\r
+\r
+  @param[in] SequenceHandle    Handle for the sequence object\r
+  @param[in] Buffer            Data to be added to hash\r
\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2SequenceUpdate (\r
+  IN TPMI_DH_OBJECT   SequenceHandle,\r
+  IN TPM2B_MAX_BUFFER *Buffer\r
+  );\r
+\r
+/**\r
+  This command adds the last part of data, if any, to an Event sequence and returns the result in a digest list.\r
+  If pcrHandle references a PCR and not TPM_RH_NULL, then the returned digest list is processed in\r
+  the same manner as the digest list input parameter to TPM2_PCR_Extend() with the pcrHandle in each\r
+  bank extended with the associated digest value.\r
+\r
+  @param[in]  PcrHandle         PCR to be extended with the Event data\r
+  @param[in]  SequenceHandle    Authorization for the sequence\r
+  @param[in]  Buffer            Data to be added to the Event\r
+  @param[out] Results           List of digests computed for the PCR\r
\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2EventSequenceComplete (\r
+  IN TPMI_DH_PCR         PcrHandle,\r
+  IN TPMI_DH_OBJECT      SequenceHandle,\r
+  IN TPM2B_MAX_BUFFER    *Buffer,\r
+  OUT TPML_DIGEST_VALUES *Results\r
+  );\r
+\r
+/**\r
+  This command adds the last part of data, if any, to a hash/HMAC sequence and returns the result.\r
+\r
+  @param[in]  SequenceHandle    Authorization for the sequence\r
+  @param[in]  Buffer            Data to be added to the hash/HMAC\r
+  @param[out] Result            The returned HMAC or digest in a sized buffer\r
\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2SequenceComplete (\r
+  IN TPMI_DH_OBJECT      SequenceHandle,\r
+  IN TPM2B_MAX_BUFFER    *Buffer,\r
+  OUT TPM2B_DIGEST       *Result\r
+  );\r
+\r
+/**\r
+  Send Startup command to TPM2.\r
+\r
+  @param[in] StartupType           TPM_SU_CLEAR or TPM_SU_STATE\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2Startup (\r
+  IN      TPM_SU             StartupType\r
+  );\r
+\r
+/**\r
+  Send Shutdown command to TPM2.\r
+\r
+  @param[in] ShutdownType           TPM_SU_CLEAR or TPM_SU_STATE.\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2Shutdown (\r
+  IN      TPM_SU             ShutdownType\r
+  );\r
+\r
+/**\r
+  This command causes the TPM to perform a test of its capabilities.\r
+  If the fullTest is YES, the TPM will test all functions.\r
+  If fullTest = NO, the TPM will only test those functions that have not previously been tested.\r
+\r
+  @param[in] FullTest    YES if full test to be performed\r
+                         NO if only test of untested functions required\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2SelfTest (\r
+  IN TPMI_YES_NO          FullTest\r
+  );\r
+\r
+/**\r
+  This command removes all TPM context associated with a specific Owner.\r
+\r
+  @param[in] AuthHandle        TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}\r
+  @param[in] AuthSession       Auth Session context\r
\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2Clear (\r
+  IN TPMI_RH_CLEAR             AuthHandle,\r
+  IN TPMS_AUTH_COMMAND         *AuthSession OPTIONAL\r
+  );\r
+\r
+/**\r
+  Disables and enables the execution of TPM2_Clear().\r
+\r
+  @param[in] AuthHandle        TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}\r
+  @param[in] AuthSession       Auth Session context\r
+  @param[in] Disable           YES if the disableOwnerClear flag is to be SET,\r
+                               NO if the flag is to be CLEAR.\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2ClearControl (\r
+  IN TPMI_RH_CLEAR             AuthHandle,\r
+  IN TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL\r
+  IN TPMI_YES_NO               Disable\r
+  );\r
+\r
+/**\r
+  This command allows the authorization secret for a hierarchy or lockout to be changed using the current\r
+  authorization value as the command authorization.\r
+\r
+  @param[in] AuthHandle        TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}\r
+  @param[in] AuthSession       Auth Session context\r
+  @param[in] NewAuth           New authorization secret\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2HierarchyChangeAuth (\r
+  IN TPMI_RH_HIERARCHY_AUTH    AuthHandle,\r
+  IN TPMS_AUTH_COMMAND         *AuthSession,\r
+  IN TPM2B_AUTH                *NewAuth\r
+  );\r
+\r
+/**\r
+  This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to\r
+  their default initialization values.\r
+\r
+  @param[in] AuthHandle        TPM_RH_PLATFORM+{PP}\r
+  @param[in] AuthSession       Auth Session context\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2ChangeEPS (\r
+  IN TPMI_RH_PLATFORM          AuthHandle,\r
+  IN TPMS_AUTH_COMMAND         *AuthSession\r
+  );\r
+\r
+/**\r
+  This replaces the current PPS with a value from the RNG and sets platformPolicy to the default\r
+  initialization value (the Empty Buffer).\r
+\r
+  @param[in] AuthHandle        TPM_RH_PLATFORM+{PP}\r
+  @param[in] AuthSession       Auth Session context\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2ChangePPS (\r
+  IN TPMI_RH_PLATFORM          AuthHandle,\r
+  IN TPMS_AUTH_COMMAND         *AuthSession\r
+  );\r
+\r
+/**\r
+  This command enables and disables use of a hierarchy.\r
+\r
+  @param[in] AuthHandle        TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}\r
+  @param[in] AuthSession       Auth Session context\r
+  @param[in] Hierarchy         Hierarchy of the enable being modified\r
+  @param[in] State             YES if the enable should be SET,\r
+                               NO if the enable should be CLEAR\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2HierarchyControl (\r
+  IN TPMI_RH_HIERARCHY         AuthHandle,\r
+  IN TPMS_AUTH_COMMAND         *AuthSession,\r
+  IN TPMI_RH_HIERARCHY         Hierarchy,\r
+  IN TPMI_YES_NO               State\r
+  );\r
+\r
+/**\r
+  This command cancels the effect of a TPM lockout due to a number of successive authorization failures.\r
+  If this command is properly authorized, the lockout counter is set to zero.\r
+\r
+  @param[in]  LockHandle            LockHandle\r
+  @param[in]  AuthSession           Auth Session context\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2DictionaryAttackLockReset (\r
+  IN  TPMI_RH_LOCKOUT           LockHandle,\r
+  IN  TPMS_AUTH_COMMAND         *AuthSession\r
+  );\r
+\r
+/**\r
+  This command cancels the effect of a TPM lockout due to a number of successive authorization failures.\r
+  If this command is properly authorized, the lockout counter is set to zero.\r
+\r
+  @param[in]  LockHandle            LockHandle\r
+  @param[in]  AuthSession           Auth Session context\r
+  @param[in]  NewMaxTries           Count of authorization failures before the lockout is imposed\r
+  @param[in]  NewRecoveryTime       Time in seconds before the authorization failure count is automatically decremented\r
+  @param[in]  LockoutRecovery       Time in seconds after a lockoutAuth failure before use of lockoutAuth is allowed\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2DictionaryAttackParameters (\r
+  IN  TPMI_RH_LOCKOUT           LockHandle,\r
+  IN  TPMS_AUTH_COMMAND         *AuthSession,\r
+  IN  UINT32                    NewMaxTries,\r
+  IN  UINT32                    NewRecoveryTime,\r
+  IN  UINT32                    LockoutRecovery\r
+  );\r
+\r
+/**\r
+  This command is used to read the public area and Name of an NV Index.\r
+\r
+  @param[in]  NvIndex            The NV Index.\r
+  @param[out] NvPublic           The public area of the index.\r
+  @param[out] NvName             The Name of the nvIndex.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2NvReadPublic (\r
+  IN      TPMI_RH_NV_INDEX          NvIndex,\r
+  OUT     TPM2B_NV_PUBLIC           *NvPublic,\r
+  OUT     TPM2B_NAME                *NvName\r
+  );\r
+\r
+/**\r
+  This command defines the attributes of an NV Index and causes the TPM to\r
+  reserve space to hold the data associated with the index.\r
+  If a definition already exists at the index, the TPM will return TPM_RC_NV_DEFINED.\r
+\r
+  @param[in]  AuthHandle         TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.\r
+  @param[in]  AuthSession        Auth Session context\r
+  @param[in]  Auth               The authorization data.\r
+  @param[in]  NvPublic           The public area of the index.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+  @retval EFI_ALREADY_STARTED    The command was returned successfully, but NvIndex is already defined.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2NvDefineSpace (\r
+  IN      TPMI_RH_PROVISION         AuthHandle,\r
+  IN      TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL\r
+  IN      TPM2B_AUTH                *Auth,\r
+  IN      TPM2B_NV_PUBLIC           *NvPublic\r
+  );\r
+\r
+/**\r
+  This command removes an index from the TPM.\r
+\r
+  @param[in]  AuthHandle         TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.\r
+  @param[in]  NvIndex            The NV Index.\r
+  @param[in]  AuthSession        Auth Session context\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2NvUndefineSpace (\r
+  IN      TPMI_RH_PROVISION         AuthHandle,\r
+  IN      TPMI_RH_NV_INDEX          NvIndex,\r
+  IN      TPMS_AUTH_COMMAND         *AuthSession OPTIONAL\r
+  );\r
+\r
+/**\r
+  This command reads a value from an area in NV memory previously defined by TPM2_NV_DefineSpace().\r
+\r
+  @param[in]     AuthHandle         the handle indicating the source of the authorization value.\r
+  @param[in]     NvIndex            The index to be read.\r
+  @param[in]     AuthSession        Auth Session context\r
+  @param[in]     Size               Number of bytes to read.\r
+  @param[in]     Offset             Byte offset into the area.\r
+  @param[in,out] OutData            The data read.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2NvRead (\r
+  IN      TPMI_RH_NV_AUTH           AuthHandle,\r
+  IN      TPMI_RH_NV_INDEX          NvIndex,\r
+  IN      TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL\r
+  IN      UINT16                    Size,\r
+  IN      UINT16                    Offset,\r
+  IN OUT  TPM2B_MAX_BUFFER          *OutData\r
+  );\r
+\r
+/**\r
+  This command writes a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().\r
+\r
+  @param[in]  AuthHandle         the handle indicating the source of the authorization value.\r
+  @param[in]  NvIndex            The NV Index of the area to write.\r
+  @param[in]  AuthSession        Auth Session context\r
+  @param[in]  InData             The data to write.\r
+  @param[in]  Offset             The offset into the NV Area.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2NvWrite (\r
+  IN      TPMI_RH_NV_AUTH           AuthHandle,\r
+  IN      TPMI_RH_NV_INDEX          NvIndex,\r
+  IN      TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL\r
+  IN      TPM2B_MAX_BUFFER          *InData,\r
+  IN      UINT16                    Offset\r
+  );\r
+\r
+/**\r
+  This command may be used to prevent further reads of the Index until the next TPM2_Startup (TPM_SU_CLEAR).\r
+\r
+  @param[in]  AuthHandle         the handle indicating the source of the authorization value.\r
+  @param[in]  NvIndex            The NV Index of the area to lock.\r
+  @param[in]  AuthSession        Auth Session context\r
+\r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2NvReadLock (\r
+  IN      TPMI_RH_NV_AUTH           AuthHandle,\r
+  IN      TPMI_RH_NV_INDEX          NvIndex,\r
+  IN      TPMS_AUTH_COMMAND         *AuthSession OPTIONAL\r
+  );\r
+\r
+/**\r
+  This command may be used to inhibit further writes of the Index.\r
+\r
+  @param[in]  AuthHandle         the handle indicating the source of the authorization value.\r
+  @param[in]  NvIndex            The NV Index of the area to lock.\r
+  @param[in]  AuthSession        Auth Session context\r
+\r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2NvWriteLock (\r
+  IN      TPMI_RH_NV_AUTH           AuthHandle,\r
+  IN      TPMI_RH_NV_INDEX          NvIndex,\r
+  IN      TPMS_AUTH_COMMAND         *AuthSession OPTIONAL\r
+  );\r
+\r
+/**\r
+  The command will SET TPMA_NV_WRITELOCKED for all indexes that have their TPMA_NV_GLOBALLOCK attribute SET.\r
+\r
+  @param[in]  AuthHandle         TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.\r
+  @param[in]  AuthSession        Auth Session context\r
+\r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2NvGlobalWriteLock (\r
+  IN      TPMI_RH_PROVISION         AuthHandle,\r
+  IN      TPMS_AUTH_COMMAND         *AuthSession OPTIONAL\r
+  );\r
+\r
+/**\r
+  This command is used to cause an update to the indicated PCR.\r
+  The digests parameter contains one or more tagged digest value identified by an algorithm ID.\r
+  For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).\r
+\r
+  @param[in] PcrHandle   Handle of the PCR\r
+  @param[in] Digests     List of tagged digest values to be extended\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrExtend (\r
+  IN      TPMI_DH_PCR               PcrHandle,\r
+  IN      TPML_DIGEST_VALUES        *Digests\r
+  );\r
+\r
+/**\r
+  This command is used to cause an update to the indicated PCR.\r
+  The data in eventData is hashed using the hash algorithm associated with each bank in which the\r
+  indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle\r
+  references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in\r
+  TPM2_PCR_Extend().\r
+  A TPM shall support an Event.size of zero through 1,024 inclusive.\r
+\r
+  @param[in]  PcrHandle   Handle of the PCR\r
+  @param[in]  EventData   Event data in sized buffer\r
+  @param[out] Digests     List of digest\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrEvent (\r
+  IN      TPMI_DH_PCR               PcrHandle,\r
+  IN      TPM2B_EVENT               *EventData,\r
+     OUT  TPML_DIGEST_VALUES        *Digests\r
+  );\r
+\r
+/**\r
+  This command returns the values of all PCR specified in pcrSelect.\r
+\r
+  @param[in]  PcrSelectionIn     The selection of PCR to read.\r
+  @param[out] PcrUpdateCounter   The current value of the PCR update counter.\r
+  @param[out] PcrSelectionOut    The PCR in the returned list.\r
+  @param[out] PcrValues          The contents of the PCR indicated in pcrSelect.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrRead (\r
+  IN      TPML_PCR_SELECTION        *PcrSelectionIn,\r
+     OUT  UINT32                    *PcrUpdateCounter,\r
+     OUT  TPML_PCR_SELECTION        *PcrSelectionOut,\r
+     OUT  TPML_DIGEST               *PcrValues\r
+  );\r
+\r
+/**\r
+  This command is used to set the desired PCR allocation of PCR and algorithms.\r
+\r
+  @param[in]  AuthHandle         TPM_RH_PLATFORM+{PP}\r
+  @param[in]  AuthSession        Auth Session context\r
+  @param[in]  PcrAllocation      The requested allocation\r
+  @param[out] AllocationSuccess  YES if the allocation succeeded\r
+  @param[out] MaxPCR             maximum number of PCR that may be in a bank\r
+  @param[out] SizeNeeded         number of octets required to satisfy the request\r
+  @param[out] SizeAvailable      Number of octets available. Computed before the allocation\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrAllocate (\r
+  IN  TPMI_RH_PLATFORM          AuthHandle,\r
+  IN  TPMS_AUTH_COMMAND         *AuthSession,\r
+  IN  TPML_PCR_SELECTION        *PcrAllocation,\r
+  OUT TPMI_YES_NO               *AllocationSuccess,\r
+  OUT UINT32                    *MaxPCR,\r
+  OUT UINT32                    *SizeNeeded,\r
+  OUT UINT32                    *SizeAvailable\r
+  );\r
+\r
+/**\r
+  This command returns various information regarding the TPM and its current state.\r
+\r
+  The capability parameter determines the category of data returned. The property parameter \r
+  selects the first value of the selected category to be returned. If there is no property \r
+  that corresponds to the value of property, the next higher value is returned, if it exists.\r
+  The moreData parameter will have a value of YES if there are more values of the requested \r
+  type that were not returned.\r
+  If no next capability exists, the TPM will return a zero-length list and moreData will have \r
+  a value of NO.\r
+\r
+  NOTE: \r
+  To simplify this function, leave returned CapabilityData for caller to unpack since there are \r
+  many capability categories and only few categories will be used in firmware. It means the caller\r
+  need swap the byte order for the feilds in CapabilityData.\r
+\r
+  @param[in]  Capability         Group selection; determines the format of the response.\r
+  @param[in]  Property           Further definition of information. \r
+  @param[in]  PropertyCount      Number of properties of the indicated type to return.\r
+  @param[out] MoreData           Flag to indicate if there are more values of this type.\r
+  @param[out] CapabilityData     The capability data.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapability (\r
+  IN      TPM_CAP                   Capability,\r
+  IN      UINT32                    Property,\r
+  IN      UINT32                    PropertyCount,\r
+  OUT     TPMI_YES_NO               *MoreData,\r
+  OUT     TPMS_CAPABILITY_DATA      *CapabilityData\r
+  );\r
+\r
+/**\r
+  This command returns the information of TPM Family.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the Family.\r
+\r
+  @param[out] Family             The Family of TPM. (a 4-octet character string)\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityFamily (\r
+  OUT     CHAR8                     *Family\r
+  );\r
+\r
+/**\r
+  This command returns the information of TPM manufacture ID.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the TPM manufacture ID.\r
+\r
+  @param[out] ManufactureId      The manufacture ID of TPM.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityManufactureID (\r
+  OUT     UINT32                    *ManufactureId\r
+  );\r
+\r
+/**\r
+  This command returns the information of TPM FirmwareVersion.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the TPM FirmwareVersion.\r
+\r
+  @param[out] FirmwareVersion1   The FirmwareVersion1.\r
+  @param[out] FirmwareVersion2   The FirmwareVersion2.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityFirmwareVersion (\r
+  OUT     UINT32                    *FirmwareVersion1,\r
+  OUT     UINT32                    *FirmwareVersion2\r
+  );\r
+\r
+/**\r
+  This command returns the information of the maximum value for commandSize and responseSize in a command.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the max command size and response size\r
+\r
+  @param[out] MaxCommandSize     The maximum value for commandSize in a command.\r
+  @param[out] MaxResponseSize    The maximum value for responseSize in a command.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityMaxCommandResponseSize (\r
+  OUT UINT32                    *MaxCommandSize,\r
+  OUT UINT32                    *MaxResponseSize\r
+  );\r
+\r
+/**\r
+  This command returns Returns a list of TPMS_ALG_PROPERTIES. Each entry is an\r
+  algorithm ID and a set of properties of the algorithm. \r
+\r
+  This function parse the value got from TPM2_GetCapability and return the list.\r
+\r
+  @param[out] AlgList      List of algorithm.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilitySupportedAlg (\r
+  OUT TPML_ALG_PROPERTY      *AlgList\r
+  );\r
+\r
+/**\r
+  This command returns the information of TPM LockoutCounter.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the LockoutCounter.\r
+\r
+  @param[out] LockoutCounter     The LockoutCounter of TPM.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityLockoutCounter (\r
+  OUT     UINT32                    *LockoutCounter\r
+  );\r
+\r
+/**\r
+  This command returns the information of TPM LockoutInterval.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the LockoutInterval.\r
+\r
+  @param[out] LockoutInterval    The LockoutInterval of TPM.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityLockoutInterval (\r
+  OUT     UINT32                    *LockoutInterval\r
+  );\r
+\r
+/**\r
+  This command returns the information of TPM InputBufferSize.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the InputBufferSize.\r
+\r
+  @param[out] InputBufferSize    The InputBufferSize of TPM.\r
+                                 the maximum size of a parameter (typically, a TPM2B_MAX_BUFFER)\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityInputBufferSize (\r
+  OUT     UINT32                    *InputBufferSize\r
+  );\r
+\r
+/**\r
+  This command returns the information of TPM PCRs.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the PcrSelection.\r
+\r
+  @param[out] Pcrs    The Pcr Selection\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityPcrs (\r
+  OUT TPML_PCR_SELECTION      *Pcrs\r
+  );\r
+\r
+/**\r
+  This command returns the information of TPM AlgorithmSet.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the AlgorithmSet.\r
+\r
+  @param[out] AlgorithmSet    The AlgorithmSet of TPM.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityAlgorithmSet (\r
+  OUT     UINT32      *AlgorithmSet\r
+  );\r
+\r
+/**\r
+  This command is used to check to see if specific combinations of algorithm parameters are supported.\r
+\r
+  @param[in]  Parameters              Algorithm parameters to be validated\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2TestParms (\r
+  IN  TPMT_PUBLIC_PARMS           *Parameters\r
+  );\r
+\r
+/**\r
+  This command allows the platform to change the set of algorithms that are used by the TPM.\r
+  The algorithmSet setting is a vendor-dependent value.\r
+\r
+  @param[in]  AuthHandle              TPM_RH_PLATFORM\r
+  @param[in]  AuthSession             Auth Session context\r
+  @param[in]  AlgorithmSet            A TPM vendor-dependent value indicating the\r
+                                      algorithm set selection\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2SetAlgorithmSet (\r
+  IN  TPMI_RH_PLATFORM          AuthHandle,\r
+  IN  TPMS_AUTH_COMMAND         *AuthSession,\r
+  IN  UINT32                    AlgorithmSet\r
+  );\r
+\r
+//\r
+// Help function\r
+//\r
+\r
+/**\r
+  Copy AuthSessionIn to TPM2 command buffer.\r
+\r
+  @param [in]  AuthSessionIn   Input AuthSession data\r
+  @param [out] AuthSessionOut  Output AuthSession data in TPM2 command buffer\r
+\r
+  @return AuthSession size\r
+**/\r
+UINT32\r
+EFIAPI\r
+CopyAuthSessionCommand (\r
+  IN      TPMS_AUTH_COMMAND         *AuthSessionIn, OPTIONAL\r
+  OUT     UINT8                     *AuthSessionOut\r
+  );\r
+\r
+/**\r
+  Copy AuthSessionIn from TPM2 response buffer.\r
+\r
+  @param [in]  AuthSessionIn   Input AuthSession data in TPM2 response buffer\r
+  @param [out] AuthSessionOut  Output AuthSession data\r
+\r
+  @return AuthSession size\r
+**/\r
+UINT32\r
+EFIAPI\r
+CopyAuthSessionResponse (\r
+  IN      UINT8                      *AuthSessionIn,\r
+  OUT     TPMS_AUTH_RESPONSE         *AuthSessionOut OPTIONAL\r
+  );\r
+\r
+/**\r
+  Return size of digest.\r
+\r
+  @param[in] HashAlgo  Hash algorithm\r
+\r
+  @return size of digest\r
+**/\r
+UINT16\r
+EFIAPI\r
+GetHashSizeFromAlgo (\r
+  IN TPMI_ALG_HASH    HashAlgo\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Library/Tpm2DeviceLib.h b/SecurityPkg/Include/Library/Tpm2DeviceLib.h
new file mode 100644 (file)
index 0000000..67f158e
--- /dev/null
@@ -0,0 +1,109 @@
+/** @file\r
+  This library abstract how to access TPM2 hardware device.\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
+#ifndef _TPM2_DEVICE_LIB_H_\r
+#define _TPM2_DEVICE_LIB_H_\r
+\r
+#include <Uefi.h>\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
+/**\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
+/**\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
+typedef\r
+EFI_STATUS\r
+(EFIAPI *TPM2_SUBMIT_COMMAND) (\r
+  IN UINT32            InputParameterBlockSize,\r
+  IN UINT8             *InputParameterBlock,\r
+  IN OUT UINT32        *OutputParameterBlockSize,\r
+  IN UINT8             *OutputParameterBlock\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
+typedef\r
+EFI_STATUS\r
+(EFIAPI *TPM2_REQUEST_USE_TPM) (\r
+  VOID\r
+  );\r
+\r
+typedef struct {\r
+  EFI_GUID                           ProviderGuid;\r
+  TPM2_SUBMIT_COMMAND                Tpm2SubmitCommand;\r
+  TPM2_REQUEST_USE_TPM               Tpm2RequestUseTpm;\r
+} TPM2_DEVICE_INTERFACE;\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
+#endif\r
diff --git a/SecurityPkg/Include/Library/TrEEPhysicalPresenceLib.h b/SecurityPkg/Include/Library/TrEEPhysicalPresenceLib.h
new file mode 100644 (file)
index 0000000..781fd16
--- /dev/null
@@ -0,0 +1,57 @@
+/** @file\r
+  Ihis library is intended to be used by BDS modules.\r
+  This library will executing TPM2 request.\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
+#ifndef _TREE_PHYSICAL_PRESENCE_LIB_H_\r
+#define _TREE_PHYSICAL_PRESENCE_LIB_H_\r
+\r
+#include <IndustryStandard/Tpm20.h>\r
+#include <Protocol/TrEEProtocol.h>\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
+TrEEPhysicalPresenceLibProcessRequest (\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
+TrEEPhysicalPresenceLibNeedUserConfirm(\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Ppi/FirmwareVolumeInfoMeasurementExcluded.h b/SecurityPkg/Include/Ppi/FirmwareVolumeInfoMeasurementExcluded.h
new file mode 100644 (file)
index 0000000..88d09b0
--- /dev/null
@@ -0,0 +1,37 @@
+/** @file\r
+  Ihis PPI means a FV does not need to be extended to PCR by TCG modules.\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
+#ifndef __EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_H__\r
+#define __EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_H__\r
+\r
+#define EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI_GUID \\r
+ { 0x6e056ff9, 0xc695, 0x4364, { 0x9e, 0x2c, 0x61, 0x26, 0xf5, 0xce, 0xea, 0xae } }\r
+\r
+typedef struct {\r
+  EFI_PHYSICAL_ADDRESS              FvBase;\r
+  UINT64                            FvLength;\r
+} EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV;\r
+\r
+//\r
+// This PPI means a FV does not need to be extended to PCR by TCG modules.\r
+//\r
+typedef struct {\r
+  UINT32                                                Count;\r
+  EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV  Fv[1];\r
+} EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI;\r
+\r
+extern EFI_GUID gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid;\r
+\r
+#endif\r
+\r
index 2458ee2..8860dae 100644 (file)
@@ -71,6 +71,25 @@ HASH_TABLE mHash[] = {
   { L"SHA512", 64, &mHashOidValue[32], 9, NULL,                NULL,       NULL,          NULL       }\r
 };\r
 \r
+/**\r
+  SecureBoot Hook for processing image verification.\r
+\r
+  @param[in] VariableName                 Name of Variable to be found.\r
+  @param[in] VendorGuid                   Variable vendor GUID.\r
+  @param[in] DataSize                     Size of Data found. If size is less than the\r
+                                          data, this value contains the required size.\r
+  @param[in] Data                         Data pointer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SecureBootHook (\r
+  IN CHAR16                                 *VariableName,\r
+  IN EFI_GUID                               *VendorGuid,\r
+  IN UINTN                                  DataSize,\r
+  IN VOID                                   *Data\r
+  );\r
+\r
 /**\r
   Reads contents of a PE/COFF image in memory buffer.\r
 \r
@@ -846,6 +865,7 @@ IsSignatureFoundInDatabase (
           // Find the signature in database.\r
           //\r
           IsFound = TRUE;\r
+          SecureBootHook (VariableName, &gEfiImageSecurityDatabaseGuid, CertList->SignatureSize, Cert);\r
           break;\r
         }\r
 \r
@@ -948,6 +968,7 @@ IsPkcsSignedDataVerifiedBySignatureList (
                            mImageDigestSize\r
                            );\r
           if (VerifyStatus) {\r
+            SecureBootHook (VariableName, VendorGuid, CertList->SignatureSize, Cert);\r
             goto Done;\r
           }\r
           Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
index 0c6ab96..0e6a5d1 100644 (file)
@@ -35,6 +35,7 @@
 [Sources]\r
   DxeImageVerificationLib.c\r
   DxeImageVerificationLib.h\r
+  Measurement.c\r
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
@@ -54,6 +55,7 @@
   BaseCryptLib\r
   SecurityManagementLib\r
   PeCoffLib\r
+  TpmMeasurementLib\r
 \r
 [Protocols]\r
   gEfiFirmwareVolume2ProtocolGuid\r
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/Measurement.c b/SecurityPkg/Library/DxeImageVerificationLib/Measurement.c
new file mode 100644 (file)
index 0000000..2213423
--- /dev/null
@@ -0,0 +1,322 @@
+/** @file\r
+  Measure TrEE required variable.\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 <PiDxe.h>\r
+#include <Guid/ImageAuthentication.h>\r
+#include <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Protocol/TrEEProtocol.h>\r
+\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/TpmMeasurementLib.h>\r
+\r
+typedef struct {\r
+  CHAR16                                 *VariableName;\r
+  EFI_GUID                               *VendorGuid;\r
+} VARIABLE_TYPE;\r
+\r
+typedef struct {\r
+  CHAR16                                 *VariableName;\r
+  EFI_GUID                               *VendorGuid;\r
+  VOID                                   *Data;\r
+  UINTN                                  Size;\r
+} VARIABLE_RECORD;\r
+\r
+#define  MEASURED_AUTHORITY_COUNT_MAX  0x100\r
+\r
+UINTN            mMeasuredAuthorityCount    = 0;\r
+UINTN            mMeasuredAuthorityCountMax = 0;\r
+VARIABLE_RECORD  *mMeasuredAuthorityList    = NULL;\r
+\r
+VARIABLE_TYPE  mVariableType[] = {\r
+  {EFI_IMAGE_SECURITY_DATABASE,  &gEfiImageSecurityDatabaseGuid},\r
+};\r
+\r
+/**\r
+  This function will check if VarName should be recorded and return the address of VarName if it is needed.\r
+\r
+  @param[in]  VarName           A Null-terminated string that is the name of the vendor's variable.\r
+\r
+  @return the address of VarName.\r
+**/\r
+CHAR16 *\r
+AssignVarName (\r
+  IN      CHAR16                    *VarName\r
+  )\r
+{\r
+  UINTN  Index;\r
+\r
+  for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
+    if (StrCmp (VarName, mVariableType[Index].VariableName) == 0) {\r
+      return mVariableType[Index].VariableName;\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  This function will check if VendorGuid should be recorded and return the address of VendorGuid if it is needed.\r
+\r
+  @param[in]  VendorGuid        A unique identifier for the vendor.\r
+\r
+  @return the address of VendorGuid.\r
+**/\r
+EFI_GUID *\r
+AssignVendorGuid (\r
+  IN      EFI_GUID                  *VendorGuid\r
+  )\r
+{\r
+  UINTN  Index;\r
+\r
+  for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
+    if (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid)) {\r
+      return mVariableType[Index].VendorGuid;\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  This function will add variable information to MeasuredAuthorityList.\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[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
+**/\r
+EFI_STATUS\r
+AddDataMeasured (\r
+  IN      CHAR16                    *VarName,\r
+  IN      EFI_GUID                  *VendorGuid,\r
+  IN      VOID                      *Data,\r
+  IN      UINTN                     Size\r
+  )\r
+{\r
+  VARIABLE_RECORD  *NewMeasuredAuthorityList;\r
+\r
+  ASSERT (mMeasuredAuthorityCount <= mMeasuredAuthorityCountMax);\r
+  if (mMeasuredAuthorityCount == mMeasuredAuthorityCountMax) {\r
+    //\r
+    // Need enlarge\r
+    //\r
+    NewMeasuredAuthorityList = AllocateZeroPool (sizeof(VARIABLE_RECORD) * (mMeasuredAuthorityCountMax + MEASURED_AUTHORITY_COUNT_MAX));\r
+    if (NewMeasuredAuthorityList == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    if (mMeasuredAuthorityList != NULL) {\r
+      CopyMem (NewMeasuredAuthorityList, mMeasuredAuthorityList, sizeof(VARIABLE_RECORD) * mMeasuredAuthorityCount);\r
+      FreePool (mMeasuredAuthorityList);\r
+    }\r
+    mMeasuredAuthorityList     = NewMeasuredAuthorityList;\r
+    mMeasuredAuthorityCountMax += MEASURED_AUTHORITY_COUNT_MAX;\r
+  }\r
+\r
+  //\r
+  // Add new entry\r
+  //\r
+  mMeasuredAuthorityList[mMeasuredAuthorityCount].VariableName = AssignVarName (VarName);\r
+  mMeasuredAuthorityList[mMeasuredAuthorityCount].VendorGuid   = AssignVendorGuid (VendorGuid);\r
+  mMeasuredAuthorityList[mMeasuredAuthorityCount].Size         = Size;\r
+  mMeasuredAuthorityList[mMeasuredAuthorityCount].Data         = AllocatePool (Size);\r
+  if (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  CopyMem (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data, Data, Size);\r
+  mMeasuredAuthorityCount++;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function will return if this variable is already measured.\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[in]  VarData           The content of the variable data.  \r
+  @param[in]  VarSize           The size of the variable data.  \r
+\r
+  @retval TRUE  The data is already measured.\r
+  @retval FALSE The data is not measured yet.\r
+**/\r
+BOOLEAN\r
+IsDataMeasured (\r
+  IN      CHAR16                    *VarName,\r
+  IN      EFI_GUID                  *VendorGuid,\r
+  IN      VOID                      *Data,\r
+  IN      UINTN                     Size\r
+  )\r
+{\r
+  UINTN  Index;\r
+\r
+  for (Index = 0; Index < mMeasuredAuthorityCount; Index++) {\r
+    if ((StrCmp (VarName, mMeasuredAuthorityList[Index].VariableName) == 0) &&\r
+        (CompareGuid (VendorGuid, mMeasuredAuthorityList[Index].VendorGuid)) &&\r
+        (CompareMem (Data, mMeasuredAuthorityList[Index].Data, Size) == 0) &&\r
+        (Size == mMeasuredAuthorityList[Index].Size)) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  This function will return if this variable is SecureAuthority Variable.\r
+\r
+  @param[in]  VariableName      A Null-terminated string that is the name of the vendor's variable.\r
+  @param[in]  VendorGuid        A unique identifier for the vendor.\r
+\r
+  @retval TRUE  This is SecureAuthority Variable\r
+  @retval FALSE This is not SecureAuthority Variable\r
+**/\r
+BOOLEAN\r
+IsSecureAuthorityVariable (\r
+  IN CHAR16                                 *VariableName,\r
+  IN EFI_GUID                               *VendorGuid\r
+  )\r
+{\r
+  UINTN   Index;\r
+\r
+  for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
+    if ((StrCmp (VariableName, mVariableType[Index].VariableName) == 0) && \r
+        (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid))) {\r
+      return TRUE;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Measure and log an EFI variable, and extend the measurement result into a specific PCR.\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[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
+EFIAPI\r
+MeasureVariable (\r
+  IN      CHAR16                    *VarName,\r
+  IN      EFI_GUID                  *VendorGuid,\r
+  IN      VOID                      *VarData,\r
+  IN      UINTN                     VarSize\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             VarNameLength;\r
+  EFI_VARIABLE_DATA_TREE            *VarLog;\r
+  UINT32                            VarLogSize;\r
+\r
+  //\r
+  // The EFI_VARIABLE_DATA_TREE.VariableData value shall be the EFI_SIGNATURE_DATA value\r
+  // from the EFI_SIGNATURE_LIST that contained the authority that was used to validate the image\r
+  //\r
+  VarNameLength      = StrLen (VarName);\r
+  VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
+                        - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
+\r
+  VarLog = (EFI_VARIABLE_DATA_TREE *) AllocateZeroPool (VarLogSize);\r
+  if (VarLog == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  CopyMem (&VarLog->VariableName, VendorGuid, sizeof(VarLog->VariableName));\r
+  VarLog->UnicodeNameLength  = VarNameLength;\r
+  VarLog->VariableDataLength = VarSize;\r
+  CopyMem (\r
+     VarLog->UnicodeName,\r
+     VarName,\r
+     VarNameLength * sizeof (*VarName)\r
+     );\r
+  CopyMem (\r
+     (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
+     VarData,\r
+     VarSize\r
+     );\r
+\r
+  DEBUG ((EFI_D_INFO, "DxeImageVerification: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));\r
+  DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
+\r
+  Status = TpmMeasureAndLogData (\r
+             7,\r
+             EV_EFI_VARIABLE_AUTHORITY,\r
+             VarLog,\r
+             VarLogSize,\r
+             VarLog,\r
+             VarLogSize\r
+             );\r
+  FreePool (VarLog);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  SecureBoot Hook for processing image verification.\r
+\r
+  @param[in] VariableName                 Name of Variable to be found.\r
+  @param[in] VendorGuid                   Variable vendor GUID.\r
+  @param[in] DataSize                     Size of Data found. If size is less than the\r
+                                          data, this value contains the required size.\r
+  @param[in] Data                         Data pointer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SecureBootHook (\r
+  IN CHAR16                                 *VariableName,\r
+  IN EFI_GUID                               *VendorGuid,\r
+  IN UINTN                                  DataSize,\r
+  IN VOID                                   *Data\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+\r
+  if (!IsSecureAuthorityVariable (VariableName, VendorGuid)) {\r
+    return ;\r
+  }\r
+\r
+  if (IsDataMeasured (VariableName, VendorGuid, Data, DataSize)) {\r
+    DEBUG ((EFI_D_ERROR, "MeasureSecureAuthorityVariable - IsDataMeasured\n"));\r
+    return ;\r
+  }\r
+\r
+  Status = MeasureVariable (\r
+             VariableName,\r
+             VendorGuid,\r
+             Data,\r
+             DataSize\r
+             );\r
+  DEBUG ((EFI_D_ERROR, "MeasureBootPolicyVariable - %r\n", Status));\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    AddDataMeasured (VariableName, VendorGuid, Data, DataSize);\r
+  }\r
+\r
+  return ;\r
+}\r
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
new file mode 100644 (file)
index 0000000..3c81b5a
--- /dev/null
@@ -0,0 +1,700 @@
+/** @file\r
+  The library instance provides security service of TPM2 measure boot.\r
+\r
+  Caution: This file requires additional review when modified.\r
+  This library will have external input - PE/COFF image and GPT partition.\r
+  This external input must be validated carefully to avoid security issue like\r
+  buffer overflow, integer overflow.\r
+\r
+  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
+  data structure within this image buffer before use.\r
+\r
+  TrEEMeasureGptTable() function will receive untrusted GPT partition table, and parse\r
+  partition data carefully.\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 <PiDxe.h>\r
+\r
+#include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/DiskIo.h>\r
+#include <Protocol/DevicePathToText.h>\r
+#include <Protocol/FirmwareVolumeBlock.h>\r
+\r
+#include <Guid/MeasuredFvHob.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/BaseCryptLib.h>\r
+#include <Library/PeCoffLib.h>\r
+#include <Library/SecurityManagementLib.h>\r
+#include <Library/HobLib.h>\r
+\r
+//\r
+// Flag to check GPT partition. It only need be measured once.\r
+//\r
+BOOLEAN                           mTrEEMeasureGptTableFlag = FALSE;\r
+EFI_GUID                          mTrEEZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
+UINTN                             mTrEEMeasureGptCount = 0;\r
+VOID                              *mTrEEFileBuffer;\r
+UINTN                             mTrEEImageSize;\r
+//\r
+// Measured FV handle cache\r
+//\r
+EFI_HANDLE                        mTrEECacheMeasuredHandle  = NULL;\r
+MEASURED_HOB_DATA                 *mTrEEMeasuredHobData     = NULL;\r
+\r
+/**\r
+  Reads contents of a PE/COFF image in memory buffer.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  PE/COFF image is external input, so this function will make sure the PE/COFF image content\r
+  read is within the image buffer.\r
+\r
+  @param  FileHandle      Pointer to the file handle to read the PE/COFF image.\r
+  @param  FileOffset      Offset into the PE/COFF image to begin the read operation.\r
+  @param  ReadSize        On input, the size in bytes of the requested read operation.  \r
+                          On output, the number of bytes actually read.\r
+  @param  Buffer          Output buffer that contains the data read from the PE/COFF image.\r
+  \r
+  @retval EFI_SUCCESS     The specified portion of the PE/COFF image was read and the size \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeTpm2MeasureBootLibImageRead (\r
+  IN     VOID    *FileHandle,\r
+  IN     UINTN   FileOffset,\r
+  IN OUT UINTN   *ReadSize,\r
+  OUT    VOID    *Buffer\r
+  )\r
+{\r
+  UINTN               EndPosition;\r
+\r
+  if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (MAX_ADDRESS - FileOffset < *ReadSize) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  EndPosition = FileOffset + *ReadSize;\r
+  if (EndPosition > mTrEEImageSize) {\r
+    *ReadSize = (UINT32)(mTrEEImageSize - FileOffset);\r
+  }\r
+\r
+  if (FileOffset >= mTrEEImageSize) {\r
+    *ReadSize = 0;\r
+  }\r
+\r
+  CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Measure GPT table data into TPM log.\r
+\r
+  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 GptHandle               Handle that GPT partition was installed.\r
+\r
+  @retval EFI_SUCCESS            Successfully measure GPT table.\r
+  @retval EFI_UNSUPPORTED        Not support GPT table on the given handle.\r
+  @retval EFI_DEVICE_ERROR       Can't get GPT table because device error.\r
+  @retval EFI_OUT_OF_RESOURCES   No enough resource to measure GPT table.\r
+  @retval other error value\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TrEEMeasureGptTable (\r
+  IN  EFI_TREE_PROTOCOL  *TreeProtocol,\r
+  IN  EFI_HANDLE         GptHandle\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_BLOCK_IO_PROTOCOL             *BlockIo;\r
+  EFI_DISK_IO_PROTOCOL              *DiskIo;\r
+  EFI_PARTITION_TABLE_HEADER        *PrimaryHeader;\r
+  EFI_PARTITION_ENTRY               *PartitionEntry;\r
+  UINT8                             *EntryPtr;\r
+  UINTN                             NumberOfPartition;\r
+  UINT32                            Index;\r
+  TrEE_EVENT                        *TreeEvent;\r
+  EFI_GPT_DATA                      *GptData;\r
+  UINT32                            EventSize;\r
+\r
+  if (mTrEEMeasureGptCount > 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = gBS->HandleProtocol (GptHandle, &gEfiBlockIoProtocolGuid, (VOID**)&BlockIo);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Status = gBS->HandleProtocol (GptHandle, &gEfiDiskIoProtocolGuid, (VOID**)&DiskIo);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Read the EFI Partition Table Header\r
+  //  \r
+  PrimaryHeader = (EFI_PARTITION_TABLE_HEADER *) AllocatePool (BlockIo->Media->BlockSize);\r
+  if (PrimaryHeader == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }  \r
+  Status = DiskIo->ReadDisk (\r
+                     DiskIo,\r
+                     BlockIo->Media->MediaId,\r
+                     1 * BlockIo->Media->BlockSize,\r
+                     BlockIo->Media->BlockSize,\r
+                     (UINT8 *)PrimaryHeader\r
+                     );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Failed to Read Partition Table Header!\n"));\r
+    FreePool (PrimaryHeader);\r
+    return EFI_DEVICE_ERROR;\r
+  }  \r
+  //\r
+  // Read the partition entry.\r
+  //\r
+  EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry);\r
+  if (EntryPtr == NULL) {\r
+    FreePool (PrimaryHeader);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  Status = DiskIo->ReadDisk (\r
+                     DiskIo,\r
+                     BlockIo->Media->MediaId,\r
+                     MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),\r
+                     PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry,\r
+                     EntryPtr\r
+                     );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (PrimaryHeader);\r
+    FreePool (EntryPtr);\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  \r
+  //\r
+  // Count the valid partition\r
+  //\r
+  PartitionEntry    = (EFI_PARTITION_ENTRY *)EntryPtr;\r
+  NumberOfPartition = 0;\r
+  for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {\r
+    if (!CompareGuid (&PartitionEntry->PartitionTypeGUID, &mTrEEZeroGuid)) {\r
+      NumberOfPartition++;  \r
+    }\r
+    PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);\r
+  }\r
+\r
+  //\r
+  // Prepare Data for Measurement\r
+  // \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
+    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
+\r
+  //\r
+  // Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition\r
+  //  \r
+  CopyMem ((UINT8 *)GptData, (UINT8*)PrimaryHeader, sizeof (EFI_PARTITION_TABLE_HEADER));\r
+  GptData->NumberOfPartitions = NumberOfPartition;\r
+  //\r
+  // Copy the valid partition entry\r
+  //\r
+  PartitionEntry    = (EFI_PARTITION_ENTRY*)EntryPtr;\r
+  NumberOfPartition = 0;\r
+  for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {\r
+    if (!CompareGuid (&PartitionEntry->PartitionTypeGUID, &mTrEEZeroGuid)) {\r
+      CopyMem (\r
+        (UINT8 *)&GptData->Partitions + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry,\r
+        (UINT8 *)PartitionEntry,\r
+        PrimaryHeader->SizeOfPartitionEntry\r
+        );\r
+      NumberOfPartition++;\r
+    }\r
+    PartitionEntry =(EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);\r
+  }\r
+\r
+  //\r
+  // Measure the GPT data\r
+  //\r
+  Status = TreeProtocol->HashLogExtendEvent (\r
+             TreeProtocol,\r
+             0,\r
+             (EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) GptData,\r
+             (UINT64) EventSize,\r
+             TreeEvent\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    mTrEEMeasureGptCount++;\r
+  }\r
+\r
+  FreePool (PrimaryHeader);\r
+  FreePool (EntryPtr);\r
+  FreePool (TreeEvent);\r
+\r
+  return Status;\r
+}\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] TreeProtocol   Pointer to the located TREE 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
+  @param[in] ImageType      Image subsystem type.\r
+  @param[in] FilePath       File path is corresponding to the input image.\r
+\r
+  @retval EFI_SUCCESS            Successfully measure image.\r
+  @retval EFI_OUT_OF_RESOURCES   No enough resource to measure image.\r
+  @retval EFI_UNSUPPORTED        ImageType is unsupported or PE image is mal-format.  \r
+  @retval other error value\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TrEEMeasurePeImage (\r
+  IN  EFI_TREE_PROTOCOL         *TreeProtocol,\r
+  IN  EFI_PHYSICAL_ADDRESS      ImageAddress,\r
+  IN  UINTN                     ImageSize,\r
+  IN  UINTN                     LinkTimeBase,\r
+  IN  UINT16                    ImageType,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *FilePath\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TrEE_EVENT                        *TreeEvent;\r
+  EFI_IMAGE_LOAD_EVENT              *ImageLoad;\r
+  UINT32                            FilePathSize;\r
+  UINT32                            EventSize;\r
+\r
+  Status        = EFI_UNSUPPORTED;\r
+  ImageLoad     = NULL;\r
+  FilePathSize  = (UINT32) GetDevicePathSize (FilePath);\r
+\r
+  //\r
+  // 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
+    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
+\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
+      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
+      break;\r
+    case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
+      TreeEvent->Header.EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;\r
+      TreeEvent->Header.PCRIndex  = 2;\r
+      break;\r
+    default:\r
+      DEBUG ((\r
+        EFI_D_ERROR,\r
+        "TrEEMeasurePeImage: Unknown subsystem type %d",\r
+        ImageType\r
+        ));\r
+      goto Finish;\r
+  }\r
+\r
+  ImageLoad->ImageLocationInMemory = ImageAddress;\r
+  ImageLoad->ImageLengthInMemory   = ImageSize;\r
+  ImageLoad->ImageLinkTimeAddress  = LinkTimeBase;\r
+  ImageLoad->LengthOfDevicePath    = FilePathSize;\r
+  CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);\r
+\r
+  //\r
+  // Log the PE data\r
+  //\r
+  Status = TreeProtocol->HashLogExtendEvent (\r
+             TreeProtocol,\r
+             PE_COFF_IMAGE,\r
+             ImageAddress,\r
+             ImageSize,\r
+             TreeEvent\r
+             );\r
+  if (Status == EFI_VOLUME_FULL) {\r
+    //\r
+    // Volume full here means the image is hashed and its result is extended to PCR.\r
+    // But the event log cann't be saved since log area is full.\r
+    // Just return EFI_SUCCESS in order not to block the image load.\r
+    //\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
+Finish:\r
+  FreePool (TreeEvent);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  The security handler is used to abstract platform-specific policy \r
+  from the DXE core response to an attempt to use a file that returns a \r
+  given status for the authentication check from the section extraction protocol.  \r
+\r
+  The possible responses in a given SAP implementation may include locking \r
+  flash upon failure to authenticate, attestation logging for all signed drivers, \r
+  and other exception operations.  The File parameter allows for possible logging \r
+  within the SAP of the driver.\r
+\r
+  If File is NULL, then EFI_INVALID_PARAMETER is returned.\r
+\r
+  If the file specified by File with an authentication status specified by \r
+  AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned.\r
+\r
+  If the file specified by File with an authentication status specified by \r
+  AuthenticationStatus is not safe for the DXE Core to use under any circumstances, \r
+  then EFI_ACCESS_DENIED is returned.\r
+\r
+  If the file specified by File with an authentication status specified by \r
+  AuthenticationStatus is not safe for the DXE Core to use right now, but it \r
+  might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is \r
+  returned.\r
+\r
+  @param[in]      AuthenticationStatus  This is the authentication status returned\r
+                                        from the securitymeasurement services for the\r
+                                        input file.\r
+  @param[in]      File       This is a pointer to the device path of the file that is\r
+                             being dispatched. This will optionally be used for logging.\r
+  @param[in]      FileBuffer File buffer matches the input file device path.\r
+  @param[in]      FileSize   Size of File buffer matches the input file device path.\r
+  @param[in]      BootPolicy A boot policy that was used to call LoadImage() UEFI service.\r
+\r
+  @retval EFI_SUCCESS             The file specified by DevicePath and non-NULL\r
+                                  FileBuffer did authenticate, and the platform policy dictates\r
+                                  that the DXE Foundation may use the file.\r
+  @retval other error value\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeTpm2MeasureBootHandler (\r
+  IN  UINT32                           AuthenticationStatus,\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File,\r
+  IN  VOID                             *FileBuffer,\r
+  IN  UINTN                            FileSize,\r
+  IN  BOOLEAN                          BootPolicy\r
+  )\r
+{\r
+  EFI_TREE_PROTOCOL                   *TreeProtocol;\r
+  EFI_STATUS                          Status;\r
+  TREE_BOOT_SERVICE_CAPABILITY        ProtocolCapability;\r
+  EFI_DEVICE_PATH_PROTOCOL            *DevicePathNode;\r
+  EFI_DEVICE_PATH_PROTOCOL            *OrigDevicePathNode;\r
+  EFI_HANDLE                          Handle;\r
+  EFI_HANDLE                          TempHandle;\r
+  BOOLEAN                             ApplicationRequired;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT        ImageContext;\r
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvbProtocol;\r
+  EFI_PHYSICAL_ADDRESS                FvAddress;\r
+  UINT32                              Index;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // TrEE 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_ERROR, "DxeTpm2MeasureBootHandler - TrEE - %r\n", Status));\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  ProtocolCapability.Size = (UINT8) sizeof (ProtocolCapability);\r
+  Status = TreeProtocol->GetCapability (\r
+                           TreeProtocol, \r
+                           &ProtocolCapability\r
+                           );\r
+  if (EFI_ERROR (Status) || !ProtocolCapability.TrEEPresentFlag) {\r
+    //\r
+    // TPM device doesn't work or activate.\r
+    //\r
+    DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler (%r) - TrEEPresentFlag - %x\n", Status, ProtocolCapability.TrEEPresentFlag));\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Copy File Device Path\r
+  //\r
+  OrigDevicePathNode = DuplicateDevicePath (File);\r
+  \r
+  //\r
+  // 1. Check whether this device path support BlockIo protocol.\r
+  // Is so, this device path may be a GPT device path.\r
+  //\r
+  DevicePathNode = OrigDevicePathNode;\r
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);\r
+  if (!EFI_ERROR (Status) && !mTrEEMeasureGptTableFlag) {\r
+    //\r
+    // Find the gpt partion on the given devicepath\r
+    //\r
+    DevicePathNode = OrigDevicePathNode;\r
+    ASSERT (DevicePathNode != NULL);\r
+    while (!IsDevicePathEnd (DevicePathNode)) {\r
+      //\r
+      // Find the Gpt partition\r
+      //\r
+      if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH &&\r
+            DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP) {\r
+        //\r
+        // Check whether it is a gpt partition or not\r
+        //                           \r
+        if (((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER && \r
+            ((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID) {\r
+\r
+          //\r
+          // Change the partition device path to its parent device path (disk) and get the handle.\r
+          //\r
+          DevicePathNode->Type    = END_DEVICE_PATH_TYPE;\r
+          DevicePathNode->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;\r
+          DevicePathNode          = OrigDevicePathNode;\r
+          Status = gBS->LocateDevicePath (\r
+                         &gEfiDiskIoProtocolGuid,\r
+                         &DevicePathNode,\r
+                         &Handle\r
+                         );\r
+          if (!EFI_ERROR (Status)) {\r
+            //\r
+            // Measure GPT disk.\r
+            //\r
+            Status = TrEEMeasureGptTable (TreeProtocol, Handle);\r
+            DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler - TrEEMeasureGptTable - %r\n", Status));\r
+            if (!EFI_ERROR (Status)) {\r
+              //\r
+              // GPT disk check done.\r
+              //\r
+              mTrEEMeasureGptTableFlag = TRUE;\r
+            }\r
+          }\r
+          FreePool (OrigDevicePathNode);\r
+          OrigDevicePathNode = DuplicateDevicePath (File);\r
+          ASSERT (OrigDevicePathNode != NULL);\r
+          break;\r
+        }\r
+      }\r
+      DevicePathNode    = NextDevicePathNode (DevicePathNode);\r
+    }\r
+  }\r
+  \r
+  //\r
+  // 2. Measure PE image.\r
+  //\r
+  ApplicationRequired = FALSE;\r
+\r
+  //\r
+  // Check whether this device path support FVB protocol.\r
+  //\r
+  DevicePathNode = OrigDevicePathNode;\r
+  Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Don't check FV image, and directly return EFI_SUCCESS.\r
+    // It can be extended to the specific FV authentication according to the different requirement.\r
+    //\r
+    if (IsDevicePathEnd (DevicePathNode)) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    //\r
+    // The PE image from unmeasured Firmware volume need be measured\r
+    // The PE image from measured Firmware volume will be mearsured according to policy below.\r
+    //   If it is driver, do not measure\r
+    //   If it is application, still measure.\r
+    //\r
+    ApplicationRequired = TRUE;\r
+\r
+    if (mTrEECacheMeasuredHandle != Handle && mTrEEMeasuredHobData != NULL) {\r
+      //\r
+      // Search for Root FV of this PE image\r
+      //\r
+      TempHandle = Handle;\r
+      do {\r
+        Status = gBS->HandleProtocol(\r
+                        TempHandle, \r
+                        &gEfiFirmwareVolumeBlockProtocolGuid,\r
+                        (VOID**)&FvbProtocol\r
+                        );\r
+        TempHandle = FvbProtocol->ParentHandle;\r
+      } while (!EFI_ERROR(Status) && FvbProtocol->ParentHandle != NULL);\r
+\r
+      //\r
+      // Search in measured FV Hob\r
+      //\r
+      Status = FvbProtocol->GetPhysicalAddress(FvbProtocol, &FvAddress);\r
+      if (EFI_ERROR(Status)){\r
+        return Status;\r
+      }\r
+\r
+      ApplicationRequired = FALSE;\r
+\r
+      for (Index = 0; Index < mTrEEMeasuredHobData->Num; Index++) {\r
+        if(mTrEEMeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) {\r
+          //\r
+          // Cache measured FV for next measurement\r
+          //\r
+          mTrEECacheMeasuredHandle = Handle;\r
+          ApplicationRequired  = TRUE;\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // File is not found.\r
+  //\r
+  if (FileBuffer == NULL) {\r
+    Status = EFI_SECURITY_VIOLATION;\r
+    goto Finish;\r
+  }\r
+\r
+  mTrEEImageSize  = FileSize;\r
+  mTrEEFileBuffer = FileBuffer;\r
+\r
+  //\r
+  // Measure PE Image\r
+  //\r
+  DevicePathNode = OrigDevicePathNode;\r
+  ZeroMem (&ImageContext, sizeof (ImageContext));\r
+  ImageContext.Handle    = (VOID *) FileBuffer;\r
+  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) DxeTpm2MeasureBootLibImageRead;\r
+\r
+  //\r
+  // Get information about the image being loaded\r
+  //\r
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // The information can't be got from the invalid PeImage\r
+    //\r
+    goto Finish;\r
+  }\r
+  \r
+  //\r
+  // Measure only application if Application flag is set\r
+  // Measure drivers and applications if Application flag is not set\r
+  //\r
+  if ((!ApplicationRequired) || \r
+        (ApplicationRequired && ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) {  \r
+    //\r
+    // Print the image path to be measured.\r
+    //    \r
+    DEBUG_CODE_BEGIN ();\r
+      CHAR16                            *ToText;\r
+      ToText = ConvertDevicePathToText (\r
+                 DevicePathNode,\r
+                 FALSE,\r
+                 TRUE\r
+                 );\r
+      if (ToText != NULL) {\r
+        DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText));\r
+        FreePool (ToText);\r
+      }\r
+    DEBUG_CODE_END ();\r
+\r
+    //\r
+    // Measure PE image into TPM log.\r
+    //\r
+    Status = TrEEMeasurePeImage (\r
+               TreeProtocol,\r
+               (EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer, \r
+               FileSize, \r
+               (UINTN) ImageContext.ImageAddress, \r
+               ImageContext.ImageType, \r
+               DevicePathNode\r
+               );\r
+    DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler - TrEEMeasurePeImage - %r\n", Status));\r
+  }\r
+\r
+  //\r
+  // Done, free the allocated resource.\r
+  //\r
+Finish:\r
+  if (OrigDevicePathNode != NULL) {\r
+    FreePool (OrigDevicePathNode);\r
+  }\r
+\r
+  DEBUG ((EFI_D_ERROR, "DxeTpm2MeasureBootHandler - %r\n", Status));\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Register the security handler to provide TPM measure boot service.\r
+\r
+  @param  ImageHandle  ImageHandle of the loaded driver.\r
+  @param  SystemTable  Pointer to the EFI System Table.\r
+\r
+  @retval  EFI_SUCCESS            Register successfully.\r
+  @retval  EFI_OUT_OF_RESOURCES   No enough memory to register this handler.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeTpm2MeasureBootLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_HOB_GUID_TYPE  *GuidHob;\r
+\r
+  GuidHob = NULL;\r
+\r
+  GuidHob = GetFirstGuidHob (&gMeasuredFvHobGuid);\r
+\r
+  if (GuidHob != NULL) {\r
+    mTrEEMeasuredHobData = GET_GUID_HOB_DATA (GuidHob);\r
+  }\r
+\r
+  return RegisterSecurity2Handler (\r
+          DxeTpm2MeasureBootHandler,\r
+          EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED\r
+          );\r
+}\r
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
new file mode 100644 (file)
index 0000000..4dfd62b
--- /dev/null
@@ -0,0 +1,63 @@
+## @file\r
+#  The library instance provides security service of TPM2 measure boot.\r
+#\r
+#  Caution: This module requires additional review when modified.\r
+#  This library will have external input - PE/COFF image and GPT partition.\r
+#  This external input must be validated carefully to avoid security issue like\r
+#  buffer overflow, integer overflow.\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
+# 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                      = DxeTpm2MeasureBootLib\r
+  FILE_GUID                      = 778CE4F4-36BD-4ae7-B8F0-10B420B0D174\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER \r
+  CONSTRUCTOR                    = DxeTpm2MeasureBootLibConstructor\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
+  DxeTpm2MeasureBootLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  CryptoPkg/CryptoPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  DebugLib\r
+  MemoryAllocationLib\r
+  DevicePathLib\r
+  UefiBootServicesTableLib\r
+  BaseCryptLib\r
+  PeCoffLib\r
+  BaseLib\r
+  SecurityManagementLib\r
+  HobLib\r
+\r
+[Guids]\r
+  gMeasuredFvHobGuid\r
+\r
+[Protocols]\r
+  gEfiTrEEProtocolGuid                   ## CONSUMES\r
+  gEfiFirmwareVolumeBlockProtocolGuid   ## CONSUMES\r
+  gEfiBlockIoProtocolGuid               ## CONSUMES\r
+  gEfiDiskIoProtocolGuid                ## CONSUMES\r
+\r
index b4732bc..ffeac59 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, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2012 - 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
@@ -15,6 +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
 \r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
@@ -93,6 +94,67 @@ Tpm12MeasureAndLogData (
   return Status;\r
 }\r
 \r
+/**\r
+  Tpm20 measure and log data, 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]  EventLog         Measurement event log.\r
+  @param[in]  LogLen           Event log length in bytes.\r
+  @param[in]  HashData         The start of the data buffer to be hashed, extended.\r
+  @param[in]  HashDataLen      The length, in bytes, of the buffer referenced by HashData\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_UNSUPPORTED       TPM device not available.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+Tpm20MeasureAndLogData (\r
+  IN UINT32             PcrIndex,\r
+  IN UINT32             EventType,\r
+  IN VOID               *EventLog,\r
+  IN UINT32             LogLen,\r
+  IN VOID               *HashData,\r
+  IN UINT64             HashDataLen\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_TREE_PROTOCOL         *TreeProtocol;\r
+  TrEE_EVENT                *TreeEvent;\r
+\r
+  //\r
+  // TrEEPresentFlag is checked in HashLogExtendEvent\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  TreeEvent = (TrEE_EVENT *) AllocateZeroPool (LogLen + sizeof (TrEE_EVENT));\r
+  if(TreeEvent == 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
+\r
+  Status = TreeProtocol->HashLogExtendEvent (\r
+                           TreeProtocol,\r
+                           0,\r
+                           (EFI_PHYSICAL_ADDRESS)(UINTN)HashData,\r
+                           HashDataLen,\r
+                           TreeEvent\r
+                           );\r
+  FreePool (TreeEvent);\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Tpm measure and log data, and extend the measurement result into a specific PCR.\r
 \r
@@ -132,6 +194,19 @@ TpmMeasureAndLogData (
                HashData,\r
                HashDataLen\r
                );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Try to measure using Tpm20 protocol\r
+    //\r
+    Status = Tpm20MeasureAndLogData(\r
+               PcrIndex,\r
+               EventType,\r
+               EventLog,\r
+               LogLen,\r
+               HashData,\r
+               HashDataLen\r
+               );\r
+  }\r
 \r
   return Status;\r
 }\r
index a09900f..75cc773 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
-#  This library is used by other modules to measure data to TPM 1.2.\r
+#  This library is used by other modules to measure data to TPM 1.2 or TPM 2.0.\r
 #\r
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2012 - 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
@@ -40,4 +40,5 @@
   UefiBootServicesTableLib\r
 \r
 [Protocols]\r
-  gEfiTcgProtocolGuid
\ No newline at end of file
+  gEfiTcgProtocolGuid\r
+  gEfiTrEEProtocolGuid\r
diff --git a/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c b/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c
new file mode 100644 (file)
index 0000000..28b809b
--- /dev/null
@@ -0,0 +1,716 @@
+/** @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
+  TrEEExecutePendingTpmRequest() will receive untrusted input and do validation.\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 <PiDxe.h>\r
+\r
+#include <Protocol/TrEEProtocol.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 <Guid/EventGroup.h>\r
+#include <Guid/TrEEPhysicalPresenceData.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+\r
+#define TPM_PP_SUCCESS              0\r
+#define TPM_PP_USER_ABORT           ((TPM_RESULT)(-0x10))\r
+#define TPM_PP_BIOS_FAILURE         ((TPM_RESULT)(-0x0f))\r
+\r
+#define CONFIRM_BUFFER_SIZE         4096\r
+\r
+EFI_HII_HANDLE mTrEEPpStringPackHandle;\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
+TrEEPhysicalPresenceGetStringById (\r
+  IN  EFI_STRING_ID   Id\r
+  )\r
+{\r
+  return HiiGetString (mTrEEPpStringPackHandle, 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
+TpmCommandClear (\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_ERROR, "Tpm2ClearControl ... \n"));\r
+  Status = Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO);\r
+  DEBUG ((EFI_D_ERROR, "Tpm2ClearControl - %r\n", Status));\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  DEBUG ((EFI_D_ERROR, "Tpm2Clear ... \n"));\r
+  Status = Tpm2Clear (TPM_RH_PLATFORM, AuthSession);\r
+  DEBUG ((EFI_D_ERROR, "Tpm2Clear - %r\n", Status));\r
+\r
+Done:\r
+  ZeroMem (&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));\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, out] PpiFlags            The physical presence interface flags.\r
+  \r
+  @retval TPM_PP_BIOS_FAILURE         Unknown physical presence operation.\r
+  @retval TPM_PP_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
+TPM_RESULT\r
+TrEEExecutePhysicalPresence (\r
+  IN      TPM2B_AUTH                *PlatformAuth,  OPTIONAL\r
+  IN      UINT8                     CommandCode,\r
+  IN OUT  UINT8                     *PpiFlags\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  switch (CommandCode) {\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:\r
+      Status = TpmCommandClear (PlatformAuth);\r
+      if (EFI_ERROR (Status)) {\r
+        return TPM_PP_BIOS_FAILURE;\r
+      } else {\r
+        return TPM_PP_SUCCESS;\r
+      }\r
+\r
+    case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:\r
+      *PpiFlags &= ~TREE_FLAG_NO_PPI_CLEAR;\r
+      return TPM_PP_SUCCESS;\r
+\r
+    case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:\r
+      *PpiFlags |= TREE_FLAG_NO_PPI_CLEAR;\r
+      return TPM_PP_SUCCESS;\r
+\r
+    default:\r
+      if (CommandCode <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
+        return TPM_PP_SUCCESS;\r
+      } else {\r
+        return TPM_PP_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
+TrEEReadUserKey (\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
+  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
+TrEEPhysicalPresenceLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  mTrEEPpStringPackHandle = HiiAddPackages (&gEfiTrEEPhysicalPresenceGuid, ImageHandle, DxeTrEEPhysicalPresenceLibStrings, NULL);\r
+  ASSERT (mTrEEPpStringPackHandle != NULL);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Display the confirm text and get user confirmation.\r
+\r
+  @param[in] TpmPpCommand  The requested TPM physical presence command.\r
+\r
+  @retval    TRUE          The user has confirmed the changes.\r
+  @retval    FALSE         The user doesn't confirm the changes.\r
+**/\r
+BOOLEAN\r
+TrEEUserConfirm (\r
+  IN      UINT8                     TpmPpCommand\r
+  )\r
+{\r
+  CHAR16                            *ConfirmText;\r
+  CHAR16                            *TmpStr1;\r
+  CHAR16                            *TmpStr2; \r
+  UINTN                             BufSize;\r
+  BOOLEAN                           CautionKey;\r
+  UINT16                            Index;\r
+  CHAR16                            DstStr[81];\r
+    \r
+  TmpStr2     = NULL;\r
+  CautionKey  = FALSE;\r
+  BufSize     = CONFIRM_BUFFER_SIZE;\r
+  ConfirmText = AllocateZeroPool (BufSize);\r
+  ASSERT (ConfirmText != NULL);\r
+\r
+  switch (TpmPpCommand) {\r
+\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
+\r
+      TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);      \r
+\r
+      TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
+\r
+      TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1); \r
+\r
+      TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    default:\r
+      ;\r
+  }\r
+\r
+  if (TmpStr2 == NULL) {\r
+    FreePool (ConfirmText);\r
+    return FALSE;\r
+  }\r
+\r
+  TmpStr1 = TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));\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
+    StrnCpy(DstStr, ConfirmText + Index, 80);    \r
+    Print (DstStr);    \r
+  }\r
+  \r
+  FreePool (TmpStr1);\r
+  FreePool (TmpStr2);\r
+  FreePool (ConfirmText);\r
+\r
+  if (TrEEReadUserKey (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 TrEE 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
+TrEEHaveValidTpmRequest  (\r
+  IN      EFI_TREE_PHYSICAL_PRESENCE     *TcgPpData,\r
+  IN      UINT8                          Flags,\r
+  OUT     BOOLEAN                        *RequestConfirmed\r
+  )\r
+{\r
+  *RequestConfirmed = FALSE;\r
+\r
+  switch (TcgPpData->PPRequest) {\r
+    case TREE_PHYSICAL_PRESENCE_NO_ACTION:\r
+      *RequestConfirmed = TRUE;\r
+      return TRUE;\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:\r
+      if ((Flags & TREE_FLAG_NO_PPI_CLEAR) != 0) {\r
+        *RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:\r
+      *RequestConfirmed = TRUE;\r
+      break;\r
+\r
+    case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:\r
+      break;\r
+\r
+    default:\r
+      //\r
+      // Wrong Physical Presence command\r
+      //\r
+      return FALSE;\r
+  }\r
+\r
+  if ((Flags & TREE_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
+TrEEExecutePendingTpmRequest (\r
+  IN      TPM2B_AUTH                     *PlatformAuth,  OPTIONAL\r
+  IN      EFI_TREE_PHYSICAL_PRESENCE     *TcgPpData,\r
+  IN      UINT8                          Flags\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  BOOLEAN                           RequestConfirmed;\r
+  UINT8                             NewFlags;\r
+\r
+  if (TcgPpData->PPRequest == TREE_PHYSICAL_PRESENCE_NO_ACTION) {\r
+    //\r
+    // No operation request\r
+    //\r
+    return;\r
+  }\r
+\r
+  if (!TrEEHaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {\r
+    //\r
+    // Invalid operation request.\r
+    //\r
+    if (TcgPpData->PPRequest <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
+      TcgPpData->PPResponse = TPM_PP_SUCCESS;\r
+    } else {\r
+      TcgPpData->PPResponse = TPM_PP_BIOS_FAILURE;\r
+    }\r
+    TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
+    TcgPpData->PPRequest = TREE_PHYSICAL_PRESENCE_NO_ACTION;\r
+    DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);\r
+    Status = gRT->SetVariable (\r
+                    TREE_PHYSICAL_PRESENCE_VARIABLE,\r
+                    &gEfiTrEEPhysicalPresenceGuid,\r
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                    DataSize,\r
+                    TcgPpData\r
+                    );\r
+    return;\r
+  }\r
+\r
+  if (!RequestConfirmed) {\r
+    //\r
+    // Print confirm text and wait for approval. \r
+    //\r
+    RequestConfirmed = TrEEUserConfirm (TcgPpData->PPRequest\r
+                                        );\r
+  }\r
+\r
+  //\r
+  // Execute requested physical presence command\r
+  //\r
+  TcgPpData->PPResponse = TPM_PP_USER_ABORT;\r
+  NewFlags = Flags;\r
+  if (RequestConfirmed) {\r
+    TcgPpData->PPResponse = TrEEExecutePhysicalPresence (PlatformAuth, TcgPpData->PPRequest, \r
+                                                         &NewFlags);\r
+  }\r
+\r
+  //\r
+  // Save the flags if it is updated.\r
+  //\r
+  if (Flags != NewFlags) {\r
+    Status   = gRT->SetVariable (\r
+                      TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                      &gEfiTrEEPhysicalPresenceGuid,\r
+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                      sizeof (UINT8),\r
+                      &NewFlags\r
+                      ); \r
+  }\r
+\r
+  //\r
+  // Clear request\r
+  //\r
+  if ((NewFlags & TREE_FLAG_RESET_TRACK) == 0) {\r
+    TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
+    TcgPpData->PPRequest = TREE_PHYSICAL_PRESENCE_NO_ACTION;    \r
+  }\r
+\r
+  //\r
+  // Save changes\r
+  //\r
+  DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);\r
+  Status = gRT->SetVariable (\r
+                  TREE_PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiTrEEPhysicalPresenceGuid,\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 == TPM_PP_USER_ABORT) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Reset system to make new TPM settings in effect\r
+  //\r
+  switch (TcgPpData->LastPPRequest) {\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:\r
+    case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:\r
+      break;\r
+    default:\r
+      if (TcgPpData->PPRequest != TREE_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
+TrEEPhysicalPresenceLibProcessRequest (\r
+  IN      TPM2B_AUTH                     *PlatformAuth  OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  EFI_TREE_PHYSICAL_PRESENCE        TcgPpData;\r
+  EFI_TREE_PROTOCOL                 *TreeProtocol;\r
+  EDKII_VARIABLE_LOCK_PROTOCOL      *VariableLockProtocol;\r
+  UINT8                             PpiFlags;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return ;\r
+  }\r
+\r
+  //\r
+  // Initialize physical presence flags.\r
+  //\r
+  DataSize = sizeof (UINT8);\r
+  Status = gRT->GetVariable (\r
+                  TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                  &gEfiTrEEPhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &PpiFlags\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    if (Status == EFI_NOT_FOUND) {\r
+      PpiFlags = 0;\r
+      Status   = gRT->SetVariable (\r
+                        TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                        &gEfiTrEEPhysicalPresenceGuid,\r
+                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                        sizeof (UINT8),\r
+                        &PpiFlags\r
+                        );\r
+    }\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+  DEBUG ((EFI_D_ERROR, "[TPM2] PpiFlags = %x, Status = %r\n", PpiFlags, Status));\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
+                                     TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                                     &gEfiTrEEPhysicalPresenceGuid\r
+                                     );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "[TPM2] Error when lock variable %s, Status = %r\n", TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Initialize physical presence variable.\r
+  //\r
+  DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);\r
+  Status = gRT->GetVariable (\r
+                  TREE_PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiTrEEPhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &TcgPpData\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    if (Status == EFI_NOT_FOUND) {\r
+      ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));\r
+      DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);\r
+      Status   = gRT->SetVariable (\r
+                        TREE_PHYSICAL_PRESENCE_VARIABLE,\r
+                        &gEfiTrEEPhysicalPresenceGuid,\r
+                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                        DataSize,\r
+                        &TcgPpData\r
+                        );\r
+    }\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  DEBUG ((EFI_D_ERROR, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));\r
+\r
+  //\r
+  // Execute pending TPM request.\r
+  //  \r
+  TrEEExecutePendingTpmRequest (PlatformAuth, &TcgPpData, PpiFlags);\r
+  DEBUG ((EFI_D_ERROR, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags));\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
+TrEEPhysicalPresenceLibNeedUserConfirm(\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_TREE_PHYSICAL_PRESENCE        TcgPpData;\r
+  UINTN                             DataSize;\r
+  BOOLEAN                           RequestConfirmed;\r
+  EFI_TREE_PROTOCOL                 *TreeProtocol;\r
+  UINT8                             PpiFlags;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check Tpm requests\r
+  //\r
+  DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);\r
+  Status = gRT->GetVariable (\r
+                  TREE_PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiTrEEPhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &TcgPpData\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+  DataSize = sizeof (UINT8);\r
+  Status = gRT->GetVariable (\r
+                  TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+                  &gEfiTrEEPhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &PpiFlags\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+  \r
+  if (TcgPpData.PPRequest == TREE_PHYSICAL_PRESENCE_NO_ACTION) {\r
+    //\r
+    // No operation request\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  if (!TrEEHaveValidTpmRequest(&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
diff --git a/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.inf b/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.inf
new file mode 100644 (file)
index 0000000..3ef9a82
--- /dev/null
@@ -0,0 +1,59 @@
+## @file\r
+# TrEE physical presence library instance. This library will execute TPM2 request.\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, 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                      = DxeTrEEPhysicalPresenceLib   \r
+  FILE_GUID                      = 601ECB06-7874-489e-A280-805780F6C861\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = TrEEPhysicalPresenceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_APPLICATION UEFI_DRIVER \r
+  CONSTRUCTOR                    = TrEEPhysicalPresenceLibConstructor\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
+  DxeTrEEPhysicalPresenceLib.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
+  Tpm2CommandLib\r
+\r
+[Protocols]\r
+  gEfiTrEEProtocolGuid\r
+  gEdkiiVariableLockProtocolGuid\r
+\r
+[Guids]\r
+  gEfiTrEEPhysicalPresenceGuid\r
diff --git a/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/PhysicalPresenceStrings.uni b/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/PhysicalPresenceStrings.uni
new file mode 100644 (file)
index 0000000..26c10ac
Binary files /dev/null and b/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/PhysicalPresenceStrings.uni differ
diff --git a/SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c b/SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c
new file mode 100644 (file)
index 0000000..a42c60d
--- /dev/null
@@ -0,0 +1,155 @@
+/** @file\r
+  Ihis library is BaseCrypto SHA1 hash instance.\r
+  It can be registered to BaseCrypto router, to serve as hash engine.\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 <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HashLib.h>\r
+\r
+/**\r
+  The function set SHA1 to digest list.\r
+\r
+  @param DigestList digest list\r
+  @param Sha1Digest SHA1 digest\r
+**/\r
+VOID\r
+Tpm2SetSha1ToDigestList (\r
+  IN TPML_DIGEST_VALUES *DigestList,\r
+  IN UINT8              *Sha1Digest\r
+  )\r
+{\r
+  DigestList->count = 1;\r
+  DigestList->digests[0].hashAlg = TPM_ALG_SHA1;\r
+  CopyMem (\r
+    DigestList->digests[0].digest.sha1,\r
+    Sha1Digest,\r
+    SHA1_DIGEST_SIZE\r
+    );\r
+}\r
+\r
+/**\r
+  Start hash sequence.\r
+\r
+  @param HashHandle Hash handle.\r
+\r
+  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.\r
+  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Sha1HashInit (\r
+  OUT HASH_HANDLE    *HashHandle\r
+  )\r
+{\r
+  VOID     *Sha1Ctx;\r
+  UINTN    CtxSize;\r
+\r
+  CtxSize = Sha1GetContextSize ();\r
+  Sha1Ctx = AllocatePool (CtxSize);\r
+  ASSERT (Sha1Ctx != NULL);\r
+\r
+  Sha1Init (Sha1Ctx);\r
+\r
+  *HashHandle = (HASH_HANDLE)Sha1Ctx;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update hash sequence data.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence updated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Sha1HashUpdate (\r
+  IN HASH_HANDLE    HashHandle,\r
+  IN VOID           *DataToHash,\r
+  IN UINTN          DataToHashLen\r
+  )\r
+{\r
+  VOID     *Sha1Ctx;\r
+\r
+  Sha1Ctx = (VOID *)HashHandle;\r
+  Sha1Update (Sha1Ctx, DataToHash, DataToHashLen);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Complete hash sequence complete.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Sha1HashFinal (\r
+  IN HASH_HANDLE         HashHandle,\r
+  OUT TPML_DIGEST_VALUES *DigestList\r
+  )\r
+{\r
+  UINT8         Digest[SHA1_DIGEST_SIZE];\r
+  VOID          *Sha1Ctx;\r
+\r
+  Sha1Ctx = (VOID *)HashHandle;\r
+  Sha1Final (Sha1Ctx, Digest);\r
+\r
+  FreePool (Sha1Ctx);\r
+  \r
+  Tpm2SetSha1ToDigestList (DigestList, Digest);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+HASH_INTERFACE  mSha1InternalHashInstance = {\r
+  HASH_ALGORITHM_SHA1_GUID,\r
+  Sha1HashInit,\r
+  Sha1HashUpdate,\r
+  Sha1HashFinal,\r
+};\r
+\r
+/**\r
+  The function register SHA1 instance.\r
+  \r
+  @retval EFI_SUCCESS   SHA1 instance is registered, or system dose not surpport registr SHA1 instance\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashInstanceLibSha1Constructor (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = RegisterHashInterfaceLib (&mSha1InternalHashInstance);\r
+  if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {\r
+    //\r
+    // Unsupported means platform policy does not need this instance enabled.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+  return Status;\r
+}
\ No newline at end of file
diff --git a/SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf b/SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
new file mode 100644 (file)
index 0000000..d5fe6fe
--- /dev/null
@@ -0,0 +1,44 @@
+## @file\r
+#  Ihis library is BaseCrypto SHA1 hash instance.\r
+#  It can be registered to BaseCrypto router, to serve as hash engine.\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
+# 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                      = HashInstanceLibSha1\r
+  FILE_GUID                      = 9A7A6AB4-9DA6-4aa4-90CB-6D4B79EDA7B9\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL\r
+  CONSTRUCTOR                    = HashInstanceLibSha1Constructor\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
+  HashInstanceLibSha1.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  CryptoPkg/CryptoPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  Tpm2CommandLib\r
+  MemoryAllocationLib\r
+  BaseCryptLib\r
diff --git a/SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.c b/SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.c
new file mode 100644 (file)
index 0000000..abc97b4
--- /dev/null
@@ -0,0 +1,155 @@
+/** @file\r
+  Ihis library is BaseCrypto SHA256 hash instance.\r
+  It can be registered to BaseCrypto router, to serve as hash engine.\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 <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HashLib.h>\r
+\r
+/**\r
+  The function set SHA256 to digest list.\r
+\r
+  @param DigestList   digest list\r
+  @param Sha256Digest SHA256 digest\r
+**/\r
+VOID\r
+Tpm2SetSha256ToDigestList (\r
+  IN TPML_DIGEST_VALUES *DigestList,\r
+  IN UINT8              *Sha256Digest\r
+  )\r
+{\r
+  DigestList->count = 1;\r
+  DigestList->digests[0].hashAlg = TPM_ALG_SHA256;\r
+  CopyMem (\r
+    DigestList->digests[0].digest.sha256,\r
+    Sha256Digest,\r
+    SHA256_DIGEST_SIZE\r
+    );\r
+}\r
+\r
+/**\r
+  Start hash sequence.\r
+\r
+  @param HashHandle Hash handle.\r
+\r
+  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.\r
+  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Sha256HashInit (\r
+  OUT HASH_HANDLE    *HashHandle\r
+  )\r
+{\r
+  VOID     *Sha256Ctx;\r
+  UINTN    CtxSize;\r
+\r
+  CtxSize = Sha256GetContextSize ();\r
+  Sha256Ctx = AllocatePool (CtxSize);\r
+  ASSERT (Sha256Ctx != NULL);\r
+\r
+  Sha256Init (Sha256Ctx);\r
+\r
+  *HashHandle = (HASH_HANDLE)Sha256Ctx;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update hash sequence data.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence updated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Sha256HashUpdate (\r
+  IN HASH_HANDLE    HashHandle,\r
+  IN VOID           *DataToHash,\r
+  IN UINTN          DataToHashLen\r
+  )\r
+{\r
+  VOID     *Sha256Ctx;\r
+\r
+  Sha256Ctx = (VOID *)HashHandle;\r
+  Sha256Update (Sha256Ctx, DataToHash, DataToHashLen);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Complete hash sequence complete.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Sha256HashFinal (\r
+  IN HASH_HANDLE         HashHandle,\r
+  OUT TPML_DIGEST_VALUES *DigestList\r
+  )\r
+{\r
+  UINT8         Digest[SHA256_DIGEST_SIZE];\r
+  VOID          *Sha256Ctx;\r
+\r
+  Sha256Ctx = (VOID *)HashHandle;\r
+  Sha256Final (Sha256Ctx, Digest);\r
+\r
+  FreePool (Sha256Ctx);\r
+  \r
+  Tpm2SetSha256ToDigestList (DigestList, Digest);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+HASH_INTERFACE  mSha256InternalHashInstance = {\r
+  HASH_ALGORITHM_SHA256_GUID,\r
+  Sha256HashInit,\r
+  Sha256HashUpdate,\r
+  Sha256HashFinal,\r
+};\r
+\r
+/**\r
+  The function register SHA256 instance.\r
+  \r
+  @retval EFI_SUCCESS   SHA256 instance is registered, or system dose not surpport registr SHA256 instance\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashInstanceLibSha256Constructor (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = RegisterHashInterfaceLib (&mSha256InternalHashInstance);\r
+  if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {\r
+    //\r
+    // Unsupported means platform policy does not need this instance enabled.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+  return Status;\r
+}
\ No newline at end of file
diff --git a/SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf b/SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
new file mode 100644 (file)
index 0000000..a1fb891
--- /dev/null
@@ -0,0 +1,44 @@
+## @file\r
+#  Ihis library is BaseCrypto SHA256 hash instance.\r
+#  It can be registered to BaseCrypto router, to serve as hash engine.\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
+# 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                      = HashInstanceLibSha256\r
+  FILE_GUID                      = 5810798A-ED30-4080-8DD7-B9667A748C02\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL\r
+  CONSTRUCTOR                    = HashInstanceLibSha256Constructor\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
+  HashInstanceLibSha256.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  CryptoPkg/CryptoPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  Tpm2CommandLib\r
+  MemoryAllocationLib\r
+  BaseCryptLib\r
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.c b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.c
new file mode 100644 (file)
index 0000000..833cce2
--- /dev/null
@@ -0,0 +1,77 @@
+/** @file\r
+  Ihis is BaseCrypto router support function.\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 <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HashLib.h>\r
+#include <Protocol/TrEEProtocol.h>\r
+\r
+typedef struct {\r
+  EFI_GUID  Guid;\r
+  UINT32    Mask;\r
+} 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
+};\r
+\r
+/**\r
+  The function get hash mask info from algorithm.\r
+\r
+  @param HashGuid Hash Guid\r
+\r
+  @return HashMask\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tpm2GetHashMaskFromAlgo (\r
+  IN EFI_GUID  *HashGuid\r
+  )\r
+{\r
+  UINTN  Index;\r
+  for (Index = 0; Index < sizeof(mTpm2HashMask)/sizeof(mTpm2HashMask[0]); Index++) {\r
+    if (CompareGuid (HashGuid, &mTpm2HashMask[Index].Guid)) {\r
+      return mTpm2HashMask[Index].Mask;\r
+    }\r
+  }\r
+  return 0;\r
+}\r
+\r
+/**\r
+  The function set digest to digest list.\r
+\r
+  @param DigestList digest list\r
+  @param Digest     digest data\r
+**/\r
+VOID\r
+EFIAPI\r
+Tpm2SetHashToDigestList (\r
+  IN OUT TPML_DIGEST_VALUES *DigestList,\r
+  IN TPML_DIGEST_VALUES     *Digest\r
+  )\r
+{\r
+  CopyMem (\r
+    &DigestList->digests[DigestList->count],\r
+    &Digest->digests[0],\r
+    sizeof(Digest->digests[0])\r
+    );\r
+  DigestList->count ++;\r
+}\r
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.h b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.h
new file mode 100644 (file)
index 0000000..f0ea3ca
--- /dev/null
@@ -0,0 +1,44 @@
+/** @file\r
+  Ihis is BaseCrypto router support function definition.\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
+#ifndef _HASH_LIB_BASE_CRYPTO_ROUTER_COMMON_H_\r
+#define _HASH_LIB_BASE_CRYPTO_ROUTER_COMMON_H_\r
+\r
+/**\r
+  The function get hash mask info from algorithm.\r
+\r
+  @param HashGuid Hash Guid\r
+\r
+  @return HashMask\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tpm2GetHashMaskFromAlgo (\r
+  IN EFI_GUID  *HashGuid\r
+  );\r
+\r
+/**\r
+  The function set digest to digest list.\r
+\r
+  @param DigestList digest list\r
+  @param Digest     digest data\r
+**/\r
+VOID\r
+EFIAPI\r
+Tpm2SetHashToDigestList (\r
+  IN OUT TPML_DIGEST_VALUES *DigestList,\r
+  IN TPML_DIGEST_VALUES     *Digest\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
new file mode 100644 (file)
index 0000000..8e93335
--- /dev/null
@@ -0,0 +1,221 @@
+/** @file\r
+  Ihis library is BaseCrypto router. It will redirect hash request to each individual\r
+  hash handler registerd, such as SHA1, SHA256.\r
+  Platform can use PcdTpm2HashMask to mask some hash engines.\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 <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/HashLib.h>\r
+\r
+#include "HashLibBaseCryptoRouterCommon.h"\r
+\r
+HASH_INTERFACE   mHashInterface[HASH_COUNT] = {0};\r
+UINTN            mHashInterfaceCount = 0;\r
+\r
+/**\r
+  Start hash sequence.\r
+\r
+  @param HashHandle Hash handle.\r
+\r
+  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.\r
+  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashStart (\r
+  OUT HASH_HANDLE    *HashHandle\r
+  )\r
+{\r
+  HASH_HANDLE  *HashCtx;\r
+  UINTN        Index;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = AllocatePool (sizeof(*HashCtx) * mHashInterfaceCount);\r
+  ASSERT (HashCtx != NULL);\r
+\r
+  for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
+    mHashInterface[Index].HashInit (&HashCtx[Index]);\r
+  }\r
+\r
+  *HashHandle = (HASH_HANDLE)HashCtx;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update hash sequence data.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence updated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashUpdate (\r
+  IN HASH_HANDLE    HashHandle,\r
+  IN VOID           *DataToHash,\r
+  IN UINTN          DataToHashLen\r
+  )\r
+{\r
+  HASH_HANDLE  *HashCtx;\r
+  UINTN        Index;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = (HASH_HANDLE *)HashHandle;\r
+\r
+  for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
+    mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Hash sequence complete and extend to PCR.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashCompleteAndExtend (\r
+  IN HASH_HANDLE         HashHandle,\r
+  IN TPMI_DH_PCR         PcrIndex,\r
+  IN VOID                *DataToHash,\r
+  IN UINTN               DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES *DigestList\r
+  )\r
+{\r
+  TPML_DIGEST_VALUES Digest;\r
+  HASH_HANDLE        *HashCtx;\r
+  UINTN              Index;\r
+  EFI_STATUS         Status;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = (HASH_HANDLE *)HashHandle;\r
+  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
+  }\r
+\r
+  FreePool (HashCtx);\r
+\r
+  Status = Tpm2PcrExtend (\r
+             PcrIndex,\r
+             DigestList\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Hash data and extend to PCR.\r
+\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash data and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashAndExtend (\r
+  IN TPMI_DH_PCR                    PcrIndex,\r
+  IN VOID                           *DataToHash,\r
+  IN UINTN                          DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES            *DigestList\r
+  )\r
+{\r
+  HASH_HANDLE    HashHandle;\r
+  EFI_STATUS     Status;\r
+\r
+  if (mHashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashStart (&HashHandle);\r
+  HashUpdate (HashHandle, DataToHash, DataToHashLen);\r
+  Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This service register Hash.\r
+\r
+  @param HashInterface  Hash interface\r
+\r
+  @retval EFI_SUCCESS          This hash interface is registered successfully.\r
+  @retval EFI_UNSUPPORTED      System does not support register this interface.\r
+  @retval EFI_ALREADY_STARTED  System already register this interface.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterHashInterfaceLib (\r
+  IN HASH_INTERFACE   *HashInterface\r
+  )\r
+{\r
+  UINTN              Index;\r
+  UINT32             HashMask;\r
+\r
+  //\r
+  // Check allow\r
+  //\r
+  HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);\r
+  if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Check duplication\r
+  //\r
+  for (Index = 0; Index < mHashInterfaceCount; Index++) {\r
+    if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) {\r
+      return EFI_ALREADY_STARTED;\r
+    }\r
+  }\r
+\r
+  CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface));\r
+  mHashInterfaceCount ++;\r
+  \r
+  return EFI_SUCCESS;\r
+}
\ No newline at end of file
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
new file mode 100644 (file)
index 0000000..f2cf915
--- /dev/null
@@ -0,0 +1,49 @@
+## @file\r
+#  Ihis library is BaseCrypto router. It will redirect hash request to each individual\r
+#  hash handler registerd, such as SHA1, SHA256.\r
+#  Platform can use PcdTpm2HashMask to mask some hash engines.\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
+# 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                      = HashLibBaseCryptoRouterDxe\r
+  FILE_GUID                      = 158DC712-F15A-44dc-93BB-1675045BE066\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = HashLibBaseCrypto|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
+  HashLibBaseCryptoRouterCommon.h\r
+  HashLibBaseCryptoRouterCommon.c\r
+  HashLibBaseCryptoRouterDxe.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  Tpm2CommandLib\r
+  MemoryAllocationLib\r
+  PcdLib\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask\r
+\r
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
new file mode 100644 (file)
index 0000000..1e7eb2d
--- /dev/null
@@ -0,0 +1,288 @@
+/** @file\r
+  Ihis library is BaseCrypto router. It will redirect hash request to each individual\r
+  hash handler registerd, such as SHA1, SHA256.\r
+  Platform can use PcdTpm2HashMask to mask some hash engines.\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 <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/HashLib.h>\r
+\r
+#include "HashLibBaseCryptoRouterCommon.h"\r
+\r
+#define HASH_LIB_PEI_ROUTER_GUID \\r
+  { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }\r
+\r
+EFI_GUID mHashLibPeiRouterGuid = HASH_LIB_PEI_ROUTER_GUID;\r
+\r
+typedef struct {\r
+  UINTN            HashInterfaceCount;\r
+  HASH_INTERFACE   HashInterface[HASH_COUNT];\r
+} HASH_INTERFACE_HOB;\r
+\r
+/**\r
+  This function get hash interface.\r
+\r
+  @retval hash interface.\r
+**/\r
+HASH_INTERFACE_HOB *\r
+InternalGetHashInterface (\r
+  VOID\r
+  )\r
+{\r
+  EFI_HOB_GUID_TYPE *Hob;\r
+\r
+  Hob = GetFirstGuidHob (&mHashLibPeiRouterGuid);\r
+  if (Hob == NULL) {\r
+    return NULL;\r
+  }\r
+  return (HASH_INTERFACE_HOB *)(Hob + 1);\r
+}\r
+\r
+/**\r
+  Start hash sequence.\r
+\r
+  @param HashHandle Hash handle.\r
+\r
+  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.\r
+  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashStart (\r
+  OUT HASH_HANDLE    *HashHandle\r
+  )\r
+{\r
+  HASH_INTERFACE_HOB *HashInterfaceHob;\r
+  HASH_HANDLE        *HashCtx;\r
+  UINTN              Index;\r
+\r
+  HashInterfaceHob = InternalGetHashInterface ();\r
+  if (HashInterfaceHob == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (HashInterfaceHob->HashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount);\r
+  ASSERT (HashCtx != NULL);\r
+\r
+  for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
+    HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);\r
+  }\r
+\r
+  *HashHandle = (HASH_HANDLE)HashCtx;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update hash sequence data.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence updated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashUpdate (\r
+  IN HASH_HANDLE    HashHandle,\r
+  IN VOID           *DataToHash,\r
+  IN UINTN          DataToHashLen\r
+  )\r
+{\r
+  HASH_INTERFACE_HOB *HashInterfaceHob;\r
+  HASH_HANDLE        *HashCtx;\r
+  UINTN              Index;\r
+\r
+  HashInterfaceHob = InternalGetHashInterface ();\r
+  if (HashInterfaceHob == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (HashInterfaceHob->HashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = (HASH_HANDLE *)HashHandle;\r
+\r
+  for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
+    HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Hash sequence complete and extend to PCR.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashCompleteAndExtend (\r
+  IN HASH_HANDLE         HashHandle,\r
+  IN TPMI_DH_PCR         PcrIndex,\r
+  IN VOID                *DataToHash,\r
+  IN UINTN               DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES *DigestList\r
+  )\r
+{\r
+  TPML_DIGEST_VALUES Digest;\r
+  HASH_INTERFACE_HOB *HashInterfaceHob;\r
+  HASH_HANDLE        *HashCtx;\r
+  UINTN              Index;\r
+  EFI_STATUS         Status;\r
+\r
+  HashInterfaceHob = InternalGetHashInterface ();\r
+  if (HashInterfaceHob == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (HashInterfaceHob->HashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashCtx = (HASH_HANDLE *)HashHandle;\r
+  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
+  }\r
+\r
+  FreePool (HashCtx);\r
+\r
+  Status = Tpm2PcrExtend (\r
+             PcrIndex,\r
+             DigestList\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Hash data and extend to PCR.\r
+\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash data and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashAndExtend (\r
+  IN TPMI_DH_PCR                    PcrIndex,\r
+  IN VOID                           *DataToHash,\r
+  IN UINTN                          DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES            *DigestList\r
+  )\r
+{\r
+  HASH_INTERFACE_HOB *HashInterfaceHob;\r
+  HASH_HANDLE        HashHandle;\r
+  EFI_STATUS         Status;\r
+\r
+  HashInterfaceHob = InternalGetHashInterface ();\r
+  if (HashInterfaceHob == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (HashInterfaceHob->HashInterfaceCount == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashStart (&HashHandle);\r
+  HashUpdate (HashHandle, DataToHash, DataToHashLen);\r
+  Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This service register Hash.\r
+\r
+  @param HashInterface  Hash interface\r
+\r
+  @retval EFI_SUCCESS          This hash interface is registered successfully.\r
+  @retval EFI_UNSUPPORTED      System does not support register this interface.\r
+  @retval EFI_ALREADY_STARTED  System already register this interface.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterHashInterfaceLib (\r
+  IN HASH_INTERFACE   *HashInterface\r
+  )\r
+{\r
+  UINTN              Index;\r
+  HASH_INTERFACE_HOB *HashInterfaceHob;\r
+  HASH_INTERFACE_HOB LocalHashInterfaceHob;\r
+  UINT32             HashMask;\r
+\r
+  //\r
+  // Check allow\r
+  //\r
+  HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);\r
+  if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  HashInterfaceHob = InternalGetHashInterface ();\r
+  if (HashInterfaceHob == NULL) {\r
+    ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));\r
+    HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));\r
+    if (HashInterfaceHob == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
+\r
+  if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Check duplication\r
+  //\r
+  for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {\r
+    if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {\r
+      //\r
+      // In PEI phase, there will be shadow driver dispatched again.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "RegisterHashInterfaceLib - Override\n"));\r
+      CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface));\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));\r
+  HashInterfaceHob->HashInterfaceCount ++;\r
+  \r
+  return EFI_SUCCESS;\r
+}
\ No newline at end of file
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
new file mode 100644 (file)
index 0000000..5e3d74e
--- /dev/null
@@ -0,0 +1,50 @@
+## @file\r
+#  Ihis library is BaseCrypto router. It will redirect hash request to each individual\r
+#  hash handler registerd, such as SHA1, SHA256.\r
+#  Platform can use PcdTpm2HashMask to mask some hash engines.\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
+# 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                      = HashLibBaseCryptoRouterPei\r
+  FILE_GUID                      = DDCBCFBA-8EEB-488a-96D6-097831A6E50B\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = HashLibBaseCrypto|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\r
+#\r
+\r
+[Sources]\r
+  HashLibBaseCryptoRouterCommon.h\r
+  HashLibBaseCryptoRouterCommon.c\r
+  HashLibBaseCryptoRouterPei.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  Tpm2CommandLib\r
+  MemoryAllocationLib\r
+  PcdLib\r
+  HobLib\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask\r
+\r
diff --git a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c
new file mode 100644 (file)
index 0000000..b2e01af
--- /dev/null
@@ -0,0 +1,342 @@
+/** @file\r
+  Ihis library uses TPM2 device to calculation hash.\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 <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/DebugLib.h>\r
+#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
+  UINT32     Mask;\r
+} 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
+};\r
+\r
+/**\r
+  The function get algorith from hash mask info.\r
+\r
+  @return Hash algorithm\r
+**/\r
+TPM_ALG_ID\r
+Tpm2GetAlgoFromHashMask (\r
+  VOID\r
+  )\r
+{\r
+  UINT32 HashMask;\r
+  UINTN  Index;\r
+\r
+  HashMask = PcdGet32 (PcdTpm2HashMask);\r
+  for (Index = 0; Index < sizeof(mTpm2HashMask)/sizeof(mTpm2HashMask[0]); Index++) {\r
+    if (mTpm2HashMask[Index].Mask == HashMask) {\r
+      return mTpm2HashMask[Index].AlgoId;\r
+    }\r
+  }\r
+\r
+  return TPM_ALG_NULL;\r
+}\r
+\r
+/**\r
+  Start hash sequence.\r
+\r
+  @param HashHandle Hash handle.\r
+\r
+  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.\r
+  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashStart (\r
+  OUT HASH_HANDLE    *HashHandle\r
+  )\r
+{\r
+  TPMI_DH_OBJECT        SequenceHandle;\r
+  EFI_STATUS            Status;\r
+  TPM_ALG_ID            AlgoId;\r
+\r
+  AlgoId = Tpm2GetAlgoFromHashMask ();\r
+\r
+  Status = Tpm2HashSequenceStart (AlgoId, &SequenceHandle);\r
+  if (!EFI_ERROR (Status)) {\r
+    *HashHandle = (HASH_HANDLE)SequenceHandle;\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Update hash sequence data.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence updated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashUpdate (\r
+  IN HASH_HANDLE    HashHandle,\r
+  IN VOID           *DataToHash,\r
+  IN UINTN          DataToHashLen\r
+  )\r
+{\r
+  UINT8            *Buffer;\r
+  UINT64           HashLen;\r
+  TPM2B_MAX_BUFFER HashBuffer;\r
+  EFI_STATUS       Status;\r
+\r
+  Buffer = (UINT8 *)(UINTN)DataToHash;\r
+  for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
+\r
+    HashBuffer.size = sizeof(HashBuffer.buffer);\r
+    CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
+    Buffer += sizeof(HashBuffer.buffer);\r
+\r
+    Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
+    if (EFI_ERROR(Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Last one\r
+  //\r
+  HashBuffer.size = (UINT16)HashLen;\r
+  CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
+  Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
+  if (EFI_ERROR(Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Hash sequence complete and extend to PCR.\r
+\r
+  @param HashHandle    Hash handle.\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashCompleteAndExtend (\r
+  IN HASH_HANDLE         HashHandle,\r
+  IN TPMI_DH_PCR         PcrIndex,\r
+  IN VOID                *DataToHash,\r
+  IN UINTN               DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES *DigestList\r
+  )\r
+{\r
+  UINT8            *Buffer;\r
+  UINT64           HashLen;\r
+  TPM2B_MAX_BUFFER HashBuffer;\r
+  EFI_STATUS       Status;\r
+  TPM_ALG_ID       AlgoId;\r
+  TPM2B_DIGEST     Result;\r
+\r
+  AlgoId = Tpm2GetAlgoFromHashMask ();\r
+\r
+  Buffer = (UINT8 *)(UINTN)DataToHash;\r
+  for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
+\r
+    HashBuffer.size = sizeof(HashBuffer.buffer);\r
+    CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
+    Buffer += sizeof(HashBuffer.buffer);\r
+\r
+    Status = Tpm2SequenceUpdate((TPMI_DH_OBJECT)HashHandle, &HashBuffer);\r
+    if (EFI_ERROR(Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Last one\r
+  //\r
+  HashBuffer.size = (UINT16)HashLen;\r
+  CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
+\r
+  ZeroMem(DigestList, sizeof(*DigestList));\r
+  DigestList->count = HASH_COUNT;\r
+\r
+  if (AlgoId == TPM_ALG_NULL) {\r
+    Status = Tpm2EventSequenceComplete (\r
+               PcrIndex,\r
+               (TPMI_DH_OBJECT)HashHandle,\r
+               &HashBuffer,\r
+               DigestList\r
+               );\r
+  } else {\r
+    Status = Tpm2SequenceComplete (\r
+               (TPMI_DH_OBJECT)HashHandle,\r
+               &HashBuffer,\r
+               &Result\r
+               );\r
+    if (EFI_ERROR(Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    DigestList->count = 1;\r
+    DigestList->digests[0].hashAlg = AlgoId;\r
+    CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);\r
+    Status = Tpm2PcrExtend (\r
+               PcrIndex,\r
+               DigestList\r
+               );\r
+  }\r
+  if (EFI_ERROR(Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Hash data and extend to PCR.\r
+\r
+  @param PcrIndex      PCR to be extended.\r
+  @param DataToHash    Data to be hashed.\r
+  @param DataToHashLen Data size.\r
+  @param DigestList    Digest list.\r
+\r
+  @retval EFI_SUCCESS     Hash data and DigestList is returned.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HashAndExtend (\r
+  IN TPMI_DH_PCR                    PcrIndex,\r
+  IN VOID                           *DataToHash,\r
+  IN UINTN                          DataToHashLen,\r
+  OUT TPML_DIGEST_VALUES            *DigestList\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  UINT8              *Buffer;\r
+  UINT64             HashLen;\r
+  TPMI_DH_OBJECT     SequenceHandle;\r
+  TPM2B_MAX_BUFFER   HashBuffer;\r
+  TPM_ALG_ID         AlgoId;\r
+  TPM2B_EVENT        EventData;\r
+  TPM2B_DIGEST       Result;\r
+\r
+  DEBUG((EFI_D_INFO, "\n HashAndExtend Entry \n"));\r
+\r
+  SequenceHandle = 0xFFFFFFFF; // Know bad value\r
+\r
+  AlgoId = Tpm2GetAlgoFromHashMask ();\r
+\r
+  if ((AlgoId == TPM_ALG_NULL) && (DataToHashLen <= sizeof(EventData.buffer))) {\r
+    EventData.size = (UINT16)DataToHashLen;\r
+    CopyMem (EventData.buffer, DataToHash, DataToHashLen);\r
+    Status = Tpm2PcrEvent (PcrIndex, &EventData, DigestList);\r
+    if (EFI_ERROR(Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = Tpm2HashSequenceStart(AlgoId, &SequenceHandle);\r
+  if (EFI_ERROR(Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  DEBUG((EFI_D_INFO, "\n Tpm2HashSequenceStart Success \n"));\r
+\r
+  Buffer = (UINT8 *)(UINTN)DataToHash;\r
+  for (HashLen = DataToHashLen; HashLen > sizeof(HashBuffer.buffer); HashLen -= sizeof(HashBuffer.buffer)) {\r
+\r
+    HashBuffer.size = sizeof(HashBuffer.buffer);\r
+    CopyMem(HashBuffer.buffer, Buffer, sizeof(HashBuffer.buffer));\r
+    Buffer += sizeof(HashBuffer.buffer);\r
+\r
+    Status = Tpm2SequenceUpdate(SequenceHandle, &HashBuffer);\r
+    if (EFI_ERROR(Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+  }\r
+  DEBUG((EFI_D_INFO, "\n Tpm2SequenceUpdate Success \n"));\r
+\r
+  HashBuffer.size = (UINT16)HashLen;\r
+  CopyMem(HashBuffer.buffer, Buffer, (UINTN)HashLen);\r
+\r
+  ZeroMem(DigestList, sizeof(*DigestList));\r
+  DigestList->count = HASH_COUNT;\r
+\r
+  if (AlgoId == TPM_ALG_NULL) {\r
+    Status = Tpm2EventSequenceComplete (\r
+               PcrIndex,\r
+               SequenceHandle,\r
+               &HashBuffer,\r
+               DigestList\r
+               );\r
+    if (EFI_ERROR(Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+    DEBUG((EFI_D_INFO, "\n Tpm2EventSequenceComplete Success \n"));\r
+  } else {\r
+    Status = Tpm2SequenceComplete (\r
+               SequenceHandle,\r
+               &HashBuffer,\r
+               &Result\r
+               );\r
+    if (EFI_ERROR(Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+    DEBUG((EFI_D_INFO, "\n Tpm2SequenceComplete Success \n"));\r
+\r
+    DigestList->count = 1;\r
+    DigestList->digests[0].hashAlg = AlgoId;\r
+    CopyMem (&DigestList->digests[0].digest, Result.buffer, Result.size);\r
+    Status = Tpm2PcrExtend (\r
+               PcrIndex,\r
+               DigestList\r
+               );\r
+    if (EFI_ERROR(Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+    DEBUG((EFI_D_INFO, "\n Tpm2PcrExtend Success \n"));\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This service register Hash.\r
+\r
+  @param HashInterface  Hash interface\r
+\r
+  @retval EFI_SUCCESS          This hash interface is registered successfully.\r
+  @retval EFI_UNSUPPORTED      System does not support register this interface.\r
+  @retval EFI_ALREADY_STARTED  System already register this interface.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterHashInterfaceLib (\r
+  IN HASH_INTERFACE   *HashInterface\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}
\ No newline at end of file
diff --git a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf
new file mode 100644 (file)
index 0000000..ebd81a2
--- /dev/null
@@ -0,0 +1,45 @@
+## @file\r
+#  Ihis library uses TPM2 device to calculation hash.\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
+# 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                      = HashLibTpm2\r
+  FILE_GUID                      = 1317F0D5-7842-475c-B1CA-6EDC20DCBE7D\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = HashLibTpm2\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
+  HashLibTpm2.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  CryptoPkg/CryptoPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  Tpm2CommandLib\r
+  MemoryAllocationLib\r
+  PcdLib\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask\r
diff --git a/SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf b/SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
new file mode 100644 (file)
index 0000000..622eb2b
--- /dev/null
@@ -0,0 +1,43 @@
+## @file\r
+#  This library is used by other modules to send TPM12 command.\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
+# 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                      = Tpm12CommandLib\r
+  FILE_GUID                      = C595047C-70B3-4731-99CC-A014E956D7A7\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tpm12CommandLib\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
+  Tpm12Startup.c\r
+  Tpm12Ownership.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  IoLib\r
+  TimerLib\r
+  DebugLib\r
+  Tpm12DeviceLib\r
+\r
diff --git a/SecurityPkg/Library/Tpm12CommandLib/Tpm12Ownership.c b/SecurityPkg/Library/Tpm12CommandLib/Tpm12Ownership.c
new file mode 100644 (file)
index 0000000..63cc174
--- /dev/null
@@ -0,0 +1,72 @@
+/** @file\r
+  Implement TPM1.2 Startup related command.\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 <Uefi.h>\r
+#include <IndustryStandard/Tpm12.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/Tpm12DeviceLib.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  TPM_RQU_COMMAND_HDR   Hdr;\r
+} TPM_CMD_FORCE_CLEAR;\r
+\r
+typedef struct {\r
+  TPM_RSP_COMMAND_HDR   Hdr;\r
+} TPM_RSP_FORCE_CLEAR;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+  Send ForceClear command to TPM1.2.\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12ForceClear (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINT32                            TpmRecvSize;\r
+  UINT32                            TpmSendSize;\r
+  TPM_CMD_FORCE_CLEAR               SendBuffer;\r
+  TPM_RSP_FORCE_CLEAR               RecvBuffer;\r
+  UINT32                            ReturnCode;\r
+\r
+  //\r
+  // send Tpm command TPM_ORD_ForceClear\r
+  //\r
+  TpmRecvSize               = sizeof (TPM_RSP_FORCE_CLEAR);\r
+  TpmSendSize               = sizeof (TPM_CMD_FORCE_CLEAR);\r
+  SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
+  SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);\r
+  SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_ForceClear);\r
+\r
+  Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);\r
+  switch (ReturnCode) {\r
+  case TPM_SUCCESS:\r
+    return EFI_SUCCESS;\r
+  default:\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+}
\ No newline at end of file
diff --git a/SecurityPkg/Library/Tpm12CommandLib/Tpm12Startup.c b/SecurityPkg/Library/Tpm12CommandLib/Tpm12Startup.c
new file mode 100644 (file)
index 0000000..684c9b5
--- /dev/null
@@ -0,0 +1,78 @@
+/** @file\r
+  Implement TPM1.2 Startup related command.\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 <Uefi.h>\r
+#include <IndustryStandard/Tpm12.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/Tpm12DeviceLib.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  TPM_RQU_COMMAND_HDR   Hdr;\r
+  TPM_STARTUP_TYPE      TpmSt;\r
+} TPM_CMD_START_UP;\r
+\r
+typedef struct {\r
+  TPM_RSP_COMMAND_HDR   Hdr;\r
+} TPM_RSP_START_UP;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+  Send Startup command to TPM1.2.\r
+\r
+  @param TpmSt           Startup Type.\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12Startup (\r
+  IN TPM_STARTUP_TYPE          TpmSt\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINT32                            TpmRecvSize;\r
+  UINT32                            TpmSendSize;\r
+  TPM_CMD_START_UP                  SendBuffer;\r
+  TPM_RSP_START_UP                  RecvBuffer;\r
+  UINT32                            ReturnCode;\r
+\r
+  //\r
+  // send Tpm command TPM_ORD_Startup\r
+  //\r
+  TpmRecvSize               = sizeof (TPM_RSP_START_UP);\r
+  TpmSendSize               = sizeof (TPM_CMD_START_UP);\r
+  SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
+  SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);\r
+  SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_Startup);\r
+  SendBuffer.TpmSt          = SwapBytes16 (TpmSt);\r
+\r
+  Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);\r
+  switch (ReturnCode) {\r
+  case TPM_SUCCESS:\r
+  case TPM_INVALID_POSTINIT:\r
+    // In warm reset, TPM may response TPM_INVALID_POSTINIT\r
+    return EFI_SUCCESS;\r
+  default:\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+}
\ No newline at end of file
diff --git a/SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf b/SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
new file mode 100644 (file)
index 0000000..0eb91ee
--- /dev/null
@@ -0,0 +1,44 @@
+## @file\r
+#  Ihis library is TPM2 DTPM device lib.\r
+#  Choosing this library means platform uses and only uses DTPM device as TPM2 engine.\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
+# 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                      = Tpm12DeviceLibDTpm\r
+  FILE_GUID                      = BC2B7672-A48B-4d58-B39E-AEE3707B5A23\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tpm12DeviceLib\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
+  Tpm12Tis.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  IoLib\r
+  TimerLib\r
+  DebugLib\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
\ No newline at end of file
diff --git a/SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12Tis.c b/SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12Tis.c
new file mode 100644 (file)
index 0000000..2ad5345
--- /dev/null
@@ -0,0 +1,572 @@
+/** @file\r
+  TIS (TPM Interface Specification) functions used by TPM1.2.\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 <Uefi.h>\r
+#include <IndustryStandard/Tpm12.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/Tpm12CommandLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+//\r
+// Set structure alignment to 1-byte\r
+//\r
+#pragma pack (1)\r
+\r
+//\r
+// Register set map as specified in TIS specification Chapter 10\r
+//\r
+typedef struct {\r
+  ///\r
+  /// Used to gain ownership for this particular port.\r
+  ///\r
+  UINT8                             Access;             // 0\r
+  UINT8                             Reserved1[7];       // 1\r
+  ///\r
+  /// Controls interrupts.\r
+  ///\r
+  UINT32                            IntEnable;          // 8\r
+  ///\r
+  /// SIRQ vector to be used by the TPM.\r
+  ///\r
+  UINT8                             IntVector;          // 0ch\r
+  UINT8                             Reserved2[3];       // 0dh\r
+  ///\r
+  /// What caused interrupt.\r
+  ///\r
+  UINT32                            IntSts;             // 10h\r
+  ///\r
+  /// Shows which interrupts are supported by that particular TPM.\r
+  ///\r
+  UINT32                            IntfCapability;     // 14h\r
+  ///\r
+  /// Status Register. Provides status of the TPM.\r
+  ///\r
+  UINT8                             Status;             // 18h\r
+  ///\r
+  /// Number of consecutive writes that can be done to the TPM.\r
+  ///\r
+  UINT16                            BurstCount;         // 19h\r
+  UINT8                             Reserved3[9];\r
+  ///\r
+  /// Read or write FIFO, depending on transaction.\r
+  ///\r
+  UINT32                            DataFifo;           // 24h\r
+  UINT8                             Reserved4[0xed8];   // 28h\r
+  ///\r
+  /// Vendor ID\r
+  ///\r
+  UINT16                            Vid;                // 0f00h\r
+  ///\r
+  /// Device ID\r
+  ///\r
+  UINT16                            Did;                // 0f02h\r
+  ///\r
+  /// Revision ID\r
+  ///\r
+  UINT8                             Rid;                // 0f04h\r
+  ///\r
+  /// TCG defined configuration registers.\r
+  ///\r
+  UINT8                             TcgDefined[0x7b];   // 0f05h\r
+  ///\r
+  /// Alias to I/O legacy space.\r
+  ///\r
+  UINT32                            LegacyAddress1;     // 0f80h\r
+  ///\r
+  /// Additional 8 bits for I/O legacy space extension.\r
+  ///\r
+  UINT32                            LegacyAddress1Ex;   // 0f84h\r
+  ///\r
+  /// Alias to second I/O legacy space.\r
+  ///\r
+  UINT32                            LegacyAddress2;     // 0f88h\r
+  ///\r
+  /// Additional 8 bits for second I/O legacy space extension.\r
+  ///\r
+  UINT32                            LegacyAddress2Ex;   // 0f8ch\r
+  ///\r
+  /// Vendor-defined configuration registers.\r
+  ///\r
+  UINT8                             VendorDefined[0x70];// 0f90h\r
+} TIS_PC_REGISTERS;\r
+\r
+//\r
+// Restore original structure alignment\r
+//\r
+#pragma pack ()\r
+\r
+//\r
+// Define pointer types used to access TIS registers on PC\r
+//\r
+typedef TIS_PC_REGISTERS  *TIS_PC_REGISTERS_PTR;\r
+\r
+//\r
+// Define bits of ACCESS and STATUS registers\r
+//\r
+\r
+///\r
+/// This bit is a 1 to indicate that the other bits in this register are valid.\r
+///\r
+#define TIS_PC_VALID                BIT7\r
+///\r
+/// Indicate that this locality is active.\r
+///\r
+#define TIS_PC_ACC_ACTIVE           BIT5\r
+///\r
+/// Set to 1 to indicate that this locality had the TPM taken away while\r
+/// this locality had the TIS_PC_ACC_ACTIVE bit set.\r
+///\r
+#define TIS_PC_ACC_SEIZED           BIT4\r
+///\r
+/// Set to 1 to indicate that TPM MUST reset the\r
+/// TIS_PC_ACC_ACTIVE bit and remove ownership for localities less than the\r
+/// locality that is writing this bit.\r
+///\r
+#define TIS_PC_ACC_SEIZE            BIT3\r
+///\r
+/// When this bit is 1, another locality is requesting usage of the TPM.\r
+///\r
+#define TIS_PC_ACC_PENDIND          BIT2\r
+///\r
+/// Set to 1 to indicate that this locality is requesting to use TPM.\r
+///\r
+#define TIS_PC_ACC_RQUUSE           BIT1\r
+///\r
+/// A value of 1 indicates that a T/OS has not been established on the platform\r
+///\r
+#define TIS_PC_ACC_ESTABLISH        BIT0\r
+\r
+///\r
+/// When this bit is 1, TPM is in the Ready state, \r
+/// indicating it is ready to receive a new command.\r
+///\r
+#define TIS_PC_STS_READY            BIT6\r
+///\r
+/// Write a 1 to this bit to cause the TPM to execute that command.\r
+///\r
+#define TIS_PC_STS_GO               BIT5\r
+///\r
+/// This bit indicates that the TPM has data available as a response.\r
+///\r
+#define TIS_PC_STS_DATA             BIT4\r
+///\r
+/// The TPM sets this bit to a value of 1 when it expects another byte of data for a command.\r
+///\r
+#define TIS_PC_STS_EXPECT           BIT3\r
+///\r
+/// Writes a 1 to this bit to force the TPM to re-send the response.\r
+///\r
+#define TIS_PC_STS_RETRY            BIT1\r
+\r
+//\r
+// Default TimeOut value\r
+//\r
+#define TIS_TIMEOUT_A               (750  * 1000)  // 750ms\r
+#define TIS_TIMEOUT_B               (2000 * 1000)  // 2s\r
+#define TIS_TIMEOUT_C               (750  * 1000)  // 750ms\r
+#define TIS_TIMEOUT_D               (750  * 1000)  // 750ms\r
+\r
+//\r
+// Max TPM command/reponse length\r
+//\r
+#define TPMCMDBUFLENGTH             1024\r
+\r
+/**\r
+  Check whether TPM chip exist.\r
+\r
+  @param[in] TisReg  Pointer to TIS register.\r
+\r
+  @retval    TRUE    TPM chip exists.\r
+  @retval    FALSE   TPM chip is not found.\r
+**/\r
+BOOLEAN\r
+Tpm12TisPcPresenceCheck (\r
+  IN      TIS_PC_REGISTERS_PTR      TisReg\r
+  )\r
+{\r
+  UINT8                             RegRead;\r
+  \r
+  RegRead = MmioRead8 ((UINTN)&TisReg->Access);\r
+  return (BOOLEAN)(RegRead != (UINT8)-1);\r
+}\r
+\r
+/**\r
+  Check whether the value of a TPM chip register satisfies the input BIT setting.\r
+\r
+  @param[in]  Register     Address port of register to be checked.\r
+  @param[in]  BitSet       Check these data bits are set.\r
+  @param[in]  BitClear     Check these data bits are clear.\r
+  @param[in]  TimeOut      The max wait time (unit MicroSecond) when checking register.\r
+\r
+  @retval     EFI_SUCCESS  The register satisfies the check bit.\r
+  @retval     EFI_TIMEOUT  The register can't run into the expected status in time.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12TisPcWaitRegisterBits (\r
+  IN      UINT8                     *Register,\r
+  IN      UINT8                     BitSet,\r
+  IN      UINT8                     BitClear,\r
+  IN      UINT32                    TimeOut\r
+  )\r
+{\r
+  UINT8                             RegRead;\r
+  UINT32                            WaitTime;\r
+\r
+  for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){\r
+    RegRead = MmioRead8 ((UINTN)Register);\r
+    if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)\r
+      return EFI_SUCCESS;\r
+    MicroSecondDelay (30);\r
+  }\r
+  return EFI_TIMEOUT;\r
+}\r
+\r
+/**\r
+  Get BurstCount by reading the burstCount field of a TIS regiger \r
+  in the time of default TIS_TIMEOUT_D.\r
+\r
+  @param[in]  TisReg                Pointer to TIS register.\r
+  @param[out] BurstCount            Pointer to a buffer to store the got BurstConut.\r
+\r
+  @retval     EFI_SUCCESS           Get BurstCount.\r
+  @retval     EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.\r
+  @retval     EFI_TIMEOUT           BurstCount can't be got in time.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12TisPcReadBurstCount (\r
+  IN      TIS_PC_REGISTERS_PTR      TisReg,\r
+     OUT  UINT16                    *BurstCount\r
+  )\r
+{\r
+  UINT32                            WaitTime;\r
+  UINT8                             DataByte0;\r
+  UINT8                             DataByte1;\r
+\r
+  if (BurstCount == NULL || TisReg == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  WaitTime = 0;\r
+  do {\r
+    //\r
+    // TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,\r
+    // so it needs to use MmioRead8 to read two times\r
+    //\r
+    DataByte0   = MmioRead8 ((UINTN)&TisReg->BurstCount);\r
+    DataByte1   = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);\r
+    *BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);\r
+    if (*BurstCount != 0) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    MicroSecondDelay (30);\r
+    WaitTime += 30;\r
+  } while (WaitTime < TIS_TIMEOUT_D);\r
+\r
+  return EFI_TIMEOUT;\r
+}\r
+\r
+/**\r
+  Set TPM chip to ready state by sending ready command TIS_PC_STS_READY \r
+  to Status Register in time.\r
+\r
+  @param[in] TisReg                Pointer to TIS register.\r
+\r
+  @retval    EFI_SUCCESS           TPM chip enters into ready state.\r
+  @retval    EFI_INVALID_PARAMETER TisReg is NULL.\r
+  @retval    EFI_TIMEOUT           TPM chip can't be set to ready state in time.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12TisPcPrepareCommand (\r
+  IN      TIS_PC_REGISTERS_PTR      TisReg\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+\r
+  if (TisReg == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);\r
+  Status = Tpm12TisPcWaitRegisterBits (\r
+             &TisReg->Status,\r
+             TIS_PC_STS_READY,\r
+             0,\r
+             TIS_TIMEOUT_B\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE \r
+  to ACCESS Register in the time of default TIS_TIMEOUT_A.\r
+\r
+  @param[in] TisReg                Pointer to TIS register.\r
+\r
+  @retval    EFI_SUCCESS           Get the control of TPM chip.\r
+  @retval    EFI_INVALID_PARAMETER TisReg is NULL.\r
+  @retval    EFI_NOT_FOUND         TPM chip doesn't exit.\r
+  @retval    EFI_TIMEOUT           Can't get the TPM control in time.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12TisPcRequestUseTpm (\r
+  IN      TIS_PC_REGISTERS_PTR      TisReg\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  \r
+  if (TisReg == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  if (!Tpm12TisPcPresenceCheck (TisReg)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);\r
+  Status = Tpm12TisPcWaitRegisterBits (\r
+             &TisReg->Access,\r
+             (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),\r
+             0,\r
+             TIS_TIMEOUT_A\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Send a command to TPM for execution and return response data.\r
+\r
+  @param[in]      TisReg        TPM register space base address.  \r
+  @param[in]      BufferIn      Buffer for command data.  \r
+  @param[in]      SizeIn        Size of command data.  \r
+  @param[in, out] BufferOut     Buffer for response data.  \r
+  @param[in, out] SizeOut       Size of response data.  \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
+  @retval EFI_UNSUPPORTED       Unsupported TPM version\r
+\r
+**/\r
+EFI_STATUS\r
+Tpm12TisTpmCommand (\r
+  IN     TIS_PC_REGISTERS_PTR       TisReg,\r
+  IN     UINT8                      *BufferIn,\r
+  IN     UINT32                     SizeIn,\r
+  IN OUT UINT8                      *BufferOut,\r
+  IN OUT UINT32                     *SizeOut\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINT16                            BurstCount;\r
+  UINT32                            Index;\r
+  UINT32                            TpmOutSize;\r
+  UINT16                            Data16;\r
+  UINT32                            Data32;\r
+\r
+  DEBUG_CODE (\r
+    UINTN  DebugSize;\r
+\r
+    DEBUG ((EFI_D_INFO, "Tpm12TisTpmCommand Send - "));\r
+    if (SizeIn > 0x100) {\r
+      DebugSize = 0x40;\r
+    } else {\r
+      DebugSize = SizeIn;\r
+    }\r
+    for (Index = 0; Index < DebugSize; Index++) {\r
+      DEBUG ((EFI_D_INFO, "%02x ", BufferIn[Index]));\r
+    }\r
+    if (DebugSize != SizeIn) {\r
+      DEBUG ((EFI_D_INFO, "...... "));\r
+      for (Index = SizeIn - 0x20; Index < SizeIn; Index++) {\r
+        DEBUG ((EFI_D_INFO, "%02x ", BufferIn[Index]));\r
+      }\r
+    }\r
+    DEBUG ((EFI_D_INFO, "\n"));\r
+  );\r
+  TpmOutSize = 0;\r
+\r
+  Status = Tpm12TisPcPrepareCommand (TisReg);\r
+  if (EFI_ERROR (Status)){\r
+    DEBUG ((DEBUG_ERROR, "Tpm12 is not ready for command!\n"));\r
+    return Status;\r
+  }\r
+  //\r
+  // Send the command data to Tpm\r
+  //\r
+  Index = 0;\r
+  while (Index < SizeIn) {\r
+    Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_TIMEOUT;\r
+      goto Exit;\r
+    }\r
+    for (; BurstCount > 0 && Index < SizeIn; BurstCount--) {\r
+      MmioWrite8((UINTN)&TisReg->DataFifo, *(BufferIn + Index));\r
+      Index++;\r
+    }\r
+  }\r
+  //\r
+  // Check the Tpm status STS_EXPECT change from 1 to 0\r
+  //\r
+  Status = Tpm12TisPcWaitRegisterBits (\r
+             &TisReg->Status,\r
+             (UINT8) TIS_PC_VALID,\r
+             TIS_PC_STS_EXPECT,\r
+             TIS_TIMEOUT_C\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm12 The send buffer too small!\n"));\r
+    Status = EFI_BUFFER_TOO_SMALL;\r
+    goto Exit;\r
+  }\r
+  //\r
+  // Executed the TPM command and waiting for the response data ready\r
+  //\r
+  MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_GO);\r
+  Status = Tpm12TisPcWaitRegisterBits (\r
+             &TisReg->Status,\r
+             (UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),\r
+             0,\r
+             TIS_TIMEOUT_B\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Wait for Tpm12 response data time out!!\n"));\r
+    Status = EFI_TIMEOUT;\r
+    goto Exit;\r
+  }\r
+  //\r
+  // Get response data header\r
+  //\r
+  Index = 0;\r
+  BurstCount = 0;\r
+  while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {\r
+    Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_TIMEOUT;\r
+      goto Exit;\r
+    }\r
+    for (; BurstCount > 0; BurstCount--) {\r
+      *(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);\r
+      Index++;\r
+      if (Index == sizeof (TPM_RSP_COMMAND_HDR)) break;\r
+    }\r
+  }\r
+  DEBUG_CODE (\r
+    DEBUG ((EFI_D_INFO, "Tpm12TisTpmCommand ReceiveHeader - "));\r
+    for (Index = 0; Index < sizeof (TPM_RSP_COMMAND_HDR); Index++) {\r
+      DEBUG ((EFI_D_INFO, "%02x ", BufferOut[Index]));\r
+    }\r
+    DEBUG ((EFI_D_INFO, "\n"));\r
+  );\r
+  //\r
+  // Check the reponse data header (tag,parasize and returncode )\r
+  //\r
+  CopyMem (&Data16, BufferOut, sizeof (UINT16));\r
+  if (SwapBytes16 (Data16) != TPM_TAG_RSP_COMMAND) {\r
+    DEBUG ((EFI_D_ERROR, "TPM12: TPM_ST_RSP error - %x\n", TPM_TAG_RSP_COMMAND));\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Exit;\r
+  }\r
+\r
+  CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));\r
+  TpmOutSize  = SwapBytes32 (Data32);\r
+  if (*SizeOut < TpmOutSize) {\r
+    Status = EFI_BUFFER_TOO_SMALL;\r
+    goto Exit;\r
+  }\r
+  *SizeOut = TpmOutSize;\r
+  //\r
+  // Continue reading the remaining data\r
+  //\r
+  while ( Index < TpmOutSize ) {\r
+    for (; BurstCount > 0; BurstCount--) {\r
+      *(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);\r
+      Index++;\r
+      if (Index == TpmOutSize) {\r
+        Status = EFI_SUCCESS;\r
+        goto Exit;\r
+      }\r
+    }\r
+    Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_TIMEOUT;\r
+      goto Exit;\r
+    }\r
+  }\r
+Exit:\r
+  DEBUG_CODE (\r
+    DEBUG ((EFI_D_INFO, "Tpm12TisTpmCommand Receive - "));\r
+    for (Index = 0; Index < TpmOutSize; Index++) {\r
+      DEBUG ((EFI_D_INFO, "%02x ", BufferOut[Index]));\r
+    }\r
+    DEBUG ((EFI_D_INFO, "\n"));\r
+  );\r
+  MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This service enables the sending of commands to the TPM12.\r
+\r
+  @param[in]      InputParameterBlockSize  Size of the TPM12 input parameter block.\r
+  @param[in]      InputParameterBlock      Pointer to the TPM12 input parameter block.\r
+  @param[in,out]  OutputParameterBlockSize Size of the TPM12 output parameter block.\r
+  @param[in]      OutputParameterBlock     Pointer to the TPM12 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
+Tpm12SubmitCommand (\r
+  IN UINT32            InputParameterBlockSize,\r
+  IN UINT8             *InputParameterBlock,\r
+  IN OUT UINT32        *OutputParameterBlockSize,\r
+  IN UINT8             *OutputParameterBlock\r
+  )\r
+{\r
+  return Tpm12TisTpmCommand (\r
+           (TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress),\r
+           InputParameterBlock,\r
+           InputParameterBlockSize,\r
+           OutputParameterBlock,\r
+           OutputParameterBlockSize\r
+           );\r
+}\r
+\r
+/**\r
+  This service requests use TPM12.\r
+\r
+  @retval EFI_SUCCESS      Get the control of TPM12 chip.\r
+  @retval EFI_NOT_FOUND    TPM12 not found.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12RequestUseTpm (\r
+  VOID\r
+  )\r
+{\r
+  return Tpm12TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
+}\r
diff --git a/SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.c b/SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.c
new file mode 100644 (file)
index 0000000..6b793bf
--- /dev/null
@@ -0,0 +1,108 @@
+/** @file\r
+  Ihis library is TPM12 TCG 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 <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/Tpm12DeviceLib.h>\r
+#include <Protocol/TcgService.h>\r
+#include <IndustryStandard/Tpm12.h>\r
+\r
+EFI_TCG_PROTOCOL  *mTcgProtocol = NULL; \r
+\r
+/**\r
+  This service enables the sending of commands to the TPM12.\r
+\r
+  @param[in]      InputParameterBlockSize  Size of the TPM12 input parameter block.\r
+  @param[in]      InputParameterBlock      Pointer to the TPM12 input parameter block.\r
+  @param[in,out]  OutputParameterBlockSize Size of the TPM12 output parameter block.\r
+  @param[in]      OutputParameterBlock     Pointer to the TPM12 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
+Tpm12SubmitCommand (\r
+  IN UINT32            InputParameterBlockSize,\r
+  IN UINT8             *InputParameterBlock,\r
+  IN OUT UINT32        *OutputParameterBlockSize,\r
+  IN UINT8             *OutputParameterBlock\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  TPM_RSP_COMMAND_HDR       *Header;\r
+\r
+  if (mTcgProtocol == NULL) {\r
+    Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &mTcgProtocol);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // TCG protocol is not installed. So, TPM12 is not present.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Tpm12SubmitCommand - TCG - %r\n", Status));\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+  //\r
+  // Assume when TCG Protocol is ready, RequestUseTpm already done.\r
+  //\r
+  Status = mTcgProtocol->PassThroughToTpm (\r
+                           mTcgProtocol,\r
+                           InputParameterBlockSize,\r
+                           InputParameterBlock,\r
+                           *OutputParameterBlockSize,\r
+                           OutputParameterBlock\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Header = (TPM_RSP_COMMAND_HDR *)OutputParameterBlock;\r
+  *OutputParameterBlockSize = SwapBytes32 (Header->paramSize);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This service requests use TPM12.\r
+\r
+  @retval EFI_SUCCESS      Get the control of TPM12 chip.\r
+  @retval EFI_NOT_FOUND    TPM12 not found.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12RequestUseTpm (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS   Status;\r
+\r
+  if (mTcgProtocol == NULL) {\r
+    Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &mTcgProtocol);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // TCG protocol is not installed. So, TPM12 is not present.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Tpm12RequestUseTpm - TCG - %r\n", Status));\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+  //\r
+  // Assume when TCG Protocol is ready, RequestUseTpm already done.\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf b/SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
new file mode 100644 (file)
index 0000000..7ab5217
--- /dev/null
@@ -0,0 +1,42 @@
+## @file\r
+#  Ihis library is TPM12 TCG 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
+# 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                      = Tpm12DeviceLibTcg\r
+  FILE_GUID                      = 4D8B77D9-E923-48f8-B070-4053D78B7E56\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tpm12DeviceLib|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\r
+#\r
+\r
+[Sources]\r
+  Tpm12DeviceLibTcg.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
+  gEfiTcgProtocolGuid                           ## CONSUMES\r
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c
new file mode 100644 (file)
index 0000000..0fe2c36
--- /dev/null
@@ -0,0 +1,741 @@
+/** @file\r
+  Implement TPM2 Capability related command.\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 <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPM_CAP                   Capability;\r
+  UINT32                    Property;\r
+  UINT32                    PropertyCount;\r
+} TPM2_GET_CAPABILITY_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER      Header;\r
+  TPMI_YES_NO               MoreData;\r
+  TPMS_CAPABILITY_DATA      CapabilityData;\r
+} TPM2_GET_CAPABILITY_RESPONSE;\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMT_PUBLIC_PARMS         Parameters;\r
+} TPM2_TEST_PARMS_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+} TPM2_TEST_PARMS_RESPONSE;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+  This command returns various information regarding the TPM and its current state.\r
+\r
+  The capability parameter determines the category of data returned. The property parameter \r
+  selects the first value of the selected category to be returned. If there is no property \r
+  that corresponds to the value of property, the next higher value is returned, if it exists.\r
+  The moreData parameter will have a value of YES if there are more values of the requested \r
+  type that were not returned.\r
+  If no next capability exists, the TPM will return a zero-length list and moreData will have \r
+  a value of NO.\r
+\r
+  NOTE: \r
+  To simplify this function, leave returned CapabilityData for caller to unpack since there are \r
+  many capability categories and only few categories will be used in firmware. It means the caller\r
+  need swap the byte order for the feilds in CapabilityData.\r
+\r
+  @param[in]  Capability         Group selection; determines the format of the response.\r
+  @param[in]  Property           Further definition of information. \r
+  @param[in]  PropertyCount      Number of properties of the indicated type to return.\r
+  @param[out] MoreData           Flag to indicate if there are more values of this type.\r
+  @param[out] CapabilityData     The capability data.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapability (\r
+  IN      TPM_CAP                   Capability,\r
+  IN      UINT32                    Property,\r
+  IN      UINT32                    PropertyCount,\r
+  OUT     TPMI_YES_NO               *MoreData,\r
+  OUT     TPMS_CAPABILITY_DATA      *CapabilityData\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TPM2_GET_CAPABILITY_COMMAND       SendBuffer;\r
+  TPM2_GET_CAPABILITY_RESPONSE      RecvBuffer;\r
+  UINT32                            SendBufferSize;\r
+  UINT32                            RecvBufferSize;\r
+\r
+  //\r
+  // Construct command\r
+  //\r
+  SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
+  SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_GetCapability);\r
+\r
+  SendBuffer.Capability = SwapBytes32 (Capability);\r
+  SendBuffer.Property = SwapBytes32 (Property);\r
+  SendBuffer.PropertyCount = SwapBytes32 (PropertyCount);\r
\r
+  SendBufferSize = (UINT32) sizeof (SendBuffer);\r
+  SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
+    \r
+  //\r
+  // send Tpm command\r
+  //\r
+  RecvBufferSize = sizeof (RecvBuffer);\r
+  Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (RecvBufferSize <= sizeof (TPM2_RESPONSE_HEADER) + sizeof (UINT8)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Return the response\r
+  //\r
+  *MoreData = RecvBuffer.MoreData;\r
+  //\r
+  // Does not unpack all possiable property here, the caller should unpack it and note the byte order.\r
+  //\r
+  CopyMem (CapabilityData, &RecvBuffer.CapabilityData, RecvBufferSize - sizeof (TPM2_RESPONSE_HEADER) - sizeof (UINT8));\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of TPM Family.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the Family.\r
+\r
+  @param[out] Family             The Family of TPM. (a 4-octet character string)\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityFamily (\r
+  OUT     CHAR8                     *Family\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status; \r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_FAMILY_INDICATOR, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  CopyMem (Family, &TpmCap.data.tpmProperties.tpmProperty->value, 4);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of TPM manufacture ID.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the TPM manufacture ID.\r
+\r
+  @param[out] ManufactureId      The manufacture ID of TPM.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityManufactureID (\r
+  OUT     UINT32                    *ManufactureId\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status; \r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_MANUFACTURER, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *ManufactureId = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of TPM FirmwareVersion.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the TPM FirmwareVersion.\r
+\r
+  @param[out] FirmwareVersion1   The FirmwareVersion1.\r
+  @param[out] FirmwareVersion2   The FirmwareVersion2.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityFirmwareVersion (\r
+  OUT     UINT32                    *FirmwareVersion1,\r
+  OUT     UINT32                    *FirmwareVersion2\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status; \r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_FIRMWARE_VERSION_1, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *FirmwareVersion1 = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_FIRMWARE_VERSION_2, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *FirmwareVersion2 = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of the maximum value for commandSize and responseSize in a command.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the max command size and response size\r
+\r
+  @param[out] MaxCommandSize     The maximum value for commandSize in a command.\r
+  @param[out] MaxResponseSize    The maximum value for responseSize in a command.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityMaxCommandResponseSize (\r
+  OUT UINT32                    *MaxCommandSize,\r
+  OUT UINT32                    *MaxResponseSize\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status;\r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_MAX_COMMAND_SIZE, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *MaxCommandSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_MAX_RESPONSE_SIZE, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *MaxResponseSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+  return EFI_SUCCESS; \r
+}\r
+\r
+/**\r
+  This command returns Returns a list of TPMS_ALG_PROPERTIES. Each entry is an\r
+  algorithm ID and a set of properties of the algorithm. \r
+\r
+  This function parse the value got from TPM2_GetCapability and return the list.\r
+\r
+  @param[out] AlgList      List of algorithm.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilitySupportedAlg (\r
+  OUT TPML_ALG_PROPERTY      *AlgList\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  UINTN                   Index;\r
+  EFI_STATUS              Status;\r
\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_ALGS, \r
+             1, \r
+             MAX_CAP_ALGS, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  CopyMem (AlgList, &TpmCap.data.algorithms, sizeof (TPML_ALG_PROPERTY));\r
+\r
+  AlgList->count = SwapBytes32 (AlgList->count);\r
+  for (Index = 0; Index < AlgList->count; Index++) {\r
+    AlgList->algProperties[Index].alg = SwapBytes16 (AlgList->algProperties[Index].alg);\r
+    WriteUnaligned32 ((UINT32 *)&AlgList->algProperties[Index].algProperties, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&AlgList->algProperties[Index].algProperties)));\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of TPM LockoutCounter.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the LockoutCounter.\r
+\r
+  @param[out] LockoutCounter     The LockoutCounter of TPM.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityLockoutCounter (\r
+  OUT     UINT32                    *LockoutCounter\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status; \r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_LOCKOUT_COUNTER, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *LockoutCounter = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of TPM LockoutInterval.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the LockoutInterval.\r
+\r
+  @param[out] LockoutInterval    The LockoutInterval of TPM.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityLockoutInterval (\r
+  OUT     UINT32                    *LockoutInterval\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status; \r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_LOCKOUT_INTERVAL, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *LockoutInterval = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of TPM InputBufferSize.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the InputBufferSize.\r
+\r
+  @param[out] InputBufferSize    The InputBufferSize of TPM.\r
+                                 the maximum size of a parameter (typically, a TPM2B_MAX_BUFFER)\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityInputBufferSize (\r
+  OUT     UINT32                    *InputBufferSize\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status; \r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_INPUT_BUFFER, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *InputBufferSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of TPM PCRs.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the PcrSelection.\r
+\r
+  @param[out] Pcrs    The Pcr Selection\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityPcrs (\r
+  OUT TPML_PCR_SELECTION      *Pcrs\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status;\r
+  UINTN                   Index;\r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_PCRS, \r
+             0, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Pcrs->count = SwapBytes32 (TpmCap.data.assignedPCR.count);\r
+  for (Index = 0; Index < Pcrs->count; Index++) {\r
+    Pcrs->pcrSelections[Index].hash = SwapBytes16 (TpmCap.data.assignedPCR.pcrSelections[Index].hash);\r
+    Pcrs->pcrSelections[Index].sizeofSelect = TpmCap.data.assignedPCR.pcrSelections[Index].sizeofSelect;\r
+    CopyMem (Pcrs->pcrSelections[Index].pcrSelect, TpmCap.data.assignedPCR.pcrSelections[Index].pcrSelect, Pcrs->pcrSelections[Index].sizeofSelect);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command returns the information of TPM AlgorithmSet.\r
+\r
+  This function parse the value got from TPM2_GetCapability and return the AlgorithmSet.\r
+\r
+  @param[out] AlgorithmSet    The AlgorithmSet of TPM.\r
+  \r
+  @retval EFI_SUCCESS            Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2GetCapabilityAlgorithmSet (\r
+  OUT     UINT32      *AlgorithmSet\r
+  )\r
+{\r
+  TPMS_CAPABILITY_DATA    TpmCap;\r
+  TPMI_YES_NO             MoreData;\r
+  EFI_STATUS              Status; \r
+\r
+  Status = Tpm2GetCapability (\r
+             TPM_CAP_TPM_PROPERTIES, \r
+             TPM_PT_ALGORITHM_SET, \r
+             1, \r
+             &MoreData, \r
+             &TpmCap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *AlgorithmSet = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command is used to check to see if specific combinations of algorithm parameters are supported.\r
+\r
+  @param[in]  Parameters              Algorithm parameters to be validated\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2TestParms (\r
+  IN  TPMT_PUBLIC_PARMS           *Parameters\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TPM2_TEST_PARMS_COMMAND           SendBuffer;\r
+  TPM2_TEST_PARMS_RESPONSE          RecvBuffer;\r
+  UINT32                            SendBufferSize;\r
+  UINT32                            RecvBufferSize;\r
+  UINT8                             *Buffer;\r
+\r
+  //\r
+  // Construct command\r
+  //\r
+  SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
+  SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_TestParms);\r
+\r
+  Buffer = (UINT8 *)&SendBuffer.Parameters;\r
+  WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->type));\r
+  Buffer += sizeof(UINT16);\r
+  switch (Parameters->type) {\r
+  case TPM_ALG_KEYEDHASH:\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.scheme));\r
+    Buffer += sizeof(UINT16);\r
+    switch (Parameters->parameters.keyedHashDetail.scheme.scheme) {\r
+    case TPM_ALG_HMAC:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.hmac.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_XOR:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.xor.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.xor.kdf));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  case TPM_ALG_SYMCIPHER:\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.algorithm));\r
+    Buffer += sizeof(UINT16);\r
+    switch (Parameters->parameters.symDetail.algorithm) {\r
+    case TPM_ALG_AES:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.aes));\r
+      Buffer += sizeof(UINT16);\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.mode.aes));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_SM4:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.SM4));\r
+      Buffer += sizeof(UINT16);\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.mode.SM4));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_XOR:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.xor));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_NULL:\r
+      break;\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    break;\r
+  case TPM_ALG_RSA:\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.algorithm));\r
+    Buffer += sizeof(UINT16);\r
+    switch (Parameters->parameters.rsaDetail.symmetric.algorithm) {\r
+    case TPM_ALG_AES:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.keyBits.aes));\r
+      Buffer += sizeof(UINT16);\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.mode.aes));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_SM4:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.keyBits.SM4));\r
+      Buffer += sizeof(UINT16);\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.mode.SM4));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_NULL:\r
+      break;\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.scheme));\r
+    Buffer += sizeof(UINT16);\r
+    switch (Parameters->parameters.rsaDetail.scheme.scheme) {\r
+    case TPM_ALG_RSASSA:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.rsassa.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_RSAPSS:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.rsapss.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_RSAES:\r
+      break;\r
+    case TPM_ALG_OAEP:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.oaep.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_NULL:\r
+      break;\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.keyBits));\r
+    Buffer += sizeof(UINT16);\r
+    WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Parameters->parameters.rsaDetail.exponent));\r
+    Buffer += sizeof(UINT32);\r
+    break;\r
+  case TPM_ALG_ECC:\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.algorithm));\r
+    Buffer += sizeof(UINT16);\r
+    switch (Parameters->parameters.eccDetail.symmetric.algorithm) {\r
+    case TPM_ALG_AES:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.keyBits.aes));\r
+      Buffer += sizeof(UINT16);\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.mode.aes));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_SM4:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.keyBits.SM4));\r
+      Buffer += sizeof(UINT16);\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.mode.SM4));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_NULL:\r
+      break;\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.scheme));\r
+    Buffer += sizeof(UINT16);\r
+    switch (Parameters->parameters.eccDetail.scheme.scheme) {\r
+    case TPM_ALG_ECDSA:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecdsa.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_ECDAA:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecdaa.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_ECSCHNORR:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecSchnorr.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_ECDH:\r
+      break;\r
+    case TPM_ALG_NULL:\r
+      break;\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.curveID));\r
+    Buffer += sizeof(UINT16);\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.scheme));\r
+    Buffer += sizeof(UINT16);\r
+    switch (Parameters->parameters.eccDetail.kdf.scheme) {\r
+    case TPM_ALG_MGF1:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.mgf1.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_KDF1_SP800_108:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_KDF1_SP800_56a:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_KDF2:\r
+      WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf2.hashAlg));\r
+      Buffer += sizeof(UINT16);\r
+      break;\r
+    case TPM_ALG_NULL:\r
+      break;\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    break;\r
+  default:\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);\r
+  SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
+\r
+  //\r
+  // send Tpm command\r
+  //\r
+  RecvBufferSize = sizeof (RecvBuffer);\r
+  Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2TestParms - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2TestParms - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf b/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
new file mode 100644 (file)
index 0000000..804f063
--- /dev/null
@@ -0,0 +1,48 @@
+## @file\r
+#  This library is used by other modules to send TPM2 command.\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
+# 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                      = Tpm2CommandLib\r
+  FILE_GUID                      = 2F572F32-8BE5-4868-BD1D-7438AD97DC27\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = Tpm2CommandLib\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
+  Tpm2Capability.c\r
+  Tpm2Sequences.c\r
+  Tpm2Integrity.c\r
+  Tpm2Hierarchy.c\r
+  Tpm2NVStorage.c\r
+  Tpm2Startup.c\r
+  Tpm2Test.c\r
+  Tpm2DictionaryAttack.c\r
+  Tpm2Miscellaneous.c\r
+  Tpm2Help.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  Tpm2DeviceLib\r
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2DictionaryAttack.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2DictionaryAttack.c
new file mode 100644 (file)
index 0000000..2f6488f
--- /dev/null
@@ -0,0 +1,203 @@
+/** @file\r
+  Implement TPM2 DictionaryAttack related command.\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 <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMI_RH_LOCKOUT           LockHandle;\r
+  UINT32                    AuthSessionSize;\r
+  TPMS_AUTH_COMMAND         AuthSession;\r
+} TPM2_DICTIONARY_ATTACK_LOCK_RESET_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+  UINT32                     AuthSessionSize;\r
+  TPMS_AUTH_RESPONSE         AuthSession;\r
+} TPM2_DICTIONARY_ATTACK_LOCK_RESET_RESPONSE;\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMI_RH_LOCKOUT           LockHandle;\r
+  UINT32                    AuthSessionSize;\r
+  TPMS_AUTH_COMMAND         AuthSession;\r
+  UINT32                    NewMaxTries;\r
+  UINT32                    NewRecoveryTime;\r
+  UINT32                    LockoutRecovery;\r
+} TPM2_DICTIONARY_ATTACK_PARAMETERS_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+  UINT32                     AuthSessionSize;\r
+  TPMS_AUTH_RESPONSE         AuthSession;\r
+} TPM2_DICTIONARY_ATTACK_PARAMETERS_RESPONSE;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+  This command cancels the effect of a TPM lockout due to a number of successive authorization failures.\r
+  If this command is properly authorized, the lockout counter is set to zero.\r
+\r
+  @param[in]  LockHandle            TPM_RH_LOCKOUT\r
+  @param[in]  AuthSession           Auth Session context\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2DictionaryAttackLockReset (\r
+  IN  TPMI_RH_LOCKOUT           LockHandle,\r
+  IN  TPMS_AUTH_COMMAND         *AuthSession\r
+  )\r
+{\r
+  EFI_STATUS                                 Status;\r
+  TPM2_DICTIONARY_ATTACK_LOCK_RESET_COMMAND  SendBuffer;\r
+  TPM2_DICTIONARY_ATTACK_LOCK_RESET_RESPONSE RecvBuffer;\r
+  UINT32                                     SendBufferSize;\r
+  UINT32                                     RecvBufferSize;\r
+  UINT8                                      *Buffer;\r
+  UINT32                                     SessionInfoSize;\r
+\r
+  //\r
+  // Construct command\r
+  //\r
+  SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
+  SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_DictionaryAttackLockReset);\r
+\r
+  SendBuffer.LockHandle = SwapBytes32 (LockHandle);\r
+\r
+  //\r
+  // Add in Auth session\r
+  //\r
+  Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
+\r
+  // sessionInfoSize\r
+  SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
+  Buffer += SessionInfoSize;\r
+  SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
+\r
+  SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);\r
+  SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
+\r
+  //\r
+  // send Tpm command\r
+  //\r
+  RecvBufferSize = sizeof (RecvBuffer);\r
+  Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackLockReset - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackLockReset - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This command cancels the effect of a TPM lockout due to a number of successive authorization failures.\r
+  If this command is properly authorized, the lockout counter is set to zero.\r
+\r
+  @param[in]  LockHandle            TPM_RH_LOCKOUT\r
+  @param[in]  AuthSession           Auth Session context\r
+  @param[in]  NewMaxTries           Count of authorization failures before the lockout is imposed\r
+  @param[in]  NewRecoveryTime       Time in seconds before the authorization failure count is automatically decremented\r
+  @param[in]  LockoutRecovery       Time in seconds after a lockoutAuth failure before use of lockoutAuth is allowed\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2DictionaryAttackParameters (\r
+  IN  TPMI_RH_LOCKOUT           LockHandle,\r
+  IN  TPMS_AUTH_COMMAND         *AuthSession,\r
+  IN  UINT32                    NewMaxTries,\r
+  IN  UINT32                    NewRecoveryTime,\r
+  IN  UINT32                    LockoutRecovery\r
+  )\r
+{\r
+  EFI_STATUS                                 Status;\r
+  TPM2_DICTIONARY_ATTACK_PARAMETERS_COMMAND  SendBuffer;\r
+  TPM2_DICTIONARY_ATTACK_PARAMETERS_RESPONSE RecvBuffer;\r
+  UINT32                                     SendBufferSize;\r
+  UINT32                                     RecvBufferSize;\r
+  UINT8                                      *Buffer;\r
+  UINT32                                     SessionInfoSize;\r
+\r
+  //\r
+  // Construct command\r
+  //\r
+  SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
+  SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_DictionaryAttackParameters);\r
+\r
+  SendBuffer.LockHandle = SwapBytes32 (LockHandle);\r
+\r
+  //\r
+  // Add in Auth session\r
+  //\r
+  Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
+\r
+  // sessionInfoSize\r
+  SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
+  Buffer += SessionInfoSize;\r
+  SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
+\r
+  //\r
+  // Real data\r
+  //\r
+  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(NewMaxTries));\r
+  Buffer += sizeof(UINT32);\r
+  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(NewRecoveryTime));\r
+  Buffer += sizeof(UINT32);\r
+  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(LockoutRecovery));\r
+  Buffer += sizeof(UINT32);\r
+\r
+  SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);\r
+  SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
+\r
+  //\r
+  // send Tpm command\r
+  //\r
+  RecvBufferSize = sizeof (RecvBuffer);\r
+  Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackParameters - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
+    DEBUG ((EFI_D_ERROR, "Tpm2DictionaryAttackParameters - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Help.c
new file mode 100644 (file)
index 0000000..4f5fcb5
--- /dev/null
@@ -0,0 +1,166 @@
+/** @file\r
+  Implement TPM2 help.\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 <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+typedef struct {\r
+  TPMI_ALG_HASH              HashAlgo;\r
+  UINT16                     HashSize;\r
+} INTERNAL_HASH_INFO;\r
+\r
+STATIC INTERNAL_HASH_INFO mHashInfo[] = {\r
+  {TPM_ALG_SHA1,          SHA1_DIGEST_SIZE},\r
+  {TPM_ALG_SHA256,        SHA256_DIGEST_SIZE},\r
+  {TPM_ALG_SM3_256,       SM3_256_DIGEST_SIZE},\r
+  {TPM_ALG_SHA384,        SHA384_DIGEST_SIZE},\r
+  {TPM_ALG_SHA512,        SHA512_DIGEST_SIZE},\r
+};\r
+\r
+/**\r
+  Return size of digest.\r
+\r
+  @param[in] HashAlgo  Hash algorithm\r
+\r
+  @return size of digest\r
+**/\r
+UINT16\r
+EFIAPI\r
+GetHashSizeFromAlgo (\r
+  IN TPMI_ALG_HASH    HashAlgo\r
+  )\r
+{\r
+  UINTN  Index;\r
+\r
+  for (Index = 0; Index < sizeof(mHashInfo)/sizeof(mHashInfo[0]); Index++) {\r
+    if (mHashInfo[Index].HashAlgo == HashAlgo) {\r
+      return mHashInfo[Index].HashSize;\r
+    }\r
+  }\r
+  return 0;\r
+}\r
+\r
+/**\r
+  Copy AuthSessionIn to TPM2 command buffer.\r
+\r
+  @param [in]  AuthSessionIn   Input AuthSession data\r
+  @param [out] AuthSessionOut  Output AuthSession data in TPM2 command buffer\r
+\r
+  @return AuthSession size\r
+**/\r
+UINT32\r
+EFIAPI\r
+CopyAuthSessionCommand (\r
+  IN      TPMS_AUTH_COMMAND         *AuthSessionIn, OPTIONAL\r
+  OUT     UINT8                     *AuthSessionOut\r
+  )\r
+{\r
+  UINT8  *Buffer;\r
+\r
+  Buffer = (UINT8 *)AuthSessionOut;\r
+  \r
+  //\r
+  // Add in Auth session\r
+  //\r
+  if (AuthSessionIn != NULL) {\r
+    //  sessionHandle\r
+    WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(AuthSessionIn->sessionHandle));\r
+    Buffer += sizeof(UINT32);\r
+\r
+    // nonce\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->nonce.size));\r
+    Buffer += sizeof(UINT16);\r
+\r
+    CopyMem (Buffer, AuthSessionIn->nonce.buffer, AuthSessionIn->nonce.size);\r
+    Buffer += AuthSessionIn->nonce.size;\r
+\r
+    // sessionAttributes\r
+    *(UINT8 *)Buffer = *(UINT8 *)&AuthSessionIn->sessionAttributes;\r
+    Buffer += sizeof(UINT8);\r
+\r
+    // hmac\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthSessionIn->hmac.size));\r
+    Buffer += sizeof(UINT16);\r
+\r
+    CopyMem (Buffer, AuthSessionIn->hmac.buffer, AuthSessionIn->hmac.size);\r
+    Buffer += AuthSessionIn->hmac.size;\r
+  } else {\r
+    //  sessionHandle\r
+    WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(TPM_RS_PW));\r
+    Buffer += sizeof(UINT32);\r
+\r
+    // nonce = nullNonce\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0));\r
+    Buffer += sizeof(UINT16);\r
+\r
+    // sessionAttributes = 0\r
+    *(UINT8 *)Buffer = 0x00;\r
+    Buffer += sizeof(UINT8);\r
+\r
+    // hmac = nullAuth\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(0));\r
+    Buffer += sizeof(UINT16);\r
+  }\r
+\r
+  return (UINT32)(UINTN)(Buffer - (UINT8 *)AuthSessionOut);\r
+}\r
+\r
+/**\r
+  Copy AuthSessionIn from TPM2 response buffer.\r
+\r
+  @param [in]  AuthSessionIn   Input AuthSession data in TPM2 response buffer\r
+  @param [out] AuthSessionOut  Output AuthSession data\r
+\r
+  @return AuthSession size\r
+**/\r
+UINT32\r
+EFIAPI\r
+CopyAuthSessionResponse (\r
+  IN      UINT8                      *AuthSessionIn,\r
+  OUT     TPMS_AUTH_RESPONSE         *AuthSessionOut OPTIONAL\r
+  )\r
+{\r
+  UINT8                      *Buffer;\r
+  TPMS_AUTH_RESPONSE         LocalAuthSessionOut;\r
+\r
+  if (AuthSessionOut == NULL) {\r
+    AuthSessionOut = &LocalAuthSessionOut;\r
+  }\r
+\r
+  Buffer = (UINT8 *)AuthSessionIn;\r
+\r
+  // nonce\r
+  AuthSessionOut->nonce.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+  Buffer += sizeof(UINT16);\r
+\r
+  CopyMem (AuthSessionOut->nonce.buffer, Buffer, AuthSessionOut->nonce.size);\r
+  Buffer += AuthSessionOut->nonce.size;\r
+\r
+  // sessionAttributes\r
+  *(UINT8 *)&AuthSessionOut->sessionAttributes = *(UINT8 *)Buffer;\r
+  Buffer += sizeof(UINT8);\r
+\r
+  // hmac\r
+  AuthSessionOut->hmac.size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
+  Buffer += sizeof(UINT16);\r
+\r
+  CopyMem (AuthSessionOut->hmac.buffer, Buffer, AuthSessionOut->hmac.size);\r
+  Buffer += AuthSessionOut->hmac.size;\r
+\r
+  return (UINT32)(UINTN)(Buffer - (UINT8 *)AuthSessionIn);\r
+}\r
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
new file mode 100644 (file)
index 0000000..c6935d9
--- /dev/null
@@ -0,0 +1,635 @@
+/** @file\r
+  Implement TPM2 Hierarchy related command.\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 <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Library/Tpm2CommandLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMI_RH_CLEAR             AuthHandle;\r
+  UINT32                    AuthorizationSize;\r
+  TPMS_AUTH_COMMAND         AuthSession;\r
+} TPM2_CLEAR_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+  UINT32                     ParameterSize;\r
+  TPMS_AUTH_RESPONSE         AuthSession;\r
+} TPM2_CLEAR_RESPONSE;\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMI_RH_CLEAR             AuthHandle;\r
+  UINT32                    AuthorizationSize;\r
+  TPMS_AUTH_COMMAND         AuthSession;\r
+  TPMI_YES_NO               Disable;\r
+} TPM2_CLEAR_CONTROL_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+  UINT32                     ParameterSize;\r
+  TPMS_AUTH_RESPONSE         AuthSession;\r
+} TPM2_CLEAR_CONTROL_RESPONSE;\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMI_RH_HIERARCHY_AUTH    AuthHandle;\r
+  UINT32                    AuthorizationSize;\r
+  TPMS_AUTH_COMMAND         AuthSession;\r
+  TPM2B_AUTH                NewAuth;\r
+} TPM2_HIERARCHY_CHANGE_AUTH_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+  UINT32                     ParameterSize;\r
+  TPMS_AUTH_RESPONSE         AuthSession;\r
+} TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE;\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMI_RH_PLATFORM          AuthHandle;\r
+  UINT32                    AuthorizationSize;\r
+  TPMS_AUTH_COMMAND         AuthSession;\r
+} TPM2_CHANGE_EPS_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+  UINT32                     ParameterSize;\r
+  TPMS_AUTH_RESPONSE         AuthSession;\r
+} TPM2_CHANGE_EPS_RESPONSE;\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMI_RH_PLATFORM          AuthHandle;\r
+  UINT32                    AuthorizationSize;\r
+  TPMS_AUTH_COMMAND         AuthSession;\r
+} TPM2_CHANGE_PPS_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+  UINT32                     ParameterSize;\r
+  TPMS_AUTH_RESPONSE         AuthSession;\r
+} TPM2_CHANGE_PPS_RESPONSE;\r
+\r
+typedef struct {\r
+  TPM2_COMMAND_HEADER       Header;\r
+  TPMI_RH_HIERARCHY         AuthHandle;\r
+  UINT32                    AuthorizationSize;\r
+  TPMS_AUTH_COMMAND         AuthSession;\r
+  TPMI_RH_HIERARCHY         Hierarchy;\r
+  TPMI_YES_NO               State;\r
+} TPM2_HIERARCHY_CONTROL_COMMAND;\r
+\r
+typedef struct {\r
+  TPM2_RESPONSE_HEADER       Header;\r
+  UINT32                     ParameterSize;\r
+  TPMS_AUTH_RESPONSE         AuthSession;\r
+} TPM2_HIERARCHY_CONTROL_RESPONSE;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+  This command removes all TPM context associated with a specific Owner.\r
+\r
+  @param[in] AuthHandle        TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}\r
+  @param[in] AuthSession       Auth Session context\r
\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2Clear (\r
+  IN TPMI_RH_CLEAR             AuthHandle,\r
+  IN TPMS_AUTH_COMMAND         *AuthSession OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TPM2_CLEAR_COMMAND                Cmd;\r
+  TPM2_CLEAR_RESPONSE               Res;\r
+  UINT32                            ResultBufSize;\r
+  UINT32                            CmdSize;\r
+  UINT32                            RespSize;\r
+  UINT8                             *Buffer;\r
+  UINT32                            SessionInfoSize;\r
+\r
+  Cmd.Header.tag         = SwapBytes16(TPM_ST_SESSIONS);\r
+  Cmd.Header.commandCode = SwapBytes32(TPM_CC_Clear);\r
+  Cmd.AuthHandle         = SwapBytes32(AuthHandle);\r
+\r
+  //\r
+  // Add in Auth session\r
+  //\r
+  Buffer = (UINT8 *)&Cmd.AuthSession;\r
+\r
+  // sessionInfoSize\r
+  SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
+  Buffer += SessionInfoSize;\r
+  Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
+\r
+  CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
+  Cmd.Header.paramSize   = SwapBytes32(CmdSize);\r
+\r
+  ResultBufSize = sizeof(Res);\r
+  Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (ResultBufSize > sizeof(Res)) {\r
+    DEBUG ((EFI_D_ERROR, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  //\r
+  // Validate response headers\r
+  //\r
+  RespSize = SwapBytes32(Res.Header.paramSize);\r
+  if (RespSize > sizeof(Res)) {\r
+    DEBUG ((EFI_D_ERROR, "Clear: Response size too large! %d\r\n", RespSize));\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  //\r
+  // Fail if command failed\r
+  //\r
+  if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
+    DEBUG ((EFI_D_ERROR, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Unmarshal the response\r
+  //\r
+\r
+  // None\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Disables and enables the execution of TPM2_Clear().\r
+\r
+  @param[in] AuthHandle        TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}\r
+  @param[in] AuthSession       Auth Session context\r
+  @param[in] Disable           YES if the disableOwnerClear flag is to be SET,\r
+                               NO if the flag is to be CLEAR.\r
+\r
+  @retval EFI_SUCCESS      Operation completed successfully.\r
+  @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2ClearControl (\r
+  IN TPMI_RH_CLEAR             AuthHandle,\r
+  IN TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL\r
+  IN TPMI_YES_NO               Disable\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TPM2_CLEAR_CONTROL_COMMAND        Cmd;\r
+  TPM2_CLEAR_CONTROL_RESPONSE       Res;\r
+  UINT32                            ResultBufSize;\r
+  UINT32                            CmdSize;\r
+  UINT32                            RespSize;\r
+  UINT8                             *Buffer;\r
+  UINT32                            SessionInfoSize;\r
+\r
+  Cmd.Header.tag         = SwapBytes16(TPM_ST_SESSIONS);\r
+  Cmd.Header.commandCode = SwapBytes32(TPM_CC_ClearControl);\r
+  Cmd.AuthHandle         = SwapBytes32(AuthHandle);\r
+\r
+  //\r
+  // Add in Auth session\r
+  //\r
+  Buffer = (UINT8 *)&Cmd.AuthSession;\r
+\r
+  // sessionInfoSize\r
+  SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
+  Buffer += SessionInfoSize;\r
+  Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
+\r
+  // disable\r
+  *(UINT8 *)Buffer = Disable;\r