Managing EFI Boot Loaders for Linux:
Dealing with Secure Boot

by Rod Smith, rodsmith@rodsbooks.com

Originally written: 11/4/2012; last update: 3/24/2024

This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!

Donate $1.00 Donate $2.50 Donate $5.00 Donate $10.00 Donate another value
Donate with PayPal
Donate with PayPal
Donate with PayPal
Donate with PayPal
Donate with PayPal

This page is part of my Managing EFI Boot Loaders for Linux document. If a Web search has brought you to this page, you may want to start at the beginning.

In addition to implementing a new boot protocol, UEFI adds a new feature that can improve system security, but that also has the potential to cause a great deal of confusion and trouble: Secure Boot. As the name implies, Secure Boot is intended as a security feature. By its very nature, though, Secure Boot can also make it harder to boot Linux, particularly on commodity PCs that ship with Windows pre-installed. This page provides an overview of what Secure Boot is and how the Linux community is responding to it. Although Secure Boot is developing less rapidly than it was in late 2012, when I first wrote this page, it's still a dynamic area. In other words, things may have changed!

What Is Secure Boot?

For decades, PCs have been plagued by viruses, worms, and other malware. Some of the earliest viruses for PCs spread as boot sector viruses: They resided as code in the boot sectors of floppy disks and spread from one computer to another when users booted their computers using infected DOS floppies. Although other modes of virus transmission gained prominence as floppies faded in importance and Internet connections became common, pre-boot malware has always had its appeal to malware authors. By executing before an OS kernel gains control of the computer, malware can "hide out" in ways that aren't possible once an OS has taken over, thus making it virtually impossible for virus scanners to detect the malware—at least, not without rebooting into an emergency system that's not infected.

BIOS provides few protections against infection by pre-boot malware; in the BIOS boot path, the OS implicitly trusts whatever executes as the boot loader. Until late 2012, this has been true of most production EFI implementations, too. Secure Boot, though, is designed to add a layer of protection to the pre-boot process. With Secure Boot active, the firmware checks for the presence of a cryptographic signature on any EFI program that it executes. If the cryptographic signature is absent, doesn't correspond to a key held in the computer's NVRAM, or is blacklisted in the NVRAM, the firmware refuses to execute the program. Of course, this is simply the start of the process; a trusted EFI boot loader must continue the boot process in a secure fashion, leading ultimately to an OS that is itself secure. A malware author would need to get the malware signed, which would be difficult if users control their own system keys (in a secure way!). Thus, pre-boot malware can be blocked. There are a lot of ways for things to go wrong higher up the chain, but Secure Boot at least provides a foundation from which to secure the computer as a whole—at least, in theory!

The description of Secure Boot in the UEFI specification doesn't provide any mechanism to create a web of trust for its keys. Based on the UEFI specification alone, one might think that Secure Boot would be implemented in a site-by-site fashion; administrators at a site could sign the boot loaders that they use, thus locking out malware authors. Microsoft, however, included a requirement in its Windows 8 certification program for desktop and laptop computers that vendors ship computers with Secure Boot enabled. As a practical matter, this means that vendors must include Microsoft's keys on their computers, and unless computer manufacturers include other keys, only boot loaders signed by Microsoft will work.

Fortunately, things aren't quite as bad as this might seem. Microsoft has partnered with Verisign to manage boot loader signing. OS distributors and hardware manufacturers can pay $99 to Verisign to obtain the means to sign an unlimited number of binaries with Microsoft's key—or more precisely, a key that Microsoft uses to sign third-party binaries. (Microsoft uses another key to sign its own binaries.) Furthermore, for Windows 8, Microsoft required that x86 and x86-64 computers provide the means to completely disable Secure Boot, giving users control over the process. (ARM users aren't so lucky; Microsoft requires that Secure Boot can not be disabled on ARM systems bearing a Windows 8 logo.) For Windows 10, Microsoft dropped this requirement to the status of a suggestion; but as far as I know, all manufacturers continue to enable users to disable Secure Boot on their x86-64 computers. For those who are interested, this ALT Linux page describes the process of having Microsoft sign a binary in excruciating detail. (Note, however, that Microsoft and Verisign have become reluctant to let random individuals sign their EFI binaries with Microsoft's key. This privilege seems to now be reserved to trusted organizations.)

The initial public discussion of these matters was sparked by a blog post by Matthew J. Garrett, then a Red Hat developer, in September of 2011. Much of the initial discussion on Web forums and other public meeting places was downright panicky, and even a year later I saw occasional overwrought posts. By early 2015, the hysteria had died down and had been replaced by a combination of frustration when users run into problems and real-world knowledge of workarounds and even ways to employ Secure Boot for your own benefit. As described on this page, there are at least three ways to deal with Secure Boot: disable it, use a pre-signed boot loader, or use your own keys. (The last of these options is complex enough that I devote an entire page, Controlling Secure Boot, to this topic rather than do more than mention it on this page.) A fourth in-between option is possible with recent versions of Shim: You can enable Secure Boot but configure Shim to not enforce its rules.

Disabling Secure Boot

If you aren't convinced that Secure Boot will improve your system's security, or if it's simply causing you too many problems, you might want to disable the feature entirely. Given the fact that most malware targets Windows, this approach is most reasonable on computers that don't run Windows. (For an in-between approach, see the upcoming section on disabling Secure Boot only for Shim-launched programs.) You'll have to be comfortable navigating your firmware's setup screens to completely disable Secure Boot. Unfortunately, there's no standardization in where Secure Boot options might be located or what they might be called; therefore, I can't provide a procedure that will work for every computer. Instead, I describe the options on several computers I own that support Secure Boot: the ASRock FM2A88M Extreme4+ motherboard, the ASUS P8H77-I motherboard, the HP EliteDesk 705 mini-desktop computer, the Intel NUC DC53427 mini-desktop computer, the Lenovo IdeaPad U530 Touch laptop computer, the MSI A88X-G43 motherboard, and the Samsung Notebook 7 Spin laptop computer. I present details of all of these systems here in the hopes that one of them will be similar enough to whatever you're facing to be helpful. Most of these tools work in a similar way, despite significant differences in their graphics—you locate a menu (usually called Boot or Security) on which an option exists to enable or disable Secure Boot, and disable it. Sometimes another option must be set before this can be done, though; and sometimes names vary enough to create confusion.

