8/12/2018

Enable Secure Boot with Your own Keys

Using Secure Boot with Linux is quite a challenge because most mainboards only have Microsoft's own KEK and DB keys installed. There are possibilities like shim, but that's quite cumbersome and it won't work for macOS (if you are running a "Hackintosh"). Creating your own Secure Boot keys is the most elegant way and will work for Windows, Linux and macOS.

There is a great tutorial about signing EFI binaries using sbsigntools by Rod Smith, however this won't work with Apple's binaries. pesign from Red Hat is a better and more robust alternative in my opinion. It also brings its own keygen for creating compatible SSL keys and uses Mozilla's NSS to store them in a secure database. Neat!


I won't describe the details about Secure Boot and what all those keys do here, please refer to Rod Smith's website if you want to learn more about that.

  • Generating the keys


The self-signed Platform Key comes first:
# efikeygen -d /etc/pki/pesign -C -S -n "Secure Boot PK" \
-c "CN=Secure Boot PK"

The Key Exchange Key is signed by PK:
# efikeygen -d /etc/pki/pesign --signer="Secure Boot PK" \
-n "Secure Boot KEK" -c "CN=Secure Boot KEK"

And finally the Database Key is signed by KEK:
# efikeygen -d /etc/pki/pesign --signer="Secure Boot KEK" \
-n "Secure Boot DB" -c "CN=Secure Boot DB"


Those keys need to be exported for later deployment in UEFI:
# certutil -d /etc/pki/pesign -L -n "Secure Boot PK" -r >~/PK.cer
# certutil -d /etc/pki/pesign -L -n "Secure Boot KEK" -r >~/KEK.cer
# certutil -d /etc/pki/pesign -L -n "Secure Boot DB" -r >~/DB.cer


It's a good idea to do a backup and store them in a safe place. Chose a strong password.
# pk12util -d /etc/pki/pesign -n "Secure Boot PK" \
-o ~/SecureBootPK.p12
# pk12util -d /etc/pki/pesign -n "Secure Boot KEK" \
-o ~/SecureBootKEK.p12
# pk12util -d /etc/pki/pesign -n "Secure Boot DB" \
-o ~/SecureBootDB.p12

To later import the keys into a NSS database:
# pk12util -d etc/pki/pesign -i ~/SecureBootPK.p12
# ...

  • Sign the EFI binarys


# pesign -s -n /etc/pki/pesign -c "Secure Boot DB" -i sample.efi \
-o sample_signed.efi

Every bootloader and its drivers need to be signed in order to be loaded by the UEFI.
Also bear in mind, that you have to sign every Linux kernel, so it's a good idea to write a little script/hook that runs every time the kernel is updated.

#! /bin/sh
pesign -n /etc/pki/pesign -c "Secure Boot DB" -s \
-i /boot/vmlinuz-linux -o /tmp/vmlinuz-linux-signed
mv /tmp/vmlinuz-linux-signed /boot/vmlinuz-linux

For Windows, every EFI file in EFI/Microsoft/Boot should be signed:
bootmgfw.efi
bootmgr.efi
memtest.efi

In macOS, these files must be signed:
/System/Library/CoreServices/boot.efi
When using FileVault and APFS, the Preboot .efi has to be signed too:
/Volumes/Preboot/<UUID>/System/Library/CoreServices/boot.efi
It might be a good idea to sign the recovery .efi to have access to the recovery partition.
First mount the Recovery Partition:
$ diskutil mount diskXsY
Then sign /Volumes/Recovery/<UUID>/boot.efi

  • Import the Keys into BIOS/UEFI


Now it's time to import the keys and activate Secure Boot.
This can vary greatly depending on the mainboard. This is a great tutorial on the topic.


NOTE:

Deleting Microsoft's Keys from your BIOS will result in not being able to boot Windows. Either don't remove them (if possible with your firmware), add their keys manually as discribed here or simply sign the Windows bootloader. Deleting the Microsoft signature from the bootloader will also result in Windows not booting, so leave them intact.

Also note that you will probably need Microsoft Corporation UEFI CA 2011 to be in your DB. Otherwise your graphics card or network card might not work in pre-boot environment as their EFI firmware is most likely signed by Microsoft.
It's possible to extract those drivers, sign and repack them, but you might risk bricking your graphics card.



References

Last edited on 01/2021

No comments: