Privacy Tools Guide

Linux Secure Boot Setup with Custom Keys for Preventing Firmware Level Tampering

Replace manufacturer Secure Boot keys with your own custom keys to gain complete authority over boot trust chains. Generate a three-tier key hierarchy (Platform Key, Key Exchange Key, and Signature Database key) using OpenSSL, enroll them in UEFI firmware, then sign all bootloaders and kernels. This approach prevents firmware-level tampering and ensures only your signed code executes at boot time.

Automate kernel signing after updates using kernel hooks, and create encrypted backups of your keys for recovery purposes. This guide includes step-by-step enrollment procedures for different firmware types and troubleshooting for common boot failures.

Why Custom Keys Rather Than Default Secure Boot

Most Linux distributions ship with Secure Boot support using keys from Microsoft and the distribution’s own key exchange key. This works, but it has a critical limitation: your firmware trusts Microsoft’s keys, which means any bootloader signed by Microsoft — including those used in certain well-known malware campaigns — can boot on your system.

By replacing manufacturer keys with your own, you close this trust chain to any party other than yourself. The firmware will only boot code you have personally signed. This protection is particularly valuable in environments where physical access to your machine is possible — laptops carried through customs, machines in shared offices, or hardware used in security research.

Custom keys also allow you to enforce Measured Boot more meaningfully. When combined with TPM-based disk encryption, a properly configured custom Secure Boot setup ensures that the TPM will only release disk encryption keys when the exact signed boot chain is present, detecting any firmware or bootloader tampering before the OS loads.

Key Hierarchy: Understanding the Three-Tier Structure

The Secure Boot key hierarchy has a specific purpose for each tier:

Key Role Who Can Modify It
Platform Key (PK) Root of trust; controls who can modify KEK Only the PK itself
Key Exchange Key (KEK) Controls who can modify the db and dbx PK
Signature Database (db) Contains keys that may sign boot executables KEK
Forbidden Signatures (dbx) Revoked keys and hashes KEK

The dbx (forbidden signatures database) is as important as the db. It allows you to revoke specific executables or keys even if they were previously trusted. Keep it updated — the Linux Vendor Firmware Service (LVFS) publishes dbx updates to revoke known-compromised bootloaders.

Prerequisites

Before beginning, gather the following:

Install the required tools on your current distribution:

# Debian/Ubuntu
sudo apt install sbsigntool efitools

# Fedora/RHEL
sudo dnf install sbsigntool efitools

# Arch Linux
sudo pacman -S sbsigntool efitools

Generating Your Custom Keys

Secure Boot uses RSA key pairs — public keys get enrolled in your firmware, while private keys sign your boot components. Generate a 4096-bit key set using OpenSSL for stronger security; 2048-bit is the minimum acceptable, but 4096-bit is preferred for long-lived keys:

# Create a directory for keys with restricted permissions
mkdir -p ~/secureboot/keys
chmod 700 ~/secureboot/keys
cd ~/secureboot/keys

# Generate the Platform Key (PK)
openssl genrsa -out PK.key 4096
openssl req -new -x509 -key PK.key -out PK.crt -days 3650 \
    -subj "/CN=Platform Key/"

# Generate the Key Exchange Key (KEK)
openssl genrsa -out KEK.key 4096
openssl req -new -x509 -key KEK.key -out KEK.crt -days 3650 \
    -subj "/CN=Key Exchange Key/"

# Generate the Signature Database key (db)
openssl genrsa -out db.key 4096
openssl req -new -x509 -key db.key -out db.crt -days 3650 \
    -subj "/CN=Signature Database Key/"

The Platform Key serves as the root of trust — only this key can modify other keys in Secure Boot. The Key Exchange Key controls what keys can sign executables in the permitted database. The db key signs your actual boot components.

Protect your private keys with appropriate filesystem permissions:

chmod 600 *.key
chmod 644 *.crt

Enrolling Keys in UEFI Firmware

This step requires accessing your system’s UEFI setup utility. The exact key varies by manufacturer—common options include F2, F10, Delete, or Esc. Look for the Secure Boot configuration section.

The enrollment process typically involves converting certificates to EFI format:

# Convert certificates to EFI signature list format
cert-to-efi-sig-list -g $(uuidgen) PK.crt PK.esl
cert-to-efi-sig-list -g $(uuidgen) KEK.crt KEK.esl
cert-to-efi-sig-list -g $(uuidgen) db.crt db.esl

# Sign the KEK and db entries with the PK
sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.signed
sign-efi-sig-list -k PK.key -c PK.crt KEK KEK.esl KEK.signed
sign-efi-sig-list -k PK.key -c PK.crt db db.esl db.signed

The exact enrollment method depends on your firmware. Some systems provide a “Key Management” interface where you can enroll .esl or .cer files directly. Others require using efi-updatevar from a bootable environment:

# From a live USB with Secure Boot disabled
sudo efi-updatevar -f db.esl db
sudo efi-updatevar -f KEK.esl KEK
sudo efi-updatevar -f PK.esl PK

