From nobody Wed Jan 24 14:24:20 2024 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TKmRt2qhRz585vZ for ; Wed, 24 Jan 2024 14:24:26 +0000 (UTC) (envelope-from kempe@lysator.liu.se) Received: from mail.lysator.liu.se (mail.lysator.liu.se [130.236.254.3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4TKmRs3JGpz4fM5 for ; Wed, 24 Jan 2024 14:24:25 +0000 (UTC) (envelope-from kempe@lysator.liu.se) Authentication-Results: mx1.freebsd.org; dkim=none; dmarc=pass (policy=none) header.from=lysator.liu.se; spf=pass (mx1.freebsd.org: domain of kempe@lysator.liu.se designates 130.236.254.3 as permitted sender) smtp.mailfrom=kempe@lysator.liu.se Received: from mail.lysator.liu.se (localhost [127.0.0.1]) by mail.lysator.liu.se (Postfix) with ESMTP id 8C1761EA4F for ; Wed, 24 Jan 2024 15:24:21 +0100 (CET) Received: from shipon.lysator.liu.se (shipon.lysator.liu.se [IPv6:2001:6b0:17:f0a0::83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.lysator.liu.se (Postfix) with ESMTPSA id 75D041EA4E for ; Wed, 24 Jan 2024 15:24:21 +0100 (CET) Date: Wed, 24 Jan 2024 15:24:20 +0100 From: Andreas Kempe To: freebsd-hackers@freebsd.org Subject: The state of secure boot with FreeBSD Message-ID: List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@freebsd.org MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="VFTUei/UZlVZivxW" Content-Disposition: inline X-Virus-Scanned: ClamAV using ClamSMTP X-Spamd-Bar: --- X-Spamd-Result: default: False [-4.00 / 15.00]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; NEURAL_HAM_SHORT(-1.00)[-1.000]; DMARC_POLICY_ALLOW(-0.50)[lysator.liu.se,none]; R_SPF_ALLOW(-0.20)[+a:mail.lysator.liu.se]; RCVD_IN_DNSWL_MED(-0.20)[130.236.254.3:from]; MIME_GOOD(-0.10)[multipart/mixed,text/plain,text/x-diff]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; MISSING_XM_UA(0.00)[]; ASN(0.00)[asn:2843, ipnet:130.236.0.0/16, country:SE]; MIME_TRACE(0.00)[0:+,1:+,2:+]; R_DKIM_NA(0.00)[]; MLMMJ_DEST(0.00)[freebsd-hackers@freebsd.org]; MID_RHS_MATCH_FROMTLD(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[]; ARC_NA(0.00)[]; TO_DN_NONE(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[freebsd-hackers@freebsd.org]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_TLS_LAST(0.00)[]; HAS_ATTACHMENT(0.00)[] X-Rspamd-Queue-Id: 4TKmRs3JGpz4fM5 --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 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--