Disabling Secure Boot on the ASRock FM2A88M Extreme4+ Motherboard

The first step to disabling Secure Boot on any computer is discovering how to enter the firmware setup utility. This motherboard, unlike some, presents a boot-time prompt to hit F11 to do this, whereupon you're greeted by the colorful main setup screen. Using the keyboard or mouse, you should select the Security tab, which produces the screen shown here:


The ASRock Secure Boot menu is easy to find.

To disable Secure Boot, click the Enabled button near the middle of the screen. You'll then be able to select Enabled or Disabled; select the latter. Once this is done, select the Exit tab and choose the option to exit while saving your changes.

Disabling Secure Boot on the ASUS P8H77-I Motherboard

The ASUS P8H77-I motherboard enables you to enter the setup utility by pressing Del or F2 during startup. The motherboard defaults to booting in what it calls EZ Mode, but to disable Secure Boot, you must first press F7 to enter Advanced Mode (unless of course you've already changed this default). That done, you can click the Boot tab and then scroll down to around the middle of the option list (which is likely to scroll—note the scroll bar in the screen shot), where you'll see an item called Secure Boot, as shown below. (Early versions of this model's firmware called it Security Boot Parameters.)
The ASUS Secure Boot menu is logically labeled.

Selecting the Secure Boot option opens another menu, in which you select the OS Type—ASUS seems to think that Secure Boot is a Windows-only feature, so Secure Boot is enabled when the OS Type is set to Windows UEFI mode and disabled when it's set to Other OS. (Earlier versions of this firmware used Other Legacy & UEFI to disable Secure Boot.)


ASUS considers Secure Boot active when the OS Type is set to
    Windows UEFI mode.

When you've made your changes, press the F10 key to save them and reboot.

Disabling Secure Boot on the Hewlett-Packard EliteDesk 705 Mini-Desktop Computer

The HP EliteDesk 705 has one of the more unusual Secure Boot configuration systems I've seen—although I've heard of some that are more quirky, at least in their user interfaces. To begin, you hit the Esc key when you power on or reboot to display the HP's Startup Menu, as shown here:


You hit the Esc key to obtain a menu to a variety of firmware
    sub-utilities on the HP 705.

From this menu, hitting F10 enters the computer setup utility, which has a text-only "GUI" that you manipulate via your cursor keys. From this menu, select Security -> Secure Boot Configuration, which produces the following screen:


You must verify your changes after you reboot by entering a
    four-digit passcode.

As you might expect, you should locate the Secure Boot option in the Secure Boot Configuration box and set it to Disabled. At this point, you must hit the F10 key to accept your changes! If you hit the Esc key, your changes will be ignored. You must then select File -> Save Changes and Exit to apply your new settings. Whenever you make a change to its Secure Boot configuration, the HP provides one more hurdle: When the system reboots, it asks for verification, as shown here:


The HP requires confirmation on the next boot whenever you change
    your Secure Boot settings.

In this example, you would type 8023, followed by the Enter key; the code is displayed to you on the screen.

Disabling Secure Boot on the Intel NUC DC53427HYE Mini-Desktop Computer

The Intel NUC DC53427HYE uses the F2 key as a signal to enter its setup utility. Like many modern computers, this setup utility is a colorful GUI affair (or at least, it can be; it also supports a more traditional "Classic Mode" option). The main GUI screen looks like this:


The main NUC firmware interface defaults to a heavily GUI
    appearance.

From this main menu, you must select Advanced Setup -> Boot, then click the Secure Boot tab. The resulting display looks like this:


The NUC provides a check box to enable or disable Secure Boot.

The NUC firmware's GUI uses a check box to enable or disable Secure Boot; you should uncheck the Secure Boot option to disable it. A red asterisk will then appear next to the check box, signifying an unsaved change to the configuration. When you click Exit, the firmware will ask if you want to save the changes; you must reply Yes (Y).

Disabling Secure Boot on the Lenovo IdeaPad U530 Touch Laptop

The Lenovo U530 has a firmware user interface that more closely resembles a traditional BIOS setup utility than do the interfaces of the other computers described here. To enter it, you can hit the Fn+F2 key as the computer boots. Once you've entered the setup utility, use the right arrow key to select the Security tab. The result looks like this:


Lenovo's UEFI user interface is a simple text-mode affair.

The Secure Boot option is clearly labeled and easily changed from Enabled to Disabled by using the arrow and Enter keys. When you're done, press Fn+F10 to save the change and exit.

Disabling Secure Boot on the MSI A88X-G43 Motherboard

To enter the firmware setup utility in the MSI A88X-G43, you press the Delete key while the system starts up. The result is an unusually flashy tool. Use the keyboard or mouse to select the large Settings item on the left of the screen. This yields a series of menus in the center. From these menus, select Advanced -> Windows 8/8.1 Configuration -> Secure Boot -> Secure Boot Support. The resulting screen looks like this:


MSI, like ASUS, seems to think that Secure Boot is a
    Windows-specific feature.

When you select the Secure Boot Support option, you can set it to Enabled or Disabled. Once you've done this, use the Esc key to back out of the menus to the top Settings menu, from which you can select Save & Exit, which in turn presents various exit options. You should pick the option to save your changes and reboot.

Disabling Secure Boot on the Samsung Notebook 7 Spin (740U5M-X01) Laptop

The Samsung Notebook 7 Spin (aka the Samsung 740U5M-X01) laptop has a firmware setup system that's designed to resemble the touch user interface of Windows 8 and later. This user interface is best navigated via the computer's touch-sensitive screen or using the more conventional touchpad or a mouse you plug into the USB port. Keyboard operation is possible, but I found it confusing.


Samsung's UEFI user interface is modeled after that of Windows 8.

From a logical perspective, disabling Secure Boot on this model is much like doing the job on any other computer—select the Boot menu (on the left of the screen) to reveal the options, which include one called Secure Boot Control. Once you turn this option Off, a new option line appears, OS Mode Selection. You can set this to CSM OS, UEFI OS, or CSM and UEFI OS. As a general rule, I recommend using UEFI OS, since that option should disable the CSM, which is how the computer boots BIOS-mode OSes. (See my page on the CSM for details on this matter.) Contrary to what you might think, setting CSM OS does not completely lock out EFI-mode boot loaders; I was still able to boot EFI-mode OSes with this option set. Presumably this option adjusts the preference given to BIOS-mode boot loaders compared to the CSM and UEFI OS option, but I haven't studied this matter in detail.

Once you've disabled Secure Boot in this way, select Save from the strip of options on the right of the screen. The computer will ask for confirmation. Once you give it, the computer will reboot.

Final Thoughts on Disabling Secure Boot

Of course, unless you happen to have one of these specific computers, or one with a nearly-identical UEFI implementation, chances are you won't see menus exactly like those I've just described. Fortunately, most are fairly straightforward, like these. A few present scary warnings against a red background if you attempt to disable Secure Boot. I've seen reports from people who've been unable to find Secure Boot options, but I don't know if this was because their computers hid them particularly well or because they were actually missing. Note that options sometimes don't appear until you've set other options in a particular way. The ASUS board's need to enter Advanced Mode is one example of this. The bottom line is that you may need to dig through multiple menus and try related options to locate your Secure Boot options.

Most Linux distributions will install just fine with Secure Boot active. Scenarios in which it makes the most sense to disable Secure Boot include the following:

Using a Signed Boot Loader

Using a boot loader signed with Microsoft's key is the simplest and most direct approach to booting with Secure Boot active; however, it's also the most limiting approach. Depending on what signed boot loader you use, you'll have to deal with boot-time confirmation whenever you try to boot an unsigned boot loader or be limited in what OSes and kernels you can boot. As of early 2023, I know of two signed boot loaders intended for use with Linux: Fedora's Shim program (which is also being used by Ubuntu, SUSE, Sabayon, ALT, and others) and the Linux Foundation's "PreLoader." As I write, several signed versions of Shim are available, as is at least one signed version of PreLoader. PreLoader, however, has been largely abandoned, so it's mainly of historical interest. I also describe how to verify a signed boot loader's signature to be sure it is what you think it is.

PreLoader works by calculating a hash of the follow-on binary and seeing if that hash is stored in a database held in NVRAM. Shim, by contrast, originally worked by checking to see if a binary had been signed with a cryptographic key; but recent versions support both this method and the same types of hashes that PreLoader uses. Thus, Shim is the more flexible tool. It's also more readily available in up-to-date and signed forms. Use of hashes can be good if you want to launch binaries that haven't already been signed (such as those you compile yourself or those delivered by a distribution maintainer that doesn't sign their binaries). On the other hand, using hashes necessitates that you register the hash of every unsigned binary you want to launch—potentially including every kernel and kernel module. This can be a hassle, and is where binaries signed with keys become superior, since you will have to register each key just once, at most. Because Shim is more flexible and more readily available in current signed form, Shim is generally the preferred program.

Using the Shim Program

Ideally, Shim is easy to use, in which case you need only read the Initial Shim Setup section—and you can even ignore parts of that section. If you have more advanced needs or run into problems, though, you may need to know how to sign your own binaries and verify your or others' binaries.

Initial Shim Setup

To adhere to the goals of Secure Boot, a Linux boot loader should provide authentication of the Linux kernel, and a Linux distribution should provide further security measures in the kernels it provides. Unfortunately, these goals are at odds with the open source philosophy of freedom and user control of their computers. Thus, a Secure Boot solution for Linux must balance these two goals. Fedora designed its Shim program to do just that. It does so by supporting three different types of keys (or hashes, in recent versions):

The whole point of Secure Boot is to prevent malware from gaining control of the computer. Therefore, when booting with Secure Boot active, Fedora 18 and later, Ubuntu 16.04 and later, and probably other distributions restrict actions that some Linux users take for granted. For instance, Linux kernel modules must be signed, which complicates use of third-party kernel drivers, such as Nvidia's and AMD/ATI's proprietary video drivers. More recent kernels may, if Secure Boot is active, also check that they were launched from a boot loader that honors Secure Boot, and shut down if this was not the case. (This check can prevent the use of ELILO, SYSLINUX, or other boot loaders that don't honor Secure Boot, even if the boot loader itself is signed.) To launch a locally-compiled kernel, you must sign it with a MOK and register that MOK with the system. (In both cases, you can register a hash rather than sign the binary; but this approach results in an ever-growing database in NVRAM, which is undesirable.) The extent of such restrictions is entirely up to those who develop and sign the boot loader launched by Shim and the kernel launched by that boot loader, though. Some distributions ship kernels that are relatively unencumbered by added security restrictions.

As a practical matter, if you want to use Shim, you have two choices: You can run a distribution that provides its own signed version of Shim, such as Fedora 18 or later or Ubuntu 12.10 or later; or you can run a signed version from such a distribution or from another source, add your own MOK, and sign whatever binaries you like. This first option is quite straightforward if you happen to want to use a distribution that ships with Shim, and it requires little extra elaboration. Ideally, it will Just Work. If it doesn't, that could indicate a bug in Shim or in your UEFI implementation. In such a case, disabling Secure Boot may be your best bet, at least in the short term as you investigate the cause of the problem.

If you're dual-booting with multiple Linux distributions or if you want to use a distribution that doesn't provide a pre-signed Shim, you'll have to jump through some extra hoops:

  1. Boot the computer. This can be a challenge in and of itself. You may need to use a Secure Boot–enabled Linux emergency disc, temporarily disable Secure Boot, boot using the Linux Foundation's PreLoader, or do the work from Windows. (An Ubuntu disc in its rescue mode can work for the first of these options.)
  2. The Shim you install can launch boot loaders and validate kernels included with the distribution from which you got it. Other boot loaders and kernels fall into one of two categories, each of which requires its own preliminaries:
  3. If it's not already installed, install Shim. Treat shim.efi or shimx64.efi like any other boot loader, as described in the EFI Boot Loader Installation page. (The first versions of Shim called their binaries shim.efi, but for several years now, shimx64.efi has been the more common name on x86-64 systems.)
  4. Along with Shim, install MokManager. This program should come with Shim, and should reside, under the name MokManager.efi (for very old versions) or mmx64.efi (or a variant for non-x86-64 systems), in the same directory as the Shim binary. As the name suggests, this program manages MOKs. I describe its use shortly.
  5. If necessary, sign the follow-on boot loader, as well as any unsigned kernel you want to launch. This step is necessary only if the follow-on boot loader and kernel are not already signed—for instance, if you compiled them yourself.
  6. If Shim's follow-on boot loader is not already installed, copy it to the filename grubx64.efi in the same directory that holds shimx64.efi. (If your Shim binary lacks the x64 filename component, chances are it will try to launch grub.efi rather than grubx64.efi. Adjust your filenames as necessary.) Shim is designed to launch GRUB 2, but it can launch other boot loaders, provided they're named grubx64.efi. Note, however, that most older follow-on boot loaders, such as ELILO, won't honor the Secure Boot settings. rEFInd and gummiboot/systemd-boot are designed to honor Secure Boot settings. Note that you need not register the follow-on boot loader directly with the firmware by using efibootmgr. Such a registration might cause warnings of Secure Boot failures or even system freezes on some computers.
  7. If you need to use MOKs, you may optionally import them now, using the mokutil program. Doing so will simplify your post-reboot MOK enrollment, but will take a bit more effort at this point. See the upcoming section, Using mokutil, for details. If you don't import MOKs using mokutil, be sure to copy them to the ESP at this point. You'll need to copy the files that have .cer or .der filename extensions.
  8. Reboot. With any luck, you'll see a simple text-mode user interface with a label of Shim UEFI key management. This is the MokManager program, which Shim launched when your boot loader failed verification because its key is not yet enrolled.
  9. Press your down arrow key and press Enter to select Enroll key from disk. The screen will clear and prompt you to select a key, as shown here:
    Recent versions of MokManager provide a somewhat more
    user-friendly user interface.
  10. (Early versions of MokManager used a more primitive user interface with white and yellow text on a black background. If this is what you see, some details will differ, but the program should still work. You might want to find more recent programs for the better user interface and other updated features, though.)
  11. Each of the lines with a long awkward string represents a disk partition. Select one and you'll see a list of files and directories. Continue selecting subdirectories until you find the public key file you obtained or created and copied to the ESP earlier.
  12. Select the public key file. MokManager will ask for verification that you want to enroll the key. Provide it.
  13. Back out of any directories you entered and return to the MokManager main menu.
  14. Select Continue boot at the main menu.

At this point the computer may boot into its default OS, reboot, or perhaps even hang. When you reboot it, though, the boot program you installed under the name grubx64.efi should start up in Secure Boot mode. Depending on its capabilities, it might boot any kernel it can boot as if Secure Boot were disabled, launch only boot loaders signed with the platform's Secure Boot keys, or launch EFI programs or kernels signed with regular Secure Boot keys or your own MOK.

Recent versions of Shim and MokManager support enrolling hashes as well as keys. This process works much like the one just described, but you must select the option to enroll a hash rather than the one to enroll a key. You must then select the binary you want the computer to trust, such as the grubx64.efi binary in the same directory as shimx64.efi and mmx64.efi. To enroll the hash of a kernel, the kernel must be on a partition that the EFI can read. Since Linux filesystems are not a standard part of the EFI's repertoire, you must either copy the kernel to the ESP or use an EFI filesystem driver, such as one that comes with rEFInd, to give the EFI access to the Linux partition. I recommend using the hash-signing feature sparingly, if at all, because NVRAM space to store hashes and keys is limited; you don't want to consume it all with hashes for every boot loader, kernel, and potentially even kernel module you'll use over your computer's lifetime. Instead, use it only for boot loaders or related programs that are unlikely to change often. The advantage of using hashes, of course, is that you don't need to sign your binaries, which can be a hassle, as described next.

Signing Your Binaries

If you want to boot a kernel you compile yourself or launch an OS that doesn't sign its boot loader, you'll need to either sign the relevant binaries or enroll their hashes. With recent versions of Shim, though, you will also need to make the binary compatible with the Secure Boot Advanced Targeting (SBAT) standard. In fact, you must begin with that step.

Adding SBAT Support

SBAT is part of the response to the Boot Hole vulnerability. It involves, among other things, embedding software version numbers in their binaries. If you're dealing with recent pre-compiled binaries from major publishers (such as the major distribution publishers), chances are their binaries already have SBAT support — but they're also probably already signed. Older binaries, binaries from oddball sources, and binaries you compile yourself may need to be enabled to support SBAT.

The key to SBAT is a comma-separated value (CSV) file that holds information on the program's component name, component generation number, vendor name, package name, package version, and URL. Each line of the CSV file holds those seven fields, and each CSV file holds at least two lines — the first for SBAT itself and the second for the program. Additional lines may be added to reference re-packagers. All of this is described in detail in the SBAT documentation. As an example, consider the following file (let's call it example.csv):

sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
brug,1,Free Software People,brug,2.04,https://www.example.org/software/brug/
brug.bowler,1,The Bowler Project,brug2,2.04-31.bh33,https://src.example.com/rpms/brug

The first line of the CSV file should be the same for all programs, at least until a change is made to the SBAT specification. The second line of this example describes the fictitious BRUG program, version 2.04, which was originally written by the fictitious Free Software People. The third line identifies the re-packaged version for the fictitious Bowler Project Linux distribution.

If you're signing your own program, you'll need to create or modify a CSV file. If it's your own work, then your file will likely have two lines. If you're recompiling a program you found elsewhere, then you should probably add a line to its existing SBAT CSV file (if it has one) or create a three-line file that describes the original source and your own modification.

Suppose you create a CSV file, called example.csv, and you want to embed it in the examplex64.efi program file. The command to do so is fairly straightforward:

$ objcopy --set-section-alignment '.sbat=512' --add-section .sbat=example.csv \
   --adjust-section-vma .sbat+10000000 examplex64.efi

This command, however, may fail if an existing SBAT section exists. Details vary from one version of objcopy to another; but objcopy version 2.38, as distributed with Ubuntu 22.04, produces an error like this:

objcopy: stRh7k4f: can't add section '.sbat': file in wrong format

If you see this error, or one with a more helpful error message that implicates the same cause, then you should consider whether you want to replace the existing SBAT section. Chances are the existing SBAT section is appropriate and should not be modified. If you're certain you want to do so, however, you can place the --remove-section .sbat option before the --add-section option, as in:

$ objcopy --set-section-alignment '.sbat=512' --remove-section .sbat \
   --add-section .sbat=example.csv --adjust-section-vma .sbat+10000000 examplex64.efi

Note that, whether or not you use the --remove-section .sbat option, this command changes the existing examplex64.efi file; it does not create a new file! If you check the file's size before and after adding SBAT support, it should be a little larger afterwards. As the command's syntax suggests, this support is added to a section called .sbat, and some documentation refers to it as such. You can also check for this support by using the objdump command:

$ objdump -j .sbat -s examplex64.efi

examplex64.efi:     file format pei-x86-64

Contents of section .sbat:
 989680 73626174 2c312c53 42415420 56657273  sbat,1,SBAT Vers
 989690 696f6e2c 73626174 2c312c68 74747073  ion,sbat,1,https
 9896a0 3a2f2f67 69746875 622e636f 6d2f7268  ://github.com/rh
 9896b0 626f6f74 2f736869 6d2f626c 6f622f6d  boot/shim/blob/m
 9896c0 61696e2f 53424154 2e6d640a 62727567  ain/SBAT.md.brug
 9896d0 2c312c46 72656520 536f6674 77617265  ,1,Free Software
 9896e0 2050656f 706c652c 62727567 2c322e30   People,brug,2.0
 9896f0 342c6874 7470733a 2f2f7777 772e6578  4,https://www.ex
 989700 616d706c 652e6f72 672f736f 66747761  ample.org/softwa
 989710 72652f62 7275672f 0a627275 672e626f  re/brug/.brug.bo
 989720 776c6572 2c312c54 68652042 6f776c65  wler,1,The Bowle
 989730 72205072 6f6a6563 742c6272 7567322c  r Project,brug2,
 989740 322e3034 2d33312e 62683333 2c687474  2.04-31.bh33,htt
 989750 70733a2f 2f737263 2e657861 6d706c65  ps://src.example
 989760 2e636f6d 2f72706d 732f6272 75670a    .com/rpms/brug. 

With an .sbat section added to your EFI binary, you can proceed to actually signing it....

REALLY Signing Your Binaries

Signing the binaries is preferable to enrolling their hashes if you do this type of thing even remotely often. To begin this process, you must first prepare a set of keys with openssl, as described earlier. You'll also need the sbsigntool package, which comes standard with some distributions. If yours isn't one of them, you can obtain binaries for several distributions from the OpenSUSE Build Service or download the source code from this page.

Once you've installed the sbsigntool package and created keys, you can sign a binary with a command like the following:

$ sbsign --key ~/efitools/MOK.key --cert ~/efitools/MOK.crt \
         --output vmlinuz-signed.efi vmlinuz.efi
warning: file-aligned section .text extends beyond end of file
warning: checksum areas are greater than image size. Invalid section table?

This example signs the vmlinuz.efi binary, located in the current directory, writing the signed binary to vmlinuz-signed.efi. Of course, you must change the names of the binaries to suit your needs, as well as adjust the path to the keys (MOK.key and MOK.crt).

This example shows two warnings. I don't claim to fully understand them, but they don't seem to do any harm—at least, the Linux kernel binaries I've signed that have produced these warnings have worked fine. (Such warnings seem to be less common in 2015 and later than they were a couple of years before then.) Another warning I've seen on binaries produced with GNU-EFI also seems harmless:

warning: data remaining[1231832 vs 1357089]: gaps between PE/COFF sections?

On the other hand, the ChangeLog file for GNU-EFI indicates that binaries created with GNU-EFI versions earlier than 3.0q may not boot in a Secure Boot environment when signed, and signing such binaries produces another warning:

warning: gap in section table:
    .text   : 0x00000400 - 0x00019c00,
    .reloc  : 0x00019c91 - 0x0001a091,
warning: gap in section table:
    .reloc  : 0x00019c91 - 0x0001a091,
    .data   : 0x0001a000 - 0x00035000,
gaps in the section table may result in different checksums

If you see a warning like this, you may need to recompile your binary using a more recent version of GNU-EFI.

If you're using rEFInd or gummiboot/systemd-boot, you must sign not just the boot manager binary, but also the binaries that it launches, such as rEFInd's filesystem drivers, Linux kernels, or ELILO binaries. If you fail to do this, you'll be unable to launch the boot loaders that the boot manager is intended to launch. (Failure to sign EFI filesystem drivers means you won't be able to read your kernels from Linux filesystems.) rEFIt can't "talk" to Shim, and so can't launch follow-on boot loaders and kernels that are signed only with MOKs. Stock versions of ELILO, SYSLINUX, GRUB Legacy, and older builds of GRUB 2 don't check Secure Boot status or use EFI system calls to load kernels, so even signed versions of these programs will launch any kernel you feed them. This defeats the purpose of Secure Boot, at least when launching Linux. Most recent versions of GRUB 2 communicate with Shim for authenticating Linux kernels and so will refuse to launch a Linux kernel that's not been signed, at least when GRUB is launched via Shim.

Once you've signed your binaries, you should install them to your ESP much as you would an unsigned EFI binary. Signed binaries should work fine even on systems on which you've disabled Secure Boot. Note, however, that anything launched directly from the firmware (that is, registered with efibootmgr or launched using the fallback filename) must be signed with a key in the firmware. Boot loaders signed by a MOK can be launched directly from Shim or from rEFInd (if rEFInd is launched from Shim).

As a side note, the pesign utility, available from git://github.com/vathpela/pesign.git, is an alternative to sbtools; however, because efitools is coded to use sbtools, I've barely looked at pesign. You might want to check it out if you have problems with sbtools, though.

Verifying Your Boot Loaders

You can use the Secure Boot signature on an EFI binary to verify the authenticity of the binary. This is useful both in diagnosing boot problems (since an improperly-signed binary won't boot) and to check that the binary comes from the claimed source.

To verify a binary, you'll need two things: A public key file matched to the private key that was used to sign the binary; and a program called sbverify. As noted earlier, I provide a collection of public key files with rEFInd; see the rEFInd git repository for access to individual keys. Note that for verification, you'll need a text-mode PEM file with a .crt extension, not the .cer or .der file needed when adding the key to the MOK list. Most public key files for Secure Boot are distributed in both forms, but if you have only a .cer/.der file, it's possible to convert it to .crt form with openssl, like this:

$ openssl x509 -in fedora-ca.cer -inform der -out fedora-ca.crt

This example converts the fedora-ca.cer file to fedora-ca.crt, which you can use to verify the authenticity of signed Fedora binaries.

The sbverify program is available with some distributions, such as Ubuntu, as part of the sbsigntool package. OpenSUSE binaries are available from the OpenSUSE Build Service. If necessary, you can obtain the source code from various sites. If you have git installed, typing git://kernel.ubuntu.com/jk/sbsigntool should pull it down.

Once you've installed sbsigntool you can use the sbverify command:

$ sbverify --cert keys/refind.crt refind_x64.efi
Signature verification OK

This example shows a successful verification of the refind_x64.efi binary against the keys/refind.crt public key. Failures are typically preceded by messages that describe what went wrong, often using technical language. Typically, binaries are either not signed or they're signed with a key other than the one whose public counterpart you tried to use. if you're uncertain of what key was used to sign a binary, you may be able to find a clue by using the --list option to sbverify, like this:

$ sbverify --list /boot/efi/EFI/opensuse/grub.efi
signature 1
image signature issuers:
 - /CN=openSUSE Secure Boot CA/C=DE/L=Nuremberg/O=openSUSE Project/emailAddress=build@opensuse.org
image signature certificates:
 - subject: /CN=openSUSE Secure Boot Signkey/C=DE/L=Nuremberg/O=openSUSE Project/emailAddress=build@opensuse.org
   issuer:  /CN=openSUSE Secure Boot CA/C=DE/L=Nuremberg/O=openSUSE Project/emailAddress=build@opensuse.org

This example shows that the binary bears a signature indicating it is associated with OpenSUSE. Of course, this information could be misleading, but that's the point — by checking against a known-good public key file, you can verify that the binary is legitimate. (The --list operation by itself does not do this; you'll need to use --cert to verify the signature. The --list option can simply help you figure out which key file might match.) Also, note that some distributions have multiple key files, either because they're used for different things or because one key has expired and been replaced by a newer one.

Using mokutil

Although you can use MokManager to enroll a MOK from the EFI, its use is not intuitive to the less technically-inclined. To help simplify matters, and to enable checking on the status of MOKs and other EFI key databases, the mokutil program exists. This program has many options, and I cover just a few of them here; type man mokutil to read about more of them. This program might not be installed by default, so you may need to install it, typically from a package of the same name.

The use of mokutil that's most relevant to this page is to import a MOK. In this context, importing refers to storing a MOK in the computer's NVRAM, along with a flag to tell Shim and MokUtil that the MOK is there and ready to be enlisted when you next reboot the computer. To do this, you use the -i option to point to the .cer/.der file that holds the public key:

# mokutil -i keys/centos.cer
input password:
input password again:

Be sure to remember the password you type, since you'll need it when you reboot. (You won't need this password beyond this point, though.) You can check the current imports by typing mokutil --list-new, and revoke all current imports by typing mokutil --revoke-import.

When you reboot the computer, MokUtil should appear, as described earlier, in Initial Shim Setup; but when you press a key to manage your MOKs, the menu will include a new option, Enroll MOK. Selecting that option is much like picking a MOK from the disk; but when you approve the installation, you will have to enter the password you typed when using mokutil.

As noted earlier, mokutil has many options, which enable it to do many more things. A few highlights of these include the following:

Options that change the NVRAM contents must be typed as root or using sudo, and they require you to enter a password. Upon reboot, MokManager asks for confirmation that you want to perform the requested operation. If you decline, it is forgotten; you'll have to re-enter the relevant mokutil command from Linux, or perform the operation in some other way, if you later decide you really do want to do it.

Using the Linux Foundation's PreLoader

The Linux Foundation's solution to the Secure Boot problem, known as PreLoader, shares some significant similarities with Shim, but it's also different in two key respects:

To use PreLoader, follow these steps:

  1. Boot the computer. As with installing Shim, this step can be a challenge. You may need to temporarily disable Secure Boot, use a Secure Boot-enabled emergency disc, or do the work from Windows.
  2. Obtain PreLoader. Pre-signed binaries are available from its download site. Note, however, that these pre-signed binaries were released in 2013—quite old by computer software standards. The program has been updated since then, but I'm not aware of any more recent signed binaries. PreLoader's author, James Bottomley, has told me via e-mail that the initial signed PreLoader was meant mainly as a demonstration of Linux using Secure Boot and a test of Microsoft's signing process. Given the popularity of Shim, he doesn't plan to release new signed versions of PreLoader. (He remains active in the area, though; he maintains the efitools set of utilities, which are helpful when taking full control of Secure Boot on a computer.)
  3. Install the PreLoader as described on the EFI Boot Loader Installation page. You'll probably want to install it in your default boot loader's directory.
  4. Copy the HashTool.efi file from the PreLoader package to the same directory as the PreLoader binary.
  5. Rename your default boot loader as loader.efi, in the same directory as PreLoader.
  6. Reboot and, if necessary, select PreLoader as your boot option. PreLoader should launch, but it will probably complain that it couldn't launch loader.efi. It will then launch HashTool, which is the program that PreLoader uses to store information (hashes) on the programs you authorize.
  7. In HashTool, select the Enroll Hash option.
  8. Browse to and select the loader.efi program file. HashTool asks for confirmation; respond Yes.
  9. As a practical matter, you'll now want to repeat the previous two steps for every boot loader you might want to launch from the first one. For instance, if you're using gummiboot/systemd-boot or rEFInd to launch Linux kernels, you'll want to select each of those kernels for enrollment. This won't be necessary if you're using ELILO, GRUB Legacy, or some versions of GRUB 2 to launch Linux kernels, but you may need to enroll a hash for a chainloaded boot loader launched from GRUB.
  10. Select Exit or Reboot System from the HashTool main menu.

At this point, your computer should reboot into your regular boot loader, and it should be able to launch kernels and follow-on boot loaders as if they were signed with your platform's Secure Boot key—provided you registered those binaries with HashTool! This last point is an important one. If you're using rEFInd or gummiboot/systemd-boot to launch Linux kernels, you'll need to register each new kernel as you (or your distribution's package system) installs it. This fact also means that you must provide a way to launch HashTool. ELILO can't do this, but you can configure rEFIt, rEFInd, gummiboot/systemd-boot, GRUB Legacy, and GRUB 2 to launch HashTool. In fact, rEFInd 0.6.7 and later recognize the HashTool.efi binary and provide a tag for it on the main screen.

Behind the scenes, the PreLoader is actually using the same MOK list that Shim uses; PreLoader is simply using it to store program hashes rather than keys.

Replacing or Supplementing Your Firmware's Keys

It's possible to replace Microsoft's keys with your own, which enables you to gain the benefits of Secure Boot without using either Shim or PreLoader. This can be a useful approach if you want the benefits of Secure Boot but don't want to trust Microsoft or any of the others who distribute binaries signed with Microsoft's keys. It's also possible to add your own keys to those built into the firmware, without removing Microsoft's keys. This is useful if Shim or PreLoader malfunctions or if you want to use a boot program, such as rEFIt, that doesn't work well with Shim. Broadly speaking, there are three main steps to this process: generating your own keys, signing your binaries, and installing your keys in your firmware. The first two of these steps are also necessary if you want to sign your own binaries for use with Shim.

Unfortunately, there are significant model-to-model differences in Secure Boot implementations and available tools, which means that describing this approach to managing Secure Boot is complex. Thus, I've written a separate page covering the process in detail.

Replacing your firmware's keys doesn't take much more effort than using Shim if you would need to sign your own binaries for some reason—say, if you're using a distribution such as Gentoo that doesn't provide pre-signed binaries. It also has some security advantages, particularly if you don't need Microsoft's keys. On the other hand, it's a lot more hassle than using Shim if you just want to get a Shim-using distribution up and running quickly. You will also lose the benefits of SBAT — sooner or later, new vulnerabilities will be discovered and blocked with SBAT; but if you bypass Shim by using your own keys, you won't be able to easily block the affected programs unless you re-incorporate Shim into the process. Overall, I recommend this approach only for those who are fairly technically inclined.

