Add security package to repository.
authorgdong1 <gdong1@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 2 Sep 2011 07:49:32 +0000 (07:49 +0000)
committergdong1 <gdong1@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 2 Sep 2011 07:49:32 +0000 (07:49 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12261 6f19259b-4bc3-4df7-8a09-765794883524

102 files changed:
SecurityPkg/Application/VariableInfo/VariableInfo.c [new file with mode: 0644]
SecurityPkg/Application/VariableInfo/VariableInfo.inf [new file with mode: 0644]
SecurityPkg/Include/Guid/AuthenticatedVariableFormat.h [new file with mode: 0644]
SecurityPkg/Include/Guid/PhysicalPresenceData.h [new file with mode: 0644]
SecurityPkg/Include/Guid/SecurityPkgTokenSpace.h [new file with mode: 0644]
SecurityPkg/Include/Guid/TcgEventHob.h [new file with mode: 0644]
SecurityPkg/Include/Library/PlatformSecureLib.h [new file with mode: 0644]
SecurityPkg/Include/Library/TpmCommLib.h [new file with mode: 0644]
SecurityPkg/Include/Ppi/LockPhysicalPresence.h [new file with mode: 0644]
SecurityPkg/Include/Ppi/TpmInitialized.h [new file with mode: 0644]
SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c [new file with mode: 0644]
SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.h [new file with mode: 0644]
SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf [new file with mode: 0644]
SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c [new file with mode: 0644]
SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h [new file with mode: 0644]
SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf [new file with mode: 0644]
SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c [new file with mode: 0644]
SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf [new file with mode: 0644]
SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.c [new file with mode: 0644]
SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf [new file with mode: 0644]
SecurityPkg/Library/TpmCommLib/CommonHeader.h [new file with mode: 0644]
SecurityPkg/Library/TpmCommLib/TisPc.c [new file with mode: 0644]
SecurityPkg/Library/TpmCommLib/TpmComm.c [new file with mode: 0644]
SecurityPkg/Library/TpmCommLib/TpmCommLib.inf [new file with mode: 0644]
SecurityPkg/SecurityPkg.dec [new file with mode: 0644]
SecurityPkg/SecurityPkg.dsc [new file with mode: 0644]
SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c [new file with mode: 0644]
SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.h [new file with mode: 0644]
SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf [new file with mode: 0644]
SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresence.c [new file with mode: 0644]
SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresence.h [new file with mode: 0644]
SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceDxe.inf [new file with mode: 0644]
SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceStrings.uni [new file with mode: 0644]
SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.c [new file with mode: 0644]
SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf [new file with mode: 0644]
SecurityPkg/Tcg/TcgConfigDxe/TcgConfig.vfr [new file with mode: 0644]
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf [new file with mode: 0644]
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.h [new file with mode: 0644]
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigNvData.h [new file with mode: 0644]
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigStrings.uni [new file with mode: 0644]
SecurityPkg/Tcg/TcgDxe/TcgDxe.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgDxe/TcgDxe.inf [new file with mode: 0644]
SecurityPkg/Tcg/TcgDxe/TisDxe.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgDxe/TpmComm.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgDxe/TpmComm.h [new file with mode: 0644]
SecurityPkg/Tcg/TcgPei/TcgPei.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgPei/TcgPei.inf [new file with mode: 0644]
SecurityPkg/Tcg/TcgPei/TisPei.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgPei/TpmComm.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgPei/TpmComm.h [new file with mode: 0644]
SecurityPkg/Tcg/TcgSmm/TcgSmm.c [new file with mode: 0644]
SecurityPkg/Tcg/TcgSmm/TcgSmm.inf [new file with mode: 0644]
SecurityPkg/Tcg/TcgSmm/Tpm.asl [new file with mode: 0644]
SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.c [new file with mode: 0644]
SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.h [new file with mode: 0644]
SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderData.h [new file with mode: 0644]
SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderDxe.inf [new file with mode: 0644]
SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderStrings.uni [new file with mode: 0644]
SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderVfr.Vfr [new file with mode: 0644]
SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProvider.c [new file with mode: 0644]
SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProvider.h [new file with mode: 0644]
SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProviderDxe.inf [new file with mode: 0644]
SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProviderStrings.uni [new file with mode: 0644]
SecurityPkg/UserIdentification/UserIdentifyManagerDxe/LoadDeferredImage.c [new file with mode: 0644]
SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c [new file with mode: 0644]
SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.h [new file with mode: 0644]
SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManagerData.h [new file with mode: 0644]
SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManagerDxe.inf [new file with mode: 0644]
SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManagerStrings.uni [new file with mode: 0644]
SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManagerVfr.Vfr [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileAdd.c [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileDelete.c [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.c [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.h [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerData.h [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerStrings.uni [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerVfr.Vfr [new file with mode: 0644]
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileModify.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/AuthService.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/AuthService.h [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/EsalVariableDxeSal.inf [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/InitVariable.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/Reclaim.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/Variable.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/Variable.h [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/Pei/Variable.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/Pei/Variable.h [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c [new file with mode: 0644]
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf [new file with mode: 0644]

diff --git a/SecurityPkg/Application/VariableInfo/VariableInfo.c b/SecurityPkg/Application/VariableInfo/VariableInfo.c
new file mode 100644 (file)
index 0000000..418cec3
--- /dev/null
@@ -0,0 +1,268 @@
+/** @file\r
+  If the Variable services have PcdVariableCollectStatistics set to TRUE then \r
+  this utility will print out the statistics information. You can use console \r
+  redirection to capture the data.\r
+  \r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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/UefiLib.h>\r
+#include <Library/UefiApplicationEntryPoint.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include <Guid/AuthenticatedVariableFormat.h>\r
+#include <Guid/SmmVariableCommon.h>\r
+#include <Protocol/SmmCommunication.h>\r
+#include <Protocol/SmmVariable.h>\r
+\r
+#define EFI_VARIABLE_GUID \\r
+  { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d } }\r
+\r
+EFI_GUID                        mEfiVariableGuid   = EFI_VARIABLE_GUID;\r
+EFI_SMM_COMMUNICATION_PROTOCOL  *mSmmCommunication = NULL;\r
+\r
+/**\r
+\r
+  This function get the variable statistics data from SMM variable driver. \r
+\r
+  @param[in, out] SmmCommunicateHeader In input, a pointer to a collection of data that will\r
+                                       be passed into an SMM environment. In output, a pointer \r
+                                       to a collection of data that comes from an SMM environment.\r
+  @param[in, out] SmmCommunicateSize   The size of the SmmCommunicateHeader.\r
+                      \r
+  @retval EFI_SUCCESS               Get the statistics data information.\r
+  @retval EFI_NOT_FOUND             Not found.\r
+  @retval EFI_BUFFER_TO_SMALL       DataSize is too small for the result.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetVariableStatisticsData (\r
+  IN OUT  EFI_SMM_COMMUNICATE_HEADER  *SmmCommunicateHeader,\r
+  IN OUT  UINTN                       *SmmCommunicateSize\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  SMM_VARIABLE_COMMUNICATE_HEADER     *SmmVariableFunctionHeader;\r
+\r
+  CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);\r
+  SmmCommunicateHeader->MessageLength = *SmmCommunicateSize - OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
+\r
+  SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) &SmmCommunicateHeader->Data[0];\r
+  SmmVariableFunctionHeader->Function = SMM_VARIABLE_FUNCTION_GET_STATISTICS;\r
+  \r
+  Status = mSmmCommunication->Communicate (mSmmCommunication, SmmCommunicateHeader, SmmCommunicateSize);\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  Status = SmmVariableFunctionHeader->ReturnStatus; \r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+\r
+  This function get and print the variable statistics data from SMM variable driver. \r
+                     \r
+  @retval EFI_SUCCESS               Print the statistics information successfully.\r
+  @retval EFI_NOT_FOUND             Not found the statistics information.\r
+\r
+**/\r
+EFI_STATUS\r
+PrintInfoFromSmm (\r
+  VOID  \r
+  )\r
+{\r
+  EFI_STATUS                                     Status;\r
+  VARIABLE_INFO_ENTRY                            *VariableInfo;\r
+  EFI_SMM_COMMUNICATE_HEADER                     *CommBuffer;\r
+  UINTN                                          RealCommSize;\r
+  UINTN                                          CommSize;\r
+  SMM_VARIABLE_COMMUNICATE_HEADER                *FunctionHeader;\r
+  EFI_SMM_VARIABLE_PROTOCOL                      *Smmvariable;\r
+  \r
+\r
+  Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **) &Smmvariable);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }  \r
+\r
+  CommSize  = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;\r
+  RealCommSize = CommSize;\r
+  CommBuffer = AllocateZeroPool (CommSize);\r
+  ASSERT (CommBuffer != NULL);\r
+  \r
+  Print (L"Non-Volatile SMM Variables:\n");\r
+  do {\r
+    Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      FreePool (CommBuffer);\r
+      CommBuffer = AllocateZeroPool (CommSize);\r
+      ASSERT (CommBuffer != NULL);\r
+      RealCommSize = CommSize;\r
+      Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
+    }\r
+\r
+    if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) { \r
+      break;\r
+    }\r
+\r
+    if (CommSize < RealCommSize) {\r
+      CommSize = RealCommSize;\r
+    }\r
+\r
+    FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data;\r
+    VariableInfo   = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data;\r
+\r
+    if (!VariableInfo->Volatile) {\r
+      Print (\r
+          L"%g R%03d(%03d) W%03d D%03d:%s\n", \r
+          &VariableInfo->VendorGuid,  \r
+          VariableInfo->ReadCount,\r
+          VariableInfo->CacheCount,\r
+          VariableInfo->WriteCount,\r
+          VariableInfo->DeleteCount,\r
+          (CHAR16 *)(VariableInfo + 1)\r
+          );\r
+    }\r
+  } while (TRUE);\r
+  \r
+  Print (L"Volatile SMM Variables:\n");\r
+  ZeroMem (CommBuffer, CommSize);\r
+  do {\r
+    Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      FreePool (CommBuffer);\r
+      CommBuffer = AllocateZeroPool (CommSize);\r
+      ASSERT (CommBuffer != NULL);\r
+      RealCommSize = CommSize;\r
+      Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
+    }\r
+\r
+    if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) { \r
+      break;\r
+    }\r
+\r
+    if (CommSize < RealCommSize) {\r
+      CommSize = RealCommSize;\r
+    }\r
+\r
+    FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data;\r
+    VariableInfo   = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data;\r
+\r
+    if (VariableInfo->Volatile) {\r
+      Print (\r
+          L"%g R%03d(%03d) W%03d D%03d:%s\n", \r
+          &VariableInfo->VendorGuid,  \r
+          VariableInfo->ReadCount,\r
+          VariableInfo->CacheCount,\r
+          VariableInfo->WriteCount,\r
+          VariableInfo->DeleteCount,\r
+          (CHAR16 *)(VariableInfo + 1)\r
+          );\r
+    }\r
+  } while (TRUE);\r
+\r
+  FreePool (CommBuffer);  \r
+  return Status;\r
+}\r
+\r
+/**\r
+  The user Entry Point for Application. The user code starts with this function\r
+  as the real entry point for the image goes into a library that calls this \r
+  function.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UefiMain (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  VARIABLE_INFO_ENTRY   *VariableInfo;\r
+  VARIABLE_INFO_ENTRY   *Entry;\r
+\r
+  Status = EfiGetSystemConfigurationTable (&mEfiVariableGuid, (VOID **)&Entry);\r
+  if (EFI_ERROR (Status) || (Entry == NULL)) {\r
+    Status = EfiGetSystemConfigurationTable (&gEfiAuthenticatedVariableGuid, (VOID **)&Entry);\r
+  }\r
+\r
+  if (EFI_ERROR (Status) || (Entry == NULL)) {\r
+    Status = PrintInfoFromSmm ();\r
+    if (!EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }  \r
+\r
+  if (!EFI_ERROR (Status) && (Entry != NULL)) {\r
+    Print (L"Non-Volatile EFI Variables:\n");\r
+    VariableInfo = Entry;\r
+    do {\r
+      if (!VariableInfo->Volatile) {\r
+        Print (\r
+          L"%g R%03d(%03d) W%03d D%03d:%s\n", \r
+          &VariableInfo->VendorGuid,  \r
+          VariableInfo->ReadCount,\r
+          VariableInfo->CacheCount,\r
+          VariableInfo->WriteCount,\r
+          VariableInfo->DeleteCount,\r
+          VariableInfo->Name\r
+          );\r
+      }\r
+\r
+      VariableInfo = VariableInfo->Next;\r
+    } while (VariableInfo != NULL);\r
+\r
+    Print (L"Volatile EFI Variables:\n");\r
+    VariableInfo = Entry;\r
+    do {\r
+      if (VariableInfo->Volatile) {\r
+        Print (\r
+          L"%g R%03d(%03d) W%03d D%03d:%s\n", \r
+          &VariableInfo->VendorGuid,  \r
+          VariableInfo->ReadCount,\r
+          VariableInfo->CacheCount,\r
+          VariableInfo->WriteCount,\r
+          VariableInfo->DeleteCount,\r
+          VariableInfo->Name\r
+          );\r
+      }\r
+      VariableInfo = VariableInfo->Next;\r
+    } while (VariableInfo != NULL);\r
+\r
+  } else {\r
+    Print (L"Warning: Variable Dxe driver doesn't enable the feature of statistical information!\n");\r
+    Print (L"If you want to see this info, please:\n");\r
+    Print (L"  1. Set PcdVariableCollectStatistics as TRUE\n");\r
+    Print (L"  2. Rebuild Variable Dxe driver\n");\r
+    Print (L"  3. Run \"VariableInfo\" cmd again\n");\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/SecurityPkg/Application/VariableInfo/VariableInfo.inf b/SecurityPkg/Application/VariableInfo/VariableInfo.inf
new file mode 100644 (file)
index 0000000..a247d53
--- /dev/null
@@ -0,0 +1,54 @@
+## @file\r
+#  This is a shell application that will display statistical information \r
+#  about variable usage.\r
+#  Note that if Variable Dxe driver doesn't enable the feature by setting \r
+#  PcdVariableCollectStatistics as TRUE, The application will not display \r
+#  variable statistical information.\r
+#\r
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# 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                      = VariableInfo\r
+  FILE_GUID                      = B9EF901F-A2A2-4fc8-8D2B-3A2E07B301CC\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = UefiMain\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
+  VariableInfo.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiApplicationEntryPoint\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+\r
+[Protocols]\r
+  gEfiSmmCommunicationProtocolGuid\r
+  gEfiSmmVariableProtocolGuid\r
+  \r
+[Guids]\r
+  gEfiAuthenticatedVariableGuid        ## CONSUMES ## Configuration Table Guid\r
+  \r
diff --git a/SecurityPkg/Include/Guid/AuthenticatedVariableFormat.h b/SecurityPkg/Include/Guid/AuthenticatedVariableFormat.h
new file mode 100644 (file)
index 0000000..245339c
--- /dev/null
@@ -0,0 +1,174 @@
+/** @file\r
+  The variable data structures are related to EDKII-specific \r
+  implementation of UEFI authenticated variables.\r
+  AuthenticatedVariableFormat.h defines variable data headers \r
+  and variable storage region headers.\r
+\r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 __AUTHENTICATED_VARIABLE_FORMAT_H__\r
+#define __AUTHENTICATED_VARIABLE_FORMAT_H__\r
+\r
+#define EFI_AUTHENTICATED_VARIABLE_GUID \\r
+  { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }\r
+\r
+extern EFI_GUID gEfiAuthenticatedVariableGuid;\r
+\r
+///\r
+/// Alignment of variable name and data, according to the architecture:\r
+/// * For IA-32 and Intel(R) 64 architectures: 1.\r
+/// * For IA-64 architecture: 8.\r
+///\r
+#if defined (MDE_CPU_IPF)\r
+#define ALIGNMENT         8\r
+#else\r
+#define ALIGNMENT         1\r
+#endif\r
+\r
+//\r
+// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.\r
+//\r
+#if (ALIGNMENT == 1)\r
+#define GET_PAD_SIZE(a) (0)\r
+#else\r
+#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))\r
+#endif\r
+\r
+///\r
+/// Alignment of Variable Data Header in Variable Store region.\r
+///\r
+#define HEADER_ALIGNMENT  4\r
+#define HEADER_ALIGN(Header)  (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))\r
+\r
+///\r
+/// Status of Variable Store Region.\r
+///\r
+typedef enum {\r
+  EfiRaw,\r
+  EfiValid,\r
+  EfiInvalid,\r
+  EfiUnknown\r
+} VARIABLE_STORE_STATUS;\r
+\r
+#pragma pack(1)\r
+\r
+#define VARIABLE_STORE_SIGNATURE  EFI_AUTHENTICATED_VARIABLE_GUID\r
+\r
+///\r
+/// Variable Store Header Format and State.\r
+///\r
+#define VARIABLE_STORE_FORMATTED          0x5a\r
+#define VARIABLE_STORE_HEALTHY            0xfe\r
+\r
+///\r
+/// Variable Store region header.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Variable store region signature.\r
+  ///\r
+  EFI_GUID  Signature;\r
+  ///\r
+  /// Size of entire variable store, \r
+  /// including size of variable store header but not including the size of FvHeader.\r
+  ///\r
+  UINT32  Size;\r
+  ///\r
+  /// Variable region format state.\r
+  ///\r
+  UINT8   Format;\r
+  ///\r
+  /// Variable region healthy state.\r
+  ///\r
+  UINT8   State;\r
+  UINT16  Reserved;\r
+  UINT32  Reserved1;\r
+} VARIABLE_STORE_HEADER;\r
+\r
+///\r
+/// Variable data start flag.\r
+///\r
+#define VARIABLE_DATA                     0x55AA\r
+\r
+///\r
+/// Variable State flags.\r
+///\r
+#define VAR_IN_DELETED_TRANSITION     0xfe  ///< Variable is in obsolete transition.\r
+#define VAR_DELETED                   0xfd  ///< Variable is obsolete.\r
+#define VAR_HEADER_VALID_ONLY         0x7f  ///< Variable header has been valid.\r
+#define VAR_ADDED                     0x3f  ///< Variable has been completely added.\r
+\r
+///\r
+/// Single Variable Data Header Structure.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Variable Data Start Flag.\r
+  ///\r
+  UINT16      StartId;\r
+  ///\r
+  /// Variable State defined above.\r
+  ///\r
+  UINT8       State;\r
+  UINT8       Reserved;\r
+  ///\r
+  /// Attributes of variable defined in UEFI specification.\r
+  ///\r
+  UINT32      Attributes;\r
+  ///\r
+  /// Associated monotonic count value against replay attack.\r
+  ///\r
+  UINT64      MonotonicCount;\r
+  ///\r
+  /// Associated TimeStamp value against replay attack. \r
+  ///\r
+  EFI_TIME    TimeStamp;\r
+  ///\r
+  /// Index of associated public key in database.\r
+  ///\r
+  UINT32      PubKeyIndex;\r
+  ///\r
+  /// Size of variable null-terminated Unicode string name.\r
+  ///\r
+  UINT32      NameSize;\r
+  ///\r
+  /// Size of the variable data without this header.\r
+  ///\r
+  UINT32      DataSize;\r
+  ///\r
+  /// A unique identifier for the vendor that produces and consumes this varaible.\r
+  ///\r
+  EFI_GUID    VendorGuid;\r
+} VARIABLE_HEADER;\r
+\r
+#pragma pack()\r
+\r
+typedef struct _VARIABLE_INFO_ENTRY  VARIABLE_INFO_ENTRY;\r
+\r
+///\r
+/// This structure contains the variable list that is put in EFI system table.\r
+/// The variable driver collects all variables that were used at boot service time and produces this list.\r
+/// This is an optional feature to dump all used variables in shell environment. \r
+///\r
+struct _VARIABLE_INFO_ENTRY {\r
+  VARIABLE_INFO_ENTRY *Next;       ///< Pointer to next entry.\r
+  EFI_GUID            VendorGuid;  ///< Guid of Variable.\r
+  CHAR16              *Name;       ///< Name of Variable. \r
+  UINT32              Attributes;  ///< Attributes of variable defined in UEFI spec.\r
+  UINT32              ReadCount;   ///< Number of times to read this variable.\r
+  UINT32              WriteCount;  ///< Number of times to write this variable.\r
+  UINT32              DeleteCount; ///< Number of times to delete this variable.\r
+  UINT32              CacheCount;  ///< Number of times that cache hits this variable.\r
+  BOOLEAN             Volatile;    ///< TRUE if volatile, FALSE if non-volatile.\r
+};\r
+\r
+#endif // __AUTHENTICATED_VARIABLE_FORMAT_H__\r
diff --git a/SecurityPkg/Include/Guid/PhysicalPresenceData.h b/SecurityPkg/Include/Guid/PhysicalPresenceData.h
new file mode 100644 (file)
index 0000000..1ae8095
--- /dev/null
@@ -0,0 +1,76 @@
+/** @file\r
+  Define the variable data structures used for TCG physical presence.\r
+  The TPM request from firmware or OS is saved to variable. And it is\r
+  cleared after it is processed in the next boot cycle. The TPM response \r
+  is saved to variable.\r
+\r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 __PHYSICAL_PRESENCE_DATA_GUID_H__\r
+#define __PHYSICAL_PRESENCE_DATA_GUID_H__\r
+\r
+#define EFI_PHYSICAL_PRESENCE_DATA_GUID \\r
+  { \\r
+    0xf6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc }\\r
+  }\r
+\r
+#define PHYSICAL_PRESENCE_VARIABLE  L"PhysicalPresence"\r
+\r
+typedef struct {\r
+  UINT8   PPRequest;      ///< Physical Presence request command.\r
+  UINT8   LastPPRequest;\r
+  UINT32  PPResponse;\r
+  UINT8   Flags;\r
+} EFI_PHYSICAL_PRESENCE;\r
+\r
+//\r
+// The definition bit of the flags\r
+//\r
+#define FLAG_NO_PPI_PROVISION                    BIT0\r
+#define FLAG_NO_PPI_CLEAR                        BIT1\r
+#define FLAG_NO_PPI_MAINTENANCE                  BIT2\r
+#define FLAG_RESET_TRACK                         BIT3\r
+\r
+#define H2NS(x)        ((((x) << 8) | ((x) >> 8)) & 0xffff)\r
+#define H2NL(x)        (H2NS ((x) >> 16) | (H2NS ((x) & 0xffff) << 16))\r
+\r
+//\r
+// The definition of physical presence operation actions\r
+//\r
+#define NO_ACTION                               0\r
+#define ENABLE                                  1\r
+#define DISABLE                                 2\r
+#define ACTIVATE                                3\r
+#define DEACTIVATE                              4 \r
+#define CLEAR                                   5\r
+#define ENABLE_ACTIVATE                         6\r
+#define DEACTIVATE_DISABLE                      7\r
+#define SET_OWNER_INSTALL_TRUE                  8\r
+#define SET_OWNER_INSTALL_FALSE                 9\r
+#define ENABLE_ACTIVATE_OWNER_TRUE              10\r
+#define DEACTIVATE_DISABLE_OWNER_FALSE          11\r
+#define DEFERRED_PP_UNOWNERED_FIELD_UPGRADE     12\r
+#define SET_OPERATOR_AUTH                       13\r
+#define CLEAR_ENABLE_ACTIVATE                   14\r
+#define SET_NO_PPI_PROVISION_FALSE              15\r
+#define SET_NO_PPI_PROVISION_TRUE               16\r
+#define SET_NO_PPI_CLEAR_FALSE                  17\r
+#define SET_NO_PPI_CLEAR_TRUE                   18\r
+#define SET_NO_PPI_MAINTENANCE_FALSE            19\r
+#define SET_NO_PPI_MAINTENANCE_TRUE             20\r
+#define ENABLE_ACTIVATE_CLEAR                   21\r
+#define ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE   22\r
+\r
+extern EFI_GUID  gEfiPhysicalPresenceGuid;\r
+\r
+#endif\r
+\r
diff --git a/SecurityPkg/Include/Guid/SecurityPkgTokenSpace.h b/SecurityPkg/Include/Guid/SecurityPkgTokenSpace.h
new file mode 100644 (file)
index 0000000..b1b7666
--- /dev/null
@@ -0,0 +1,25 @@
+/** @file\r
+  GUID for SecurityPkg PCD Token Space.\r
+\r
+Copyright (c) 2009 - 2010, 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 _SECURITYPKG_TOKEN_SPACE_GUID_H_\r
+#define _SECURITYPKG_TOKEN_SPACE_GUID_H_\r
+\r
+#define SECURITYPKG_TOKEN_SPACE_GUID \\r
+  { \\r
+    0xd3fb176, 0x9569, 0x4d51, { 0xa3, 0xef, 0x7d, 0x61, 0xc6, 0x4f, 0xea, 0xba } \\r
+  }\r
+\r
+extern EFI_GUID gEfiSecurityPkgTokenSpaceGuid;\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Guid/TcgEventHob.h b/SecurityPkg/Include/Guid/TcgEventHob.h
new file mode 100644 (file)
index 0000000..e88bd3a
--- /dev/null
@@ -0,0 +1,30 @@
+/** @file\r
+  Defines the HOB GUID used to pass a TCG_PCR_EVENT from a TPM PEIM to \r
+  a TPM DXE Driver. A GUIDed HOB is generated for each measurement \r
+  made in the PEI Phase.\r
+    \r
+Copyright (c) 2007 - 2010, 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 _TCG_EVENT_HOB_H_\r
+#define _TCG_EVENT_HOB_H_\r
+\r
+///\r
+/// The Global ID of a GUIDed HOB used to pass a TCG_PCR_EVENT from a TPM PEIM to a TPM DXE Driver.\r
+///\r
+#define EFI_TCG_EVENT_HOB_GUID \\r
+  { \\r
+    0x2e3044ac, 0x879f, 0x490f, {0x97, 0x60, 0xbb, 0xdf, 0xaf, 0x69, 0x5f, 0x50 } \\r
+  }\r
+\r
+extern EFI_GUID gTcgEventEntryHobGuid;\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Library/PlatformSecureLib.h b/SecurityPkg/Include/Library/PlatformSecureLib.h
new file mode 100644 (file)
index 0000000..c544719
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+  Provides a secure platform-specific method to clear PK(Platform Key).\r
+\r
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 __PLATFORM_SECURE_LIB_H__\r
+#define __PLATFORM_SECURE_LIB_H__\r
+\r
+\r
+/**\r
+\r
+  This function detects whether a secure platform-specific method to clear PK(Platform Key)\r
+  is configured by platform owner. This method is provided for users force to clear PK \r
+  in case incorrect enrollment mis-haps.\r
+  \r
+  UEFI231 spec chapter 27.5.2 stipulates: The platform key may also be cleared using \r
+  a secure platform-specific method. In  this case, the global variable SetupMode \r
+  must also be updated to 1.\r
+\r
+  NOTE THAT: This function cannot depend on any EFI Variable Service since they are\r
+  not available when this function is called in AuthenticateVariable driver.\r
+  \r
+  @retval  TRUE       The Platform owner wants to force clear PK.\r
+  @retval  FALSE      The Platform owner doesn't want to force clear PK. \r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ForceClearPK (\r
+  VOID\r
+  );\r
+\r
+#endif
\ No newline at end of file
diff --git a/SecurityPkg/Include/Library/TpmCommLib.h b/SecurityPkg/Include/Library/TpmCommLib.h
new file mode 100644 (file)
index 0000000..175dd8d
--- /dev/null
@@ -0,0 +1,286 @@
+/** @file\r
+  Ihis library is only intended to be used by TPM modules.\r
+  It provides basic TPM Interface Specification (TIS) and Command functions.\r
+\r
+Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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_COMM_LIB_H_\r
+#define _TPM_COMM_LIB_H_\r
+\r
+#include <IndustryStandard/Tpm12.h>\r
+\r
+typedef EFI_HANDLE  TIS_TPM_HANDLE;\r
+\r
+///\r
+/// TPM register base address.\r
+///\r
+#define TPM_BASE_ADDRESS            0xfed40000\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;           // 24\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
+// TCG Platform Type based on TCG ACPI Specification Version 1.00\r
+//\r
+#define TCG_PLATFORM_TYPE_CLIENT   0\r
+#define TCG_PLATFORM_TYPE_SERVER   1\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_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 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
+TisPcWaitRegisterBits (\r
+  IN UINT8   *Register,\r
+  IN UINT8   BitSet,   \r
+  IN UINT8   BitClear, \r
+  IN UINT32  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
+TisPcReadBurstCount (\r
+  IN  TIS_PC_REGISTERS_PTR  TisReg,\r
+  OUT UINT16                *BurstCount\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
+TisPcPrepareCommand (\r
+  IN TIS_PC_REGISTERS_PTR  TisReg\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_D.\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
+TisPcRequestUseTpm (\r
+  IN TIS_PC_REGISTERS_PTR  TisReg\r
+  );\r
+\r
+/**\r
+  Single function calculates SHA1 digest value for all raw data. It\r
+  combines Sha1Init(), Sha1Update() and Sha1Final().\r
+\r
+  @param[in]  Data          Raw data to be digested.\r
+  @param[in]  DataLen       Size of the raw data.\r
+  @param[out] Digest        Pointer to a buffer that stores the final digest.\r
+  \r
+  @retval     EFI_SUCCESS   Always successfully calculate the final digest.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TpmCommHashAll (\r
+  IN  CONST UINT8       *Data,\r
+  IN        UINTN       DataLen,\r
+  OUT       TPM_DIGEST  *Digest\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Include/Ppi/LockPhysicalPresence.h b/SecurityPkg/Include/Ppi/LockPhysicalPresence.h
new file mode 100644 (file)
index 0000000..0ae3b7b
--- /dev/null
@@ -0,0 +1,60 @@
+/** @file\r
+  This file defines the lock physical Presence PPI. This PPI is \r
+  produced by a platform specific PEIM and consumed by the TPM \r
+  PEIM.\r
+\r
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 __PEI_LOCK_PHYSICAL_PRESENCE_H__\r
+#define __PEI_LOCK_PHYSICAL_PRESENCE_H__\r
+\r
+///\r
+/// Global ID for the PEI_LOCK_PHYSICAL_PRESENCE_PPI_GUID.  \r
+///\r
+#define PEI_LOCK_PHYSICAL_PRESENCE_PPI_GUID  \\r
+  { \\r
+    0xef9aefe5, 0x2bd3, 0x4031, { 0xaf, 0x7d, 0x5e, 0xfe, 0x5a, 0xbb, 0x9a, 0xd } \\r
+  }\r
+\r
+///\r
+/// Forward declaration for the PEI_LOCK_PHYSICAL_PRESENCE_PPI\r
+///\r
+typedef struct _PEI_LOCK_PHYSICAL_PRESENCE_PPI PEI_LOCK_PHYSICAL_PRESENCE_PPI;\r
+\r
+/**\r
+  This interface returns whether TPM physical presence needs be locked.\r
+\r
+  @param[in]  PeiServices       The pointer to the PEI Services Table.\r
+\r
+  @retval     TRUE              The TPM physical presence should be locked.\r
+  @retval     FALSE             The TPM physical presence cannot be locked.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *PEI_LOCK_PHYSICAL_PRESENCE)(\r
+  IN CONST  EFI_PEI_SERVICES                    **PeiServices\r
+);\r
+\r
+///\r
+/// This service abstracts TPM physical presence lock interface. It is necessary for  \r
+/// safety to convey this information to the TPM driver so that TPM physical presence  \r
+/// can be locked as early as possible. This PPI is produced by a platform specific \r
+/// PEIM and consumed by the TPM PEIM.\r
+///\r
+struct _PEI_LOCK_PHYSICAL_PRESENCE_PPI {\r
+  PEI_LOCK_PHYSICAL_PRESENCE  LockPhysicalPresence;\r
+};\r
+\r
+extern EFI_GUID  gPeiLockPhysicalPresencePpiGuid;\r
+\r
+#endif  //  __PEI_LOCK_PHYSICAL_PRESENCE_H__
\ No newline at end of file
diff --git a/SecurityPkg/Include/Ppi/TpmInitialized.h b/SecurityPkg/Include/Ppi/TpmInitialized.h
new file mode 100644 (file)
index 0000000..dbbd415
--- /dev/null
@@ -0,0 +1,30 @@
+/** @file\r
+  Tag GUID that must be installed by the TPM PEIM after the TPM hardware is\r
+  initialized.  PEIMs that must execute after TPM hardware initialization\r
+  may use this GUID in their dependency expressions.\r
+    \r
+Copyright (c) 2008 - 2010, 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 _PEI_TPM_INITIALIZED_PPI_H_\r
+#define _PEI_TPM_INITIALIZED_PPI_H_\r
+\r
+///\r
+/// Global ID for the PEI_TPM_INITIALIZED_PPI which always uses a NULL interface. \r
+///\r
+#define PEI_TPM_INITIALIZED_PPI_GUID \\r
+  { \\r
+    0xe9db0d58, 0xd48d, 0x47f6, 0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41 \\r
+  }\r
+\r
+extern EFI_GUID gPeiTpmInitializedPpiGuid;\r
+\r
+#endif\r
diff --git a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c
new file mode 100644 (file)
index 0000000..f7fe594
--- /dev/null
@@ -0,0 +1,858 @@
+/** @file\r
+  Implement defer image load services for user identification in UEFI2.2.\r
+\r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 "DxeDeferImageLoadLib.h"\r
+\r
+//\r
+// Handle for the Deferred Image Load Protocol instance produced by this driver.\r
+//\r
+EFI_HANDLE                       mDeferredImageHandle = NULL;\r
+BOOLEAN                          mIsProtocolInstalled = FALSE;\r
+EFI_USER_MANAGER_PROTOCOL        *mUserManager        = NULL;\r
+DEFERRED_IMAGE_TABLE             mDeferredImage       = {\r
+  0,       // Deferred image count\r
+  NULL     // The deferred image info\r
+};\r
+\r
+EFI_DEFERRED_IMAGE_LOAD_PROTOCOL gDeferredImageLoad   = {\r
+  GetDefferedImageInfo\r
+};\r
+\r
+/**\r
+  Get the image type.\r
+\r
+  @param[in]    File    This is a pointer to the device path of the file\r
+                        that is being dispatched. \r
+\r
+  @return       UINT32  Image Type             \r
+\r
+**/\r
+UINT32\r
+GetFileType (\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_HANDLE                        DeviceHandle; \r
+  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePath;\r
+  EFI_BLOCK_IO_PROTOCOL             *BlockIo;\r
+\r
+  //\r
+  // First check to see if File is from a Firmware Volume\r
+  //\r
+  DeviceHandle      = NULL;\r
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiFirmwareVolume2ProtocolGuid,\r
+                  &TempDevicePath,\r
+                  &DeviceHandle\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->OpenProtocol (\r
+                    DeviceHandle,\r
+                    &gEfiFirmwareVolume2ProtocolGuid,\r
+                    NULL,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      return IMAGE_FROM_FV;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Next check to see if File is from a Block I/O device\r
+  //\r
+  DeviceHandle   = NULL;\r
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  &TempDevicePath,\r
+                  &DeviceHandle\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    BlockIo = NULL;\r
+    Status = gBS->OpenProtocol (\r
+                    DeviceHandle,\r
+                    &gEfiBlockIoProtocolGuid,\r
+                    (VOID **) &BlockIo,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (!EFI_ERROR (Status) && BlockIo != NULL) {\r
+      if (BlockIo->Media != NULL) {\r
+        if (BlockIo->Media->RemovableMedia) {\r
+          //\r
+          // Block I/O is present and specifies the media is removable\r
+          //\r
+          return IMAGE_FROM_REMOVABLE_MEDIA;\r
+        } else {\r
+          //\r
+          // Block I/O is present and specifies the media is not removable\r
+          //\r
+          return IMAGE_FROM_FIXED_MEDIA;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // File is not in a Firmware Volume or on a Block I/O device, so check to see if \r
+  // the device path supports the Simple File System Protocol.\r
+  //\r
+  DeviceHandle   = NULL;\r
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &TempDevicePath,\r
+                  &DeviceHandle\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Simple File System is present without Block I/O, so assume media is fixed.\r
+    //\r
+    return IMAGE_FROM_FIXED_MEDIA;\r
+  }\r
+\r
+  //\r
+  // File is not from an FV, Block I/O or Simple File System, so the only options\r
+  // left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.  \r
+  //\r
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+  while (!IsDevicePathEndType (TempDevicePath)) {\r
+    switch (DevicePathType (TempDevicePath)) {\r
+    \r
+    case MEDIA_DEVICE_PATH:\r
+      if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) {\r
+        return IMAGE_FROM_OPTION_ROM;\r
+      }\r
+      break;\r
+\r
+    case MESSAGING_DEVICE_PATH:\r
+      if (DevicePathSubType(TempDevicePath) == MSG_MAC_ADDR_DP) {\r
+        return IMAGE_FROM_REMOVABLE_MEDIA;\r
+      } \r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+    TempDevicePath = NextDevicePathNode (TempDevicePath);\r
+  }\r
+  return IMAGE_UNKNOWN; \r
+}\r
+\r
+\r
+/**\r
+  Get current user's access right.\r
+\r
+  @param[out]  AccessControl Points to the user's access control data, the\r
+                             caller should free data buffer.\r
+  @param[in]   AccessType    The type of user access control.\r
+\r
+  @retval      EFI_SUCCESS   Get current user access control successfully\r
+  @retval      others        Fail to get current user access control\r
+\r
+**/\r
+EFI_STATUS\r
+GetAccessControl (\r
+  OUT  EFI_USER_INFO_ACCESS_CONTROL     **AccessControl,\r
+  IN   UINT32                           AccessType\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_USER_INFO_HANDLE          UserInfo;\r
+  EFI_USER_INFO                 *Info;\r
+  UINTN                         InfoSize;\r
+  EFI_USER_INFO_ACCESS_CONTROL  *Access;\r
+  EFI_USER_PROFILE_HANDLE       CurrentUser;\r
+  UINTN                         CheckLen;\r
+  EFI_USER_MANAGER_PROTOCOL     *UserManager;\r
+\r
+  CurrentUser = NULL;\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiUserManagerProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &UserManager\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  \r
+  //\r
+  // Get current user access information.\r
+  //\r
+  UserManager->Current (UserManager, &CurrentUser);\r
+\r
+  UserInfo = NULL;\r
+  Info     = NULL;\r
+  InfoSize = 0;\r
+  while (TRUE) {\r
+    //\r
+    // Get next user information.\r
+    //\r
+    Status = UserManager->GetNextInfo (UserManager, CurrentUser, &UserInfo);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    Status = UserManager->GetInfo (\r
+                            UserManager,\r
+                            CurrentUser,\r
+                            UserInfo,\r
+                            Info,\r
+                            &InfoSize\r
+                            );\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      if (Info != NULL) {\r
+        FreePool (Info);\r
+      }\r
+      Info = AllocateZeroPool (InfoSize);\r
+      ASSERT (Info != NULL);\r
+      Status = UserManager->GetInfo (\r
+                              UserManager,\r
+                              CurrentUser,\r
+                              UserInfo,\r
+                              Info,\r
+                              &InfoSize\r
+                              );\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    \r
+    ASSERT (Info != NULL);\r
+    if (Info->InfoType != EFI_USER_INFO_ACCESS_POLICY_RECORD) {\r
+      continue;\r
+    }\r
+    \r
+    //\r
+    // Get specified access information.\r
+    //\r
+    CheckLen  = 0;\r
+    while (CheckLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {\r
+      Access = (EFI_USER_INFO_ACCESS_CONTROL *) ((UINT8 *) (Info + 1) + CheckLen);\r
+      if ((Access->Type == AccessType)) {\r
+        *AccessControl = AllocateZeroPool (Access->Size);\r
+        ASSERT (*AccessControl != NULL);\r
+        CopyMem (*AccessControl, Access, Access->Size);\r
+        FreePool (Info);\r
+        return EFI_SUCCESS;\r
+      }\r
+      CheckLen += Access->Size;\r
+    }\r
+  }\r
+  \r
+  if (Info != NULL) {\r
+    FreePool (Info);\r
+  }\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+  Convert the '/' to '\' in the specified string.\r
+\r
+  @param[in, out]  Str       Points to the string to convert.\r
+\r
+**/\r
+VOID\r
+ConvertDPStr (\r
+  IN OUT EFI_STRING                     Str \r
+  )\r
+{\r
+  INTN                                  Count;\r
+  INTN                                  Index;\r
+  \r
+  Count = StrSize(Str) / 2 - 1;\r
+\r
+  if (Count < 4) {\r
+    return;\r
+  }\r
+  \r
+  //\r
+  // Convert device path string.\r
+  //\r
+  Index = Count - 1;\r
+  while (Index > 0) {\r
+    //\r
+    // Find the last '/'.\r
+    //\r
+    for (Index = Count - 1; Index > 0; Index--) {\r
+      if (Str[Index] == L'/')\r
+        break;\r
+    }\r
+\r
+    //\r
+    // Check next char.\r
+    //\r
+    if (Str[Index + 1] == L'\\')\r
+      return;\r
+    \r
+    Str[Index] = L'\\';\r
+    \r
+    //\r
+    // Check previous char.\r
+    //\r
+    if ((Index > 0) && (Str[Index - 1] == L'\\')) {\r
+      CopyMem (&Str[Index - 1], &Str[Index], (UINTN) ((Count - Index + 1) * sizeof (CHAR16)));\r
+      return;\r
+    }\r
+    Index--;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Check whether the DevicePath2 is identical with DevicePath1, or identical with\r
+  DevicePath1's child device path.\r
+\r
+  If DevicePath2 is identical with DevicePath1, or with DevicePath1's child device\r
+  path, then TRUE returned. Otherwise, FALSE is returned.\r
+  \r
+  If DevicePath1 is NULL, then ASSERT().\r
+  If DevicePath2 is NULL, then ASSERT().\r
+\r
+  @param[in]  DevicePath1   A pointer to a device path.\r
+  @param[in]  DevicePath2   A pointer to a device path.\r
+\r
+  @retval     TRUE          Two device paths are identical , or DevicePath2 is \r
+                            DevicePath1's child device path.\r
+  @retval     FALSE         Two device paths are not identical, and DevicePath2 \r
+                            is not DevicePath1's child device path.\r
+\r
+**/\r
+BOOLEAN\r
+CheckDevicePath (\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL          *DevicePath1,\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL          *DevicePath2\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_STRING                            DevicePathStr1;\r
+  EFI_STRING                            DevicePathStr2;\r
+  UINTN                                 StrLen1;\r
+  UINTN                                 StrLen2;\r
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL      *DevicePathText;\r
+  BOOLEAN                               DevicePathEqual;\r
+\r
+  ASSERT (DevicePath1 != NULL);\r
+  ASSERT (DevicePath2 != NULL);\r
+  \r
+  DevicePathEqual = FALSE;\r
+  DevicePathText  = NULL;\r
+  Status = gBS->LocateProtocol ( \r
+                  &gEfiDevicePathToTextProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &DevicePathText\r
+                  );\r
+  ASSERT (Status == EFI_SUCCESS);\r
+  \r
+  //\r
+  // Get first device path string.\r
+  //\r
+  DevicePathStr1 = DevicePathText->ConvertDevicePathToText (DevicePath1, TRUE, TRUE);\r
+  ConvertDPStr (DevicePathStr1);\r
+  //\r
+  // Get second device path string.\r
+  //\r
+  DevicePathStr2 = DevicePathText->ConvertDevicePathToText (DevicePath2, TRUE, TRUE);\r
+  ConvertDPStr (DevicePathStr2);\r
+  \r
+  //\r
+  // Compare device path string.\r
+  //\r
+  StrLen1 = StrSize (DevicePathStr1);\r
+  StrLen2 = StrSize (DevicePathStr2);\r
+  if (StrLen1 > StrLen2) {\r
+    DevicePathEqual = FALSE;\r
+    goto Done;\r
+  }\r
+  \r
+  if (CompareMem (DevicePathStr1, DevicePathStr2, StrLen1) == 0) {\r
+    DevicePathEqual = TRUE;\r
+  }\r
+\r
+Done:\r
+  FreePool (DevicePathStr1);\r
+  FreePool (DevicePathStr2);\r
+  return DevicePathEqual;\r
+}\r
+\r
+\r
+/**\r
+  Check whether the image pointed to by DevicePath is in the device path list \r
+  specified by AccessType.  \r
+\r
+  @param[in] DevicePath  Points to device path.\r
+  @param[in] AccessType  The type of user access control.\r
\r
+  @retval    TURE        The DevicePath is in the specified List.\r
+  @retval    FALSE       The DevicePath is not in the specified List.\r
+\r
+**/\r
+BOOLEAN\r
+IsDevicePathInList (\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,\r
+  IN        UINT32                     AccessType\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_USER_INFO_ACCESS_CONTROL          *Access;\r
+  EFI_DEVICE_PATH_PROTOCOL              *Path;\r
+  UINTN                                 OffSet;  \r
+\r
+  Status = GetAccessControl (&Access, AccessType);\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }  \r
+\r
+  OffSet = 0;\r
+  while (OffSet < Access->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
+    Path = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)(Access + 1) + OffSet);    \r
+    if (CheckDevicePath (Path, DevicePath)) {\r
+      //\r
+      // The device path is found in list.\r
+      //\r
+      FreePool (Access);\r
+      return TRUE;\r
+    }  \r
+    OffSet += GetDevicePathSize (Path);\r
+  }\r
+  \r
+  FreePool (Access);\r
+  return FALSE; \r
+}\r
+\r
+\r
+/**\r
+  Check whether the image pointed to by DevicePath is permitted to load.  \r
+\r
+  @param[in] DevicePath  Points to device path\r
\r
+  @retval    TURE        The image pointed by DevicePath is permitted to load.\r
+  @retval    FALSE       The image pointed by DevicePath is forbidden to load.\r
+\r
+**/\r
+BOOLEAN\r
+VerifyDevicePath (\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath\r
+  )\r
+{\r
+  if (IsDevicePathInList (DevicePath, EFI_USER_INFO_ACCESS_PERMIT_LOAD)) {\r
+    //\r
+    // This access control overrides any restrictions put in place by the \r
+    // EFI_USER_INFO_ACCESS_FORBID_LOAD record.\r
+    //\r
+    return TRUE;\r
+  }\r
+  \r
+  if (IsDevicePathInList (DevicePath, EFI_USER_INFO_ACCESS_FORBID_LOAD)) {\r
+    //\r
+    // The device path is found in the forbidden list.\r
+    //\r
+    return FALSE;\r
+  }\r
+  \r
+  return TRUE; \r
+}\r
+\r
+\r
+/**\r
+  Check the image pointed by DevicePath is a boot option or not.  \r
+\r
+  @param[in] DevicePath  Points to device path.\r
\r
+  @retval    TURE        The image pointed by DevicePath is a boot option.\r
+  @retval    FALSE       The image pointed by DevicePath is not a boot option.\r
+\r
+**/\r
+BOOLEAN\r
+IsBootOption (\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL      *DevicePath\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINT16                            *BootOrderList;\r
+  UINTN                             BootOrderListSize;\r
+  UINTN                             Index;\r
+  CHAR16                            StrTemp[20];\r
+  UINT8                             *OptionBuffer;\r
+  UINT8                             *OptionPtr;\r
+  EFI_DEVICE_PATH_PROTOCOL          *OptionDevicePath;\r
+  \r
+  //\r
+  // Get BootOrder\r
+  //\r
+  BootOrderListSize = 0;\r
+  BootOrderList     = NULL;  \r
+  Status = gRT->GetVariable (\r
+                  L"BootOrder", \r
+                  &gEfiGlobalVariableGuid, \r
+                  NULL, \r
+                  &BootOrderListSize, \r
+                  NULL\r
+                  );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    BootOrderList = AllocateZeroPool (BootOrderListSize);\r
+    ASSERT (BootOrderList != NULL);\r
+    Status = gRT->GetVariable (\r
+                    L"BootOrder", \r
+                    &gEfiGlobalVariableGuid, \r
+                    NULL, \r
+                    &BootOrderListSize, \r
+                    BootOrderList\r
+                    );\r
+  }\r
+  \r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // No Boot option\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  OptionBuffer = NULL;\r
+  for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {\r
+    //\r
+    // Try to find the DevicePath in BootOption\r
+    //\r
+    UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index);\r
+    OptionBuffer = GetEfiGlobalVariable (StrTemp);\r
+    if (OptionBuffer == NULL) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Check whether the image is forbidden.\r
+    //\r
+    \r
+    OptionPtr = OptionBuffer;\r
+    //\r
+    // Skip attribute.\r
+    //\r
+    OptionPtr += sizeof (UINT32);\r
+\r
+    //\r
+    // Skip device path length.\r
+    //\r
+    OptionPtr += sizeof (UINT16);\r
+\r
+    //\r
+    // Skip descript string\r
+    //\r
+    OptionPtr += StrSize ((UINT16 *) OptionPtr);\r
\r
+    //\r
+    // Now OptionPtr points to Device Path.\r
+    //\r
+    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) OptionPtr;\r
+\r
+    if (CheckDevicePath (DevicePath, OptionDevicePath)) {\r
+      FreePool (OptionBuffer);\r
+      OptionBuffer = NULL;\r
+      return TRUE;\r
+    }\r
+    FreePool (OptionBuffer);\r
+    OptionBuffer = NULL;\r
+  }\r
+\r
+  if (BootOrderList != NULL) {\r
+    FreePool (BootOrderList);\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+\r
+/**\r
+  Add the image info to a deferred image list.\r
+\r
+  @param[in]  ImageDevicePath  A pointer to the device path of a image.                                \r
+  @param[in]  Image            Points to the first byte of the image, or NULL if the \r
+                               image is not available.\r
+  @param[in]  ImageSize        The size of the image, or 0 if the image is not available.\r
+  \r
+**/\r
+VOID\r
+PutDefferedImageInfo (\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL    *ImageDevicePath,\r
+  IN        VOID                        *Image,\r
+  IN        UINTN                       ImageSize\r
+  )\r
+{\r
+  DEFERRED_IMAGE_INFO    *CurImageInfo;\r
+  UINTN                  PathSize;\r
+\r
+  //\r
+  // Expand memory for the new deferred image.\r
+  //\r
+  if (mDeferredImage.Count == 0) {\r
+    mDeferredImage.ImageInfo = AllocatePool (sizeof (DEFERRED_IMAGE_INFO));\r
+    ASSERT (mDeferredImage.ImageInfo != NULL);\r
+  } else {\r
+    CurImageInfo = AllocatePool ((mDeferredImage.Count + 1) * sizeof (DEFERRED_IMAGE_INFO));\r
+    ASSERT (CurImageInfo != NULL);\r
+    \r
+    CopyMem (\r
+      CurImageInfo, \r
+      mDeferredImage.ImageInfo,\r
+      mDeferredImage.Count * sizeof (DEFERRED_IMAGE_INFO)\r
+      );\r
+    FreePool (mDeferredImage.ImageInfo);\r
+    mDeferredImage.ImageInfo = CurImageInfo;\r
+  }\r
+  mDeferredImage.Count++;\r
+  \r
+  //\r
+  // Save the deferred image information.\r
+  //\r
+  CurImageInfo = &mDeferredImage.ImageInfo[mDeferredImage.Count - 1];\r
+  PathSize     = GetDevicePathSize (ImageDevicePath);\r
+  CurImageInfo->ImageDevicePath = AllocateZeroPool (PathSize);\r
+  ASSERT (CurImageInfo->ImageDevicePath != NULL);\r
+  CopyMem (CurImageInfo->ImageDevicePath, ImageDevicePath, PathSize);\r
+\r
+  CurImageInfo->Image      = Image;\r
+  CurImageInfo->ImageSize  = ImageSize;\r
+  CurImageInfo->BootOption = IsBootOption (ImageDevicePath);\r
+}\r
+\r
+\r
+/**\r
+  Returns information about a deferred image.\r
+\r
+  This function returns information about a single deferred image. The deferred images are \r
+  numbered consecutively, starting with 0.  If there is no image which corresponds to \r
+  ImageIndex, then EFI_NOT_FOUND is returned. All deferred images may be returned by \r
+  iteratively calling this function until EFI_NOT_FOUND is returned.\r
+  Image may be NULL and ImageSize set to 0 if the decision to defer execution was made \r
+  because of the location of the executable image, rather than its actual contents.  \r
+\r
+  @param[in]  This             Points to this instance of the EFI_DEFERRED_IMAGE_LOAD_PROTOCOL.\r
+  @param[in]  ImageIndex       Zero-based index of the deferred index.\r
+  @param[out] ImageDevicePath  On return, points to a pointer to the device path of the image. \r
+                               The device path should not be freed by the caller. \r
+  @param[out] Image            On return, points to the first byte of the image or NULL if the \r
+                               image is not available. The image should not be freed by the caller\r
+                               unless LoadImage() has been successfully called.  \r
+  @param[out] ImageSize        On return, the size of the image, or 0 if the image is not available.\r
+  @param[out] BootOption       On return, points to TRUE if the image was intended as a boot option \r
+                               or FALSE if it was not intended as a boot option. \r
\r
+  @retval EFI_SUCCESS           Image information returned successfully.\r
+  @retval EFI_NOT_FOUND         ImageIndex does not refer to a valid image.\r
+  @retval EFI_INVALID_PARAMETER ImageDevicePath is NULL or Image is NULL or ImageSize is NULL or \r
+                                BootOption is NULL.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDefferedImageInfo (\r
+  IN     EFI_DEFERRED_IMAGE_LOAD_PROTOCOL  *This,\r
+  IN     UINTN                             ImageIndex,\r
+     OUT EFI_DEVICE_PATH_PROTOCOL          **ImageDevicePath,\r
+     OUT VOID                              **Image,\r
+     OUT UINTN                             *ImageSize,\r
+     OUT BOOLEAN                           *BootOption\r
+  )\r
+{\r
+  DEFERRED_IMAGE_INFO   *ReqImageInfo;\r
+\r
+  //\r
+  // Check the parameter.\r
+  //\r
+\r
+  if ((This == NULL) || (ImageSize == NULL) || (Image == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  if ((ImageDevicePath == NULL) || (BootOption == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (ImageIndex >= mDeferredImage.Count) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  \r
+  //\r
+  // Get the request deferred image.\r
+  // \r
+  ReqImageInfo = &mDeferredImage.ImageInfo[ImageIndex];\r
+   \r
+  *ImageDevicePath = ReqImageInfo->ImageDevicePath;\r
+  *Image           = ReqImageInfo->Image;\r
+  *ImageSize       = ReqImageInfo->ImageSize;\r
+  *BootOption      = ReqImageInfo->BootOption;\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Provides the service of deferring image load based on platform policy control,\r
+  and installs Deferred Image Load Protocol.\r
+\r
+  @param[in]  AuthenticationStatus  This is the authentication status returned from the \r
+                                    security measurement services for the input file.\r
+  @param[in]  File                  This is a pointer to the device path of the file that\r
+                                    is being dispatched. This will optionally be used for\r
+                                    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
+\r
+  @retval EFI_SUCCESS               The file specified by File did authenticate, and the\r
+                                    platform policy dictates that the DXE Core may use File.\r
+  @retval EFI_INVALID_PARAMETER     File is NULL.\r
+  @retval EFI_SECURITY_VIOLATION    The file specified by File did not authenticate, and\r
+                                    the platform policy dictates that File should be placed\r
+                                    in the untrusted state. A file may be promoted from\r
+                                    the untrusted to the trusted state at a future time\r
+                                    with a call to the Trust() DXE Service.\r
+  @retval EFI_ACCESS_DENIED         The file specified by File did not authenticate, and\r
+                                    the platform policy dictates that File should not be\r
+                                    used for any purpose.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeDeferImageLoadHandler (\r
+  IN  UINT32                           AuthenticationStatus,\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File,\r
+  IN  VOID                             *FileBuffer,\r
+  IN  UINTN                            FileSize\r
+  )\r
+\r
+{\r
+  EFI_STATUS                           Status;\r
+  EFI_USER_PROFILE_HANDLE              CurrentUser;\r
+  UINT32                               Policy;\r
+  UINT32                               FileType;\r
+\r
+  if (File == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check whether user has a logon.\r
+  // \r
+  CurrentUser = NULL;\r
+  if (mUserManager != NULL) {\r
+    mUserManager->Current (mUserManager, &CurrentUser);\r
+    if (CurrentUser != NULL) {\r
+      //\r
+      // The user is logon; verify the FilePath by current user access policy.\r
+      //\r
+      if (!VerifyDevicePath (File)) {\r
+        DEBUG ((EFI_D_ERROR, "[Security] The image is forbidden to load!\n"));\r
+        return EFI_ACCESS_DENIED;\r
+      }\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Still no user logon.\r
+  // Check the file type and get policy setting.\r
+  //\r
+  FileType = GetFileType (File);\r
+  Policy   = PcdGet32 (PcdDeferImageLoadPolicy);\r
+  if ((Policy & FileType) == FileType) {\r
+    //\r
+    // This file type is secure to load.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
\r
+  DEBUG ((EFI_D_ERROR, "[Security] No user identified, the image is deferred to load!\n"));\r
+  PutDefferedImageInfo (File, NULL, 0);\r
+\r
+  //\r
+  // Install the Deferred Image Load Protocol onto a new handle.\r
+  //\r
+  if (!mIsProtocolInstalled) {\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &mDeferredImageHandle,\r
+                    &gEfiDeferredImageLoadProtocolGuid,\r
+                    &gDeferredImageLoad,\r
+                    NULL\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+    mIsProtocolInstalled = TRUE;\r
+  }\r
+\r
+  return EFI_ACCESS_DENIED;\r
+}\r
+\r
+/**\r
+  Locate user manager protocol when user manager is installed.  \r
+\r
+  @param[in] Event    The Event that is being processed, not used.\r
+  @param[in] Context  Event Context, not used. \r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FindUserManagerProtocol (\r
+  IN EFI_EVENT    Event,\r
+  IN VOID*        Context\r
+  )\r
+{\r
+  gBS->LocateProtocol (\r
+         &gEfiUserManagerProtocolGuid,\r
+         NULL,\r
+         (VOID **) &mUserManager\r
+         );\r
+  \r
+}\r
+\r
+\r
+/**\r
+  Register security handler for deferred image load.\r
+\r
+  @param[in]  ImageHandle   ImageHandle of the loaded driver.\r
+  @param[in]  SystemTable   Pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS   The handlers were registered successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeDeferImageLoadLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  VOID                 *Registration;\r
+  \r
+  //\r
+  // Register user manager notification function.\r
+  //\r
+  EfiCreateProtocolNotifyEvent (\r
+    &gEfiUserManagerProtocolGuid, \r
+    TPL_CALLBACK,\r
+    FindUserManagerProtocol,\r
+    NULL,\r
+    &Registration\r
+    );\r
+  \r
+  return RegisterSecurityHandler (\r
+           DxeDeferImageLoadHandler,\r
+           EFI_AUTH_OPERATION_DEFER_IMAGE_LOAD \r
+           );      \r
+}\r
+\r
+\r
diff --git a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.h b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.h
new file mode 100644 (file)
index 0000000..52eb81b
--- /dev/null
@@ -0,0 +1,106 @@
+/** @file\r
+  The internal header file includes the common header files, defines\r
+  internal structure and functions used by DeferImageLoadLib.\r
+\r
+Copyright (c) 2009 - 2010, 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 __DEFER_IMAGE_LOAD_LIB_H__\r
+#define __DEFER_IMAGE_LOAD_LIB_H__\r
+\r
+#include <PiDxe.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/SecurityManagementLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Protocol/DeferredImageLoad.h>\r
+#include <Protocol/UserCredential.h>\r
+#include <Protocol/UserManager.h>\r
+#include <Protocol/DevicePathToText.h>\r
+\r
+#include <Guid/GlobalVariable.h>\r
+\r
+//\r
+// Image type definitions.\r
+//\r
+#define IMAGE_UNKNOWN                         0x00000001\r
+#define IMAGE_FROM_FV                         0x00000002\r
+#define IMAGE_FROM_OPTION_ROM                 0x00000004\r
+#define IMAGE_FROM_REMOVABLE_MEDIA            0x00000008\r
+#define IMAGE_FROM_FIXED_MEDIA                0x00000010\r
+\r
+//\r
+// The struct to save the deferred image information.\r
+//\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL          *ImageDevicePath;\r
+  VOID                              *Image;\r
+  UINTN                             ImageSize;\r
+  BOOLEAN                           BootOption;\r
+} DEFERRED_IMAGE_INFO;\r
+\r
+//\r
+// The table to save the deferred image item.\r
+//\r
+typedef struct {\r
+  UINTN                             Count;         ///< deferred image count\r
+  DEFERRED_IMAGE_INFO               *ImageInfo;    ///< deferred image item\r
+} DEFERRED_IMAGE_TABLE;\r
+\r
+/**\r
+  Returns information about a deferred image.\r
+\r
+  This function returns information about a single deferred image. The deferred images are \r
+  numbered consecutively, starting with 0.  If there is no image which corresponds to \r
+  ImageIndex, then EFI_NOT_FOUND is returned. All deferred images may be returned by \r
+  iteratively calling this function until EFI_NOT_FOUND is returned.\r
+  Image may be NULL and ImageSize set to 0 if the decision to defer execution was made \r
+  because of the location of the executable image, rather than its actual contents.  \r
+\r
+  @param[in]  This              Points to this instance of the EFI_DEFERRED_IMAGE_LOAD_PROTOCOL.\r
+  @param[in]  ImageIndex        Zero-based index of the deferred index.\r
+  @param[out] ImageDevicePath   On return, points to a pointer to the device path of the image. \r
+                                The device path should not be freed by the caller. \r
+  @param[out] Image             On return, points to the first byte of the image or NULL if the \r
+                                image is not available. The image should not be freed by the caller\r
+                                unless LoadImage() has been called successfully.  \r
+  @param[out] ImageSize         On return, the size of the image, or 0 if the image is not available.\r
+  @param[out] BootOption        On return, points to TRUE if the image was intended as a boot option \r
+                                or FALSE if it was not intended as a boot option. \r
\r
+  @retval EFI_SUCCESS           Image information returned successfully.\r
+  @retval EFI_NOT_FOUND         ImageIndex does not refer to a valid image.\r
+  @retval EFI_INVALID_PARAMETER ImageDevicePath is NULL or Image is NULL or ImageSize is NULL or \r
+                                BootOption is NULL.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDefferedImageInfo (\r
+  IN     EFI_DEFERRED_IMAGE_LOAD_PROTOCOL  *This,\r
+  IN     UINTN                             ImageIndex,\r
+     OUT EFI_DEVICE_PATH_PROTOCOL          **ImageDevicePath,\r
+     OUT VOID                              **Image,\r
+     OUT UINTN                             *ImageSize,\r
+     OUT BOOLEAN                           *BootOption\r
+  );\r
+  \r
+#endif\r
diff --git a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
new file mode 100644 (file)
index 0000000..e16fe8d
--- /dev/null
@@ -0,0 +1,62 @@
+## @file\r
+#  The library instance provides security service of deferring image load.\r
+#\r
+# Copyright (c) 2009 - 2010, 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                      = DxeDeferImageLoadLib   \r
+  FILE_GUID                      = 5E2FAE1F-41DA-4fbd-BC81-603CE5CD8497\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL|DXE_DRIVER UEFI_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION\r
+  CONSTRUCTOR                    = DxeDeferImageLoadLibConstructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
+#\r
+\r
+[Sources]\r
+  DxeDeferImageLoadLib.c\r
+  DxeDeferImageLoadLib.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+  SecurityManagementLib\r
+  MemoryAllocationLib\r
+  DevicePathLib\r
+  BaseMemoryLib\r
+  PrintLib\r
+  DebugLib \r
+  UefiLib\r
+  PcdLib \r
+\r
+[Protocols]\r
+  gEfiFirmwareVolume2ProtocolGuid\r
+  gEfiBlockIoProtocolGuid\r
+  gEfiSimpleFileSystemProtocolGuid\r
+  gEfiUserManagerProtocolGuid\r
+  gEfiDeferredImageLoadProtocolGuid\r
+  gEfiDevicePathToTextProtocolGuid\r
+  \r
+[Guids]\r
+  gEfiGlobalVariableGuid\r
+  \r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdDeferImageLoadPolicy\r
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
new file mode 100644 (file)
index 0000000..148dbd5
--- /dev/null
@@ -0,0 +1,1368 @@
+/** @file\r
+  Implement image verification services for secure boot service in UEFI2.3.1.\r
+\r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 "DxeImageVerificationLib.h"\r
+\r
+EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader;\r
+UINTN                               mImageSize;\r
+UINT32                              mPeCoffHeaderOffset; \r
+UINT8                               mImageDigest[MAX_DIGEST_SIZE];\r
+UINTN                               mImageDigestSize;\r
+EFI_IMAGE_DATA_DIRECTORY            *mSecDataDir      = NULL;\r
+UINT8                               *mImageBase       = NULL;\r
+EFI_GUID                            mCertType;\r
+\r
+//\r
+// Notify string for authorization UI.\r
+//\r
+CHAR16  mNotifyString1[MAX_NOTIFY_STRING_LEN] = L"Image verification pass but not found in authorized database!";\r
+CHAR16  mNotifyString2[MAX_NOTIFY_STRING_LEN] = L"Launch this image anyway? (Yes/Defer/No)";\r
+//\r
+// Public Exponent of RSA Key.\r
+//\r
+CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };\r
+\r
+\r
+//\r
+// OID ASN.1 Value for Hash Algorithms\r
+//\r
+UINT8 mHashOidValue[] = {\r
+  0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05,         // OBJ_md5\r
+  0x2B, 0x0E, 0x03, 0x02, 0x1A,                           // OBJ_sha1\r
+  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,   // OBJ_sha224\r
+  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,   // OBJ_sha256\r
+  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,   // OBJ_sha384\r
+  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,   // OBJ_sha512\r
+  };\r
+\r
+HASH_TABLE mHash[] = {\r
+  { L"SHA1",   20, &mHashOidValue[8],  5, Sha1GetContextSize,  Sha1Init,   Sha1Update,    Sha1Final  },\r
+  { L"SHA224", 28, &mHashOidValue[13], 9, NULL,                NULL,       NULL,          NULL       },\r
+  { L"SHA256", 32, &mHashOidValue[22], 9, Sha256GetContextSize,Sha256Init, Sha256Update,  Sha256Final},\r
+  { L"SHA384", 48, &mHashOidValue[31], 9, NULL,                NULL,       NULL,          NULL       },\r
+  { L"SHA512", 64, &mHashOidValue[40], 9, NULL,                NULL,       NULL,          NULL       }\r
+};\r
+\r
+\r
+/**\r
+  Get the image type.\r
+\r
+  @param[in]    File       This is a pointer to the device path of the file that is\r
+                           being dispatched. \r
+\r
+  @return UINT32           Image Type             \r
+\r
+**/\r
+UINT32\r
+GetImageType (\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_HANDLE                        DeviceHandle; \r
+  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePath;\r
+  EFI_BLOCK_IO_PROTOCOL             *BlockIo;\r
+\r
+  //\r
+  // First check to see if File is from a Firmware Volume\r
+  //\r
+  DeviceHandle      = NULL;\r
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiFirmwareVolume2ProtocolGuid,\r
+                  &TempDevicePath,\r
+                  &DeviceHandle\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->OpenProtocol (\r
+                    DeviceHandle,\r
+                    &gEfiFirmwareVolume2ProtocolGuid,\r
+                    NULL,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      return IMAGE_FROM_FV;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Next check to see if File is from a Block I/O device\r
+  //\r
+  DeviceHandle   = NULL;\r
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  &TempDevicePath,\r
+                  &DeviceHandle\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    BlockIo = NULL;\r
+    Status = gBS->OpenProtocol (\r
+                    DeviceHandle,\r
+                    &gEfiBlockIoProtocolGuid,\r
+                    (VOID **) &BlockIo,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (!EFI_ERROR (Status) && BlockIo != NULL) {\r
+      if (BlockIo->Media != NULL) {\r
+        if (BlockIo->Media->RemovableMedia) {\r
+          //\r
+          // Block I/O is present and specifies the media is removable\r
+          //\r
+          return IMAGE_FROM_REMOVABLE_MEDIA;\r
+        } else {\r
+          //\r
+          // Block I/O is present and specifies the media is not removable\r
+          //\r
+          return IMAGE_FROM_FIXED_MEDIA;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // File is not in a Firmware Volume or on a Block I/O device, so check to see if \r
+  // the device path supports the Simple File System Protocol.\r
+  //\r
+  DeviceHandle   = NULL;\r
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &TempDevicePath,\r
+                  &DeviceHandle\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Simple File System is present without Block I/O, so assume media is fixed.\r
+    //\r
+    return IMAGE_FROM_FIXED_MEDIA;\r
+  }\r
+\r
+  //\r
+  // File is not from an FV, Block I/O or Simple File System, so the only options\r
+  // left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.  \r
+  //\r
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
+  while (!IsDevicePathEndType (TempDevicePath)) {\r
+    switch (DevicePathType (TempDevicePath)) {\r
+    \r
+    case MEDIA_DEVICE_PATH:\r
+      if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) {\r
+        return IMAGE_FROM_OPTION_ROM;\r
+      }\r
+      break;\r
+\r
+    case MESSAGING_DEVICE_PATH:\r
+      if (DevicePathSubType(TempDevicePath) == MSG_MAC_ADDR_DP) {\r
+        return IMAGE_FROM_REMOVABLE_MEDIA;\r
+      } \r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+    TempDevicePath = NextDevicePathNode (TempDevicePath);\r
+  }\r
+  return IMAGE_UNKNOWN; \r
+}\r
+\r
+/**\r
+  Caculate hash of Pe/Coff image based on the authenticode image hashing in\r
+  PE/COFF Specification 8.0 Appendix A\r
+\r
+  @param[in]    HashAlg   Hash algorithm type.\r
\r
+  @retval TRUE            Successfully hash image.\r
+  @retval FALSE           Fail in hash image.\r
+\r
+**/\r
+BOOLEAN \r
+HashPeImage (\r
+  IN  UINT32              HashAlg\r
+  )\r
+{\r
+  BOOLEAN                   Status;\r
+  UINT16                    Magic;\r
+  EFI_IMAGE_SECTION_HEADER  *Section;\r
+  VOID                      *HashCtx;\r
+  UINTN                     CtxSize;\r
+  UINT8                     *HashBase;\r
+  UINTN                     HashSize;\r
+  UINTN                     SumOfBytesHashed;\r
+  EFI_IMAGE_SECTION_HEADER  *SectionHeader;\r
+  UINTN                     Index;\r
+  UINTN                     Pos;\r
+\r
+  HashCtx       = NULL;\r
+  SectionHeader = NULL;\r
+  Status        = FALSE;\r
+\r
+  if ((HashAlg != HASHALG_SHA1) && (HashAlg != HASHALG_SHA256)) {\r
+    return FALSE;\r
+  }\r
+  \r
+  //\r
+  // Initialize context of hash.\r
+  //\r
+  ZeroMem (mImageDigest, MAX_DIGEST_SIZE);\r
+\r
+  if (HashAlg == HASHALG_SHA1) {\r
+    mImageDigestSize  = SHA1_DIGEST_SIZE;\r
+    mCertType         = gEfiCertSha1Guid;\r
+  } else if (HashAlg == HASHALG_SHA256) {\r
+    mImageDigestSize  = SHA256_DIGEST_SIZE;\r
+    mCertType         = gEfiCertSha256Guid;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+\r
+  CtxSize   = mHash[HashAlg].GetContextSize();\r
+  \r
+  HashCtx = AllocatePool (CtxSize);\r
+  ASSERT (HashCtx != NULL);\r
+\r
+  // 1.  Load the image header into memory.\r
+\r
+  // 2.  Initialize a SHA hash context.\r
+  Status = mHash[HashAlg].HashInit(HashCtx);\r
+  \r
+  if (!Status) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // Measuring PE/COFF Image Header;\r
+  // But CheckSum field and SECURITY data directory (certificate) are excluded\r
+  //\r
+  Magic = mNtHeader.Pe32->OptionalHeader.Magic;\r
+  //\r
+  // 3.  Calculate the distance from the base of the image header to the image checksum address.\r
+  // 4.  Hash the image header from its base to beginning of the image checksum.\r
+  //\r
+  HashBase = mImageBase;\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset.\r
+    //\r
+    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - HashBase);\r
+  } else {\r
+    //\r
+    // Use PE32+ offset.\r
+    //\r
+    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - HashBase);\r
+  }\r
+\r
+  Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+  if (!Status) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // 5.  Skip over the image checksum (it occupies a single ULONG).\r
+  // 6.  Get the address of the beginning of the Cert Directory.\r
+  // 7.  Hash everything from the end of the checksum to the start of the Cert Directory.\r
+  //\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset.\r
+    //\r
+    HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
+    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+  } else {\r
+    //\r
+    // Use PE32+ offset.\r
+    //    \r
+    HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
+    HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+  }\r
+\r
+  Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+  if (!Status) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // 8.  Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)\r
+  // 9.  Hash everything from the end of the Cert Directory to the end of image header.\r
+  //\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset\r
+    //\r
+    HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
+    HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);\r
+  } else {\r
+    //\r
+    // Use PE32+ offset.\r
+    //\r
+    HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
+    HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - mImageBase);\r
+  }\r
+\r
+  Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+  if (!Status) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // 10. Set the SUM_OF_BYTES_HASHED to the size of the header.\r
+  //\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset.\r
+    //\r
+    SumOfBytesHashed = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders;\r
+  } else {\r
+    //\r
+    // Use PE32+ offset\r
+    //\r
+    SumOfBytesHashed = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders;\r
+  }\r
+\r
+  //\r
+  // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER\r
+  //     structures in the image. The 'NumberOfSections' field of the image\r
+  //     header indicates how big the table should be. Do not include any\r
+  //     IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.\r
+  //\r
+  SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections);\r
+  ASSERT (SectionHeader != NULL);\r
+  //\r
+  // 12.  Using the 'PointerToRawData' in the referenced section headers as\r
+  //      a key, arrange the elements in the table in ascending order. In other\r
+  //      words, sort the section headers according to the disk-file offset of\r
+  //      the section.\r
+  //\r
+  Section = (EFI_IMAGE_SECTION_HEADER *) (\r
+               mImageBase +\r
+               mPeCoffHeaderOffset +\r
+               sizeof (UINT32) +\r
+               sizeof (EFI_IMAGE_FILE_HEADER) +\r
+               mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader\r
+               );\r
+  for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) {\r
+    Pos = Index;\r
+    while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {\r
+      CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER));\r
+      Pos--;\r
+    }\r
+    CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER));\r
+    Section += 1;\r
+  }\r
+\r
+  //\r
+  // 13.  Walk through the sorted table, bring the corresponding section\r
+  //      into memory, and hash the entire section (using the 'SizeOfRawData'\r
+  //      field in the section header to determine the amount of data to hash).\r
+  // 14.  Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .\r
+  // 15.  Repeat steps 13 and 14 for all the sections in the sorted table.\r
+  //\r
+  for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) {\r
+    Section = &SectionHeader[Index];\r
+    if (Section->SizeOfRawData == 0) {\r
+      continue;\r
+    }\r
+    HashBase  = mImageBase + Section->PointerToRawData;\r
+    HashSize  = (UINTN) Section->SizeOfRawData;\r
+\r
+    Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+    if (!Status) {\r
+      goto Done;\r
+    }\r
+\r
+    SumOfBytesHashed += HashSize;\r
+  }\r
+\r
+  //\r
+  // 16.  If the file size is greater than SUM_OF_BYTES_HASHED, there is extra\r
+  //      data in the file that needs to be added to the hash. This data begins\r
+  //      at file offset SUM_OF_BYTES_HASHED and its length is:\r
+  //             FileSize  -  (CertDirectory->Size)\r
+  //\r
+  if (mImageSize > SumOfBytesHashed) {\r
+    HashBase = mImageBase + SumOfBytesHashed;\r
+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+      //\r
+      // Use PE32 offset.\r
+      //\r
+      HashSize = (UINTN)(\r
+                 mImageSize -\r
+                 mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -\r
+                 SumOfBytesHashed);\r
+    } else {\r
+      //\r
+      // Use PE32+ offset.\r
+      //\r
+      HashSize = (UINTN)(\r
+                 mImageSize -\r
+                 mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -\r
+                 SumOfBytesHashed);      \r
+    }\r
+\r
+    Status  = mHash[HashAlg].HashUpdate(HashCtx, HashBase, HashSize);\r
+    if (!Status) {\r
+      goto Done;\r
+    }\r
+  }\r
+  Status  = mHash[HashAlg].HashFinal(HashCtx, mImageDigest);\r
+\r
+Done:\r
+  if (HashCtx != NULL) {\r
+    FreePool (HashCtx);\r
+  }\r
+  if (SectionHeader != NULL) {\r
+    FreePool (SectionHeader);\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Recognize the Hash algorithm in PE/COFF Authenticode and caculate hash of \r
+  Pe/Coff image based on the authenticode image hashing in PE/COFF Specification \r
+  8.0 Appendix A\r
+\r
+  @retval EFI_UNSUPPORTED             Hash algorithm is not supported.\r
+  @retval EFI_SUCCESS                 Hash successfully.\r
+\r
+**/\r
+EFI_STATUS \r
+HashPeImageByType (\r
+  VOID\r
+  )\r
+{\r
+  UINT8                     Index;\r
+  WIN_CERTIFICATE_EFI_PKCS  *PkcsCertData;\r
+\r
+  PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *) (mImageBase + mSecDataDir->VirtualAddress);\r
+\r
+  for (Index = 0; Index < HASHALG_MAX; Index++) {  \r
+    //\r
+    // Check the Hash algorithm in PE/COFF Authenticode.\r
+    //    According to PKCS#7 Definition: \r
+    //        SignedData ::= SEQUENCE {\r
+    //            version Version,\r
+    //            digestAlgorithms DigestAlgorithmIdentifiers,\r
+    //            contentInfo ContentInfo,\r
+    //            .... }\r
+    //    The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing\r
+    //    This field has the fixed offset (+32) in final Authenticode ASN.1 data.\r
+    //    \r
+    if (CompareMem (PkcsCertData->CertData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Index == HASHALG_MAX) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // HASH PE Image based on Hash algorithm in PE/COFF Authenticode.\r
+  //\r
+  if (!HashPeImage(Index)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Returns the size of a given image execution info table in bytes.\r
+\r
+  This function returns the size, in bytes, of the image execution info table specified by\r
+  ImageExeInfoTable. If ImageExeInfoTable is NULL, then 0 is returned.\r
+\r
+  @param  ImageExeInfoTable          A pointer to a image execution info table structure.\r
+  \r
+  @retval 0       If ImageExeInfoTable is NULL.\r
+  @retval Others  The size of a image execution info table in bytes.\r
+\r
+**/\r
+UINTN\r
+GetImageExeInfoTableSize (\r
+  EFI_IMAGE_EXECUTION_INFO_TABLE        *ImageExeInfoTable\r
+  )\r
+{\r
+  UINTN                     Index;\r
+  EFI_IMAGE_EXECUTION_INFO  *ImageExeInfoItem;\r
+  UINTN                     TotalSize;\r
+\r
+  if (ImageExeInfoTable == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  ImageExeInfoItem  = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) ImageExeInfoTable + sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE));\r
+  TotalSize         = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);\r
+  for (Index = 0; Index < ImageExeInfoTable->NumberOfImages; Index++) {\r
+    TotalSize += ReadUnaligned32 ((UINT32 *) &ImageExeInfoItem->InfoSize);\r
+    ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) ImageExeInfoItem + ReadUnaligned32 ((UINT32 *) &ImageExeInfoItem->InfoSize));\r
+  }\r
+\r
+  return TotalSize;\r
+}\r
+\r
+/**\r
+  Create an Image Execution Information Table entry and add it to system configuration table.\r
+\r
+  @param[in]  Action          Describes the action taken by the firmware regarding this image.\r
+  @param[in]  Name            Input a null-terminated, user-friendly name.\r
+  @param[in]  DevicePath      Input device path pointer.\r
+  @param[in]  Signature       Input signature info in EFI_SIGNATURE_LIST data structure.\r
+  @param[in]  SignatureSize   Size of signature.\r
+  \r
+**/\r
+VOID\r
+AddImageExeInfo (\r
+  IN       EFI_IMAGE_EXECUTION_ACTION       Action, \r
+  IN       CHAR16                           *Name OPTIONAL, \r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath,\r
+  IN       EFI_SIGNATURE_LIST               *Signature OPTIONAL,\r
+  IN       UINTN                            SignatureSize\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_IMAGE_EXECUTION_INFO_TABLE  *ImageExeInfoTable;\r
+  EFI_IMAGE_EXECUTION_INFO_TABLE  *NewImageExeInfoTable;\r
+  EFI_IMAGE_EXECUTION_INFO        *ImageExeInfoEntry;\r
+  UINTN                           ImageExeInfoTableSize;\r
+  UINTN                           NewImageExeInfoEntrySize;\r
+  UINTN                           NameStringLen;\r
+  UINTN                           DevicePathSize;\r
+\r
+  ASSERT (DevicePath != NULL);\r
+  ImageExeInfoTable     = NULL;\r
+  NewImageExeInfoTable  = NULL;\r
+  ImageExeInfoEntry     = NULL;\r
+  NameStringLen         = 0;\r
+\r
+  if (Name != NULL) {\r
+    NameStringLen = StrSize (Name);\r
+  }\r
+\r
+  ImageExeInfoTable = NULL;\r
+  EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID**)&ImageExeInfoTable);\r
+  if (ImageExeInfoTable != NULL) {\r
+    //\r
+    // The table has been found!\r
+    // We must enlarge the table to accmodate the new exe info entry.\r
+    //\r
+    ImageExeInfoTableSize = GetImageExeInfoTableSize (ImageExeInfoTable);\r
+  } else {\r
+    //\r
+    // Not Found!\r
+    // We should create a new table to append to the configuration table.\r
+    //\r
+    ImageExeInfoTableSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);\r
+  }\r
+\r
+  DevicePathSize            = GetDevicePathSize (DevicePath);\r
+  NewImageExeInfoEntrySize  = sizeof (EFI_IMAGE_EXECUTION_INFO) + NameStringLen + DevicePathSize + SignatureSize;\r
+  NewImageExeInfoTable      = (EFI_IMAGE_EXECUTION_INFO_TABLE *) AllocateRuntimePool (ImageExeInfoTableSize + NewImageExeInfoEntrySize);\r
+  ASSERT (NewImageExeInfoTable != NULL);\r
+\r
+  if (ImageExeInfoTable != NULL) {\r
+    CopyMem (NewImageExeInfoTable, ImageExeInfoTable, ImageExeInfoTableSize);\r
+  } else {\r
+    NewImageExeInfoTable->NumberOfImages = 0;\r
+  }\r
+  NewImageExeInfoTable->NumberOfImages++;\r
+  ImageExeInfoEntry = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) NewImageExeInfoTable + ImageExeInfoTableSize);\r
+  //\r
+  // Update new item's infomation.\r
+  //\r
+  WriteUnaligned32 ((UINT32 *) &ImageExeInfoEntry->Action, Action);\r
+  WriteUnaligned32 ((UINT32 *) &ImageExeInfoEntry->InfoSize, (UINT32) NewImageExeInfoEntrySize);\r
+\r
+  if (Name != NULL) {\r
+    CopyMem ((UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32), Name, NameStringLen);\r
+  }\r
+  CopyMem (\r
+    (UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32) + NameStringLen,\r
+    DevicePath,\r
+    DevicePathSize\r
+    );\r
+  if (Signature != NULL) {\r
+    CopyMem (\r
+      (UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32) + NameStringLen + DevicePathSize,\r
+      Signature,\r
+      SignatureSize\r
+      );\r
+  }\r
+  //\r
+  // Update/replace the image execution table.\r
+  //\r
+  Status = gBS->InstallConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID *) NewImageExeInfoTable);\r
+  ASSERT_EFI_ERROR (Status);\r
+  //\r
+  // Free Old table data!\r
+  //\r
+  if (ImageExeInfoTable != NULL) {\r
+    FreePool (ImageExeInfoTable);\r
+  }\r
+}\r
+\r
+/**\r
+  Discover if the UEFI image is authorized by user's policy setting.\r
+\r
+  @param[in]    Policy            Specify platform's policy setting. \r
+\r
+  @retval EFI_ACCESS_DENIED       Image is not allowed to run.\r
+  @retval EFI_SECURITY_VIOLATION  Image is deferred.\r
+  @retval EFI_SUCCESS             Image is authorized to run.\r
+\r
+**/\r
+EFI_STATUS\r
+ImageAuthorization (\r
+  IN UINT32     Policy\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  EFI_INPUT_KEY Key;\r
+\r
+  Status = EFI_ACCESS_DENIED;\r
+\r
+  switch (Policy) {\r
+  \r
+  case QUERY_USER_ON_SECURITY_VIOLATION:\r
+    do {\r
+      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, mNotifyString1, mNotifyString2, NULL);\r
+      if (Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'y') {\r
+        Status = EFI_SUCCESS;\r
+        break;\r
+      } else if (Key.UnicodeChar == L'N' || Key.UnicodeChar == L'n') {\r
+        Status = EFI_ACCESS_DENIED;\r
+        break;\r
+      } else if (Key.UnicodeChar == L'D' || Key.UnicodeChar == L'd') {\r
+        Status = EFI_SECURITY_VIOLATION;\r
+        break;\r
+      }\r
+    } while (TRUE);\r
+    break;\r
+\r
+  case ALLOW_EXECUTE_ON_SECURITY_VIOLATION:\r
+    Status = EFI_SUCCESS;\r
+    break;\r
+\r
+  case DEFER_EXECUTE_ON_SECURITY_VIOLATION:\r
+    Status = EFI_SECURITY_VIOLATION;\r
+    break;\r
+\r
+  case DENY_EXECUTE_ON_SECURITY_VIOLATION:\r
+    Status = EFI_ACCESS_DENIED;\r
+    break;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Check whether signature is in specified database.\r
+\r
+  @param[in]  VariableName        Name of database variable that is searched in.\r
+  @param[in]  Signature           Pointer to signature that is searched for.\r
+  @param[in]  CertType            Pointer to hash algrithom.\r
+  @param[in]  SignatureSize       Size of Signature.\r
+\r
+  @return TRUE                    Found the signature in the variable database.\r
+  @return FALSE                   Not found the signature in the variable database.\r
+\r
+**/\r
+BOOLEAN\r
+IsSignatureFoundInDatabase (\r
+  IN CHAR16             *VariableName,\r
+  IN UINT8              *Signature, \r
+  IN EFI_GUID           *CertType,\r
+  IN UINTN              SignatureSize\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_SIGNATURE_LIST  *CertList;\r
+  EFI_SIGNATURE_DATA  *Cert;\r
+  UINTN               DataSize;\r
+  UINT8               *Data;\r
+  UINTN               Index;\r
+  UINTN               CertCount;\r
+  BOOLEAN             IsFound;\r
+  //\r
+  // Read signature database variable.\r
+  //\r
+  IsFound   = FALSE;\r
+  Data      = NULL;\r
+  DataSize  = 0;\r
+  Status    = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    return FALSE;\r
+  }\r
+\r
+  Data = (UINT8 *) AllocateZeroPool (DataSize);\r
+  ASSERT (Data != NULL);\r
+\r
+  Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // Enumerate all signature data in SigDB to check if executable's signature exists.\r
+  //\r
+  CertList = (EFI_SIGNATURE_LIST *) Data;\r
+  while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
+    CertCount = (CertList->SignatureListSize - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+    Cert      = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+    if ((CertList->SignatureSize == sizeof(EFI_SIGNATURE_DATA) - 1 + SignatureSize) && (CompareGuid(&CertList->SignatureType, CertType))) {\r
+      for (Index = 0; Index < CertCount; Index++) {\r
+        if (CompareMem (Cert->SignatureData, Signature, SignatureSize) == 0) {\r
+          //\r
+          // Find the signature in database.\r
+          //\r
+          IsFound = TRUE;\r
+          break;\r
+        }\r
+\r
+        Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+      }\r
+\r
+      if (IsFound) {\r
+        break;\r
+      }\r
+    }\r
+\r
+    DataSize -= CertList->SignatureListSize;\r
+    CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+  }\r
+\r
+Done:\r
+  if (Data != NULL) {\r
+    FreePool (Data);\r
+  }\r
+\r
+  return IsFound;\r
+}\r
+\r
+/**\r
+  Verify certificate in WIN_CERT_TYPE_PKCS_SIGNED_DATA format .\r
+\r
+  @retval EFI_SUCCESS                 Image pass verification.\r
+  @retval EFI_SECURITY_VIOLATION      Image fail verification.\r
+  @retval other error value\r
+\r
+**/\r
+EFI_STATUS \r
+VerifyCertPkcsSignedData (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  BOOLEAN                   VerifyStatus;\r
+  WIN_CERTIFICATE_EFI_PKCS  *PkcsCertData;\r
+  EFI_SIGNATURE_LIST        *CertList;\r
+  EFI_SIGNATURE_DATA        *Cert;\r
+  UINTN                     DataSize;\r
+  UINT8                     *Data;\r
+  UINT8                     *RootCert;\r
+  UINTN                     RootCertSize;\r
+  UINTN                     Index;\r
+  UINTN                     CertCount;\r
+\r
+  Data                   = NULL;\r
+  CertList               = NULL;\r
+  Cert                   = NULL;\r
+  RootCert               = NULL;\r
+  RootCertSize           = 0;\r
+  VerifyStatus           = FALSE;\r
+  PkcsCertData           = (WIN_CERTIFICATE_EFI_PKCS *) (mImageBase + mSecDataDir->VirtualAddress);\r
+\r
+  //\r
+  // 1: Find certificate from KEK database and try to verify authenticode struct.\r
+  //\r
+  DataSize = 0;\r
+  Status   = gRT->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, NULL, &DataSize, NULL);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    Data = (UINT8 *)AllocateZeroPool (DataSize);\r
+    ASSERT (Data != NULL);\r
+\r
+    Status = gRT->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, NULL, &DataSize, (VOID *)Data);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+    \r
+    //\r
+    // Find Cert Enrolled in KEK database to verify the signature in pkcs7 signed data.\r
+    // \r
+    CertList = (EFI_SIGNATURE_LIST *) Data;\r
+    while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
+      if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
+        Cert          = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+        CertCount     = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+        for (Index = 0; Index < CertCount; Index++) {\r
+          //\r
+          // Iterate each Signature Data Node within this CertList for a verify\r
+          //        \r
+          RootCert      = Cert->SignatureData;\r
+          RootCertSize  = CertList->SignatureSize;\r
+  \r
+          //\r
+          // Call AuthenticodeVerify library to Verify Authenticode struct. \r
+          //\r
+          VerifyStatus = AuthenticodeVerify (\r
+                           PkcsCertData->CertData,\r
+                           mSecDataDir->Size - sizeof(PkcsCertData->Hdr),\r
+                           RootCert,\r
+                           RootCertSize,\r
+                           mImageDigest,\r
+                           mImageDigestSize\r
+                           );\r
+  \r
+          if (VerifyStatus) {\r
+            goto Done;\r
+          }\r
+          Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+        }        \r
+      }\r
+      DataSize -= CertList->SignatureListSize;\r
+      CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+    }\r
+  }\r
+\r
+  \r
+\r
+  //\r
+  // 2: Find certificate from DB database and try to verify authenticode struct.\r
+  //\r
+  DataSize = 0;\r
+  Status   = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    Data = (UINT8 *)AllocateZeroPool (DataSize);\r
+    ASSERT (Data != NULL);\r
+\r
+    Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *)Data);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Find Cert Enrolled in DB database to verify the signature in pkcs7 signed data.\r
+    // \r
+    CertList = (EFI_SIGNATURE_LIST *) Data;\r
+    while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
+      if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
+        Cert          = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+        CertCount     = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+        for (Index = 0; Index < CertCount; Index++) {\r
+          //\r
+          // Iterate each Signature Data Node within this CertList for a verify\r
+          //        \r
+          RootCert      = Cert->SignatureData;\r
+          RootCertSize  = CertList->SignatureSize;\r
+  \r
+          //\r
+          // Call AuthenticodeVerify library to Verify Authenticode struct. \r
+          //\r
+          VerifyStatus = AuthenticodeVerify (\r
+                           PkcsCertData->CertData,\r
+                           mSecDataDir->Size - sizeof(PkcsCertData->Hdr),\r
+                           RootCert,\r
+                           RootCertSize,\r
+                           mImageDigest,\r
+                           mImageDigestSize\r
+                           );\r
+  \r
+          if (VerifyStatus) {\r
+            goto Done;\r
+          }\r
+          Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
+        }        \r
+      }\r
+      DataSize -= CertList->SignatureListSize;\r
+      CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+    }\r
+  }\r
+\r
+Done:\r
+  if (Data != NULL) {\r
+    FreePool (Data);\r
+  }\r
+\r
+  if (VerifyStatus) {\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
+}\r
+\r
+/**\r
+  Verify certificate in WIN_CERTIFICATE_UEFI_GUID format. \r
+\r
+  @retval EFI_SUCCESS                 Image pass verification.\r
+  @retval EFI_SECURITY_VIOLATION      Image fail verification.\r
+  @retval other error value\r
+\r
+**/\r
+EFI_STATUS \r
+VerifyCertUefiGuid (\r
+  VOID\r
+  )\r
+{\r
+  BOOLEAN                         Status;\r
+  WIN_CERTIFICATE_UEFI_GUID       *EfiCert;\r
+  EFI_SIGNATURE_LIST              *KekList;\r
+  EFI_SIGNATURE_DATA              *KekItem;\r
+  EFI_CERT_BLOCK_RSA_2048_SHA256  *CertBlock;\r
+  VOID                            *Rsa;\r
+  UINTN                           KekCount;\r
+  UINTN                           Index;\r
+  UINTN                           KekDataSize;\r
+  BOOLEAN                         IsFound;\r
+  EFI_STATUS                      Result;\r
+\r
+  EfiCert   = NULL;\r
+  KekList   = NULL;\r
+  KekItem   = NULL;\r
+  CertBlock = NULL;\r
+  Rsa       = NULL;\r
+  Status    = FALSE;\r
+  IsFound   = FALSE;\r
+  KekDataSize = 0;\r
+\r
+  EfiCert   = (WIN_CERTIFICATE_UEFI_GUID *) (mImageBase + mSecDataDir->VirtualAddress);\r
+  CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) EfiCert->CertData;\r
+  if (!CompareGuid (&EfiCert->CertType, &gEfiCertTypeRsa2048Sha256Guid)) {\r
+    //\r
+    // Invalid Certificate Data Type.\r
+    //\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
+\r
+  //\r
+  // Get KEK database variable data size\r
+  //\r
+  Result = gRT->GetVariable (EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid, NULL, &KekDataSize, NULL);\r
+  if (Result != EFI_BUFFER_TOO_SMALL) {\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
+\r
+  //\r
+  // Get KEK database variable.\r
+  //\r
+  KekList = GetEfiGlobalVariable (EFI_KEY_EXCHANGE_KEY_NAME);\r
+  if (KekList == NULL) {\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
+  \r
+  //\r
+  // Enumerate all Kek items in this list to verify the variable certificate data.\r
+  // If anyone is authenticated successfully, it means the variable is correct!\r
+  //\r
+  while ((KekDataSize > 0) && (KekDataSize >= KekList->SignatureListSize)) {\r
+    if (CompareGuid (&KekList->SignatureType, &gEfiCertRsa2048Guid)) {\r
+      KekItem   = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize);\r
+      KekCount  = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize;\r
+      for (Index = 0; Index < KekCount; Index++) {\r
+        if (CompareMem (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {\r
+          IsFound = TRUE;\r
+          break;\r
+        }\r
+        KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize);\r
+      }\r
+    }\r
+    KekDataSize -= KekList->SignatureListSize;\r
+    KekList = (EFI_SIGNATURE_LIST *) ((UINT8 *) KekList + KekList->SignatureListSize);\r
+  }\r
+  \r
+  if (!IsFound) {\r
+    //\r
+    // Signed key is not a trust one.\r
+    //\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Now, we found the corresponding security policy.\r
+  // Verify the data payload.\r
+  //\r
+  Rsa = RsaNew ();\r
+  ASSERT (Rsa != NULL);\r
+  // \r
+  // Set RSA Key Components.\r
+  // NOTE: Only N and E are needed to be set as RSA public key for signature verification.\r
+  //\r
+  Status = RsaSetKey (Rsa, RsaKeyN, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE);\r
+  if (!Status) {\r
+    goto Done;\r
+  }\r
+  Status = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));\r
+  if (!Status) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // Verify the signature.\r
+  //\r
+  Status = RsaPkcs1Verify (\r
+             Rsa, \r
+             mImageDigest, \r
+             mImageDigestSize, \r
+             CertBlock->Signature, \r
+             EFI_CERT_TYPE_RSA2048_SHA256_SIZE\r
+             );\r
\r
+Done:\r
+  if (KekList != NULL) {\r
+    FreePool (KekList);\r
+  }\r
+  if (Rsa != NULL ) {\r
+    RsaFree (Rsa);\r
+  }\r
+  if (Status) {\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
+}\r
+\r
+/**\r
+  Provide verification service for signed images, which include both signature validation\r
+  and platform policy control. For signature types, both UEFI WIN_CERTIFICATE_UEFI_GUID and \r
+  MSFT Authenticode type signatures are supported.\r
+  \r
+  In this implementation, only verify external executables when in USER MODE.\r
+  Executables from FV is bypass, so pass in AuthenticationStatus is ignored. \r
+\r
+  @param[in]    AuthenticationStatus \r
+                           This is the authentication status returned from the security\r
+                           measurement services for the 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
+\r
+  @retval EFI_SUCCESS            The file specified by File did authenticate, and the\r
+                                 platform policy dictates that the DXE Core may use File.\r
+  @retval EFI_INVALID_PARAMETER  File is NULL.\r
+  @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and\r
+                                 the platform policy dictates that File should be placed\r
+                                 in the untrusted state. A file may be promoted from\r
+                                 the untrusted to the trusted state at a future time\r
+                                 with a call to the Trust() DXE Service.\r
+  @retval EFI_ACCESS_DENIED      The file specified by File did not authenticate, and\r
+                                 the platform policy dictates that File should not be\r
+                                 used for any purpose.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeImageVerificationHandler (\r
+  IN  UINT32                           AuthenticationStatus,\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File,\r
+  IN  VOID                             *FileBuffer,\r
+  IN  UINTN                            FileSize\r
+  )\r
+\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINT16                      Magic;\r
+  EFI_IMAGE_DOS_HEADER        *DosHdr;\r
+  EFI_STATUS                  VerifyStatus;\r
+  UINT8                       *SetupMode;\r
+  EFI_SIGNATURE_LIST          *SignatureList;\r
+  UINTN                       SignatureListSize;\r
+  EFI_SIGNATURE_DATA          *Signature;\r
+  EFI_IMAGE_EXECUTION_ACTION  Action;\r
+  WIN_CERTIFICATE             *WinCertificate;\r
+  UINT32                      Policy;\r
+\r
+  if (File == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  SignatureList     = NULL;\r
+  SignatureListSize = 0;\r
+  WinCertificate    = NULL;\r
+  Action            = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;\r
+  Status            = EFI_ACCESS_DENIED;\r
+  //\r
+  // Check the image type and get policy setting.\r
+  //\r
+  switch (GetImageType (File)) {\r
+  \r
+  case IMAGE_FROM_FV:\r
+    Policy = ALWAYS_EXECUTE;\r
+    break;\r
+\r
+  case IMAGE_FROM_OPTION_ROM:\r
+    Policy = PcdGet32 (PcdOptionRomImageVerificationPolicy);\r
+    break;\r
+\r
+  case IMAGE_FROM_REMOVABLE_MEDIA:\r
+    Policy = PcdGet32 (PcdRemovableMediaImageVerificationPolicy);\r
+    break;\r
+\r
+  case IMAGE_FROM_FIXED_MEDIA:\r
+    Policy = PcdGet32 (PcdFixedMediaImageVerificationPolicy);\r
+    break;\r
+\r
+  default:\r
+    Policy = DENY_EXECUTE_ON_SECURITY_VIOLATION; \r
+    break;\r
+  }\r
+  //\r
+  // If policy is always/never execute, return directly.\r
+  //\r
+  if (Policy == ALWAYS_EXECUTE) {\r
+    return EFI_SUCCESS;\r
+  } else if (Policy == NEVER_EXECUTE) {\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+  SetupMode = GetEfiGlobalVariable (EFI_SETUP_MODE_NAME);\r
+\r
+  //\r
+  // SetupMode doesn't exist means no AuthVar driver is dispatched,\r
+  // skip verification.\r
+  //\r
+  if (SetupMode == NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // If platform is in SETUP MODE, skip verification.\r
+  //\r
+  if (*SetupMode == SETUP_MODE) {\r
+    FreePool (SetupMode);\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // Read the Dos header.\r
+  //\r
+  ASSERT (FileBuffer != NULL);\r
+  mImageBase  = (UINT8 *) FileBuffer;\r
+  mImageSize  = FileSize;\r
+  DosHdr      = (EFI_IMAGE_DOS_HEADER *) (mImageBase);\r
+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+    //\r
+    // DOS image header is present, \r
+    // so read the PE header after the DOS image header.\r
+    //\r
+    mPeCoffHeaderOffset = DosHdr->e_lfanew;\r
+  } else {\r
+    mPeCoffHeaderOffset = 0;\r
+  }\r
+  //\r
+  // Check PE/COFF image.\r
+  //\r
+  mNtHeader.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (mImageBase + mPeCoffHeaderOffset);\r
+  if (mNtHeader.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+    //\r
+    // It is not a valid Pe/Coff file.\r
+    //\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  Magic = mNtHeader.Pe32->OptionalHeader.Magic;\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset.\r
+    //\r
+    mSecDataDir = (EFI_IMAGE_DATA_DIRECTORY *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
+  } else {\r
+    //\r
+    // Use PE32+ offset.\r
+    //\r
+    mSecDataDir = (EFI_IMAGE_DATA_DIRECTORY *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];\r
+  }\r
+\r
+  if (mSecDataDir->Size == 0) {\r
+    //\r
+    // This image is not signed.\r
+    //\r
+    Action = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;\r
+    Status = EFI_ACCESS_DENIED;  \r
+    goto Done; \r
+  }\r
+  //\r
+  // Verify signature of executables.\r
+  //\r
+  WinCertificate = (WIN_CERTIFICATE *) (mImageBase + mSecDataDir->VirtualAddress);\r
+\r
+  switch (WinCertificate->wCertificateType) {\r
+  \r
+  case WIN_CERT_TYPE_EFI_GUID:\r
+    //\r
+    // Verify UEFI GUID type.\r
+    //   \r
+    if (!HashPeImage (HASHALG_SHA256)) {\r
+      goto Done;\r
+    }\r
+\r
+    VerifyStatus = VerifyCertUefiGuid ();\r
+    break;\r
+\r
+  case WIN_CERT_TYPE_PKCS_SIGNED_DATA:\r
+    //\r
+    // Verify Pkcs signed data type.\r
+    //\r
+    Status    = HashPeImageByType();\r
+    if (EFI_ERROR(Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    VerifyStatus = VerifyCertPkcsSignedData ();\r
+\r
+    //\r
+    // For image verification against enrolled certificate(root or intermediate),\r
+    // no need to check image's hash in the allowed database.\r
+    //\r
+    if (!EFI_ERROR (VerifyStatus)) {\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+  default:\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+  //\r
+  // Get image hash value as executable's signature.\r
+  //\r
+  SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;\r
+  SignatureList     = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SignatureListSize);\r
+  ASSERT (SignatureList != NULL);\r
+  SignatureList->SignatureHeaderSize  = 0;\r
+  SignatureList->SignatureListSize    = (UINT32) SignatureListSize;\r
+  SignatureList->SignatureSize        = (UINT32) mImageDigestSize;\r
+  CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));\r
+  Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
+  CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
+  //\r
+  // Signature database check after verification.\r
+  //\r
+  if (EFI_ERROR (VerifyStatus)) {\r
+    //\r
+    // Verification failure.\r
+    //\r
+    Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;\r
+    Status = EFI_ACCESS_DENIED;\r
+  } else if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, Signature->SignatureData, &mCertType, mImageDigestSize)) {\r
+    //\r
+    // Executable signature verification passes, but is found in forbidden signature database.\r
+    //\r
+    Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;\r
+    Status = EFI_ACCESS_DENIED;\r
+  } else if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, Signature->SignatureData, &mCertType, mImageDigestSize)) {\r
+    //\r
+    // Executable signature is found in authorized signature database.\r
+    //\r
+    Status = EFI_SUCCESS;\r
+  } else {\r
+    //\r
+    // Executable signature verification passes, but cannot be found in authorized signature database.\r
+    // Get platform policy to determine the action.\r
+    //\r
+    Action = EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED;\r
+    Status = ImageAuthorization (Policy);\r
+  }\r
+\r
+Done:\r
+  if (Status != EFI_SUCCESS) {\r
+    //\r
+    // Policy decides to defer or reject the image; add its information in image executable information table.\r
+    //\r
+    AddImageExeInfo (Action, NULL, File, SignatureList, SignatureListSize);\r
+  }\r
+\r
+  if (SignatureList != NULL) {\r
+    FreePool (SignatureList);\r
+  }\r
+\r
+  FreePool (SetupMode);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  When VariableWriteArchProtocol install, create "SecureBoot" variable.\r
+  \r
+  @param[in] Event    Event whose notification function is being invoked.\r
+  @param[in] Context  Pointer to the notification function's context.\r
+  \r
+**/\r
+VOID\r
+EFIAPI\r
+VariableWriteCallBack (\r
+  IN  EFI_EVENT                           Event,\r
+  IN  VOID                                *Context\r
+  )\r
+{\r
+  UINT8                       SecureBootMode;\r
+  UINT8                       *SecureBootModePtr;\r
+  EFI_STATUS                  Status;\r
+  VOID                        *ProtocolPointer;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, &ProtocolPointer);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+  \r
+  //\r
+  // Check whether "SecureBoot" variable exists.\r
+  // If this library is built-in, it means firmware has capability to perform\r
+  // driver signing verification.\r
+  //\r
+  SecureBootModePtr = GetEfiGlobalVariable (EFI_SECURE_BOOT_MODE_NAME);\r
+  if (SecureBootModePtr == NULL) {\r
+    SecureBootMode   = SECURE_BOOT_MODE_DISABLE;\r
+    //\r
+    // Authenticated variable driver will update "SecureBoot" depending on SetupMode variable.\r
+    //\r
+    gRT->SetVariable (\r
+           EFI_SECURE_BOOT_MODE_NAME,\r
+           &gEfiGlobalVariableGuid,\r
+           EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+           sizeof (UINT8),\r
+           &SecureBootMode\r
+           );\r
+  } else {\r
+    FreePool (SecureBootModePtr);\r
+  }\r
+}  \r
+\r
+/**\r
+  Register security measurement handler.\r
+\r
+  @param  ImageHandle   ImageHandle of the loaded driver.\r
+  @param  SystemTable   Pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS   The handlers were registered successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeImageVerificationLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  VOID                *Registration;\r
+\r
+  //\r
+  // Register callback function upon VariableWriteArchProtocol.\r
+  // \r
+  EfiCreateProtocolNotifyEvent (\r
+    &gEfiVariableWriteArchProtocolGuid,\r
+    TPL_CALLBACK,\r
+    VariableWriteCallBack,\r
+    NULL,\r
+    &Registration\r
+    );\r
+\r
+  return RegisterSecurityHandler (\r
+          DxeImageVerificationHandler,\r
+          EFI_AUTH_OPERATION_VERIFY_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED\r
+          );      \r
+}\r
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h
new file mode 100644 (file)
index 0000000..34ed0c8
--- /dev/null
@@ -0,0 +1,201 @@
+/** @file\r
+  The internal header file includes the common header files, defines\r
+  internal structure and functions used by ImageVerificationLib.\r
+\r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 __IMAGEVERIFICATIONLIB_H__\r
+#define __IMAGEVERIFICATIONLIB_H__\r
+\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/SecurityManagementLib.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Protocol/VariableWrite.h>\r
+#include <Guid/ImageAuthentication.h>\r
+#include <IndustryStandard/PeImage.h>\r
+\r
+#define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256\r
+#define EFI_CERT_TYPE_RSA2048_SIZE        256\r
+#define MAX_NOTIFY_STRING_LEN             64\r
+\r
+//\r
+// Image type definitions\r
+//\r
+#define IMAGE_UNKNOWN                         0x00000000\r
+#define IMAGE_FROM_FV                         0x00000001\r
+#define IMAGE_FROM_OPTION_ROM                 0x00000002\r
+#define IMAGE_FROM_REMOVABLE_MEDIA            0x00000003\r
+#define IMAGE_FROM_FIXED_MEDIA                0x00000004\r
+\r
+//\r
+// Authorization policy bit definition\r
+//\r
+#define ALWAYS_EXECUTE                         0x00000000\r
+#define NEVER_EXECUTE                          0x00000001\r
+#define ALLOW_EXECUTE_ON_SECURITY_VIOLATION    0x00000002\r
+#define DEFER_EXECUTE_ON_SECURITY_VIOLATION    0x00000003\r
+#define DENY_EXECUTE_ON_SECURITY_VIOLATION     0x00000004\r
+#define QUERY_USER_ON_SECURITY_VIOLATION       0x00000005\r
+\r
+//\r
+// Support hash types\r
+//\r
+#define HASHALG_SHA1                           0x00000000\r
+#define HASHALG_SHA224                         0x00000001\r
+#define HASHALG_SHA256                         0x00000002\r
+#define HASHALG_SHA384                         0x00000003\r
+#define HASHALG_SHA512                         0x00000004\r
+#define HASHALG_MAX                            0x00000005\r
+\r
+//\r
+// Set max digest size as SHA256 Output (32 bytes) by far\r
+//\r
+#define MAX_DIGEST_SIZE    SHA256_DIGEST_SIZE      \r
+//\r
+//\r
+// PKCS7 Certificate definition\r
+//\r
+typedef struct {\r
+  WIN_CERTIFICATE Hdr;\r
+  UINT8           CertData[1];\r
+} WIN_CERTIFICATE_EFI_PKCS;\r
+\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for hash operations.\r
+\r
+**/\r
+typedef\r
+UINTN\r
+(EFIAPI *HASH_GET_CONTEXT_SIZE)(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HashContext as hash context for\r
+  subsequent use.\r
+\r
+  If HashContext is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HashContext  Pointer to  Context being initialized.\r
+\r
+  @retval TRUE   HASH context initialization succeeded.\r
+  @retval FALSE  HASH context initialization failed.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *HASH_INIT)(\r
+  IN OUT  VOID  *HashContext\r
+  );\r
+\r
+\r
+/**\r
+  Performs digest on a data buffer of the specified length. This function can\r
+  be called multiple times to compute the digest of long or discontinuous data streams.\r
+\r
+  If HashContext is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HashContext  Pointer to the MD5 context.\r
+  @param[in]       Data         Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataLength   Length of Data buffer in bytes.\r
+\r
+  @retval TRUE     HASH data digest succeeded.\r
+  @retval FALSE    Invalid HASH context. After HashFinal function has been called, the\r
+                   HASH context cannot be reused.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *HASH_UPDATE)(\r
+  IN OUT  VOID        *HashContext,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataLength\r
+  );\r
+\r
+/**\r
+  Completes hash computation and retrieves the digest value into the specified\r
+  memory. After this function has been called, the context cannot be used again.\r
+\r
+  If HashContext is NULL, then ASSERT().\r
+  If HashValue is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HashContext  Pointer to the MD5 context\r
+  @param[out]      HashValue    Pointer to a buffer that receives the HASH digest\r
+                                value.\r
+\r
+  @retval TRUE   HASH digest computation succeeded.\r
+  @retval FALSE  HASH digest computation failed.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *HASH_FINAL)(\r
+  IN OUT  VOID   *HashContext,\r
+  OUT     UINT8  *HashValue\r
+  );\r
+\r
+\r
+//\r
+// Hash Algorithm Table\r
+//\r
+typedef struct {\r
+  //\r
+  // Name for Hash Algorithm\r
+  //\r
+  CHAR16                   *Name;\r
+  //\r
+  // Digest Length\r
+  //\r
+  UINTN                    DigestLength;\r
+  //\r
+  // Hash Algorithm OID ASN.1 Value\r
+  //\r
+  UINT8                    *OidValue;\r
+  //\r
+  // Length of Hash OID Value\r
+  //\r
+  UINTN                    OidLength;\r
+  //\r
+  // Pointer to Hash GetContentSize function\r
+  //\r
+  HASH_GET_CONTEXT_SIZE    GetContextSize;\r
+  //\r
+  // Pointer to Hash Init function\r
+  //\r
+  HASH_INIT                HashInit;\r
+  //\r
+  // Pointer to Hash Update function\r
+  //\r
+  HASH_UPDATE              HashUpdate;\r
+  //\r
+  // Pointer to Hash Final function\r
+  //\r
+  HASH_FINAL               HashFinal;\r
+} HASH_TABLE;\r
+\r
+#endif\r
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
new file mode 100644 (file)
index 0000000..5874d6b
--- /dev/null
@@ -0,0 +1,73 @@
+## @file\r
+#  The library instance provides security service of image verification.\r
+#  Image verification Library module supports UEFI2.3.1\r
+#\r
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# 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                      = DxeImageVerificationLib   \r
+  FILE_GUID                      = 0CA970E1-43FA-4402-BC0A-81AF336BFFD6\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                    = DxeImageVerificationLibConstructor\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
+  DxeImageVerificationLib.c\r
+  DxeImageVerificationLib.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  CryptoPkg/CryptoPkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  BaseLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  DevicePathLib\r
+  BaseCryptLib\r
+  SecurityManagementLib\r
+\r
+[Protocols]\r
+  gEfiFirmwareVolume2ProtocolGuid\r
+  gEfiBlockIoProtocolGuid\r
+  gEfiSimpleFileSystemProtocolGuid\r
+  gEfiVariableWriteArchProtocolGuid\r
+  \r
+[Guids]\r
+  gEfiCertTypeRsa2048Sha256Guid\r
+  gEfiImageSecurityDatabaseGuid\r
+  gEfiCertSha1Guid\r
+  gEfiCertSha256Guid\r
+  gEfiCertX509Guid\r
+  gEfiCertRsa2048Guid\r
+  \r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy\r
+\r
+  \r
+\r
+\r
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
new file mode 100644 (file)
index 0000000..c012f13
--- /dev/null
@@ -0,0 +1,830 @@
+/** @file\r
+  The library instance provides security service of TPM measure boot.  \r
+\r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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/TcgService.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/DiskIo.h>\r
+#include <Protocol/DevicePathToText.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
+\r
+//\r
+// Flag to check GPT partition. It only need be measured once.\r
+//\r
+BOOLEAN                           mMeasureGptTableFlag = FALSE;\r
+EFI_GUID                          mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
+UINTN                             mMeasureGptCount = 0;\r
+\r
+/**\r
+  Reads contents of a PE/COFF image in memory 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
+ImageRead (\r
+  IN     VOID    *FileHandle,\r
+  IN     UINTN   FileOffset,\r
+  IN OUT UINTN   *ReadSize,\r
+  OUT    VOID    *Buffer\r
+  )\r
+{\r
+  CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Measure GPT table data into TPM log.\r
+\r
+  @param TcgProtocol             Pointer to the located TCG 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
+TcgMeasureGptTable (\r
+  IN  EFI_TCG_PROTOCOL   *TcgProtocol,\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
+  TCG_PCR_EVENT                     *TcgEvent;\r
+  EFI_GPT_DATA                      *GptData;\r
+  UINT32                            EventSize;\r
+  UINT32                            EventNumber;\r
+  EFI_PHYSICAL_ADDRESS              EventLogLastEntry;\r
+\r
+  if (mMeasureGptCount > 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, &mZeroGuid)) {\r
+      NumberOfPartition++;  \r
+    }\r
+    PartitionEntry++;\r
+  }\r
+\r
+  //\r
+  // Parepare Data for Measurement\r
+  // \r
+  EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) \r
+                        + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry);\r
+  TcgEvent = (TCG_PCR_EVENT *) AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT));\r
+  if (TcgEvent == NULL) {\r
+    FreePool (PrimaryHeader);\r
+    FreePool (EntryPtr);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  TcgEvent->PCRIndex   = 5;\r
+  TcgEvent->EventType  = EV_EFI_GPT_EVENT;\r
+  TcgEvent->EventSize  = EventSize;\r
+  GptData = (EFI_GPT_DATA *) TcgEvent->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, &mZeroGuid)) {\r
+      CopyMem (\r
+        (UINT8 *)&GptData->Partitions + NumberOfPartition * sizeof (EFI_PARTITION_ENTRY),\r
+        (UINT8 *)PartitionEntry,\r
+        sizeof (EFI_PARTITION_ENTRY)\r
+        );\r
+      NumberOfPartition++;\r
+    }\r
+    PartitionEntry++;\r
+  }\r
+\r
+  //\r
+  // Measure the GPT data\r
+  //\r
+  EventNumber = 1;\r
+  Status = TcgProtocol->HashLogExtendEvent (\r
+             TcgProtocol,\r
+             (EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) GptData,\r
+             (UINT64) TcgEvent->EventSize,\r
+             TPM_ALG_SHA,\r
+             TcgEvent,\r
+             &EventNumber,\r
+             &EventLogLastEntry\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    mMeasureGptCount++;\r
+  }\r
+\r
+  FreePool (PrimaryHeader);\r
+  FreePool (EntryPtr);\r
+  FreePool (TcgEvent);\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
+  @param[in] TcgProtocol    Pointer to the located TCG 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 other error value\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TcgMeasurePeImage (\r
+  IN  EFI_TCG_PROTOCOL          *TcgProtocol,\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
+  TCG_PCR_EVENT                     *TcgEvent;\r
+  EFI_IMAGE_LOAD_EVENT              *ImageLoad;\r
+  UINT32                            FilePathSize;\r
+  VOID                              *Sha1Ctx;\r
+  UINTN                             CtxSize;\r
+  EFI_IMAGE_DOS_HEADER              *DosHdr;\r
+  UINT32                            PeCoffHeaderOffset;\r
+  EFI_IMAGE_SECTION_HEADER          *Section;\r
+  UINT8                             *HashBase;\r
+  UINTN                             HashSize;\r
+  UINTN                             SumOfBytesHashed;\r
+  EFI_IMAGE_SECTION_HEADER          *SectionHeader;\r
+  UINTN                             Index, Pos;\r
+  UINT16                            Magic;\r
+  UINT32                            EventSize;\r
+  UINT32                            EventNumber;\r
+  EFI_PHYSICAL_ADDRESS              EventLogLastEntry;\r
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;\r
+\r
+  Status        = EFI_SUCCESS;\r
+  ImageLoad     = NULL;\r
+  SectionHeader = NULL;\r
+  Sha1Ctx       = NULL;\r
+  FilePathSize  = (UINT32) GetDevicePathSize (FilePath);\r
+\r
+  //\r
+  // Determine destination PCR by BootPolicy\r
+  //\r
+  EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize;\r
+  TcgEvent = AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT));\r
+  if (TcgEvent == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  TcgEvent->EventSize = EventSize;\r
+  ImageLoad           = (EFI_IMAGE_LOAD_EVENT *) TcgEvent->Event;\r
+\r
+  switch (ImageType) {\r
+    case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:\r
+      TcgEvent->EventType = EV_EFI_BOOT_SERVICES_APPLICATION;\r
+      TcgEvent->PCRIndex  = 4;\r
+      break;\r
+    case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:\r
+      TcgEvent->EventType = EV_EFI_BOOT_SERVICES_DRIVER;\r
+      TcgEvent->PCRIndex  = 2;\r
+      break;\r
+    case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
+      TcgEvent->EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;\r
+      TcgEvent->PCRIndex  = 2;\r
+      break;\r
+    default:\r
+      DEBUG ((\r
+        EFI_D_ERROR,\r
+        "TcgMeasurePeImage: Unknown subsystem type %d",\r
+        ImageType\r
+        ));\r
+      ASSERT (FALSE);\r
+      TcgEvent->EventType = ImageType;\r
+      Status = EFI_UNSUPPORTED;\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
+  // Check PE/COFF image\r
+  //\r
+  DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress;\r
+  PeCoffHeaderOffset = 0;\r
+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+    PeCoffHeaderOffset = DosHdr->e_lfanew;\r
+  }\r
+  if (((EFI_TE_IMAGE_HEADER *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset))->Signature\r
+       == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // PE/COFF Image Measurement\r
+  //\r
+  //    NOTE: The following codes/steps are based upon the authenticode image hashing in\r
+  //      PE/COFF Specification 8.0 Appendix A.\r
+  //\r
+  //\r
+\r
+  // 1.  Load the image header into memory.\r
+\r
+  // 2.  Initialize a SHA hash context.\r
+  CtxSize = Sha1GetContextSize ();\r
+  Sha1Ctx = AllocatePool (CtxSize);\r
+  if (Sha1Ctx == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Finish;\r
+  }\r
+\r
+  Sha1Init (Sha1Ctx);\r
+\r
+  //\r
+  // Measuring PE/COFF Image Header;\r
+  // But CheckSum field and SECURITY data directory (certificate) are excluded\r
+  //\r
+  Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset);\r
+  Magic    = Hdr.Pe32->OptionalHeader.Magic;\r
+  \r
+  //\r
+  // 3.  Calculate the distance from the base of the image header to the image checksum address.\r
+  // 4.  Hash the image header from its base to beginning of the image checksum.\r
+  //\r
+  HashBase = (UINT8 *) (UINTN) ImageAddress;\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset\r
+    //\r
+    HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.CheckSum) - HashBase);\r
+  } else {\r
+    //\r
+    // Use PE32+ offset\r
+    //\r
+    HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - HashBase);\r
+  }\r
+\r
+  Sha1Update (Sha1Ctx, HashBase, HashSize);\r
+\r
+  //\r
+  // 5.  Skip over the image checksum (it occupies a single ULONG).\r
+  // 6.  Get the address of the beginning of the Cert Directory.\r
+  // 7.  Hash everything from the end of the checksum to the start of the Cert Directory.\r
+  //\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset\r
+    //\r
+    HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
+    HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+  } else {\r
+    //\r
+    // Use PE32+ offset\r
+    //    \r
+    HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
+    HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);\r
+  }\r
+\r
+  Sha1Update (Sha1Ctx, HashBase, HashSize);\r
+\r
+  //\r
+  // 8.  Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)\r
+  // 9.  Hash everything from the end of the Cert Directory to the end of image header.\r
+  //\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset\r
+    //\r
+    HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
+    HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders -\r
+             (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) (UINTN) ImageAddress);\r
+  } else {\r
+    //\r
+    // Use PE32+ offset\r
+    //\r
+    HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
+    HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders -\r
+             (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) (UINTN) ImageAddress);\r
+  }\r
+  \r
+  Sha1Update (Sha1Ctx, HashBase, HashSize);\r
+\r
+  //\r
+  // 10. Set the SUM_OF_BYTES_HASHED to the size of the header\r
+  //\r
+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+    //\r
+    // Use PE32 offset\r
+    //\r
+    SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
+  } else {\r
+    //\r
+    // Use PE32+ offset\r
+    //\r
+    SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;\r
+  }\r
+\r
+  //\r
+  // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER\r
+  //     structures in the image. The 'NumberOfSections' field of the image\r
+  //     header indicates how big the table should be. Do not include any\r
+  //     IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.\r
+  //\r
+  SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections);\r
+  if (SectionHeader == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // 12.  Using the 'PointerToRawData' in the referenced section headers as\r
+  //      a key, arrange the elements in the table in ascending order. In other\r
+  //      words, sort the section headers according to the disk-file offset of\r
+  //      the section.\r
+  //\r
+  Section = (EFI_IMAGE_SECTION_HEADER *) (\r
+               (UINT8 *) (UINTN) ImageAddress +\r
+               PeCoffHeaderOffset +\r
+               sizeof(UINT32) +\r
+               sizeof(EFI_IMAGE_FILE_HEADER) +\r
+               Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
+               );\r
+  for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
+    Pos = Index;\r
+    while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {\r
+      CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof(EFI_IMAGE_SECTION_HEADER));\r
+      Pos--;\r
+    }\r
+    CopyMem (&SectionHeader[Pos], Section, sizeof(EFI_IMAGE_SECTION_HEADER));\r
+    Section += 1;\r
+  }\r
+\r
+  //\r
+  // 13.  Walk through the sorted table, bring the corresponding section\r
+  //      into memory, and hash the entire section (using the 'SizeOfRawData'\r
+  //      field in the section header to determine the amount of data to hash).\r
+  // 14.  Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .\r
+  // 15.  Repeat steps 13 and 14 for all the sections in the sorted table.\r
+  //\r
+  for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
+    Section  = (EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index];\r
+    if (Section->SizeOfRawData == 0) {\r
+      continue;\r
+    }\r
+    HashBase = (UINT8 *) (UINTN) ImageAddress + Section->PointerToRawData;\r
+    HashSize = (UINTN) Section->SizeOfRawData;\r
+\r
+    Sha1Update (Sha1Ctx, HashBase, HashSize);\r
+\r
+    SumOfBytesHashed += HashSize;\r
+  }\r
+\r
+  //\r
+  // 16.  If the file size is greater than SUM_OF_BYTES_HASHED, there is extra\r
+  //      data in the file that needs to be added to the hash. This data begins\r
+  //      at file offset SUM_OF_BYTES_HASHED and its length is:\r
+  //             FileSize  -  (CertDirectory->Size)\r
+  //\r
+  if (ImageSize > SumOfBytesHashed) {\r
+    HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;\r
+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+      //\r
+      // Use PE32 offset\r
+      //\r
+      HashSize = (UINTN)(ImageSize -\r
+                 Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -\r
+                 SumOfBytesHashed);\r
+    } else {\r
+      //\r
+      // Use PE32+ offset\r
+      //\r
+      HashSize = (UINTN)(ImageSize -\r
+                 Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -\r
+                 SumOfBytesHashed);      \r
+    }\r
+\r
+    Sha1Update (Sha1Ctx, HashBase, HashSize);\r
+  }\r
+\r
+  //\r
+  // 17.  Finalize the SHA hash.\r
+  //\r
+  Sha1Final (Sha1Ctx, (UINT8 *)&TcgEvent->Digest);\r
+\r
+  //\r
+  // Log the PE data\r
+  //\r
+  EventNumber = 1;\r
+  Status = TcgProtocol->HashLogExtendEvent (\r
+             TcgProtocol,\r
+             (EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) NULL,\r
+             0,\r
+             TPM_ALG_SHA,\r
+             TcgEvent,\r
+             &EventNumber,\r
+             &EventLogLastEntry\r
+             );\r
+\r
+Finish:\r
+  FreePool (TcgEvent);\r
+\r
+  if (SectionHeader != NULL) {\r
+    FreePool (SectionHeader);\r
+  }\r
+\r
+  if (Sha1Ctx != NULL ) {\r
+    FreePool (Sha1Ctx);\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, out] 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
+\r
+  @retval EFI_SUCCESS            The file specified by File did authenticate, and the\r
+                                 platform policy dictates that the DXE Core may use File.\r
+  @retval EFI_INVALID_PARAMETER  File is NULL.\r
+  @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and\r
+                                 the platform policy dictates that File should be placed\r
+                                 in the untrusted state. A file may be promoted from\r
+                                 the untrusted to the trusted state at a future time\r
+                                 with a call to the Trust() DXE Service.\r
+  @retval EFI_ACCESS_DENIED      The file specified by File did not authenticate, and\r
+                                 the platform policy dictates that File should not be\r
+                                 used for any purpose.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeTpmMeasureBootHandler (\r
+  IN  OUT   UINT32                     AuthenticationStatus,\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File,\r
+  IN  VOID                             *FileBuffer OPTIONAL,\r
+  IN  UINTN                            FileSize OPTIONAL\r
+  )\r
+{\r
+  EFI_TCG_PROTOCOL                  *TcgProtocol;\r
+  EFI_STATUS                        Status;\r
+  TCG_EFI_BOOT_SERVICE_CAPABILITY   ProtocolCapability;\r
+  UINT32                            TCGFeatureFlags;\r
+  EFI_PHYSICAL_ADDRESS              EventLogLocation;\r
+  EFI_PHYSICAL_ADDRESS              EventLogLastEntry;\r
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;\r
+  EFI_DEVICE_PATH_PROTOCOL          *OrigDevicePathNode;\r
+  EFI_HANDLE                        Handle;\r
+  BOOLEAN                           ApplicationRequired;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT      ImageContext;\r
+\r
+  if (File == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // TCG protocol is not installed. So, TPM is not present.\r
+    // Don't do any measurement, and directly return EFI_SUCCESS.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  ProtocolCapability.Size = (UINT8) sizeof (ProtocolCapability);\r
+  Status = TcgProtocol->StatusCheck (\r
+             TcgProtocol, \r
+             &ProtocolCapability,\r
+             &TCGFeatureFlags,\r
+             &EventLogLocation,\r
+             &EventLogLastEntry\r
+           );\r
+  if (EFI_ERROR (Status) || ProtocolCapability.TPMDeactivatedFlag) {\r
+    //\r
+    // TPM device doesn't work or activate.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Copy File Device Path\r
+  //\r
+  OrigDevicePathNode = DuplicateDevicePath (File);\r
+  ASSERT (OrigDevicePathNode != NULL);\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) && !mMeasureGptTableFlag) {\r
+    //\r
+    // Find the gpt partion on the given devicepath\r
+    //\r
+    DevicePathNode = OrigDevicePathNode;\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 = TcgMeasureGptTable (TcgProtocol, Handle);\r
+            if (!EFI_ERROR (Status)) {\r
+              //\r
+              // GPT disk check done.\r
+              //\r
+              mMeasureGptTableFlag = 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 FV2 protocol.\r
+  //\r
+  DevicePathNode = OrigDevicePathNode;\r
+  Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &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 image from Firmware image will not be mearsured.\r
+    // Current policy doesn't measure PeImage from Firmware if it is driver\r
+    // If the got PeImage is application, it will be still be measured.\r
+    //\r
+    ApplicationRequired = TRUE;\r
+  }\r
+  \r
+  //\r
+  // File is not found.\r
+  //\r
+  if (FileBuffer == NULL) {\r
+    Status = EFI_SECURITY_VIOLATION;\r
+    goto Finish;\r
+  }\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) ImageRead;\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
+      EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevPathToText;\r
+      Status = gBS->LocateProtocol (\r
+                      &gEfiDevicePathToTextProtocolGuid,\r
+                      NULL,\r
+                      (VOID **) &DevPathToText\r
+                      );\r
+      if (!EFI_ERROR (Status)) {\r
+        ToText = DevPathToText->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
+        }\r
+      }\r
+    DEBUG_CODE_END ();\r
+\r
+    //\r
+    // Measure PE image into TPM log.\r
+    //\r
+    Status = TcgMeasurePeImage (\r
+               TcgProtocol,\r
+               (EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer, \r
+               FileSize, \r
+               (UINTN) ImageContext.ImageAddress, \r
+               ImageContext.ImageType, \r
+               DevicePathNode\r
+               );\r
+  }\r
+\r
+  //\r
+  // Done, free the allocated resource.\r
+  //\r
+Finish:\r
+  FreePool (OrigDevicePathNode);\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
+DxeTpmMeasureBootLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  return RegisterSecurityHandler (\r
+          DxeTpmMeasureBootHandler,\r
+          EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED\r
+          );\r
+}\r
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
new file mode 100644 (file)
index 0000000..bf83bf1
--- /dev/null
@@ -0,0 +1,54 @@
+## @file\r
+#  The library instance provides security service of TPM measure boot.\r
+#\r
+# Copyright (c) 2009 - 2010, 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                      = DxeTpmMeasureBootLib\r
+  FILE_GUID                      = 6C60C7D0-922A-4b7c-87D7-E503EDD73BBF\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                    = DxeTpmMeasureBootLibConstructor\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
+  DxeTpmMeasureBootLib.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
+\r
+[Protocols]\r
+  gEfiTcgProtocolGuid                   ## CONSUMES\r
+  gEfiFirmwareVolume2ProtocolGuid       ## CONSUMES\r
+  gEfiBlockIoProtocolGuid               ## CONSUMES\r
+  gEfiDiskIoProtocolGuid                ## CONSUMES\r
+  gEfiDevicePathToTextProtocolGuid      ## SOMETIMES_CONSUMES (Only used in debug mode)\r
diff --git a/SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.c b/SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.c
new file mode 100644 (file)
index 0000000..f085d62
--- /dev/null
@@ -0,0 +1,39 @@
+/** @file\r
+  Provides a secure platform-specific method to clear PK(Platform Key).\r
+\r
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+/**\r
+\r
+  This function detects whether a secure platform-specific method to clear PK(Platform Key)\r
+  is configured by platform owner. This method is provided for users force to clear PK \r
+  in case incorrect enrollment mis-haps.\r
+  \r
+  UEFI231 spec chapter 27.5.2 stipulates: The platform key may also be cleared using \r
+  a secure platform-specific method. In  this case, the global variable SetupMode \r
+  must also be updated to 1.\r
+  \r
+  NOTE THAT: This function cannot depend on any EFI Variable Service since they are\r
+  not available when this function is called in AuthenticateVariable driver.\r
+\r
+  @retval  TRUE       The Platform owner wants to force clear PK.\r
+  @retval  FALSE      The Platform owner doesn't want to force clear PK. \r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ForceClearPK (\r
+  VOID\r
+  )\r
+{\r
+  return FALSE;\r
+}\r
diff --git a/SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf b/SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
new file mode 100644 (file)
index 0000000..5750198
--- /dev/null
@@ -0,0 +1,33 @@
+## @file\r
+#  Provides a secure platform-specific method to clear PK(Platform Key).\r
+#\r
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# 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                      = PlatformSecureLibNull\r
+  FILE_GUID                      = 7FA68D82-10A4-4e71-9524-D3D9500D3CDF\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PlatformSecureLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER\r
+\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
+  PlatformSecureLibNull.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
diff --git a/SecurityPkg/Library/TpmCommLib/CommonHeader.h b/SecurityPkg/Library/TpmCommLib/CommonHeader.h
new file mode 100644 (file)
index 0000000..b8496c7
--- /dev/null
@@ -0,0 +1,29 @@
+/** @file\r
+  The intenal header file for TpmCommLib.\r
+\r
+Copyright (c) 2006 - 2010, 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 _TPMCOMMLIB_COMMON_HEADER_H_\r
+#define _TPMCOMMLIB_COMMON_HEADER_H_\r
+\r
+#include <PiPei.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/TpmCommLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#endif\r
diff --git a/SecurityPkg/Library/TpmCommLib/TisPc.c b/SecurityPkg/Library/TpmCommLib/TisPc.c
new file mode 100644 (file)
index 0000000..3d74a01
--- /dev/null
@@ -0,0 +1,180 @@
+/** @file\r
+  Basic TIS (TPM Interface Specification) functions.\r
+\r
+Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 "CommonHeader.h"\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
+TisPcPresenceCheck (\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
+TisPcWaitRegisterBits (\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
+TisPcReadBurstCount (\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
+TisPcPrepareCommand (\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 = TisPcWaitRegisterBits (\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_D.\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
+TisPcRequestUseTpm (\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 (!TisPcPresenceCheck (TisReg)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);\r
+  Status = TisPcWaitRegisterBits (\r
+             &TisReg->Access,\r
+             (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),\r
+             0,\r
+             TIS_TIMEOUT_D\r
+             );\r
+  return Status;\r
+}\r
diff --git a/SecurityPkg/Library/TpmCommLib/TpmComm.c b/SecurityPkg/Library/TpmCommLib/TpmComm.c
new file mode 100644 (file)
index 0000000..3197f96
--- /dev/null
@@ -0,0 +1,50 @@
+/** @file\r
+  Basic TPM command functions.\r
+\r
+Copyright (c) 2005 - 2010, 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 "CommonHeader.h"\r
+\r
+/**\r
+  Single function calculates SHA1 digest value for all raw data. It\r
+  combines Sha1Init(), Sha1Update() and Sha1Final().\r
+\r
+  @param[in]  Data          Raw data to be digested.\r
+  @param[in]  DataLen       Size of the raw data.\r
+  @param[out] Digest        Pointer to a buffer that stores the final digest.\r
+  \r
+  @retval     EFI_SUCCESS   Always successfully calculate the final digest.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TpmCommHashAll (\r
+  IN  CONST UINT8                   *Data,\r
+  IN        UINTN                   DataLen,\r
+  OUT       TPM_DIGEST              *Digest\r
+  )\r
+{\r
+  VOID     *Sha1Ctx;\r
+  UINTN    CtxSize;\r
+\r
+  CtxSize = Sha1GetContextSize ();\r
+  Sha1Ctx = AllocatePool (CtxSize);\r
+  ASSERT (Sha1Ctx != NULL);\r
+\r
+  Sha1Init (Sha1Ctx);\r
+  Sha1Update (Sha1Ctx, Data, DataLen);\r
+  Sha1Final (Sha1Ctx, (UINT8 *)Digest);\r
+\r
+  FreePool (Sha1Ctx);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/SecurityPkg/Library/TpmCommLib/TpmCommLib.inf b/SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
new file mode 100644 (file)
index 0000000..7188a3b
--- /dev/null
@@ -0,0 +1,46 @@
+## @file\r
+#  TpmCommLib instance implements basis TPM Interface Specification (TIS) and TPM command functions.\r
+#\r
+# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# 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                      = TpmCommLib\r
+  FILE_GUID                      = 7d9fe32e-a6a9-4cdf-abff-10cc7f22e1c9\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = TpmCommLib|DXE_DRIVER UEFI_DRIVER PEIM DXE_SMM_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
+  TisPc.c\r
+  TpmComm.c\r
+  CommonHeader.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  CryptoPkg/CryptoPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  IoLib\r
+  TimerLib\r
+  BaseCryptLib\r
+  MemoryAllocationLib\r
+  DebugLib\r
+\r
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
new file mode 100644 (file)
index 0000000..8121f39
--- /dev/null
@@ -0,0 +1,122 @@
+## @file  SecurityPkg.dec\r
+#  This package includes the security drivers, defintions(including PPIs/PROTOCOLs/GUIDs  \r
+#  and library classes) and libraries instances.\r
+#\r
+# Copyright (c) 2009 - 2011, 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 which 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
+[Defines]\r
+  DEC_SPECIFICATION              = 0x00010005\r
+  PACKAGE_NAME                   = SecurityPkg\r
+  PACKAGE_GUID                   = 24369CAC-6AA6-4fb8-88DB-90BF061668AD\r
+  PACKAGE_VERSION                = 0.91\r
+\r
+[Includes]\r
+  Include\r
+\r
+[LibraryClasses]\r
+  ##  @libraryclass  Definitions for common TPM commands as library API for TPM\r
+  #                  module use.\r
+  TpmCommLib|Include/Library/TpmCommLib.h\r
+\r
+[Guids]\r
+  ## Security package token space guid\r
+  # Include/Guid/SecurityPkgTokenSpace.h\r
+  gEfiSecurityPkgTokenSpaceGuid  = { 0xd3fb176, 0x9569, 0x4d51, { 0xa3, 0xef, 0x7d, 0x61, 0xc6, 0x4f, 0xea, 0xba }}\r
+  ## Guid acted as the authenticated variable store header's signature, and to specify the variable list entries put in the EFI system table.\r
+  #  Include/Guid/AuthenticatedVariableFormat.h\r
+  gEfiAuthenticatedVariableGuid  = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }\r
+\r
+  ## Include/Guid/TcgEventHob.h\r
+  gTcgEventEntryHobGuid              = { 0x2e3044ac, 0x879f, 0x490f, {0x97, 0x60, 0xbb, 0xdf, 0xaf, 0x69, 0x5f, 0x50 }}\r
+\r
+  ## Include/Guid/PhysicalPresenceData.h\r
+  gEfiPhysicalPresenceGuid           = { 0xf6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc }}\r
+\r
+[Ppis]\r
+  ## Include/Ppi/LockPhysicalPresence.h\r
+  gPeiLockPhysicalPresencePpiGuid    = { 0xef9aefe5, 0x2bd3, 0x4031, { 0xaf, 0x7d, 0x5e, 0xfe, 0x5a, 0xbb, 0x9a, 0xd } }\r
+\r
+  ## Include/Ppi/TpmInitialized.h\r
+  gPeiTpmInitializedPpiGuid      = { 0xe9db0d58, 0xd48d, 0x47f6, { 0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41 }}\r
+\r
+[PcdsFixedAtBuild]\r
+  ## Pcd for OptionRom.\r
+  #  Image verification policy settings:\r
+  #  ALWAYS_EXECUTE                         0x00000000\r
+  #  NEVER_EXECUTE                          0x00000001\r
+  #  ALLOW_EXECUTE_ON_SECURITY_VIOLATION    0x00000002\r
+  #  DEFER_EXECUTE_ON_SECURITY_VIOLATION    0x00000003\r
+  #  DENY_EXECUTE_ON_SECURITY_VIOLATION     0x00000004\r
+  #  QUERY_USER_ON_SECURITY_VIOLATION       0x00000005 \r
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00|UINT32|0x00000001\r
+  \r
+  ## Pcd for removable media.\r
+  #  Removable media include CD-ROM, Floppy, USB and network.\r
+  #  Image verification policy settings:\r
+  #  ALWAYS_EXECUTE                         0x00000000\r
+  #  NEVER_EXECUTE                          0x00000001\r
+  #  ALLOW_EXECUTE_ON_SECURITY_VIOLATION    0x00000002\r
+  #  DEFER_EXECUTE_ON_SECURITY_VIOLATION    0x00000003\r
+  #  DENY_EXECUTE_ON_SECURITY_VIOLATION     0x00000004\r
+  #  QUERY_USER_ON_SECURITY_VIOLATION       0x00000005\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x05|UINT32|0x00000002\r
+  \r
+  ## Pcd for fixed media.\r
+  #  Fixed media include hard disk.\r
+  #  Image verification policy settings:\r
+  #  ALWAYS_EXECUTE                         0x00000000\r
+  #  NEVER_EXECUTE                          0x00000001\r
+  #  ALLOW_EXECUTE_ON_SECURITY_VIOLATION    0x00000002\r
+  #  DEFER_EXECUTE_ON_SECURITY_VIOLATION    0x00000003\r
+  #  DENY_EXECUTE_ON_SECURITY_VIOLATION     0x00000004\r
+  #  QUERY_USER_ON_SECURITY_VIOLATION       0x00000005  \r
+  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x05|UINT32|0x00000003\r
+  \r
+  ## Defer Image Load policy settings.\r
+  #  The policy is bitwise. \r
+  #  If bit is set, the image from corresponding device will be trust when loading.\r
+  #\r
+  # IMAGE_UNKNOWN                         0x00000001\r
+  # IMAGE_FROM_FV                         0x00000002\r
+  # IMAGE_FROM_OPTION_ROM                 0x00000004\r
+  # IMAGE_FROM_REMOVABLE_MEDIA            0x00000008\r
+  # IMAGE_FROM_FIXED_MEDIA                0x00000010\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdDeferImageLoadPolicy|0x0000001F|UINT32|0x0000004\r
+  \r
+  ## The token file name used to save credential in USB credential provider driver.\r
+  #  The specified file should be saved at the root directory of USB storage disk.\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdFixedUsbCredentialProviderTokenFileName|L"Token.bin"|VOID*|0x00000005\r
+\r
+  ## The size of Append variable buffer. This buffer is reserved for runtime use, OS can append data into one existing variable.\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdMaxAppendVariableSize|0x2000|UINT32|0x30000005  \r
+\r
+  ## This PCD specifies the type of TCG platform that contains TPM chip. \r
+  #  This PCD is only avaiable when PcdTpmPhysicalPresence is TRUE.\r
+  #  If 0, TCG platform type is PC client.\r
+  #  If 1, TCG platform type is server.\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass|0|UINT8|0x00000006\r
+\r
+  ## The PCD is used to control whether to support hiding the TPM.\r
+  #  If TRUE, PcdHideTpm controls whether to hide the TPM.\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport|FALSE|BOOLEAN|0x00000007\r
+  \r
+[PcdsDynamic, PcdsDynamicEx]\r
+  ## The PCD is used to control whether to hide the TPM.\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm|FALSE|BOOLEAN|0x00010002\r
+\r
+  ## The PCD is used to specify whether or not MOR (MemoryOverwriteControl) feature is enabled.\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdMorEnable|FALSE|BOOLEAN|0x00010000\r
+\r
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]\r
+  ## This PCD indicates the presence or absence of the platform operator.\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmPhysicalPresence|TRUE|BOOLEAN|0x00010001\r
+\r
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
new file mode 100644 (file)
index 0000000..09aa8fc
--- /dev/null
@@ -0,0 +1,125 @@
+## @file\r
+#  Security Module Package for All Architectures.\r
+#\r
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# 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
+[Defines]\r
+  PLATFORM_NAME                  = SecurityPkg\r
+  PLATFORM_GUID                  = B2C4614D-AE76-47ba-B876-5988BFED064F\r
+  PLATFORM_VERSION               = 0.91\r
+  DSC_SPECIFICATION              = 0x00010005\r
+  OUTPUT_DIRECTORY               = Build/SecurityPkg\r
+  SUPPORTED_ARCHITECTURES        = IA32|IPF|X64|EBC\r
+  BUILD_TARGETS                  = DEBUG|RELEASE\r
+  SKUID_IDENTIFIER               = DEFAULT\r
+\r
+[LibraryClasses]\r
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf\r
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf  \r
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf\r
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf\r
+  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf\r
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf\r
+\r
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf\r
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf\r
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf\r
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf\r
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf\r
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf\r
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf\r
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf\r
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf\r
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf\r
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf\r
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf\r
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf\r
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf\r
+  TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf\r
+  PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf    \r
+\r
+[LibraryClasses.common.PEIM]\r
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf\r
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf\r
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf\r
+\r
+[LibraryClasses.common.DXE_DRIVER]\r
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf\r
+\r
+[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER,]\r
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
+  DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf\r
+\r
+[LibraryClasses.IPF.DXE_SAL_DRIVER]\r
+  ExtendedSalLib|MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf\r
+\r
+[LibraryClasses.common.DXE_SMM_DRIVER]\r
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf\r
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf\r
+    \r
+[Components]\r
+  SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf\r
+  SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf\r
+  SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf\r
+  SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManagerDxe.inf\r
+  SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf\r
+  SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderDxe.inf\r
+  SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProviderDxe.inf\r
+\r
+  #\r
+  # Application\r
+  #\r
+  SecurityPkg/Application/VariableInfo/VariableInfo.inf\r
+\r
+  #\r
+  # TPM\r
+  #\r
+  SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf\r
+  SecurityPkg/Tcg/TcgPei/TcgPei.inf\r
+  SecurityPkg/Tcg/TcgDxe/TcgDxe.inf\r
+  SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf\r
+  SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceDxe.inf\r
+  SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf\r
+  SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf {\r
+    <LibraryClasses>\r
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  }\r
+  SecurityPkg/Tcg/TcgSmm/TcgSmm.inf\r
+\r
+[Components.IA32, Components.X64]\r
+  SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf {\r
+    <LibraryClasses>\r
+      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf\r
+  }\r
+\r
+  SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf\r
+  SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf\r
+\r
+[Components.IPF]\r
+  SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/EsalVariableDxeSal.inf \r
+\r
+[Components.EBC]\r
+# Build only\r
+  SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf \r
+\r
+[BuildOptions]\r
+   MSFT:*_*_IA32_DLINK_FLAGS = /ALIGN:256\r
+  INTEL:*_*_IA32_DLINK_FLAGS = /ALIGN:256\r
+\r
diff --git a/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c b/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c
new file mode 100644 (file)
index 0000000..ce53112
--- /dev/null
@@ -0,0 +1,82 @@
+/** @file\r
+  TCG MOR (Memory Overwrite Request) Control Driver.\r
+\r
+  This driver initilize MemoryOverwriteRequestControl variable. It \r
+  will clear MOR_CLEAR_MEMORY_BIT bit if it is set.\r
+\r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 "TcgMor.h"\r
+\r
+/**\r
+  Entry Point for TCG MOR Control driver.\r
+\r
+  @param[in] ImageHandle  Image handle of this driver.\r
+  @param[in] SystemTable  A Pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCEESS     \r
+  @return Others          Some error occurs.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MorDriverEntryPoint (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       MorControl;\r
+  UINTN       DataSize;\r
+\r
+  ///\r
+  /// The firmware is required to create the MemoryOverwriteRequestControl UEFI variable.\r
+  ///\r
+\r
+  DataSize = sizeof (MorControl);\r
+  Status = gRT->GetVariable (\r
+                  MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, \r
+                  &gEfiMemoryOverwriteControlDataGuid, \r
+                  NULL, \r
+                  &DataSize, \r
+                  &MorControl\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Set default value to 0\r
+    //\r
+    MorControl = 0;\r
+  } else {\r
+    if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {\r
+      //\r
+      // MorControl is expected, directly return to avoid unnecessary variable operation\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+    //\r
+    // Clear MOR_CLEAR_MEMORY_BIT\r
+    //\r
+    DEBUG ((EFI_D_INFO, "TcgMor: Clear MorClearMemory bit\n"));\r
+    MorControl &= 0xFE;\r
+  }\r
+  \r
+  Status = gRT->SetVariable (\r
+                  MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, \r
+                  &gEfiMemoryOverwriteControlDataGuid, \r
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                  DataSize, \r
+                  &MorControl\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  return Status;\r
+}\r
+\r
+\r
diff --git a/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.h b/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.h
new file mode 100644 (file)
index 0000000..bfad2cf
--- /dev/null
@@ -0,0 +1,27 @@
+/** @file\r
+  The header file for TcgMor.\r
+\r
+Copyright (c) 2009, 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 __TCG_MOR_H__\r
+#define __TCG_MOR_H__\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Guid/MemoryOverwriteControl.h>\r
+\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#endif\r
+\r
diff --git a/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf b/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
new file mode 100644 (file)
index 0000000..e62a904
--- /dev/null
@@ -0,0 +1,50 @@
+## @file\r
+#  Component description file for Memory Overwrite Control driver.\r
+#\r
+# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# 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                      = TcgMor\r
+  FILE_GUID                      = AD416CE3-A483-45b1-94C2-4B4E4D575562\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = MorDriverEntryPoint\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
+  TcgMor.c\r
+  TcgMor.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiDriverEntryPoint\r
+  UefiRuntimeServicesTableLib\r
+  ReportStatusCodeLib\r
+  DebugLib\r
+\r
+[Guids]\r
+  gEfiMemoryOverwriteControlDataGuid            # GUID ALWAYS_CONSUMED\r
+\r
+[Depex]\r
+  gEfiVariableArchProtocolGuid AND\r
+  gEfiVariableWriteArchProtocolGuid AND\r
+  gEfiTcgProtocolGuid\r
+\r
diff --git a/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresence.c b/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresence.c
new file mode 100644 (file)
index 0000000..187c3ca
--- /dev/null
@@ -0,0 +1,1115 @@
+/** @file\r
+  This driver checks whether there is pending TPM request. If yes, \r
+  it will display TPM request information and ask for user confirmation.\r
+  The TPM request will be cleared after it is processed.  \r
+  \r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 "PhysicalPresence.h"\r
+\r
+EFI_HII_HANDLE mPpStringPackHandle;\r
+\r
+/**\r
+  Get TPM physical presence permanent flags.\r
+\r
+  @param[out] LifetimeLock  Returns physicalPresenceLifetimeLock permanent flag.  \r
+  @param[out] CmdEnable     Returns physicalPresenceCMDEnable permanent flag.\r
+  \r
+  @retval EFI_SUCCESS       Flags were returns successfully.\r
+  @retval other             Failed to locate EFI TCG Protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+GetTpmCapability (\r
+  OUT  BOOLEAN                      *LifetimeLock,\r
+  OUT  BOOLEAN                      *CmdEnable\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_TCG_PROTOCOL                  *TcgProtocol;\r
+  TPM_RQU_COMMAND_HDR               *TpmRqu;\r
+  TPM_RSP_COMMAND_HDR               *TpmRsp;\r
+  UINT32                            *SendBufPtr;\r
+  UINT8                             SendBuffer[sizeof (*TpmRqu) + sizeof (UINT32) * 3];\r
+  TPM_PERMANENT_FLAGS               *TpmPermanentFlags;\r
+  UINT8                             RecvBuffer[40];\r
+  \r
+  Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Fill request header\r
+  //\r
+  TpmRsp = (TPM_RSP_COMMAND_HDR*)RecvBuffer;\r
+  TpmRqu = (TPM_RQU_COMMAND_HDR*)SendBuffer;\r
+  \r
+  TpmRqu->tag       = H2NS (TPM_TAG_RQU_COMMAND);\r
+  TpmRqu->paramSize = H2NL (sizeof (SendBuffer));\r
+  TpmRqu->ordinal   = H2NL (TPM_ORD_GetCapability);\r
+\r
+  //\r
+  // Set request parameter\r
+  //\r
+  SendBufPtr      = (UINT32*)(TpmRqu + 1);\r
+  WriteUnaligned32 (SendBufPtr++, H2NL (TPM_CAP_FLAG));\r
+  WriteUnaligned32 (SendBufPtr++, H2NL (sizeof (TPM_CAP_FLAG_PERMANENT)));\r
+  WriteUnaligned32 (SendBufPtr, H2NL (TPM_CAP_FLAG_PERMANENT));  \r
+  \r
+  Status = TcgProtocol->PassThroughToTpm (\r
+                          TcgProtocol,\r
+                          sizeof (SendBuffer),\r
+                          (UINT8*)TpmRqu,\r
+                          sizeof (RecvBuffer),\r
+                          (UINT8*)&RecvBuffer\r
+                          );\r
+  ASSERT_EFI_ERROR (Status);\r
+  ASSERT (TpmRsp->tag == H2NS (TPM_TAG_RSP_COMMAND));\r
+  ASSERT (TpmRsp->returnCode == 0);\r
+  \r
+  TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];\r
+  \r
+  if (LifetimeLock != NULL) {\r
+    *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock;\r
+  }\r
+\r
+  if (CmdEnable != NULL) {\r
+    *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Issue TSC_PhysicalPresence command to TPM.\r
+\r
+  @param[in] PhysicalPresence     The state to set the TPM's Physical Presence flags.  \r
+  \r
+  @retval EFI_SUCCESS             TPM executed the command successfully.\r
+  @retval EFI_SECURITY_VIOLATION  TPM returned error when executing the command.\r
+  @retval other                   Failed to locate EFI TCG Protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+TpmPhysicalPresence (\r
+  IN      TPM_PHYSICAL_PRESENCE     PhysicalPresence\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_TCG_PROTOCOL                  *TcgProtocol;\r
+  TPM_RQU_COMMAND_HDR               *TpmRqu;\r
+  TPM_PHYSICAL_PRESENCE             *TpmPp;\r
+  TPM_RSP_COMMAND_HDR               TpmRsp;\r
+  UINT8                             Buffer[sizeof (*TpmRqu) + sizeof (*TpmPp)];\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  TpmRqu = (TPM_RQU_COMMAND_HDR*)Buffer;\r
+  TpmPp = (TPM_PHYSICAL_PRESENCE*)(TpmRqu + 1);\r
+\r
+  TpmRqu->tag = H2NS (TPM_TAG_RQU_COMMAND);\r
+  TpmRqu->paramSize = H2NL (sizeof (Buffer));\r
+  TpmRqu->ordinal = H2NL (TSC_ORD_PhysicalPresence);\r
+  WriteUnaligned16 (TpmPp, (TPM_PHYSICAL_PRESENCE) H2NS (PhysicalPresence));  \r
+\r
+  Status = TcgProtocol->PassThroughToTpm (\r
+                          TcgProtocol,\r
+                          sizeof (Buffer),\r
+                          (UINT8*)TpmRqu,\r
+                          sizeof (TpmRsp),\r
+                          (UINT8*)&TpmRsp\r
+                          );\r
+  ASSERT_EFI_ERROR (Status);\r
+  ASSERT (TpmRsp.tag == H2NS (TPM_TAG_RSP_COMMAND));\r
+  if (TpmRsp.returnCode != 0) {\r
+    //\r
+    // If it fails, some requirements may be needed for this command.\r
+    //\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Issue a TPM command for which no additional output data will be returned.\r
+\r
+  @param[in] TcgProtocol              EFI TCG Protocol instance.  \r
+  @param[in] Ordinal                  TPM command code.  \r
+  @param[in] AdditionalParameterSize  Additional parameter size.  \r
+  @param[in] AdditionalParameters     Pointer to the Additional paramaters.  \r
+  \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
+**/\r
+TPM_RESULT\r
+TpmCommandNoReturnData (\r
+  IN      EFI_TCG_PROTOCOL          *TcgProtocol,\r
+  IN      TPM_COMMAND_CODE          Ordinal,\r
+  IN      UINTN                     AdditionalParameterSize,\r
+  IN      VOID                      *AdditionalParameters\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  TPM_RQU_COMMAND_HDR               *TpmRqu;\r
+  TPM_RSP_COMMAND_HDR               TpmRsp;\r
+  UINT32                            Size;\r
+\r
+  TpmRqu = (TPM_RQU_COMMAND_HDR*)AllocatePool (\r
+                                   sizeof (*TpmRqu) + AdditionalParameterSize\r
+                                   );\r
+  if (TpmRqu == NULL) {\r
+    return TPM_PP_BIOS_FAILURE;\r
+  }\r
+\r
+  TpmRqu->tag       = H2NS (TPM_TAG_RQU_COMMAND);\r
+  Size              = (UINT32)(sizeof (*TpmRqu) + AdditionalParameterSize);\r
+  TpmRqu->paramSize = H2NL (Size);\r
+  TpmRqu->ordinal   = H2NL (Ordinal);\r
+  gBS->CopyMem (TpmRqu + 1, AdditionalParameters, AdditionalParameterSize);\r
+\r
+  Status = TcgProtocol->PassThroughToTpm (\r
+                          TcgProtocol,\r
+                          Size,\r
+                          (UINT8*)TpmRqu,\r
+                          (UINT32)sizeof (TpmRsp),\r
+                          (UINT8*)&TpmRsp\r
+                          );\r
+  FreePool (TpmRqu);\r
+  if (EFI_ERROR (Status) || (TpmRsp.tag != H2NS (TPM_TAG_RSP_COMMAND))) {\r
+    return TPM_PP_BIOS_FAILURE;\r
+  }\r
+  return H2NL (TpmRsp.returnCode);\r
+}\r
+\r
+/**\r
+  Execute physical presence operation requested by the OS.\r
+\r
+  @param[in]      TcgProtocol         EFI TCG Protocol instance.  \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
+**/\r
+TPM_RESULT\r
+ExecutePhysicalPresence (\r
+  IN      EFI_TCG_PROTOCOL          *TcgProtocol,\r
+  IN      UINT8                     CommandCode,\r
+  IN OUT  UINT8                     *PpiFlags\r
+  )\r
+{\r
+  BOOLEAN                           BoolVal;\r
+  TPM_RESULT                        TpmResponse;\r
+  UINT32                            InData[5];\r
+\r
+  switch (CommandCode) {\r
+    case ENABLE:\r
+      return TpmCommandNoReturnData (\r
+               TcgProtocol,\r
+               TPM_ORD_PhysicalEnable,\r
+               0,\r
+               NULL\r
+               );\r
+\r
+    case DISABLE:\r
+      return TpmCommandNoReturnData (\r
+               TcgProtocol,\r
+               TPM_ORD_PhysicalDisable,\r
+               0,\r
+               NULL\r
+               );\r
+\r
+    case ACTIVATE:\r
+      BoolVal = FALSE;\r
+      return TpmCommandNoReturnData (\r
+               TcgProtocol,\r
+               TPM_ORD_PhysicalSetDeactivated,\r
+               sizeof (BoolVal),\r
+               &BoolVal\r
+               );\r
+\r
+    case DEACTIVATE:\r
+      BoolVal = TRUE;\r
+      return TpmCommandNoReturnData (\r
+               TcgProtocol,\r
+               TPM_ORD_PhysicalSetDeactivated,\r
+               sizeof (BoolVal),\r
+               &BoolVal\r
+               );\r
+\r
+    case CLEAR:\r
+      return TpmCommandNoReturnData (\r
+               TcgProtocol,\r
+               TPM_ORD_ForceClear,\r
+               0,\r
+               NULL\r
+               );\r
+\r
+    case ENABLE_ACTIVATE:\r
+      TpmResponse = ExecutePhysicalPresence (TcgProtocol, ENABLE, PpiFlags);\r
+      if (TpmResponse == 0) {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, ACTIVATE, PpiFlags);\r
+      }\r
+      return TpmResponse;\r
+\r
+    case DEACTIVATE_DISABLE:\r
+      TpmResponse = ExecutePhysicalPresence (TcgProtocol, DEACTIVATE, PpiFlags);\r
+      if (TpmResponse == 0) {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, DISABLE, PpiFlags);\r
+      }\r
+      return TpmResponse;\r
+\r
+    case SET_OWNER_INSTALL_TRUE:\r
+      BoolVal = TRUE;\r
+      return TpmCommandNoReturnData (\r
+               TcgProtocol,\r
+               TPM_ORD_SetOwnerInstall,\r
+               sizeof (BoolVal),\r
+               &BoolVal\r
+               );\r
+\r
+    case SET_OWNER_INSTALL_FALSE:\r
+      BoolVal = FALSE;\r
+      return TpmCommandNoReturnData (\r
+               TcgProtocol,\r
+               TPM_ORD_SetOwnerInstall,\r
+               sizeof (BoolVal),\r
+               &BoolVal\r
+               );\r
+\r
+    case ENABLE_ACTIVATE_OWNER_TRUE:\r
+      //\r
+      // ENABLE_ACTIVATE + SET_OWNER_INSTALL_TRUE\r
+      // SET_OWNER_INSTALL_TRUE will be executed atfer reboot\r
+      //\r
+      if ((*PpiFlags & FLAG_RESET_TRACK) == 0) {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, ENABLE_ACTIVATE, PpiFlags);\r
+        *PpiFlags |= FLAG_RESET_TRACK;\r
+      } else {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, SET_OWNER_INSTALL_TRUE, PpiFlags);\r
+        *PpiFlags &= ~FLAG_RESET_TRACK;\r
+      }\r
+      return TpmResponse;\r
+\r
+    case DEACTIVATE_DISABLE_OWNER_FALSE:\r
+      TpmResponse = ExecutePhysicalPresence (TcgProtocol, SET_OWNER_INSTALL_FALSE, PpiFlags);\r
+      if (TpmResponse == 0) {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, DEACTIVATE_DISABLE, PpiFlags);\r
+      }\r
+      return TpmResponse;\r
+\r
+    case DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
+      InData[0] = H2NL (TPM_SET_STCLEAR_DATA);            // CapabilityArea\r
+      InData[1] = H2NL (sizeof(UINT32));                  // SubCapSize\r
+      InData[2] = H2NL (TPM_SD_DEFERREDPHYSICALPRESENCE); // SubCap\r
+      InData[3] = H2NL (sizeof(UINT32));                  // SetValueSize\r
+      InData[4] = H2NL (1);                               // UnownedFieldUpgrade; bit0\r
+      return TpmCommandNoReturnData (\r
+               TcgProtocol,\r
+               TPM_ORD_SetCapability,\r
+               sizeof (UINT32) * 5,\r
+               InData\r
+               );\r
+\r
+    case SET_OPERATOR_AUTH:\r
+      //\r
+      // TPM_SetOperatorAuth\r
+      // This command requires UI to prompt user for Auth data\r
+      // Here it is NOT implemented\r
+      //\r
+      return TPM_PP_BIOS_FAILURE;\r
+\r
+    case CLEAR_ENABLE_ACTIVATE:\r
+      TpmResponse = ExecutePhysicalPresence (TcgProtocol, CLEAR, PpiFlags);\r
+      if (TpmResponse == 0) {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, ENABLE_ACTIVATE, PpiFlags);\r
+      }\r
+      return TpmResponse;\r
+\r
+    case SET_NO_PPI_PROVISION_FALSE:\r
+      *PpiFlags &= ~FLAG_NO_PPI_PROVISION;\r
+      return 0;\r
+\r
+    case SET_NO_PPI_PROVISION_TRUE:\r
+      *PpiFlags |= FLAG_NO_PPI_PROVISION;\r
+      return 0;\r
+\r
+    case SET_NO_PPI_CLEAR_FALSE:\r
+      *PpiFlags &= ~FLAG_NO_PPI_CLEAR;\r
+      return 0;\r
+\r
+    case SET_NO_PPI_CLEAR_TRUE:\r
+      *PpiFlags |= FLAG_NO_PPI_CLEAR;\r
+      return 0;\r
+\r
+    case SET_NO_PPI_MAINTENANCE_FALSE:\r
+      *PpiFlags &= ~FLAG_NO_PPI_MAINTENANCE;\r
+      return 0;\r
+\r
+    case SET_NO_PPI_MAINTENANCE_TRUE:\r
+      *PpiFlags |= FLAG_NO_PPI_MAINTENANCE;\r
+      return 0;\r
+  \r
+    case ENABLE_ACTIVATE_CLEAR:\r
+      TpmResponse = ExecutePhysicalPresence (TcgProtocol, ENABLE_ACTIVATE, PpiFlags);\r
+      if (TpmResponse == 0) {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, CLEAR, PpiFlags);\r
+      }\r
+      return TpmResponse;\r
+\r
+    case ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:\r
+      //\r
+      // ENABLE_ACTIVATE + CLEAR_ENABLE_ACTIVATE\r
+      // CLEAR_ENABLE_ACTIVATE will be executed atfer reboot.\r
+      //\r
+      if ((*PpiFlags & FLAG_RESET_TRACK) == 0) {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, ENABLE_ACTIVATE, PpiFlags);\r
+        *PpiFlags |= FLAG_RESET_TRACK;\r
+      } else {\r
+        TpmResponse = ExecutePhysicalPresence (TcgProtocol, CLEAR_ENABLE_ACTIVATE, PpiFlags);\r
+        *PpiFlags &= ~FLAG_RESET_TRACK;\r
+      } \r
+      return TpmResponse;\r
+\r
+    default:\r
+      ;\r
+  }\r
+  return TPM_PP_BIOS_FAILURE;\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
+**/\r
+BOOLEAN\r
+ReadUserKey (\r
+  IN     BOOLEAN                    CautionKey\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_INPUT_KEY                     Key;\r
+  UINT16                            InputKey;\r
+  EFI_TPL                           OldTpl;\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); \r
+  gBS->RestoreTPL (TPL_APPLICATION);\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
+  gBS->RaiseTPL (OldTpl); \r
+\r
+  if (InputKey != SCAN_ESC) {\r
+    return TRUE;\r
+  }\r
+  \r
+  return FALSE;\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
+UserConfirm (\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
+  mPpStringPackHandle = HiiAddPackages (\r
+                          &gEfiPhysicalPresenceGuid,\r
+                          NULL,\r
+                          PhysicalPresenceDxeStrings,\r
+                          NULL\r
+                          );\r
+  ASSERT (mPpStringPackHandle != NULL);\r
+\r
+  switch (TpmPpCommand) {\r
+    case ENABLE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ENABLE), NULL);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);      \r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case DISABLE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_DISABLE), NULL);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+      \r
+    case ACTIVATE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACTIVATE), NULL);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case DEACTIVATE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_DEACTIVATE), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1); \r
+      break;\r
+\r
+    case CLEAR:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CLEAR), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_CLEAR), NULL);\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 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CAUTION_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case ENABLE_ACTIVATE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ENABLE_ACTIVATE), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NOTE_ON), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case DEACTIVATE_DISABLE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_DEACTIVATE_DISABLE), NULL);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);      \r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NOTE_OFF), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case SET_OWNER_INSTALL_TRUE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ALLOW_TAKE_OWNERSHIP), NULL);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);      \r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case SET_OWNER_INSTALL_FALSE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_DISALLOW_TAKE_OWNERSHIP), NULL);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);      \r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case ENABLE_ACTIVATE_OWNER_TRUE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_TURN_ON), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NOTE_ON), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case DEACTIVATE_DISABLE_OWNER_FALSE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_TURN_OFF), NULL);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);      \r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NOTE_OFF), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_UNOWNED_FIELD_UPGRADE), NULL);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_UPGRADE_HEAD_STR), NULL);      \r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+      \r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_MAINTAIN), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CAUTION_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case SET_OPERATOR_AUTH:\r
+      //\r
+      // TPM_SetOperatorAuth\r
+      // This command requires UI to prompt user for Auth data\r
+      // Here it is NOT implemented\r
+      //\r
+      break;\r
+\r
+    case CLEAR_ENABLE_ACTIVATE:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CLEAR_TURN_ON), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NOTE_ON), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_CLEAR), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_CLEAR_CONT), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CAUTION_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case SET_NO_PPI_PROVISION_TRUE:\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NO_PPI_PROVISION), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_PPI_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ACCEPT_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NO_PPI_INFO), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case SET_NO_PPI_CLEAR_TRUE:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CLEAR), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_PPI_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NOTE_CLEAR), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_CLEAR), NULL);\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 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CAUTION_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NO_PPI_INFO), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case SET_NO_PPI_MAINTENANCE_TRUE:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NO_PPI_MAINTAIN), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_PPI_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_MAINTAIN), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CAUTION_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NO_PPI_INFO), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case ENABLE_ACTIVATE_CLEAR:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_CLEAR), NULL);\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 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CAUTION_KEY), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+      break;\r
+\r
+    case ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:\r
+      CautionKey = TRUE;\r
+      TmpStr2 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE), NULL);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_HEAD_STR), NULL);\r
+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_NOTE_ON), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_CLEAR), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_WARNING_CLEAR_CONT), NULL);\r
+      StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
+      FreePool (TmpStr1);\r
+\r
+      TmpStr1 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_CAUTION_KEY), NULL);\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 = HiiGetString (mPpStringPackHandle, STRING_TOKEN (TPM_REJECT_KEY), NULL);\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 (ReadUserKey (CautionKey)) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;  \r
+}\r
+\r
+/**\r
+  Check and execute the requested physical presence command.\r
+  \r
+  @param[in, out] TcgPpData  Point to the physical presence NV variable.\r
+\r
+**/\r
+VOID\r
+ExecutePendingTpmRequest (\r
+  IN OUT  EFI_PHYSICAL_PRESENCE     *TcgPpData\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_TCG_PROTOCOL                  *TcgProtocol;\r
+  UINTN                             DataSize;\r
+  UINT8                             Flags;\r
+  BOOLEAN                           RequestConfirmed;\r
+\r
+  Flags            = TcgPpData->Flags;\r
+  RequestConfirmed = FALSE;  \r
+  switch (TcgPpData->PPRequest) {\r
+    case NO_ACTION:\r
+      return;\r
+    case ENABLE:\r
+    case DISABLE:\r
+    case ACTIVATE:\r
+    case DEACTIVATE:\r
+    case ENABLE_ACTIVATE:\r
+    case DEACTIVATE_DISABLE:\r
+    case SET_OWNER_INSTALL_TRUE:\r
+    case SET_OWNER_INSTALL_FALSE:\r
+    case ENABLE_ACTIVATE_OWNER_TRUE:\r
+    case DEACTIVATE_DISABLE_OWNER_FALSE:\r
+    case SET_OPERATOR_AUTH:\r
+      if ((Flags & FLAG_NO_PPI_PROVISION) != 0) {\r
+        RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case CLEAR:\r
+    case ENABLE_ACTIVATE_CLEAR:\r
+      if ((Flags & FLAG_NO_PPI_CLEAR) != 0) {\r
+        RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
+      if ((Flags & FLAG_NO_PPI_MAINTENANCE) != 0) {\r
+        RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case CLEAR_ENABLE_ACTIVATE:\r
+    case ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:\r
+      if ((Flags & FLAG_NO_PPI_CLEAR) != 0 && (Flags & FLAG_NO_PPI_PROVISION) != 0) {\r
+        RequestConfirmed = TRUE;\r
+      }\r
+      break;  \r
+\r
+    case SET_NO_PPI_PROVISION_FALSE:\r
+    case SET_NO_PPI_CLEAR_FALSE:\r
+    case SET_NO_PPI_MAINTENANCE_FALSE:\r
+      RequestConfirmed = TRUE;\r
+      break;\r
+  }\r
+\r
+  if ((Flags & 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
+  if (!RequestConfirmed) {\r
+    //\r
+    // Print confirm text and wait for approval. \r
+    //\r
+    RequestConfirmed = UserConfirm (TcgPpData->PPRequest);\r
+  }\r
+\r
+  //\r
+  // Execute requested physical presence command.\r
+  //\r
+  TcgPpData->PPResponse = TPM_PP_USER_ABORT;\r
+  if (RequestConfirmed) {\r
+    Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID**) &TcgProtocol);\r
+    ASSERT_EFI_ERROR (Status);\r
+    TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &TcgPpData->Flags);\r
+  }\r
+\r
+  //\r
+  // Clear request\r
+  //\r
+  if ((TcgPpData->Flags & FLAG_RESET_TRACK) == 0) {\r
+    TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
+    TcgPpData->PPRequest = 0;    \r
+  }\r
+\r
+  //\r
+  // Save changes\r
+  //\r
+  DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
+  Status = gRT->SetVariable (\r
+                  PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiPhysicalPresenceGuid,\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 ACTIVATE:\r
+    case DEACTIVATE:\r
+    case CLEAR:\r
+    case ENABLE_ACTIVATE:\r
+    case DEACTIVATE_DISABLE:\r
+    case ENABLE_ACTIVATE_OWNER_TRUE:\r
+    case DEACTIVATE_DISABLE_OWNER_FALSE:\r
+    case DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
+    case CLEAR_ENABLE_ACTIVATE:\r
+    case ENABLE_ACTIVATE_CLEAR:\r
+    case ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:      \r
+      break;\r
+    default:\r
+      if (TcgPpData->PPRequest != 0) {\r
+        break;\r
+      }\r
+      return;\r
+  }\r
+\r
+  Print (L"Rebooting system to make TPM settings in effect\n");\r
+  gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
+  ASSERT (FALSE);  \r
+}\r
+\r
+/**\r
+  Check and execute the physical presence command requested and\r
+  Lock physical presence.\r
+\r
+  @param[in]  Event        Event whose notification function is being invoked\r
+  @param[in]  Context      Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnReadyToBoot (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  BOOLEAN                           LifetimeLock;\r
+  BOOLEAN                           CmdEnable;\r
+  UINTN                             DataSize;\r
+  EFI_PHYSICAL_PRESENCE             TcgPpData;\r
+  \r
+  //\r
+  // Check pending request, if not exist, just return.\r
+  //\r
+  DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
+  Status = gRT->GetVariable (\r
+                  PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiPhysicalPresenceGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &TcgPpData\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", TcgPpData.Flags, TcgPpData.PPRequest));\r
\r
+  Status = GetTpmCapability (&LifetimeLock, &CmdEnable);\r
+  if (EFI_ERROR (Status)) {\r
+    return ;\r
+  }\r
+\r
+  if (!CmdEnable) {\r
+    if (LifetimeLock) {\r
+      //\r
+      // physicalPresenceCMDEnable is locked, can't execute physical presence command.\r
+      //\r
+      return ;\r
+    }\r
+    Status = TpmPhysicalPresence (TPM_PHYSICAL_PRESENCE_CMD_ENABLE);\r
+    if (EFI_ERROR (Status)) {\r
+      return ;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Set operator physical presence flags\r
+  //\r
+  TpmPhysicalPresence (TPM_PHYSICAL_PRESENCE_PRESENT);\r
+  \r
+  //\r
+  // Execute pending TPM request.\r
+  //  \r
+  ExecutePendingTpmRequest (&TcgPpData);\r
+  DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));\r
+\r
+  //\r
+  // Lock physical presence.\r
+  //\r
+  TpmPhysicalPresence (TPM_PHYSICAL_PRESENCE_NOTPRESENT | TPM_PHYSICAL_PRESENCE_LOCK);\r
+}\r
+\r
+/**\r
+  The driver's entry point.\r
+\r
+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable  A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS     The entry point is executed successfully.\r
+  @retval other           Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverEntry (\r
+  IN      EFI_HANDLE                ImageHandle,\r
+  IN      EFI_SYSTEM_TABLE          *SystemTable\r
+  )\r
+{\r
+  EFI_EVENT                         Event;\r
+  EFI_STATUS                        Status;\r
+  UINTN                             DataSize;\r
+  EFI_PHYSICAL_PRESENCE             TcgPpData;\r
+  \r
+  //\r
+  // Initialize physical presence variable exists.\r
+  //\r
+  DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
+  Status = gRT->GetVariable (\r
+                  PHYSICAL_PRESENCE_VARIABLE,\r
+                  &gEfiPhysicalPresenceGuid,\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
+      TcgPpData.Flags |= FLAG_NO_PPI_PROVISION;\r
+      DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
+      Status   = gRT->SetVariable (\r
+                        PHYSICAL_PRESENCE_VARIABLE,\r
+                        &gEfiPhysicalPresenceGuid,\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
+  //\r
+  // TPL Level of physical presence should be larger \r
+  // than one of TcgDxe driver (TPL_CALLBACK)\r
+  //\r
+  Status = EfiCreateEventReadyToBootEx (\r
+             TPL_CALLBACK,\r
+             OnReadyToBoot,\r
+             NULL,\r
+             &Event\r
+             );\r
+  return Status;\r
+}\r
+\r
diff --git a/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresence.h b/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresence.h
new file mode 100644 (file)
index 0000000..63d6f21
--- /dev/null
@@ -0,0 +1,38 @@
+/** @file\r
+  The header file for TPM physical presence driver.\r
+\r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 __PHYSICAL_PRESENCE_H__\r
+#define __PHYSICAL_PRESENCE_H__\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/TcgService.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/PhysicalPresenceData.h>\r
+\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
+#endif\r
diff --git a/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceDxe.inf b/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceDxe.inf
new file mode 100644 (file)
index 0000000..9b4aded
--- /dev/null
@@ -0,0 +1,61 @@
+## @file\r
+#  Component file for PhysicalPresenceDxe driver.\r
+#\r
+# Copyright (c) 2006 - 2010, 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                      = PhysicalPresenceDxe\r
+  FILE_GUID                      = D85A4A0C-2E73-4491-92E1-DCEFC3882A68\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = DriverEntry\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF\r
+#\r
+\r
+[Sources]\r
+  PhysicalPresence.c\r
+  PhysicalPresence.h\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
+\r
+[Protocols]\r
+  gEfiTcgProtocolGuid\r
+\r
+[Guids]\r
+  gEfiPhysicalPresenceGuid\r
+\r
+[Depex]\r
+  gEfiTcgProtocolGuid                  AND\r
+  gEfiVariableArchProtocolGuid         AND\r
+  gEfiVariableWriteArchProtocolGuid    AND\r
+  gEfiResetArchProtocolGuid\r
+\r
diff --git a/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceStrings.uni b/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceStrings.uni
new file mode 100644 (file)
index 0000000..2034af7
Binary files /dev/null and b/SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceStrings.uni differ
diff --git a/SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.c b/SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.c
new file mode 100644 (file)
index 0000000..e694db8
--- /dev/null
@@ -0,0 +1,134 @@
+/** @file\r
+  This driver produces PEI_LOCK_PHYSICAL_PRESENCE_PPI to indicate \r
+  whether TPM need be locked or not. It can be replaced by a platform \r
+  specific driver.\r
+\r
+Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 <Ppi/LockPhysicalPresence.h>\r
+#include <Ppi/ReadOnlyVariable2.h>\r
+#include <Guid/PhysicalPresenceData.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+\r
+/**\r
+  This interface returns whether TPM physical presence needs be locked or not.\r
+\r
+  @param[in]  PeiServices       The pointer to the PEI Services Table.\r
+\r
+  @retval     TRUE              The TPM physical presence should be locked.\r
+  @retval     FALSE             The TPM physical presence cannot be locked.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+LockTpmPhysicalPresence (\r
+  IN CONST  EFI_PEI_SERVICES             **PeiServices\r
+  );\r
+\r
+//\r
+// Gobal defintions for lock physical presence PPI and its descriptor.\r
+//\r
+PEI_LOCK_PHYSICAL_PRESENCE_PPI    mLockPhysicalPresencePpi = {\r
+  LockTpmPhysicalPresence\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR       mLockPhysicalPresencePpiList = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gPeiLockPhysicalPresencePpiGuid,\r
+  &mLockPhysicalPresencePpi\r
+};\r
+\r
+/**\r
+  This interface returns whether TPM physical presence needs be locked or not.\r
+\r
+  @param[in]  PeiServices       The pointer to the PEI Services Table.\r
+\r
+  @retval     TRUE              The TPM physical presence should be locked.\r
+  @retval     FALSE             The TPM physical presence cannot be locked.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+LockTpmPhysicalPresence (\r
+  IN CONST  EFI_PEI_SERVICES             **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI    *Variable;\r
+  UINTN                              DataSize;\r
+  EFI_PHYSICAL_PRESENCE              TcgPpData;\r
+\r
+  //\r
+  // The CRTM has sensed the physical presence assertion of the user. For example, \r
+  // the user has pressed the startup button or inserted a USB dongle. The details \r
+  // of the implementation are vendor-specific. Here we read a PCD value to indicate\r
+  // whether operator physical presence.\r
+  // \r
+  if (!PcdGetBool (PcdTpmPhysicalPresence)) {\r
+    return TRUE;\r
+  }\r
+\r
+  //\r
+  // Check the pending TPM requests. Lock TPM physical presence if there is no TPM \r
+  // request.  \r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiReadOnlyVariable2PpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&Variable\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
+    Status = Variable->GetVariable ( \r
+                         Variable, \r
+                         PHYSICAL_PRESENCE_VARIABLE,\r
+                         &gEfiPhysicalPresenceGuid,\r
+                         NULL,\r
+                         &DataSize,\r
+                         &TcgPpData\r
+                         );\r
+    if (!EFI_ERROR (Status)) {\r
+      if (TcgPpData.PPRequest != 0) {\r
+        return FALSE;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Lock TPM physical presence by default.\r
+  //\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Entry point of this module.\r
+\r
+  It installs lock physical presence PPI. \r
+\r
+  @param[in] FileHandle   Handle of the file being invoked.\r
+  @param[in] PeiServices  Describes the list of possible PEI Services.\r
+\r
+  @return                 Status of install lock physical presence PPI.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeimEntry (\r
+  IN       EFI_PEI_FILE_HANDLE       FileHandle,\r
+  IN CONST EFI_PEI_SERVICES          **PeiServices\r
+  )\r
+{\r
+  return PeiServicesInstallPpi (&mLockPhysicalPresencePpiList);\r
+}\r
diff --git a/SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf b/SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
new file mode 100644 (file)
index 0000000..da4e032
--- /dev/null
@@ -0,0 +1,55 @@
+## @file\r
+#  Component description file for physical presence PEI module.\r
+#\r
+# Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# 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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PhysicalPresencePei\r
+  FILE_GUID                      = 4FE772E8-FE3E-4086-B638-8C493C490488\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = PeimEntry\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
+  PhysicalPresencePei.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  PeimEntryPoint\r
+  PeiServicesLib\r
+\r
+[Ppis]\r
+  gPeiLockPhysicalPresencePpiGuid\r
+  gEfiPeiReadOnlyVariable2PpiGuid\r
+\r
+[Guids]\r
+  gEfiPhysicalPresenceGuid\r
+\r
+[Pcd]\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmPhysicalPresence\r
+\r
+[Depex] \r
+  gEfiPeiMemoryDiscoveredPpiGuid AND\r
+  gEfiPeiReadOnlyVariable2PpiGuid AND\r
+  gPeiTpmInitializedPpiGuid\r
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfig.vfr b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfig.vfr
new file mode 100644 (file)
index 0000000..360e556
--- /dev/null
@@ -0,0 +1,114 @@
+/** @file\r
+  VFR file used by the TCG configuration component.\r
+\r
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 "TcgConfigNvData.h"\r
+\r
+formset\r
+  guid      = TCG_CONFIG_PRIVATE_GUID,\r
+  title     = STRING_TOKEN(STR_TPM_TITLE),\r
+  help      = STRING_TOKEN(STR_TPM_HELP),\r
+  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,\r
+\r
+  varstore TCG_CONFIGURATION,\r
+    varid = TCG_CONFIGURATION_VARSTORE_ID,\r
+    name  = TCG_CONFIGURATION,\r
+    guid  = TCG_CONFIG_PRIVATE_GUID;\r
+\r
+  form formid = TCG_CONFIGURATION_FORM_ID,\r
+    title = STRING_TOKEN(STR_TPM_TITLE);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    suppressif TRUE;\r
+      checkbox varid   = TCG_CONFIGURATION.TpmEnable,\r
+              prompt   = STRING_TOKEN(STR_NULL),\r
+              help     = STRING_TOKEN(STR_NULL),\r
+      endcheckbox;\r
+    endif;\r
+\r
+    suppressif TRUE;\r
+      checkbox varid   = TCG_CONFIGURATION.TpmActivate,\r
+              prompt   = STRING_TOKEN(STR_NULL),\r
+              help     = STRING_TOKEN(STR_NULL),\r
+      endcheckbox;\r
+    endif;\r
+\r
+    suppressif TRUE;\r
+      checkbox varid   = TCG_CONFIGURATION.OriginalHideTpm,\r
+              prompt   = STRING_TOKEN(STR_NULL),\r
+              help     = STRING_TOKEN(STR_NULL),\r
+      endcheckbox;\r
+    endif;\r
+\r
+    text\r
+      help   = STRING_TOKEN(STR_TPM_STATE_HELP),\r
+      text   = STRING_TOKEN(STR_TPM_STATE_PROMPT),\r
+        text   = STRING_TOKEN(STR_TPM_STATE_CONTENT);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    label LABEL_TCG_CONFIGURATION_HIDETPM;\r
+\r
+    checkbox varid = TCG_CONFIGURATION.HideTpm,\r
+          questionid  = KEY_HIDE_TPM,\r
+          prompt      = STRING_TOKEN(STR_HIDE_TPM_PROMPT),\r
+          help        = STRING_TOKEN(STR_HIDE_TPM_HELP),\r
+          flags       = RESET_REQUIRED,\r
+    endcheckbox;\r
+\r
+    label LABEL_END;\r
+\r
+    grayoutif ideqval TCG_CONFIGURATION.OriginalHideTpm == 1;\r
+    oneof varid  = TCG_CONFIGURATION.TpmOperation,\r
+          questionid = KEY_TPM_ACTION,\r
+          prompt = STRING_TOKEN(STR_TPM_OPERATION),\r
+          help   = STRING_TOKEN(STR_TPM_OPERATION_HELP),\r
+          flags  = INTERACTIVE,\r
+          //\r
+          // Disable (TPM_ORD_PhysicalDisable) command is not available when disabled.\r
+          // Activate/deactivate (TPM_ORD_physicalSetDeactivated) command is not available when disabled.\r
+          //\r
+          suppressif ideqval TCG_CONFIGURATION.TpmEnable == 0;\r
+            option text = STRING_TOKEN(STR_DISABLE), value = DISABLE, flags = 0;\r
+            option text = STRING_TOKEN(STR_TPM_ACTIVATE), value = ACTIVATE, flags = 0;\r
+            option text = STRING_TOKEN(STR_TPM_DEACTIVATE), value = DEACTIVATE, flags = 0;\r
+            option text = STRING_TOKEN(STR_TPM_DEACTIVATE_DISABLE), value = DEACTIVATE_DISABLE, flags = 0;\r
+          endif\r
+          //\r
+          // Clear (TPM_ORD_ForceClear) command is not available when disabled or deactivated. \r
+          //\r
+          suppressif ideqval TCG_CONFIGURATION.TpmEnable == 0 OR\r
+                     ideqval TCG_CONFIGURATION.TpmActivate == 0;\r
+            option text = STRING_TOKEN(STR_TPM_CLEAR), value = CLEAR, flags = 0;\r
+            option text = STRING_TOKEN(STR_TPM_CLEAR_ENABLE_ACTIVATE), value = CLEAR_ENABLE_ACTIVATE, flags = 0;\r
+          endif\r
+\r
+          option text = STRING_TOKEN(STR_ENABLE), value = ENABLE, flags = 0;\r
+          option text = STRING_TOKEN(STR_TPM_ENABLE_ACTIVATE), value = ENABLE_ACTIVATE, flags = 0;          \r
+          option text = STRING_TOKEN(STR_TPM_ENABLE_ACTIVATE_CLEAR), value = ENABLE_ACTIVATE_CLEAR, flags = 0;\r
+          option text = STRING_TOKEN(STR_TPM_ENABLE_ACTIVATE_CLEAR_E_A), value = ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE, flags = 0;\r
+    endoneof;\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    checkbox varid = TCG_CONFIGURATION.MorState,\r
+          questionid = KEY_TPM_MOR_ENABLE,\r
+          prompt = STRING_TOKEN(STR_MOR_PROMPT),\r
+          help   = STRING_TOKEN(STR_MOR_HELP),\r
+    endcheckbox; \r
+    endif;\r
+\r
+  endform;\r
+\r
+endformset;\r
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c
new file mode 100644 (file)
index 0000000..4b2008f
--- /dev/null
@@ -0,0 +1,147 @@
+/** @file\r
+  The module entry point for Tcg configuration module.\r
+\r
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+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 "TcgConfigImpl.h"\r
+\r
+EFI_GUID gTcgConfigPrivateGuid = TCG_CONFIG_PRIVATE_GUID;\r
+\r
+/**\r
+  The entry point for Tcg configuration driver.\r
+\r
+  @param[in]  ImageHandle        The image handle of the driver.\r
+  @param[in]  SystemTable        The system table.\r
+\r
+  @retval EFI_ALREADY_STARTED    The driver already exists in system.\r
+  @retval EFI_OUT_OF_RESOURCES   Fail to execute entry point due to lack of resources.\r
+  @retval EFI_SUCCES             All the related protocols are installed on the driver.\r
+  @retval Others                 Fail to install protocols as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TcgConfigDriverEntryPoint (\r
+  IN EFI_HANDLE          ImageHandle,\r
+  IN EFI_SYSTEM_TABLE    *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  TCG_CONFIG_PRIVATE_DATA   *PrivateData;\r
+  EFI_TCG_PROTOCOL          *TcgProtocol;\r
+\r
+  Status = TisPcRequestUseTpm ((TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "TPM not detected!\n"));\r
+    return Status;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    TcgProtocol = NULL;\r
+  }\r
+  \r
+  Status = gBS->OpenProtocol (\r
+                  ImageHandle,\r
+                  &gTcgConfigPrivateGuid,\r
+                  NULL,\r
+                  ImageHandle,\r
+                  ImageHandle,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+  \r
+  //\r
+  // Create a private data structure.\r
+  //\r
+  PrivateData = AllocateCopyPool (sizeof (TCG_CONFIG_PRIVATE_DATA), &mTcgConfigPrivateDateTemplate);\r
+  if (PrivateData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  PrivateData->TcgProtocol = TcgProtocol;\r
+  PrivateData->HideTpm     = PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm);\r
+  \r
+  //\r
+  // Install TCG configuration form\r
+  //\r
+  Status = InstallTcgConfigForm (PrivateData);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ErrorExit;\r
+  }\r
+\r
+  //\r
+  // Install private GUID.\r
+  //    \r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &ImageHandle,\r
+                  &gTcgConfigPrivateGuid,\r
+                  PrivateData,\r
+                  NULL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto ErrorExit;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+  if (PrivateData != NULL) {\r
+    UninstallTcgConfigForm (PrivateData);\r
+  }  \r
+  \r
+  return Status;\r
+}\r
+\r
+/**\r
+  Unload the Tcg configuration form.\r
+\r
+  @param[in]  ImageHandle         The driver's image handle.\r
+\r
+  @retval     EFI_SUCCESS         The Tcg configuration form is unloaded.\r
+  @retval     Others              Failed to unload the form.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TcgConfigDriverUnload (\r
+  IN EFI_HANDLE  ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  TCG_CONFIG_PRIVATE_DATA   *PrivateData;\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  ImageHandle,\r
+                  &gTcgConfigPrivateGuid,\r
+                  (VOID **) &PrivateData\r
+                  );  \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;  \r
+  }\r
+  \r
+  ASSERT (PrivateData->Signature == TCG_CONFIG_PRIVATE_DATA_SIGNATURE);\r
+\r
+  gBS->UninstallMultipleProtocolInterfaces (\r
+         &ImageHandle,\r
+         &gTcgConfigPrivateGuid,\r
+         PrivateData,\r
+         NULL\r
+         );\r
+  \r
+  UninstallTcgConfigForm (PrivateData);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
new file mode 100644 (file)
index 0000000..d9d3102
--- /dev/null
@@ -0,0 +1,75 @@
+## @file\r
+#  Component name for Tcg configuration module.\r
+#\r
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# 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                      = TcgConfigDxe\r
+  FILE_GUID                      = 1FA4DAFE-FA5D-4d75-BEA6-5863862C520A\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = TcgConfigDriverEntryPoint\r
+  UNLOAD_IMAGE                   = TcgConfigDriverUnload\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  TcgConfigDriver.c\r
+  TcgConfigImpl.c\r
+  TcgConfigImpl.h\r
+  TcgConfig.vfr\r
+  TcgConfigStrings.uni\r
+  TcgConfigNvData.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiDriverEntryPoint\r
+  UefiHiiServicesLib\r
+  DebugLib\r
+  HiiLib\r
+  PcdLib\r
+  PrintLib\r
+  TpmCommLib\r
+\r
+[Guids]\r
+  gEfiPhysicalPresenceGuid\r
+  gEfiIfrTianoGuid\r
+\r
+[Protocols]\r
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES\r
+  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES\r
+  gEfiTcgProtocolGuid                           ## CONSUMES\r
+\r
+[FixedPcd]\r</