-
Notifications
You must be signed in to change notification settings - Fork 46
Secure Boot Workflow
STATUS: DRAFT - This document may not cover every scenario. Open an issue for clarifications and questions
β οΈ 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. Particulary those who sell to governments.
- Firmware failures may be unrecoverable and may result in a unrecoverable machine. Please exercise caution when servicing Secure Boot.
- For systems that use Bitlocker, servicing secure boot will alter PCR[7] measurements and will result in a bitlockered machine going through bitlocker recovery. It is recommended that bitlocker be suspended during servicing.
- For systems that use VSM, servicing secure boot may result in lost data due to changes in PCR[7] Measurements.
- 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)
- If you have a graphics card you likely need the third party CA
This guide provides step-by-step instructions for managing Secure Boot keys, entering Setup mode, and performing end-to-end Secure Boot configuration based on real-world implementations and community discussions.
π I'm not familiar with the Linux commands but everything discussed also applies to Linux.
It's recommended letting the OS service this. Windows does this natively however you may need to install FWUPD if you are on Linux.
- Understanding Secure Boot Key Hierarchy
- 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
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.
- 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.
# Check current Secure Boot status
Get-SecureBootPolicyThe simplest approach is to use the pre-built keys from the secureboot_objects repository. Specifically for Setup mode the easiest method is to use the release does not end in "-signed" (those are used in servicing).
Unfortunately at this time this repo does not provide a self-signed PK. Which means for systems that enforce a requirement for the PK to be self signed the reader will be required to create one for themselves in a safe manner. This will be discussed in Creating Authenticated Variables For Custom Keys,
Select a release that matches your architecture for my system that's https://github.com/microsoft/secureboot_objects/releases/download/v1.5.1/edk2-x64-secureboot-binaries.zip.
Now you must select a configuration that works for you.
Directory: C:\Users\User\Downloads\edk2-x64-secureboot-binaries
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 7/11/2025 1:20 PM LegacyFirmwareDefaults
d---- 7/11/2025 1:20 PM MicrosoftAndOptionRoms
d---- 7/11/2025 1:20 PM MicrosoftAndThirdParty
d---- 7/11/2025 1:20 PM MicrosoftOnly
-a--- 7/11/2025 1:20 PM 6 version
For systems such as laptops that only need to boot Windows, the MicrosoftOnly configuration may be sufficient.
π This configuration uses the 2023 Windows Production CA and will not allow booting from media signed with the 2011 Windows CA. You must use 2023 or newer Windows boot media.
πThe LegacyFirmwareDefaults option trusts both 2011 and 2023 CAs but is considered less secure.
# Download and run the installation script
PS C:\> .\scripts\windows\InstallSecureBootKeys.ps1 Templates\MicrosoftOnly\Firmware
# Or if you are using a self signed PK
PS C:\> .\scripts\windows\InstallSecureBootKeys.ps1 Templates\MicrosoftOnly\Firmware <path\to\signature.bin.p7>Look at the the files that end in *.json to understand what will be installed. Example: DefaultDb.json. They should match the template they were built from.
You can verify these with tools like powershell tools Uefiv2
The initial time only matters for SET payloads. For APPEND the time is ignored.
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.
- Windows SDK with SignTool (Or you can use the python tool)
- HSM or some secure storage for valid code signing certificates
- Administrative privileges
Create a new TOML file that uses your certificates. For testing you can use CreateTestCerts.ps1 but DO NOT USE THESE IN PRODUCTION.
Follow the instructions in Key Installation Methods to get them installed.
When using your own certificates, you gain the ability to sign custom boot media and control what is trusted by Secure Boot. However, this also means you are solely responsible for managing and revoking those certificates if they become compromised or are no longer needed. Proper key lifecycle managementβincluding timely revocation and updatesβis essential to maintain system security.
π That all of these instructions can be used for each layer in the SecureBoot Hierarchy. Just note that PK updates must be self signed, KEK updates must be PK signed, and DB / DBX must be KEK signed.
# 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 .
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.
- 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.