public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 00/11] Enhance Secure Boot Variable Libraries
@ 2022-06-13 20:39 Kun Qin
  2022-06-13 20:39 ` [PATCH v2 01/11] SecurityPkg: UefiSecureBoot: Definitions of cert and payload structures Kun Qin
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel
  Cc: Jiewen Yao, Jian J Wang, Min Xu, Sean Brogan, Ard Biesheuvel,
	Jordan Justen, Gerd Hoffmann, Rebecca Cran, Peter Grehan,
	Sebastien Boeuf, Andrew Fish, Ray Ni

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3909
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3910
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3911

This is a revamp of a previously submitted patch series based on top of
master branch: https://edk2.groups.io/g/devel/message/89507. No changes
added.

Current SecureBootVariableLib provide great support for deleting secure
boot related variables, creating time-based payloads.

However, for secure boot enrollment, the SecureBootVariableProvisionLib
interfaces always assume the changes from variable storage, limiting the
usage, requiring existing platforms to change key initialization process
to adapt to the new methods, as well as bringing in extra dependencies
such as FV protocol, time protocols.

This patch series proposes to update the implementation for Secure Boot
Variable libraries and their consumers to better support the related
variables operations.

Patch v2 branch: https://github.com/kuqin12/edk2/tree/secure_boot_enhance_v2

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rebecca Cran <rebecca@bsdio.com>
Cc: Peter Grehan <grehan@freebsd.org>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>

Kun Qin (8):
  SecurityPkg: UefiSecureBoot: Definitions of cert and payload
    structures
  SecurityPkg: PlatformPKProtectionLib: Added PK protection interface
  SecurityPkg: SecureBootVariableLib: Updated time based payload creator
  SecurityPkg: SecureBootVariableProvisionLib: Updated implementation
  SecurityPkg: Secure Boot Drivers: Added common header files
  SecurityPkg: SecureBootConfigDxe: Updated invocation pattern
  OvmfPkg: Pipeline: Resolve SecureBootVariableLib dependency
  EmulatorPkg: Pipeline: Resolve SecureBootVariableLib dependency

kuqin (3):
  SecurityPkg: SecureBootVariableLib: Updated signature list creator
  SecurityPkg: SecureBootVariableLib: Added newly supported interfaces
  SecurityPkg: SecureBootVariableLib: Added unit tests

 SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.c                           |    1 +
 SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.c   |   51 +
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c                         |  486 ++++-
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.c          |   36 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.c                          |  201 ++
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.c      |   13 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c        | 2037 ++++++++++++++++++++
 SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c       |  145 +-
 SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c              |  128 +-
 SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.c     |    1 +
 EmulatorPkg/EmulatorPkg.dsc                                                               |    1 +
 OvmfPkg/Bhyve/BhyveX64.dsc                                                                |    1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc                                                            |    1 +
 OvmfPkg/IntelTdx/IntelTdxX64.dsc                                                          |    1 +
 OvmfPkg/OvmfPkgIa32.dsc                                                                   |    1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                                                                |    1 +
 OvmfPkg/OvmfPkgX64.dsc                                                                    |    1 +
 SecurityPkg/Include/Library/PlatformPKProtectionLib.h                                     |   31 +
 SecurityPkg/Include/Library/SecureBootVariableLib.h                                       |  103 +-
 SecurityPkg/Include/UefiSecureBoot.h                                                      |   94 +
 SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf |   36 +
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf                       |   14 +-
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf        |   33 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf                        |   45 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf    |   25 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf      |   36 +
 SecurityPkg/SecurityPkg.ci.yaml                                                           |   11 +
 SecurityPkg/SecurityPkg.dec                                                               |    5 +
 SecurityPkg/SecurityPkg.dsc                                                               |    2 +
 SecurityPkg/Test/SecurityPkgHostTest.dsc                                                  |   38 +
 SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf             |    1 +
 31 files changed, 3468 insertions(+), 112 deletions(-)
 create mode 100644 SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.c
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.c
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.c
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.c
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
 create mode 100644 SecurityPkg/Include/Library/PlatformPKProtectionLib.h
 create mode 100644 SecurityPkg/Include/UefiSecureBoot.h
 create mode 100644 SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf
 create mode 100644 SecurityPkg/Test/SecurityPkgHostTest.dsc

-- 
2.35.1.windows.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 01/11] SecurityPkg: UefiSecureBoot: Definitions of cert and payload structures
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 02/11] SecurityPkg: PlatformPKProtectionLib: Added PK protection interface Kun Qin
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: Kun Qin <kuqin@microsoft.com>

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

This change added certificate and payload structures that can be consumed
by SecureBootVariableLib and other Secure Boot related operations.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/Include/UefiSecureBoot.h | 94 ++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/SecurityPkg/Include/UefiSecureBoot.h b/SecurityPkg/Include/UefiSecureBoot.h
new file mode 100644
index 000000000000..642fef38f3a1
--- /dev/null
+++ b/SecurityPkg/Include/UefiSecureBoot.h
@@ -0,0 +1,94 @@
+/** @file
+  Provides a Secure Boot related data structure definitions.
+
+  Copyright (c) Microsoft Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef UEFI_SECURE_BOOT_H_
+#define UEFI_SECURE_BOOT_H_
+
+#pragma pack (push, 1)
+
+/*
+  Data structure to provide certificates to setup authenticated secure
+  boot variables ('db', 'dbx', 'dbt', 'pk', etc.).
+
+*/
+typedef struct {
+  //
+  // The size, in number of bytes, of supplied certificate in 'Data' field.
+  //
+  UINTN         DataSize;
+  //
+  // The pointer to the certificates in DER-encoded format.
+  // Note: This certificate data should not contain the EFI_VARIABLE_AUTHENTICATION_2
+  //       for authenticated variables.
+  //
+  CONST VOID    *Data;
+} SECURE_BOOT_CERTIFICATE_INFO;
+
+/*
+  Data structure to provide all Secure Boot related certificates.
+
+*/
+typedef struct {
+  //
+  // The human readable name for this set of Secure Boot key sets.
+  //
+  CONST CHAR16    *SecureBootKeyName;
+  //
+  // The size, in number of bytes, of supplied certificate in 'DbPtr' field.
+  //
+  UINTN           DbSize;
+  //
+  // The pointer to the DB certificates in signature list format.
+  // Note: This DB certificates should not contain the EFI_VARIABLE_AUTHENTICATION_2
+  //       for authenticated variables.
+  //
+  CONST VOID      *DbPtr;
+  //
+  // The size, in number of bytes, of supplied certificate in 'DbxPtr' field.
+  //
+  UINTN           DbxSize;
+  //
+  // The pointer to the DBX certificates in signature list format.
+  // Note: This DBX certificates should not contain the EFI_VARIABLE_AUTHENTICATION_2
+  //       for authenticated variables.
+  //
+  CONST VOID      *DbxPtr;
+  //
+  // The size, in number of bytes, of supplied certificate in 'DbtPtr' field.
+  //
+  UINTN           DbtSize;
+  //
+  // The pointer to the DBT certificates in signature list format.
+  // Note: This DBT certificates should not contain the EFI_VARIABLE_AUTHENTICATION_2
+  //       for authenticated variables.
+  //
+  CONST VOID      *DbtPtr;
+  //
+  // The size, in number of bytes, of supplied certificate in 'KekPtr' field.
+  //
+  UINTN           KekSize;
+  //
+  // The pointer to the KEK certificates in signature list format.
+  // Note: This KEK certificates should not contain the EFI_VARIABLE_AUTHENTICATION_2
+  //       for authenticated variables.
+  //
+  CONST VOID      *KekPtr;
+  //
+  // The size, in number of bytes, of supplied certificate in 'PkPtr' field.
+  //
+  UINTN           PkSize;
+  //
+  // The pointer to the PK certificates in signature list format.
+  // Note: This PK certificates should not contain the EFI_VARIABLE_AUTHENTICATION_2
+  //       for authenticated variables.
+  //
+  CONST VOID      *PkPtr;
+} SECURE_BOOT_PAYLOAD_INFO;
+#pragma pack (pop)
+
+#endif // UEFI_SECURE_BOOT_H_
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 02/11] SecurityPkg: PlatformPKProtectionLib: Added PK protection interface
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
  2022-06-13 20:39 ` [PATCH v2 01/11] SecurityPkg: UefiSecureBoot: Definitions of cert and payload structures Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 03/11] SecurityPkg: SecureBootVariableLib: Updated time based payload creator Kun Qin
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: Kun Qin <kuqin@microsoft.com>

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

This patch provides an abstracted interface for platform to implement PK
variable related protection interface, which is designed to be used when
PK variable is about to be changed by UEFI firmware.

This change also provided a variable policy based library implementation
to accomodate platforms that supports variable policy for variable
protections.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.c   | 51 ++++++++++++++++++++
 SecurityPkg/Include/Library/PlatformPKProtectionLib.h                                     | 31 ++++++++++++
 SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf | 36 ++++++++++++++
 SecurityPkg/SecurityPkg.dec                                                               |  5 ++
 SecurityPkg/SecurityPkg.dsc                                                               |  2 +
 5 files changed, 125 insertions(+)

diff --git a/SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.c b/SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.c
new file mode 100644
index 000000000000..a2649242246f
--- /dev/null
+++ b/SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.c
@@ -0,0 +1,51 @@
+/** @file
+  Provides an abstracted interface for configuring PK related variable protection.
+
+  Copyright (c) Microsoft Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Uefi.h>
+#include <Protocol/VariablePolicy.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+  Disable any applicable protection against variable 'PK'. The implementation
+  of this interface is platform specific, depending on the protection techniques
+  used per platform.
+
+  Note: It is the platform's responsibility to conduct cautious operation after
+        disabling this protection.
+
+  @retval     EFI_SUCCESS             State has been successfully updated.
+  @retval     Others                  Error returned from implementation specific
+                                      underying APIs.
+
+**/
+EFI_STATUS
+EFIAPI
+DisablePKProtection (
+  VOID
+  )
+{
+  EFI_STATUS                      Status;
+  EDKII_VARIABLE_POLICY_PROTOCOL  *VariablePolicy;
+
+  DEBUG ((DEBUG_INFO, "%a() Entry...\n", __FUNCTION__));
+
+  // IMPORTANT NOTE: This operation is sticky and leaves variable protections disabled.
+  //                  The system *MUST* be reset after performing this operation.
+  Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicy);
+  if (!EFI_ERROR (Status)) {
+    Status = VariablePolicy->DisableVariablePolicy ();
+    // EFI_ALREADY_STARTED means that everything is currently disabled.
+    // This should be considered SUCCESS.
+    if (Status == EFI_ALREADY_STARTED) {
+      Status = EFI_SUCCESS;
+    }
+  }
+
+  return Status;
+}
diff --git a/SecurityPkg/Include/Library/PlatformPKProtectionLib.h b/SecurityPkg/Include/Library/PlatformPKProtectionLib.h
new file mode 100644
index 000000000000..3586a47b77c2
--- /dev/null
+++ b/SecurityPkg/Include/Library/PlatformPKProtectionLib.h
@@ -0,0 +1,31 @@
+/** @file
+  Provides an abstracted interface for configuring PK related variable protection.
+
+  Copyright (c) Microsoft Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_PK_PROTECTION_LIB_H_
+#define PLATFORM_PK_PROTECTION_LIB_H_
+
+/**
+  Disable any applicable protection against variable 'PK'. The implementation
+  of this interface is platform specific, depending on the protection techniques
+  used per platform.
+
+  Note: It is the platform's responsibility to conduct cautious operation after
+        disabling this protection.
+
+  @retval     EFI_SUCCESS             State has been successfully updated.
+  @retval     Others                  Error returned from implementation specific
+                                      underying APIs.
+
+**/
+EFI_STATUS
+EFIAPI
+DisablePKProtection (
+  VOID
+  );
+
+#endif
diff --git a/SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf b/SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
new file mode 100644
index 000000000000..df42ce06c019
--- /dev/null
+++ b/SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
@@ -0,0 +1,36 @@
+## @file
+#  Provides an abstracted interface for configuring PK related variable protection.
+#
+#  Copyright (c) Microsoft Corporation.
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformPKProtectionLibVarPolicy
+  FILE_GUID                      = AE0C5992-526C-4518-93BA-3C2611B801E0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformPKProtectionLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  PlatformPKProtectionLibVarPolicy.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  UefiBootServicesTableLib
+
+[Protocols]
+  gEdkiiVariablePolicyProtocolGuid
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index 0ee75efc1a97..7ecf9565d98c 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -99,6 +99,11 @@ [LibraryClasses]
   ## @libraryclass  Provides support to enroll Secure Boot keys.
   #
   SecureBootVariableProvisionLib|Include/Library/SecureBootVariableProvisionLib.h
+
+  ## @libraryclass  Provides support to manage variable 'PK' related protections.
+  #
+  PlatformPKProtectionLib|Include/Library/PlatformPKProtectionLib.h
+
 [Guids]
   ## Security package token space guid.
   # Include/Guid/SecurityPkgTokenSpace.h
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index d883747474e4..f48187650f2f 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -71,6 +71,7 @@ [LibraryClasses]
   TcgEventLogRecordLib|SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.inf
   MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
   SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
   SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
 
@@ -261,6 +262,7 @@ [Components]
   #
   SecurityPkg/Library/VariableKeyLibNull/VariableKeyLibNull.inf
   SecurityPkg/Library/RpmcLibNull/RpmcLibNull.inf
+  SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
 
   #
   # Other
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 03/11] SecurityPkg: SecureBootVariableLib: Updated time based payload creator
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
  2022-06-13 20:39 ` [PATCH v2 01/11] SecurityPkg: UefiSecureBoot: Definitions of cert and payload structures Kun Qin
  2022-06-13 20:39 ` [PATCH v2 02/11] SecurityPkg: PlatformPKProtectionLib: Added PK protection interface Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 04/11] SecurityPkg: SecureBootVariableLib: Updated signature list creator Kun Qin
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: Kun Qin <kuqin@microsoft.com>

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

This change updated the interface of 'CreateTimeBasedPayload' by
requiring the caller to provide a timestamp, instead of relying on time
protocol to be ready during runtime. It intends to extend the library
availability during boot environment.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c   | 53 ++++++++++++--------
 SecurityPkg/Include/Library/SecureBootVariableLib.h                 |  9 +++-
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf |  8 +--
 3 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
