[edk2-devel] [PATCH v7 01/11] SecurityPkg: Create SecureBootVariableLib.

Grzegorz Bernacki gjb at semihalf.com
Fri Jul 30 10:23:16 UTC 2021


This commits add library, which consist helper functions related
to creation/removal Secure Boot variables. Some of the functions
was moved from SecureBootConfigImpl.c file.

Signed-off-by: Grzegorz Bernacki <gjb at semihalf.com>
Reviewed-by: Sunny Wang <sunny.wang at arm.com>
Reviewed-by: Jiewen Yao <Jiewen.yao at intel.com>
---
 SecurityPkg/SecurityPkg.dec                                         |   4 +
 SecurityPkg/SecurityPkg.dsc                                         |   1 +
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf |  80 +++
 SecurityPkg/Include/Library/SecureBootVariableLib.h                 | 153 ++++++
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c   | 510 ++++++++++++++++++++
 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni |  17 +
 6 files changed, 765 insertions(+)
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
 create mode 100644 SecurityPkg/Include/Library/SecureBootVariableLib.h
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
 create mode 100644 SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni

diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index 4001650fa2..8f3710e59f 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -87,6 +87,10 @@
   ## @libraryclass  Provides interfaces about firmware TPM measurement.
   #
   TcgEventLogRecordLib|Include/Library/TcgEventLogRecordLib.h
+
+  ## @libraryclass  Provides helper functions related to creation/removal Secure Boot variables.
+  #
+  SecureBootVariableLib|Include/Library/SecureBootVariableLib.h
 [Guids]
   ## Security package token space guid.
   # Include/Guid/SecurityPkgTokenSpace.h
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index bd4b810bce..854f250625 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -70,6 +70,7 @@
   RpmcLib|SecurityPkg/Library/RpmcLibNull/RpmcLibNull.inf
   TcgEventLogRecordLib|SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.inf
   MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
+  SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
 
 [LibraryClasses.ARM]
   #
diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
new file mode 100644
index 0000000000..b32814736d
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
@@ -0,0 +1,80 @@
+## @file
+#  Provides helper function for initialization of Secure Boot
+#  keys and databases.
+#
+#  Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2021, Semihalf All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecureBootVariableLib
+  MODULE_UNI_FILE                = SecureBootVariableLib.uni
+  FILE_GUID                      = D4FFF5CA-6D8E-4DBD-8A4B-7C7CEBD97F6F
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SecureBootVariableLib|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]
+  SecureBootVariableLib.c
+
+[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"
+  ## PRODUCES            ## Variable:L"SetupMode"
+  ## CONSUMES            ## Variable:L"SecureBoot"
+  ## PRODUCES            ## Variable:L"SecureBoot"
+  ## PRODUCES            ## Variable:L"PK"
+  ## PRODUCES            ## Variable:L"KEK"
+  ## CONSUMES            ## Variable:L"PKDefault"
+  ## CONSUMES            ## Variable:L"KEKDefault"
+  ## CONSUMES            ## Variable:L"dbDefault"
+  ## CONSUMES            ## Variable:L"dbxDefault"
+  ## CONSUMES            ## Variable:L"dbtDefault"
+  gEfiGlobalVariableGuid
+
+  ## SOMETIMES_CONSUMES  ## Variable:L"DB"
+  ## SOMETIMES_CONSUMES  ## Variable:L"DBX"
+  ## SOMETIMES_CONSUMES  ## Variable:L"DBT"
+  gEfiImageSecurityDatabaseGuid
+
+  ## CONSUMES            ## Variable:L"SecureBootEnable"
+  ## PRODUCES            ## Variable:L"SecureBootEnable"
+  gEfiSecureBootEnableDisableGuid
+
+  ## CONSUMES            ## Variable:L"CustomMode"
+  ## PRODUCES            ## Variable:L"CustomMode"
+  gEfiCustomModeEnableGuid
+
+  gEfiCertTypeRsa2048Sha256Guid  ## CONSUMES
+  gEfiCertX509Guid               ## CONSUMES
+  gEfiCertPkcs7Guid              ## CONSUMES
+
+  gDefaultPKFileGuid
+  gDefaultKEKFileGuid
+  gDefaultdbFileGuid
+  gDefaultdbxFileGuid
+  gDefaultdbtFileGuid
+
diff --git a/SecurityPkg/Include/Library/SecureBootVariableLib.h b/SecurityPkg/Include/Library/SecureBootVariableLib.h
new file mode 100644
index 0000000000..6e6d624071
--- /dev/null
+++ b/SecurityPkg/Include/Library/SecureBootVariableLib.h
@@ -0,0 +1,153 @@
+/** @file
+  Provides a helper functions for creating variable authenticated
+  payloads, signature lists related to secure boot keys.
+
+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>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SECURE_BOOT_VARIABLE_LIB_H_
+#define SECURE_BOOT_VARIABLE_LIB_H_
+
+/**
+  Set the platform secure boot mode into "Custom" or "Standard" mode.
+
+  @param[in]   SecureBootMode        New secure boot mode: STANDARD_SECURE_BOOT_MODE or
+                                     CUSTOM_SECURE_BOOT_MODE.
+
+  @return EFI_SUCCESS                The platform has switched to the special mode successfully.
+  @return other                      Fail to operate the secure boot mode.
+
+--*/
+EFI_STATUS
+SetSecureBootMode (
+  IN  UINT8  SecureBootMode
+);
+
+/**
+  Fetches the value of SetupMode variable.
+
+  @param[out] SetupMode             Pointer to UINT8 for SetupMode output
+
+  @retval other                     Error codes from GetVariable.
+--*/
+EFI_STATUS
+EFIAPI
+GetSetupMode (
+  OUT UINT8 *SetupMode
+);
+
+/**
+  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]       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.
+  @retval EFI_INVALID_PARAMETER    Embedded key has a wrong format.
+  @retval Others                   Unexpected error happens.
+
+--*/
+EFI_STATUS
+SecureBootFetchData (
+    IN  EFI_GUID           *KeyFileGuid,
+    OUT UINTN              *SigListsSize,
+    OUT EFI_SIGNATURE_LIST **SigListOut
+);
+
+/**
+  Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2
+  descriptor with the input data. NO authentication is required in this function.
+
+  @param[in, out]   DataSize       On input, the size of Data buffer in bytes.
+                                   On output, the size of data returned in Data
+                                   buffer in bytes.
+  @param[in, out]   Data           On input, Pointer to data buffer to be wrapped or
+                                   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.
+
+  @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
+CreateTimeBasedPayload (
+  IN OUT UINTN            *DataSize,
+  IN OUT UINT8            **Data
+);
+
+/**
+  Clears the content of the 'db' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2(), GetTime() and SetVariable()
+--*/
+EFI_STATUS
+EFIAPI
+DeleteDb (
+  VOID
+);
+
+/**
+  Clears the content of the 'dbx' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2(), GetTime() and SetVariable()
+--*/
+EFI_STATUS
+EFIAPI
+DeleteDbx (
+  VOID
+);
+
+/**
+  Clears the content of the 'dbt' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2(), GetTime() and SetVariable()
+--*/
+EFI_STATUS
+EFIAPI
+DeleteDbt (
+  VOID
+);
+
+/**
+  Clears the content of the 'KEK' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2(), GetTime() and SetVariable()
+--*/
+EFI_STATUS
+EFIAPI
+DeleteKEK (
+  VOID
+);
+
+/**
+  Clears the content of the 'PK' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2(), GetTime() and SetVariable()
+--*/
+EFI_STATUS
+EFIAPI
+DeletePlatformKey (
+  VOID
+);
+#endif
diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
new file mode 100644
index 0000000000..ce99f6c808
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
@@ -0,0 +1,510 @@
+/** @file
+  This library provides helper functions to set/clear Secure Boot
+  keys and databases.
+
+  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>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#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>
+#include <Library/UefiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SecureBootVariableLib.h>
+#include "Library/DxeServicesLib.h"
+
+/** Creates EFI Signature List structure.
+
+  @param[in]      Data     A pointer to signature data.
+  @param[in]      Size     Size of signature data.
+  @param[out]     SigList  Created Signature List.
+
+  @retval  EFI_SUCCESS           Signature List was created successfully.
+  @retval  EFI_OUT_OF_RESOURCES  Failed to allocate memory.
+--*/
+STATIC
+EFI_STATUS
+CreateSigList (
+  IN VOID                *Data,
+  IN UINTN               Size,
+  OUT EFI_SIGNATURE_LIST **SigList
+  )
+{
+  UINTN                  SigListSize;
+  EFI_SIGNATURE_LIST     *TmpSigList;
+  EFI_SIGNATURE_DATA     *SigData;
+
+  //
+  // Allocate data for Signature Database
+  //
+  SigListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + Size;
+  TmpSigList = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SigListSize);
+  if (TmpSigList == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Only gEfiCertX509Guid type is supported
+  //
+  TmpSigList->SignatureListSize = (UINT32)SigListSize;
+  TmpSigList->SignatureSize = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + Size);
+  TmpSigList->SignatureHeaderSize = 0;
+  CopyGuid (&TmpSigList->SignatureType, &gEfiCertX509Guid);
+
+  //
+  // Copy key data
+  //
+  SigData = (EFI_SIGNATURE_DATA *) (TmpSigList + 1);
+  CopyGuid (&SigData->SignatureOwner, &gEfiGlobalVariableGuid);
+  CopyMem (&SigData->SignatureData[0], Data, Size);
+
+  *SigList = TmpSigList;
+
+  return EFI_SUCCESS;
+}
+
+/** Adds new signature list to signature database.
+
+  @param[in]      SigLists        A pointer to signature database.
+  @param[in]      SigListAppend  A signature list to be added.
+  @param[out]     *SigListOut     Created signature database.
+  @param[in, out] SigListsSize    A size of created signature database.
+
+  @retval  EFI_SUCCESS           Signature List was added successfully.
+  @retval  EFI_OUT_OF_RESOURCES  Failed to allocate memory.
+--*/
+STATIC
+EFI_STATUS
+ConcatenateSigList (
+  IN  EFI_SIGNATURE_LIST *SigLists,
+  IN  EFI_SIGNATURE_LIST *SigListAppend,
+  OUT EFI_SIGNATURE_LIST **SigListOut,
+  IN OUT UINTN           *SigListsSize
+)
+{
+  EFI_SIGNATURE_LIST *TmpSigList;
+  UINT8              *Offset;
+  UINTN              NewSigListsSize;
+
+  NewSigListsSize = *SigListsSize + SigListAppend->SignatureListSize;
+
+  TmpSigList = (EFI_SIGNATURE_LIST *) AllocateZeroPool (NewSigListsSize);
+  if (TmpSigList == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (TmpSigList, SigLists, *SigListsSize);
+
+  Offset = (UINT8 *)TmpSigList;
+  Offset += *SigListsSize;
+  CopyMem ((VOID *)Offset, SigListAppend, SigListAppend->SignatureListSize);
+
+  *SigListsSize = NewSigListsSize;
+  *SigListOut = TmpSigList;
+  return EFI_SUCCESS;
+}
+
+/**
+  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.
+
+--*/
+EFI_STATUS
+SecureBootFetchData (
+    IN  EFI_GUID           *KeyFileGuid,
+    OUT UINTN              *SigListsSize,
+    OUT EFI_SIGNATURE_LIST **SigListOut
+)
+{
+  EFI_SIGNATURE_LIST *EfiSig;
+  EFI_SIGNATURE_LIST *TmpEfiSig;
+  EFI_SIGNATURE_LIST *TmpEfiSig2;
+  EFI_STATUS         Status;
+  VOID               *Buffer;
+  VOID               *RsaPubKey;
+  UINTN               Size;
+  UINTN               KeyIndex;
+
+
+  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));
+        if (EfiSig != NULL) {
+          FreePool(EfiSig);
+        }
+        FreePool(Buffer);
+        return EFI_INVALID_PARAMETER;
+      }
+
+      Status = CreateSigList (Buffer, Size, &TmpEfiSig);
+
+      //
+      // Concatenate lists if more than one section found
+      //
+      if (KeyIndex == 0) {
+        EfiSig = TmpEfiSig;
+        *SigListsSize = TmpEfiSig->SignatureListSize;
+      } else {
+        ConcatenateSigList (EfiSig, TmpEfiSig, &TmpEfiSig2, SigListsSize);
+        FreePool (EfiSig);
+        FreePool (TmpEfiSig);
+        EfiSig = TmpEfiSig2;
+      }
+
+      KeyIndex++;
+      FreePool (Buffer);
+    } if (Status == EFI_NOT_FOUND) {
+      break;
+    }
+  };
+
+  if (KeyIndex == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  *SigListOut = EfiSig;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2
+  descriptor with the input data. NO authentication is required in this function.
+
+  @param[in, out]   DataSize       On input, the size of Data buffer in bytes.
+                                   On output, the size of data returned in Data
+                                   buffer in bytes.
+  @param[in, out]   Data           On input, Pointer to data buffer to be wrapped or
+                                   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.
+
+  @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
+CreateTimeBasedPayload (
+  IN OUT UINTN            *DataSize,
+  IN OUT UINT8            **Data
+  )
+{
+  EFI_STATUS                       Status;
+  UINT8                            *NewData;
+  UINT8                            *Payload;
+  UINTN                            PayloadSize;
+  EFI_VARIABLE_AUTHENTICATION_2    *DescriptorData;
+  UINTN                            DescriptorSize;
+  EFI_TIME                         Time;
+
+  if (Data == NULL || DataSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // In Setup mode or Custom mode, the variable does not need to be signed but the
+  // parameters to the SetVariable() call still need to be prepared as authenticated
+  // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate
+  // data in it.
+  //
+  Payload     = *Data;
+  PayloadSize = *DataSize;
+
+  DescriptorSize    = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
+  NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize);
+  if (NewData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  if ((Payload != NULL) && (PayloadSize != 0)) {
+    CopyMem (NewData + DescriptorSize, Payload, PayloadSize);
+  }
+
+  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));
+
+  DescriptorData->AuthInfo.Hdr.dwLength         = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
+  DescriptorData->AuthInfo.Hdr.wRevision        = 0x0200;
+  DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
+  CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid);
+
+  if (Payload != NULL) {
+    FreePool(Payload);
+  }
+
+  *DataSize = DescriptorSize + PayloadSize;
+  *Data     = NewData;
+  return EFI_SUCCESS;
+}
+
+/**
+  Internal helper function to delete a Variable given its name and GUID, NO authentication
+  required.
+
+  @param[in]      VariableName            Name of the Variable.
+  @param[in]      VendorGuid              GUID of the Variable.
+
+  @retval EFI_SUCCESS              Variable deleted successfully.
+  @retval Others                   The driver failed to start the device.
+
+--*/
+EFI_STATUS
+DeleteVariable (
+  IN  CHAR16                    *VariableName,
+  IN  EFI_GUID                  *VendorGuid
+  )
+{
+  EFI_STATUS              Status;
+  VOID*                   Variable;
+  UINT8                   *Data;
+  UINTN                   DataSize;
+  UINT32                  Attr;
+
+  GetVariable2 (VariableName, VendorGuid, &Variable, NULL);
+  if (Variable == NULL) {
+    return EFI_SUCCESS;
+  }
+  FreePool (Variable);
+
+  Data     = NULL;
+  DataSize = 0;
+  Attr     = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS
+             | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+
+  Status = CreateTimeBasedPayload (&DataSize, &Data);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
+    return Status;
+  }
+
+  Status = gRT->SetVariable (
+                  VariableName,
+                  VendorGuid,
+                  Attr,
+                  DataSize,
+                  Data
+                  );
+  if (Data != NULL) {
+    FreePool (Data);
+  }
+  return Status;
+}
+
+/**
+
+  Set the platform secure boot mode into "Custom" or "Standard" mode.
+
+  @param[in]   SecureBootMode        New secure boot mode: STANDARD_SECURE_BOOT_MODE or
+                                     CUSTOM_SECURE_BOOT_MODE.
+
+  @return EFI_SUCCESS                The platform has switched to the special mode successfully.
+  @return other                      Fail to operate the secure boot mode.
+
+--*/
+EFI_STATUS
+SetSecureBootMode (
+  IN  UINT8  SecureBootMode
+  )
+{
+  return gRT->SetVariable (
+                EFI_CUSTOM_MODE_NAME,
+                &gEfiCustomModeEnableGuid,
+                EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                sizeof (UINT8),
+                &SecureBootMode
+                );
+}
+
+/**
+  Fetches the value of SetupMode variable.
+
+  @param[out] SetupMode             Pointer to UINT8 for SetupMode output
+
+  @retval other                     Retval from GetVariable.
+--*/
+EFI_STATUS
+EFIAPI
+GetSetupMode (
+    OUT UINT8 *SetupMode
+)
+{
+  UINTN      Size;
+  EFI_STATUS Status;
+
+  Size = sizeof (*SetupMode);
+  Status = gRT->GetVariable (
+                  EFI_SETUP_MODE_NAME,
+                  &gEfiGlobalVariableGuid,
+                  NULL,
+                  &Size,
+                  SetupMode
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Clears the content of the 'db' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2 (), GetTime () and SetVariable ()
+--*/
+EFI_STATUS
+EFIAPI
+DeleteDb (
+  VOID
+)
+{
+  EFI_STATUS Status;
+
+  Status = DeleteVariable (
+             EFI_IMAGE_SECURITY_DATABASE,
+             &gEfiImageSecurityDatabaseGuid
+             );
+
+  return Status;
+}
+
+/**
+  Clears the content of the 'dbx' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2 (), GetTime () and SetVariable ()
+--*/
+EFI_STATUS
+EFIAPI
+DeleteDbx (
+  VOID
+)
+{
+  EFI_STATUS Status;
+
+  Status = DeleteVariable (
+             EFI_IMAGE_SECURITY_DATABASE1,
+             &gEfiImageSecurityDatabaseGuid
+             );
+
+  return Status;
+}
+
+/**
+  Clears the content of the 'dbt' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2 (), GetTime () and SetVariable ()
+--*/
+EFI_STATUS
+EFIAPI
+DeleteDbt (
+  VOID
+)
+{
+  EFI_STATUS Status;
+
+  Status = DeleteVariable (
+             EFI_IMAGE_SECURITY_DATABASE2,
+             &gEfiImageSecurityDatabaseGuid
+             );
+
+  return Status;
+}
+
+/**
+  Clears the content of the 'KEK' variable.
+
+  @retval EFI_OUT_OF_RESOURCES      If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
+                                    while VendorGuid is NULL.
+  @retval other                     Errors from GetVariable2 (), GetTime () and SetVariable ()
+--*/
+EFI_STATUS
+EFIAPI
+DeleteKEK (
+  VOID
+)
+{
+  EFI_STATUS Status;
+
+  Status = DeleteVariable (
+             EFI_KEY_EXCHANGE_KEY_NAME,
+             &gEfiGlobalVariableGuid
+             );
+
+  return Status;
+}
+
+/**
+  Remove the PK variable.
+
+  @retval EFI_SUCCESS    Delete PK successfully.
+  @retval Others         Could not allow to delete PK.
+
+--*/
+EFI_STATUS
+EFIAPI
+DeletePlatformKey (
+  VOID
+)
+{
+  EFI_STATUS Status;
+
+  Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = DeleteVariable (
+             EFI_PLATFORM_KEY_NAME,
+             &gEfiGlobalVariableGuid
+             );
+  return Status;
+}
diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni
new file mode 100644
index 0000000000..2d5fb7cbb8
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni
@@ -0,0 +1,17 @@
+// /** @file
+//
+// Provides helper function for initialization of Secure Boot
+// keys and databases.
+//
+// Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
+// Copyright (c) 2021, Semihalf All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Provides helper functions to initialize PK, KEK and databases based on default variables."
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Provides helper functions to initialize PK, KEK and databases based on default variables."
+
-- 
2.25.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#78424): https://edk2.groups.io/g/devel/message/78424
Mute This Topic: https://groups.io/mt/84547393/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list