UefiPayloadPkg: Add Secureboot support

Must use RuntimeVariableDxe instead of EmuVariableDxe.
Currently doesn't boot on qemu.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
This commit is contained in:
Patrick Rudolph
2020-04-01 15:05:54 +02:00
committed by Tim Crawford
parent b9564773f1
commit eec38fd383
12 changed files with 856 additions and 3 deletions

View File

@@ -0,0 +1,644 @@
/** @file
Enroll default PK, KEK, DB and DBX
Copyright (C) 2014, Red Hat, Inc.
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Guid/AuthenticatedVariableFormat.h>
#include <Guid/GlobalVariable.h>
#include <Guid/ImageAuthentication.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#define EFI_MICROSOFT_KEK_CERT_GUID \
{ 0xA23665E3, 0xACA6, 0x4F6D, {0x80, 0xCC, 0x34, 0x1E, 0x7D, 0x7B, 0x8C, 0xC6} }
#define EFI_SECUREBOOT_PK_CERT_GUID \
{ 0xF8104268, 0xA364, 0x45F5, {0x8E, 0x00, 0xAB, 0xA3, 0xFD, 0xEA, 0x12, 0xBE} }
#define EFI_MICROSOFT_DB1_CERT_GUID \
{ 0x26A517B0, 0xE3FD, 0x46C2, {0x89, 0x32, 0xE9, 0x26, 0xBF, 0x98, 0x94, 0x1F} }
#define EFI_MICROSOFT_DB2_CERT_GUID \
{ 0x91D2E32B, 0x0134, 0x4306, {0xBA, 0x90, 0x54, 0xED, 0xCB, 0xF3, 0x49, 0xCA} }
#define EFI_MICROSOFT_DBX_GUID \
{ 0x74BB6E72, 0x2A56, 0x4D0E, {0xA5, 0xB3, 0x5D, 0x39, 0xFC, 0x2E, 0xE3, 0x46} }
#define EFI_MICROSOFT_OWNER_GUID \
{ 0x77FA9ABD, 0x0359, 0x4D32, {0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B} }
EFI_GUID gEfiSecureBootDb1CertGuid = EFI_MICROSOFT_DB1_CERT_GUID;
EFI_GUID gEfiSecureBootDb2CertGuid = EFI_MICROSOFT_DB2_CERT_GUID;
EFI_GUID gEfiSecureBootDbxCrlGuid = EFI_MICROSOFT_DBX_GUID;
EFI_GUID gEfiSecureBootKekCertGuid = EFI_MICROSOFT_KEK_CERT_GUID;
EFI_GUID gEfiSecureBootPkCertGuid = EFI_SECUREBOOT_PK_CERT_GUID;
EFI_GUID gEfiMicrosoftOwnerGuid = EFI_MICROSOFT_OWNER_GUID;
//
// The most important thing about the variable payload is that it is a list of
// lists, where the element size of any given *inner* list is constant.
//
// Since X509 certificates vary in size, each of our *inner* lists will contain
// one element only (one X.509 certificate). This is explicitly mentioned in
// the UEFI specification, in "28.4.1 Signature Database", in a Note.
//
// The list structure looks as follows:
//
// struct EFI_VARIABLE_AUTHENTICATION_2 { |
// struct EFI_TIME { |
// UINT16 Year; |
// UINT8 Month; |
// UINT8 Day; |
// UINT8 Hour; |
// UINT8 Minute; |
// UINT8 Second; |
// UINT8 Pad1; |
// UINT32 Nanosecond; |
// INT16 TimeZone; |
// UINT8 Daylight; |
// UINT8 Pad2; |
// } TimeStamp; |
// |
// struct WIN_CERTIFICATE_UEFI_GUID { | |
// struct WIN_CERTIFICATE { | |
// UINT32 dwLength; ----------------------------------------+ |
// UINT16 wRevision; | |
// UINT16 wCertificateType; | |
// } Hdr; | +- DataSize
// | |
// EFI_GUID CertType; | |
// UINT8 CertData[1] = { <--- "struct hack" | |
// struct EFI_SIGNATURE_LIST { | | |
// EFI_GUID SignatureType; | | |
// UINT32 SignatureListSize; -------------------------+ | |
// UINT32 SignatureHeaderSize; | | |
// UINT32 SignatureSize; ---------------------------+ | | |
// UINT8 SignatureHeader[SignatureHeaderSize]; | | | |
// v | | |
// struct EFI_SIGNATURE_DATA { | | | |
// EFI_GUID SignatureOwner; | | | |
// UINT8 SignatureData[1] = { <--- "struct hack" | | | |
// X.509 payload | | | |
// } | | | |
// } Signatures[]; | | |
// } SigLists[]; | |
// }; | |
// } AuthInfo; | |
// }; |
//
// Given that the "struct hack" invokes undefined behavior (which is why C99
// introduced the flexible array member), and because subtracting those pesky
// sizes of 1 is annoying, and because the format is fully specified in the
// UEFI specification, we'll introduce two matching convenience structures that
// are customized for our X.509 purposes.
//
#pragma pack(1)
typedef struct {
EFI_TIME TimeStamp;
//
// dwLength covers data below
//
UINT32 dwLength;
UINT16 wRevision;
UINT16 wCertificateType;
EFI_GUID CertType;
} SINGLE_HEADER;
typedef struct {
//
// SignatureListSize covers data below
//
EFI_GUID SignatureType;
UINT32 SignatureListSize;
UINT32 SignatureHeaderSize; // constant 0
UINT32 SignatureSize;
//
// SignatureSize covers data below
//
EFI_GUID SignatureOwner;
//
// X.509 certificate follows
//
} REPEATING_HEADER;
#pragma pack()
/**
Enroll a set of certificates in a global variable, overwriting it.
The variable will be rewritten with NV+BS+RT+AT attributes.
@param[in] VariableName The name of the variable to overwrite.
@param[in] VendorGuid The namespace (ie. vendor GUID) of the variable to
overwrite.
@param[in] CertType The GUID determining the type of all the
certificates in the set that is passed in. For
example, gEfiCertX509Guid stands for DER-encoded
X.509 certificates, while gEfiCertSha256Guid stands
for SHA256 image hashes.
@param[in] ... A list of
IN CONST UINT8 *Cert,
IN UINTN CertSize,
IN CONST EFI_GUID *OwnerGuid
triplets. If the first component of a triplet is
NULL, then the other two components are not
accessed, and processing is terminated. The list of
certificates is enrolled in the variable specified,
overwriting it. The OwnerGuid component identifies
the agent installing the certificate.
@retval EFI_INVALID_PARAMETER The triplet list is empty (ie. the first Cert
value is NULL), or one of the CertSize values
is 0, or one of the CertSize values would
overflow the accumulated UINT32 data size.
@retval EFI_OUT_OF_RESOURCES Out of memory while formatting variable
payload.
@retval EFI_SUCCESS Enrollment successful; the variable has been
overwritten (or created).
@return Error codes from gRT->GetTime() and
gRT->SetVariable().
**/
STATIC
EFI_STATUS
EFIAPI
EnrollListOfCerts (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN EFI_GUID *CertType,
...
)
{
UINTN DataSize;
SINGLE_HEADER *SingleHeader;
REPEATING_HEADER *RepeatingHeader;
VA_LIST Marker;
CONST UINT8 *Cert;
EFI_STATUS Status;
UINT8 *Data;
UINT8 *Position;
Status = EFI_SUCCESS;
//
// compute total size first, for UINT32 range check, and allocation
//
DataSize = sizeof *SingleHeader;
VA_START (Marker, CertType);
for (Cert = VA_ARG (Marker, CONST UINT8 *);
Cert != NULL;
Cert = VA_ARG (Marker, CONST UINT8 *)) {
UINTN CertSize;
CertSize = VA_ARG (Marker, UINTN);
(VOID)VA_ARG (Marker, CONST EFI_GUID *);
if (CertSize == 0 ||
CertSize > MAX_UINT32 - sizeof *RepeatingHeader ||
DataSize > MAX_UINT32 - sizeof *RepeatingHeader - CertSize) {
Status = EFI_INVALID_PARAMETER;
break;
}
DataSize += sizeof *RepeatingHeader + CertSize;
}
VA_END (Marker);
if (DataSize == sizeof *SingleHeader) {
Status = EFI_INVALID_PARAMETER;
}
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: Invalid certificate parameters\n"));
goto Out;
}
Data = AllocatePool (DataSize);
if (Data == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Out;
}
Position = Data;
SingleHeader = (SINGLE_HEADER *)Position;
Status = gRT->GetTime (&SingleHeader->TimeStamp, NULL);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "SecureBootSetup: GetTime failed\n"));
// Fill in dummy values
SingleHeader->TimeStamp.Year = 2018;
SingleHeader->TimeStamp.Month = 1;
SingleHeader->TimeStamp.Day = 1;
SingleHeader->TimeStamp.Hour = 0;
SingleHeader->TimeStamp.Minute = 0;
SingleHeader->TimeStamp.Second = 0;
Status = EFI_SUCCESS;
}
SingleHeader->TimeStamp.Pad1 = 0;
SingleHeader->TimeStamp.Nanosecond = 0;
SingleHeader->TimeStamp.TimeZone = 0;
SingleHeader->TimeStamp.Daylight = 0;
SingleHeader->TimeStamp.Pad2 = 0;
//
// This looks like a bug in edk2. According to the UEFI specification,
// dwLength is "The length of the entire certificate, including the length of
// the header, in bytes". That shouldn't stop right after CertType -- it
// should include everything below it.
//
SingleHeader->dwLength = sizeof *SingleHeader - sizeof SingleHeader->TimeStamp;
SingleHeader->wRevision = 0x0200;
SingleHeader->wCertificateType = WIN_CERT_TYPE_EFI_GUID;
CopyGuid (&SingleHeader->CertType, &gEfiCertPkcs7Guid);
Position += sizeof *SingleHeader;
VA_START (Marker, CertType);
for (Cert = VA_ARG (Marker, CONST UINT8 *);
Cert != NULL;
Cert = VA_ARG (Marker, CONST UINT8 *)) {
UINTN CertSize;
CONST EFI_GUID *OwnerGuid;
CertSize = VA_ARG (Marker, UINTN);
OwnerGuid = VA_ARG (Marker, CONST EFI_GUID *);
RepeatingHeader = (REPEATING_HEADER *)Position;
CopyGuid (&RepeatingHeader->SignatureType, CertType);
RepeatingHeader->SignatureListSize =
(UINT32)(sizeof *RepeatingHeader + CertSize);
RepeatingHeader->SignatureHeaderSize = 0;
RepeatingHeader->SignatureSize =
(UINT32)(sizeof RepeatingHeader->SignatureOwner + CertSize);
CopyGuid (&RepeatingHeader->SignatureOwner, OwnerGuid);
Position += sizeof *RepeatingHeader;
CopyMem (Position, Cert, CertSize);
Position += CertSize;
}
VA_END (Marker);
ASSERT (Data + DataSize == Position);
Status = gRT->SetVariable (VariableName, VendorGuid,
(EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
DataSize, Data);
FreePool (Data);
Out:
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: %a(\"%s\", %g): %r\n", __FUNCTION__, VariableName,
VendorGuid, Status));
}
return Status;
}
STATIC
EFI_STATUS
EFIAPI
GetExact (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VOID *Data,
IN UINTN DataSize,
IN BOOLEAN AllowMissing
)
{
UINTN Size;
EFI_STATUS Status;
Size = DataSize;
Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &Size, Data);
if (EFI_ERROR (Status)) {
if (Status == EFI_NOT_FOUND && AllowMissing) {
ZeroMem (Data, DataSize);
return EFI_SUCCESS;
}
DEBUG ((EFI_D_ERROR, "SecureBootSetup: GetVariable(\"%s\", %g): %r\n", VariableName,
VendorGuid, Status));
return Status;
}
if (Size != DataSize) {
DEBUG ((EFI_D_INFO, "SecureBootSetup: GetVariable(\"%s\", %g): expected size 0x%Lx, "
"got 0x%Lx\n", VariableName, VendorGuid, (UINT64)DataSize, (UINT64)Size));
return EFI_PROTOCOL_ERROR;
}
return EFI_SUCCESS;
}
typedef struct {
UINT8 SetupMode;
UINT8 SecureBoot;
UINT8 SecureBootEnable;
UINT8 CustomMode;
UINT8 VendorKeys;
} SETTINGS;
STATIC
EFI_STATUS
EFIAPI
GetSettings (
OUT SETTINGS *Settings,
BOOLEAN AllowMissing
)
{
EFI_STATUS Status;
ZeroMem (Settings, sizeof(SETTINGS));
Status = GetExact (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid,
&Settings->SetupMode, sizeof Settings->SetupMode, AllowMissing);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetExact (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid,
&Settings->SecureBoot, sizeof Settings->SecureBoot, AllowMissing);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetExact (EFI_SECURE_BOOT_ENABLE_NAME,
&gEfiSecureBootEnableDisableGuid, &Settings->SecureBootEnable,
sizeof Settings->SecureBootEnable, AllowMissing);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetExact (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid,
&Settings->CustomMode, sizeof Settings->CustomMode, AllowMissing);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetExact (EFI_VENDOR_KEYS_VARIABLE_NAME, &gEfiGlobalVariableGuid,
&Settings->VendorKeys, sizeof Settings->VendorKeys, AllowMissing);
return Status;
}
STATIC
VOID
EFIAPI
PrintSettings (
IN CONST SETTINGS *Settings
)
{
DEBUG ((EFI_D_INFO, "SecureBootSetup: SetupMode=%d SecureBoot=%d SecureBootEnable=%d "
"CustomMode=%d VendorKeys=%d\n", Settings->SetupMode, Settings->SecureBoot,
Settings->SecureBootEnable, Settings->CustomMode, Settings->VendorKeys));
}
/**
Install SecureBoot certificates once the VariableDriver is running.
@param[in] Event Event whose notification function is being invoked
@param[in] Context Pointer to the notification function's context
**/
VOID
EFIAPI
InstallSecureBootHook (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
VOID *Protocol;
SETTINGS Settings;
UINT8 *MicrosoftPCA = 0;
UINTN MicrosoftPCASize;
UINT8 *MicrosoftUefiCA = 0;
UINTN MicrosoftUefiCASize;
UINT8 *MicrosoftKEK = 0;
UINTN MicrosoftKEKSize;
UINT8 *SecureBootPk = 0;
UINTN SecureBootPkSize;
UINT8 *MicrosoftDbx = 0;
UINTN MicrosoftDbxSize;
Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
if (EFI_ERROR (Status)) {
return;
}
Status = GetSettings (&Settings, TRUE);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: Failed to get current settings\n"));
return;
}
if (Settings.SetupMode != SETUP_MODE) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: already in User Mode\n"));
return;
}
PrintSettings (&Settings);
if (Settings.CustomMode != CUSTOM_SECURE_BOOT_MODE) {
Settings.CustomMode = CUSTOM_SECURE_BOOT_MODE;
Status = gRT->SetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid,
(EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS),
sizeof Settings.CustomMode, &Settings.CustomMode);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: SetVariable(\"%s\", %g): %r\n", EFI_CUSTOM_MODE_NAME,
&gEfiCustomModeEnableGuid, Status));
ASSERT_EFI_ERROR (Status);
}
}
Status = GetSectionFromAnyFv(&gEfiSecureBootDb1CertGuid, EFI_SECTION_RAW, 0, (void **)&MicrosoftPCA, &MicrosoftPCASize);
ASSERT_EFI_ERROR (Status);
Status = GetSectionFromAnyFv(&gEfiSecureBootDb2CertGuid, EFI_SECTION_RAW, 0, (void **)&MicrosoftUefiCA, &MicrosoftUefiCASize);
ASSERT_EFI_ERROR (Status);
Status = GetSectionFromAnyFv(&gEfiSecureBootKekCertGuid, EFI_SECTION_RAW, 0, (void **)&MicrosoftKEK, &MicrosoftKEKSize);
ASSERT_EFI_ERROR (Status);
Status = GetSectionFromAnyFv(&gEfiSecureBootPkCertGuid, EFI_SECTION_RAW, 0, (void **)&SecureBootPk, &SecureBootPkSize);
ASSERT_EFI_ERROR (Status);
Status = GetSectionFromAnyFv(&gEfiSecureBootDbxCrlGuid, EFI_SECTION_RAW, 0, (void **)&MicrosoftDbx, &MicrosoftDbxSize);
ASSERT_EFI_ERROR (Status);
Status = gRT->SetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid,
(EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
MicrosoftDbxSize, MicrosoftDbx);
ASSERT_EFI_ERROR (Status);
Status = EnrollListOfCerts (
EFI_IMAGE_SECURITY_DATABASE,
&gEfiImageSecurityDatabaseGuid,
&gEfiCertX509Guid,
MicrosoftPCA, MicrosoftPCASize, &gEfiMicrosoftOwnerGuid,
MicrosoftUefiCA, MicrosoftUefiCASize, &gEfiMicrosoftOwnerGuid,
NULL);
ASSERT_EFI_ERROR (Status);
Status = EnrollListOfCerts (
EFI_KEY_EXCHANGE_KEY_NAME,
&gEfiGlobalVariableGuid,
&gEfiCertX509Guid,
SecureBootPk, SecureBootPkSize, &gEfiCallerIdGuid,
MicrosoftKEK, MicrosoftKEKSize, &gEfiMicrosoftOwnerGuid,
NULL);
ASSERT_EFI_ERROR (Status);
Status = EnrollListOfCerts (
EFI_PLATFORM_KEY_NAME,
&gEfiGlobalVariableGuid,
&gEfiCertX509Guid,
SecureBootPk, SecureBootPkSize, &gEfiGlobalVariableGuid,
NULL);
ASSERT_EFI_ERROR (Status);
FreePool (MicrosoftPCA);
FreePool (MicrosoftUefiCA);
FreePool (MicrosoftKEK);
FreePool (SecureBootPk);
FreePool (MicrosoftDbx);
Settings.CustomMode = STANDARD_SECURE_BOOT_MODE;
Status = gRT->SetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof Settings.CustomMode, &Settings.CustomMode);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: SetVariable(\"%s\", %g): %r\n", EFI_CUSTOM_MODE_NAME,
&gEfiCustomModeEnableGuid, Status));
ASSERT_EFI_ERROR (Status);
}
// FIXME: Force SecureBoot to ON. The AuthService will do this if authenticated variables
// are supported, which aren't as the SMM handler isn't able to verify them.
Settings.SecureBootEnable = SECURE_BOOT_ENABLE;
Status = gRT->SetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof Settings.SecureBootEnable, &Settings.SecureBootEnable);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: SetVariable(\"%s\", %g): %r\n", EFI_SECURE_BOOT_ENABLE_NAME,
&gEfiSecureBootEnableDisableGuid, Status));
ASSERT_EFI_ERROR (Status);
}
Settings.SecureBoot = SECURE_BOOT_ENABLE;
Status = gRT->SetVariable (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof Settings.SecureBoot, &Settings.SecureBoot);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: SetVariable(\"%s\", %g): %r\n", EFI_SECURE_BOOT_MODE_NAME,
&gEfiGlobalVariableGuid, Status));
ASSERT_EFI_ERROR (Status);
}
Status = GetSettings (&Settings, FALSE);
ASSERT_EFI_ERROR (Status);
//
// Final sanity check:
//
// [SetupMode]
// (read-only, standardized by UEFI)
// / \_
// 0 1, default
// / \_
// PK enrolled no PK enrolled yet,
// (this is called "User Mode") PK enrollment possible
// |
// |
// [SecureBootEnable]
// (read-write, edk2-specific, boot service only)
// / \_
// 0 1, default
// / \_
// [SecureBoot]=0 [SecureBoot]=1
// (read-only, standardized by UEFI) (read-only, standardized by UEFI)
// images are not verified images are verified, platform is
// operating in Secure Boot mode
// |
// |
// [CustomMode]
// (read-write, edk2-specific, boot service only)
// / \_
// 0, default 1
// / \_
// PK, KEK, db, dbx PK, KEK, db, dbx
// updates are verified updates are not verified
//
PrintSettings (&Settings);
if (Settings.SetupMode != 0 || Settings.SecureBoot != 1 ||
Settings.SecureBootEnable != 1 || Settings.CustomMode != 0 ||
Settings.VendorKeys != 0) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: disabled\n"));
return;
}
DEBUG ((EFI_D_INFO, "SecureBootSetup: SecureBoot enabled\n"));
}
EFI_STATUS
EFIAPI
DriverEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
VOID *TcgProtocol;
VOID *Registration;
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);
if (!EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SecureBootSetup: Started too late."
"TPM is already running!\n"));
return EFI_DEVICE_ERROR;
}
//
// Create event callback, because we need access variable on SecureBootPolicyVariable
// We should use VariableWriteArch instead of VariableArch, because Variable driver
// may update SecureBoot value based on last setting.
//
EfiCreateProtocolNotifyEvent (
&gEfiVariableWriteArchProtocolGuid,
TPL_CALLBACK,
InstallSecureBootHook,
NULL,
&Registration);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,54 @@
## @file
# This file handels SecureBoot setup.
#
# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SecureBootSetup
MODULE_UNI_FILE = SecureBootSetup.uni
FILE_GUID = 14693BD4-D114-4177-979E-37F279BAD620
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 0.1
ENTRY_POINT = DriverEntry
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
SecureBootSetup.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[Guids]
gEfiCertPkcs7Guid
gEfiCertX509Guid
gEfiCustomModeEnableGuid
gEfiGlobalVariableGuid
gEfiImageSecurityDatabaseGuid
gEfiSecureBootEnableDisableGuid
[LibraryClasses]
BaseMemoryLib
DebugLib
MemoryAllocationLib
UefiRuntimeServicesTableLib
UefiDriverEntryPoint
DxeServicesLib
UefiBootServicesTableLib
[Protocols]
gEfiTcgProtocolGuid ## CONSUMES
gEfiVariableWriteArchProtocolGuid ## NOTIFY
[Depex]
AFTER gEfiVariableWriteArchProtocolGuid