Using Secure Boot While Disabling Shim's Enforcement

I'm not sure when this feature was added, but recent versions of Shim enable an odd halfway measure: You can leave Secure Boot enabled on the computer but tell Shim to not enforce its rules when launching follow-on boot programs. This option might be useful if you want to prevent malware from inserting itself in Windows or other non-Linux OSes, but you want to be able to boot a locally-compiled kernel or use a boot program (such as gummiboot/systemd-boot) that lacks explicit Secure Boot support.

To use this feature, you should follow these steps:

  1. Boot Linux.
  2. Use the mokutil program and its --disable-validation option. (If you launch it with sudo, you may be asked for your account password.) You will then have to enter a MOK administration password (twice):
    # mokutil --disable-validation
    password length: 8~16
    input password: 
    input password again: 
    
  3. Reboot the computer. It should boot into the MokManager program.
  4. You should be greeted by a screen that advises you to press a key to begin MOK management. Do so.
  5. You will now have four choices: Continue boot; Change Secure Boot state; Enroll key from disk; or Enroll hash from disk. Select Change Secure Boot state.
  6. The tool will now ask for your password. With recent versions, it may do so strangely, by asking for characters out of order.
  7. Once MokManager is satisfied with your password skills, it presents a simple No/Yes option, with no explanatory prompt. Select Yes.
  8. MokManager will now show the options Reboot; Enroll key from disk; and Enroll hash from disk. Select the Reboot option.

Once you reboot, Shim should stop enforcing Secure Boot rules; but they will still apply to programs and OSes that are not launched via Shim. You can verify this state by using the --sb-state option to mokutil:

$ mokutil --sb-state
SecureBoot enabled
SecureBoot validation is disabled in shim

If you launch rEFInd from Shim, its information screen will claim that Secure Boot is enabled; but it will launch any EFI binary that appears in its menu, whether or not it's signed, and whether or not the signature is valid for any Secure Boot key or MOK that's present on the system.

Revoking Keys and Hashes

As described in greater detail in the Controlling Secure Boot page, Secure Boot relies on several small databases of keys and hashes stored in NVRAM. In order to address the possibility of security bugs in boot programs, one of these databases, known as the dbx, contains a list of keys and hashes for binaries that are forbidden from running. If a bug is discovered in a particular binary, its hash can be added to the dbx to prevent it from running. (Its key could be added to cover everything signed with that key, but this may impact other binaries that are not affected by the problem.)

Adding items to the dbx requires that the new keys be signed by another key. In practice, this other key is usually controlled by Microsoft, so Microsoft is the de facto controller of the dbx, and these additions are usually carried out through updates to Windows, or conceivably other OSes' updates that deliver the updates Microsoft provides. In the years since Secure Boot was introduced, a steady trickle of such Microsoft-approved dbx additions have occurred.

