summaryrefslogtreecommitdiffstats
path: root/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c')
-rw-r--r--SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c482
1 files changed, 482 insertions, 0 deletions
diff --git a/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c b/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
new file mode 100644
index 0000000000..848f7ce929
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.c
@@ -0,0 +1,482 @@
+/** @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/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/SecureBootVariableProvisionLib.h>
+
+/**
+ 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;
+}
+
+/**
+ 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;
+}
+
+/**
+ 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;
+}
+
+/**
+ 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;
+}
+
+/**
+ 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;
+}
+
+/**
+ 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;
+}