View File

@@ -0,0 +1,21 @@
// /** @file
// Provides authenticated variable service for IPF platform
//
// This module installs variable arch protocol and variable write arch protocol to provide
// four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo.
//
// Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
//
// This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "Provides authenticated variable service for IPF platform"
#string STR_MODULE_DESCRIPTION #language en-US "This module installs variable arch protocol and variable write arch protocol to provide four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo."

View File

@@ -0,0 +1,17 @@
// /** @file
// EsalVariableDxeSal Localized Strings and Content
//
// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
//
// This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
// **/
#string STR_PROPERTIES_MODULE_NAME
#language en-US
"9elements Secure Boot DXE"

View File

@@ -0,0 +1,8 @@
# PK certificate generation
* Do not save private key for re-usage.
* Generate a RSA 2048 / SHA256 x509 certificate
* Exponent should be 65537
* Microsoft certificates can be found here: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-secure-boot-key-creation-and-management-guidance
openssl req -outform DER -newkey rsa:2048 -keyout /dev/null -passout file:<(head -c 40 /dev/urandom) -x509 -days 365 -out pk.crt

Binary file not shown.

View File

@@ -101,6 +101,10 @@
DEFINE RTC_TARGET_REGISTER = 0x71 DEFINE RTC_TARGET_REGISTER = 0x71
DEFINE SERIAL_DRIVER_ENABLE = TRUE DEFINE SERIAL_DRIVER_ENABLE = TRUE
#
# Security options:
#
DEFINE SECURE_BOOT_ENABLE = FALSE
[BuildOptions] [BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
@@ -163,6 +167,10 @@
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLib/DxeHobListLib.inf DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLib/DxeHobListLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
!endif
!if $(UNIVERSAL_PAYLOAD) == TRUE !if $(UNIVERSAL_PAYLOAD) == TRUE
HobLib|UefiPayloadPkg/Library/DxeHobLib/DxeHobLib.inf HobLib|UefiPayloadPkg/Library/DxeHobLib/DxeHobLib.inf
@@ -244,7 +252,6 @@
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
@@ -255,6 +262,9 @@
SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf
!endif !endif
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
[LibraryClasses.common.SEC] [LibraryClasses.common.SEC]
HobLib|UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf HobLib|UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -272,6 +282,17 @@
!endif !endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
!else
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!endif
[LibraryClasses.common.DXE_DRIVER] [LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -284,12 +305,35 @@
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
!else
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!endif
[LibraryClasses.common.DXE_RUNTIME_DRIVER] [LibraryClasses.common.DXE_RUNTIME_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
!else
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!endif
[LibraryClasses.common.UEFI_DRIVER,LibraryClasses.common.UEFI_APPLICATION] [LibraryClasses.common.UEFI_DRIVER,LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -454,7 +498,22 @@
# #
# Components that produce the architectural protocols # Components that produce the architectural protocols
# #
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
<LibraryClasses>
!if $(SECURE_BOOT_ENABLE) == TRUE
NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
!endif
!if $(TPM_ENABLE) == TRUE
NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
!endif
}
!if $(SECURE_BOOT_ENABLE) == TRUE
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf
!endif
UefiCpuPkg/CpuDxe/CpuDxe.inf UefiCpuPkg/CpuDxe/CpuDxe.inf
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
MdeModulePkg/Logo/LogoDxe.inf MdeModulePkg/Logo/LogoDxe.inf
@@ -476,8 +535,12 @@
PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
!if $(EMU_VARIABLE_ENABLE) == TRUE !if $(EMU_VARIABLE_ENABLE) == TRUE
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
}
!endif !endif
# #
# Following are the DXE drivers # Following are the DXE drivers
# #

View File

@@ -92,6 +92,10 @@ APRIORI DXE {
INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf # After DevicePathDxe INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf # After DevicePathDxe
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf # After BlSMMStoreDxe, RuntimeDxe INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf # After BlSMMStoreDxe, RuntimeDxe
INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf # After FaultTolerantWriteDxe INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf # After FaultTolerantWriteDxe
!if $(SECURE_BOOT_ENABLE) == TRUE
INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
INF SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf # After SMBusConfigLoader and PcatRealTimeClockRuntimeDxe, before Tcg2Dxe
!endif
} }
# #
@@ -226,6 +230,35 @@ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
# #
INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
#
# Security
#
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
INF SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf
FILE FREEFORM = 85254ea7-4759-4fc4-82d4-5eed5fb0a4a0 {
SECTION RAW = UefiPayloadPkg/SecureBootEnrollDefaultKeys/keys/pk.crt
SECTION UI = "PK Default"
}
FILE FREEFORM = 6f64916e-9f7a-4c35-b952-cd041efb05a3 {
SECTION RAW = UefiPayloadPkg/SecureBootEnrollDefaultKeys/keys/kek.crt
SECTION UI = "KEK Default"
}
FILE FREEFORM = c491d352-7623-4843-accc-2791a7574421 {
SECTION RAW = UefiPayloadPkg/SecureBootEnrollDefaultKeys/keys/db-1.crt
SECTION RAW = UefiPayloadPkg/SecureBootEnrollDefaultKeys/keys/db-2.crt
SECTION UI = "DB Default"
}
FILE FREEFORM = 5740766a-718e-4dc0-9935-c36f7d3f884f {
SECTION RAW = UefiPayloadPkg/SecureBootEnrollDefaultKeys/keys/crl.bin
SECTION UI = "DBX Default"
}
!endif
# #
# Shell # Shell
# #
@@ -346,3 +379,16 @@ SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = $(BLOCK_SIZE)
FILE RAW = $(NAMED_GUID) { FILE RAW = $(NAMED_GUID) {
RAW RAW |.raw RAW RAW |.raw
} }
[RULE.COMMON.USER_DEFINED]
FILE FREEFORM = $(NAMED_GUID) {
RAW BIN |.crt
RAW BIN |.bin
}
[RULE.COMMON.USER_DEFINED.BINARY]
FILE FREEFORM = $(NAMED_GUID) {
RAW BIN |.crt
RAW BIN |.bin
UI STRING="$(MODULE_NAME)" Optional
}