For systems with limited firmware options, tools like keytool from the efitools package provide a graphical interface for key enrollment.

Important: Always enroll keys in order — db first, then KEK, then PK last. Enrolling the PK activates Secure Boot enforcement. If you enroll the PK before the db and KEK, you may lock yourself out of being able to add additional keys without first disabling Secure Boot and clearing all keys.

Signing Boot Components

With keys enrolled, you must sign every component your system boots. This includes the bootloader, kernel, and any intermediate loaders.

Sign your GRUB bootloader:

# Sign the GRUB binary
sbsign --key ~/secureboot/keys/db.key --cert ~/secureboot/keys/db.crt \
    --output /boot/efi/EFI/*/grubx64.efi /boot/efi/EFI/*/grubx64.efi

For systems using systemd-boot, sign the bootloader similarly:

sbsign --key ~/secureboot/keys/db.key --cert ~/secureboot/keys/db.crt \
    --output /boot/efi/EFI/systemd/systemd-bootx64.efi \
    /boot/efi/EFI/systemd/systemd-bootx64.efi

If you use a unified kernel image (UKI), sign the entire kernel bundle:

sbsign --key ~/secureboot/keys/db.key --cert ~/secureboot/keys/db.crt \
    --output /boot/vmlinuz-$(uname -r).signed \
    /boot/vmlinuz-$(uname -r)

Configuring Automatic Signing

Rebuilding and manually signing after every kernel update quickly becomes tedious. Automate this process with a kernel hook:

sudo tee /etc/kernel/postinst.d/secure-boot-sign > /dev/null << 'EOF'
#!/bin/bash
KERNEL_VERSION="$1"
BOOT_DIR="$2"

sbsign --key /home/*/secureboot/keys/db.key \
       --cert /home/*/secureboot/keys/db.crt \
       --output "${BOOT_DIR}/vmlinuz-${KERNEL_VERSION}.signed" \
       "${BOOT_DIR}/vmlinuz-${KERNEL_VERSION}" 2>/dev/null || true
EOF

sudo chmod +x /etc/kernel/postinst.d/secure-boot-sign

Adjust paths according to your setup. This hook triggers after kernel installations, automatically signing new kernels.

Store your private keys in a location accessible only to root rather than in a user home directory. On systems where the key directory resides under /etc/secureboot/, update the path in the hook accordingly:

sudo mkdir -p /etc/secureboot/keys
sudo chmod 700 /etc/secureboot/keys
sudo mv ~/secureboot/keys/*.key /etc/secureboot/keys/
sudo mv ~/secureboot/keys/*.crt /etc/secureboot/keys/
sudo chmod 600 /etc/secureboot/keys/*.key

Troubleshooting Common Boot Failures

Custom Secure Boot configurations can fail silently or with cryptic error messages. The most common issues:

Signature verification failed: The kernel or bootloader was updated without re-signing. Boot from a live USB, mount your EFI partition, and re-sign the updated binary using your db key.

Bootloader not found after key enrollment: Some firmware implementations require a signed EFI application to be designated as the boot entry. Use efibootmgr to add an entry pointing to your signed bootloader after enrollment.

Firmware reverts to Setup Mode: A small number of consumer laptops have buggy firmware that drops back to Setup Mode after reboot. In this case, you may need to re-enroll keys each time. Consider whether your hardware actually supports stable Secure Boot customization before investing more time.

Module loading fails: Kernel modules must also be signed when Secure Boot is active. Use kmodsign to sign out-of-tree modules:

kmodsign sha256 /etc/secureboot/keys/db.key /etc/secureboot/keys/db.crt \
    /path/to/module.ko

Verification and Testing

After completing setup, verify your configuration:

# Check if Secure Boot is enabled
mokutil --sb-state

# List enrolled keys
mokutil --list-enrolled

# Verify a signed binary
sbverify --cert ~/secureboot/keys/db.crt /boot/efi/EFI/*/grubx64.efi

Successful verification produces output indicating the signature is valid.

Test the setup by rebooting into your firmware settings and examining the Secure Boot status. Your custom keys should appear in the key management interface.

Recovery Planning

Custom Secure Boot configurations carry a risk—losing access to your keys or making enrollment mistakes can render your system unbootable. Create backup media before proceeding:

# Export keys to encrypted archive
tar czf secureboot-keys-backup.tar.gz -C ~/secureboot keys/
gpg -o secureboot-keys-backup.tar.gz.gpg --symmetric secureboot-keys-backup.tar.gz

Store this backup securely, preferably offline on a USB drive kept in a physically secure location. Additionally, note your firmware’s “Clear Secure Boot Keys” or “Restore Factory Keys” option — this returns to manufacturer defaults and allows you to boot unsigned media, giving you a path to re-enroll your keys if something goes wrong.

Document the GUID used when creating your EFI signature lists. If you need to re-enroll from scratch, you should use the same GUID to ensure key continuity across reinstallation.

Built by theluckystrike — More at zovo.one