Skip to content

Secure Boot Workflow

Doug Flick edited this page Dec 8, 2025 · 6 revisions

Secure Boot Workflow: Setup Mode, Key Installation, and Management

❗DOCUMENT STATUS: DRAFT // IN PROGRESS

⚠️ IMPORTANT

The information and opinions contained in this document are provided "as is" and without any warranties or guarantees. This is considered an advanced guide that should only be followed by professionals capable of recovering their system such as an Original Equipment Manufacturer (OEM).

Risks are as follows:

  • Some implementations of Secure Boot are not well tested outside of what the manufacturer ships
    • The hope with this guide is that firmware vendors may use these tools to test Secure Boot and stress test it to provide better quality firmware.
    • Many (but not all) firmware provided by the largest OEMs allows for "expert key management".
    • Inability to modify Secure Boot keys is a "Platform" decision made by an OEM.
  • Firmware failures due to interacting with the variable store may cause a platform to become unrecoverable Please exercise caution when servicing Secure Boot.
  • For technologies that depend on a TPM such as disk encryption technology (e.g Bitlocker), or credential storing technologies (e.g VSM), servicing secure boot will alter PCR[7] and may impact those technologies.
  • Certificates authorize certain software to run. Without those certificates you may be unable to boot.
    • Windows CA: Authorizes Windows
    • Third Party CA: Authorizes Linux and Third party Software (Such as your Graphics Card)
    • Option ROM CA (NEW): Authorizes 2023+ Option Roms.
      • If you have a graphics card you likely need the third party CA
    • For these reasons modifying these should only be done by an expert.

This guide is intended for firmware engineers or advance users and provide step-by-step instructions for managing Secure Boot keys, entering Setup mode, and performing end-to-end Secure Boot workflows that a platform will normally see in its lifetime.

This document will use "Test Certificates" for examples.

Real platforms should ONLY USE PRODUCTION KEYS STORED SECURELY. That is an exercise left up to the reader.

System Context Notation

This guide distinguishes between operations performed on different systems using the following notation:

πŸ”Ž On System: Device Under Test

Indicates instructions to be executed on the target device where Secure Boot is being configured or tested.

πŸ”Ž On System: Development Machine

Indicates instructions to be executed on the development workstation where certificates are generated and signed.

While both sets of operations can be performed on a single system, this guide assumes a typical firmware development workflow where these systems are separate.

Table of Contents

  1. Understanding Secure Boot Key Hierarchy
  2. Getting Certificates
  3. Entering Setup Mode
  4. Key Installation Methods
  5. Signing and Installing Custom Keys
  6. DBX Updates and Management
  7. Troubleshooting Common Issues
  8. Additional Resources

Understanding Secure Boot Key Hierarchy

Secure Boot uses a hierarchical key structure:

  • PK (Platform Key): Root of trust, typically one key per platform
  • KEK (Key Exchange Key): Used to sign database updates
  • DB (Signature Database): Contains authorized signatures
  • DBX (Forbidden Signature Database): Contains revoked/blocked signatures
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚                         β”‚
              β”‚    Platform Key (PK)    β”‚    Acts as the trust anchor and is a single X.509 certificate
              β”‚                         β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚                         β”œβ”€β”€β”
              β”‚ Key Exchange Key (KEK)  β”‚  β”‚
              β”‚                         β”‚  β”‚ Multiple X.509 certificates that authorize changes to the signature databases
              β””β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                 β”‚                         β”‚
                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚                                   β”‚
          β”‚                                   β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    β”‚        β”‚                             β”œβ”€β”€β”€β”
β”‚    Database (DB)   β”œβ”€β”€β”€β”    β”‚   Forbidden Database (DBX)  β”‚   β”‚
β”‚                    β”‚   β”‚    β”‚                             β”‚   β”‚
β””β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚    β””β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚ Contains signatures of software that should not be truste
   β”‚    Certificates     β”‚        β”‚      Certificates           β”‚
   β”‚                     β”‚        β”‚                             β”‚
   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
   β”‚                     β”‚        β”‚                             β”‚
   β”‚    Hashes           β”‚        β”‚      Hashes                 β”‚
   β”‚                     β”‚        β”‚                             β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Contains Hashes or Certificates of trusted software

Entering Setup Mode

πŸ”Ž On System: Device Under Test

Setup Mode allows you to enroll custom keys and modify the Secure Boot configuration. The methods to enter setup mode are generally custom to the OEM and not always well documented. Consult your OEM for more information on entering Setup Mode.

This document will generalize how enter setup mode however real steps may vary depending on your platform. Usually the requirement is that platforms secure boot variables are cleared, however some firmware has additional requirements.

UEFI Firmware Setup

  1. Boot into UEFI firmware setup (usually F2, F12, or Del during boot)
  2. Navigate to Security settings
  3. Find Secure Boot configuration
  4. Clear Platform Key (PK) to enter Setup Mode (Ex: On Surface this is Secure Boot Disabled)
  5. Save changes and reboot

The system will now boot in setup mode with secure boot disabled.

Verify Setup Mode

After entering Setup Mode, verify the system state in an administrative PowerShell session:

# Check current Secure Boot status
Get-SecureBootPolicy

# Verify the PK variable is undefined
Get-SecureBootUEFI -Name PK

⚠️ IMPORTANT: If the PK variable is still defined after disabling Secure Boot, subsequent key installation steps will fail. The PK variable must be undefined (cleared) to perform a SET operation for initial key enrollment. If Get-SecureBootUEFI -Name PK returns data, return to UEFI firmware setup and ensure the Platform Key is completely cleared, not just Secure Boot disabled.

⚠️ UEFI SPECIFICATION COMPLIANCE: Per UEFI Specification 2.10 Section 32 (Secure Boot and Driver Signing), when entering Setup Mode the Platform Key variable must be cleared (undefined). If your firmware still reports a defined PK variable after entering Setup Mode, the firmware is in violation of the UEFI specification. This non-compliant behavior prevents proper initial key enrollment and may indicate other Secure Boot implementation issues.

Getting Certificates

πŸ”Ž On System: Development Machine

As mentioned multiple times, real platforms should use production keys. This section will show how to get test keys and examples below will use them. Please substitute the instructions with real keys for production use.

⚠️ WARNING: The test certificates generated in this section are NOT SECURE and should NEVER be used in production systems. Production systems must use certificates generated and stored in Hardware Security Modules (HSMs) or other secure key management systems.

Generating Test Certificates

The powershell script CreateTestCerts.ps1 can be used to generate a complete set of test keys for Secure Boot development and testing.

Prerequisites

  • Windows PowerShell (Administrator privileges required)
  • Access to the secureboot_objects repository

Step 1: Create Test Certificates

Run the script to generate a complete set of test certificates. The script uses the $Env:TestSecureBootDefaults environment variable to determine where to place the generated certificates. If not set, it defaults to SecureBootDefaults in the current directory.

# Navigate to the repository root
cd C:\git\microsoft\secureboot_objects

mkdir test-certs

PS C:\git\Microsoft\secureboot_objects> $Env:TestSecureBootDefaults = "C:\git\microsoft\secureboot_objects\test-certs"
PS C:\git\Microsoft\secureboot_objects> .\scripts\windows\CreateTestCerts.ps1 -Action create
WARNING: ================================================================================
WARNING: This script is for validation and testing purposes only.
DO NOT use the generated certificates or keys in production environments.
Keys are stored in software and are not protected by a Hardware Security Module (HSM).
For production, always use an HSM or other secure key storage solution.
================================================================================

Next the script will ask for a password. Again since these are test keys its important you do not commit them, do not save them, do not share them. When you're done use -Action delete. These are for local testing only. The script will use the same password for all the files, you should not do this in production.

Enter a password to protect the certificate private keys:

Note: The exported files will have the following extensions and this is what they mean:

  • .crt = public certificate only (Used in UEFI firmware for PK, KEK, DB)
  • .p7b = certificate chain, no private keys (Generally not used in UEFI)
  • .pfx = certificate(s) + private key(s), password protected (Used by the authority to sign PE Images, and Secure Boot Variable updates)

