Introduction
UEFI Secure Boot
UEFI Secure Boot is a security feature designed to provide an infrastructure for UEFI Image load-time authentication. It authenticates OS Loaders, UEFI drivers, and applications. The Platform Owner manages the platform’s security policy and can check the integrity and security of a given UEFI Image.
Linux
Mainstream distributions like Ubuntu or Fedora took the approach of using a
small, signed bootloader called shim
, which is pre-signed by Microsoft. Shim
loads the bootloader, which is verified against a certificate embedded in shim,
and the bootloader then loads the Linux kernel, also ensuring it is signed and
trusted. To put it simply, they can sign their kernel themselves, instead of
having to ask Microsoft to sign each kernel update.
Please see this blogpost for more information on this specific subject.
UEFI Secure Boot status on FreeBSD - brief summary
In short, the FreeBSD wiki proposes two stages of UEFI Secure Boot implementation.
First would be to enable booting the system with Microsoft-signed shim and a FreeBSD-signed EFI loader, while also offering users to generate their own keys and certificates.
The second stage would involve having all of the drivers and kernel modules to be signed and authorized, resulting in a locked-down system, as is now possible in the upstream Linux kernel
As of the time of writing this post, the first stage is mostly complete. It is possible to create and sign a complete EFI executable containing the bootloader and the FreeBSD kernel, which can be booted using UEFI Secure Boot.
Now, let’s analyze what the said executable consists of.
FreeBSD UEFI boot process
The regular UEFI boot process on FreeBSD is as follows:
- UEFI firmware loads
boot1.efi
boot1.efi
in turn loadsloader.efi
- Finally,
loader.efi
loads the kernel.
The target scenario, according to the FreeBSD Foundation, would be that a cryptographic handshake would verify each transition within the process. That is still under development, and the currently available option is a little less modular.
It is possible to skip boot1.efi
and combine the loader and the kernel into
one large package, which then can be signed with self-issued keys. The keys
are enrolled into Dasharo firmware, which boots the loader-kernel object
directly.
Creating a UEFI Secure Boot - ready FreeBSD EFI executable
Please note that this guide assumes that you have a working FreeBSD installation that you wish to modify for UEFI Secure Boot support. Installation of the system will not be covered here.
Determine the loader of choice
There are currently several flavors of the loader.efi
available. The original
one was written in
FORTH.
The 14.1 release defaults to a more modern Lua one, the final option being
loader_simp
- a simplified C implementation. This guide will only provide
instructions on using the legacy FORTH loader and the current default. The
process has been tested using FreeBSD 14.1.
Copy the boot filesystem
|
|
Lua loader
|
|
FORTH loader
|
|
Copy the fstab
|
|
Create an image of the filesystem
|
|
Determine the size of the boot filesystem. This will determine how much memory to reserve in the loader:
|
|
Add a safety factor of a couple hundred bytes (~512) to this number, and record it.
Build the Loader With Extra Space
This step requires you to have the source code for your system. You might have
checked the src
component during OS installation, then the /usr/src/
directory should be already populated. If not, clone the source code from
GitHub, substituting 14.1
with the release you are currently using:
|
|
Now, recall your bootfs size and substitute ${BOOTFS_SIZE_PLUS_SAFETY}
below:
|
|
Embed bootfs image in the loader.efi
The build results will be available under /usr/obj
.
-
If you have chosen to use the legacy FORTH loader, the path to the file that interests you should be similar to
/usr/obj/usr/src/amd64.amd64/stand/efi/loader_4th/loader_4th.efi
. -
If you have chosen the Lua loader, the path should be similar to
/usr/obj/usr/src/amd64.amd64/stand/efi/loader_lua/loader_lua.efi
Copy the appropriate file and use the available embedding utility:
|
|
You might need to make embed_mfs.sh
executable:
|
|
At this point, loader.efi
is an UEFI-bootable binary, consisting of the
FreeBSD bootloader and kernel. The last remaining step to UEFI Secure Boot
compatibility is generating keys and signing the binary.
Signing the binary
FreeBSD includes a tool for signing EFI executables - uefisign
. There is also
a utility provided to generate example keys and certificates needed to sign an
executable.
You can generate a self-signed certificate and use it to sign a binary as follows:
|
|
As earlier, make sure the script is marked as executable.
You should now have a signed-loader.efi
and a testkey.cer
file. The loader
file is what we’re going to be booting from Dasharo, and the .cer
file is our
custom certificate we need to enroll, so that UEFI Secure Boot can verify the
loader’s signature against it.
Testing in QEMU
To spare yourself the trouble of recovering a broken OS installation, it is recommended to test the binary in an emulated environment.
Make sure you have an up-to-date installation of QEMU on your system, and get the latest QEMU release of Dasharo here. This process has been tested on the v0.1.0 release.
Launching QEMU with an emulated filesystem
Create a directory for the QEMU firmware files, and a directory for the test EFI files:
|
|
Download OVMF_CODE_RELEASE.fd
and OVMF_VARS_RELEASE.fd
from
GitHub and place them in
the ~/qemu_test
directory. Place the signed-loader.efi
and .cer
files in
the ~/qemu_test/efi
directory:
|
|
Run Dasharo firmware in QEMU, mounting the EFI directory as a virtual fat drive:
|
|
Enrolling the certificate
Preparing clean UEFI Secure Boot
-
Press
F2
to enter setup -
Navigate to
Device Manager/Secure Boot Configuration
-
Enable
Custom Mode
-
Enter the new
Advanced Secure Boot Keys Management
menu -
Select
Reset to default Secure Boot Keys
-
Select
YES
-
Press
F10
to save andY
to confirm -
Reset the platform by pressing
ESC
twice and selectingReset
Enrolling the ceritficate
-
Press
F2
to enter setup again -
Navigate to
Device Manager/Secure Boot Configuration
-
Enable
Custom Mode
and enter theAdvanced Secure Boot Keys Management
menu again. -
Navigate to
DB Options/Enroll Signature/Enroll Signature Using File/
. If the EFI directory is properly mounted, you should see a single entry in this menu, similar to this -
Select the entry, and then select
testcert.cer
-
Select
Commit Changes and Exit
-
Press
F10
to save andY
to confirm -
Make sure that
Current Secure Boot State
is enabled -
Reset the platform again
Booting FreeBSD
-
Enter setup menu
-
Navigate to
Boot Maintenance Manager/Boot Options/Add Boot Option
-
Choose the
QEMU_VFAT
disk label -
Find the loader-kernel object. It should be located under
<efi>/<freebsd>/loader.efi
-
Name the entry appropriately, confirm and save the changes.
-
Say hello to Beastie
Testing on hardware
Upon making sure that the loader-kernel object boots properly within an emulation environment, we can proceed to UEFI Secure Booting FreeBSD on hardware.
To do that, follow the exact same steps as with emulation, the only differewnce being that you will now need to upload the certificate to a USB drive and enroll the certificate from there.
You will also need to place the signed-loader.efi
file in your EFI partition,
and add it as a custom boot option.
Adding a custom boot option
NOTE: You should always set a Setup Menu password if using UEFI Secure Boot. Otherwise, nothing keeps a bad actor from simply disabling it ;)
- Enter setup menu
- Navigate to
Boot Maintenance Manager/Boot Options/Add Boot Option
- Choose the appropriate disk label. They might look intimidating, but you
should be able to find the correct one by looking for a familiar keyword.
If you have an NVME drive for example, there should be an entry with
Pci(0x0,0x0)/NVMe
. - Find the loader-kernel object. It should be located under
<efi>/<freebsd>/loader.efi
- Name the entry appropriately, confirm and save the changes.
Troubleshooting
Mountroot
If after booting the signed-loader.efi
you land in mountroot
, you need to
type in zfs:zroot/ROOT/default
and add the line
|
|
to your /boot/loader.conf
.
Summary
We have learned how to set up UEFI Secure Boot on FreeBSD, a feature that ensures only trusted, signed software can run during boot to protect against malware. FreeBSD’s implementation involves two stages: using Microsoft’s signed shim bootloader along with a FreeBSD EFI loader, and later securing all kernel modules.
As our approach, we have chosen to bundle the bootloader and kernel into a single EFI executable, then sign it using FreeBSD’s uefisign tool. We have also tested the setup in QEMU before deploying on hardware, ensuring that custom keys are properly enrolled in Dasharo firmware to enable UEFI Secure Boot.
If you want to deepen your understanding of UEFI Secure Boot and explore Intel Root of Trust technologies hands-on, consider joining our DS08MSA: Mastering UEFI Secure Boot and Intel Root of Trust Technologies training. This intensive course provides the operational knowledge and practical skills to work confidently with security technologies for x86 platforms. You’ll learn to handle hardware assessments, configure UEFI Secure Boot, and provision Root of Trust for robust system security; for more details, visit our training page at 3mdeb Training.