-
Notifications
You must be signed in to change notification settings - Fork 52
Secure Boot Workflow
β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.
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.
- Understanding Secure Boot Key Hierarchy
- Getting Certificates
- Entering Setup Mode
- Key Installation Methods
- Signing and Installing Custom Keys
- DBX Updates and Management
- Troubleshooting Common Issues
- Additional Resources
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
π 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.
- Boot into UEFI firmware setup (usually F2, F12, or Del during boot)
- Navigate to Security settings
- Find Secure Boot configuration
- Clear Platform Key (PK) to enter Setup Mode (Ex: On Surface this is Secure Boot Disabled)
- Save changes and reboot
The system will now boot in setup mode with secure boot disabled.
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 aSEToperation for initial key enrollment. IfGet-SecureBootUEFI -Name PKreturns 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.
π 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.
The powershell script CreateTestCerts.ps1 can be used to generate a complete set of test keys for Secure Boot development and testing.
- Windows PowerShell (Administrator privileges required)
- Access to the secureboot_objects repository
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
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"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.
π On System: Development Machine
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
templatesto the end user with descriptive explanations about what they enable and select a "secure-by-design" default that the end user may change.
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.tomlNow 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.crtNext 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.
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.tomlNow 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.
π 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.
# 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# 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 -AppendWriteOn 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.jsonOn 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.binCongrats 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 -AppendWriteAlternatively, 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
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>.efiReplace <password> with your certificate password and <Path\to\Efi\App>.efi with the path to your EFI application.
To remove an existing signature from an EFI binary:
& 'signtool.exe' sign remove /s <Path\to\Efi\App>.efiThis can be useful if you need to re-sign the binary or distribute it unsigned.
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.
- edk2-pytool-library: Python tools for UEFI development
- SplitDbxContent PowerShell Module: Utility for splitting authenticated variables
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.