Ultimately you will end up with the following files:

  • PK/TestPK.crt
  • KEK/TestKEK.crt
  • DB/TestDB.crt
  • SigningCerts/TestPK.p7b
  • SigningCerts/TestPK.pfx
  • SigningCerts/TestKEK.p7b
  • SigningCerts/TestKEK.pfx
  • SigningCerts/TestDB.p7b
  • SigningCerts/TestDB.pfx

Step 2: Verify Generated Certificates

You can verify the generated certificates like so:

# View certificate details
Get-PfxCertificate -FilePath .\test-certs\PK\TestPK.crt
# Thumbprint                                Subject              EnhancedKeyUsageList
# ----------                                -------              --------------------
# F7A7FB1BDCE5881DE21B25047715F5BCB7306577  CN="TestPK OU=TESTI…

# View only the CN (Common Name)
$(Get-PfxCertificate -FilePath .\test-certs\PK\TestPK.crt).subject
# CN="TestPK OU=TESTING ONLY - DO NOT USE FOR PRODUCTION"

Next Steps

Some platforms allow you to directly install your keys through "Expert Key Management" in the UEFI front page (sometimes referred to as a BIOS menu). This guide will not use those feature.

Now that the certificates are created, this guide will move on to installation.

Secure Boot Setup

πŸ”Ž On System: Development Machine

Selecting a Configuration Template

For this guide, we will base the test configuration off of most compatible configuration template to ensure the broadest compatibility with various boot media and operating systems. This allows for easier testing and validation of your Secure Boot implementation. However, production platforms must conform to Microsoft's official requirements:

πŸ“ Production Requirement: Production Windows devices must follow the Windows Secure Boot Key Creation and Management Guidance, specifically Section 1.6 which details the UEFI Secure Boot configuration requirements for Windows 11 version 25H2 devices.

Platforms are encouraged to provide multiple templates to the end user with descriptive explanations about what they enable and select a "secure-by-design" default that the end user may change.

Setting up the Testing Configuration toml

Start by copying the Most Compatible configuration so we can begin modifying it for testing.

PS C:\git\microsoft\secureboot_objects> cp .\Templates\MostCompatible.toml .\Templates\TestConfiguration.toml

Now in TestConfiguration.toml replace the platform key with the TestPk.crt that was created before. Start by getting the SHA1 of Get-FileHash -Algorithm [SHA1 <file>

PS C:\git\microsoft\secureboot_objects> Get-FileHash -Algorithm SHA1 .\test-certs\PK\TestPK.crt

Algorithm       Hash                                                                   Path
---------       ----                                                                   ----
SHA1            F7A7FB1BDCE5881DE21B25047715F5BCB7306577                               C:\git\microsoft\secureboot_objects\test-certs\PK\TestPK.crt

Next generate a random guid. This signature_owner should be unique to your certificates. Microsoft certificates should use "77fa9abd-0359-4d32-bd60-28f4e78f784b" however production CAs should use a unique guid that is specific to the OEM.

The random guid that will be used for the rest of this document will be "cf108b79-7848-431c-8118-f5e3631bb527".

Now edit the TestConfiguration.toml so that it uses the platform key certificate and signature owner you generated.

[PK]
help = "Contains the Microsoft PK to enable signature database updates and binary execution."

[[PK.files]]
- path = "PreSignedObjects/PK/Certificate/WindowsOEMDevicesPK.der"
+ test-certs/PK/TestPK.crt
- sha1 = 0x3D8660C0CB2D57B189C3D7995572A552F75E48B5
+ sha1 = 0xF7A7FB1BDCE5881DE21B25047715F5BCB7306577
- signature_owner = "77fa9abd-0359-4d32-bd60-28f4e78f784b"
+ signature_owner = "cf108b79-7848-431c-8118-f5e3631bb527"
description = "Platform Key (owner) who may authorize changes to the KEK Variable"

You may do additional configuration to your platform configuration files as we will do in later steps.

Generate the EFI_SIGNATURE_LIST

Now generate the EFI_SIGNATURE_LISTs that will be used in later steps.

PS C:\git\microsoft\secureboot_objects> python .\scripts\secure_boot_default_keys.py --keystore .\Templates\TestConfiguration.toml

Now this will generate a lot of output but the key lines we care about:

INFO: Building default keys for secure boot.
INFO: Converting test-certs\PK\TestPK.crt to signature list.
INFO: Appended test-certs\PK\TestPK.crt to signature database for variable PK.
...
INFO: Default keys created successfully. See C:\git\microsoft\secureboot_objects\Artifacts for details.

Now find the output for the architecture you care about. This guide will use x64 - substitute the architecture with your Device Under Test architecture where necessary.

Artifacts\X64\TestConfiguration\Firmware

Now the Device Under Test is ready for setup. Copy over these files.

πŸ“There are two folders produced:

  • Firmware
    • used by Firmware or Powershell
  • Imaging
    • Used if you call the C API SetFirmwareEnvironmentVariable(..) under certain circumstances)