In early 2020, a vulnerability in GRUB 2 was discovered, known as Boot Hole, which led to a deep scrutiny of GRUB 2, which discovered a total of eight distinct GRUB 2 vulnerabilities. This situation posed a problem: Because so many Linux distributions have released so many signed GRUB 2 binaries, the number of dbx entries required to keep them from running threatened to overwhelm the available space in computers' NVRAM.

The solution, developed by major Linux distribution developers in conjunction with Microsoft, is to use an updated Shim, which incorporates its own dbx-like features, and to block earlier versions of Shim (which are less numerous than the affected GRUB binaries) to the UEFI's own dbx. The new mechanism relies on the SBAT, as described earlier, to enable newer versions of Shim to block large numbers of compromised programs, once they've been identified, without overwhelming NVRAM storage constraints.

This solution does have a negative consequence, though: Older versions of Shim will stop working as soon as the computer's dbx is updated. This is unlikely to be a problem for users of popular Linux distributions who use those distributions alone or who dual-boot with Windows using GRUB 2; such computers' GRUB 2 binaries will be (or most likely have already been) updated along with their Shim binaries, with any luck before the UEFI's dbx is updated, thus keeping everything working. This solution may affect people who have manually installed Shim to boot distributions that don't normally use it, or who use Shim in association with boot managers or boot loaders such as rEFInd; if these non-standard programs' Shim binaries are not updated but Windows installs a dbx update that prevents Shim from running, the manually-installed boot programs are likely to stop working.

