# Unified Extensible Firmware Interface/Secure Boot

From ArchWiki
< Unified Extensible Firmware Interface
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Related articles

- Arch boot process
- Unified Extensible Firmware Interface
- Security

Secure Boot is a security feature found in the UEFI standard, designed to add a layer of protection to the pre-boot process: by maintaining a cryptographically signed list of binaries authorized or forbidden to run at boot, it helps in improving the confidence that the machine core boot components (boot manager, kernel, initramfs) haven't been tampered with.

As such it can be seen as a continuation or complement to the efforts in securing one's computing environment, reducing the attack surface that other software security solutions such as system encryption cannot easily cover, while being totally distinct and not dependent on them. Secure Boot just stands on its own as a component of current security practices, with its own set of pros and cons.

Note: For a deeper overview about Secure Boot in Linux, see Rodsbooks' Secure Boot article and other online resources. This article focuses on how to set up Secure Boot in Arch Linux.

## Checking Secure Boot status

### Before booting the OS

At this point, one has to look at the firmware setup. If the machine was booted and is running, in most cases it will have to be rebooted.

You may access the firmware configuration by pressing a special key during the boot process. The key to use depends on the firmware. It is usually one of `Esc`, `F2`, `Del` or possibly another `Fn` key. Sometimes the right key is displayed for a short while at the beginning of the boot process. The motherboard manual usually records it. You might want to press the key, and keep pressing it, immediately following powering on the machine, even before the screen actually displays anything.

After entering the firmware setup, be careful not to change any settings without prior intention. Usually there are navigation instructions, and short help for the settings, at the bottom of each setup screen. The setup itself might be composed of several pages. You will have to navigate to the correct place. The interesting setting might be simply denoted by secure boot, which can be set on or off.

### After booting the OS

An easy way to check Secure Boot status on systems using systemd is to use systemd-boot:

Note: There is no need to be using systemd-boot as your boot manager for this command to work, it is more akin to the others *ctl systemd utilities (localectl, timedatectl...) and won't touch your configuration.

    $ bootctl status
    System:
         Firmware: UEFI 2.70 (American Megatrends 5.15)
      Secure Boot: enabled
       Setup Mode: user
     Boot into FW: supported
    ...

Here we see that Secure Boot is enabled and enforced; other values are `disabled` for Secure Boot and `setup` for Setup Mode[1].

The factual accuracy of this article or section is disputed.