Read the readme for each for more information.

Windows Installation

πŸ”Ž On System: Device Under Test

If your firmware supports it, Set-SecureBootUEFI supports appending an "empty signature list" that allows the firmware it. This is currently limited to firmware based on Project MU.

# Download and run the installation script
PS C:\> .\scripts\windows\InstallSecureBootKeys.ps1 Templates\TestConfiguration\Firmware

# Or if you are using / need a self signed PK
# PS C:\> .\scripts\windows\InstallSecureBootKeys.ps1 Templates\TestConfiguration\Firmware <path\to\signature.bin.p7>

If your system requires a signed PK in order to be set See Self Signed PK Generation

You can verify the script worked with tools like powershell tools Uefiv2

The initial time only matters for SET payloads. For APPEND the time is ignored.

The script uses the date 2015-08-28T00:00:00Z. There is nothing particularly special about this date but is important to keep track of for SET Payloads. For workflows where APPEND is used, the time validated for signature validation but is ignored when actually set allowing multiple secure boot servicers to potentially service the firmware.


🚧 REWRITE UNDERWAY

Exanmple Servicing Secure Boot

Method 1: Using PowerShell

# Create unsigned binary for signing
Format-SecureBootUEFI `
  -Name DBX `
  -Algorithm SHA256 `
  -SignatureOwner 6841bdb0-b2af-4079-918f-fe458325d5cd `
  -Hash "2944DA098861619E21B522A642235BB2EC189FF20EF96E100B2FFDD9A39C3416" `
  -SignableFilePath out\to_be_signed.bin `
  -ContentFilePath out\dbx.bin `
  -Time 2010-03-06T19:17:21Z `
  -AppendWrite

# Sign the to-be-signed content
signtool sign /fd sha256 /p7 .\ /p7co 1.2.840.113549.1.7.1 /p7ce DetachedSignedData /a /f "kek.pfx" out\to_be_signed.bin

# Install the signed update
Set-SecureBootUEFI -Name DBX -Time 2010-03-06T19:17:21Z -ContentFilePath dbx.bin -SignedFilePath to_be_signed.bin.p7 -AppendWrite

Method 2: Using Python Authentication Variable Tool

# Create signed authenticated variable
python scripts/auth_var_tool.py sign dbx d719b2cb-3d3a-4596-a3bc-dad00e67656f "NV,BS,RT,AT,AP" DefaultDb.bin kek.pfx --output-dir .
python scripts/auth_var_tool.py sign dbx d719b2cb-3d3a-4596-a3bc-dad00e67656f "NV,BS,RT,AT,AP" DefaultDb.bin kek.pfx --output-dir .

PS C:\> SplitDbxContent.ps1 .\DefaultDb.authvar.bin
Successfully created output file .\signature.p7
Successfully created output file .\content.bin

PS C:\> Set-SecureBootUEFI -Name dbx -ContentFilePath .\content.bin -SignedFilePath .\signature.p7 -Time 2010-03-06T19:17:21Z -AppendWrite

Method 3: Using Python Authentication Variable Tool and signing with on external machine

On your first machine create the contents and signable file:

PS C:> python scripts/auth_var_tool.py format DBX d719b2cb-3d3a-4596-a3bc-dad00e67656f "NV,BS,RT,AT,AP" DefaultDb.bin
INFO:root:Formatting variable 'DBX' for external signing.
INFO:root:Using current timestamp: 2025-07-11T21:51:56.192155+00:00
INFO:root:Signable data for DBX with GUID: d719b2cb-3d3a-4596-a3bc-dad00e67656f
INFO:root:Signable data saved to: ./DBX.signable.bin
INFO:root:Receipt saved to: ./DBX.receipt.json
INFO:root:To attach a signature later, use: --receipt-file ./DBX.receipt.json

On your secure certificate storage machine:

# Secure Method
& 'signtool.exe' sign /fd sha256 /p7 .\ /p7co 1.2.840.113549.1.7.1 /p7ce DetachedSignedData /a /f .\DBX.signable.bin <sha1 of cert in store>
Successfully signed: .\DBX.signable.bin

# Less Secure
& 'signtool.exe' sign /p password /fd sha256 /p7 .\ /p7co 1.2.840.113549.1.7.1 /p7ce DetachedSignedData /a /f KEK.pfx .\DBX.signable.bin
Done Adding Additional Store
Successfully signed: .\DBX.signable.bin

Congrats you now have a signature called .\DBX.signable.bin.p7

Now back on machine you're servicing:

PS C:\> Set-SecureBootUEFI -Name dbx -ContentFilePath DefaultDb.bin -SignedFilePath .\DBX.signable.bin.p7 -Time 2010-03-06T19:17:21Z -AppendWrite

Alternatively, this powershell command is actually doing a little bit of magic. Where it's rebuilding the authenticated variable. If you're going through a C API like SetFirmwareVariableExW in Windows or in firmware you can use the below command to build the authenticated variable:

 PS C:\> python .\auth_var_tool.py sign --receipt-file .\DBX.receipt.json --signature-file .\DBX.signable.bin.p7

⚠️ The C API is not Bit Locker aware and will cause Bit Locker recovery to trigger

Signing an EFI Binary

If you have your own DB (signature database) certificate, you can sign an EFI binary using signtool:

& 'signtool.exe' sign /fd sha256 /f DB.pfx /p <password> <Path\to\Efi\App>.efi

Replace <password> with your certificate password and <Path\to\Efi\App>.efi with the path to your EFI application.

Removing a Signature from an EFI Binary

To remove an existing signature from an EFI binary:

& 'signtool.exe' sign remove /s <Path\to\Efi\App>.efi

This can be useful if you need to re-sign the binary or distribute it unsigned.

Manually Updating Secure Boot (DBX) (Windows)

You can manually update the contents for your system using the official payloads like so:

PS C:\> SplitDbxContent.ps1 .\DBXUpdate.bin
Successfully created output file .\signature.p7
Successfully created output file .\content.bin

PS C:\> Set-SecureBootUEFI -Name dbx -ContentFilePath .\content.bin -SignedFilePath .\signature.p7 -Time 2010-03-06T19:17:21Z -AppendWrite

πŸ“ Set-SecureBootUEFIis BitLocker aware and will perform the appropriate BitLocker resealing to avoid a machine going into BitLocker recovery. For manual servicing this is the preferred method.

⚠️ This is writing to your machines flash space, if it overfills its possible the machine is unrecoverable. OEMs should test to understand how much flash space they have reserved and ensure that a machine can recover such a situation.

Additional Resources

Official Documentation

Security Guidelines

Tools and Libraries

Key Signing Process Overview

The secure boot signing process involves several components:

EFI_VARIABLE_AUTHENTICATION_2 Structure:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   EFI_TIME  β”‚ WIN_CERTIFICATE β”‚  SIGNATURE  β”‚       DATA       β”‚
β”‚ Fixed Size  β”‚ Variable Size   β”‚Variable Sizeβ”‚  Variable Size   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Where:
- SIGNATURE = ASN.1 SignedData or ContentInfo object
- DATA = EFI_SIGNATURE_LIST containing the actual key/hash data

The signature is calculated over the concatenation of:

  • Variable name (UTF-16LE encoded)
  • Variable GUID (little-endian bytes)
  • Variable attributes
  • Timestamp
  • Payload data

This comprehensive workflow enables secure management of UEFI Secure Boot while maintaining security best practices.

Clone this wiki locally