The solution should be simple: Update the old shim.efi or shimx64.efi binary that's been added to the UEFI dbx with a new version. This may also require updating the follow-on program, though. If nothing else, because newer Shim binaries require SBAT support in follow-on programs, those programs must include SBAT sections, which older programs lack. In theory, another solution is to prevent updates to the UEFI dbx. In practice, this is an undesirable solution, since it leaves the computer vulnerable to any exploits that might involve the affected GRUB 2 binaries. Replacing all your Secure Boot keys, as described on the next page, might or might not leave you vulnerable, as described on that page.

Note also that there's always the possibility of vulnerabilities in rEFInd, systemd-boot, or other boot programs. These programs are not as popular as GRUB 2 and so have not seen the sort of intense audit that GRUB 2 experienced in 2020 and early 2021, so security bugs could be lurking in them. Of course, the fact that they're less popular, and are rarely signed by distribution maintainers, means that they're less likely to be vectors of attack — but this is basically "security through obscurity," which is unreliable at best.

For more on this topic, see this blog post, which covers the issue from an Ubuntu perspective. Some details vary from one distribution to another, but all Linux distributions that provide signed GRUB 2 binaries are affected, and the solution is similar for all of them.

Concluding Thoughts

In early 2023, Secure Boot is a somewhere between a non-issue and a major hassle for Linux users. Although Secure Boot has the potential to improve security, Linux has historically not been plagued by viruses, so it's unclear that Secure Boot is a practical benefit for Linux-only computers, although it does offer theoretical benefits. If you dual-boot with Windows, though, you may want to keep Secure Boot enabled. Using the Shim program looks like the best way to do this for users of Fedora, OpenSUSE, Ubuntu, and other distributions that support Shim. If you're using another distribution or are having trouble booting multiple distributions, disabling Secure Boot is the easiest way to deal with it. Signing your own boot loaders to use the native Secure Boot mechanism and your own key set is another alternative, and one that provides you with the greatest security and flexibility. This approach is the hardest one to implement, particularly if your computer's firmware setup utility lacks the ability to add keys.


Go on to "Controlling Secure Boot"

Return to "Managing EFI Boot Loaders for Linux" main page


copyright © 2012–2023 by Roderick W. Smith

If you have problems with or comments about this web page, please e-mail me at rodsmith@rodsbooks.com. Thanks.

Return to my main Web page.