index e0d137666e0e..3b33a356aba3 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
@@ -6,8 +6,10 @@
   (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
   Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
   Copyright (c) 2021, Semihalf All rights reserved.<BR>
+  Copyright (c) Microsoft Corporation.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
+#include <Uefi.h>
 #include <Guid/GlobalVariable.h>
 #include <Guid/AuthenticatedVariableFormat.h>
 #include <Guid/ImageAuthentication.h>
@@ -21,6 +23,21 @@
 #include <Library/SecureBootVariableLib.h>
 #include "Library/DxeServicesLib.h"
 
+// This time can be used when deleting variables, as it should be greater than any variable time.
+EFI_TIME  mMaxTimestamp = {
+  0xFFFF,     // Year
+  0xFF,       // Month
+  0xFF,       // Day
+  0xFF,       // Hour
+  0xFF,       // Minute
+  0xFF,       // Second
+  0x00,
+  0x00000000, // Nanosecond
+  0,
+  0,
+  0x00
+};
+
 /** Creates EFI Signature List structure.
 
   @param[in]      Data     A pointer to signature data.
@@ -118,7 +135,7 @@ ConcatenateSigList (
 
   @param[in]        KeyFileGuid    A pointer to to the FFS filename GUID
   @param[out]       SigListsSize   A pointer to size of signature list
-  @param[out]       SigListOut    a pointer to a callee-allocated buffer with signature lists
+  @param[out]       SigListsOut    a pointer to a callee-allocated buffer with signature lists
 
   @retval EFI_SUCCESS              Create time based payload successfully.
   @retval EFI_NOT_FOUND            Section with key has not been found.
@@ -210,28 +227,30 @@ SecureBootFetchData (
                                    pointer to NULL to wrap an empty payload.
                                    On output, Pointer to the new payload date buffer allocated from pool,
                                    it's caller's responsibility to free the memory when finish using it.
+  @param[in]        Time           Pointer to time information to created time based payload.
 
   @retval EFI_SUCCESS              Create time based payload successfully.
   @retval EFI_OUT_OF_RESOURCES     There are not enough memory resources to create time based payload.
   @retval EFI_INVALID_PARAMETER    The parameter is invalid.
   @retval Others                   Unexpected error happens.
 
-**/
+--*/
 EFI_STATUS
+EFIAPI
 CreateTimeBasedPayload (
-  IN OUT UINTN  *DataSize,
-  IN OUT UINT8  **Data
+  IN OUT UINTN     *DataSize,
+  IN OUT UINT8     **Data,
+  IN     EFI_TIME  *Time
   )
 {
-  EFI_STATUS                     Status;
   UINT8                          *NewData;
   UINT8                          *Payload;
   UINTN                          PayloadSize;
   EFI_VARIABLE_AUTHENTICATION_2  *DescriptorData;
   UINTN                          DescriptorSize;
-  EFI_TIME                       Time;
 
-  if ((Data == NULL) || (DataSize == NULL)) {
+  if ((Data == NULL) || (DataSize == NULL) || (Time == NULL)) {
+    DEBUG ((DEBUG_ERROR, "%a(), invalid arg\n", __FUNCTION__));
     return EFI_INVALID_PARAMETER;
   }
 
@@ -247,6 +266,7 @@ CreateTimeBasedPayload (
   DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
   NewData        = (UINT8 *)AllocateZeroPool (DescriptorSize + PayloadSize);
   if (NewData == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a() Out of resources.\n", __FUNCTION__));
     return EFI_OUT_OF_RESOURCES;
   }
 
@@ -256,19 +276,7 @@ CreateTimeBasedPayload (
 
   DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *)(NewData);
 
-  ZeroMem (&Time, sizeof (EFI_TIME));
-  Status = gRT->GetTime (&Time, NULL);
-  if (EFI_ERROR (Status)) {
-    FreePool (NewData);
-    return Status;
-  }
-
-  Time.Pad1       = 0;
-  Time.Nanosecond = 0;
-  Time.TimeZone   = 0;
-  Time.Daylight   = 0;
-  Time.Pad2       = 0;
-  CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME));
+  CopyMem (&DescriptorData->TimeStamp, Time, sizeof (EFI_TIME));
 
   DescriptorData->AuthInfo.Hdr.dwLength         = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
   DescriptorData->AuthInfo.Hdr.wRevision        = 0x0200;
@@ -277,6 +285,7 @@ CreateTimeBasedPayload (
 
   if (Payload != NULL) {
     FreePool (Payload);
+    Payload = NULL;
   }
 
   *DataSize = DescriptorSize + PayloadSize;
@@ -296,6 +305,7 @@ CreateTimeBasedPayload (
 
 **/
 EFI_STATUS
+EFIAPI
 DeleteVariable (
   IN  CHAR16    *VariableName,
   IN  EFI_GUID  *VendorGuid
@@ -319,7 +329,7 @@ DeleteVariable (
   Attr     = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS
              | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
 
-  Status = CreateTimeBasedPayload (&DataSize, &Data);
+  Status = CreateTimeBasedPayload (&DataSize, &Data, &mMaxTimestamp);
   if (EFI_ERROR (Status)) {
     DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
     return Status;
@@ -351,6 +361,7 @@ DeleteVariable (
 
 **/
 EFI_STATUS
+EFIAPI
 SetSecureBootMode (
   IN  UINT8  SecureBootMode
   )
diff --git a/SecurityPkg/Include/Library/SecureBootVariableLib.h b/SecurityPkg/Include/Library/SecureBootVariableLib.h
index 7b7afd9cde7c..9f2d41220b70 100644
--- a/SecurityPkg/Include/Library/SecureBootVariableLib.h
+++ b/SecurityPkg/Include/Library/SecureBootVariableLib.h
@@ -6,6 +6,7 @@ Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
 Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
 Copyright (c) 2021, Semihalf All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -24,6 +25,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 --*/
 EFI_STATUS
+EFIAPI
 SetSecureBootMode (
   IN  UINT8  SecureBootMode
   );
@@ -73,6 +75,7 @@ SecureBootFetchData (
                                    pointer to NULL to wrap an empty payload.
                                    On output, Pointer to the new payload date buffer allocated from pool,
                                    it's caller's responsibility to free the memory when finish using it.
+  @param[in]        Time           Pointer to time information to created time based payload.
 
   @retval EFI_SUCCESS              Create time based payload successfully.
   @retval EFI_OUT_OF_RESOURCES     There are not enough memory resources to create time based payload.
@@ -81,9 +84,11 @@ SecureBootFetchData (
 
 --*/
 EFI_STATUS
+EFIAPI
 CreateTimeBasedPayload (
-  IN OUT UINTN  *DataSize,
-  IN OUT UINT8  **Data
+  IN OUT UINTN     *DataSize,
+  IN OUT UINT8     **Data,
+  IN     EFI_TIME  *Time
   );
 
 /**
diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
index ed7af3dd9cd5..87db5a258021 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
@@ -4,6 +4,7 @@
 #
 #  Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
 #  Copyright (c) 2021, Semihalf All rights reserved.<BR>
+#  Copyright (c) Microsoft Corporation.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -68,12 +69,5 @@ [Guids]
   ## PRODUCES            ## Variable:L"CustomMode"
   gEfiCustomModeEnableGuid
 
-  gEfiCertTypeRsa2048Sha256Guid  ## CONSUMES
   gEfiCertX509Guid               ## CONSUMES
   gEfiCertPkcs7Guid              ## CONSUMES
-
-  gDefaultPKFileGuid
-  gDefaultKEKFileGuid
-  gDefaultdbFileGuid
-  gDefaultdbxFileGuid
-  gDefaultdbtFileGuid
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 04/11] SecurityPkg: SecureBootVariableLib: Updated signature list creator
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (2 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 03/11] SecurityPkg: SecureBootVariableLib: Updated time based payload creator Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 05/11] SecurityPkg: SecureBootVariableLib: Added newly supported interfaces Kun Qin
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: kuqin <kuqin@microsoft.com>

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

This change removes the interface of SecureBootFetchData, and replaced
it with `SecureBootCreateDataFromInput`, which will require caller to
prepare available certificates in defined structures.

This improvement will eliminate the dependency of reading from FV,
extending the availability of this library instance.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c   | 69 +++++++++++---------
 SecurityPkg/Include/Library/SecureBootVariableLib.h                 | 25 ++++---
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf |  3 -
 3 files changed, 53 insertions(+), 44 deletions(-)

diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
index 3b33a356aba3..f56f0322e943 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
@@ -10,10 +10,10 @@
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 #include <Uefi.h>
+#include <UefiSecureBoot.h>
 #include <Guid/GlobalVariable.h>
 #include <Guid/AuthenticatedVariableFormat.h>
 #include <Guid/ImageAuthentication.h>
-#include <Library/BaseCryptLib.h>
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
@@ -21,7 +21,6 @@
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiRuntimeServicesTableLib.h>
 #include <Library/SecureBootVariableLib.h>
-#include "Library/DxeServicesLib.h"
 
 // This time can be used when deleting variables, as it should be greater than any variable time.
 EFI_TIME  mMaxTimestamp = {
@@ -130,24 +129,29 @@ ConcatenateSigList (
 }
 
 /**
-  Create a EFI Signature List with data fetched from section specified as a argument.
-  Found keys are verified using RsaGetPublicKeyFromX509().
+  Create a EFI Signature List with data supplied from input argument.
+  The input certificates from KeyInfo parameter should be DER-encoded
+  format.
 
-  @param[in]        KeyFileGuid    A pointer to to the FFS filename GUID
   @param[out]       SigListsSize   A pointer to size of signature list
-  @param[out]       SigListsOut    a pointer to a callee-allocated buffer with signature lists
+  @param[out]       SigListOut     A pointer to a callee-allocated buffer with signature lists
+  @param[in]        KeyInfoCount   The number of certificate pointer and size pairs inside KeyInfo.
+  @param[in]        KeyInfo        A pointer to all certificates, in the format of DER-encoded,
+                                   to be concatenated into signature lists.
 
-  @retval EFI_SUCCESS              Create time based payload successfully.
+  @retval EFI_SUCCESS              Created signature list from payload successfully.
   @retval EFI_NOT_FOUND            Section with key has not been found.
-  @retval EFI_INVALID_PARAMETER    Embedded key has a wrong format.
+  @retval EFI_INVALID_PARAMETER    Embedded key has a wrong format or input pointers are NULL.
   @retval Others                   Unexpected error happens.
 
 **/
 EFI_STATUS
-SecureBootFetchData (
-  IN  EFI_GUID            *KeyFileGuid,
-  OUT UINTN               *SigListsSize,
-  OUT EFI_SIGNATURE_LIST  **SigListOut
+EFIAPI
+SecureBootCreateDataFromInput (
+  OUT UINTN                               *SigListsSize,
+  OUT EFI_SIGNATURE_LIST                  **SigListOut,
+  IN  UINTN                               KeyInfoCount,
+  IN  CONST SECURE_BOOT_CERTIFICATE_INFO  *KeyInfo
   )
 {
   EFI_SIGNATURE_LIST  *EfiSig;
@@ -155,36 +159,41 @@ SecureBootFetchData (
   EFI_SIGNATURE_LIST  *TmpEfiSig2;
   EFI_STATUS          Status;
   VOID                *Buffer;
-  VOID                *RsaPubKey;
   UINTN               Size;
+  UINTN               InputIndex;
   UINTN               KeyIndex;
 
+  if ((SigListOut == NULL) || (SigListsSize == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((KeyInfoCount == 0) || (KeyInfo == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InputIndex    = 0;
   KeyIndex      = 0;
   EfiSig        = NULL;
   *SigListsSize = 0;
-  while (1) {
-    Status = GetSectionFromAnyFv (
-               KeyFileGuid,
-               EFI_SECTION_RAW,
-               KeyIndex,
-               &Buffer,
-               &Size
-               );
-
-    if (Status == EFI_SUCCESS) {
-      RsaPubKey = NULL;
-      if (RsaGetPublicKeyFromX509 (Buffer, Size, &RsaPubKey) == FALSE) {
-        DEBUG ((DEBUG_ERROR, "%a: Invalid key format: %d\n", __FUNCTION__, KeyIndex));
+  while (InputIndex < KeyInfoCount) {
+    if (KeyInfo[InputIndex].Data != NULL) {
+      Size   = KeyInfo[InputIndex].DataSize;
+      Buffer = AllocateCopyPool (Size, KeyInfo[InputIndex].Data);
+      if (Buffer == NULL) {
         if (EfiSig != NULL) {
           FreePool (EfiSig);
         }
 
-        FreePool (Buffer);
-        return EFI_INVALID_PARAMETER;
+        return EFI_OUT_OF_RESOURCES;
       }
 
       Status = CreateSigList (Buffer, Size, &TmpEfiSig);
 
+      if (EFI_ERROR (Status)) {
+        FreePool (Buffer);
+        break;
+      }
+
       //
       // Concatenate lists if more than one section found
       //
@@ -202,9 +211,7 @@ SecureBootFetchData (
       FreePool (Buffer);
     }
 
-    if (Status == EFI_NOT_FOUND) {
-      break;
-    }
+    InputIndex++;
   }
 
   if (KeyIndex == 0) {
diff --git a/SecurityPkg/Include/Library/SecureBootVariableLib.h b/SecurityPkg/Include/Library/SecureBootVariableLib.h
index 9f2d41220b70..24ff0df067fa 100644
--- a/SecurityPkg/Include/Library/SecureBootVariableLib.h
+++ b/SecurityPkg/Include/Library/SecureBootVariableLib.h
@@ -44,24 +44,29 @@ GetSetupMode (
   );
 
 /**
-  Create a EFI Signature List with data fetched from section specified as a argument.
-  Found keys are verified using RsaGetPublicKeyFromX509().
+  Create a EFI Signature List with data supplied from input argument.
+  The input certificates from KeyInfo parameter should be DER-encoded
+  format.
 
-  @param[in]        KeyFileGuid    A pointer to to the FFS filename GUID
   @param[out]       SigListsSize   A pointer to size of signature list
-  @param[out]       SigListsOut    a pointer to a callee-allocated buffer with signature lists
+  @param[out]       SigListOut     A pointer to a callee-allocated buffer with signature lists
+  @param[in]        KeyInfoCount   The number of certificate pointer and size pairs inside KeyInfo.
+  @param[in]        KeyInfo        A pointer to all certificates, in the format of DER-encoded,
+                                   to be concatenated into signature lists.
 
-  @retval EFI_SUCCESS              Create time based payload successfully.
+  @retval EFI_SUCCESS              Created signature list from payload successfully.
   @retval EFI_NOT_FOUND            Section with key has not been found.
-  @retval EFI_INVALID_PARAMETER    Embedded key has a wrong format.
+  @retval EFI_INVALID_PARAMETER    Embedded key has a wrong format or input pointers are NULL.
   @retval Others                   Unexpected error happens.
 
 --*/
 EFI_STATUS
-SecureBootFetchData (
-  IN  EFI_GUID            *KeyFileGuid,
-  OUT UINTN               *SigListsSize,
-  OUT EFI_SIGNATURE_LIST  **SigListOut
+EFIAPI
+SecureBootCreateDataFromInput (
+  OUT UINTN                               *SigListsSize,
+  OUT EFI_SIGNATURE_LIST                  **SigListOut,
+  IN  UINTN                               KeyInfoCount,
+  IN  CONST SECURE_BOOT_CERTIFICATE_INFO  *KeyInfo
   );
 
 /**
diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
index 87db5a258021..3d4b77cfb073 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
@@ -32,15 +32,12 @@ [Packages]
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
   SecurityPkg/SecurityPkg.dec
-  CryptoPkg/CryptoPkg.dec
 
 [LibraryClasses]
   BaseLib
   BaseMemoryLib
   DebugLib
   MemoryAllocationLib
-  BaseCryptLib
-  DxeServicesLib
 
 [Guids]
   ## CONSUMES            ## Variable:L"SetupMode"
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 05/11] SecurityPkg: SecureBootVariableLib: Added newly supported interfaces
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (3 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 04/11] SecurityPkg: SecureBootVariableLib: Updated signature list creator Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 06/11] SecurityPkg: SecureBootVariableProvisionLib: Updated implementation Kun Qin
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: kuqin <kuqin@microsoft.com>

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

This change updated the interfaces provided by SecureBootVariableLib.

The new additions provided interfaces to enroll single authenticated
variable from input, a helper function to query secure boot status,
enroll all secure boot variables from UefiSecureBoot.h defined data
structures, a as well as a routine that deletes all secure boot related
variables.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c   | 366 ++++++++++++++++++++
 SecurityPkg/Include/Library/SecureBootVariableLib.h                 |  69 ++++
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf |   3 +
 3 files changed, 438 insertions(+)

diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
index f56f0322e943..6718133aa6e4 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
@@ -21,6 +21,7 @@
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiRuntimeServicesTableLib.h>
 #include <Library/SecureBootVariableLib.h>
+#include <Library/PlatformPKProtectionLib.h>
 
 // This time can be used when deleting variables, as it should be greater than any variable time.
 EFI_TIME  mMaxTimestamp = {
@@ -37,6 +38,25 @@ EFI_TIME  mMaxTimestamp = {
   0x00
 };
 
+//
+// MS Default Time-Based Payload Creation Date
+// This is the date that is used when creating SecureBoot default variables.
+// NOTE: This is a placeholder date that doesn't correspond to anything else.
+//
+EFI_TIME  mDefaultPayloadTimestamp = {
+  15,   // Year (2015)
+  8,    // Month (Aug)
+  28,   // Day (28)
+  0,    // Hour
+  0,    // Minute
+  0,    // Second
+  0,    // Pad1
+  0,    // Nanosecond
+  0,    // Timezone (Dummy value)
+  0,    // Daylight (Dummy value)
+  0     // Pad2
+};
+
 /** Creates EFI Signature List structure.
 
   @param[in]      Data     A pointer to signature data.
@@ -413,6 +433,44 @@ GetSetupMode (
   return EFI_SUCCESS;
 }
 
+/**
+  Helper function to quickly determine whether SecureBoot is enabled.
+
+  @retval     TRUE    SecureBoot is verifiably enabled.
+  @retval     FALSE   SecureBoot is either disabled or an error prevented checking.
+
+**/
+BOOLEAN
+EFIAPI
+IsSecureBootEnabled (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       *SecureBoot;
+
+  SecureBoot = NULL;
+
+  Status = GetEfiGlobalVariable2 (EFI_SECURE_BOOT_MODE_NAME, (VOID **)&SecureBoot, NULL);
+  //
+  // Skip verification if SecureBoot variable doesn't exist.
+  //
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Cannot check SecureBoot variable %r \n ", Status));
+    return FALSE;
+  }
+
+  //
+  // Skip verification if SecureBoot is disabled but not AuditMode
+  //
+  if (*SecureBoot == SECURE_BOOT_MODE_DISABLE) {
+    FreePool (SecureBoot);
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
+
 /**
   Clears the content of the 'db' variable.
 
@@ -531,3 +589,311 @@ DeletePlatformKey (
              );
   return Status;
 }
+
+/**
+  This function will delete the secure boot keys, thus
+  disabling secure boot.
+
+  @return EFI_SUCCESS or underlying failure code.
+**/
+EFI_STATUS
+EFIAPI
+DeleteSecureBootVariables (
+  VOID
+  )
+{
+  EFI_STATUS  Status, TempStatus;
+
+  DEBUG ((DEBUG_INFO, "%a - Attempting to delete the Secure Boot variables.\n", __FUNCTION__));
+
+  //
+  // Step 1: Notify that a PK update is coming shortly...
+  Status = DisablePKProtection ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a - Failed to signal PK update start! %r\n", __FUNCTION__, Status));
+    // Classify this as a PK deletion error.
+    Status = EFI_ABORTED;
+  }
+
+  //
+  // Step 2: Attempt to delete the PK.
+  // Let's try to nuke the PK, why not...
+  if (!EFI_ERROR (Status)) {
+    Status = DeletePlatformKey ();
+    DEBUG ((DEBUG_INFO, "%a - PK Delete = %r\n", __FUNCTION__, Status));
+    // If the PK is not found, then our work here is done.
+    if (Status == EFI_NOT_FOUND) {
+      Status = EFI_SUCCESS;
+    }
+    // If any other error occurred, let's inform the caller that the PK delete in particular failed.
+    else if (EFI_ERROR (Status)) {
+      Status = EFI_ABORTED;
+    }
+  }
+
+  //
+  // Step 3: Attempt to delete remaining keys/databases...
+  // Now that the PK is deleted (assuming Status == EFI_SUCCESS) the system is in SETUP_MODE.
+  // Arguably we could leave these variables in place and let them be deleted by whoever wants to
+  // update all the SecureBoot variables. However, for cleanliness sake, let's try to
+  // get rid of them here.
+  if (!EFI_ERROR (Status)) {
+    //
+    // If any of THESE steps have an error, report the error but attempt to delete all keys.
+    // Using TempStatus will prevent an error from being trampled by an EFI_SUCCESS.
+    // Overwrite Status ONLY if TempStatus is an error.
+    //
+    // If the error is EFI_NOT_FOUND, we can safely ignore it since we were trying to delete
+    // the variables anyway.
+    //
+    TempStatus = DeleteKEK ();
+    DEBUG ((DEBUG_INFO, "%a - KEK Delete = %r\n", __FUNCTION__, TempStatus));
+    if (EFI_ERROR (TempStatus) && (TempStatus != EFI_NOT_FOUND)) {
+      Status = EFI_ACCESS_DENIED;
+    }
+
+    TempStatus = DeleteDb ();
+    DEBUG ((DEBUG_INFO, "%a - db Delete = %r\n", __FUNCTION__, TempStatus));
+    if (EFI_ERROR (TempStatus) && (TempStatus != EFI_NOT_FOUND)) {
+      Status = EFI_ACCESS_DENIED;
+    }
+
+    TempStatus = DeleteDbx ();
+    DEBUG ((DEBUG_INFO, "%a - dbx Delete = %r\n", __FUNCTION__, TempStatus));
+    if (EFI_ERROR (TempStatus) && (TempStatus != EFI_NOT_FOUND)) {
+      Status = EFI_ACCESS_DENIED;
+    }
+
+    TempStatus = DeleteDbt ();
+    DEBUG ((DEBUG_INFO, "%a - dbt Delete = %r\n", __FUNCTION__, TempStatus));
+    if (EFI_ERROR (TempStatus) && (TempStatus != EFI_NOT_FOUND)) {
+      Status = EFI_ACCESS_DENIED;
+    }
+  }
+
+  return Status;
+}// DeleteSecureBootVariables()
+
+/**
+  A helper function to take in a variable payload, wrap it in the
+  proper authenticated variable structure, and install it in the
+  EFI variable space.
+
+  @param[in]  VariableName  The name of the key/database.
+  @param[in]  VendorGuid    The namespace (ie. vendor GUID) of the variable
+  @param[in]  DataSize      Size parameter for target secure boot variable.
+  @param[in]  Data          Pointer to signature list formatted secure boot variable content.
+
+  @retval EFI_SUCCESS              The enrollment for authenticated variable was successful.
+  @retval EFI_OUT_OF_RESOURCES     There are not enough memory resources to create time based payload.
+  @retval EFI_INVALID_PARAMETER    The parameter is invalid.
+  @retval Others                   Unexpected error happens.
+**/
+EFI_STATUS
+EFIAPI
+EnrollFromInput (
+  IN CHAR16    *VariableName,
+  IN EFI_GUID  *VendorGuid,
+  IN UINTN     DataSize,
+  IN VOID      *Data
+  )
+{
+  VOID        *Payload;
+  UINTN       PayloadSize;
+  EFI_STATUS  Status;
+
+  Payload = NULL;
+
+  if ((VariableName == NULL) || (VendorGuid == 0)) {
+    DEBUG ((DEBUG_ERROR, "Input vendor variable invalid: %p and %p\n", VariableName, VendorGuid));
+    Status = EFI_INVALID_PARAMETER;
+    goto Exit;
+  }
+
+  if ((Data == NULL) || (DataSize == 0)) {
+    // You might as well just use DeleteVariable...
+    DEBUG ((DEBUG_ERROR, "Input argument invalid: %p: %x\n", Data, DataSize));
+    Status = EFI_INVALID_PARAMETER;
+    goto Exit;
+  }
+
+  // Bring in the noise...
+  PayloadSize = DataSize;
+  Payload     = AllocateZeroPool (DataSize);
+  // Bring in the funk...
+  if (Payload == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  } else {
+    CopyMem (Payload, Data, DataSize);
+  }
+
+  Status = CreateTimeBasedPayload (&PayloadSize, (UINT8 **)&Payload, &mDefaultPayloadTimestamp);
+  if (EFI_ERROR (Status) || (Payload == NULL)) {
+    DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r\n", Status));
+    Payload = NULL;
+    Status  = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+
+  //
+  // Allocate memory for auth variable
+  //
+  Status = gRT->SetVariable (
+                  VariableName,
+                  VendorGuid,
+                  (EFI_VARIABLE_NON_VOLATILE |
+                   EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                   EFI_VARIABLE_RUNTIME_ACCESS |
+                   EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
+                  PayloadSize,
+                  Payload
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "error: %a (\"%s\", %g): %r\n",
+      __FUNCTION__,
+      VariableName,
+      VendorGuid,
+      Status
+      ));
+  }
+
+Exit:
+  //
+  // Always Put Away Your Toys
+  // Payload will be reassigned by CreateTimeBasedPayload()...
+  if (Payload != NULL) {
+    FreePool (Payload);
+    Payload = NULL;
+  }
+
+  return Status;
+}
+
+/**
+  Similar to DeleteSecureBootVariables, this function is used to unilaterally
+  force the state of related SB variables (db, dbx, dbt, KEK, PK, etc.) to be
+  the built-in, hardcoded default vars.
+
+  @param[in]  SecureBootPayload  Payload information for secure boot related keys.
+
+  @retval     EFI_SUCCESS               SecureBoot keys are now set to defaults.
+  @retval     EFI_ABORTED               SecureBoot keys are not empty. Please delete keys first
+                                        or follow standard methods of altering keys (ie. use the signing system).
+  @retval     EFI_SECURITY_VIOLATION    Failed to create the PK.
+  @retval     Others                    Something failed in one of the subfunctions.
+
+**/
+EFI_STATUS
+EFIAPI
+SetSecureBootVariablesToDefault (
+  IN  CONST SECURE_BOOT_PAYLOAD_INFO  *SecureBootPayload
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       *Data;
+  UINTN       DataSize;
+
+  DEBUG ((DEBUG_INFO, "%a() Entry\n", __FUNCTION__));
+
+  if (SecureBootPayload == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a - Invalid SecureBoot payload is supplied!\n", __FUNCTION__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Right off the bat, if SecureBoot is currently enabled, bail.
+  if (IsSecureBootEnabled ()) {
+    DEBUG ((DEBUG_ERROR, "%a - Cannot set default keys while SecureBoot is enabled!\n", __FUNCTION__));
+    return EFI_ABORTED;
+  }
+
+  DEBUG ((DEBUG_INFO, "%a - Setting up key %s!\n", __FUNCTION__, SecureBootPayload->SecureBootKeyName));
+
+  //
+  // Start running down the list, creating variables in our wake.
+  // dbx is a good place to start.
+  Data     = (UINT8 *)SecureBootPayload->DbxPtr;
+  DataSize = SecureBootPayload->DbxSize;
+  Status   = EnrollFromInput (
+               EFI_IMAGE_SECURITY_DATABASE1,
+               &gEfiImageSecurityDatabaseGuid,
+               DataSize,
+               Data
+               );
+
+  // If that went well, try the db (make sure to pick the right one!).
+  if (!EFI_ERROR (Status)) {
+    Data     = (UINT8 *)SecureBootPayload->DbPtr;
+    DataSize = SecureBootPayload->DbSize;
+    Status   = EnrollFromInput (
+                 EFI_IMAGE_SECURITY_DATABASE,
+                 &gEfiImageSecurityDatabaseGuid,
+                 DataSize,
+                 Data
+                 );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a - Failed to enroll DB %r!\n", __FUNCTION__, Status));
+    }
+  } else {
+    DEBUG ((DEBUG_ERROR, "%a - Failed to enroll DBX %r!\n", __FUNCTION__, Status));
+  }
+
+  // Keep it going. Keep it going. dbt if supplied...
+  if (!EFI_ERROR (Status) && (SecureBootPayload->DbtPtr != NULL)) {
+    Data     = (UINT8 *)SecureBootPayload->DbtPtr;
+    DataSize = SecureBootPayload->DbtSize;
+    Status   = EnrollFromInput (
+                 EFI_IMAGE_SECURITY_DATABASE2,
+                 &gEfiImageSecurityDatabaseGuid,
+                 DataSize,
+                 Data
+                 );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a - Failed to enroll DBT %r!\n", __FUNCTION__, Status));
+    }
+  }
+
+  // Keep it going. Keep it going. KEK...
+  if (!EFI_ERROR (Status)) {
+    Data     = (UINT8 *)SecureBootPayload->KekPtr;
+    DataSize = SecureBootPayload->KekSize;
+    Status   = EnrollFromInput (
+                 EFI_KEY_EXCHANGE_KEY_NAME,
+                 &gEfiGlobalVariableGuid,
+                 DataSize,
+                 Data
+                 );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a - Failed to enroll KEK %r!\n", __FUNCTION__, Status));
+    }
+  }
+
+  //
+  // Finally! The Big Daddy of them all.
+  // The PK!
+  //
+  if (!EFI_ERROR (Status)) {
+    //
+    // Finally, install the key.
+    Data     = (UINT8 *)SecureBootPayload->PkPtr;
+    DataSize = SecureBootPayload->PkSize;
+    Status   = EnrollFromInput (
+                 EFI_PLATFORM_KEY_NAME,
+                 &gEfiGlobalVariableGuid,
+                 DataSize,
+                 Data
+                 );
+
+    //
+    // Report PK creation errors.
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a - Failed to update the PK! - %r\n", __FUNCTION__, Status));
+      Status = EFI_SECURITY_VIOLATION;
+    }
+  }
+
+  return Status;
+}
diff --git a/SecurityPkg/Include/Library/SecureBootVariableLib.h b/SecurityPkg/Include/Library/SecureBootVariableLib.h
index 24ff0df067fa..c486801c318b 100644
--- a/SecurityPkg/Include/Library/SecureBootVariableLib.h
+++ b/SecurityPkg/Include/Library/SecureBootVariableLib.h
@@ -43,6 +43,19 @@ GetSetupMode (
   OUT UINT8  *SetupMode
   );
 
+/**
+  Helper function to quickly determine whether SecureBoot is enabled.
+
+  @retval     TRUE    SecureBoot is verifiably enabled.
+  @retval     FALSE   SecureBoot is either disabled or an error prevented checking.
+
+**/
+BOOLEAN
+EFIAPI
+IsSecureBootEnabled (
+  VOID
+  );
+
 /**
   Create a EFI Signature List with data supplied from input argument.
   The input certificates from KeyInfo parameter should be DER-encoded
@@ -161,4 +174,60 @@ DeletePlatformKey (
   VOID
   );
 
+/**
+  This function will delete the secure boot keys, thus
+  disabling secure boot.
+
+  @return EFI_SUCCESS or underlying failure code.
+**/
+EFI_STATUS
+EFIAPI
+DeleteSecureBootVariables (
+  VOID
+  );
+
+/**
+  A helper function to take in a variable payload, wrap it in the
+  proper authenticated variable structure, and install it in the
+  EFI variable space.
+
+  @param[in]  VariableName  The name of the key/database.
+  @param[in]  VendorGuid    The namespace (ie. vendor GUID) of the variable
+  @param[in]  DataSize      Size parameter for target secure boot variable.
+  @param[in]  Data          Pointer to signature list formatted secure boot variable content.
+
+  @retval EFI_SUCCESS              The enrollment for authenticated variable was successful.
+  @retval EFI_OUT_OF_RESOURCES     There are not enough memory resources to create time based payload.
+  @retval EFI_INVALID_PARAMETER    The parameter is invalid.
+  @retval Others                   Unexpected error happens.
+**/
+EFI_STATUS
+EFIAPI
+EnrollFromInput (
+  IN CHAR16    *VariableName,
+  IN EFI_GUID  *VendorGuid,
+  IN UINTN     DataSize,
+  IN VOID      *Data
+  );
+
+/**
+  Similar to DeleteSecureBootVariables, this function is used to unilaterally
+  force the state of related SB variables (db, dbx, dbt, KEK, PK, etc.) to be
+  the built-in, hardcoded default vars.
+
+  @param[in]  SecureBootPayload  Payload information for secure boot related keys.
+
+  @retval     EFI_SUCCESS               SecureBoot keys are now set to defaults.
+  @retval     EFI_ABORTED               SecureBoot keys are not empty. Please delete keys first
+                                        or follow standard methods of altering keys (ie. use the signing system).
+  @retval     EFI_SECURITY_VIOLATION    Failed to create the PK.
+  @retval     Others                    Something failed in one of the subfunctions.
+
+**/
+EFI_STATUS
+EFIAPI
+SetSecureBootVariablesToDefault (
+  IN  CONST SECURE_BOOT_PAYLOAD_INFO  *SecureBootPayload
+  );
+
 #endif
diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
index 3d4b77cfb073..eabe9db6c93f 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
@@ -38,6 +38,9 @@ [LibraryClasses]
   BaseMemoryLib
   DebugLib
   MemoryAllocationLib
+  PlatformPKProtectionLib
+  UefiLib
+  UefiRuntimeServicesTableLib
 
 [Guids]
   ## CONSUMES            ## Variable:L"SetupMode"
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 06/11] SecurityPkg: SecureBootVariableProvisionLib: Updated implementation
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (4 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 05/11] SecurityPkg: SecureBootVariableLib: Added newly supported interfaces Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 07/11] SecurityPkg: Secure Boot Drivers: Added common header files Kun Qin
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: Kun Qin <kuqin@microsoft.com>

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

This change is in pair with the previous SecureBootVariableLib, which
removes the explicit invocation of `CreateTimeBasedPayload` and used new
interface `EnrollFromInput` instead.

The original `SecureBootFetchData` is also moved to this library and
incorporated with the newly defined `SecureBootCreateDataFromInput` to
keep the original code flow.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c | 145 ++++++++++++++++----
 1 file changed, 115 insertions(+), 30 deletions(-)

diff --git a/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c b/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
index 536b0f369907..bed1fe86205d 100644
--- a/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
+++ b/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
@@ -8,10 +8,13 @@
   Copyright (c) 2021, Semihalf All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
+#include <Uefi.h>
+#include <UefiSecureBoot.h>
 #include <Guid/GlobalVariable.h>
 #include <Guid/AuthenticatedVariableFormat.h>
 #include <Guid/ImageAuthentication.h>
 #include <Library/BaseLib.h>
+#include <Library/BaseCryptLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
 #include <Library/UefiLib.h>
@@ -19,6 +22,117 @@
 #include <Library/UefiRuntimeServicesTableLib.h>
 #include <Library/SecureBootVariableLib.h>
 #include <Library/SecureBootVariableProvisionLib.h>
+#include <Library/DxeServicesLib.h>
+
+/**
+  Create a EFI Signature List with data fetched from section specified as a argument.
+  Found keys are verified using RsaGetPublicKeyFromX509().
+
+  @param[in]        KeyFileGuid    A pointer to to the FFS filename GUID
+  @param[out]       SigListsSize   A pointer to size of signature list
+  @param[out]       SigListOut    a pointer to a callee-allocated buffer with signature lists
+
+  @retval EFI_SUCCESS              Create time based payload successfully.
+  @retval EFI_NOT_FOUND            Section with key has not been found.
+  @retval EFI_INVALID_PARAMETER    Embedded key has a wrong format.
+  @retval Others                   Unexpected error happens.
+
+**/
+STATIC
+EFI_STATUS
+SecureBootFetchData (
+  IN  EFI_GUID            *KeyFileGuid,
+  OUT UINTN               *SigListsSize,
+  OUT EFI_SIGNATURE_LIST  **SigListOut
+  )
+{
+  EFI_SIGNATURE_LIST            *EfiSig;
+  EFI_STATUS                    Status;
+  VOID                          *Buffer;
+  VOID                          *RsaPubKey;
+  UINTN                         Size;
+  UINTN                         KeyIndex;
+  UINTN                         Index;
+  SECURE_BOOT_CERTIFICATE_INFO  *CertInfo;
+  SECURE_BOOT_CERTIFICATE_INFO  *NewCertInfo;
+
+  KeyIndex      = 0;
+  EfiSig        = NULL;
+  *SigListOut   = NULL;
+  *SigListsSize = 0;
+  CertInfo      = AllocatePool (sizeof (SECURE_BOOT_CERTIFICATE_INFO));
+  NewCertInfo   = CertInfo;
+  while (1) {
+    if (NewCertInfo == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      break;
+    } else {
+      CertInfo = NewCertInfo;
+    }
+
+    Status = GetSectionFromAnyFv (
+               KeyFileGuid,
+               EFI_SECTION_RAW,
+               KeyIndex,
+               &Buffer,
+               &Size
+               );
+
+    if (Status == EFI_SUCCESS) {
+      RsaPubKey = NULL;
+      if (RsaGetPublicKeyFromX509 (Buffer, Size, &RsaPubKey) == FALSE) {
+        DEBUG ((DEBUG_ERROR, "%a: Invalid key format: %d\n", __FUNCTION__, KeyIndex));
+        if (EfiSig != NULL) {
+          FreePool (EfiSig);
+        }
+
+        FreePool (Buffer);
+        Status = EFI_INVALID_PARAMETER;
+        break;
+      }
+
+      CertInfo[KeyIndex].Data     = Buffer;
+      CertInfo[KeyIndex].DataSize = Size;
+      KeyIndex++;
+      NewCertInfo = ReallocatePool (
+                      sizeof (SECURE_BOOT_CERTIFICATE_INFO) * KeyIndex,
+                      sizeof (SECURE_BOOT_CERTIFICATE_INFO) * (KeyIndex + 1),
+                      CertInfo
+                      );
+    }
+
+    if (Status == EFI_NOT_FOUND) {
+      Status = EFI_SUCCESS;
+      break;
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+    goto Cleanup;
+  }
+
+  if (KeyIndex == 0) {
+    Status = EFI_NOT_FOUND;
+    goto Cleanup;
+  }
+
+  // Now that we collected all certs from FV, convert it into sig list
+  Status = SecureBootCreateDataFromInput (SigListsSize, SigListOut, KeyIndex, CertInfo);
+  if (EFI_ERROR (Status)) {
+    goto Cleanup;
+  }
+
+Cleanup:
+  if (CertInfo) {
+    for (Index = 0; Index < KeyIndex; Index++) {
+      FreePool ((VOID *)CertInfo[Index].Data);
+    }
+
+    FreePool (CertInfo);
+  }
+
+  return Status;
+}
 
 /**
   Enroll a key/certificate based on a default variable.
@@ -52,36 +166,7 @@ EnrollFromDefault (
     return Status;
   }
 
-  CreateTimeBasedPayload (&DataSize, (UINT8 **)&Data);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
-    return Status;
-  }
-
-  //
-  // Allocate memory for auth variable
-  //
-  Status = gRT->SetVariable (
-                  VariableName,
-                  VendorGuid,
-                  (EFI_VARIABLE_NON_VOLATILE |
-                   EFI_VARIABLE_BOOTSERVICE_ACCESS |
-                   EFI_VARIABLE_RUNTIME_ACCESS |
-                   EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
-                  DataSize,
-                  Data
-                  );
-
-  if (EFI_ERROR (Status)) {
-    DEBUG ((
-      DEBUG_ERROR,
-      "error: %a (\"%s\", %g): %r\n",
-      __FUNCTION__,
-      VariableName,
-      VendorGuid,
-      Status
-      ));
-  }
+  Status = EnrollFromInput (VariableName, VendorGuid, DataSize, Data);
 
   if (Data != NULL) {
     FreePool (Data);
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 07/11] SecurityPkg: Secure Boot Drivers: Added common header files
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (5 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 06/11] SecurityPkg: SecureBootVariableProvisionLib: Updated implementation Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 08/11] SecurityPkg: SecureBootConfigDxe: Updated invocation pattern Kun Qin
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: Kun Qin <kuqin@microsoft.com>

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

This change added common header files to consumer drivers to unblock
pipeline builds.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.c                       | 1 +
 SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c          | 1 +
 SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.c | 1 +
 3 files changed, 3 insertions(+)

diff --git a/SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.c b/SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.c
index cb7095b269b1..aa4d0c7a993d 100644
--- a/SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.c
+++ b/SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.c
@@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/UefiLib.h>                     // AsciiPrint()
 #include <Library/UefiRuntimeServicesTableLib.h> // gRT
 #include <Uefi/UefiMultiPhase.h>
+#include <UefiSecureBoot.h>
 #include <Library/SecureBootVariableLib.h>
 #include <Library/SecureBootVariableProvisionLib.h>
 
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index 0122e8d55fa0..a13c349a0f89 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -8,6 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
 #include "SecureBootConfigImpl.h"
+#include <UefiSecureBoot.h>
 #include <Protocol/HiiPopup.h>
 #include <Library/BaseCryptLib.h>
 #include <Library/SecureBootVariableLib.h>
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.c b/SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.c
index ef7b01f16119..0abde52a05ae 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.c
@@ -15,6 +15,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiRuntimeServicesTableLib.h>
+#include <UefiSecureBoot.h>
 #include <Library/SecureBootVariableLib.h>
 #include <Library/SecureBootVariableProvisionLib.h>
 
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 08/11] SecurityPkg: SecureBootConfigDxe: Updated invocation pattern
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (6 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 07/11] SecurityPkg: Secure Boot Drivers: Added common header files Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 09/11] SecurityPkg: SecureBootVariableLib: Added unit tests Kun Qin
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: Kun Qin <kuqin@microsoft.com>

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

This change is in pair with the previous SecureBootVariableLib change,
which updated the interface of `CreateTimeBasedPayload`.

This change added a helper function to query the current time through
Real Time Clock protocol. This function is used when needing to format
an authenticated variable payload.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c  | 127 ++++++++++++++++++--
 SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf |   1 +
 2 files changed, 119 insertions(+), 9 deletions(-)

diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index a13c349a0f89..4299a6b5e56d 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -10,6 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include "SecureBootConfigImpl.h"
 #include <UefiSecureBoot.h>
 #include <Protocol/HiiPopup.h>
+#include <Protocol/RealTimeClock.h>
 #include <Library/BaseCryptLib.h>
 #include <Library/SecureBootVariableLib.h>
 #include <Library/SecureBootVariableProvisionLib.h>
@@ -136,6 +137,51 @@ CloseEnrolledFile (
   FileContext->FileType = UNKNOWN_FILE_TYPE;
 }
 
+/**
+  Helper function to populate an EFI_TIME instance.
+
+  @param[in] Time   FileContext cached in SecureBootConfig driver
+
+**/
+STATIC
+EFI_STATUS
+GetCurrentTime (
+  IN EFI_TIME  *Time
+  )
+{
+  EFI_STATUS  Status;
+  VOID        *TestPointer;
+
+  if (Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiRealTimeClockArchProtocolGuid, NULL, &TestPointer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ZeroMem (Time, sizeof (EFI_TIME));
+  Status = gRT->GetTime (Time, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a(), GetTime() failed, status = '%r'\n",
+      __FUNCTION__,
+      Status
+      ));
+    return Status;
+  }
+
+  Time->Pad1       = 0;
+  Time->Nanosecond = 0;
+  Time->TimeZone   = 0;
+  Time->Daylight   = 0;
+  Time->Pad2       = 0;
+
+  return EFI_SUCCESS;
+}
+
 /**
   This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix.
 
@@ -436,6 +482,7 @@ EnrollPlatformKey (
   UINT32              Attr;
   UINTN               DataSize;
   EFI_SIGNATURE_LIST  *PkCert;
+  EFI_TIME            Time;
 
   PkCert = NULL;
 
@@ -463,7 +510,13 @@ EnrollPlatformKey (
   Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
          | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
   DataSize = PkCert->SignatureListSize;
-  Status   = CreateTimeBasedPayload (&DataSize, (UINT8 **)&PkCert);
+  Status   = GetCurrentTime (&Time);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+    goto ON_EXIT;
+  }
+
+  Status = CreateTimeBasedPayload (&DataSize, (UINT8 **)&PkCert, &Time);
   if (EFI_ERROR (Status)) {
     DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
     goto ON_EXIT;
@@ -522,6 +575,7 @@ EnrollRsa2048ToKek (
   UINTN               KekSigListSize;
   UINT8               *KeyBuffer;
   UINTN               KeyLenInBytes;
+  EFI_TIME            Time;
 
   Attr           = 0;
   DataSize       = 0;
@@ -608,7 +662,13 @@ EnrollRsa2048ToKek (
   //
   Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
          | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
-  Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8 **)&KekSigList);
+  Status = GetCurrentTime (&Time);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+    goto ON_EXIT;
+  }
+
+  Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8 **)&KekSigList, &Time);
   if (EFI_ERROR (Status)) {
     DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
     goto ON_EXIT;
@@ -689,6 +749,7 @@ EnrollX509ToKek (
   UINTN               DataSize;
   UINTN               KekSigListSize;
   UINT32              Attr;
+  EFI_TIME            Time;
 
   X509Data       = NULL;
   X509DataSize   = 0;
@@ -735,7 +796,13 @@ EnrollX509ToKek (
   //
   Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
          | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
-  Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8 **)&KekSigList);
+  Status = GetCurrentTime (&Time);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+    goto ON_EXIT;
+  }
+
+  Status = CreateTimeBasedPayload (&KekSigListSize, (UINT8 **)&KekSigList, &Time);
   if (EFI_ERROR (Status)) {
     DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
     goto ON_EXIT;
@@ -861,6 +928,7 @@ EnrollX509toSigDB (
   UINTN               DataSize;
   UINTN               SigDBSize;
   UINT32              Attr;
+  EFI_TIME            Time;
 
   X509DataSize  = 0;
   SigDBSize     = 0;
@@ -910,7 +978,13 @@ EnrollX509toSigDB (
   //
   Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
          | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
-  Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **)&Data);
+  Status = GetCurrentTime (&Time);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+    goto ON_EXIT;
+  }
+
+  Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **)&Data, &Time);
   if (EFI_ERROR (Status)) {
     DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
     goto ON_EXIT;
@@ -1321,6 +1395,7 @@ EnrollX509HashtoSigDB (
   UINT16              *FilePostFix;
   UINTN               NameLength;
   EFI_TIME            *Time;
+  EFI_TIME            NewTime;
 
   X509DataSize  = 0;
   DbSize        = 0;
@@ -1490,7 +1565,13 @@ EnrollX509HashtoSigDB (
     DataSize = DbSize;
   }
 
-  Status = CreateTimeBasedPayload (&DataSize, (UINT8 **)&Data);
+  Status = GetCurrentTime (&NewTime);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+    goto ON_EXIT;
+  }
+
+  Status = CreateTimeBasedPayload (&DataSize, (UINT8 **)&Data, &NewTime);
   if (EFI_ERROR (Status)) {
     goto ON_EXIT;
   }
@@ -2169,6 +2250,7 @@ EnrollImageSignatureToSigDB (
   UINTN                      SigDBSize;
   UINT32                     Attr;
   WIN_CERTIFICATE_UEFI_GUID  *GuidCertData;
+  EFI_TIME                   Time;
 
   Data         = NULL;
   GuidCertData = NULL;
@@ -2267,7 +2349,13 @@ EnrollImageSignatureToSigDB (
 
   Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS
          | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
-  Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **)&Data);
+  Status = GetCurrentTime (&Time);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+    goto ON_EXIT;
+  }
+
+  Status = CreateTimeBasedPayload (&SigDBSize, (UINT8 **)&Data, &Time);
   if (EFI_ERROR (Status)) {
     DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
     goto ON_EXIT;
@@ -2609,6 +2697,7 @@ DeleteKeyExchangeKey (
   UINT32              KekDataSize;
   UINTN               DeleteKekIndex;
   UINTN               GuidIndex;
+  EFI_TIME            Time;
 
   Data           = NULL;
   OldData        = NULL;
@@ -2727,7 +2816,13 @@ DeleteKeyExchangeKey (
 
   DataSize = Offset;
   if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
-    Status = CreateTimeBasedPayload (&DataSize, &OldData);
+    Status = GetCurrentTime (&Time);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+      goto ON_EXIT;
+    }
+
+    Status = CreateTimeBasedPayload (&DataSize, &OldData, &Time);
     if (EFI_ERROR (Status)) {
       DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
       goto ON_EXIT;
@@ -2805,6 +2900,7 @@ DeleteSignature (
   BOOLEAN             IsItemFound;
   UINT32              ItemDataSize;
   UINTN               GuidIndex;
+  EFI_TIME            Time;
 
   Data     = NULL;
   OldData  = NULL;
@@ -2931,7 +3027,13 @@ DeleteSignature (
 
   DataSize = Offset;
   if ((Attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
-    Status = CreateTimeBasedPayload (&DataSize, &OldData);
+    Status = GetCurrentTime (&Time);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+      goto ON_EXIT;
+    }
+
+    Status = CreateTimeBasedPayload (&DataSize, &OldData, &Time);
     if (EFI_ERROR (Status)) {
       DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
       goto ON_EXIT;
@@ -3000,6 +3102,7 @@ DeleteSignatureEx (
   UINTN               Offset;
   UINT8               *VariableData;
   UINT8               *NewVariableData;
+  EFI_TIME            Time;
 
   Status           = EFI_SUCCESS;
   VariableAttr     = 0;
@@ -3120,7 +3223,13 @@ DeleteSignatureEx (
   }
 
   if ((VariableAttr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
-    Status = CreateTimeBasedPayload (&VariableDataSize, &NewVariableData);
+    Status = GetCurrentTime (&Time);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Fail to fetch valid time data: %r", Status));
+      goto ON_EXIT;
+    }
+
+    Status = CreateTimeBasedPayload (&VariableDataSize, &NewVariableData, &Time);
     if (EFI_ERROR (Status)) {
       DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
       goto ON_EXIT;
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
index 420687a21141..1671d5be7ccd 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
@@ -111,6 +111,7 @@ [Protocols]
   gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
   gEfiDevicePathProtocolGuid                    ## PRODUCES
   gEfiHiiPopupProtocolGuid
+  gEfiRealTimeClockArchProtocolGuid             ## CONSUMES
 
 [Depex]
   gEfiHiiConfigRoutingProtocolGuid  AND
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 09/11] SecurityPkg: SecureBootVariableLib: Added unit tests
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (7 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 08/11] SecurityPkg: SecureBootConfigDxe: Updated invocation pattern Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 10/11] OvmfPkg: Pipeline: Resolve SecureBootVariableLib dependency Kun Qin
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Jian J Wang, Min Xu

From: kuqin <kuqin@microsoft.com>

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

This change added unit test and enabled it from pipeline for the updated
SecureBootVariableLib.

The unit test covers all implemented interfaces and certain corner cases.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Min Xu <min.m.xu@intel.com>

Signed-off-by: Kun Qin <kun.qin@microsoft.com>
---
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.c       |   36 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.c                       |  201 ++
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.c   |   13 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c     | 2037 ++++++++++++++++++++
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf     |   33 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf                     |   45 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf |   25 +
 SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf   |   36 +
 SecurityPkg/SecurityPkg.ci.yaml                                                        |   11 +
 SecurityPkg/Test/SecurityPkgHostTest.dsc                                               |   38 +
 10 files changed, 2475 insertions(+)

diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.c b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.c
new file mode 100644
index 000000000000..a8644d272df6
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.c
@@ -0,0 +1,36 @@
+/** @file
+  Provides a mocked interface for configuring PK related variable protection.
+
+  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>
+
+/**
+  Disable any applicable protection against variable 'PK'. The implementation
+  of this interface is platform specific, depending on the protection techniques
+  used per platform.
+
+  Note: It is the platform's responsibility to conduct cautious operation after
+        disabling this protection.
+
+  @retval     EFI_SUCCESS             State has been successfully updated.
+  @retval     Others                  Error returned from implementation specific
+                                      underying APIs.
+
+**/
+EFI_STATUS
+EFIAPI
+DisablePKProtection (
+  VOID
+  )
+{
+  return (EFI_STATUS)mock ();
+}
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.c b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.c
new file mode 100644
index 000000000000..df271c39f26c
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.c
@@ -0,0 +1,201 @@
+/** @file
+  The UEFI Library provides functions and macros that simplify the development of
+  UEFI Drivers and UEFI Applications.  These functions and macros help manage EFI
+  events, build simple locks utilizing EFI Task Priority Levels (TPLs), install
+  EFI Driver Model related protocols, manage Unicode string tables for UEFI Drivers,
+  and print messages on the console output and standard error devices.
+
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+/**
+  Returns the status whether get the variable success. The function retrieves
+  variable  through the UEFI Runtime Service GetVariable().  The
+  returned buffer is allocated using AllocatePool().  The caller is responsible
+  for freeing this buffer with FreePool().
+
+  If Name  is NULL, then ASSERT().
+  If Guid  is NULL, then ASSERT().
+  If Value is NULL, then ASSERT().
+
+  @param[in]  Name  The pointer to a Null-terminated Unicode string.
+  @param[in]  Guid  The pointer to an EFI_GUID structure
+  @param[out] Value The buffer point saved the variable info.
+  @param[out] Size  The buffer size of the variable.
+
+  @return EFI_OUT_OF_RESOURCES      Allocate buffer failed.
+  @return EFI_SUCCESS               Find the specified variable.
+  @return Others Errors             Return errors from call to gRT->GetVariable.
+
+**/
+EFI_STATUS
+EFIAPI
+GetVariable2 (
+  IN CONST CHAR16    *Name,
+  IN CONST EFI_GUID  *Guid,
+  OUT VOID           **Value,
+  OUT UINTN          *Size OPTIONAL
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       BufferSize;
+
+  ASSERT (Name != NULL && Guid != NULL && Value != NULL);
+
+  //
+  // Try to get the variable size.
+  //
+  BufferSize = 0;
+  *Value     = NULL;
+  if (Size != NULL) {
+    *Size = 0;
+  }
+
+  Status = gRT->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid, NULL, &BufferSize, *Value);
+  if (Status != EFI_BUFFER_TOO_SMALL) {
+    return Status;
+  }
+
+  //
+  // Allocate buffer to get the variable.
+  //
+  *Value = AllocatePool (BufferSize);
+  ASSERT (*Value != NULL);
+  if (*Value == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Get the variable data.
+  //
+  Status = gRT->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid, NULL, &BufferSize, *Value);
+  if (EFI_ERROR (Status)) {
+    FreePool (*Value);
+    *Value = NULL;
+  }
+
+  if (Size != NULL) {
+    *Size = BufferSize;
+  }
+
+  return Status;
+}
+
+/** Return the attributes of the variable.
+
+  Returns the status whether get the variable success. The function retrieves
+  variable  through the UEFI Runtime Service GetVariable().  The
+  returned buffer is allocated using AllocatePool().  The caller is responsible
+  for freeing this buffer with FreePool().  The attributes are returned if
+  the caller provides a valid Attribute parameter.
+
+  If Name  is NULL, then ASSERT().
+  If Guid  is NULL, then ASSERT().
+  If Value is NULL, then ASSERT().
+
+  @param[in]  Name  The pointer to a Null-terminated Unicode string.
+  @param[in]  Guid  The pointer to an EFI_GUID structure
+  @param[out] Value The buffer point saved the variable info.
+  @param[out] Size  The buffer size of the variable.
+  @param[out] Attr  The pointer to the variable attributes as found in var store
+
+  @retval EFI_OUT_OF_RESOURCES      Allocate buffer failed.
+  @retval EFI_SUCCESS               Find the specified variable.
+  @retval Others Errors             Return errors from call to gRT->GetVariable.
+
+**/
+EFI_STATUS
+EFIAPI
+GetVariable3 (
+  IN CONST CHAR16    *Name,
+  IN CONST EFI_GUID  *Guid,
+  OUT VOID           **Value,
+  OUT UINTN          *Size OPTIONAL,
+  OUT UINT32         *Attr OPTIONAL
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       BufferSize;
+
+  ASSERT (Name != NULL && Guid != NULL && Value != NULL);
+
+  //
+  // Try to get the variable size.
+  //
+  BufferSize = 0;
+  *Value     = NULL;
+  if (Size != NULL) {
+    *Size = 0;
+  }
+
+  if (Attr != NULL) {
+    *Attr = 0;
+  }
+
+  Status = gRT->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid, Attr, &BufferSize, *Value);
+  if (Status != EFI_BUFFER_TOO_SMALL) {
+    return Status;
+  }
+
+  //
+  // Allocate buffer to get the variable.
+  //
+  *Value = AllocatePool (BufferSize);
+  ASSERT (*Value != NULL);
+  if (*Value == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Get the variable data.
+  //
+  Status = gRT->GetVariable ((CHAR16 *)Name, (EFI_GUID *)Guid, Attr, &BufferSize, *Value);
+  if (EFI_ERROR (Status)) {
+    FreePool (*Value);
+    *Value = NULL;
+  }
+
+  if (Size != NULL) {
+    *Size = BufferSize;
+  }
+
+  return Status;
+}
+
+/**
+  Returns a pointer to an allocated buffer that contains the contents of a
+  variable retrieved through the UEFI Runtime Service GetVariable().  This
+  function always uses the EFI_GLOBAL_VARIABLE GUID to retrieve variables.
+  The returned buffer is allocated using AllocatePool().  The caller is
+  responsible for freeing this buffer with FreePool().
+
+  If Name is NULL, then ASSERT().
+  If Value is NULL, then ASSERT().
+
+  @param[in]  Name  The pointer to a Null-terminated Unicode string.
+  @param[out] Value The buffer point saved the variable info.
+  @param[out] Size  The buffer size of the variable.
+
+  @return EFI_OUT_OF_RESOURCES      Allocate buffer failed.
+  @return EFI_SUCCESS               Find the specified variable.
+  @return Others Errors             Return errors from call to gRT->GetVariable.
+
+**/
+EFI_STATUS
+EFIAPI
+GetEfiGlobalVariable2 (
+  IN CONST CHAR16  *Name,
+  OUT VOID         **Value,
+  OUT UINTN        *Size OPTIONAL
+  )
+{
+  return GetVariable2 (Name, &gEfiGlobalVariableGuid, Value, Size);
+}
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.c b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.c
new file mode 100644
index 000000000000..e86192a05f32
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.c
@@ -0,0 +1,13 @@
+/** @file
+  Mock implementation of the UEFI Runtime Services Table Library.
+
+  Copyright (C) Microsoft Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+extern EFI_RUNTIME_SERVICES  gMockRuntime;
+
+EFI_RUNTIME_SERVICES  *gRT = &gMockRuntime;
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
new file mode 100644
index 000000000000..a23135dfb016
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
@@ -0,0 +1,2037 @@
+/** @file
+  Unit tests of the implementation of SecureBootVariableLib.
+
+  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 <UefiSecureBoot.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/AuthenticatedVariableFormat.h>
+#include <Guid/ImageAuthentication.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Library/UnitTestLib.h>
+#include <Library/SecureBootVariableLib.h>
+
+#define UNIT_TEST_APP_NAME     "SecureBootVariableLib Unit Tests"
+#define UNIT_TEST_APP_VERSION  "1.0"
+#define VAR_AUTH_DESC_SIZE     OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)
+
+extern EFI_TIME  mMaxTimestamp;
+extern EFI_TIME  mDefaultPayloadTimestamp;
+
+/**
+  Sets the value of a variable.
+
+  @param[in]  VariableName       A Null-terminated string that is the name of the vendor's variable.
+                                 Each VariableName is unique for each VendorGuid. VariableName must
+                                 contain 1 or more characters. If VariableName is an empty string,
+                                 then EFI_INVALID_PARAMETER is returned.
+  @param[in]  VendorGuid         A unique identifier for the vendor.
+  @param[in]  Attributes         Attributes bitmask to set for the variable.
+  @param[in]  DataSize           The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or
+                                 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
+                                 causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
+                                 set, then a SetVariable() call with a DataSize of zero will not cause any change to
+                                 the variable value (the timestamp associated with the variable may be updated however
+                                 even if no new data value is provided,see the description of the
+                                 EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
+                                 be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
+  @param[in]  Data               The contents for the variable.
+
+  @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
+                                 defined by the Attributes.
+  @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits, name, and GUID was supplied, or the
+                                 DataSize exceeds the maximum allowed.
+  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+  @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set,
+                                 but the AuthInfo does NOT pass the validation check carried out by the firmware.
+
+  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+MockSetVariable (
+  IN  CHAR16    *VariableName,
+  IN  EFI_GUID  *VendorGuid,
+  IN  UINT32    Attributes,
+  IN  UINTN     DataSize,
+  IN  VOID      *Data
+  )
+{
+  DEBUG ((
+    DEBUG_INFO,
+    "%a %s %g %x %x %p\n",
+    __FUNCTION__,
+    VariableName,
+    VendorGuid,
+    Attributes,
+    DataSize,
+    Data
+    ));
+  check_expected_ptr (VariableName);
+  check_expected_ptr (VendorGuid);
+  check_expected_ptr (Attributes);
+  check_expected (DataSize);
+  check_expected (Data);
+
+  return (EFI_STATUS)mock ();
+}
+
+/**
+  Returns the value of a variable.
+
+  @param[in]       VariableName  A Null-terminated string that is the name of the vendor's
+                                 variable.
+  @param[in]       VendorGuid    A unique identifier for the vendor.
+  @param[out]      Attributes    If not NULL, a pointer to the memory location to return the
+                                 attributes bitmask for the variable.
+  @param[in, out]  DataSize      On input, the size in bytes of the return Data buffer.
+                                 On output the size of data returned in Data.
+  @param[out]      Data          The buffer to return the contents of the variable. May be NULL
+                                 with a zero DataSize in order to determine the size buffer needed.
+
+  @retval EFI_SUCCESS            The function completed successfully.
+  @retval EFI_NOT_FOUND          The variable was not found.
+  @retval EFI_BUFFER_TOO_SMALL   The DataSize is too small for the result.
+  @retval EFI_INVALID_PARAMETER  VariableName is NULL.
+  @retval EFI_INVALID_PARAMETER  VendorGuid is NULL.
+  @retval EFI_INVALID_PARAMETER  DataSize is NULL.
+  @retval EFI_INVALID_PARAMETER  The DataSize is not too small and Data is NULL.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+MockGetVariable (
+  IN     CHAR16    *VariableName,
+  IN     EFI_GUID  *VendorGuid,
+  OUT    UINT32    *Attributes     OPTIONAL,
+  IN OUT UINTN     *DataSize,
+  OUT    VOID      *Data           OPTIONAL
+  )
+{
+  UINTN    TargetSize;
+  BOOLEAN  Exist;
+
+  DEBUG ((
+    DEBUG_INFO,
+    "%a %s %g %p %x %p\n",
+    __FUNCTION__,
+    VariableName,
+    VendorGuid,
+    Attributes,
+    *DataSize,
+    Data
+    ));
+  assert_non_null (DataSize);
+  check_expected_ptr (VariableName);
+  check_expected_ptr (VendorGuid);
+  check_expected (*DataSize);
+
+  Exist = (BOOLEAN)mock ();
+
+  if (!Exist) {
+    return EFI_NOT_FOUND;
+  }
+
+  TargetSize = (UINTN)mock ();
+  if (TargetSize > *DataSize) {
+    *DataSize = TargetSize;
+    return EFI_BUFFER_TOO_SMALL;
+  } else {
+    assert_non_null (Data);
+    CopyMem (Data, (VOID *)mock (), TargetSize);
+  }
+
+  return EFI_SUCCESS;
+}
+
+///
+/// Mock version of the UEFI Runtime Services Table
+///
+EFI_RUNTIME_SERVICES  gMockRuntime = {
+  {
+    EFI_RUNTIME_SERVICES_SIGNATURE,     // Signature
+    EFI_RUNTIME_SERVICES_REVISION,      // Revision
+    sizeof (EFI_RUNTIME_SERVICES),      // HeaderSize
+    0,                                  // CRC32
+    0                                   // Reserved
+  },
+  NULL,               // GetTime
+  NULL,               // SetTime
+  NULL,               // GetWakeupTime
+  NULL,               // SetWakeupTime
+  NULL,               // SetVirtualAddressMap
+  NULL,               // ConvertPointer
+  MockGetVariable,    // GetVariable
+  NULL,               // GetNextVariableName
+  MockSetVariable,    // SetVariable
+  NULL,               // GetNextHighMonotonicCount
+  NULL,               // ResetSystem
+  NULL,               // UpdateCapsule
+  NULL,               // QueryCapsuleCapabilities
+  NULL                // QueryVariableInfo
+};
+
+/**
+  Unit test for SetSecureBootMode () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootModeShouldSetVar (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  UINT8       SecureBootMode;
+  EFI_STATUS  Status;
+
+  SecureBootMode = 0xAB; // Any random magic number...
+  expect_memory (MockSetVariable, VariableName, EFI_CUSTOM_MODE_NAME, sizeof (EFI_CUSTOM_MODE_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiCustomModeEnableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS);
+  expect_value (MockSetVariable, DataSize, sizeof (SecureBootMode));
+  expect_memory (MockSetVariable, Data, &SecureBootMode, sizeof (SecureBootMode));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = SetSecureBootMode (SecureBootMode);
+
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for GetSetupMode () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+GetSetupModeShouldGetVar (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       TargetMode;
+  UINT8       SetupMode;
+
+  TargetMode = 0xAB; // Any random magic number...
+  expect_memory (MockGetVariable, VariableName, EFI_SETUP_MODE_NAME, sizeof (EFI_SETUP_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (SetupMode));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (SetupMode));
+  will_return (MockGetVariable, &TargetMode);
+
+  Status = GetSetupMode (&SetupMode);
+
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (SetupMode, TargetMode);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for GetSetupMode () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+IsSecureBootEnableShouldGetVar (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  BOOLEAN  Enabled;
+  UINT8    TargetMode;
+
+  TargetMode = SECURE_BOOT_MODE_ENABLE;
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (TargetMode));
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (TargetMode));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (TargetMode));
+  will_return (MockGetVariable, &TargetMode);
+
+  Enabled = IsSecureBootEnabled ();
+
+  UT_ASSERT_EQUAL (Enabled, SECURE_BOOT_MODE_ENABLE);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SecureBootCreateDataFromInput () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SecureBootCreateDataFromInputSimple (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_SIGNATURE_LIST            *SigList    = NULL;
+  EFI_SIGNATURE_DATA            *SigData    = NULL;
+  UINTN                         SigListSize = 0;
+  EFI_STATUS                    Status;
+  UINT8                         TestData[] = { 0 };
+  SECURE_BOOT_CERTIFICATE_INFO  KeyInfo    = {
+    .Data     = TestData,
+    .DataSize = sizeof (TestData)
+  };
+
+  Status = SecureBootCreateDataFromInput (&SigListSize, &SigList, 1, &KeyInfo);
+
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  UT_ASSERT_NOT_NULL (SigList);
+  UT_ASSERT_TRUE (CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid));
+  UT_ASSERT_EQUAL (SigList->SignatureSize, sizeof (EFI_SIGNATURE_DATA) - 1 + sizeof (TestData));
+  UT_ASSERT_EQUAL (SigList->SignatureHeaderSize, 0);
+  UT_ASSERT_EQUAL (SigList->SignatureListSize, sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + sizeof (TestData));
+  UT_ASSERT_EQUAL (SigList->SignatureListSize, SigListSize);
+
+  SigData = (EFI_SIGNATURE_DATA *)((UINTN)SigList + sizeof (EFI_SIGNATURE_LIST));
+  UT_ASSERT_TRUE (CompareGuid (&SigData->SignatureOwner, &gEfiGlobalVariableGuid));
+  UT_ASSERT_MEM_EQUAL (SigData->SignatureData, TestData, sizeof (TestData));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SecureBootCreateDataFromInput () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SecureBootCreateDataFromInputNull (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_SIGNATURE_LIST            *SigList    = NULL;
+  UINTN                         SigListSize = 0;
+  EFI_STATUS                    Status;
+  SECURE_BOOT_CERTIFICATE_INFO  KeyInfo = {
+    .Data     = NULL,
+    .DataSize = 0
+  };
+
+  Status = SecureBootCreateDataFromInput (&SigListSize, &SigList, 0, NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
+
+  Status = SecureBootCreateDataFromInput (&SigListSize, &SigList, 1, &KeyInfo);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SecureBootCreateDataFromInput () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SecureBootCreateDataFromInputMultiple (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_SIGNATURE_LIST            *SigList    = NULL;
+  EFI_SIGNATURE_DATA            *SigData    = NULL;
+  UINTN                         SigListSize = 0;
+  UINTN                         TotalSize   = 0;
+  UINTN                         Index       = 0;
+  UINT8                         TestData1[] = { 0 };
+  UINT8                         TestData2[] = { 1, 2 };
+  EFI_STATUS                    Status;
+  SECURE_BOOT_CERTIFICATE_INFO  KeyInfo[2] = {
+    {
+      .Data     = TestData1,
+      .DataSize = sizeof (TestData1)
+    },
+    {
+      .Data     = TestData2,
+      .DataSize = sizeof (TestData2)
+    }
+  };
+
+  Status = SecureBootCreateDataFromInput (&SigListSize, &SigList, 2, KeyInfo);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  UT_ASSERT_NOT_NULL (SigList);
+
+  for (Index = 0; Index < 2; Index++) {
+    UT_ASSERT_TRUE (SigListSize > TotalSize);
+
+    UT_ASSERT_TRUE (CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid));
+    UT_ASSERT_EQUAL (SigList->SignatureSize, sizeof (EFI_SIGNATURE_DATA) - 1 + KeyInfo[Index].DataSize);
+    UT_ASSERT_EQUAL (SigList->SignatureHeaderSize, 0);
+    UT_ASSERT_EQUAL (SigList->SignatureListSize, sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + KeyInfo[Index].DataSize);
+
+    SigData = (EFI_SIGNATURE_DATA *)((UINTN)SigList + sizeof (EFI_SIGNATURE_LIST));
+    UT_ASSERT_TRUE (CompareGuid (&SigData->SignatureOwner, &gEfiGlobalVariableGuid));
+    UT_ASSERT_MEM_EQUAL (SigData->SignatureData, KeyInfo[Index].Data, KeyInfo[Index].DataSize);
+    TotalSize = TotalSize + SigList->SignatureListSize;
+    SigList   = (EFI_SIGNATURE_LIST *)((UINTN)SigList + SigList->SignatureListSize);
+  }
+
+  UT_ASSERT_EQUAL (SigListSize, TotalSize);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for CreateTimeBasedPayload () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+CreateTimeBasedPayloadShouldPopulateDescriptor (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  UINT8                          Data[]   = { 2 };
+  UINTN                          DataSize = sizeof (Data);
+  UINT8                          *CheckData;
+  EFI_VARIABLE_AUTHENTICATION_2  *VarAuth;
+  EFI_STATUS                     Status;
+  EFI_TIME                       Time = {
+    .Year       = 2012,
+    .Month      = 3,
+    .Day        = 4,
+    .Hour       = 5,
+    .Minute     = 6,
+    .Second     = 7,
+    .Pad1       = 0,
+    .Nanosecond = 8910,
+    .TimeZone   = 1112,
+    .Pad2       = 0
+  };
+
+  CheckData = AllocateCopyPool (DataSize, Data);
+  Status    = CreateTimeBasedPayload (&DataSize, &CheckData, &Time);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  // This is result that we did not pack this structure...
+  // we cannot even use the sizeof (EFI_VARIABLE_AUTHENTICATION_2) - 1,
+  // because the structure is not at the end of this structure, but partially
+  // inside it...
+  UT_ASSERT_EQUAL (DataSize, VAR_AUTH_DESC_SIZE + sizeof (Data));
+  UT_ASSERT_NOT_NULL (CheckData);
+
+  VarAuth = (EFI_VARIABLE_AUTHENTICATION_2 *)CheckData;
+  UT_ASSERT_MEM_EQUAL (&(VarAuth->TimeStamp), &Time, sizeof (EFI_TIME));
+
+  UT_ASSERT_EQUAL (VarAuth->AuthInfo.Hdr.dwLength, OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData));
+  UT_ASSERT_EQUAL (VarAuth->AuthInfo.Hdr.wRevision, 0x0200);
+  UT_ASSERT_EQUAL (VarAuth->AuthInfo.Hdr.wCertificateType, WIN_CERT_TYPE_EFI_GUID);
+  UT_ASSERT_TRUE (CompareGuid (&VarAuth->AuthInfo.CertType, &gEfiCertPkcs7Guid));
+
+  UT_ASSERT_MEM_EQUAL (VarAuth->AuthInfo.CertData, Data, sizeof (Data));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for CreateTimeBasedPayload () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+CreateTimeBasedPayloadShouldCheckInput (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  UINTN       DataSize = 0;
+  UINT8       *Data    = NULL;
+  EFI_TIME    Time;
+  EFI_STATUS  Status;
+
+  Status = CreateTimeBasedPayload (NULL, &Data, &Time);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
+
+  Status = CreateTimeBasedPayload (&DataSize, NULL, &Time);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
+
+  Status = CreateTimeBasedPayload (&DataSize, &Data, NULL);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeleteDb () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+DeleteDbShouldDelete (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Dummy       = 3;
+  UINT8       *Payload    = NULL;
+  UINTN       PayloadSize = 0;
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  Status = CreateTimeBasedPayload (&PayloadSize, &Payload, &mMaxTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE);
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = DeleteDb ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeleteDbx () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+DeleteDbxShouldDelete (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Dummy       = 3;
+  UINT8       *Payload    = NULL;
+  UINTN       PayloadSize = 0;
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  Status = CreateTimeBasedPayload (&PayloadSize, &Payload, &mMaxTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE);
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = DeleteDbx ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeleteDbt () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+DeleteDbtShouldDelete (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Dummy       = 3;
+  UINT8       *Payload    = NULL;
+  UINTN       PayloadSize = 0;
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  Status = CreateTimeBasedPayload (&PayloadSize, &Payload, &mMaxTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE);
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = DeleteDbt ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeleteKEK () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+DeleteKEKShouldDelete (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Dummy       = 3;
+  UINT8       *Payload    = NULL;
+  UINTN       PayloadSize = 0;
+
+  expect_memory (MockGetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  Status = CreateTimeBasedPayload (&PayloadSize, &Payload, &mMaxTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE);
+
+  expect_memory (MockSetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = DeleteKEK ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeletePlatformKey () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+DeletePKShouldDelete (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Dummy       = 3;
+  UINT8       *Payload    = NULL;
+  UINTN       PayloadSize = 0;
+  UINT8       BootMode    = CUSTOM_SECURE_BOOT_MODE;
+
+  expect_memory (MockSetVariable, VariableName, EFI_CUSTOM_MODE_NAME, sizeof (EFI_CUSTOM_MODE_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiCustomModeEnableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS);
+  expect_value (MockSetVariable, DataSize, sizeof (BootMode));
+  expect_memory (MockSetVariable, Data, &BootMode, sizeof (BootMode));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  expect_memory (MockGetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  Status = CreateTimeBasedPayload (&PayloadSize, &Payload, &mMaxTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE);
+
+  expect_memory (MockSetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = DeletePlatformKey ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeleteSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+DeleteSecureBootVariablesShouldDelete (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Dummy       = 3;
+  UINT8       *Payload    = NULL;
+  UINTN       PayloadSize = 0;
+  UINT8       BootMode    = CUSTOM_SECURE_BOOT_MODE;
+
+  Status = CreateTimeBasedPayload (&PayloadSize, &Payload, &mMaxTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE);
+
+  will_return (DisablePKProtection, EFI_SUCCESS);
+
+  expect_memory (MockSetVariable, VariableName, EFI_CUSTOM_MODE_NAME, sizeof (EFI_CUSTOM_MODE_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiCustomModeEnableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS);
+  expect_value (MockSetVariable, DataSize, sizeof (BootMode));
+  expect_memory (MockSetVariable, Data, &BootMode, sizeof (BootMode));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  expect_memory (MockGetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  expect_memory (MockSetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  expect_memory (MockGetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  expect_memory (MockSetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (Dummy));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (Dummy));
+  will_return (MockGetVariable, &Dummy);
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE);
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE);
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = DeleteSecureBootVariables ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeleteSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+DeleteSecureBootVariablesShouldCheckProtection (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+
+  will_return (DisablePKProtection, EFI_SECURITY_VIOLATION);
+
+  Status = DeleteSecureBootVariables ();
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_ABORTED);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeleteSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+DeleteSecureBootVariablesShouldProceedWithNotFound (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       BootMode = CUSTOM_SECURE_BOOT_MODE;
+
+  will_return (DisablePKProtection, EFI_SUCCESS);
+
+  expect_memory (MockSetVariable, VariableName, EFI_CUSTOM_MODE_NAME, sizeof (EFI_CUSTOM_MODE_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiCustomModeEnableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS);
+  expect_value (MockSetVariable, DataSize, sizeof (BootMode));
+  expect_memory (MockSetVariable, Data, &BootMode, sizeof (BootMode));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  expect_memory (MockGetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  expect_memory (MockGetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  expect_memory (MockGetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockGetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  Status = DeleteSecureBootVariables ();
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for DeleteSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+EnrollFromInputShouldComplete (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Dummy       = 3;
+  UINT8       *Payload    = NULL;
+  UINTN       PayloadSize = sizeof (Dummy);
+
+  Payload = AllocateCopyPool (sizeof (Dummy), &Dummy);
+  Status  = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (Dummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (Dummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (Dummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = EnrollFromInput (EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid, sizeof (Dummy), &Dummy);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SetDefaultSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootVariablesShouldComplete (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS                Status;
+  UINT8                     DbDummy     = 0xDE;
+  UINT8                     DbtDummy    = 0xAD;
+  UINT8                     DbxDummy    = 0xBE;
+  UINT8                     KekDummy    = 0xEF;
+  UINT8                     PkDummy     = 0xFE;
+  UINT8                     *Payload    = NULL;
+  UINTN                     PayloadSize = sizeof (DbDummy);
+  SECURE_BOOT_PAYLOAD_INFO  PayloadInfo = {
+    .DbPtr             = &DbDummy,
+    .DbSize            = sizeof (DbDummy),
+    .DbxPtr            = &DbxDummy,
+    .DbxSize           = sizeof (DbxDummy),
+    .DbtPtr            = &DbtDummy,
+    .DbtSize           = sizeof (DbtDummy),
+    .KekPtr            = &KekDummy,
+    .KekSize           = sizeof (KekDummy),
+    .PkPtr             = &PkDummy,
+    .PkSize            = sizeof (PkDummy),
+    .SecureBootKeyName = L"Food"
+  };
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  Payload = AllocateCopyPool (sizeof (DbxDummy), &DbxDummy);
+  Status  = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbDummy, sizeof (DbDummy));
+  PayloadSize = sizeof (DbDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbtDummy, sizeof (DbtDummy));
+  PayloadSize = sizeof (DbtDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &KekDummy, sizeof (KekDummy));
+  PayloadSize = sizeof (KekDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &PkDummy, sizeof (PkDummy));
+  PayloadSize = sizeof (PkDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = SetSecureBootVariablesToDefault (&PayloadInfo);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SetDefaultSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootVariablesShouldStopWhenSecure (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS                Status;
+  UINT8                     TargetMode = SECURE_BOOT_MODE_ENABLE;
+  SECURE_BOOT_PAYLOAD_INFO  PayloadInfo;
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (TargetMode));
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, sizeof (TargetMode));
+
+  will_return (MockGetVariable, TRUE);
+  will_return (MockGetVariable, sizeof (TargetMode));
+  will_return (MockGetVariable, &TargetMode);
+
+  Status = SetSecureBootVariablesToDefault (&PayloadInfo);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_ABORTED);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SetDefaultSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootVariablesShouldStopFailDBX (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS                Status;
+  UINT8                     DbxDummy    = 0xBE;
+  UINT8                     *Payload    = NULL;
+  UINTN                     PayloadSize = sizeof (DbxDummy);
+  SECURE_BOOT_PAYLOAD_INFO  PayloadInfo = {
+    .DbxPtr            = &DbxDummy,
+    .DbxSize           = sizeof (DbxDummy),
+    .SecureBootKeyName = L"Fail DBX"
+  };
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  Payload = AllocateCopyPool (sizeof (DbxDummy), &DbxDummy);
+  Status  = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  will_return (MockSetVariable, EFI_WRITE_PROTECTED);
+
+  Status = SetSecureBootVariablesToDefault (&PayloadInfo);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SetDefaultSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootVariablesShouldStopFailDB (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS                Status;
+  UINT8                     DbDummy     = 0xDE;
+  UINT8                     DbxDummy    = 0xBE;
+  UINT8                     *Payload    = NULL;
+  UINTN                     PayloadSize = sizeof (DbDummy);
+  SECURE_BOOT_PAYLOAD_INFO  PayloadInfo = {
+    .DbPtr             = &DbDummy,
+    .DbSize            = sizeof (DbDummy),
+    .DbxPtr            = &DbxDummy,
+    .DbxSize           = sizeof (DbxDummy),
+    .SecureBootKeyName = L"Fail DB"
+  };
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  Payload = AllocateCopyPool (sizeof (DbxDummy), &DbxDummy);
+  Status  = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbDummy, sizeof (DbDummy));
+  PayloadSize = sizeof (DbDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  will_return (MockSetVariable, EFI_WRITE_PROTECTED);
+
+  Status = SetSecureBootVariablesToDefault (&PayloadInfo);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SetDefaultSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootVariablesShouldStopFailDBT (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS                Status;
+  UINT8                     DbDummy     = 0xDE;
+  UINT8                     DbtDummy    = 0xAD;
+  UINT8                     DbxDummy    = 0xBE;
+  UINT8                     *Payload    = NULL;
+  UINTN                     PayloadSize = sizeof (DbDummy);
+  SECURE_BOOT_PAYLOAD_INFO  PayloadInfo = {
+    .DbPtr             = &DbDummy,
+    .DbSize            = sizeof (DbDummy),
+    .DbxPtr            = &DbxDummy,
+    .DbxSize           = sizeof (DbxDummy),
+    .DbtPtr            = &DbtDummy,
+    .DbtSize           = sizeof (DbtDummy),
+    .SecureBootKeyName = L"Fail DBT"
+  };
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  Payload = AllocateCopyPool (sizeof (DbxDummy), &DbxDummy);
+  Status  = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbDummy, sizeof (DbDummy));
+  PayloadSize = sizeof (DbDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbtDummy, sizeof (DbtDummy));
+  PayloadSize = sizeof (DbtDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+
+  will_return (MockSetVariable, EFI_ACCESS_DENIED);
+
+  Status = SetSecureBootVariablesToDefault (&PayloadInfo);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_ACCESS_DENIED);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SetDefaultSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootVariablesShouldStopFailKEK (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS                Status;
+  UINT8                     DbDummy     = 0xDE;
+  UINT8                     DbtDummy    = 0xAD;
+  UINT8                     DbxDummy    = 0xBE;
+  UINT8                     KekDummy    = 0xEF;
+  UINT8                     PkDummy     = 0xFE;
+  UINT8                     *Payload    = NULL;
+  UINTN                     PayloadSize = sizeof (DbDummy);
+  SECURE_BOOT_PAYLOAD_INFO  PayloadInfo = {
+    .DbPtr             = &DbDummy,
+    .DbSize            = sizeof (DbDummy),
+    .DbxPtr            = &DbxDummy,
+    .DbxSize           = sizeof (DbxDummy),
+    .DbtPtr            = &DbtDummy,
+    .DbtSize           = sizeof (DbtDummy),
+    .KekPtr            = &KekDummy,
+    .KekSize           = sizeof (KekDummy),
+    .PkPtr             = &PkDummy,
+    .PkSize            = sizeof (PkDummy),
+    .SecureBootKeyName = L"Food"
+  };
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  Payload = AllocateCopyPool (sizeof (DbxDummy), &DbxDummy);
+  Status  = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbDummy, sizeof (DbDummy));
+  PayloadSize = sizeof (DbDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbtDummy, sizeof (DbtDummy));
+  PayloadSize = sizeof (DbtDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &KekDummy, sizeof (KekDummy));
+  PayloadSize = sizeof (KekDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+
+  will_return (MockSetVariable, EFI_DEVICE_ERROR);
+
+  Status = SetSecureBootVariablesToDefault (&PayloadInfo);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_DEVICE_ERROR);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SetDefaultSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootVariablesShouldStopFailPK (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS                Status;
+  UINT8                     DbDummy     = 0xDE;
+  UINT8                     DbtDummy    = 0xAD;
+  UINT8                     DbxDummy    = 0xBE;
+  UINT8                     KekDummy    = 0xEF;
+  UINT8                     PkDummy     = 0xFE;
+  UINT8                     *Payload    = NULL;
+  UINTN                     PayloadSize = sizeof (DbDummy);
+  SECURE_BOOT_PAYLOAD_INFO  PayloadInfo = {
+    .DbPtr             = &DbDummy,
+    .DbSize            = sizeof (DbDummy),
+    .DbxPtr            = &DbxDummy,
+    .DbxSize           = sizeof (DbxDummy),
+    .DbtPtr            = &DbtDummy,
+    .DbtSize           = sizeof (DbtDummy),
+    .KekPtr            = &KekDummy,
+    .KekSize           = sizeof (KekDummy),
+    .PkPtr             = &PkDummy,
+    .PkSize            = sizeof (PkDummy),
+    .SecureBootKeyName = L"Food"
+  };
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  Payload = AllocateCopyPool (sizeof (DbxDummy), &DbxDummy);
+  Status  = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbDummy, sizeof (DbDummy));
+  PayloadSize = sizeof (DbDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbtDummy, sizeof (DbtDummy));
+  PayloadSize = sizeof (DbtDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE2, sizeof (EFI_IMAGE_SECURITY_DATABASE2));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbtDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &KekDummy, sizeof (KekDummy));
+  PayloadSize = sizeof (KekDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &PkDummy, sizeof (PkDummy));
+  PayloadSize = sizeof (PkDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+
+  will_return (MockSetVariable, EFI_INVALID_PARAMETER);
+
+  Status = SetSecureBootVariablesToDefault (&PayloadInfo);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_SECURITY_VIOLATION);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Unit test for SetDefaultSecureBootVariables () API of the SecureBootVariableLib.
+
+  @param[in]  Context    [Optional] An optional parameter that enables:
+                         1) test-case reuse with varied parameters and
+                         2) test-case re-entry for Target tests that need a
+                         reboot.  This parameter is a VOID* and it is the
+                         responsibility of the test author to ensure that the
+                         contents are well understood by all test cases that may
+                         consume it.
+
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
+                                        case was successful.
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+SetSecureBootVariablesDBTOptional (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_STATUS                Status;
+  UINT8                     DbDummy     = 0xDE;
+  UINT8                     DbxDummy    = 0xBE;
+  UINT8                     KekDummy    = 0xEF;
+  UINT8                     PkDummy     = 0xFE;
+  UINT8                     *Payload    = NULL;
+  UINTN                     PayloadSize = sizeof (DbDummy);
+  SECURE_BOOT_PAYLOAD_INFO  PayloadInfo = {
+    .DbPtr             = &DbDummy,
+    .DbSize            = sizeof (DbDummy),
+    .DbxPtr            = &DbxDummy,
+    .DbxSize           = sizeof (DbxDummy),
+    .DbtPtr            = NULL,
+    .DbtSize           = 0,
+    .KekPtr            = &KekDummy,
+    .KekSize           = sizeof (KekDummy),
+    .PkPtr             = &PkDummy,
+    .PkSize            = sizeof (PkDummy),
+    .SecureBootKeyName = L"Food"
+  };
+
+  expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
+  expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockGetVariable, *DataSize, 0);
+
+  will_return (MockGetVariable, FALSE);
+
+  Payload = AllocateCopyPool (sizeof (DbxDummy), &DbxDummy);
+  Status  = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE1, sizeof (EFI_IMAGE_SECURITY_DATABASE1));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbxDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &DbDummy, sizeof (DbDummy));
+  PayloadSize = sizeof (DbDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_IMAGE_SECURITY_DATABASE, sizeof (EFI_IMAGE_SECURITY_DATABASE));
+  expect_value (MockSetVariable, VendorGuid, &gEfiImageSecurityDatabaseGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (DbDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &KekDummy, sizeof (KekDummy));
+  PayloadSize = sizeof (KekDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_KEY_EXCHANGE_KEY_NAME, sizeof (EFI_KEY_EXCHANGE_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (KekDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  CopyMem (Payload, &PkDummy, sizeof (PkDummy));
+  PayloadSize = sizeof (PkDummy);
+  Status      = CreateTimeBasedPayload (&PayloadSize, &Payload, &mDefaultPayloadTimestamp);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+  UT_ASSERT_EQUAL (PayloadSize, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+
+  expect_memory (MockSetVariable, VariableName, EFI_PLATFORM_KEY_NAME, sizeof (EFI_PLATFORM_KEY_NAME));
+  expect_value (MockSetVariable, VendorGuid, &gEfiGlobalVariableGuid);
+  expect_value (MockSetVariable, Attributes, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
+  expect_value (MockSetVariable, DataSize, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+  expect_memory (MockSetVariable, Data, Payload, VAR_AUTH_DESC_SIZE + sizeof (PkDummy));
+
+  will_return (MockSetVariable, EFI_SUCCESS);
+
+  Status = SetSecureBootVariablesToDefault (&PayloadInfo);
+  UT_ASSERT_NOT_EFI_ERROR (Status);
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+  Initialze the unit test framework, suite, and unit tests for the
+  SecureBootVariableLib and run the SecureBootVariableLib unit test.
+
+  @retval  EFI_SUCCESS           All test cases were dispatched.
+  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to
+                                 initialize the unit tests.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+UnitTestingEntry (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  UNIT_TEST_FRAMEWORK_HANDLE  Framework;
+  UNIT_TEST_SUITE_HANDLE      SecureBootVarMiscTests;
+  UNIT_TEST_SUITE_HANDLE      SecureBootVarDeleteTests;
+  UNIT_TEST_SUITE_HANDLE      SecureBootVarEnrollTests;
+
+  Framework = NULL;
+
+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
+
+  //
+  // Start setting up the test framework for running the tests.
+  //
+  Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+    goto EXIT;
+  }
+
+  //
+  // Populate the SecureBootVariableLib Unit Test Suite.
+  //
+  Status = CreateUnitTestSuite (&SecureBootVarMiscTests, Framework, "SecureBootVariableLib Miscellaneous Tests", "SecureBootVariableLib.Miscellaneous", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SecureBootVariableLib\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+
+  Status = CreateUnitTestSuite (&SecureBootVarDeleteTests, Framework, "SecureBootVariableLib Deletion Tests", "SecureBootVariableLib.Deletion", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SecureBootVariableLib\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+
+  Status = CreateUnitTestSuite (&SecureBootVarEnrollTests, Framework, "SecureBootVariableLib Enrollment Tests", "SecureBootVariableLib.Enrollment", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SecureBootVariableLib\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+
+  //
+  // --------------Suite-----------Description--------------Name----------Function--------Pre---Post-------------------Context-----------
+  //
+  AddTestCase (SecureBootVarMiscTests, "SetSecureBootMode should propagate to set variable", "SetSecureBootMode", SetSecureBootModeShouldSetVar, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarMiscTests, "GetSetupMode should propagate to get variable", "GetSetupMode", GetSetupModeShouldGetVar, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarMiscTests, "IsSecureBootEnabled should propagate to get variable", "IsSecureBootEnabled", IsSecureBootEnableShouldGetVar, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarMiscTests, "SecureBootCreateDataFromInput with one input cert", "SecureBootCreateDataFromInput One Cert", SecureBootCreateDataFromInputSimple, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarMiscTests, "SecureBootCreateDataFromInput with no input cert", "SecureBootCreateDataFromInput No Cert", SecureBootCreateDataFromInputNull, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarMiscTests, "SecureBootCreateDataFromInput with multiple input cert", "SecureBootCreateDataFromInput No Cert", SecureBootCreateDataFromInputMultiple, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarMiscTests, "CreateTimeBasedPayload should populate descriptor data", "CreateTimeBasedPayload Normal", CreateTimeBasedPayloadShouldPopulateDescriptor, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarMiscTests, "CreateTimeBasedPayload should fail on NULL inputs", "CreateTimeBasedPayload NULL", CreateTimeBasedPayloadShouldCheckInput, NULL, NULL, NULL);
+
+  AddTestCase (SecureBootVarDeleteTests, "DeleteDb should delete DB with auth info", "DeleteDb", DeleteDbShouldDelete, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarDeleteTests, "DeleteDbx should delete DBX with auth info", "DeleteDbx", DeleteDbxShouldDelete, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarDeleteTests, "DeleteDbt should delete DBT with auth info", "DeleteDbt", DeleteDbtShouldDelete, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarDeleteTests, "DeleteKEK should delete KEK with auth info", "DeleteKEK", DeleteKEKShouldDelete, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarDeleteTests, "DeletePlatformKey should delete PK with auth info", "DeletePlatformKey", DeletePKShouldDelete, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarDeleteTests, "DeleteSecureBootVariables should delete properly", "DeleteSecureBootVariables Normal", DeleteSecureBootVariablesShouldDelete, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarDeleteTests, "DeleteSecureBootVariables should fail if protection disable fails", "DeleteSecureBootVariables Fail", DeleteSecureBootVariablesShouldCheckProtection, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarDeleteTests, "DeleteSecureBootVariables should continue if any variable is not found", "DeleteSecureBootVariables Proceed", DeleteSecureBootVariablesShouldProceedWithNotFound, NULL, NULL, NULL);
+
+  AddTestCase (SecureBootVarEnrollTests, "EnrollFromInput should supply with authenticated payload", "EnrollFromInput Normal", EnrollFromInputShouldComplete, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarEnrollTests, "SetSecureBootVariablesToDefault should complete", "SetSecureBootVariablesToDefault Normal", SetSecureBootVariablesShouldComplete, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarEnrollTests, "SetSecureBootVariablesToDefault should stop when already enabled", "SetSecureBootVariablesToDefault Already Started", SetSecureBootVariablesShouldStopWhenSecure, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarEnrollTests, "SetSecureBootVariablesToDefault should stop when DB failed", "SetSecureBootVariablesToDefault Fails DB", SetSecureBootVariablesShouldStopFailDB, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarEnrollTests, "SetSecureBootVariablesToDefault should stop when DBT failed", "SetSecureBootVariablesToDefault Fails DBT", SetSecureBootVariablesShouldStopFailDBT, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarEnrollTests, "SetSecureBootVariablesToDefault should stop when DBX failed", "SetSecureBootVariablesToDefault Fails DBX", SetSecureBootVariablesShouldStopFailDBX, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarEnrollTests, "SetSecureBootVariablesToDefault should stop when KEK failed", "SetSecureBootVariablesToDefault Fails KEK", SetSecureBootVariablesShouldStopFailKEK, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarEnrollTests, "SetSecureBootVariablesToDefault should stop when PK failed", "SetSecureBootVariablesToDefault Fails PK", SetSecureBootVariablesShouldStopFailPK, NULL, NULL, NULL);
+  AddTestCase (SecureBootVarEnrollTests, "SetSecureBootVariablesToDefault should only be optional", "SetSecureBootVariablesToDefault DBT Optional", SetSecureBootVariablesDBTOptional, NULL, NULL, NULL);
+
+  //
+  // Execute the tests.
+  //
+  Status = RunAllTestSuites (Framework);
+
+EXIT:
+  if (Framework) {
+    FreeUnitTestFramework (Framework);
+  }
+
+  return Status;
+}
+
+/**
+  Standard POSIX C entry point for host based unit test execution.
+**/
+int
+main (
+  int   argc,
+  char  *argv[]
+  )
+{
+  return UnitTestingEntry ();
+}
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
new file mode 100644
index 000000000000..1e19033c5a91
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
@@ -0,0 +1,33 @@
+## @file
+#  Provides an abstracted interface for configuring PK related variable protection.
+#
+#  Copyright (c) Microsoft Corporation.
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MockPlatformPKProtectionLib
+  FILE_GUID                      = 5FCD74D3-3965-4D56-AB83-000B9B4806A0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformPKProtectionLib|HOST_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  MockPlatformPKProtectionLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+  UnitTestLib
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
new file mode 100644
index 000000000000..a84242ac7205
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Instance of UEFI Library.
+#
+# The UEFI Library provides functions and macros that simplify the development of
+#  UEFI Drivers and UEFI Applications.  These functions and macros help manage EFI
+#  events, build simple locks utilizing EFI Task Priority Levels (TPLs), install
+#  EFI Driver Model related protocols, manage Unicode string tables for UEFI Drivers,
+#  and print messages on the console output and standard error devices.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MockUefiLib
+  FILE_GUID                      = E3B7AEF9-4E55-49AF-B035-ED776C928EC6
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = UefiLib|HOST_APPLICATION
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  MockUefiLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  PrintLib
+  PcdLib
+  MemoryAllocationLib
+  DebugLib
+  BaseMemoryLib
+  BaseLib
+  UefiRuntimeServicesTableLib
+
+[Guids]
+  gEfiGlobalVariableGuid                        ## SOMETIMES_CONSUMES  ## Variable
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
new file mode 100644
index 000000000000..f832a93e2254
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
@@ -0,0 +1,25 @@
+## @file
+#  Mock implementation of the UEFI Runtime Services Table Library.
+#
+#  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MockUefiRuntimeServicesTableLib
+  FILE_GUID                      = 84CE0021-ABEE-403C-9A1B-763CCF2D40F1
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = UefiRuntimeServicesTableLib|HOST_APPLICATION
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  MockUefiRuntimeServicesTableLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf
new file mode 100644
index 000000000000..f99fb09be52e
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf
@@ -0,0 +1,36 @@
+## @file
+# Unit tests of the implementation of SecureBootVariableLib.
+#
+# Copyright (C) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = SecureBootVariableLibUnitTest
+  FILE_GUID                      = 71C5359E-08FB-450E-9766-BC70482DF66B
+  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
+#
+
+[Sources]
+  SecureBootVariableLibUnitTest.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+  SecureBootVariableLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  UefiLib
+  UnitTestLib
diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml
index 791214239899..2138b0a5e21b 100644
--- a/SecurityPkg/SecurityPkg.ci.yaml
+++ b/SecurityPkg/SecurityPkg.ci.yaml
@@ -15,6 +15,7 @@
         ##     "<ErrorID>", "<KeyWord>"
         ## ]
         "ExceptionList": [
+            "8005", "gRT",
         ],
         ## Both file path and directory path are accepted.
         "IgnoreFiles": [
@@ -26,6 +27,10 @@
     "CompilerPlugin": {
         "DscPath": "SecurityPkg.dsc"
     },
+    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+    "HostUnitTestCompilerPlugin": {
+        "DscPath": "Test/SecurityPkgHostTest.dsc"
+    },
     "CharEncodingCheck": {
         "IgnoreFiles": []
     },
@@ -33,6 +38,7 @@
         "AcceptableDependencies": [
             "MdePkg/MdePkg.dec",
             "MdeModulePkg/MdeModulePkg.dec",
+            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec",
             "SecurityPkg/SecurityPkg.dec",
             "StandaloneMmPkg/StandaloneMmPkg.dec",
             "CryptoPkg/CryptoPkg.dec"
@@ -47,6 +53,11 @@
         "DscPath": "SecurityPkg.dsc",
         "IgnoreInf": []
     },
+    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+    "HostUnitTestDscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": "Test/SecurityPkgHostTest.dsc"
+    },
     "GuidCheck": {
         "IgnoreGuidName": [],
         "IgnoreGuidValue": ["00000000-0000-0000-0000-000000000000"],
diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/SecurityPkgHostTest.dsc
new file mode 100644
index 000000000000..c4df01fe1b73
--- /dev/null
+++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc
@@ -0,0 +1,38 @@
+## @file
+# SecurityPkg DSC file used to build host-based unit tests.
+#
+# Copyright (C) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  PLATFORM_NAME           = SecurityPkgHostTest
+  PLATFORM_GUID           = 9D78A9B4-00CD-477E-A5BF-90CC793EEFB0
+  PLATFORM_VERSION        = 0.1
+  DSC_SPECIFICATION       = 0x00010005
+  OUTPUT_DIRECTORY        = Build/SecurityPkg/HostTest
+  SUPPORTED_ARCHITECTURES = IA32|X64
+  BUILD_TARGETS           = NOOPT
+  SKUID_IDENTIFIER        = DEFAULT
+
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+
+[LibraryClasses]
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+
+[Components]
+  SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
+  SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
+  SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
+
+  #
+  # Build SecurityPkg HOST_APPLICATION Tests
+  #
+  SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf {
+    <LibraryClasses>
+      SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+      UefiRuntimeServicesTableLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
+      PlatformPKProtectionLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
+      UefiLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
+  }
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 10/11] OvmfPkg: Pipeline: Resolve SecureBootVariableLib dependency
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (8 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 09/11] SecurityPkg: SecureBootVariableLib: Added unit tests Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-13 20:39 ` [PATCH v2 11/11] EmulatorPkg: " Kun Qin
  2022-06-30 19:44 ` [edk2-devel] [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Michael Kubacki
  11 siblings, 0 replies; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel
  Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Rebecca Cran, Peter Grehan, Sebastien Boeuf

The new changes in SecureBootVariableLib brought in a new dependency of
PlatformPKProtectionLib.

This change added the new library instance from SecurityPkg to resolve
pipeline builds.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rebecca Cran <rebecca@bsdio.com>
Cc: Peter Grehan <grehan@freebsd.org>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>

Signed-off-by: Kun Qin <kuqin12@gmail.com>
---
 OvmfPkg/Bhyve/BhyveX64.dsc       | 1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc   | 1 +
 OvmfPkg/IntelTdx/IntelTdxX64.dsc | 1 +
 OvmfPkg/OvmfPkgIa32.dsc          | 1 +
 OvmfPkg/OvmfPkgIa32X64.dsc       | 1 +
 OvmfPkg/OvmfPkgX64.dsc           | 1 +
 6 files changed, 6 insertions(+)

diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index f0166e136cd1..36270456aa31 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -199,6 +199,7 @@ [LibraryClasses]
   PlatformSecureLib|OvmfPkg/Bhyve/Library/PlatformSecureLib/PlatformSecureLib.inf
   AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
   SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
   SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
 !else
   AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 8a111444f867..5883fa81f3a7 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -210,6 +210,7 @@ [LibraryClasses]
   PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
   AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
   SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
   SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
 !else
   AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index a40f7228b98e..d44aa23ef325 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -183,6 +183,7 @@ [LibraryClasses]
   PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
   AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
   SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
   SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
 !else
   AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index a9841cbfc3ca..c291b20d4504 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -207,6 +207,7 @@ [LibraryClasses]
   PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
   AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
   SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
   SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
 !else
   AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index f7949780fa38..22ff966464c2 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -211,6 +211,7 @@ [LibraryClasses]
   PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
   AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
   SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
   SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
 !else
   AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 1448f925b782..5b681716397d 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -227,6 +227,7 @@ [LibraryClasses]
   PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
   AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
   SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
   SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
 !else
   AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 11/11] EmulatorPkg: Pipeline: Resolve SecureBootVariableLib dependency
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (9 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 10/11] OvmfPkg: Pipeline: Resolve SecureBootVariableLib dependency Kun Qin
@ 2022-06-13 20:39 ` Kun Qin
  2022-06-24  9:08   ` Ni, Ray
  2022-06-30 19:44 ` [edk2-devel] [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Michael Kubacki
  11 siblings, 1 reply; 14+ messages in thread
From: Kun Qin @ 2022-06-13 20:39 UTC (permalink / raw)
  To: devel; +Cc: Andrew Fish, Ray Ni

The new changes in SecureBootVariableLib brought in a new dependency of
PlatformPKProtectionLib.

This change added the new library instance from SecurityPkg to resolve
pipeline builds.

Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>

Signed-off-by: Kun Qin <kuqin12@gmail.com>
---
 EmulatorPkg/EmulatorPkg.dsc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc
index 4cf886b9eac7..b44435d7e6ee 100644
--- a/EmulatorPkg/EmulatorPkg.dsc
+++ b/EmulatorPkg/EmulatorPkg.dsc
@@ -134,6 +134,7 @@ [LibraryClasses]
   PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
   AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
   SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
   SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
 !else
   AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
-- 
2.35.1.windows.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 11/11] EmulatorPkg: Pipeline: Resolve SecureBootVariableLib dependency
  2022-06-13 20:39 ` [PATCH v2 11/11] EmulatorPkg: " Kun Qin
@ 2022-06-24  9:08   ` Ni, Ray
  0 siblings, 0 replies; 14+ messages in thread
From: Ni, Ray @ 2022-06-24  9:08 UTC (permalink / raw)
  To: Kun Qin, devel@edk2.groups.io; +Cc: Andrew Fish

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Kun Qin <kuqin12@gmail.com>
> Sent: Tuesday, June 14, 2022 4:40 AM
> To: devel@edk2.groups.io
> Cc: Andrew Fish <afish@apple.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [PATCH v2 11/11] EmulatorPkg: Pipeline: Resolve SecureBootVariableLib dependency
> 
> The new changes in SecureBootVariableLib brought in a new dependency of
> PlatformPKProtectionLib.
> 
> This change added the new library instance from SecurityPkg to resolve
> pipeline builds.
> 
> Cc: Andrew Fish <afish@apple.com>
> Cc: Ray Ni <ray.ni@intel.com>
> 
> Signed-off-by: Kun Qin <kuqin12@gmail.com>
> ---
>  EmulatorPkg/EmulatorPkg.dsc | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc
> index 4cf886b9eac7..b44435d7e6ee 100644
> --- a/EmulatorPkg/EmulatorPkg.dsc
> +++ b/EmulatorPkg/EmulatorPkg.dsc
> @@ -134,6 +134,7 @@ [LibraryClasses]
>    PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
>    AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
>    SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
> +  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
> 
> SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
>  !else
>    AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
> --
> 2.35.1.windows.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [edk2-devel] [PATCH v2 00/11] Enhance Secure Boot Variable Libraries
  2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
                   ` (10 preceding siblings ...)
  2022-06-13 20:39 ` [PATCH v2 11/11] EmulatorPkg: " Kun Qin
@ 2022-06-30 19:44 ` Michael Kubacki
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Kubacki @ 2022-06-30 19:44 UTC (permalink / raw)
  To: devel, kuqin12
  Cc: Jiewen Yao, Jian J Wang, Min Xu, Sean Brogan, Ard Biesheuvel,
	Jordan Justen, Gerd Hoffmann, Rebecca Cran, Peter Grehan,
	Sebastien Boeuf, Andrew Fish, Ray Ni

Acked-by: Michael Kubacki <michael.kubacki@microsoft.com>

On 6/13/2022 4:39 PM, Kun Qin wrote:
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3909
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3910
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3911
> 
> This is a revamp of a previously submitted patch series based on top of
> master branch: https://edk2.groups.io/g/devel/message/89507. No changes
> added.
> 
> Current SecureBootVariableLib provide great support for deleting secure
> boot related variables, creating time-based payloads.
> 
> However, for secure boot enrollment, the SecureBootVariableProvisionLib
> interfaces always assume the changes from variable storage, limiting the
> usage, requiring existing platforms to change key initialization process
> to adapt to the new methods, as well as bringing in extra dependencies
> such as FV protocol, time protocols.
> 
> This patch series proposes to update the implementation for Secure Boot
> Variable libraries and their consumers to better support the related
> variables operations.
> 
> Patch v2 branch: https://github.com/kuqin12/edk2/tree/secure_boot_enhance_v2
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Min Xu <min.m.xu@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Rebecca Cran <rebecca@bsdio.com>
> Cc: Peter Grehan <grehan@freebsd.org>
> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
> Cc: Andrew Fish <afish@apple.com>
> Cc: Ray Ni <ray.ni@intel.com>
> 
> Kun Qin (8):
>    SecurityPkg: UefiSecureBoot: Definitions of cert and payload
>      structures
>    SecurityPkg: PlatformPKProtectionLib: Added PK protection interface
>    SecurityPkg: SecureBootVariableLib: Updated time based payload creator
>    SecurityPkg: SecureBootVariableProvisionLib: Updated implementation
>    SecurityPkg: Secure Boot Drivers: Added common header files
>    SecurityPkg: SecureBootConfigDxe: Updated invocation pattern
>    OvmfPkg: Pipeline: Resolve SecureBootVariableLib dependency
>    EmulatorPkg: Pipeline: Resolve SecureBootVariableLib dependency
> 
> kuqin (3):
>    SecurityPkg: SecureBootVariableLib: Updated signature list creator
>    SecurityPkg: SecureBootVariableLib: Added newly supported interfaces
>    SecurityPkg: SecureBootVariableLib: Added unit tests
> 
>   SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.c                           |    1 +
>   SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.c   |   51 +
>   SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c                         |  486 ++++-
>   SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.c          |   36 +
>   SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.c                          |  201 ++
>   SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.c      |   13 +
>   SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c        | 2037 ++++++++++++++++++++
>   SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c       |  145 +-
>   SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c              |  128 +-
>   SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.c     |    1 +
>   EmulatorPkg/EmulatorPkg.dsc                                                               |    1 +
>   OvmfPkg/Bhyve/BhyveX64.dsc                                                                |    1 +
>   OvmfPkg/CloudHv/CloudHvX64.dsc                                                            |    1 +
>   OvmfPkg/IntelTdx/IntelTdxX64.dsc                                                          |    1 +
>   OvmfPkg/OvmfPkgIa32.dsc                                                                   |    1 +
>   OvmfPkg/OvmfPkgIa32X64.dsc                                                                |    1 +
>   OvmfPkg/OvmfPkgX64.dsc                                                                    |    1 +
>   SecurityPkg/Include/Library/PlatformPKProtectionLib.h                                     |   31 +
>   SecurityPkg/Include/Library/SecureBootVariableLib.h                                       |  103 +-
>   SecurityPkg/Include/UefiSecureBoot.h                                                      |   94 +
>   SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf |   36 +
>   SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf                       |   14 +-
>   SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf        |   33 +
>   SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf                        |   45 +
>   SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf    |   25 +
>   SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf      |   36 +
>   SecurityPkg/SecurityPkg.ci.yaml                                                           |   11 +
>   SecurityPkg/SecurityPkg.dec                                                               |    5 +
>   SecurityPkg/SecurityPkg.dsc                                                               |    2 +
>   SecurityPkg/Test/SecurityPkgHostTest.dsc                                                  |   38 +
>   SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf             |    1 +
>   31 files changed, 3468 insertions(+), 112 deletions(-)
>   create mode 100644 SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.c
>   create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.c
>   create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.c
>   create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.c
>   create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
>   create mode 100644 SecurityPkg/Include/Library/PlatformPKProtectionLib.h
>   create mode 100644 SecurityPkg/Include/UefiSecureBoot.h
>   create mode 100644 SecurityPkg/Library/PlatformPKProtectionLibVarPolicy/PlatformPKProtectionLibVarPolicy.inf
>   create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
>   create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
>   create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
>   create mode 100644 SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf
>   create mode 100644 SecurityPkg/Test/SecurityPkgHostTest.dsc
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-06-30 19:44 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-06-13 20:39 [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Kun Qin
2022-06-13 20:39 ` [PATCH v2 01/11] SecurityPkg: UefiSecureBoot: Definitions of cert and payload structures Kun Qin
2022-06-13 20:39 ` [PATCH v2 02/11] SecurityPkg: PlatformPKProtectionLib: Added PK protection interface Kun Qin
2022-06-13 20:39 ` [PATCH v2 03/11] SecurityPkg: SecureBootVariableLib: Updated time based payload creator Kun Qin
2022-06-13 20:39 ` [PATCH v2 04/11] SecurityPkg: SecureBootVariableLib: Updated signature list creator Kun Qin
2022-06-13 20:39 ` [PATCH v2 05/11] SecurityPkg: SecureBootVariableLib: Added newly supported interfaces Kun Qin
2022-06-13 20:39 ` [PATCH v2 06/11] SecurityPkg: SecureBootVariableProvisionLib: Updated implementation Kun Qin
2022-06-13 20:39 ` [PATCH v2 07/11] SecurityPkg: Secure Boot Drivers: Added common header files Kun Qin
2022-06-13 20:39 ` [PATCH v2 08/11] SecurityPkg: SecureBootConfigDxe: Updated invocation pattern Kun Qin
2022-06-13 20:39 ` [PATCH v2 09/11] SecurityPkg: SecureBootVariableLib: Added unit tests Kun Qin
2022-06-13 20:39 ` [PATCH v2 10/11] OvmfPkg: Pipeline: Resolve SecureBootVariableLib dependency Kun Qin
2022-06-13 20:39 ` [PATCH v2 11/11] EmulatorPkg: " Kun Qin
2022-06-24  9:08   ` Ni, Ray
2022-06-30 19:44 ` [edk2-devel] [PATCH v2 00/11] Enhance Secure Boot Variable Libraries Michael Kubacki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox