← Back to Blogs

A Word on Signed UEFI Linux Systems

January 25, 2020



Background

Remember that option in your BIOS called “Secure boot” that you disabled in order to download and install Linux on your PC? Secure boot is designed to only boot operating systems (like Windows) that have been officially signed by Microsoft’s UEFI signing key. Until now, I had been dual booting an unsigned/normal Linux along with Windows 10, with Secure Boot disabled in BIOS. However, I realized when setting up someone else’s computer that if your Windows system is encrypted, you need Secure Boot to boot properly. Turn's out not only Windows can be signed - with some work, you can sign Linux, too! So, I decided to take the opportunity to sign and setup Secure Boot for my system. I did a little reading, and here’s what I found…

From the Arch Linux Wiki:

“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 a whitelist 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.”

As I understand it, this basically means that Microsoft has been kind enough to sign two specific boot loaders for Linux systems, called PreLoader and shim. Haven’t heard of them? It’s OK, I hadn’t either. The nice thing about these two boot loaders is that they can be chain loaded — that means that they can be used in conjunction with your existing boot loader of choice (in my case, GRUB). PreLoader and shim work in slightly different ways. Based on my research, PreLoader is easier to get working alongside GRUB, so I will be using it in this article; however, there’s a catch — you need to use efibootmgr to create a custom BIOS boot menu item. For the average user, this is totally fine — you’ve probably already done so when you installed Linux in the first place. However, if you don’t own the laptop you work with, or it is managed by someone else, you will want to ask for permission before doing this. What about shim? Shim seems like it’s install process does NOT require the use of efibootmgr, but it’s also a lot more confusing to setup, especially with GRUB. I am currently researching this some more; I will release another article if it works out.

Installation + Setup

The following instructions are paraphrased from the Arch Linux Wiki page on Secure Boot.

  1. pacman -Syu --needed efitools efibootmgr
  2. yay -S preloader-signed
  3. sudo cp /usr/share/preloader-signed/{PreLoader,HashTool}.efi /efi/EFI/<your bootloader here>
  4. sudo cp /efi/EFI/GRUB/<bootloader-file>.efi /efi/EFI/<your bootloader here>/loader.efi'
  5. sudo efibootmgr --verbose --disk /dev/<linux disk> --part <partition number of EFI partition> --create --label “PreLoader" --loader /EFI/<your bootloader here>/PreLoader.efi

That’s it! The next time you boot, your UEFI BIOS should automatically boot into PreLoader , which will then sign and run GRUB (or whatever boot loader you use).

So how does this all work? Basically, you create a boot option using efibootmgr which is stored on your motherboard’s NVRAM (like all other boot options and BIOS settings). This new boot option is configured to go to the disk on which you installed Linux, mount the EFI partition, and launch /EFI/<bootloader>/PreLoader.efi . PreLoader then takes over and signs your stuff, etc. Once it’s done, it is programmed to chainload whatever other boot loader you use by calling loader.efi . Since it calls only the file with this name, you have to copy the efi file for your main bootloader to this name. PreLoader will then launch your regular boot loader and you can resume life like normal!

Testing

TL;DR: It worked, with a little more (straight forward) setup.

My first step was to just reboot, not touch anything, and see if my system booted back into Linux. It did, however I did notice one thing — GRUB_GFXMODE=auto was no longer selecting the proper resolution. This is a minor thing and by no means will it break your system, but as I like to have a very aesthetically clean OS, I went into /etc/default/grub, went down to the line that says GRUB_GFXMODE=auto and changed it to GRUB_GFXMODE=1920x1080. Naturally, you should replace these numbers with the nativeresolution of your display. I then ran sudo grub-mkconfig -o /boot/grub/grub.cfg as per usual (run sudo update-grub) if on Ubuntu and rebooted again, this time pressing F12 to look at my boot menu options. PreLoader was indeed the first item on the list. But instead of booting, I went to Setup, which launched my BIOS configuration. I went to the Security tab and enabled Secure Boot. Then, I saved, exited, and selected PreLoader. It paused for a few seconds, then gave me a menu to sign my key (I guess this wasn’t called earlier since Secure Boot was off. I told it to add a hash, then selected loader.efi (the efi file we made earlier, which launches your main boot loader). It then booted into GRUB, and Linux launched correctly. The next time I booted, I didn’t touch anything; PreLoader launched (I’m assuming), and with almost no delay, gave me my regular GRUB prompt!

That’s it for this article. I will release another one describing some more GRUB configuration soon!