Reason: This command might display more than five digits even though secure boot is enabled. (Discuss in Talk:Unified Extensible Firmware Interface/Secure Boot#)

Another way to check whether the machine was booted with Secure Boot is to use this command:

    $ od --address-radix=n --format=u1 /sys/firmware/efi/efivars/SecureBoot*

If Secure Boot is enabled, this command returns `1` as the final integer in a list of five, for example:

    6  0  0  0  1

Note, however, that the kernel may be unaware of Secure Boot (even if it is enabled in the firmware) if an insufficiently capable boot loader is used. This can be verified by checking the kernel messages shortly after the system starts up:

    # dmesg | grep -i secure

    [    0.013442] Secure boot disabled
    [    0.013442] Secure boot could not be determined

The kernel messages will otherwise read `Secure boot enabled`.

## Booting an installation medium

Note: The official installation image does not support Secure Boot (FS#53864). To successfully boot the installation medium you will need to disable Secure Boot.

Secure Boot support was initially added in `archlinux-2013.07.01-dual.iso` and later removed in `archlinux-2016.06.01-dual.iso`. At that time prebootloader was replaced with efitools, even though the latter uses unsigned EFI binaries. There has been no support for Secure Boot in the official installation medium ever since.

### Disabling Secure Boot

The Secure Boot feature can be disabled via the UEFI firmware interface. How to access the firmware configuration is described in #Before booting the OS.

If using a hotkey did not work and you can boot Windows, you can force a reboot into the firmware configuration in the following way (for Windows 10): Settings > Update & Security > Recovery > Advanced startup (Restart now) > Troubleshoot > Advanced options > UEFI Firmware settings > restart.

Note that some motherboards (this is the case in a Packard Bell laptop) only allow to disable secure boot if you have set an administrator password (that can be removed afterwards). See also Rod Smith's Disabling Secure Boot.

### Remastering the installation image

This article or section needs expansion.

Reason: Add explicit instructions. (Discuss in Talk:Unified Extensible Firmware Interface/Secure Boot#)

One might want to remaster the Install ISO in a way described by previous topics of this article. For example, the signed EFI applications `PreLoader.efi` and `HashTool.efi` from #PreLoader can be adopted to here. Another option would be to borrow the `BOOTx64.EFI` (shim) and `grubx64.efi` from installation media of another GNU+Linux distribution that supports Secure Boot and modify the GRUB configuration to one's needs. In this case, the authentication chain of Secure Boot in said distribution's installation media should end to the `grubx64.efi` ( for example Ubuntu) so that GRUB would boot the unsigned kernel and initramfs from archiso. Note that up to this point, the article assumed one can access the ESP of the machine. But when installing a machine that never had an OS before, there is no ESP present. You should explore other articles, for example Unified Extensible Firmware Interface#Create UEFI bootable USB from ISO, to learn how this situation should be handled.

## Implementing Secure Boot

There are certain conditions making for an ideal setup of Secure boot:

1. UEFI considered mostly trusted (despite having some well known criticisms and vulnerabilities[2]) and necessarily protected by a strong password
2. Default manufacturer/third party keys aren't in use, as they have been shown to weaken the security model of Secure Boot by a great margin[3]
3. UEFI directly loads a user-signed EFISTUB combined kernel image (no boot manager), including microcode (if applicable) and initramfs so as to maintain throughout the boot process the chain of trust established by Secure Boot and reduce the attack surface
4. Use of full drive encryption, so that the tools and files involved in the kernel image creation and signing process cannot be accessed and tampered with by someone having physical access to the machine.
5. Some further improvements may be obtained by using a TPM, although tooling and support makes this harder to implement.

A simple and fully self-reliant setup is described in #Using your own keys, while #Using a signed boot loader makes use of intermediate tools signed by a third-party.

### Using your own keys

Warning: Replacing the platform keys with your own can end up bricking hardware on some machines, including laptops, making it impossible to get into the UEFI/BIOS settings to rectify the situation. This is due to the fact that some device (e.g GPU) firmware is signed using Microsoft's key.

Secure Boot implementations use these keys:

Platform Key (PK)
  Top-level key.
Key Exchange Key (KEK)
  Keys used to sign Signatures Database and Forbidden Signatures Database updates.
Signature Database (db)
  Contains keys and/or hashes of allowed EFI binaries.
Forbidden Signatures Database (dbx)
  Contains keys and/or hashes of denylisted EFI binaries.

See The Meaning of all the UEFI Keys for a more detailed explanation.

To use Secure Boot you need at least PK, KEK and db keys. While you can add multiple KEK, db and dbx certificates, only one Platform Key is allowed.

Once Secure Boot is in "User Mode" keys can only be updated by signing the update (using sign-efi-sig-list) with a higher level key. Platform key can be signed by itself.

#### Install efitools

Nearly all of the following sections require you to install the efitools package.

#### Backing up current variables

Before creating new keys and modifying EFI variables, it is advisable to backup the current variables, so that they may be restored in case of error.

Run the following commands to backup all four of the principal Secure Boot variables:

    $ efi-readvar -v PK -o old_PK.esl
    $ efi-readvar -v KEK -o old_KEK.esl
    $ efi-readvar -v db -o old_db.esl
    $ efi-readvar -v dbx -o old_dbx.esl

If you perform these commands on a new computer or motherboard, the variables you extract will most likely be the ones provided by Microsoft.

#### Creating keys

##### Manual process

To generate keys, perform the following steps.

You will need private keys and certificates in multiple formats:

.key
  PEM format private keys for EFI binary and EFI signature list signing.
.crt
  PEM format certificates for sbsign(1), sbvarsign(1) and sign-efi-sig-list(1).
.cer
  DER format certificates for firmware.
.esl
  Certificates in an EFI Signature List for sbvarsign(1), efi-updatevar(1), KeyTool and firmware.
.auth
  Certificates in an EFI Signature List with an authentication header (i.e. a signed certificate update file) for efi-updatevar(1), sbkeysync, KeyTool and firmware.

Create a GUID for owner identification:

    $ uuidgen --random > GUID.txt

Platform key:

    $ openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Platform Key/" -out PK.crt
    $ openssl x509 -outform DER -in PK.crt -out PK.cer
    $ cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl
    $ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth

Sign an empty file to allow removing Platform Key when in "User Mode":

    $ sign-efi-sig-list -g "$(< GUID.txt)" -c PK.crt -k PK.key PK /dev/null rm_PK.auth

Key Exchange Key:

    $ openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Key Exchange Key/" -out KEK.crt
    $ openssl x509 -outform DER -in KEK.crt -out KEK.cer
    $ cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl
    $ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth

Signature Database key:

    $ openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -days 3650 -subj "/CN=my Signature Database key/" -out db.crt
    $ openssl x509 -outform DER -in db.crt -out db.cer
    $ cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl
    $ sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth

##### Helper scripts

A helper/convenience script is offered by the author of the reference page on this topic[4] (requires python). A mildly edited version is also packaged as sbkeysAUR.

In order to use it, simply create a folder in a secure location (e.g. `/etc/efi-keys/` if later use of sbupdate-gitAUR to automate unified kernel image creation and signing is planned) and run it:

    # mkdir /etc/efi-keys
    # cd !$
    # curl -L -O https://www.rodsbooks.com/efi-bootloaders/mkkeys.sh
    # chmod +x mkkeys.sh
    # ./mkkeys.sh
    <Enter a Common Name to embed in the keys, e.g. "Secure Boot">

This will produce the required files in different formats.

##### Updating keys

Once Secure Boot is in "User Mode" any changes to KEK, db and dbx need to be signed with a higher level key.

For example, if you wanted to replace your db key with a new one:

1. Create the new key,
2. Convert it to EFI Signature List,
3. Sign the EFI Signature List,
4. Enroll the signed certificate update file.

    $ cert-to-efi-sig-list -g "$(< GUID.txt)" new_db.crt new_db.esl
    $ sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db new_db.esl new_db.auth

If instead of replacing your db key, you want to add another one to the Signature Database, you need to use the option `-a` (see sign-efi-sig-list(1)):

    $ sign-efi-sig-list -a -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db new_db.esl new_db.auth

When `new_db.auth` is created, enroll it.

#### Signing EFI binaries

When Secure Boot is active (i.e. in "User Mode"), only signed EFI binaries (e.g. applications, drivers, unified kernel images) can be launched.

##### Manually with sbsigntools

Install sbsigntools to sign EFI binaries with sbsign(1).

Tip:

- To check if a binary is signed and list its signatures use `sbverify --list /path/to/binary`.
- The rEFInd boot manager's `refind-install` script can sign rEFInd EFI binaries and copy them together with the db certificates to the ESP. See rEFInd#Using your own keys for instructions.

Note: If running sbsign without `--output` the resulting file will be `filename.signed`. See sbsign(1) for more information.

To sign your kernel and boot manager use sbsign, e.g.:

    # sbsign --key db.key --cert db.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
    # sbsign --key db.key --cert db.crt --output esp/EFI/BOOT/BOOTx64.EFI esp/EFI/BOOT/BOOTx64.EFI

Warning: Signing kernel only will not protect the initramfs from tampering. See Preparing a unified kernel image to know how to produce a combined image that you can then manually sign with sbsign.

##### Signing the kernel with a pacman hook

You can also use mkinitcpio's pacman hook to sign the kernel on install and updates.

Copy `/usr/share/libalpm/hooks/90-mkinitcpio-install.hook` to `/etc/pacman.d/hooks/90-mkinitcpio-install.hook` and `/usr/share/libalpm/scripts/mkinitcpio-install` to `/usr/local/share/libalpm/scripts/mkinitcpio-install`.

In `/etc/pacman.d/hooks/90-mkinitcpio-install.hook`, replace:

    Exec = /usr/share/libalpm/scripts/mkinitcpio-install

with:

    Exec = /usr/local/share/libalpm/scripts/mkinitcpio-install

In `/usr/local/share/libalpm/scripts/mkinitcpio-install`, replace:

    install -Dm644 "${line}" "/boot/vmlinuz-${pkgbase}"

with:

    sbsign --key /path/to/db.key --cert /path/to/db.crt --output "/boot/vmlinuz-${pkgbase}" "${line}"

If you are using systemd-boot, there is a dedicated pacman hook doing this task semi-automatically.

##### Fully automated unified kernel generation and signing with sbupdate

sbupdate is a tool made specifically to automate unified kernel image generation and signing on Arch Linux. It handles installation, removal and updates of kernels through pacman hooks.

Install sbupdate-gitAUR and configure it following the instructions given on the project's homepage.[5]

Tip: If using systemd-boot, set `OUT_DIR="EFI/Linux"` to get your signed kernel images directly recognized without needing configuration. See systemd-boot(7) § FILES and Systemd-boot#Adding loaders.

Once configured, simply run `sbupdate` as root for first-time image generation.

Note: sbupdate output often contains errors such as `warning: data remaining[26413568 vs 26423180]: gaps between PE/COFF sections?`. Those are harmless and can be safely ignored.[6]

#### Putting firmware in "Setup Mode"

Secure Boot is in Setup Mode when the Platform Key is removed. To put firmware in Setup Mode, enter firmware setup utility and find an option to delete or clear certificates. How to enter the setup utility is described in #Before booting the OS.

#### Enrolling keys in firmware

Use one of the following methods to enroll db, KEK and PK certificates.

Tip: As the dbx (forbidden signatures db) is empty, it can be safely left out in the following instructions.
Warning: Enrolling Platform Key sets Secure Boot in "User Mode", leaving "Setup Mode", so it should be enrolled last in sequence.

##### Using sbkeysync

Install sbsigntools. Create a directory `/etc/secureboot/keys` with the following directory structure -

    /etc/secureboot/keys
    ├── db
    ├── dbx
    ├── KEK
    └── PK

For example using:

    # mkdir -p /etc/secureboot/keys/{db,dbx,KEK,PK}

Then copy each of the .auth files that were generated earlier into their respective locations (for example, `PK.auth` into `/etc/secureboot/keys/PK` and so on).

See what changes will `sbkeysync` shall do to your system's UEFI keystore.

    # sbkeysync --pk --dry-run --verbose

Finally, use `sbkeysync` to enroll your keys.

    # sbkeysync --verbose
    # sbkeysync --verbose --pk

Tip: If using `sbkeysync` returns write errors, first run `chattr -i /sys/firmware/efi/efivars/{PK,KEK,db}*` immediately prior to issuing commands with `sbkeysync` to temporarily change file attributes, enabling writing of the efi keys within the efivars directory. See chattr(1).

On next boot the UEFI should be back in User Mode and enforcing Secure Boot policy.

##### Using firmware setup utility

Copy all `*.cer`, `*.esl`, `*.auth` to a FAT formatted file system (you can use EFI system partition).

Launch firmware setup utility and enroll db, KEK and PK certificates. Firmwares have various different interfaces, see Replacing Keys Using Your Firmware's Setup Utility for example how to enroll keys.

If the used tool supports it prefer using .auth and .esl over .cer.

##### Using KeyTool

`KeyTool.efi` is in efitools package, copy it to ESP. To use it after enrolling keys, sign it with `sbsign`.

    # sbsign --key db.key --cert db.crt --output esp/KeyTool-signed.efi /usr/share/efitools/efi/KeyTool.efi

Launch `KeyTool-signed.efi` using firmware setup utility, boot loader or UEFI Shell and enroll keys.

See Replacing Keys Using KeyTool for explanation of KeyTool menu options.

#### Dual booting with other operating systems

##### Microsoft Windows

This article or section needs expansion.

Reason: Is it possible to boot Windows by signing its bootloader with a custom key? (Discuss in Talk:Unified Extensible Firmware Interface/Secure Boot#Booting Windows with custom bootloader signature)

To dual boot with Windows, you would need to add Microsoft's certificates to the Signature Database. Microsoft has two db certificates:

- Microsoft Windows Production PCA 2011 for Windows
- Microsoft Corporation UEFI CA 2011 for third-party binaries like UEFI drivers, option ROMs etc.

Create EFI Signature Lists from Microsoft's DER format certificates using Microsoft's GUID (`77fa9abd-0359-4d32-bd60-28f4e78f784b`) and combine them in one file for simplicity:

    $ sbsiglist --owner 77fa9abd-0359-4d32-bd60-28f4e78f784b --type x509 --output MS_Win_db.esl MicWinProPCA2011_2011-10-19.crt
    $ sbsiglist --owner 77fa9abd-0359-4d32-bd60-28f4e78f784b --type x509 --output MS_UEFI_db.esl MicCorUEFCA2011_2011-06-27.crt
    $ cat MS_Win_db.esl MS_UEFI_db.esl > MS_db.esl

Sign a db update with your KEK. Use `sign-efi-sig-list` with option `-a` to add not replace a db certificate:

    $ sign-efi-sig-list -a -g 77fa9abd-0359-4d32-bd60-28f4e78f784b -k KEK.key -c KEK.crt db MS_db.esl add_MS_db.auth

Follow #Enrolling keys in firmware to add `add_MS_db.auth` to Signature Database.

### Using a signed boot loader

Using a signed boot loader means using a boot loader signed with Microsoft's key. There are two known signed boot loaders: PreLoader and shim. Their purpose is to chainload other EFI binaries (usually boot loaders). Since Microsoft would never sign a boot loader that automatically launches any unsigned binary, PreLoader and shim use an allowlist called Machine Owner Key list, abbreviated MokList. If the SHA256 hash of the binary (Preloader and shim) or key the binary is signed with (shim) is in the MokList they execute it, if not they launch a key management utility which allows enrolling the hash or key.

#### PreLoader

When run, PreLoader tries to launch `loader.efi`. If the hash of `loader.efi` is not in MokList, PreLoader will launch `HashTool.efi`. In HashTool you must enroll the hash of the EFI binaries you want to launch, that means your boot loader (`loader.efi`) and kernel.

Note: Each time you update any of the binaries (e.g. boot loader or kernel) you will need to enroll their new hash.
Tip: The rEFInd boot manager's `refind-install` script can copy the rEFInd and PreLoader EFI binaries to the ESP. See rEFInd#Using PreLoader for instructions.

##### Set up PreLoader

Note: `PreLoader.efi` and `HashTool.efi` in efitools package are not signed, so their usefulness is limited. You can get a signed `PreLoader.efi` and `HashTool.efi` from preloader-signedAUR or download them manually.

Install preloader-signedAUR and copy `PreLoader.efi` and `HashTool.efi` to the boot loader directory; for systemd-boot use:

    # cp /usr/share/preloader-signed/{PreLoader,HashTool}.efi esp/EFI/systemd

Now copy over the boot loader binary and rename it to `loader.efi`; for systemd-boot use:

    # cp esp/EFI/systemd/systemd-bootx64.efi esp/EFI/systemd/loader.efi

Finally, create a new NVRAM entry to boot `PreLoader.efi`:

    # efibootmgr --verbose --disk /dev/sdX --part Y --create --label "PreLoader" --loader /EFI/systemd/PreLoader.efi

Replace `X` with the drive letter and replace `Y` with the partition number of the EFI system partition.

This entry should be added to the list as the first to boot; check with the `efibootmgr` command and adjust the boot-order if necessary.

###### Fallback

If there are problems booting the custom NVRAM entry, copy `HashTool.efi` and `loader.efi` to the default loader location booted automatically by UEFI systems:

    # cp /usr/share/preloader-signed/HashTool.efi esp/EFI/BOOT/
    # cp esp/EFI/systemd/systemd-bootx64.efi esp/EFI/BOOT/loader.efi

Copy over `PreLoader.efi` and rename it:

    # cp /usr/share/preloader-signed/PreLoader.efi esp/EFI/BOOT/BOOTx64.EFI

For particularly intransigent UEFI implementations, copy `PreLoader.efi` to the default loader location used by Windows systems:

    # mkdir -p esp/EFI/Microsoft/Boot
    # cp /usr/share/preloader-signed/PreLoader.efi esp/EFI/Microsoft/Boot/bootmgfw.efi

Note: If dual-booting with Windows, backup the original `bootmgfw.efi` first as replacing it may cause problems with Windows updates.

As before, copy `HashTool.efi` and `loader.efi` to `esp/EFI/Microsoft/Boot/`.

When the system starts with Secure Boot enabled, follow the steps above to enroll `loader.efi` and `/vmlinuz-linux` (or whichever kernel image is being used).

##### How to use while booting?

A message will show up that says `Failed to Start loader... I will now execute HashTool.` To use HashTool for enrolling the hash of `loader.efi` and `vmlinuz.efi`, follow these steps. These steps assume titles for a remastered archiso installation media. The exact titles you will get depends on your boot loader setup.

- Select OK
- In the HashTool main menu, select Enroll Hash, choose `\loader.efi` and confirm with Yes. Again, select Enroll Hash and `archiso` to enter the archiso directory, then select `vmlinuz.efi` and confirm with Yes. Then choose Exit to return to the boot device selection menu.
- In the boot device selection menu choose Arch Linux archiso x86_64 UEFI CD

##### Remove PreLoader

Note: Since you are going to remove stuff, is a good idea to backup it.

Uninstall preloader-signedAUR and simply remove the copied files and revert configuration; for systemd-boot use:

    # rm esp/EFI/systemd/{PreLoader,HashTool}.efi
    # rm esp/EFI/systemd/loader.efi
    # efibootmgr --verbose --bootnum N --delete-bootnum
    # bootctl update

Where `N` is the NVRAM boot entry created for booting `PreLoader.efi`. Check with the efibootmgr command and adjust the boot-order if necessary.

Note: The above commands cover the easiest case; if you have created, copied, renamed or edited further files probably you have to handle with them, too. If PreLoader was your operational boot entry, you obviously also need to #Disabling Secure Boot.

#### shim

This article or section needs expansion.

Reason: Testing needed. (Discuss in Talk:Unified Extensible Firmware Interface/Secure Boot#shim)

When run, shim tries to launch `grubx64.efi`. If MokList does not contain the hash of `grubx64.efi` or the key it is signed with, shim will launch MokManager (`mmx64.efi`). In MokManager you must enroll the hash of the EFI binaries you want to launch (your boot loader (`grubx64.efi`) and kernel) or enroll the key they are signed with.

Note:

- If you use #shim with hash, each time you update any of the binaries (e.g. boot loader or kernel) you will need to enroll their new hash.
- Since version 15.3, shim will not launch EFI binaries without a valid `.sbat` section. Run `objdump -j .sbat -s /path/to/binary.efi` to verify if an EFI binary has it. See the SBAT documentation for details.

##### Set up shim

Tip: The rEFInd boot manager's `refind-install` script can sign rEFInd EFI binaries and copy them along with shim and the MOK certificates to the ESP. See rEFInd#Using shim for instructions.

Install shim-signedAUR.

Rename your current boot loader to `grubx64.efi`

    # mv esp/EFI/BOOT/BOOTx64.EFI esp/EFI/BOOT/grubx64.efi

Copy shim and MokManager to your boot loader directory on ESP; use previous filename of your boot loader as as the filename for `shimx64.efi`:

    # cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI
    # cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/

Finally, create a new NVRAM entry to boot `BOOTx64.EFI`:

    # efibootmgr --verbose --disk /dev/sdX --part Y --create --label "Shim" --loader /EFI/BOOT/BOOTx64.EFI

shim can authenticate binaries by Machine Owner Key or hash stored in MokList.

Machine Owner Key (MOK)
  A key that a user generates and uses to sign EFI binaries.
hash
  A SHA256 hash of an EFI binary.

Using hash is simpler, but each time you update your boot loader or kernel you will need to add their hashes in MokManager. With MOK you only need to add the key once, but you will have to sign the boot loader and kernel each time it updates.

###### shim with hash

If shim does not find the SHA256 hash of `grubx64.efi` in MokList it will launch MokManager (`mmx64.efi`).

In MokManager select Enroll hash from disk, find `grubx64.efi` and add it to MokList. Repeat the steps and add your kernel `vmlinuz-linux`. When done select Continue boot and your boot loader will launch and it will be capable launching the kernel.

###### shim with key

Install sbsigntools.

You will need:

.key
  PEM format private key for EFI binary signing.
.crt
  PEM format certificate for sbsign.
.cer
  DER format certificate for MokManager.

Create a Machine Owner Key:

    $ openssl req -newkey rsa:4096 -nodes -keyout MOK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Machine Owner Key/" -out MOK.crt
    $ openssl x509 -outform DER -in MOK.crt -out MOK.cer

Sign your boot loader (named `grubx64.efi`) and kernel:

    # sbsign --key MOK.key --cert MOK.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
    # sbsign --key MOK.key --cert MOK.crt --output esp/EFI/BOOT/grubx64.efi esp/EFI/BOOT/grubx64.efi

You will need to do this each time they are updated. You can automate the kernel signing with a pacman hook, e.g.:

    /etc/pacman.d/hooks/999-sign_kernel_for_secureboot.hook

    [Trigger]
    Operation = Install
    Operation = Upgrade
    Type = Package
    Target = linux
    Target = linux-lts
    Target = linux-hardened
    Target = linux-zen

    [Action]
    Description = Signing kernel with Machine Owner Key for Secure Boot
    When = PostTransaction
    Exec = /usr/bin/find /boot/ -maxdepth 1 -name 'vmlinuz-*' -exec /usr/bin/sh -c 'if ! /usr/bin/sbverify --list {} 2>/dev/null | /usr/bin/grep -q "signature certificates"; then /usr/bin/sbsign --key MOK.key --cert MOK.crt --output {} {}; fi' ;
    Depends = sbsigntools
    Depends = findutils
    Depends = grep

Copy `MOK.cer` to a FAT formatted file system (you can use EFI system partition).

Reboot and enable Secure Boot. If shim does not find the certificate `grubx64.efi` is signed with in MokList it will launch MokManager (`mmx64.efi`).

In MokManager select Enroll key from disk, find `MOK.cer` and add it to MokList. When done select Continue boot and your boot loader will launch and it will be capable launching any binary signed with your Machine Owner Key.

###### shim with key and GRUB

This article or section needs language, wiki syntax or style improvements. See Help:Style for reference.

Reason: Too long, written like a blog post. Also many formatting issues, see Help:Style. (Discuss in Talk:Unified Extensible Firmware Interface/Secure Boot#)
Warning: With secureboot active GRUB can't chainload EFI binaries even if they are signed.

For signing you can for example use the grub2-signing extension.

There is also a package in the AUR: grub2-signing-extensionAUR.

Run `gpg --gen-key` as root to create a keypair.

If you get a permission denied error try:

    # chown root:root $(tty)
    # export GPG_TTY"="$(tty)

Activate the gpg-agent:

    /root/.gnupg/gpg.conf

    use-agent

    /root/.gnupg/gpg-agent.conf

    pinentry-program /usr/bin/pinentry
    no-grab
    default-cache-ttl 1800

Export your public key:

    # gpg --export -o /root/pubkey

Mount your boot partition. (Re)install GRUB2:

    # grub-install --target=x86_64-efi --efi-directory=esp --bootloader-id=GRUB -k /root/pubkey --modules="gcry_sha256 gcry_dsa gcry_rsa"

Copy your publickey to your boot partiton:

    # cp /root/pubkey /boot/pubkey

Edit your GRUB custom configuration and add:

    /etc/grub.d/40_Custom

    insmod verify
    insmod gcry_sha256
    insmod gcry_dsa gcry_rsa
    set check_signatures=enforce
    trust (crypto0)/pubkey
    insmod shim_lock

Tip: (crypt0) is the name of the partition in GRUB.

Rebuild your GRUB configuration:

    grub-mkconfig > /boot/grub/grub.cfg

Ensure that you created `MOK.key` and signed your `kernel` and `grubx64.efi` like described in shim with key.

Sign the GRUB files with `grub-sign`.

Run `grub-verify` and check if there are errors.

Here is a simple unsign hook:

    /etc/pacman.d/hooks/10-unsign-grub-before-update.hook

    [Trigger]
    Operation = Install
    Operation = Upgrade
    Operation = Remove
    Type = Package
    Target = linux
    Target = linux-lts
    Target = linux-zen
    Target = grub
    Target = intel-ucode
    Target = amd-ucode

    [Action]
    Description = Unsigning GRUB
    When = PreTransaction
    Exec = /usr/bin/grub-unsign

And a bash script you can use to sign again after the update:

     .bashrc

    function sign-update () {
       /usr/bin/grub-unsign
       if [ $? -ne 0 ]; then return 1; fi
       /usr/bin/find /boot/ -maxdepth 1 -name 'vmlinuz-*' -not -name "*.sig" -exec /usr/bin/sh -c \
       'if ! /usr/bin/sbverify --list {} 2>/dev/null | /usr/bin/grep -q "signature certificates"; \
       then echo "Signing with sbsign."; /usr/bin/sbsign --key MOK.key --cert MOK.crt --output {} {}; fi' \;
       /usr/bin/grub-sign
       /usr/bin/find /boot/ -maxdepth 1 -name 'vmlinuz-*' -not -name "*.sig" -exec /usr/bin/sh -c \
       'echo ""; echo {}; /usr/bin/sbverify --list {};' \;
    }

##### Remove shim

Uninstall shim-signedAUR, remove the copied shim and MokManager files and rename back your boot loader.

## Protecting Secure Boot

The only way to prevent anyone with physical access to disable Secure Boot is to set a user/administrator password in the firmware.

Most UEFI provide such feature, usually listed under the "Security" section.

## See also

- Understanding the UEFI Secure Boot Chain by tianocore
- Wikipedia:Unified Extensible Firmware Interface#Secure boot
- Dealing with Secure Boot by Rod Smith
- Controlling Secure Boot by Rod Smith
- UEFI secure booting (part 2) by Matthew Garrett
- UEFI Secure Boot by James Bottomley
- efitools README
- Will your computer's "Secure Boot" turn out to be "Restricted Boot"? — Free Software Foundation
- Free Software Foundation recommendations for free operating system distributions considering Secure Boot
- Intel's UEFI Secure Boot Tutorial
- Secure Boot, Signed Modules and Signed ELF Binaries
- National Security Agency docs: UEFI Defensive Practices Guidance and unclassified UEFI Secure Boot customization
- sbkeysync & maintaining uefi key databases by Jeremy Kerr
- Secure your boot process: UEFI + Secureboot + EFISTUB + Luks2 + lvm + ArchLinux (2020-07)
- How is hibernation supported, on machines with UEFI Secure Boot? (Security StackExchange)

Category:

- Boot process

Hidden categories:

- Pages or sections flagged with Template:Accuracy
- Pages or sections flagged with Template:Expansion
- Pages or sections flagged with Template:Style