Add Secure MOR implementation.
authorYao, Jiewen <Jiewen.Yao@intel.com>
Tue, 28 Jul 2015 07:20:58 +0000 (07:20 +0000)
committerjyao1 <jyao1@Edk2>
Tue, 28 Jul 2015 07:20:58 +0000 (07:20 +0000)
Add a new module MemoryOverwriteRequestControlLock to register VarCheck handler to  enforce MorLock Policy.
Only SMM version is added because MOR is only supported in SMM variable case.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <Jiewen.Yao@intel.com>
Reviewed-by: "Chao Zhang" <chao.b.zhang@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18092 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Include/IndustryStandard/MemoryOverwriteRequestControlLock.h [new file with mode: 0644]
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dsc
SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.c [new file with mode: 0644]
SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.h [new file with mode: 0644]
SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.uni [new file with mode: 0644]
SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockExtra.uni [new file with mode: 0644]
SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.c [new file with mode: 0644]
SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf [new file with mode: 0644]

diff --git a/MdePkg/Include/IndustryStandard/MemoryOverwriteRequestControlLock.h b/MdePkg/Include/IndustryStandard/MemoryOverwriteRequestControlLock.h
new file mode 100644 (file)
index 0000000..771306b
--- /dev/null
@@ -0,0 +1,43 @@
+/** @file\r
+  Support for Microsoft Secure MOR implementation, defined at \r
+  Microsoft Secure MOR implementation.\r
+  https://msdn.microsoft.com/en-us/library/windows/hardware/mt270973(v=vs.85).aspx\r
+\r
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_H__\r
+#define __MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_H__\r
+\r
+#define MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_GUID \\r
+  { \\r
+    0xBB983CCF, 0x151D, 0x40E1, {0xA0, 0x7B, 0x4A, 0x17, 0xBE, 0x16, 0x82, 0x92} \\r
+  }\r
+\r
+#define MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME L"MemoryOverwriteRequestControlLock"\r
+\r
+//\r
+// VendorGuid: {BB983CCF-151D-40E1-A07B-4A17BE168292}\r
+// Name:       MemoryOverwriteRequestControlLock\r
+// Attributes: NV+BS+RT\r
+// Size:       0x1 byte\r
+//\r
+// The BIOS initializes MemoryOverwriteRequestControlLock to a value of 0x00\r
+// before BDS (BOOT#### processing). When the OS loader calls SetVariable by\r
+// specifying 0x01, the access mode for both MemoryOverwriteRequestControlLock\r
+// and MemoryOverwriteRequestControl is changed to read-only. If any other\r
+// value is specified in the SetVariable call, it fails with the \r
+// EFI_INVALID_PARAMETER error code.\r
+//\r
+\r
+extern EFI_GUID gEfiMemoryOverwriteRequestControlLockGuid;\r
+\r
+#endif\r
index 598a6d0..7d74b69 100644 (file)
 \r
   ## Include/Guid/MemoryOverwriteControl.h\r
   gEfiMemoryOverwriteControlDataGuid = { 0xe20939be, 0x32d4, 0x41be, {0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29 }}\r
+  \r
+  ## Include/IndustryStandard/MemoryOverwriteRequestControlLock.h\r
+  gEfiMemoryOverwriteRequestControlLockGuid = { 0xBB983CCF, 0x151D, 0x40E1, {0xA0, 0x7B, 0x4A, 0x17, 0xBE, 0x16, 0x82, 0x92}}\r
 \r
   ## Include/Guid/WinCertificate.h\r
   gEfiCertTypeRsa2048Sha256Guid = { 0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf }}\r
index fa94d90..2d464a0 100644 (file)
   SecurityPkg/Pkcs7Verify/Pkcs7VerifyDxe/Pkcs7VerifyDxe.inf\r
 \r
 [Components.IA32, Components.X64]\r
+\r
+  SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf\r
   SecurityPkg/Tcg/TcgSmm/TcgSmm.inf\r
   SecurityPkg/Tcg/TrEESmm/TrEESmm.inf\r
   #\r
diff --git a/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.c b/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.c
new file mode 100644 (file)
index 0000000..7ca7079
--- /dev/null
@@ -0,0 +1,196 @@
+/** @file\r
+  TCG MOR (Memory Overwrite Request) Lock Control Driver.\r
+\r
+  This driver initilize MemoryOverwriteRequestControlLock variable.\r
+  This module will add Variable Hook and allow MemoryOverwriteRequestControlLock variable set only once.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include <Guid/MemoryOverwriteControl.h>\r
+#include <IndustryStandard/MemoryOverwriteRequestControlLock.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include "TcgMorLock.h"\r
+\r
+typedef struct {\r
+  CHAR16                                 *VariableName;\r
+  EFI_GUID                               *VendorGuid;\r
+} VARIABLE_TYPE;\r
+\r
+VARIABLE_TYPE  mMorVariableType[] = {\r
+  {MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,      &gEfiMemoryOverwriteControlDataGuid},\r
+  {MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,  &gEfiMemoryOverwriteRequestControlLockGuid},\r
+};\r
+\r
+/**\r
+  Returns if this is MOR related variable.\r
+\r
+  @param  VariableName the name of the vendor's variable, it's a Null-Terminated Unicode String\r
+  @param  VendorGuid   Unify identifier for vendor.\r
+\r
+  @retval  TRUE            The variable is MOR related.\r
+  @retval  FALSE           The variable is NOT MOR related.\r
+**/\r
+BOOLEAN\r
+IsAnyMorVariable (\r
+  IN CHAR16                                 *VariableName,\r
+  IN EFI_GUID                               *VendorGuid\r
+  )\r
+{\r
+  UINTN   Index;\r
+\r
+  for (Index = 0; Index < sizeof(mMorVariableType)/sizeof(mMorVariableType[0]); Index++) {\r
+    if ((StrCmp (VariableName, mMorVariableType[Index].VariableName) == 0) && \r
+        (CompareGuid (VendorGuid, mMorVariableType[Index].VendorGuid))) {\r
+      return TRUE;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Returns if this is MOR lock variable.\r
+\r
+  @param  VariableName the name of the vendor's variable, it's a Null-Terminated Unicode String\r
+  @param  VendorGuid   Unify identifier for vendor.\r
+\r
+  @retval  TRUE            The variable is MOR lock variable.\r
+  @retval  FALSE           The variable is NOT MOR lock variable.\r
+**/\r
+BOOLEAN\r
+IsMorLockVariable (\r
+  IN CHAR16                                 *VariableName,\r
+  IN EFI_GUID                               *VendorGuid\r
+  )\r
+{\r
+  if ((StrCmp (VariableName, MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME) == 0) && \r
+      (CompareGuid (VendorGuid, &gEfiMemoryOverwriteRequestControlLockGuid))) {\r
+    return TRUE;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  This service is a checker handler for the UEFI Runtime Service SetVariable()\r
+\r
+  @param  VariableName the name of the vendor's variable, as a\r
+                       Null-Terminated Unicode String\r
+  @param  VendorGuid   Unify identifier for vendor.\r
+  @param  Attributes   Point to memory location to return the attributes of variable. If the point\r
+                       is NULL, the parameter would be ignored.\r
+  @param  DataSize     The size in bytes of Data-Buffer.\r
+  @param  Data         Point to the content of the variable.\r
+\r
+  @retval  EFI_SUCCESS            The firmware has successfully stored the variable and its data as\r
+                                  defined by the Attributes.\r
+  @retval  EFI_INVALID_PARAMETER  An invalid combination of attribute bits was supplied, or the\r
+                                  DataSize exceeds the maximum allowed.\r
+  @retval  EFI_INVALID_PARAMETER  VariableName is an empty Unicode string.\r
+  @retval  EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.\r
+  @retval  EFI_DEVICE_ERROR       The variable could not be saved due to a hardware failure.\r
+  @retval  EFI_WRITE_PROTECTED    The variable in question is read-only.\r
+  @retval  EFI_WRITE_PROTECTED    The variable in question cannot be deleted.\r
+  @retval  EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+                                  set but the AuthInfo does NOT pass the validation check carried\r
+                                  out by the firmware.\r
+  @retval  EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetVariableCheckHandlerMor (\r
+  IN CHAR16     *VariableName,\r
+  IN EFI_GUID   *VendorGuid,\r
+  IN UINT32     Attributes,\r
+  IN UINTN      DataSize,\r
+  IN VOID       *Data\r
+  )\r
+{\r
+  UINTN       MorLockDataSize;\r
+  BOOLEAN     MorLock;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // do not handle non-MOR variable\r
+  //\r
+  if (!IsAnyMorVariable (VariableName, VendorGuid)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  MorLockDataSize = sizeof(MorLock);\r
+  Status = InternalGetVariable (\r
+             MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,\r
+             &gEfiMemoryOverwriteRequestControlLockGuid,\r
+             NULL,\r
+             &MorLockDataSize,\r
+             &MorLock\r
+             );\r
+  if (!EFI_ERROR (Status) && MorLock) {\r
+    //\r
+    // If lock, deny access\r
+    //\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  //\r
+  // check format\r
+  //\r
+  if (IsMorLockVariable(VariableName, VendorGuid)) {\r
+    //\r
+    // Delete not OK\r
+    //\r
+    if ((DataSize == 0) || (Data == NULL) || (Attributes == 0)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    //\r
+    // set to any other value not OK\r
+    //\r
+    if ((DataSize != sizeof(UINT8)) || ((*(UINT8 *)Data != 1) && (*(UINT8 *)Data != 0))) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  //\r
+  // Or grant access\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Entry Point for MOR Lock 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
+MorLockDriverInit (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       Data;\r
+\r
+  Data = 0;\r
+  Status = InternalSetVariable (\r
+             MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,\r
+             &gEfiMemoryOverwriteRequestControlLockGuid,\r
+             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+             1,\r
+             &Data\r
+             );\r
+  return Status;\r
+}\r
diff --git a/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.h b/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.h
new file mode 100644 (file)
index 0000000..50a656a
--- /dev/null
@@ -0,0 +1,137 @@
+/** @file\r
+   TCG MOR (Memory Overwrite Request) Lock Control Driver header file.\r
+   \r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _EFI_TCG_MOR_LOCK_H_\r
+#define _EFI_TCG_MOR_LOCK_H_\r
+\r
+/**\r
+  This service is a wrapper for the UEFI Runtime Service GetVariable().\r
+\r
+  @param  VariableName the name of the vendor's variable, it's a Null-Terminated Unicode String\r
+  @param  VendorGuid   Unify identifier for vendor.\r
+  @param  Attributes   Point to memory location to return the attributes of variable. If the point\r
+                       is NULL, the parameter would be ignored.\r
+  @param  DataSize     As input, point to the maximum size of return Data-Buffer.\r
+                       As output, point to the actual size of the returned Data-Buffer.\r
+  @param  Data         Point to return Data-Buffer.\r
+\r
+  @retval  EFI_SUCCESS            The function completed successfully.\r
+  @retval  EFI_NOT_FOUND          The variable was not found.\r
+  @retval  EFI_BUFFER_TOO_SMALL   The DataSize is too small for the result. DataSize has\r
+                                  been updated with the size needed to complete the request.\r
+  @retval  EFI_INVALID_PARAMETER  VariableName is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  VendorGuid is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  DataSize is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  The DataSize is not too small and Data is NULL.\r
+  @retval  EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.\r
+  @retval  EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalGetVariable (\r
+  IN      CHAR16                   *VariableName,\r
+  IN      EFI_GUID                 *VendorGuid,\r
+  OUT     UINT32                   *Attributes OPTIONAL,\r
+  IN OUT  UINTN                    *DataSize,\r
+  OUT     VOID                     *Data\r
+  );\r
+\r
+/**\r
+  This service is a wrapper for the UEFI Runtime Service SetVariable()\r
+\r
+  @param  VariableName the name of the vendor's variable, as a\r
+                       Null-Terminated Unicode String\r
+  @param  VendorGuid   Unify identifier for vendor.\r
+  @param  Attributes   Point to memory location to return the attributes of variable. If the point\r
+                       is NULL, the parameter would be ignored.\r
+  @param  DataSize     The size in bytes of Data-Buffer.\r
+  @param  Data         Point to the content of the variable.\r
+\r
+  @retval  EFI_SUCCESS            The firmware has successfully stored the variable and its data as\r
+                                  defined by the Attributes.\r
+  @retval  EFI_INVALID_PARAMETER  An invalid combination of attribute bits was supplied, or the\r
+                                  DataSize exceeds the maximum allowed.\r
+  @retval  EFI_INVALID_PARAMETER  VariableName is an empty Unicode string.\r
+  @retval  EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.\r
+  @retval  EFI_DEVICE_ERROR       The variable could not be saved due to a hardware failure.\r
+  @retval  EFI_WRITE_PROTECTED    The variable in question is read-only.\r
+  @retval  EFI_WRITE_PROTECTED    The variable in question cannot be deleted.\r
+  @retval  EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+                                  set but the AuthInfo does NOT pass the validation check carried\r
+                                  out by the firmware.\r
+  @retval  EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalSetVariable (\r
+  IN CHAR16                       *VariableName,\r
+  IN EFI_GUID                     *VendorGuid,\r
+  IN UINT32                       Attributes,\r
+  IN UINTN                        DataSize,\r
+  IN VOID                         *Data\r
+  );\r
+\r
+/**\r
+  This service is a checker handler for the UEFI Runtime Service SetVariable()\r
+\r
+  @param  VariableName the name of the vendor's variable, as a\r
+                       Null-Terminated Unicode String\r
+  @param  VendorGuid   Unify identifier for vendor.\r
+  @param  Attributes   Point to memory location to return the attributes of variable. If the point\r
+                       is NULL, the parameter would be ignored.\r
+  @param  DataSize     The size in bytes of Data-Buffer.\r
+  @param  Data         Point to the content of the variable.\r
+\r
+  @retval  EFI_SUCCESS            The firmware has successfully stored the variable and its data as\r
+                                  defined by the Attributes.\r
+  @retval  EFI_INVALID_PARAMETER  An invalid combination of attribute bits was supplied, or the\r
+                                  DataSize exceeds the maximum allowed.\r
+  @retval  EFI_INVALID_PARAMETER  VariableName is an empty Unicode string.\r
+  @retval  EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.\r
+  @retval  EFI_DEVICE_ERROR       The variable could not be saved due to a hardware failure.\r
+  @retval  EFI_WRITE_PROTECTED    The variable in question is read-only.\r
+  @retval  EFI_WRITE_PROTECTED    The variable in question cannot be deleted.\r
+  @retval  EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+                                  set but the AuthInfo does NOT pass the validation check carried\r
+                                  out by the firmware.\r
+  @retval  EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetVariableCheckHandlerMor (\r
+  IN CHAR16     *VariableName,\r
+  IN EFI_GUID   *VendorGuid,\r
+  IN UINT32     Attributes,\r
+  IN UINTN      DataSize,\r
+  IN VOID       *Data\r
+  );\r
+\r
+/**\r
+  Entry Point for MOR Lock 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
+MorLockDriverInit (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.uni b/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.uni
new file mode 100644 (file)
index 0000000..2e54937
Binary files /dev/null and b/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.uni differ
diff --git a/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockExtra.uni b/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockExtra.uni
new file mode 100644 (file)
index 0000000..ea7896b
Binary files /dev/null and b/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockExtra.uni differ
diff --git a/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.c b/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.c
new file mode 100644 (file)
index 0000000..019cb8b
--- /dev/null
@@ -0,0 +1,158 @@
+/** @file\r
+   TCG MOR (Memory Overwrite Request) Lock Control Driver SMM wrapper.\r
+   \r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiSmm.h>\r
+#include <Library/SmmServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Protocol/SmmVarCheck.h>\r
+#include <Protocol/SmmVariable.h>\r
+#include "TcgMorLock.h"\r
+\r
+EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;\r
+\r
+/**\r
+  This service is a wrapper for the UEFI Runtime Service GetVariable().\r
+\r
+  @param  VariableName the name of the vendor's variable, it's a Null-Terminated Unicode String\r
+  @param  VendorGuid   Unify identifier for vendor.\r
+  @param  Attributes   Point to memory location to return the attributes of variable. If the point\r
+                       is NULL, the parameter would be ignored.\r
+  @param  DataSize     As input, point to the maximum size of return Data-Buffer.\r
+                       As output, point to the actual size of the returned Data-Buffer.\r
+  @param  Data         Point to return Data-Buffer.\r
+\r
+  @retval  EFI_SUCCESS            The function completed successfully.\r
+  @retval  EFI_NOT_FOUND          The variable was not found.\r
+  @retval  EFI_BUFFER_TOO_SMALL   The DataSize is too small for the result. DataSize has\r
+                                  been updated with the size needed to complete the request.\r
+  @retval  EFI_INVALID_PARAMETER  VariableName is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  VendorGuid is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  DataSize is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  The DataSize is not too small and Data is NULL.\r
+  @retval  EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.\r
+  @retval  EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalGetVariable (\r
+  IN      CHAR16                   *VariableName,\r
+  IN      EFI_GUID                 *VendorGuid,\r
+  OUT     UINT32                   *Attributes OPTIONAL,\r
+  IN OUT  UINTN                    *DataSize,\r
+  OUT     VOID                     *Data\r
+  )\r
+{\r
+  return mSmmVariable->SmmGetVariable (\r
+                         VariableName,\r
+                         VendorGuid,\r
+                         Attributes,\r
+                         DataSize,\r
+                         Data\r
+                         );\r
+}\r
+\r
+/**\r
+  This service is a wrapper for the UEFI Runtime Service SetVariable()\r
+\r
+  @param  VariableName the name of the vendor's variable, as a\r
+                       Null-Terminated Unicode String\r
+  @param  VendorGuid   Unify identifier for vendor.\r
+  @param  Attributes   Point to memory location to return the attributes of variable. If the point\r
+                       is NULL, the parameter would be ignored.\r
+  @param  DataSize     The size in bytes of Data-Buffer.\r
+  @param  Data         Point to the content of the variable.\r
+\r
+  @retval  EFI_SUCCESS            The firmware has successfully stored the variable and its data as\r
+                                  defined by the Attributes.\r
+  @retval  EFI_INVALID_PARAMETER  An invalid combination of attribute bits was supplied, or the\r
+                                  DataSize exceeds the maximum allowed.\r
+  @retval  EFI_INVALID_PARAMETER  VariableName is an empty Unicode string.\r
+  @retval  EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.\r
+  @retval  EFI_DEVICE_ERROR       The variable could not be saved due to a hardware failure.\r
+  @retval  EFI_WRITE_PROTECTED    The variable in question is read-only.\r
+  @retval  EFI_WRITE_PROTECTED    The variable in question cannot be deleted.\r
+  @retval  EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\r
+                                  set but the AuthInfo does NOT pass the validation check carried\r
+                                  out by the firmware.\r
+  @retval  EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalSetVariable (\r
+  IN CHAR16                       *VariableName,\r
+  IN EFI_GUID                     *VendorGuid,\r
+  IN UINT32                       Attributes,\r
+  IN UINTN                        DataSize,\r
+  IN VOID                         *Data\r
+  )\r
+{\r
+  return mSmmVariable->SmmSetVariable (\r
+                         VariableName,\r
+                         VendorGuid,\r
+                         Attributes,\r
+                         DataSize,\r
+                         Data\r
+                         );\r
+}\r
+\r
+/**\r
+  Entry Point for MOR Lock Control driver.\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       EntryPoint runs successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MorLockDriverEntryPointSmm (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EDKII_SMM_VAR_CHECK_PROTOCOL  *SmmVarCheck;\r
+\r
+  //\r
+  // This driver link to Smm Variable driver\r
+  //\r
+  DEBUG ((EFI_D_INFO, "MorLockDriverEntryPointSmm\n"));\r
+  \r
+  Status = gSmst->SmmLocateProtocol (\r
+                  &gEfiSmmVariableProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &mSmmVariable\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gSmst->SmmLocateProtocol (\r
+                  &gEdkiiSmmVarCheckProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &SmmVarCheck\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = MorLockDriverInit ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = SmmVarCheck->SmmRegisterSetVariableCheckHandler (SetVariableCheckHandlerMor);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf b/SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf
new file mode 100644 (file)
index 0000000..19d9f3e
--- /dev/null
@@ -0,0 +1,66 @@
+## @file\r
+#  Initilizes MemoryOverwriteRequestControlLock variable\r
+#\r
+#  This module will add Variable Hook and allow MemoryOverwriteRequestControlLock variable set only once.\r
+#\r
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = TcgMorLockSmm\r
+  MODULE_UNI_FILE                = TcgMorLock.uni\r
+  FILE_GUID                      = E2EA6F47-E678-47FA-8C1B-02A03E825C6E\r
+  MODULE_TYPE                    = DXE_SMM_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  PI_SPECIFICATION_VERSION       = 0x0001000A\r
+  ENTRY_POINT                    = MorLockDriverEntryPointSmm\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
+  TcgMorLock.c\r
+  TcgMorLockSmm.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiDriverEntryPoint\r
+  SmmServicesTableLib\r
+  DebugLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+\r
+[Guids]\r
+  ## SOMETIMES_CONSUMES      ## Variable:L"MemoryOverwriteRequestControl"\r
+  gEfiMemoryOverwriteControlDataGuid\r
+\r
+  ## SOMETIMES_CONSUMES      ## Variable:L"MemoryOverwriteRequestControlLock"\r
+  ## PRODUCES                ## Variable:L"MemoryOverwriteRequestControlLock"\r
+  gEfiMemoryOverwriteRequestControlLockGuid\r
+\r
+[Protocols]\r
+  gEdkiiSmmVarCheckProtocolGuid           ## CONSUMES\r
+  gEfiSmmVariableProtocolGuid             ## CONSUMES\r
+\r
+[Depex]\r
+  gEfiSmmVariableProtocolGuid AND\r
+  gSmmVariableWriteGuid AND\r
+  ( gEfiTcgProtocolGuid OR gEfiTrEEProtocolGuid )\r
+\r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+  TcgMorLockExtra.uni\r