[edk2-devel] [PATCH v3 02/14] MdeModulePkg: Define the VariablePolicyLib

Michael Kubacki michael.kubacki at outlook.com
Thu May 21 22:43:19 UTC 2020


From: Bret Barkelew <brbarkel at microsoft.com>

https://bugzilla.tianocore.org/show_bug.cgi?id=2522

VariablePolicy is an updated interface to
replace VarLock and VarCheckProtocol.

Add the VariablePolicyLib library that implements
the portable business logic for the VariablePolicy
engine.

Also add host-based CI test cases for the lib.

Cc: Jian J Wang <jian.j.wang at intel.com>
Cc: Hao A Wu <hao.a.wu at intel.com>
Cc: Liming Gao <liming.gao at intel.com>
Cc: Bret Barkelew <brbarkel at microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki at microsoft.com>
---
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c                     |   46 +
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c               |   86 +
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c                               |  830 +++++++
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.c   | 2533 ++++++++++++++++++++
 MdeModulePkg/Include/Library/VariablePolicyLib.h                                         |  207 ++
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf                             |   44 +
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni                             |   12 +
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf                   |   51 +
 MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.inf |   40 +
 MdeModulePkg/MdeModulePkg.dec                                                            |    3 +
 MdeModulePkg/MdeModulePkg.dsc                                                            |    5 +
 MdeModulePkg/Test/MdeModulePkgHostTest.dsc                                               |   11 +
 12 files changed, 3868 insertions(+)

diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
new file mode 100644
index 000000000000..ad2ee0b2fb8f
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
@@ -0,0 +1,46 @@
+/** @file -- VariablePolicyExtraInitNull.c
+This file contains extra init and deinit routines that don't do anything
+extra.
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+
+/**
+  An extra init hook that enables the RuntimeDxe library instance to
+  register VirtualAddress change callbacks. Among other things.
+
+  @retval     EFI_SUCCESS   Everything is good. Continue with init.
+  @retval     Others        Uh... don't continue.
+
+**/
+EFI_STATUS
+VariablePolicyExtraInit (
+  VOID
+  )
+{
+  // NULL implementation.
+  return EFI_SUCCESS;
+}
+
+
+/**
+  An extra deinit hook that enables the RuntimeDxe library instance to
+  register VirtualAddress change callbacks. Among other things.
+
+  @retval     EFI_SUCCESS   Everything is good. Continue with deinit.
+  @retval     Others        Uh... don't continue.
+
+**/
+EFI_STATUS
+VariablePolicyExtraDeinit (
+  VOID
+  )
+{
+  // NULL implementation.
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c
new file mode 100644
index 000000000000..43418dd0409d
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c
@@ -0,0 +1,86 @@
+/** @file -- VariablePolicyExtraInitRuntimeDxe.c
+This file contains extra init and deinit routines that register and unregister
+VariableAddressChange callbacks.
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+extern EFI_GET_VARIABLE   mGetVariableHelper;
+extern UINT8              *mPolicyTable;
+STATIC BOOLEAN            mIsVirtualAddrConverted;
+STATIC EFI_EVENT          mVariablePolicyLibVirtualAddressChangeEvent  = NULL;
+
+/**
+  For the RuntimeDxe version of this lib, convert internal pointer addresses to virtual addresses.
+
+  @param[in] Event      Event whose notification function is being invoked.
+  @param[in] Context    The pointer to the notification function's context, which
+                        is implementation-dependent.
+**/
+STATIC
+VOID
+EFIAPI
+VariablePolicyLibVirtualAddressCallback (
+  IN  EFI_EVENT   Event,
+  IN  VOID        *Context
+  )
+{
+  gRT->ConvertPointer (0, (VOID **) &mPolicyTable);
+  gRT->ConvertPointer (0, (VOID **) &mGetVariableHelper);
+  mIsVirtualAddrConverted = TRUE;
+}
+
+
+/**
+  An extra init hook that enables the RuntimeDxe library instance to
+  register VirtualAddress change callbacks. Among other things.
+
+  @retval     EFI_SUCCESS   Everything is good. Continue with init.
+  @retval     Others        Uh... don't continue.
+
+**/
+EFI_STATUS
+VariablePolicyExtraInit (
+  VOID
+  )
+{
+  return gBS->CreateEventEx (
+                EVT_NOTIFY_SIGNAL,
+                TPL_NOTIFY,
+                VariablePolicyLibVirtualAddressCallback,
+                NULL,
+                &gEfiEventVirtualAddressChangeGuid,
+                &mVariablePolicyLibVirtualAddressChangeEvent
+                );
+}
+
+
+/**
+  An extra deinit hook that enables the RuntimeDxe library instance to
+  register VirtualAddress change callbacks. Among other things.
+
+  @retval     EFI_SUCCESS   Everything is good. Continue with deinit.
+  @retval     Others        Uh... don't continue.
+
+**/
+EFI_STATUS
+VariablePolicyExtraDeinit (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = EFI_SUCCESS;
+  if (mIsVirtualAddrConverted) {
+    Status = gBS->CloseEvent (mVariablePolicyLibVirtualAddressChangeEvent);
+  } else {
+    Status = EFI_SUCCESS;
+  }
+
+  return Status;
+}
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
new file mode 100644
index 000000000000..201c5e393a60
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
@@ -0,0 +1,830 @@
+/** @file -- VariablePolicyLib.c
+Business logic for Variable Policy enforcement.
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/SafeIntLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Protocol/VariablePolicy.h>
+#include <Library/VariablePolicyLib.h>
+
+
+// IMPORTANT NOTE: This library is currently rife with multiple return statements
+//                 for error handling. A refactor should remove these at some point.
+
+//
+// This library was designed with advanced unit-test features.
+// This define handles the configuration.
+#ifdef INTERNAL_UNIT_TEST
+#undef STATIC
+#define STATIC    // Nothing...
+#endif
+
+// An abstracted GetVariable interface that enables configuration regardless of the environment.
+EFI_GET_VARIABLE    mGetVariableHelper = NULL;
+
+// Master switch to lock this entire interface. Does not stop enforcement,
+// just prevents the configuration from being changed for the rest of the boot.
+STATIC  BOOLEAN             mInterfaceLocked = FALSE;
+
+// Master switch to disable the entire interface for a single boot.
+// This will disable all policy enforcement for the duration of the boot.
+STATIC  BOOLEAN             mProtectionDisabled = FALSE;
+
+// Table to hold all the current policies.
+UINT8               *mPolicyTable = NULL;
+STATIC  UINT32              mCurrentTableSize = 0;
+STATIC  UINT32              mCurrentTableUsage = 0;
+STATIC  UINT32              mCurrentTableCount = 0;
+
+#define POLICY_TABLE_STEP_SIZE        0x1000
+
+// NOTE: DO NOT USE THESE MACROS on any structure that has not been validated.
+//       Current table data has already been sanitized.
+#define GET_NEXT_POLICY(CurPolicy)    (VARIABLE_POLICY_ENTRY *)((UINT8 *) CurPolicy + CurPolicy->Size)
+#define GET_POLICY_NAME(CurPolicy)    (CHAR16 *)((UINTN) CurPolicy + CurPolicy->OffsetToName)
+
+#define MATCH_PRIORITY_EXACT    0
+#define MATCH_PRIORITY_MAX      MATCH_PRIORITY_EXACT
+#define MATCH_PRIORITY_MIN      MAX_UINT8
+
+// ExtraInit/ExtraDeinit functions allow RuntimeDxe to register VirtualAddress callbacks.
+EFI_STATUS
+VariablePolicyExtraInit (
+  VOID
+  );
+
+EFI_STATUS
+VariablePolicyExtraDeinit (
+  VOID
+  );
+
+
+/**
+  This helper function determines whether the structure of an incoming policy
+  is valid and internally consistent.
+
+  @param[in]  NewPolicy     Pointer to the incoming policy structure.
+
+  @retval     TRUE
+  @retval     FALSE   Pointer is NULL, size is wrong, strings are empty, or
+                      substructures overlap.
+
+**/
+STATIC
+BOOLEAN
+IsValidVariablePolicyStructure (
+  IN CONST VARIABLE_POLICY_ENTRY    *NewPolicy
+  )
+{
+  EFI_STATUS    Status;
+  UINTN         EntryEnd;
+  CHAR16        *CheckChar;
+  UINTN         WildcardCount;
+
+  // Sanitize some quick values.
+  if (NewPolicy == NULL || NewPolicy->Size == 0 ||
+      // Structure size should be at least as long as the minumum structure and a NULL string.
+      NewPolicy->Size < sizeof (VARIABLE_POLICY_ENTRY) ||
+      // Check for the known revision.
+      NewPolicy->Version != VARIABLE_POLICY_ENTRY_REVISION) {
+    return FALSE;
+  }
+
+  // Calculate the theoretical end of the structure and make sure
+  // that the structure can fit in memory.
+  Status = SafeUintnAdd ((UINTN) NewPolicy, NewPolicy->Size, &EntryEnd);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  // Check for a valid Max Size.
+  if (NewPolicy->MaxSize == 0) {
+    return FALSE;
+  }
+
+  // Check for the valid list of lock policies.
+  if (NewPolicy->LockPolicyType != VARIABLE_POLICY_TYPE_NO_LOCK &&
+      NewPolicy->LockPolicyType != VARIABLE_POLICY_TYPE_LOCK_NOW &&
+      NewPolicy->LockPolicyType != VARIABLE_POLICY_TYPE_LOCK_ON_CREATE &&
+      NewPolicy->LockPolicyType != VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE) {
+    return FALSE;
+  }
+
+  // If the policy type is VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE, make sure that the matching state variable Name
+  // terminates before the OffsetToName for the matching policy variable Name.
+  if (NewPolicy->LockPolicyType == VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE) {
+    // Adjust CheckChar to the offset of the LockPolicy->Name.
+    Status =  SafeUintnAdd (
+                (UINTN) NewPolicy + sizeof (VARIABLE_POLICY_ENTRY),
+                sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY),
+                (UINTN *) &CheckChar
+                );
+    if (EFI_ERROR (Status) || EntryEnd <= (UINTN) CheckChar) {
+      return FALSE;
+    }
+
+    while (*CheckChar != CHAR_NULL) {
+      if (EntryEnd <= (UINTN) CheckChar) {
+        return FALSE;
+      }
+      CheckChar++;
+    }
+
+    // At this point we should have either exceeded the structure or be pointing at the last char in LockPolicy->Name.
+    // We should check to make sure that the policy Name comes immediately after this character.
+    if ((UINTN) ++CheckChar != (UINTN) NewPolicy + NewPolicy->OffsetToName) {
+      return FALSE;
+    }
+  } else {
+    // If the policy type is any other value, make sure that the LockPolicy structure has a zero length.
+    if (NewPolicy->OffsetToName != sizeof (VARIABLE_POLICY_ENTRY)) {
+      return FALSE;
+    }
+  }
+
+  // Check to make sure that the name has a terminating character
+  // before the end of the structure.
+  // We've already checked that the name is within the bounds of the structure.
+  if (NewPolicy->Size != NewPolicy->OffsetToName) {
+    CheckChar = (CHAR16 *) ((UINTN) NewPolicy + NewPolicy->OffsetToName);
+    WildcardCount = 0;
+    while (*CheckChar != CHAR_NULL) {
+      // Make sure there aren't excessive wildcards.
+      if (*CheckChar == '#') {
+        WildcardCount++;
+        if (WildcardCount > MATCH_PRIORITY_MIN) {
+          return FALSE;
+        }
+      }
+      // Make sure you're still within the bounds of the policy structure.
+      if (EntryEnd <= (UINTN) CheckChar) {
+        return FALSE;
+      }
+      CheckChar++;
+    }
+
+    // Finally, we should be pointed at the very last character in Name, so we should be right
+    // up against the end of the structure.
+    if ((UINTN) ++CheckChar != EntryEnd) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+
+/**
+  This helper function evaluates a policy and determines whether it matches the target
+  variable. If matched, will also return a value corresponding to the priority of the match.
+
+  The rules for "best match" are listed in the Variable Policy Spec.
+  Perfect name matches will return 0.
+  Single wildcard characters will return the number of wildcard characters.
+  Full namespaces will return MAX_UINT8.
+
+  @param[in]  EvalEntry         Pointer to the policy entry being evaluated.
+  @param[in]  VariableName      Same as EFI_SET_VARIABLE.
+  @param[in]  VendorGuid        Same as EFI_SET_VARIABLE.
+  @param[out] MatchPriority     [Optional] On finding a match, this value contains the priority of the match.
+                                Lower number == higher priority. Only valid if a match found.
+
+  @retval     TRUE          Current entry matches the target variable.
+  @retval     FALSE         Current entry does not match at all.
+
+**/
+STATIC
+BOOLEAN
+EvaluatePolicyMatch (
+  IN CONST  VARIABLE_POLICY_ENTRY   *EvalEntry,
+  IN CONST  CHAR16                  *VariableName,
+  IN CONST  EFI_GUID                *VendorGuid,
+  OUT       UINT8                   *MatchPriority    OPTIONAL
+  )
+{
+  BOOLEAN     Result;
+  CHAR16      *PolicyName;
+  UINT8       CalculatedPriority;
+  UINTN       Index;
+
+  Result = FALSE;
+  CalculatedPriority = MATCH_PRIORITY_EXACT;
+
+  // Step 1: If the GUID doesn't match, we're done. No need to evaluate anything else.
+  if (!CompareGuid (&EvalEntry->Namespace, VendorGuid)) {
+    goto Exit;
+  }
+
+  // If the GUID matches, check to see whether there is a Name associated
+  // with the policy. If not, this policy matches the entire namespace.
+  // Missing Name is indicated by size being equal to name.
+  if (EvalEntry->Size == EvalEntry->OffsetToName) {
+    CalculatedPriority = MATCH_PRIORITY_MIN;
+    Result = TRUE;
+    goto Exit;
+  }
+
+  // Now that we know the name exists, get it.
+  PolicyName = GET_POLICY_NAME (EvalEntry);
+
+  // Evaluate the name against the policy name and check for a match.
+  // Account for any wildcards.
+  Index = 0;
+  Result = TRUE;
+  // Keep going until the end of both strings.
+  while (PolicyName[Index] != CHAR_NULL || VariableName[Index] != CHAR_NULL) {
+    // If we don't have a match...
+    if (PolicyName[Index] != VariableName[Index] || PolicyName[Index] == '#') {
+      // If this is a numerical wildcard, we can consider
+      // it a match if we alter the priority.
+      if (PolicyName[Index] == L'#' &&
+          (L'0' <= VariableName[Index] && VariableName[Index] <= L'9')) {
+        if (CalculatedPriority < MATCH_PRIORITY_MIN) {
+          CalculatedPriority++;
+        }
+      } else {
+        // Otherwise, not a match.
+        Result = FALSE;
+        goto Exit;
+      }
+    }
+    Index++;
+  }
+
+Exit:
+  if (Result && MatchPriority != NULL) {
+    *MatchPriority = CalculatedPriority;
+  }
+  return Result;
+}
+
+
+/**
+  This helper function walks the current policy table and returns a pointer
+  to the best match, if any are found. Leverages EvaluatePolicyMatch() to
+  determine "best".
+
+  @param[in]  VariableName       Same as EFI_SET_VARIABLE.
+  @param[in]  VendorGuid         Same as EFI_SET_VARIABLE.
+  @param[out] ReturnPriority     [Optional] If pointer is provided, return the
+                                 priority of the match. Same as EvaluatePolicyMatch().
+                                 Only valid if a match is returned.
+
+  @retval     VARIABLE_POLICY_ENTRY*    Best match that was found.
+  @retval     NULL                      No match was found.
+
+**/
+STATIC
+VARIABLE_POLICY_ENTRY*
+GetBestPolicyMatch (
+  IN CONST  CHAR16            *VariableName,
+  IN CONST  EFI_GUID          *VendorGuid,
+  OUT       UINT8             *ReturnPriority  OPTIONAL
+  )
+{
+  VARIABLE_POLICY_ENTRY   *BestResult;
+  VARIABLE_POLICY_ENTRY   *CurrentEntry;
+  UINT8                   MatchPriority;
+  UINT8                   CurrentPriority;
+  UINTN                   Index;
+
+  BestResult = NULL;
+
+  // Walk all entries in the table, looking for matches.
+  CurrentEntry = (VARIABLE_POLICY_ENTRY *) mPolicyTable;
+  for (Index = 0; Index < mCurrentTableCount; Index++) {
+    // Check for a match.
+    if (EvaluatePolicyMatch (CurrentEntry, VariableName, VendorGuid, &CurrentPriority)) {
+      // If match is better, take it.
+      if (BestResult == NULL || CurrentPriority < MatchPriority) {
+        BestResult = CurrentEntry;
+        MatchPriority = CurrentPriority;
+      }
+
+      // If you've hit the highest-priority match, can exit now.
+      if (MatchPriority == 0) {
+        break;
+      }
+    }
+
+    // If we're still in the loop, move to the next entry.
+    CurrentEntry = GET_NEXT_POLICY (CurrentEntry);
+  }
+
+  // If a return priority was requested, return it.
+  if (ReturnPriority != NULL) {
+    *ReturnPriority = MatchPriority;
+  }
+
+  return BestResult;
+}
+
+
+/**
+  This API function validates and registers a new policy with
+  the policy enforcement engine.
+
+  @param[in]  NewPolicy     Pointer to the incoming policy structure.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_INVALID_PARAMETER   NewPolicy is NULL or is internally inconsistent.
+  @retval     EFI_ALREADY_STARTED     An identical matching policy already exists.
+  @retval     EFI_WRITE_PROTECTED     The interface has been locked until the next reboot.
+  @retval     EFI_UNSUPPORTED         Policy enforcement has been disabled. No reason to add more policies.
+  @retval     EFI_ABORTED             A calculation error has prevented this function from completing.
+  @retval     EFI_OUT_OF_RESOURCES    Cannot grow the table to hold any more policies.
+  @retval     EFI_NOT_READY           Library has not yet been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterVariablePolicy (
+  IN CONST VARIABLE_POLICY_ENTRY    *NewPolicy
+  )
+{
+  EFI_STATUS                Status;
+  VARIABLE_POLICY_ENTRY     *MatchPolicy;
+  UINT8                     MatchPriority;
+  UINT32                    NewSize;
+  UINT8                     *NewTable;
+
+  if (!IsVariablePolicyLibInitialized ()) {
+    return EFI_NOT_READY;
+  }
+  if (mInterfaceLocked) {
+    return EFI_WRITE_PROTECTED;
+  }
+
+  if (!IsValidVariablePolicyStructure (NewPolicy)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Check to see whether an exact matching policy already exists.
+  MatchPolicy = GetBestPolicyMatch (
+                  GET_POLICY_NAME (NewPolicy),
+                  &NewPolicy->Namespace,
+                  &MatchPriority
+                  );
+  if (MatchPolicy != NULL && MatchPriority == MATCH_PRIORITY_EXACT) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  // If none exists, create it.
+  // If we need more space, allocate that now.
+  Status = SafeUint32Add (mCurrentTableUsage, NewPolicy->Size, &NewSize);
+  if (EFI_ERROR (Status)) {
+    return EFI_ABORTED;
+  }
+  if (NewSize > mCurrentTableSize) {
+    // Use NewSize to calculate the new table size in units of POLICY_TABLE_STEP_SIZE.
+    NewSize = (
+                NewSize % POLICY_TABLE_STEP_SIZE) > 0 ?
+                (NewSize / POLICY_TABLE_STEP_SIZE) + 1 :
+                (NewSize / POLICY_TABLE_STEP_SIZE
+                );
+
+    // Calculate the new table size in absolute bytes.
+    Status = SafeUint32Mult (NewSize, POLICY_TABLE_STEP_SIZE, &NewSize);
+    if (EFI_ERROR (Status)) {
+      return EFI_ABORTED;
+    }
+
+    // Reallocate and copy the table.
+    NewTable = AllocatePool (NewSize);
+    if (NewTable == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    CopyMem (NewTable, mPolicyTable, mCurrentTableUsage);
+    mCurrentTableSize = NewSize;
+    if (mPolicyTable != NULL) {
+      FreePool (mPolicyTable);
+    }
+    mPolicyTable = NewTable;
+  }
+
+  // Copy the policy into the table.
+  CopyMem (mPolicyTable + mCurrentTableUsage, NewPolicy, NewPolicy->Size);
+  mCurrentTableUsage += NewPolicy->Size;
+  mCurrentTableCount += 1;
+
+  // We're done here.
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This API function checks to see whether the parameters to SetVariable would
+  be allowed according to the current variable policies.
+
+  @param[in]  VariableName       Same as EFI_SET_VARIABLE.
+  @param[in]  VendorGuid         Same as EFI_SET_VARIABLE.
+  @param[in]  Attributes         Same as EFI_SET_VARIABLE.
+  @param[in]  DataSize           Same as EFI_SET_VARIABLE.
+  @param[in]  Data               Same as EFI_SET_VARIABLE.
+
+  @retval     EFI_SUCCESS             A matching policy allows this update.
+  @retval     EFI_SUCCESS             There are currently no policies that restrict this update.
+  @retval     EFI_SUCCESS             The protections have been disable until the next reboot.
+  @retval     EFI_WRITE_PROTECTED     Variable is currently locked.
+  @retval     EFI_INVALID_PARAMETER   Attributes or size are invalid.
+  @retval     EFI_ABORTED             A lock policy exists, but an error prevented evaluation.
+  @retval     EFI_NOT_READY           Library has not been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+ValidateSetVariable (
+  IN  CHAR16                       *VariableName,
+  IN  EFI_GUID                     *VendorGuid,
+  IN  UINT32                       Attributes,
+  IN  UINTN                        DataSize,
+  IN  VOID                         *Data
+  )
+{
+  BOOLEAN                             IsDel;
+  VARIABLE_POLICY_ENTRY               *ActivePolicy;
+  EFI_STATUS                          Status;
+  EFI_STATUS                          ReturnStatus;
+  VARIABLE_LOCK_ON_VAR_STATE_POLICY   *StateVarPolicy;
+  CHAR16                              *StateVarName;
+  UINTN                               StateVarSize;
+  UINT8                               StateVar;
+
+  ReturnStatus = EFI_SUCCESS;
+
+  if (!IsVariablePolicyLibInitialized ()) {
+    ReturnStatus = EFI_NOT_READY;
+    goto Exit;
+  }
+
+  // Bail if the protections are currently disabled.
+  if (mProtectionDisabled) {
+    ReturnStatus = EFI_SUCCESS;
+    goto Exit;
+  }
+
+  // Determine whether this is a delete operation.
+  // If so, it will affect which tests are applied.
+  if ((DataSize == 0) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {
+    IsDel = TRUE;
+  }
+  else {
+    IsDel = FALSE;
+  }
+
+  // Find an active policy if one exists.
+  ActivePolicy = GetBestPolicyMatch (VariableName, VendorGuid, NULL);
+
+  // If we have an active policy, check it against the incoming data.
+  if (ActivePolicy != NULL) {
+    //
+    // Only enforce size and attribute constraints when updating data, not deleting.
+    if (!IsDel) {
+      // Check for size constraints.
+      if ((ActivePolicy->MinSize > 0 && DataSize < ActivePolicy->MinSize) ||
+          (ActivePolicy->MaxSize > 0 && DataSize > ActivePolicy->MaxSize)) {
+        ReturnStatus = EFI_INVALID_PARAMETER;
+        DEBUG ((
+          DEBUG_VERBOSE,
+          "%a - Bad Size. 0x%X <> 0x%X-0x%X\n",
+          __FUNCTION__,
+          DataSize,
+          ActivePolicy->MinSize,
+          ActivePolicy->MaxSize
+          ));
+        goto Exit;
+      }
+
+      // Check for attribute constraints.
+      if ((ActivePolicy->AttributesMustHave & Attributes) != ActivePolicy->AttributesMustHave ||
+          (ActivePolicy->AttributesCantHave & Attributes) != 0) {
+        ReturnStatus = EFI_INVALID_PARAMETER;
+        DEBUG ((
+          DEBUG_VERBOSE,
+          "%a - Bad Attributes. 0x%X <> 0x%X:0x%X\n",
+          __FUNCTION__,
+          Attributes,
+          ActivePolicy->AttributesMustHave,
+          ActivePolicy->AttributesCantHave
+          ));
+        goto Exit;
+      }
+    }
+
+    //
+    // Lock policy check.
+    //
+    if (ActivePolicy->LockPolicyType == VARIABLE_POLICY_TYPE_LOCK_NOW) {
+      ReturnStatus = EFI_WRITE_PROTECTED;
+      goto Exit;
+    } else if (ActivePolicy->LockPolicyType == VARIABLE_POLICY_TYPE_LOCK_ON_CREATE) {
+      StateVarSize = 0;
+      Status =  mGetVariableHelper (
+                  VariableName,
+                  VendorGuid,
+                  NULL,
+                  &StateVarSize,
+                  NULL
+                  );
+      if (Status == EFI_BUFFER_TOO_SMALL) {
+        ReturnStatus = EFI_WRITE_PROTECTED;
+        goto Exit;
+      }
+    } else if (ActivePolicy->LockPolicyType == VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE) {
+      StateVarPolicy = (VARIABLE_LOCK_ON_VAR_STATE_POLICY *) ((UINT8 *) ActivePolicy + sizeof (VARIABLE_POLICY_ENTRY));
+      StateVarName = (CHAR16 *) ((UINT8 *) StateVarPolicy + sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY));
+      StateVarSize = sizeof (StateVar);
+      Status =  mGetVariableHelper (
+                  StateVarName,
+                  &StateVarPolicy->Namespace,
+                  NULL,
+                  &StateVarSize,
+                  &StateVar
+                  );
+
+      // If the variable was found, check the state. If matched, this variable is locked.
+      if (!EFI_ERROR (Status)) {
+        if (StateVar == StateVarPolicy->Value) {
+          ReturnStatus = EFI_WRITE_PROTECTED;
+          goto Exit;
+        }
+      } else if (Status != EFI_NOT_FOUND && Status != EFI_BUFFER_TOO_SMALL) {
+        // EFI_NOT_FOUND and EFI_BUFFER_TOO_SMALL indicate that the state doesn't match.
+        // We don't know what happened, but it isn't good.
+        ReturnStatus = EFI_ABORTED;
+        goto Exit;
+      }
+    }
+  }
+
+Exit:
+  DEBUG ((DEBUG_VERBOSE, "%a - Variable (%g:%s) returning %r.\n", __FUNCTION__, VendorGuid, VariableName, ReturnStatus));
+  return ReturnStatus;
+}
+
+
+/**
+  This API function disables the variable policy enforcement. If it's
+  already been called once, will return EFI_ALREADY_STARTED.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_ALREADY_STARTED   Has already been called once this boot.
+  @retval     EFI_WRITE_PROTECTED   Interface has been locked until reboot.
+  @retval     EFI_WRITE_PROTECTED   Interface option is disabled by platform PCD.
+  @retval     EFI_NOT_READY         Library has not yet been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableVariablePolicy (
+  VOID
+  )
+{
+  if (!IsVariablePolicyLibInitialized ()) {
+    return EFI_NOT_READY;
+  }
+  if (mProtectionDisabled) {
+    return EFI_ALREADY_STARTED;
+  }
+  if (mInterfaceLocked) {
+    return EFI_WRITE_PROTECTED;
+  }
+  if (!PcdGetBool (PcdAllowVariablePolicyEnforcementDisable)) {
+    return EFI_WRITE_PROTECTED;
+  }
+  mProtectionDisabled = TRUE;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This API function will dump the entire contents of the variable policy table.
+
+  Similar to GetVariable, the first call can be made with a 0 size and it will return
+  the size of the buffer required to hold the entire table.
+
+  @param[out]     Policy  Pointer to the policy buffer. Can be NULL if Size is 0.
+  @param[in,out]  Size    On input, the size of the output buffer. On output, the size
+                          of the data returned.
+
+  @retval     EFI_SUCCESS             Policy data is in the output buffer and Size has been updated.
+  @retval     EFI_INVALID_PARAMETER   Size is NULL, or Size is non-zero and Policy is NULL.
+  @retval     EFI_BUFFER_TOO_SMALL    Size is insufficient to hold policy. Size updated with required size.
+  @retval     EFI_NOT_READY           Library has not yet been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+DumpVariablePolicy (
+  OUT     UINT8         *Policy,
+  IN OUT  UINT32        *Size
+  )
+{
+  if (!IsVariablePolicyLibInitialized ()) {
+    return EFI_NOT_READY;
+  }
+
+  // Check the parameters.
+  if (Size == NULL || (*Size > 0 && Policy == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Make sure the size is sufficient to hold the policy table.
+  if (*Size < mCurrentTableUsage) {
+    *Size = mCurrentTableUsage;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  // If we're still here, copy the table and bounce.
+  CopyMem (Policy, mPolicyTable, mCurrentTableUsage);
+  *Size = mCurrentTableUsage;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This API function returns whether or not the policy engine is
+  currently being enforced.
+
+  @retval     TRUE
+  @retval     FALSE
+  @retval     FALSE         Library has not yet been initialized.
+
+**/
+BOOLEAN
+EFIAPI
+IsVariablePolicyEnabled (
+  VOID
+  )
+{
+  if (!IsVariablePolicyLibInitialized ()) {
+    return FALSE;
+  }
+  return !mProtectionDisabled;
+}
+
+
+/**
+  This API function locks the interface so that no more policy updates
+  can be performed or changes made to the enforcement until the next boot.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_NOT_READY   Library has not yet been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+LockVariablePolicy (
+  VOID
+  )
+{
+  if (!IsVariablePolicyLibInitialized ()) {
+    return EFI_NOT_READY;
+  }
+  if (mInterfaceLocked) {
+    return EFI_WRITE_PROTECTED;
+  }
+  mInterfaceLocked = TRUE;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This API function returns whether or not the policy interface is locked
+  for the remainder of the boot.
+
+  @retval     TRUE
+  @retval     FALSE
+  @retval     FALSE         Library has not yet been initialized.
+
+**/
+BOOLEAN
+EFIAPI
+IsVariablePolicyInterfaceLocked (
+  VOID
+  )
+{
+  if (!IsVariablePolicyLibInitialized ()) {
+    return FALSE;
+  }
+  return mInterfaceLocked;
+}
+
+
+/**
+  This helper function initializes the library and sets
+  up any required internal structures or handlers.
+
+  Also registers the internal pointer for the GetVariable helper.
+
+  @param[in]  GetVariableHelper A function pointer matching the EFI_GET_VARIABLE prototype that will be used to
+                  check policy criteria that involve the existence of other variables.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_ALREADY_STARTED   The initialize function has been called more than once without a call to
+                                    deinitialize.
+
+**/
+EFI_STATUS
+EFIAPI
+InitVariablePolicyLib (
+  IN  EFI_GET_VARIABLE    GetVariableHelper
+  )
+{
+  EFI_STATUS    Status;
+
+  if (mGetVariableHelper != NULL) {
+    Status = EFI_ALREADY_STARTED;
+  }
+
+  if (!EFI_ERROR (Status)) {
+    Status = VariablePolicyExtraInit ();
+  }
+
+  if (!EFI_ERROR (Status)) {
+    // Save an internal pointer to the GetVariableHelper.
+    mGetVariableHelper = GetVariableHelper;
+
+    // Initialize the global state.
+    mInterfaceLocked = FALSE;
+    mProtectionDisabled = FALSE;
+    mPolicyTable = NULL;
+    mCurrentTableSize = 0;
+    mCurrentTableUsage = 0;
+    mCurrentTableCount = 0;
+  }
+
+  return Status;
+}
+
+
+/**
+  This helper function returns whether or not the library is currently initialized.
+
+  @retval     TRUE
+  @retval     FALSE
+
+**/
+BOOLEAN
+EFIAPI
+IsVariablePolicyLibInitialized (
+  VOID
+  )
+{
+  return (mGetVariableHelper != NULL);
+}
+
+
+/**
+  This helper function tears down  the library.
+
+  Should generally only be used for test harnesses.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_NOT_READY     Deinitialize was called without first calling initialize.
+
+**/
+EFI_STATUS
+EFIAPI
+DeinitVariablePolicyLib (
+  VOID
+  )
+{
+  EFI_STATUS    Status;
+
+  if (mGetVariableHelper == NULL) {
+    Status = EFI_NOT_READY;
+  }
+
+  if (!EFI_ERROR (Status)) {
+    Status = VariablePolicyExtraDeinit ();
+  }
+
+  if (!EFI_ERROR (Status)) {
+    mGetVariableHelper = NULL;
+    mInterfaceLocked = FALSE;
+    mProtectionDisabled = FALSE;
+    mCurrentTableSize = 0;
+    mCurrentTableUsage = 0;
+    mCurrentTableCount = 0;
+
+    if (mPolicyTable != NULL) {
+      FreePool (mPolicyTable);
+      mPolicyTable = NULL;
+    }
+  }
+
+  return Status;
+}
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.c
new file mode 100644
index 000000000000..9f1122d94e91
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.c
@@ -0,0 +1,2533 @@
+/** @file -- VariablePolicyUnitTest.c
+UnitTest for...
+Business logic for Variable Policy enforcement.
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <Uefi.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UnitTestLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+
+#include <Guid/VariableFormat.h>
+
+#include <Protocol/VariablePolicy.h>
+#include <Library/VariablePolicyLib.h>
+
+// MU_CHANGE - Turn this off for now. Try to turn it back on with extra build options.
+// #ifndef INTERNAL_UNIT_TEST
+// #error Make sure to build thie with INTERNAL_UNIT_TEST enabled! Otherwise, some important tests may be skipped!
+// #endif
+
+
+#define UNIT_TEST_NAME        "UEFI Variable Policy UnitTest"
+#define UNIT_TEST_VERSION     "0.5"
+
+///=== TEST DATA ==================================================================================
+
+#pragma pack(push, 1)
+typedef struct _SIMPLE_VARIABLE_POLICY_ENTRY {
+  VARIABLE_POLICY_ENTRY     Header;
+  CHAR16                    Name[];
+} SIMPLE_VARIABLE_POLICY_ENTRY;
+#define EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_LENGTH  1001    // 1000 characters + terminator.
+#define EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_SIZE    (EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_LENGTH * sizeof (CHAR16))
+typedef struct _EXPANDED_VARIABLE_POLICY_ENTRY {
+  VARIABLE_POLICY_ENTRY               Header;
+  VARIABLE_LOCK_ON_VAR_STATE_POLICY   StatePolicy;
+  CHAR16                              StateName[EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_LENGTH];
+  CHAR16                              Name[EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_LENGTH];
+} EXPANDED_VARIABLE_POLICY_ENTRY;
+#pragma pack(pop)
+
+// {F955BA2D-4A2C-480C-BFD1-3CC522610592}
+#define TEST_GUID_1 { 0xf955ba2d, 0x4a2c, 0x480c, { 0xbf, 0xd1, 0x3c, 0xc5, 0x22, 0x61, 0x5, 0x92 } }
+EFI_GUID    mTestGuid1 = TEST_GUID_1;
+// {2DEA799E-5E73-43B9-870E-C945CE82AF3A}
+#define TEST_GUID_2 { 0x2dea799e, 0x5e73, 0x43b9, { 0x87, 0xe, 0xc9, 0x45, 0xce, 0x82, 0xaf, 0x3a } }
+EFI_GUID    mTestGuid2 = TEST_GUID_2;
+// {698A2BFD-A616-482D-B88C-7100BD6682A9}
+#define TEST_GUID_3 { 0x698a2bfd, 0xa616, 0x482d, { 0xb8, 0x8c, 0x71, 0x0, 0xbd, 0x66, 0x82, 0xa9 } }
+EFI_GUID    mTestGuid3 = TEST_GUID_3;
+
+#define   TEST_VAR_1_NAME                 L"TestVar1"
+#define   TEST_VAR_2_NAME                 L"TestVar2"
+#define   TEST_VAR_3_NAME                 L"TestVar3"
+
+#define   TEST_POLICY_ATTRIBUTES_NULL     0
+#define   TEST_POLICY_MIN_SIZE_NULL       0
+#define   TEST_POLICY_MAX_SIZE_NULL       MAX_UINT32
+
+#define   TEST_POLICY_MIN_SIZE_10         10
+#define   TEST_POLICY_MAX_SIZE_200        200
+
+#define TEST_300_HASHES_STRING      L"##################################################"\
+                                      "##################################################"\
+                                      "##################################################"\
+                                      "##################################################"\
+                                      "##################################################"\
+                                      "##################################################"
+
+
+///=== HELPER FUNCTIONS ===========================================================================
+
+/**
+  Helper function to initialize a VARIABLE_POLICY_ENTRY structure with a Name and StateName.
+
+  Takes care of all the messy packing.
+
+  @param[in,out]  Entry
+  @param[in]      Name        [Optional]
+  @param[in]      StateName   [Optional]
+
+  @retval     TRUE
+  @retval     FALSE
+
+**/
+STATIC
+BOOLEAN
+InitExpVarPolicyStrings (
+  EXPANDED_VARIABLE_POLICY_ENTRY      *Entry,
+  CHAR16                              *Name,      OPTIONAL
+  CHAR16                              *StateName  OPTIONAL
+  )
+{
+  UINTN     NameSize;
+  UINTN     StateNameSize;
+
+  NameSize = Name == NULL ? 0 : StrSize (Name);
+  StateNameSize = StateName == NULL ? 0 : StrSize (StateName);
+
+  if (NameSize > EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_SIZE || NameSize > MAX_UINT16 ||
+      StateNameSize > EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_SIZE || StateNameSize > MAX_UINT16) {
+    return FALSE;
+  }
+
+  Entry->Header.OffsetToName = sizeof (VARIABLE_POLICY_ENTRY);
+  if (StateName != NULL) {
+    Entry->Header.OffsetToName += (UINT16) sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY) + (UINT16) StateNameSize;
+  }
+  Entry->Header.Size = Entry->Header.OffsetToName + (UINT16) NameSize;
+
+  CopyMem ((UINT8 *) Entry + Entry->Header.OffsetToName, Name, NameSize);
+  if (StateName != NULL) {
+    CopyMem (
+      (UINT8 *) Entry + sizeof (VARIABLE_POLICY_ENTRY) + sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY),
+      StateName,
+      StateNameSize
+     );
+  }
+
+  return TRUE;
+}
+
+/**
+  Mocked version of GetVariable, for testing.
+**/
+EFI_STATUS
+EFIAPI
+StubGetVariableNull (
+  IN     CHAR16                      *VariableName,
+  IN     EFI_GUID                    *VendorGuid,
+  OUT    UINT32                      *Attributes,    OPTIONAL
+  IN OUT UINTN                       *DataSize,
+  OUT    VOID                        *Data           OPTIONAL
+  )
+{
+  UINT32      MockedAttr;
+  UINTN       MockedDataSize;
+  VOID        *MockedData;
+  EFI_STATUS  MockedReturn;
+
+  check_expected_ptr (VariableName);
+  check_expected_ptr (VendorGuid);
+  check_expected_ptr (DataSize);
+
+  MockedAttr = (UINT32) mock ();
+  MockedDataSize = (UINTN) mock ();
+  MockedData = (VOID *) (UINTN) mock ();
+  MockedReturn = (EFI_STATUS) mock ();
+
+  if (Attributes != NULL) {
+    *Attributes = MockedAttr;
+  }
+  if (Data != NULL && !EFI_ERROR (MockedReturn)) {
+    CopyMem (Data, MockedData, MockedDataSize);
+  }
+
+  *DataSize = MockedDataSize;
+
+  return MockedReturn;
+}
+
+//
+// Anything you think might be helpful that isn't a test itself.
+//
+
+/**
+  This is a common setup function that will ensure the library is always initialized
+  with the stubbed GetVariable.
+
+  Not used by all test cases, but by most.
+**/
+STATIC
+UNIT_TEST_STATUS
+LibInitMocked (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  return EFI_ERROR (InitVariablePolicyLib (StubGetVariableNull)) ? UNIT_TEST_ERROR_PREREQUISITE_NOT_MET : UNIT_TEST_PASSED;
+}
+
+/**
+  Common cleanup function to make sure that the library is always de-initialized prior
+  to the next test case.
+*/
+STATIC
+VOID
+LibCleanup (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  DeinitVariablePolicyLib ();
+}
+
+
+///=== TEST CASES =================================================================================
+
+///===== ARCHITECTURAL SUITE ==================================================
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldBeAbleToInitAndDeinitTheLibrary (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EFI_STATUS    Status;
+  Status = InitVariablePolicyLib (StubGetVariableNull);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  UT_ASSERT_TRUE (IsVariablePolicyLibInitialized ());
+
+  Status = DeinitVariablePolicyLib ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  UT_ASSERT_FALSE (IsVariablePolicyLibInitialized ());
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldNotBeAbleToInitializeTheLibraryTwice (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EFI_STATUS    Status;
+  Status = InitVariablePolicyLib (StubGetVariableNull);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  Status = InitVariablePolicyLib (StubGetVariableNull);
+  UT_ASSERT_TRUE (EFI_ERROR (Status));
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldFailDeinitWithoutInit (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EFI_STATUS    Status;
+  Status = DeinitVariablePolicyLib ();
+  UT_ASSERT_TRUE (EFI_ERROR (Status));
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ApiCommandsShouldNotRespondIfLibIsUninitialized (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   TestPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  UINT8     DummyData[8];
+  UINT32    DummyDataSize = sizeof (DummyData);
+
+  // This test should not start with an initialized library.
+
+  // Verify that all API commands fail.
+  UT_ASSERT_TRUE (EFI_ERROR (LockVariablePolicy ()));
+  UT_ASSERT_TRUE (EFI_ERROR (DisableVariablePolicy ()));
+  UT_ASSERT_TRUE (EFI_ERROR (RegisterVariablePolicy (&TestPolicy.Header)));
+  UT_ASSERT_TRUE (EFI_ERROR (DumpVariablePolicy (DummyData, &DummyDataSize)));
+  UT_ASSERT_FALSE (IsVariablePolicyInterfaceLocked ());
+  UT_ASSERT_FALSE (IsVariablePolicyEnabled ());
+  UT_ASSERT_TRUE (
+    EFI_ERROR (ValidateSetVariable (TEST_VAR_1_NAME, &mTestGuid1, VARIABLE_ATTRIBUTE_NV_BS, sizeof (DummyData), DummyData))
+    );
+
+  return UNIT_TEST_PASSED;
+}
+
+
+///===== INTERNAL FUNCTION SUITE ==============================================
+
+#ifdef INTERNAL_UNIT_TEST
+
+BOOLEAN
+EvaluatePolicyMatch (
+  IN CONST  VARIABLE_POLICY_ENTRY   *EvalEntry,
+  IN CONST  CHAR16                  *VariableName,
+  IN CONST  EFI_GUID                *VendorGuid,
+  OUT       UINT8                   *MatchPriority    OPTIONAL
+  );
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+PoliciesShouldMatchByNameAndGuid (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   MatchCheckPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  CHAR16        *CheckVar1Name = TEST_VAR_1_NAME;
+  CHAR16        *CheckVar2Name = TEST_VAR_2_NAME;
+
+  // Make sure that a different name does not match.
+  UT_ASSERT_FALSE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar2Name, &mTestGuid1, NULL));
+
+  // Make sure that a different GUID does not match.
+  UT_ASSERT_FALSE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar1Name, &mTestGuid2, NULL));
+
+  // Make sure that the same name and GUID match.
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar1Name, &mTestGuid1, NULL));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+WildcardPoliciesShouldMatchDigits (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   MatchCheckPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (L"Wildcard#VarName##"),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    L"Wildcard#VarName##"
+  };
+  CHAR16        *CheckVar1Name = L"Wildcard1VarName12";
+  CHAR16        *CheckVar2Name = L"Wildcard2VarName34";
+  CHAR16        *CheckVarBName = L"WildcardBVarName56";
+  CHAR16        *CheckVarHName = L"Wildcard#VarName56";
+
+  // Make sure that two different sets of wildcard numbers match.
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar1Name, &mTestGuid1, NULL));
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar2Name, &mTestGuid1, NULL));
+
+  // Make sure that the non-number charaters don't match.
+  UT_ASSERT_FALSE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVarBName, &mTestGuid1, NULL));
+
+  // Make sure that '#' signs don't match.
+  UT_ASSERT_FALSE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVarHName, &mTestGuid1, NULL));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+WildcardPoliciesShouldMatchDigitsAdvanced (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   MatchCheckPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_300_HASHES_STRING),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_300_HASHES_STRING
+  };
+  CHAR16        *CheckShorterString = L"01234567890123456789012345678901234567890123456789";
+  CHAR16        *CheckValidString = L"01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789";
+  CHAR16        *CheckLongerString = L"01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789"\
+                                      "01234567890123456789012345678901234567890123456789";
+  UINT8         MatchPriority;
+
+  // Make sure that the shorter and the longer do not match.
+  UT_ASSERT_FALSE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckShorterString, &mTestGuid1, NULL));
+  UT_ASSERT_FALSE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckLongerString, &mTestGuid1, NULL));
+
+  // Make sure that the valid one matches and has the expected priority.
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckValidString, &mTestGuid1, &MatchPriority));
+  UT_ASSERT_EQUAL (MatchPriority, MAX_UINT8);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+WildcardPoliciesShouldMatchNamespaces (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  VARIABLE_POLICY_ENTRY   MatchCheckPolicy = {
+    VARIABLE_POLICY_ENTRY_REVISION,
+    sizeof (VARIABLE_POLICY_ENTRY),
+    sizeof (VARIABLE_POLICY_ENTRY),
+    TEST_GUID_1,
+    TEST_POLICY_MIN_SIZE_NULL,
+    TEST_POLICY_MAX_SIZE_NULL,
+    TEST_POLICY_ATTRIBUTES_NULL,
+    TEST_POLICY_ATTRIBUTES_NULL,
+    VARIABLE_POLICY_TYPE_NO_LOCK
+  };
+  CHAR16        *CheckVar1Name = L"Wildcard1VarName12";
+  CHAR16        *CheckVar2Name = L"Wildcard2VarName34";
+  CHAR16        *CheckVarBName = L"WildcardBVarName56";
+  CHAR16        *CheckVarHName = L"Wildcard#VarName56";
+
+  // Make sure that all names in the same namespace match.
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy, CheckVar1Name, &mTestGuid1, NULL));
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy, CheckVar2Name, &mTestGuid1, NULL));
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy, CheckVarBName, &mTestGuid1, NULL));
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy, CheckVarHName, &mTestGuid1, NULL));
+
+  // Make sure that different namespace doesn't match.
+  UT_ASSERT_FALSE (EvaluatePolicyMatch (&MatchCheckPolicy, CheckVar1Name, &mTestGuid2, NULL));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+MatchPrioritiesShouldFollowRules (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   MatchCheckPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (L"Wildcard1VarName12"),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    L"Wildcard1VarName12"
+  };
+  CHAR16        CheckVar1Name[] = L"Wildcard1VarName12";
+  CHAR16        MatchVar1Name[] = L"Wildcard1VarName12";
+  CHAR16        MatchVar2Name[] = L"Wildcard#VarName12";
+  CHAR16        MatchVar3Name[] = L"Wildcard#VarName#2";
+  CHAR16        MatchVar4Name[] = L"Wildcard#VarName##";
+  UINT8         MatchPriority;
+
+  // Check with a perfect match.
+  CopyMem (&MatchCheckPolicy.Name, MatchVar1Name, sizeof (MatchVar1Name));
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar1Name, &mTestGuid1, &MatchPriority));
+  UT_ASSERT_EQUAL (MatchPriority, 0);
+
+  // Check with progressively lower priority matches.
+  CopyMem (&MatchCheckPolicy.Name, MatchVar2Name, sizeof (MatchVar2Name));
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar1Name, &mTestGuid1, &MatchPriority));
+  UT_ASSERT_EQUAL (MatchPriority, 1);
+  CopyMem (&MatchCheckPolicy.Name, MatchVar3Name, sizeof (MatchVar3Name));
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar1Name, &mTestGuid1, &MatchPriority));
+  UT_ASSERT_EQUAL (MatchPriority, 2);
+  CopyMem (&MatchCheckPolicy.Name, MatchVar4Name, sizeof (MatchVar4Name));
+  UT_ASSERT_TRUE (EvaluatePolicyMatch (&MatchCheckPolicy.Header, CheckVar1Name, &mTestGuid1, &MatchPriority));
+  UT_ASSERT_EQUAL (MatchPriority, 3);
+
+  // Check against the entire namespace.
+  MatchCheckPolicy.Header.Size = sizeof (VARIABLE_POLICY_ENTRY);
+  UT_ASSERT_TRUE (EvaluatePolicyMatch(&MatchCheckPolicy.Header, CheckVar1Name, &mTestGuid1, &MatchPriority));
+  UT_ASSERT_EQUAL (MatchPriority, MAX_UINT8);
+
+  return UNIT_TEST_PASSED;
+}
+
+#endif // INTERNAL_UNIT_TEST
+
+
+///=== POLICY MANIPULATION SUITE ==============================================
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldAllowNamespaceWildcards (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    L""
+  };
+
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldAllowStateVarsForNamespaces (
+  IN UNIT_TEST_CONTEXT      Context
+ )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      1,            // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, NULL, TEST_VAR_2_NAME));
+
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectNullPointers (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (NULL), EFI_INVALID_PARAMETER);
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectBadRevisions (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+
+  ValidationPolicy.Header.Version = MAX_UINT32;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectBadSizes (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+
+  ValidationPolicy.Header.Size = sizeof (VARIABLE_POLICY_ENTRY) - 2;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectBadOffsets (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      1,            // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, TEST_VAR_1_NAME, TEST_VAR_2_NAME));
+
+  // Check for an offset outside the size bounds.
+  ValidationPolicy.Header.OffsetToName = ValidationPolicy.Header.Size + 1;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  // Check for an offset inside the policy header.
+  ValidationPolicy.Header.OffsetToName = sizeof (VARIABLE_POLICY_ENTRY) - 2;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  // Check for an offset inside the state policy header.
+  ValidationPolicy.Header.OffsetToName = sizeof (VARIABLE_POLICY_ENTRY) + 2;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  // Check for a ridiculous offset.
+  ValidationPolicy.Header.OffsetToName = MAX_UINT16;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectMissingStateStrings (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      1,            // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, TEST_VAR_1_NAME, TEST_VAR_2_NAME));
+
+  // Remove the state string and copy the Name into it's place.
+  // Also adjust the offset.
+  ValidationPolicy.Header.Size          = sizeof (VARIABLE_POLICY_ENTRY) + sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY) + sizeof (TEST_VAR_1_NAME);
+  ValidationPolicy.Header.OffsetToName  = sizeof (VARIABLE_POLICY_ENTRY) + sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY);
+  CopyMem ((UINT8 *) &ValidationPolicy + ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME, sizeof (TEST_VAR_1_NAME));
+
+  // Make sure that this structure fails.
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectStringsMissingNull (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      1,            // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, TEST_VAR_1_NAME, TEST_VAR_2_NAME));
+
+  // Removing the NULL from the Name should fail.
+  ValidationPolicy.Header.Size = ValidationPolicy.Header.Size - sizeof (CHAR16);
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  // Removing the NULL from the State Name is a little trickier.
+  // Copy the Name up one byte.
+  ValidationPolicy.Header.OffsetToName = ValidationPolicy.Header.OffsetToName - sizeof (CHAR16);
+  CopyMem ((UINT8 *) &ValidationPolicy + ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME, sizeof (TEST_VAR_1_NAME));
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectMalformedStrings (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      1,            // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, TEST_VAR_1_NAME, TEST_VAR_2_NAME));
+
+  // Bisecting the NULL from the Name should fail.
+  ValidationPolicy.Header.Size = ValidationPolicy.Header.Size - 1;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  // Bisecting the NULL from the State Name is a little trickier.
+  // Copy the Name up one byte.
+  ValidationPolicy.Header.OffsetToName = ValidationPolicy.Header.OffsetToName - 1;
+  CopyMem ((UINT8 *) &ValidationPolicy + ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME, sizeof (TEST_VAR_1_NAME));
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectUnpackedPolicies (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      1,            // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, TEST_VAR_1_NAME, TEST_VAR_2_NAME));
+
+  // Increase the size and move the Name out a bit.
+  ValidationPolicy.Header.Size = ValidationPolicy.Header.Size + sizeof (CHAR16);
+  ValidationPolicy.Header.OffsetToName = ValidationPolicy.Header.OffsetToName + sizeof (CHAR16);
+  CopyMem ((UINT8 *) &ValidationPolicy + ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME, sizeof (TEST_VAR_1_NAME));
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  // Reintialize without the state policy and try the same test.
+  ValidationPolicy.Header.LockPolicyType = VARIABLE_POLICY_TYPE_NO_LOCK;
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, TEST_VAR_1_NAME, NULL));
+  ValidationPolicy.Header.Size = ValidationPolicy.Header.Size + sizeof (CHAR16);
+  ValidationPolicy.Header.OffsetToName = ValidationPolicy.Header.OffsetToName + sizeof (CHAR16);
+  CopyMem ((UINT8 *) &ValidationPolicy + ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME, sizeof (TEST_VAR_1_NAME));
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectInvalidNameCharacters (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  // EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+  //   {
+  //     VARIABLE_POLICY_ENTRY_REVISION,
+  //     0,    // Will be populated by init helper.
+  //     0,    // Will be populated by init helper.
+  //     TEST_GUID_1,
+  //     TEST_POLICY_MIN_SIZE_NULL,
+  //     TEST_POLICY_MAX_SIZE_NULL,
+  //     TEST_POLICY_ATTRIBUTES_NULL,
+  //     TEST_POLICY_ATTRIBUTES_NULL,
+  //     VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+  //   },
+  //   {
+  //     TEST_GUID_2,
+  //     1,            // Value
+  //     0             // Padding
+  //   },
+  //   L"",
+  //   L""
+  // };
+
+  // Currently, there are no known invalid characters.
+  // '#' in LockPolicy->Name are taken as literal.
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectBadPolicyConstraints (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+
+  // Make sure that invalid MAXes are rejected.
+  ValidationPolicy.Header.MaxSize = 0;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectUnknownLockPolicies (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+
+  ValidationPolicy.Header.LockPolicyType = VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE + 1;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+  ValidationPolicy.Header.LockPolicyType = VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE + 1;
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectPolicesWithTooManyWildcards (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_300_HASHES_STRING),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_300_HASHES_STRING
+  };
+
+  // 300 Hashes is currently larger than the possible maximum match priority.
+  UT_ASSERT_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+RegisterShouldRejectDuplicatePolicies (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+  UT_ASSERT_STATUS_EQUAL (RegisterVariablePolicy (&ValidationPolicy.Header), EFI_ALREADY_STARTED);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+MinAndMaxSizePoliciesShouldBeHonored (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_10,
+      TEST_POLICY_MAX_SIZE_200,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[TEST_POLICY_MAX_SIZE_200 + 1];
+
+
+  // Without a policy, there should be no constraints on variable creation.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS,
+                  TEST_POLICY_MAX_SIZE_200 + 1,
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Set a policy to test against.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // With a policy, make sure that sizes outsize the target range fail.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS,
+                  TEST_POLICY_MAX_SIZE_200 + 1,
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  // With a policy, make sure that sizes outsize the target range fail.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS,
+                  TEST_POLICY_MIN_SIZE_10 - 1,
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  // With a policy, make sure a valid variable is still valid.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS,
+                  TEST_POLICY_MIN_SIZE_10 + 1,
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+AttributeMustPoliciesShouldBeHonored (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      VARIABLE_ATTRIBUTE_NV_BS_RT,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[12];
+
+
+  // Without a policy, there should be no constraints on variable creation.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  TEST_POLICY_ATTRIBUTES_NULL,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Set a policy to test against.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // With a policy, make sure that no attributes fail.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  TEST_POLICY_ATTRIBUTES_NULL,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  // With a policy, make sure that some -- but not all -- attributes fail.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  // With a policy, make sure that all attributes pass.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS_RT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // With a policy, make sure that all attributes -- plus some -- pass.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+AttributeCantPoliciesShouldBeHonored (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[12];
+
+
+  // Without a policy, there should be no constraints on variable creation.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Set a policy to test against.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // With a policy, make sure that forbidden attributes fail.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  // With a policy, make sure that a mixture of attributes -- including the forbidden -- fail.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  // With a policy, make sure that attributes without the forbidden pass.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS_RT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+VariablesShouldBeDeletableRegardlessOfSize (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_10,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[TEST_POLICY_MAX_SIZE_200+1];
+
+  // Create a policy enforcing a minimum variable size.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // Make sure that a normal set would fail.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS,
+                  TEST_POLICY_MIN_SIZE_10-1,
+                  DummyData
+                  );
+  UT_ASSERT_STATUS_EQUAL (PolicyCheck, EFI_INVALID_PARAMETER);
+
+  // Now make sure that a delete would succeed.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS,
+                  0,
+                  NULL
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+LockNowPoliciesShouldBeHonored (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_NOW
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[12];
+
+
+  // Without a policy, there should be no constraints on variable creation.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Set a policy to test against.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // With a policy, make sure that writes immediately fail.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+LockOnCreatePoliciesShouldBeHonored (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_CREATE
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[12];
+  UINTN       ExpectedDataSize;
+
+
+  // Without a policy, there should be no constraints on variable creation.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Set a policy to test against.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // Set consistent expectations on what the calls are looking for.
+  expect_memory_count (StubGetVariableNull, VariableName, TEST_VAR_1_NAME, sizeof (TEST_VAR_1_NAME), 2);
+  expect_memory_count (StubGetVariableNull, VendorGuid, &mTestGuid1, sizeof (mTestGuid1), 2);
+  ExpectedDataSize = 0;
+  expect_memory_count (StubGetVariableNull, DataSize, &ExpectedDataSize, sizeof (ExpectedDataSize), 2);
+
+  // With a policy, make sure that writes still work, since the variable doesn't exist.
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 0);                              // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_NOT_FOUND);                  // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // With a policy, make sure that a call with an "existing" variable fails.
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 10);                             // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_BUFFER_TOO_SMALL);           // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+LockOnStatePoliciesShouldBeHonored (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      20,           // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[12];
+  UINT8       ValidationStateVar;
+  UINTN       ExpectedDataSize;
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, TEST_VAR_1_NAME, TEST_VAR_2_NAME));
+
+
+  // Without a policy, there should be no constraints on variable creation.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Set a policy to test against.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // Set consistent expectations on what the calls are looking for.
+  expect_memory_count (StubGetVariableNull, VariableName, TEST_VAR_2_NAME, sizeof (TEST_VAR_2_NAME), 5);
+  expect_memory_count (StubGetVariableNull, VendorGuid, &mTestGuid2, sizeof (mTestGuid2), 5);
+  ExpectedDataSize = 1;
+  expect_memory_count (StubGetVariableNull, DataSize, &ExpectedDataSize, sizeof (ExpectedDataSize), 5);
+
+  // With a policy, make sure that writes still work, since the variable doesn't exist.
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 0);                              // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_NOT_FOUND);                  // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // With a policy, make sure that a state variable that's too large doesn't lock the variable.
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 10);                             // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_BUFFER_TOO_SMALL);           // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // With a policy, check a state variable with the wrong value.
+  ValidationStateVar = 0;
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, sizeof (ValidationStateVar));     // Size
+  will_return (StubGetVariableNull, &ValidationStateVar);            // DataPtr
+  will_return (StubGetVariableNull, EFI_SUCCESS);                    // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // With a policy, check a state variable with another wrong value.
+  ValidationStateVar = 10;
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, sizeof (ValidationStateVar));     // Size
+  will_return (StubGetVariableNull, &ValidationStateVar);            // DataPtr
+  will_return (StubGetVariableNull, EFI_SUCCESS);                    // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // With a policy, make sure that a call with a correct state variable fails.
+  ValidationStateVar = 20;
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, sizeof (ValidationStateVar));     // Size
+  will_return (StubGetVariableNull, &ValidationStateVar);            // DataPtr
+  will_return (StubGetVariableNull, EFI_SUCCESS);                    // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+LockOnStatePoliciesShouldApplyToNamespaces (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      20,           // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[12];
+  UINT8       ValidationStateVar;
+  UINTN       ExpectedDataSize;
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, NULL, TEST_VAR_2_NAME));
+
+
+  // Without a policy, there should be no constraints on variable creation.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_3_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Set a policy to test against.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // Set consistent expectations on what the calls are looking for.
+  expect_memory_count (StubGetVariableNull, VariableName, TEST_VAR_2_NAME, sizeof (TEST_VAR_2_NAME), 4);
+  expect_memory_count (StubGetVariableNull, VendorGuid, &mTestGuid2, sizeof (mTestGuid2), 4);
+  ExpectedDataSize = 1;
+  expect_memory_count (StubGetVariableNull, DataSize, &ExpectedDataSize, sizeof (ExpectedDataSize), 4);
+
+  // With a policy, make sure that writes still work, since the variable doesn't exist.
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 0);                              // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_NOT_FOUND);                  // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 0);                              // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_NOT_FOUND);                  // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_3_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // With a policy, make sure that a call with a correct state variable fails.
+  ValidationStateVar = 20;
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, sizeof (ValidationStateVar));     // Size
+  will_return (StubGetVariableNull, &ValidationStateVar);            // DataPtr
+  will_return (StubGetVariableNull, EFI_SUCCESS);                    // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, sizeof (ValidationStateVar));     // Size
+  will_return (StubGetVariableNull, &ValidationStateVar);            // DataPtr
+  will_return (StubGetVariableNull, EFI_SUCCESS);                    // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_3_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+LockOnStateShouldHandleErrorsGracefully (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  EXPANDED_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      0,    // Will be populated by init helper.
+      0,    // Will be populated by init helper.
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
+    },
+    {
+      TEST_GUID_2,
+      20,           // Value
+      0             // Padding
+    },
+    L"",
+    L""
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[12];
+  UT_ASSERT_TRUE (InitExpVarPolicyStrings (&ValidationPolicy, TEST_VAR_1_NAME, TEST_VAR_2_NAME));
+
+
+  // Without a policy, there should be no constraints on variable creation.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Set a policy to test against.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // Configure the stub to not care about parameters. We're testing errors.
+  expect_any_always (StubGetVariableNull, VariableName);
+  expect_any_always (StubGetVariableNull, VendorGuid);
+  expect_any_always (StubGetVariableNull, DataSize);
+
+  // With a policy, make sure that writes still work, since the variable doesn't exist.
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 0);                              // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_NOT_FOUND);                  // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Verify that state variables that are the wrong size won't lock the variable.
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 0);                              // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_BUFFER_TOO_SMALL);           // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Verify that unexpected errors default to locked.
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 0);                              // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_UNSUPPORTED);                // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  will_return (StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL);    // Attributes
+  will_return (StubGetVariableNull, 0);                              // Size
+  will_return (StubGetVariableNull, NULL);                           // DataPtr
+  will_return (StubGetVariableNull, EFI_NOT_READY);                  // Status
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+BestMatchPriorityShouldBeObeyed (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   ValidationPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (L"Wild12Card34Placeholder"),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    L"Wild12Card34Placeholder"
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[70];
+  CHAR16      *PolicyName = (CHAR16 *) ((UINT8 *) &ValidationPolicy + sizeof (VARIABLE_POLICY_ENTRY));
+  UINTN       PolicyNameSize = sizeof (L"Wild12Card34Placeholder");
+  CHAR16      *FourWildcards = L"Wild##Card##Placeholder";
+  CHAR16      *ThreeWildcards = L"Wild##Card#4Placeholder";
+  CHAR16      *TwoWildcards = L"Wild##Card34Placeholder";
+  CHAR16      *OneWildcard = L"Wild#2Card34Placeholder";
+  CHAR16      *NoWildcards = L"Wild12Card34Placeholder";
+
+  // Create all of the policies from least restrictive to most restrictive.
+  // NoWildcards should be the most restrictive.
+  ValidationPolicy.Header.MaxSize = 60;
+  ValidationPolicy.Header.Size = ValidationPolicy.Header.OffsetToName;
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+  ValidationPolicy.Header.Size += (UINT16) PolicyNameSize;
+  ValidationPolicy.Header.MaxSize = 50;
+  CopyMem (PolicyName, FourWildcards, PolicyNameSize);
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+  ValidationPolicy.Header.MaxSize = 40;
+  CopyMem (PolicyName, ThreeWildcards, PolicyNameSize);
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+  ValidationPolicy.Header.MaxSize = 30;
+  CopyMem (PolicyName, TwoWildcards, PolicyNameSize);
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+  ValidationPolicy.Header.MaxSize = 20;
+  CopyMem (PolicyName, OneWildcard, PolicyNameSize);
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+  ValidationPolicy.Header.MaxSize = 10;
+  CopyMem (PolicyName, NoWildcards, PolicyNameSize);
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&ValidationPolicy.Header));
+
+  // Verify that variables only matching the namespace have the most flexible policy.
+  PolicyCheck = ValidateSetVariable (
+                  L"ArbitraryName",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  65,
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+  PolicyCheck = ValidateSetVariable (
+                  L"ArbitraryName",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  55,
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  // Verify that variables matching increasing characters get increasing policy restrictions.
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild77Card77Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  55,
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild77Card77Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  45,
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild77Card74Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  45,
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild77Card74Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  35,
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild77Card34Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  35,
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild77Card34Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  25,
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild72Card34Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  25,
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild72Card34Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  15,
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild12Card34Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  15,
+                  DummyData
+                  );
+  UT_ASSERT_TRUE (EFI_ERROR (PolicyCheck));
+  PolicyCheck = ValidateSetVariable (
+                  L"Wild12Card34Placeholder",
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_BS_RT_AT,
+                  5,
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  return UNIT_TEST_PASSED;
+}
+
+
+///=== POLICY UTILITY SUITE ===================================================
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldBeAbleToLockInterface (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   TestPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_NULL,
+      TEST_POLICY_MAX_SIZE_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+
+  // Make sure it's not already locked.
+  UT_ASSERT_FALSE (IsVariablePolicyInterfaceLocked ());
+  // Lock it.
+  UT_ASSERT_NOT_EFI_ERROR (LockVariablePolicy ());
+  // Verify that it's locked.
+  UT_ASSERT_TRUE (IsVariablePolicyInterfaceLocked ());
+
+  // Verify that all state-changing commands fail.
+  UT_ASSERT_TRUE (EFI_ERROR (LockVariablePolicy ()));
+  UT_ASSERT_TRUE (EFI_ERROR (DisableVariablePolicy ()));
+  UT_ASSERT_TRUE (EFI_ERROR (RegisterVariablePolicy (&TestPolicy.Header)));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldBeAbleToDisablePolicyEnforcement (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   TestPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_10,
+      TEST_POLICY_MAX_SIZE_200,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT8       DummyData[TEST_POLICY_MIN_SIZE_10-1];
+
+  // Make sure that the policy enforcement is currently enabled.
+  UT_ASSERT_TRUE (IsVariablePolicyEnabled ());
+  // Add a policy before it's disabled.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&TestPolicy.Header));
+  // Disable the policy enforcement.
+  UT_ASSERT_NOT_EFI_ERROR (DisableVariablePolicy ());
+  // Make sure that the policy enforcement is currently disabled.
+  UT_ASSERT_FALSE (IsVariablePolicyEnabled ());
+
+  // Check to make sure that a policy violation still passes.
+  PolicyCheck = ValidateSetVariable (
+                  TEST_VAR_1_NAME,
+                  &mTestGuid1,
+                  VARIABLE_ATTRIBUTE_NV_BS,
+                  sizeof (DummyData),
+                  DummyData
+                  );
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldNotBeAbleToDisablePoliciesTwice (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  // Make sure that the policy enforcement is currently enabled.
+  UT_ASSERT_TRUE (IsVariablePolicyEnabled ());
+  // Disable the policy enforcement.
+  UT_ASSERT_NOT_EFI_ERROR (DisableVariablePolicy ());
+  // Make sure that the policy enforcement is currently disabled.
+  UT_ASSERT_FALSE (IsVariablePolicyEnabled ());
+  // Try to disable again and verify failure.
+  UT_ASSERT_TRUE (EFI_ERROR (DisableVariablePolicy ()));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldBeAbleToAddNewPoliciesAfterDisabled (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   TestPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_10,
+      TEST_POLICY_MAX_SIZE_200,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+
+  // Make sure that the policy enforcement is currently enabled.
+  UT_ASSERT_TRUE (IsVariablePolicyEnabled ());
+  // Disable the policy enforcement.
+  UT_ASSERT_NOT_EFI_ERROR (DisableVariablePolicy ());
+
+  // Make sure that new policy creation still works, it just won't be enforced.
+  PolicyCheck = RegisterVariablePolicy (&TestPolicy.Header);
+  UT_ASSERT_NOT_EFI_ERROR (PolicyCheck);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldBeAbleToLockAfterDisabled (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  // Make sure that the policy enforcement is currently enabled.
+  UT_ASSERT_TRUE (IsVariablePolicyEnabled ());
+  // Disable the policy enforcement.
+  UT_ASSERT_NOT_EFI_ERROR (DisableVariablePolicy ());
+
+  // Make sure that we can lock in this state.
+  UT_ASSERT_FALSE (IsVariablePolicyInterfaceLocked ());
+  UT_ASSERT_NOT_EFI_ERROR (LockVariablePolicy ());
+  UT_ASSERT_TRUE (IsVariablePolicyInterfaceLocked ());
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldBeAbleToDumpThePolicyTable (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   TestPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_10,
+      TEST_POLICY_MAX_SIZE_200,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT32      DumpSize;
+  UINT32      BufferSize;
+  VOID        *DumpBuffer;
+
+  // For good measure, test some parameter validation.
+  UT_ASSERT_STATUS_EQUAL (DumpVariablePolicy (NULL, NULL), EFI_INVALID_PARAMETER);
+  DumpSize = 10;
+  UT_ASSERT_STATUS_EQUAL (DumpVariablePolicy (NULL, &DumpSize), EFI_INVALID_PARAMETER);
+
+  // Now for the actual test case.
+
+  // Allocate a buffer to hold the output.
+  BufferSize = sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME);
+  DumpBuffer = AllocatePool (BufferSize);
+  UT_ASSERT_NOT_EQUAL (DumpBuffer, NULL);
+
+  // Verify that the current table size is 0.
+  DumpSize = BufferSize;
+  UT_ASSERT_NOT_EFI_ERROR (DumpVariablePolicy (DumpBuffer, &DumpSize));
+  UT_ASSERT_EQUAL (DumpSize, 0);
+
+  // Now, set a new policy.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&TestPolicy.Header));
+
+  // Make sure that the new return is non-zero and fails as expected.
+  DumpSize = 0;
+  PolicyCheck = DumpVariablePolicy (NULL, &DumpSize);
+  UT_ASSERT_STATUS_EQUAL (PolicyCheck, EFI_BUFFER_TOO_SMALL);
+  UT_ASSERT_EQUAL (DumpSize, BufferSize);
+
+  // Now verify that we can fetch the dump.
+  DumpSize = BufferSize;
+  UT_ASSERT_NOT_EFI_ERROR (DumpVariablePolicy (DumpBuffer, &DumpSize));
+  UT_ASSERT_EQUAL (DumpSize, BufferSize);
+  UT_ASSERT_MEM_EQUAL (&TestPolicy, DumpBuffer, BufferSize);
+
+  // Always put away your toys.
+  FreePool (DumpBuffer);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Test Case
+*/
+UNIT_TEST_STATUS
+EFIAPI
+ShouldBeAbleToDumpThePolicyTableAfterDisabled (
+  IN UNIT_TEST_CONTEXT      Context
+  )
+{
+  SIMPLE_VARIABLE_POLICY_ENTRY   TestPolicy = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_1_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_1,
+      TEST_POLICY_MIN_SIZE_10,
+      TEST_POLICY_MAX_SIZE_200,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_1_NAME
+  };
+  SIMPLE_VARIABLE_POLICY_ENTRY   TestPolicy2 = {
+    {
+      VARIABLE_POLICY_ENTRY_REVISION,
+      sizeof (VARIABLE_POLICY_ENTRY) + sizeof (TEST_VAR_2_NAME),
+      sizeof (VARIABLE_POLICY_ENTRY),
+      TEST_GUID_2,
+      TEST_POLICY_MIN_SIZE_10,
+      TEST_POLICY_MAX_SIZE_200,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      TEST_POLICY_ATTRIBUTES_NULL,
+      VARIABLE_POLICY_TYPE_NO_LOCK
+    },
+    TEST_VAR_2_NAME
+  };
+  EFI_STATUS  PolicyCheck;
+  UINT32      DumpSize;
+  VOID        *DumpBuffer;
+
+  DumpBuffer = NULL;
+  DumpSize = 0;
+
+  // Register a new policy.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&TestPolicy.Header));
+  // Make sure that we can dump the policy.
+  PolicyCheck = DumpVariablePolicy (DumpBuffer, &DumpSize);
+  UT_ASSERT_STATUS_EQUAL (PolicyCheck, EFI_BUFFER_TOO_SMALL);
+  DumpBuffer = AllocatePool (DumpSize);
+  UT_ASSERT_NOT_EFI_ERROR (DumpVariablePolicy (DumpBuffer, &DumpSize));
+  UT_ASSERT_MEM_EQUAL (DumpBuffer, &TestPolicy, DumpSize);
+
+  // Clean up from this step.
+  FreePool (DumpBuffer);
+  DumpBuffer = NULL;
+  DumpSize = 0;
+
+  // Now disable the engine.
+  DisableVariablePolicy ();
+
+  // Now register a new policy and make sure that both can be dumped.
+  UT_ASSERT_NOT_EFI_ERROR (RegisterVariablePolicy (&TestPolicy2.Header));
+  // Make sure that we can dump the policy.
+  PolicyCheck = DumpVariablePolicy (DumpBuffer, &DumpSize);
+  UT_ASSERT_STATUS_EQUAL (PolicyCheck, EFI_BUFFER_TOO_SMALL);
+  DumpBuffer = AllocatePool (DumpSize);
+  UT_ASSERT_NOT_EFI_ERROR (DumpVariablePolicy (DumpBuffer, &DumpSize));
+
+  // Finally, make sure that both policies are in the dump.
+  UT_ASSERT_MEM_EQUAL (DumpBuffer, &TestPolicy, TestPolicy.Header.Size);
+  UT_ASSERT_MEM_EQUAL (
+    (UINT8 *) DumpBuffer + TestPolicy.Header.Size,
+    &TestPolicy2,
+    TestPolicy2.Header.Size
+    );
+
+  // Always put away your toys.
+  FreePool (DumpBuffer);
+
+  return UNIT_TEST_PASSED;
+}
+
+
+///=== TEST ENGINE ================================================================================
+
+/**
+  SampleUnitTestApp
+
+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.
+  @param[in] SystemTable  A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS     The entry point executed successfully.
+  @retval other           Some error occurred when executing this entry point.
+
+**/
+int
+main (
+  )
+{
+  EFI_STATUS                  Status;
+  UNIT_TEST_FRAMEWORK_HANDLE  Framework = NULL;
+  UNIT_TEST_SUITE_HANDLE      ArchTests;
+  UNIT_TEST_SUITE_HANDLE      PolicyTests;
+  UNIT_TEST_SUITE_HANDLE      UtilityTests;
+#ifdef INTERNAL_UNIT_TEST
+  UNIT_TEST_SUITE_HANDLE      InternalTests;
+#endif // INTERNAL_UNIT_TEST
+
+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));
+
+  //
+  // Start setting up the test framework for running the tests.
+  //
+  Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+    goto EXIT;
+  }
+
+
+  //
+  // Add all test suites and tests.
+  //
+  Status = CreateUnitTestSuite (&ArchTests, Framework, "Variable Policy Architectural Tests", "VarPolicy.Arch", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for ArchTests\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (ArchTests,
+                "Deinitialization should fail if not previously initialized", "VarPolicy.Arch.OnlyDeinit",
+                ShouldFailDeinitWithoutInit, NULL, NULL, NULL);
+  AddTestCase (ArchTests,
+                "Initialization followed by deinitialization should succeed", "VarPolicy.Arch.InitDeinit",
+                ShouldBeAbleToInitAndDeinitTheLibrary, NULL, NULL, NULL);
+  AddTestCase (ArchTests,
+                "The initialization function fail if called twice without a deinit", "VarPolicy.Arch.InitTwice",
+                ShouldNotBeAbleToInitializeTheLibraryTwice, NULL, LibCleanup, NULL);
+  AddTestCase (ArchTests,
+                "API functions should be unavailable until library is initialized", "VarPolicy.Arch.UninitApiOff",
+                ApiCommandsShouldNotRespondIfLibIsUninitialized, NULL, LibCleanup, NULL);
+
+#ifdef INTERNAL_UNIT_TEST
+  Status = CreateUnitTestSuite (&InternalTests, Framework, "Variable Policy Internal Tests", "VarPolicy.Internal", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for InternalTests\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (InternalTests,
+                "Policy matching should use name and GUID", "VarPolicy.Internal.NameGuid",
+                PoliciesShouldMatchByNameAndGuid, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (InternalTests,
+                "# sign wildcards should match digits", "VarPolicy.Internal.WildDigits",
+                WildcardPoliciesShouldMatchDigits, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (InternalTests,
+                "Digit wildcards should check edge cases", "VarPolicy.Internal.WildDigitsAdvanced",
+                WildcardPoliciesShouldMatchDigitsAdvanced, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (InternalTests,
+                "Empty names should match an entire namespace", "VarPolicy.Internal.WildNamespace",
+                WildcardPoliciesShouldMatchNamespaces, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (InternalTests,
+                "Match priority should weight correctly based on wildcards", "VarPolicy.Internal.Priorities",
+                MatchPrioritiesShouldFollowRules, LibInitMocked, LibCleanup, NULL);
+#endif // INTERNAL_UNIT_TEST
+
+  Status = CreateUnitTestSuite (&PolicyTests, Framework, "Variable Policy Manipulation Tests", "VarPolicy.Policy", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for PolicyTests\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (PolicyTests,
+                "RegisterShouldAllowNamespaceWildcards", "VarPolicy.Policy.AllowNamespace",
+                RegisterShouldAllowNamespaceWildcards, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldAllowStateVarsForNamespaces", "VarPolicy.Policy.AllowStateNamespace",
+                RegisterShouldAllowStateVarsForNamespaces, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectNullPointers", "VarPolicy.Policy.NullPointers",
+                RegisterShouldRejectNullPointers, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectBadRevisions", "VarPolicy.Policy.BadRevisions",
+                RegisterShouldRejectBadRevisions, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectBadSizes", "VarPolicy.Policy.BadSizes",
+                RegisterShouldRejectBadSizes, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectBadOffsets", "VarPolicy.Policy.BadOffsets",
+                RegisterShouldRejectBadOffsets, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectMissingStateStrings", "VarPolicy.Policy.MissingStateString",
+                RegisterShouldRejectMissingStateStrings, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectStringsMissingNull", "VarPolicy.Policy.MissingNull",
+                RegisterShouldRejectStringsMissingNull, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectMalformedStrings", "VarPolicy.Policy.MalformedStrings",
+                RegisterShouldRejectMalformedStrings, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectUnpackedPolicies", "VarPolicy.Policy.PolicyPacking",
+                RegisterShouldRejectUnpackedPolicies, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectInvalidNameCharacters", "VarPolicy.Policy.InvalidCharacters",
+                RegisterShouldRejectInvalidNameCharacters, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectBadPolicyConstraints", "VarPolicy.Policy.BadConstraints",
+                RegisterShouldRejectBadPolicyConstraints, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectUnknownLockPolicies", "VarPolicy.Policy.BadLocks",
+                RegisterShouldRejectUnknownLockPolicies, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectPolicesWithTooManyWildcards", "VarPolicy.Policy.TooManyWildcards",
+                RegisterShouldRejectPolicesWithTooManyWildcards, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "RegisterShouldRejectDuplicatePolicies", "VarPolicy.Policy.DuplicatePolicies",
+                RegisterShouldRejectDuplicatePolicies, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "Variables that exceed min or max sizes should be rejected", "VarPolicy.Policy.MinMax",
+                MinAndMaxSizePoliciesShouldBeHonored, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "AttributeMustPoliciesShouldBeHonored", "VarPolicy.Policy.AttrMust",
+                AttributeMustPoliciesShouldBeHonored, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "AttributeCantPoliciesShouldBeHonored", "VarPolicy.Policy.AttrCant",
+                AttributeCantPoliciesShouldBeHonored, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "VariablesShouldBeDeletableRegardlessOfSize", "VarPolicy.Policy.DeleteIgnoreSize",
+                VariablesShouldBeDeletableRegardlessOfSize, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "LockNowPoliciesShouldBeHonored", "VarPolicy.Policy.VARIABLE_POLICY_TYPE_LOCK_NOW",
+                LockNowPoliciesShouldBeHonored, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "LockOnCreatePoliciesShouldBeHonored", "VarPolicy.Policy.VARIABLE_POLICY_TYPE_LOCK_ON_CREATE",
+                LockOnCreatePoliciesShouldBeHonored, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "LockOnStatePoliciesShouldBeHonored", "VarPolicy.Policy.LockState",
+                LockOnStatePoliciesShouldBeHonored, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "LockOnStatePoliciesShouldApplyToNamespaces", "VarPolicy.Policy.NamespaceLockState",
+                LockOnStatePoliciesShouldApplyToNamespaces, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "LockOnStateShouldHandleErrorsGracefully", "VarPolicy.Policy.LockStateErrors",
+                LockOnStateShouldHandleErrorsGracefully, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (PolicyTests,
+                "BestMatchPriorityShouldBeObeyed", "VarPolicy.Policy.BestMatch",
+                BestMatchPriorityShouldBeObeyed, LibInitMocked, LibCleanup, NULL);
+
+  Status = CreateUnitTestSuite (&UtilityTests, Framework, "Variable Policy Utility Tests", "VarPolicy.Utility", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for UtilityTests\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+  AddTestCase (UtilityTests,
+                "API commands that change state should not respond after interface is locked", "VarPolicy.Utility.InterfaceLock",
+                ShouldBeAbleToLockInterface, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (UtilityTests,
+                "All policies should pass once enforcement is disabled", "VarPolicy.Utility.DisableEnforcement",
+                ShouldBeAbleToDisablePolicyEnforcement, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (UtilityTests,
+                "Disabling enforcement twice should produce an error", "VarPolicy.Utility.DisableEnforcementTwice",
+                ShouldNotBeAbleToDisablePoliciesTwice, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (UtilityTests,
+                "ShouldBeAbleToAddNewPoliciesAfterDisabled", "VarPolicy.Utility.AddAfterDisable",
+                ShouldBeAbleToAddNewPoliciesAfterDisabled, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (UtilityTests,
+                "ShouldBeAbleToLockAfterDisabled", "VarPolicy.Utility.LockAfterDisable",
+                ShouldBeAbleToLockAfterDisabled, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (UtilityTests,
+                "Should be able to dump the policy table", "VarPolicy.Utility.DumpTable",
+                ShouldBeAbleToDumpThePolicyTable, LibInitMocked, LibCleanup, NULL);
+  AddTestCase (UtilityTests,
+                "ShouldBeAbleToDumpThePolicyTableAfterDisabled", "VarPolicy.Utility.DumpTableAfterDisable",
+                ShouldBeAbleToDumpThePolicyTableAfterDisabled, LibInitMocked, LibCleanup, NULL);
+
+
+  //
+  // Execute the tests.
+  //
+  Status = RunAllTestSuites (Framework);
+
+EXIT:
+  if (Framework != NULL) {
+    FreeUnitTestFramework (Framework);
+  }
+
+  return Status;
+}
diff --git a/MdeModulePkg/Include/Library/VariablePolicyLib.h b/MdeModulePkg/Include/Library/VariablePolicyLib.h
new file mode 100644
index 000000000000..efd1840112ec
--- /dev/null
+++ b/MdeModulePkg/Include/Library/VariablePolicyLib.h
@@ -0,0 +1,207 @@
+/** @file -- VariablePolicyLib.h
+Business logic for Variable Policy enforcement.
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _VARIABLE_POLICY_LIB_H_
+#define _VARIABLE_POLICY_LIB_H_
+
+#include <Protocol/VariablePolicy.h>
+
+/**
+  This API function validates and registers a new policy with
+  the policy enforcement engine.
+
+  @param[in]  NewPolicy     Pointer to the incoming policy structure.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_INVALID_PARAMETER   NewPolicy is NULL or is internally inconsistent.
+  @retval     EFI_ALREADY_STARTED     An identical matching policy already exists.
+  @retval     EFI_WRITE_PROTECTED     The interface has been locked until the next reboot.
+  @retval     EFI_UNSUPPORTED         Policy enforcement has been disabled. No reason to add more policies.
+  @retval     EFI_ABORTED             A calculation error has prevented this function from completing.
+  @retval     EFI_OUT_OF_RESOURCES    Cannot grow the table to hold any more policies.
+  @retval     EFI_NOT_READY           Library has not yet been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterVariablePolicy (
+  IN CONST VARIABLE_POLICY_ENTRY    *NewPolicy
+  );
+
+
+/**
+  This API function checks to see whether the parameters to SetVariable would
+  be allowed according to the current variable policies.
+
+  @param[in]  VariableName       Same as EFI_SET_VARIABLE.
+  @param[in]  VendorGuid         Same as EFI_SET_VARIABLE.
+  @param[in]  Attributes         Same as EFI_SET_VARIABLE.
+  @param[in]  DataSize           Same as EFI_SET_VARIABLE.
+  @param[in]  Data               Same as EFI_SET_VARIABLE.
+
+  @retval     EFI_SUCCESS             A matching policy allows this update.
+  @retval     EFI_SUCCESS             There are currently no policies that restrict this update.
+  @retval     EFI_SUCCESS             The protections have been disable until the next reboot.
+  @retval     EFI_WRITE_PROTECTED     Variable is currently locked.
+  @retval     EFI_INVALID_PARAMETER   Attributes or size are invalid.
+  @retval     EFI_ABORTED             A lock policy exists, but an error prevented evaluation.
+  @retval     EFI_NOT_READY           Library has not been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+ValidateSetVariable (
+  IN  CHAR16                       *VariableName,
+  IN  EFI_GUID                     *VendorGuid,
+  IN  UINT32                       Attributes,
+  IN  UINTN                        DataSize,
+  IN  VOID                         *Data
+  );
+
+
+/**
+  This API function disables the variable policy enforcement. If it's
+  already been called once, will return EFI_ALREADY_STARTED.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_ALREADY_STARTED   Has already been called once this boot.
+  @retval     EFI_WRITE_PROTECTED   Interface has been locked until reboot.
+  @retval     EFI_WRITE_PROTECTED   Interface option is disabled by platform PCD.
+  @retval     EFI_NOT_READY   Library has not yet been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableVariablePolicy (
+  VOID
+  );
+
+
+/**
+  This API function will dump the entire contents of the variable policy table.
+
+  Similar to GetVariable, the first call can be made with a 0 size and it will return
+  the size of the buffer required to hold the entire table.
+
+  @param[out]     Policy  Pointer to the policy buffer. Can be NULL if Size is 0.
+  @param[in,out]  Size    On input, the size of the output buffer. On output, the size
+                          of the data returned.
+
+  @retval     EFI_SUCCESS             Policy data is in the output buffer and Size has been updated.
+  @retval     EFI_INVALID_PARAMETER   Size is NULL, or Size is non-zero and Policy is NULL.
+  @retval     EFI_BUFFER_TOO_SMALL    Size is insufficient to hold policy. Size updated with required size.
+  @retval     EFI_NOT_READY           Library has not yet been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+DumpVariablePolicy (
+  OUT     UINT8         *Policy,
+  IN OUT  UINT32        *Size
+  );
+
+
+/**
+  This API function returns whether or not the policy engine is
+  currently being enforced.
+
+  @retval     TRUE
+  @retval     FALSE
+  @retval     FALSE         Library has not yet been initialized.
+
+**/
+BOOLEAN
+EFIAPI
+IsVariablePolicyEnabled (
+  VOID
+  );
+
+
+/**
+  This API function locks the interface so that no more policy updates
+  can be performed or changes made to the enforcement until the next boot.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_NOT_READY   Library has not yet been initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+LockVariablePolicy (
+  VOID
+  );
+
+
+/**
+  This API function returns whether or not the policy interface is locked
+  for the remainder of the boot.
+
+  @retval     TRUE
+  @retval     FALSE
+  @retval     FALSE         Library has not yet been initialized.
+
+**/
+BOOLEAN
+EFIAPI
+IsVariablePolicyInterfaceLocked (
+  VOID
+  );
+
+
+/**
+  This helper function initializes the library and sets
+  up any required internal structures or handlers.
+
+  Also registers the internal pointer for the GetVariable helper.
+
+  @param[in]  GetVariableHelper A function pointer matching the EFI_GET_VARIABLE prototype that will be used to
+                  check policy criteria that involve the existence of other variables.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_ALREADY_STARTED   The initialize function has been called more than once without a call to
+                                    deinitialize.
+
+**/
+EFI_STATUS
+EFIAPI
+InitVariablePolicyLib (
+  IN  EFI_GET_VARIABLE    GetVariableHelper
+  );
+
+
+/**
+  This helper function returns whether or not the library is currently initialized.
+
+  @retval     TRUE
+  @retval     FALSE
+
+**/
+BOOLEAN
+EFIAPI
+IsVariablePolicyLibInitialized (
+  VOID
+  );
+
+
+/**
+  This helper function tears down  the library.
+
+  Should generally only be used for test harnesses.
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_NOT_READY     Deinitialize was called without first calling initialize.
+
+**/
+EFI_STATUS
+EFIAPI
+DeinitVariablePolicyLib (
+  VOID
+  );
+
+
+#endif // _VARIABLE_POLICY_LIB_H_
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
new file mode 100644
index 000000000000..f4a879d5382f
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
@@ -0,0 +1,44 @@
+## @file VariablePolicyLib.inf
+# Business logic for Variable Policy enforcement.
+#
+##
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+  INF_VERSION         = 0x00010017
+  BASE_NAME           = VariablePolicyLib
+  FILE_GUID           = E9ECD342-159A-4F24-9FDF-65724027C594
+  VERSION_STRING      = 1.0
+  MODULE_TYPE         = DXE_DRIVER
+  LIBRARY_CLASS       = VariablePolicyLib|DXE_DRIVER DXE_SMM_DRIVER MM_STANDALONE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = ANY
+#
+
+
+[Sources]
+  VariablePolicyLib.c
+  VariablePolicyExtraInitNull.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  SafeIntLib
+  PcdLib
+
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisable     ## CONSUMES
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
new file mode 100644
index 000000000000..2227ec427828
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
@@ -0,0 +1,12 @@
+// /** @file
+// VariablePolicyLib.uni
+//
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Library containing the business logic for the VariablePolicy engine"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Library containing the business logic for the VariablePolicy engine"
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
new file mode 100644
index 000000000000..8b8365741864
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
@@ -0,0 +1,51 @@
+## @file VariablePolicyLibRuntimeDxe.inf
+# Business logic for Variable Policy enforcement.
+# This instance is specifically for RuntimeDxe and contains
+# extra routines to register for VirtualAddressChangeEvents.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+  INF_VERSION         = 0x00010017
+  BASE_NAME           = VariablePolicyLibRuntimeDxe
+  FILE_GUID           = 205F7F0E-8EAC-4914-8390-1B90DD7E2A27
+  VERSION_STRING      = 1.0
+  MODULE_TYPE         = DXE_RUNTIME_DRIVER
+  LIBRARY_CLASS       = VariablePolicyLib|DXE_RUNTIME_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = ANY
+#
+
+
+[Sources]
+  VariablePolicyLib.c
+  VariablePolicyExtraInitRuntimeDxe.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  SafeIntLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  PcdLib
+
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisable     ## CONSUMES
+
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.inf b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.inf
new file mode 100644
index 000000000000..ccc04bb600d6
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.inf
@@ -0,0 +1,40 @@
+## @file VariablePolicyUnitTest.inf
+# UnitTest for...
+# Business logic for Variable Policy enforcement.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = VariablePolicyUnitTest
+  FILE_GUID                      = 1200A2E4-D756-418C-9768-528C2D181A98
+  MODULE_TYPE                    = HOST_APPLICATION
+  VERSION_STRING                 = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+  VariablePolicyUnitTest.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  UnitTestLib
+  PrintLib
+  VariablePolicyLib
+  BaseMemoryLib
+  MemoryAllocationLib
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 2e0461b87c32..31339741b840 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -31,6 +31,9 @@ [LibraryClasses]
   ##  @libraryclass  Defines a set of methods to reset whole system.
   ResetSystemLib|Include/Library/ResetSystemLib.h
 
+  ##  @libraryclass  Business logic for storing and testing variable policies
+  VariablePolicyLib|Include/Library/VariablePolicyLib.h
+
   ##  @libraryclass  Defines a set of helper functions for resetting the system.
   ResetUtilityLib|Include/Library/ResetUtilityLib.h
 
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 25aea3e2a481..14b6ed536962 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -3,6 +3,7 @@
 #
 # (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
 # Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.
 #
 #    SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -58,6 +59,7 @@ [LibraryClasses]
   DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
   DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
   UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
   #
   # Generic Modules
   #
@@ -129,6 +131,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
   LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
 
 [LibraryClasses.common.SMM_CORE]
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -306,6 +309,8 @@ [Components]
   MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
   MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
   MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
   MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
   MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
   MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf
diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
index 72a119db4568..095e613f1be1 100644
--- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
+++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
@@ -19,12 +19,23 @@ [Defines]
 
 !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
 
+[LibraryClasses]
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+
 [Components]
   MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
 
   #
   # Build MdeModulePkg HOST_APPLICATION Tests
   #
+  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePolicyUnitTest.inf {
+    <LibraryClasses>
+      VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisable|TRUE
+  }
+
   MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTestHost.inf {
     <LibraryClasses>
       ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystemLib.inf
-- 
2.16.3.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#60072): https://edk2.groups.io/g/devel/message/60072
Mute This Topic: https://groups.io/mt/74387406/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list