Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Jan 2024 15:24:20 +0100
From:      Andreas Kempe <kempe@lysator.liu.se>
To:        freebsd-hackers@freebsd.org
Subject:   The state of secure boot with FreeBSD
Message-ID:  <ZbEdlM57MuRYZRTA@shipon.lysator.liu.se>

next in thread | raw e-mail | index | archive | help

--VFTUei/UZlVZivxW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello everyone,

I've been looking at configuring my FreeBSD UEFI laptop with ZFS on
GELI with secure boot.

Using efitools[0] from Linux in a Linux VM allowed me to generate keys
that were programmed into the UEFI. The generated keys then worked
fine for signing the EFI loader using uefisign(8) on my FreeBSD
system. So far so good, but the crux is maintaining the secure boot
chain between the loader and the root file system.

One version I tried was applying the patch attached to this mail to my
loader, whitelisting the GELI header hash of my root partition. This
works, but I'm fairly sure that the loader could be manipulated with
configuration files or the creation of extra unencrypted partitions on
the drive for it to find and try to boot, making it far from an ideal
solution.

I found instructions on the FreeBSD Foundation's website[1] on how to
embed the kernel into the loader. It could be due to user error, but
when trying this, the loader simply found and booted my ZFS system
instead of the embedded kernel. Looking at the code in
stand/efi/loader/main.c seems to imply that ZFS will be tried before
the embedded image.

For verification, there are references to VERIEXEC in the loader and
in src.conf(5), but I have not been able to find any FreeBSD
documentation on how this is to be configured.

Lastly, I'm aware of the FreeBSD secure boot wiki page[2], but it has
not been updated in a few years so I don't know if it reflects the
current secure boot situation. Its status matrix indicates that secure
boot work for the loader has not been started.

Does anyone know if secure boot work is ongoing? Are there patches for
locking the loader down floating around out there? Are there
instructions I have missed or alternatives to using the EFI loader
provided in base?

Thank you for reading!
Best regards,
Andreas Kempe

[0]: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git
[1]: https://freebsdfoundation.org/freebsd-uefi-secure-boot/
[2]: https://wiki.freebsd.org/SecureBoot

--VFTUei/UZlVZivxW
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
	filename="0001-Add-GELI-MD5-whitelist-to-loader.patch"

>From 819605de931a7ac5d2e6bdf1c6a120cc5f3f46fc Mon Sep 17 00:00:00 2001
From: Andreas Kempe <kempe@lysator.liu.se>
Date: Tue, 23 Jan 2024 19:59:04 +0100
Subject: [PATCH] Add GELI MD5 whitelist to loader

---
 stand/libsa/geli/geliboot.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/stand/libsa/geli/geliboot.c b/stand/libsa/geli/geliboot.c
index 04c53e73b29a..c402bb39f289 100644
--- a/stand/libsa/geli/geliboot.c
+++ b/stand/libsa/geli/geliboot.c
@@ -133,6 +133,12 @@ geli_taste(geli_readfunc readfunc, void *readpriv, daddr_t lastsector,
 	char devname[GELIDEV_NAMELEN];
 	int error;
 	off_t alignsector;
+	const u_char valid_hash[16] = {
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00
+	};
 
 	/*
 	 * Format the name into a temp buffer and use that to search for an
@@ -191,6 +197,12 @@ geli_taste(geli_readfunc readfunc, void *readpriv, daddr_t lastsector,
 		goto out;
 	}
 
+	/* Check ELI device hash against whitelist. */
+	if (bcmp(md.md_hash, valid_hash, sizeof(valid_hash)) != 0) {
+		/* Not a whitelisted ELI device. */
+		goto out;
+	}
+
 	/*
 	 * It's geli-encrypted, create a geli_dev for it and link it into the
 	 * known_dev instance.
-- 
2.43.0


--VFTUei/UZlVZivxW--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?ZbEdlM57MuRYZRTA>