From: "Sunny Wang" <Sunny.Wang@arm.com>
To: Grzegorz Bernacki <gjb@semihalf.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>,
Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: "leif@nuviainc.com" <leif@nuviainc.com>,
"ardb+tianocore@kernel.org" <ardb+tianocore@kernel.org>,
Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>,
"mw@semihalf.com" <mw@semihalf.com>,
"upstream@semihalf.com" <upstream@semihalf.com>,
"jiewen.yao@intel.com" <jiewen.yao@intel.com>,
"jian.j.wang@intel.com" <jian.j.wang@intel.com>,
"min.m.xu@intel.com" <min.m.xu@intel.com>,
"lersek@redhat.com" <lersek@redhat.com>,
Sunny Wang <Sunny.Wang@arm.com>
Subject: Re: [PATCH v2 1/6] SecurityPkg: Create library for setting Secure Boot variables.
Date: Fri, 4 Jun 2021 07:49:39 +0000 [thread overview]
Message-ID: <DB8PR08MB39931FAAB817AEC7ED457BF2853B9@DB8PR08MB3993.eurprd08.prod.outlook.com> (raw)
In-Reply-To: <20210601131229.630611-3-gjb@semihalf.com>
Internally reviewed this patch before sending the edk2 mailing list and Greg already addressed all my comments, so It looks good to me. Please also address Bret and Min M's good catches/comments.
Moreover, for Bret's comment about CreateTimeBasedPayload (), I think we only missed one instance in edk2\MdeModulePkg\Library\PlatformVarCleanupLib\PlatVarCleanupLib.c. If not, feel free to add other instances, Bret.
Reviewed-by: Sunny Wang <sunny.wang@arm.com>
-----Original Message-----
From: Grzegorz Bernacki <gjb@semihalf.com>
Sent: Tuesday, June 1, 2021 9:12 PM
To: devel@edk2.groups.io
Cc: leif@nuviainc.com; ardb+tianocore@kernel.org; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>; Sunny Wang <Sunny.Wang@arm.com>; mw@semihalf.com; upstream@semihalf.com; jiewen.yao@intel.com; jian.j.wang@intel.com; min.m.xu@intel.com; lersek@redhat.com; Grzegorz Bernacki <gjb@semihalf.com>
Subject: [PATCH v2 1/6] SecurityPkg: Create library for setting Secure Boot variables.
This commits add library, which consist functions related
creation/removal Secure Boot variables. Some of the functions
was moved from SecureBootConfigImpl.c file.
Signed-off-by: Grzegorz Bernacki <gjb@semihalf.com>
---
SecurityPkg/SecurityPkg.dsc | 1 +
SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf | 79 ++
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf | 1 +
SecurityPkg/Include/Library/SecureBootVariableLib.h | 252 +++++
SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c | 979 ++++++++++++++++++++
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c | 189 +---
SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni | 16 +
7 files changed, 1329 insertions(+), 188 deletions(-)
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.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..84367841d5
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
@@ -0,0 +1,79 @@
+## @file
+# Provides 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/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
index 573efa6379..30d9cd8025 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
@@ -54,6 +54,7 @@
DevicePathLib
FileExplorerLib
PeCoffLib
+ SecureBootVariableLib
[Guids]
## SOMETIMES_CONSUMES ## Variable:L"CustomMode"
diff --git a/SecurityPkg/Include/Library/SecureBootVariableLib.h b/SecurityPkg/Include/Library/SecureBootVariableLib.h
new file mode 100644
index 0000000000..2961c93a36
--- /dev/null
+++ b/SecurityPkg/Include/Library/SecureBootVariableLib.h
@@ -0,0 +1,252 @@
+/** @file
+ Provides a function to enroll keys based on default values.
+
+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.
+--*/
+BOOLEAN
+EFIAPI
+GetSetupMode (
+ OUT UINT8 *SetupMode
+);
+
+/**
+ 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
+);
+
+/**
+ Sets the content of the 'db' variable based on 'dbDefault' variable content.
+
+ @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
+EnrollDbFromDefault (
+ VOID
+);
+
+/**
+ 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
+);
+
+/**
+ Sets the content of the 'dbx' variable based on 'dbxDefault' variable content.
+
+ @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
+EnrollDbxFromDefault (
+ 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
+);
+
+/**
+ Sets the content of the 'dbt' variable based on 'dbtDefault' variable content.
+
+ @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
+EnrollDbtFromDefault (
+ 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
+);
+
+/**
+ Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
+
+ @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
+EnrollKEKFromDefault (
+ 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
+);
+
+/**
+ Sets the content of the 'PK' variable based on 'PKDefault' variable content.
+
+ @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
+EnrollPKFromDefault (
+ 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
+);
+
+/** Initializes PKDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitPKDefault (
+ IN VOID
+ );
+
+/** Initializes KEKDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitKEKDefault (
+ IN VOID
+ );
+
+/** Initializes dbDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitdbDefault (
+ IN VOID
+ );
+
+/** Initializes dbtDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitdbtDefault (
+ IN VOID
+ );
+
+/** Initializes dbxDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitdbxDefault (
+ IN VOID
+ );
+#endif
diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
new file mode 100644
index 0000000000..16bad5530a
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.c
@@ -0,0 +1,979 @@
+/** @file
+ This library provides 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] SiglListAppend A signature list to be added.
+ @param[out] *SigListOut Created signature database.
+ @param[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] 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.
+
+--*/
+STATIC
+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
+ );
+}
+
+
+/**
+ Enroll a key/certificate based on a default variable.
+
+ @param[in] VariableName The name of the key/database.
+ @param[in] DefaultName The name of the default variable.
+ @param[in] VendorGuid The namespace (ie. vendor GUID) of the variable
+
+
+ @retval EFI_OUT_OF_RESOURCES Out of memory while allocating AuthHeader.
+ @retval EFI_SUCCESS Successful enrollment.
+ @return Error codes from GetTime () and SetVariable ().
+--*/
+STATIC
+EFI_STATUS
+EnrollFromDefault (
+ IN CHAR16 *VariableName,
+ IN CHAR16 *DefaultName,
+ IN EFI_GUID *VendorGuid
+ )
+{
+ VOID *Data;
+ UINTN DataSize;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ DataSize = 0;
+ Status = GetVariable2 (DefaultName, &gEfiGlobalVariableGuid, &Data, &DataSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "error: GetVariable (\"%s): %r\n", DefaultName, Status));
+ 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));
+ }
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ return Status;
+}
+
+/** Initializes PKDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitPKDefault (
+ IN VOID
+ )
+{
+ EFI_SIGNATURE_LIST *EfiSig;
+ UINTN SigListsSize;
+ EFI_STATUS Status;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_PK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_PK_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ return Status;
+ }
+
+ //
+ // Variable does not exist, can be initialized
+ //
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_PK_DEFAULT_VARIABLE_NAME));
+
+ Status = SecureBootFetchData (&gDefaultPKFileGuid, &SigListsSize, &EfiSig);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_PK_DEFAULT_VARIABLE_NAME));
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ EFI_PK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SigListsSize,
+ (VOID *)EfiSig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_PK_DEFAULT_VARIABLE_NAME));
+ }
+
+ FreePool (EfiSig);
+
+ return Status;
+}
+
+/** Initializes KEKDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitKEKDefault (
+ IN VOID
+ )
+{
+ EFI_SIGNATURE_LIST *EfiSig;
+ UINTN SigListsSize;
+ EFI_STATUS Status;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_KEK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ return Status;
+ }
+
+ //
+ // Variable does not exist, can be initialized
+ //
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
+
+ Status = SecureBootFetchData (&gDefaultKEKFileGuid, &SigListsSize, &EfiSig);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
+ return Status;
+ }
+
+
+ Status = gRT->SetVariable (
+ EFI_KEK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SigListsSize,
+ (VOID *)EfiSig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
+ }
+
+ FreePool (EfiSig);
+
+ return Status;
+}
+
+/** Initializes dbDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitdbDefault (
+ IN VOID
+ )
+{
+ EFI_SIGNATURE_LIST *EfiSig;
+ UINTN SigListsSize;
+ EFI_STATUS Status;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ Status = GetVariable2 (EFI_DB_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DB_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ return Status;
+ }
+
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DB_DEFAULT_VARIABLE_NAME));
+
+ Status = SecureBootFetchData (&gDefaultdbFileGuid, &SigListsSize, &EfiSig);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ EFI_DB_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SigListsSize,
+ (VOID *)EfiSig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DB_DEFAULT_VARIABLE_NAME));
+ }
+
+ FreePool (EfiSig);
+
+ return Status;
+}
+
+/** Initializes dbxDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitdbxDefault (
+ IN VOID
+ )
+{
+ EFI_SIGNATURE_LIST *EfiSig;
+ UINTN SigListsSize;
+ EFI_STATUS Status;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_DBX_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ return Status;
+ }
+
+ //
+ // Variable does not exist, can be initialized
+ //
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
+
+ Status = SecureBootFetchData (&gDefaultdbxFileGuid, &SigListsSize, &EfiSig);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ EFI_DBX_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SigListsSize,
+ (VOID *)EfiSig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
+ }
+
+ FreePool (EfiSig);
+
+ return Status;
+}
+
+/** Initializes dbtDefault variable with data from FFS section.
+
+
+ @retval EFI_SUCCESS Variable was initialized successfully.
+ @retval EFI_UNSUPPORTED Variable already exists.
+--*/
+EFI_STATUS
+SecureBootInitdbtDefault (
+ IN VOID
+ )
+{
+ EFI_SIGNATURE_LIST *EfiSig;
+ UINTN SigListsSize;
+ EFI_STATUS Status;
+ UINT8 *Data;
+ UINTN DataSize;
+
+ //
+ // Check if variable exists, if so do not change it
+ //
+ Status = GetVariable2 (EFI_DBT_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **) &Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
+ FreePool (Data);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ return Status;
+ }
+
+ //
+ // Variable does not exist, can be initialized
+ //
+ DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
+
+ Status = SecureBootFetchData (&gDefaultdbtFileGuid, &SigListsSize, &EfiSig);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ EFI_DBT_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SigListsSize,
+ (VOID *)EfiSig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
+ }
+
+ FreePool (EfiSig);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Fetches the value of SetupMode variable.
+
+ @param[out] SetupMode Pointer to UINT8 for SetupMode output
+
+ @retval other Retval from GetVariable.
+--*/
+BOOLEAN
+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;
+}
+
+/**
+ Sets the content of the 'db' variable based on 'dbDefault' variable content.
+
+ @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
+EnrollDbFromDefault (
+ VOID
+)
+{
+ EFI_STATUS Status;
+
+ Status = EnrollFromDefault (
+ EFI_IMAGE_SECURITY_DATABASE,
+ EFI_DB_DEFAULT_VARIABLE_NAME,
+ &gEfiImageSecurityDatabaseGuid
+ );
+
+ return Status;
+}
+
+/**
+ 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;
+}
+
+/**
+ Sets the content of the 'dbx' variable based on 'dbxDefault' variable content.
+
+ @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
+EnrollDbxFromDefault (
+ VOID
+)
+{
+ EFI_STATUS Status;
+
+ Status = EnrollFromDefault (
+ EFI_IMAGE_SECURITY_DATABASE1,
+ EFI_DBX_DEFAULT_VARIABLE_NAME,
+ &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;
+}
+
+/**
+ Sets the content of the 'dbt' variable based on 'dbtDefault' variable content.
+
+ @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
+EnrollDbtFromDefault (
+ VOID
+)
+{
+ EFI_STATUS Status;
+
+ Status = EnrollFromDefault (
+ EFI_IMAGE_SECURITY_DATABASE2,
+ EFI_DBT_DEFAULT_VARIABLE_NAME,
+ &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;
+}
+
+/**
+ Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
+
+ @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
+EnrollKEKFromDefault (
+ VOID
+)
+{
+ EFI_STATUS Status;
+
+ Status = EnrollFromDefault (
+ EFI_KEY_EXCHANGE_KEY_NAME,
+ EFI_KEK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid
+ );
+
+ 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;
+}
+
+/**
+ Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
+
+ @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
+EnrollPKFromDefault (
+ VOID
+)
+{
+ EFI_STATUS Status;
+
+ Status = EnrollFromDefault (
+ EFI_PLATFORM_KEY_NAME,
+ EFI_PK_DEFAULT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid
+ );
+
+ return Status;
+}
+
+/**
+ Remove the PK variable.
+
+ @retval EFI_SUCCESS Delete PK successfully.
+ @retval Others Could not allow to delete PK.
+
+--*/
+EFI_STATUS
+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/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index e82bfe7757..67e5e594ed 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "SecureBootConfigImpl.h"
#include <Library/BaseCryptLib.h>
+#include <Library/SecureBootVariableLib.h>
CHAR16 mSecureBootStorageName[] = L"SECUREBOOT_CONFIGURATION";
@@ -237,168 +238,6 @@ SaveSecureBootVariable (
return Status;
}
-/**
- 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 ((EFI_D_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
- );
-}
-
/**
This code checks if the encode type and key strength of X.509
certificate is qualified.
@@ -646,32 +485,6 @@ ON_EXIT:
return Status;
}
-/**
- Remove the PK variable.
-
- @retval EFI_SUCCESS Delete PK successfully.
- @retval Others Could not allow to delete PK.
-
-**/
-EFI_STATUS
-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;
-}
-
/**
Enroll a new KEK item from public key storing file (*.pbk).
diff --git a/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni
new file mode 100644
index 0000000000..2c51e4db53
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.uni
@@ -0,0 +1,16 @@
+// /** @file
+//
+// Provides 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 function to initialize PK, KEK and databases based on default variables."
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides function to initialize PK, KEK and databases based on default variables."
+
--
2.25.1
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
next prev parent reply other threads:[~2021-06-04 7:50 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-01 13:12 [PATCH v2 0/6] Secure Boot default keys Grzegorz Bernacki
2021-06-01 13:12 ` [edk2-platforms PATCH v2] Platform/RaspberryPi: Enable default Secure Boot variables initialization Grzegorz Bernacki
2021-06-02 17:40 ` [edk2-devel] " Pete Batard
2021-06-04 8:35 ` Sunny Wang
2021-07-08 18:37 ` Samer El-Haj-Mahmoud
2021-06-01 13:12 ` [PATCH v2 1/6] SecurityPkg: Create library for setting Secure Boot variables Grzegorz Bernacki
2021-06-02 17:39 ` [edk2-devel] " Pete Batard
2021-06-02 19:43 ` [EXTERNAL] " Bret Barkelew
2021-06-03 6:56 ` Min Xu
2021-06-04 7:49 ` Sunny Wang [this message]
2021-06-01 13:12 ` [PATCH v2 2/6] SecurityPkg: Create include file for default key content Grzegorz Bernacki
2021-06-02 17:39 ` [edk2-devel] " Pete Batard
2021-06-03 7:06 ` Min Xu
2021-06-04 8:11 ` Sunny Wang
2021-06-01 13:12 ` [PATCH v2 3/6] SecurityPkg: Add SecureBootDefaultKeysDxe driver Grzegorz Bernacki
2021-06-02 17:39 ` [edk2-devel] " Pete Batard
2021-06-04 8:02 ` Min Xu
2021-06-04 8:15 ` Sunny Wang
2021-06-01 13:12 ` [PATCH v2 4/6] SecurityPkg: Add EnrollFromDefaultKeys application Grzegorz Bernacki
2021-06-02 17:40 ` [edk2-devel] " Pete Batard
2021-06-02 19:38 ` [EXTERNAL] " Bret Barkelew
2021-06-04 8:24 ` Sunny Wang
2021-06-01 13:12 ` [PATCH v2 5/6] SecurityPkg: Add new modules to Security package Grzegorz Bernacki
2021-06-02 17:40 ` [edk2-devel] " Pete Batard
2021-06-04 8:09 ` Min Xu
2021-06-04 8:26 ` Sunny Wang
2021-06-01 13:12 ` [PATCH v2 6/6] SecurityPkg: Add option to reset secure boot keys Grzegorz Bernacki
2021-06-02 17:40 ` [edk2-devel] " Pete Batard
2021-06-04 8:30 ` Sunny Wang
2021-06-04 8:17 ` [PATCH v2 0/6] Secure Boot default keys Min Xu
2021-06-07 7:29 ` Grzegorz Bernacki
2021-06-14 9:47 ` Grzegorz Bernacki
2021-06-17 1:30 ` [edk2-devel] " Min Xu
2021-06-17 12:54 ` Grzegorz Bernacki
2021-06-17 13:37 ` Min Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DB8PR08MB39931FAAB817AEC7ED457BF2853B9@DB8PR08MB3993.eurprd08.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox