Introduction

New utilities from Oracle provide a straightforward way to update the UEFI (Unified Extensible Firmware Interface) Secure Boot database for VMs running Oracle Linux. This blog provides a brief overview of Secure Boot and discusses how the new utilities can be used to keep a VM up-to-date with the latest known vulnerabilities and to update the signing certificates stored in a Secure Boot database in a VM.

Secure Boot Overview

Secure Boot is a UEFI standard mechanism to help ensure software is validated prior to being executed. When Secure Boot is enabled, every binary loaded during boot is first validated against known trusted cryptographic keys or hashes stored in the UEFI firmware Secure Boot database. If a binary in the boot chain fails validation, the boot fails. The “keys” in the firmware database are typically public signing certificates from manufacturer(s) such as Microsoft. In order to pass validation, a binary either needs to be signed with the private key associated with one of the public certificates in the database or a cryptographic hash for the binary must be stored in the database. The UEFI firmware Secure Boot database is actually composed of several UEFI variables stored in the computer’s non-volatile flash memory. These variables are named “PK”, “KEK”, “db” and “dbx”. The PK and KEK variables are used to control ownership and access to the Secure Boot database itself, which is not the focus of this blog and thus are not discussed further. The db and dbx variables are where the public certificates and hashes are stored that are used for validation. More specifically, the db variable contains the certificates and hashes for known secure software and, conversely, the dbx variable contains hashes (and possibly certificates) for software which has been found to contain a vulnerability. Therefore to pass validation, a binary must have a match in the db and no match in the dbx. So, as you can see, it is the db and dbx variables which fundamentally determine what software will be able to run under Secure Boot. It is the management of the db and dbx variables that are the focus of the rest of this blog.

Secure Boot in a VM

Let’s take a closer look at how Secure Boot works with (x86_64 QEMU-based) VMs. For VMs, the UEFI firmware is provided by the OVMF (Open Virtual Machine Firmware) package. The VM’s QEMU process is passed an argument specifying an OVMF_CODE.fd file from the OVMF package to provide the UEFI firmware image binary. The OVMF package also provides an associated OVMF_VARS.fd template file. This OVMF_VARS.fd file provides simulated flash memory storage and is pre-formatted as such. A unique copy of the OVMF_VARS.fd template file is maintained for each VM, which is also passed to QEMU. The Oracle Linux OVMF package also provides a OVMF_CODE.secboot.fd and OVMF_VARS.secboot.fd variant to support Secure Boot for VMs. This variant has Secure Boot enabled by default in the firmware image. The OVMF_VARS.secboot.fd file has Secure Boot variables preset with the latest certificates/hashes required to boot the latest versions of Oracle Linux and contains hashes in the dbx for the latest known vulnerabilities at the time the OVMF package was released.

So from this, obvious questions quickly arise: 1. As new vulnerabilities are found in the future, how can an existing Secure Boot database in a VM be updated to include the newly found vulnerabilities? 2. How do I add my own signing certificates to the Secure Boot database for custom self-signed software?

Updating a VM Secure Boot database

Up until now, to update a Secure Boot database in a VM, you had to use the same “in-band” method as used on bare metal machines: the VM was booted to the OS, update file(s) were transferred to the VM’s filesystem and a utility, such as efi-updatevar, was used to write the updates to the UEFI variables using UEFI runtime variable services. This was a laborious process, as it required an admin to run an update from each VM OS individually. Imagine having to do this for a thousand VMs! It was possibly dangerous as well, as it may be risky to boot a VM which potentially contains a newly found vulnerability in order to update its Secure Boot database.

A new, easier way to update a Secure Boot database in a VM

It would be much easier (and safer) to update a Secure Boot database in a VM directly from the hypervisor/host without having to boot the VM. Since a Secure Boot database in a VM is stored as a disk file – i.e. OVMF_VARS.fd as discussed above – this should be possible. And, now, it is. The new ovmf-vars-mgr utility found in the latest Oracle Linux edk2-tools package (version 1.5.0+) does exactly that. It allows an administrator to update variables in a Secure Boot database in a VM directly “out-of-band” from the hypervisor/host without having to boot the VM. The following examples demonstrate the power of the ovmf-vars-mgr utility.

Example 1: Keeping a Secure Boot database in a VM up-to-date with respect to newly found vulnerabilities

As new vulnerabilities are discovered (such as with the recent “boothole” vulnerability in 2020), new dbx variable Secure Boot update files are published on the uefi.org website. These files contain certificates and hashes for all past and present software which contain known vulnerabilities. Using the new ovmf-vars-mgr utility, an administrator can easily apply the latest uefi.org dbx update file to a VM like so:

[from the hypervisor/host]

# ovmf-vars-mgr --var dbx --write --vars-file <path_to_the_Guest_VM_VARS_file> < dbxupdate_x64.bin

This will cause the dbx variable in the specified OVMF_VARS.fd file to be updated with the certificates/hashes found in dbxupdate_x64.bin. The VM is thus now prevented from booting software containing the latest known vulnerabilities. An administrator could apply dbx updates easily and efficiently in this manner to multiple VMs using a script executed from the hypervisor/host.

Example 2: Adding a new signing certificate to a Secure Boot database in a VM

Say, for example, an administrator wanted to use a custom version of iPXE as part of a VM’s boot process and boot the VM in Secure Boot mode.

This would involve four basic steps:

  1. Build the custom iPXE UEFI binary.
  2. Create a Secure Boot signing key – this will produce both a public certificate and a private signing key.
  3. Sign the iPXE binary using the private signing key.
  4. Add the public certificate to the Secure Boot database in a VM.

The details of steps 1-3 are beyond the scope of this blog. The openssl command is often used to generate signing keys and UEFI binaries are typically signed using the pesign utility.

Step 4 is where the new Oracle utilities come in. Unfortunately, we cannot just write the public certificate directly to the database because it needs to be converted into the proper format first, i.e. a “EFI Signature List” or .esl file. A second utility included in the latest Oracle edk2-tools, efi-siglist-gen, does precisely this. So, step 4 requires running these two commands:

# efi-siglist-gen public_key.cer > public_key.esl  # public certificate must be a .cer (DER format) file.
# ovmf-vars-mgr --var db --append --vars-file <path_to_the_Guest_VM_VARS_file> < public_key.esl

At this point, the Secure Boot database in a VM should contain the new public key and thus the custom iPXE binary can be used as part of the boot process under Secure Boot!

Important notes about the new Oracle utilities

  1. ovmf-vars-mgr cannot be used on a running VM, i.e. A VM MUST be shutdown prior to running ovmf-vars-mgr on the VM’s OVMF_VARS.fd file to avoid possible variable corruption. Also, ovmf-vars-mgr should not be used on a OVMF_VARS.fd file whose associated VM was not shutdown down cleanly. No checks are made by ovmf-vars-mgr about the state of the associated VM, so be careful!

  2. Since ovmf-vars-mgr is used out-of-band directly on the OVMF_VARS.fd file, the normal in-band checks against the PK and KEK variables (which protect against unauthorized access to the Secure Boot database) are bypassed.

  3. The ovmf-vars-mgr utility has the ability to read, write, append, and erase all four Secure Boot variables (PK, KEK, db and dbx). See the included ovmf-vars-mgr.md file from the edk2-tools package for more information and examples.

  4. The efi-siglist-gen utility has the capability to take an optional “owner GUID” (specified in a file) along with a public certificate. See the included efi-siglist-gen.md file from the edk2-tools package for more information and examples.

Summary

Until now, updates to a Secure Boot database in a VM were a difficult process requiring an in-band method from the VM OS. Now, with new utilities from Oracle, updates can be made from the hypervisor/host directly to a VM’s OVMF_VARS.fd file making the update process much more manageable.

Further reading