]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLock.c
Add Secure MOR implementation.
[mirror_edk2.git] / SecurityPkg / Tcg / MemoryOverwriteRequestControlLock / TcgMorLock.c
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