linuxboot / heads

A minimal Linux that runs as a coreboot or LinuxBoot ROM payload to provide a secure, flexible boot environment for laptops, workstations and servers.
https://osresearch.net/
GNU General Public License v2.0
1.41k stars 185 forks source link

Allow an encrypted boot partition #216

Open flammit opened 7 years ago

flammit commented 7 years ago

As per a TODO in qubes-init, it might be nice to be able to allow encrypted boot partitions. Should be straight-forward to detect and unlock, but there could potentially be many variations on how to manage the secret. Any thoughts / suggestions?

nemanjan00 commented 5 years ago

I am working on generic-init with support for encrypted lvm right now. :)

Edit: This is my progress so far:

https://github.com/nemanjan00/heads/tree/luks-lvm

I am able to mount boot partition, to find grub.cfg, but, kernel is paniking...

flammit commented 5 years ago

@nemanjan00 Cool! I was thinking of extracting mount_boot into it's own command, then have it potentially either scan for all possible boot devices or read a user-defined config file (stored in ROM using cbfs --add). That device config file could also contain the necessary parameters (raw device, lvm, luks, etc.) to properly mount to /boot and the rest of the boot can proceed normally.

The downside is that saving a default boot device + kexec option would require flashing/updating the ROM so that the fast path y default boot option can know which device to use.

@kylerankin that should also address your multiple boot device need right?

nemanjan00 commented 5 years ago

First of all, I want to get working PoC... :D

So far, I was unable to boot OS on encrypted LVM...

kylerankin commented 5 years ago

Yes, that should address my concerns. We can reuse the code I have in the flash-gui.sh script to add GPG keys to the running BIOS to reflash with an overwritten /etc/config. I had been planning on working on that myself but if someone else wants to take a stab they are more than welcome.

On Sat, Nov 10, 2018 at 11:46:51AM -0800, Francis Lam wrote:

@nemanjan00 Cool! I was thinking of extracting mount_boot into it's own command, then have it potentially either scan for all possible boot devices or read a user-defined config file (stored in ROM using cbfs --add). That device config file could also contain the necessary parameters (raw device, lvm, luks, etc.) to properly mount to /boot and the rest of the boot can proceed normally.

The downside is that saving a default boot device + kexec option would require flashing/updating the ROM so that the fast path y default boot option can know which device to use.

@kylerankin that should also address your multiple boot device need right?

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/osresearch/heads/issues/216#issuecomment-437614873

jfrederickson commented 5 years ago

Since this issue seems somewhat related - it would be helpful if the eventual solution also covered the case in which the kernel/initrd are on an encrypted (but non-/boot) partition. This is the case for Guix System installed on an encrypted filesystem; the kernel/initrd are in the Guix store like every other package.

Heads might not need to cover this use case specifically I suppose, if /boot being on the same encrypted filesystem as / would do the trick. Guix is highly configurable in that regard.

tlaurion commented 4 years ago

@jfrederickson @0rb677 so in the current use case, what would be the filesystem architecture? everything under /dev/sda1 which would be the LUKS encrypted container?

We could modify the scripts to check for type of fs prior of trying to mount "boot" partition. But in that case, all TPM based checks and rollbacks would depend on user typing their Disk Recovery Key passphrase (eavesdroppable), without the added security of using a second Disk Unlock Key passphrase, released by the TPM upon firmware integrity validation (measured boot comonent) + /boot integrity validation (verified boot component) .

The actual Heads logic here is to depend on a unencrypted /boot partition where heads store TPM and USB Security Key rollback counters + LUKS header to be able to release the Disk Unlock Key after validation. We would have to bypass it all.

Heads here relies on verified boot (verified signed unencrypted /boot content) to do its magic, permitting to modify /boot content, while making it tamper evident, while the whole filesystem being opaque; it is not really interested to it, relying on initrd to provide the requirements to deal with it once (xen +) kernel + initrd are launched through multiboot kexec call.

Any idea welcome. Other option would be to duplicate boards once more (x230-hotp-verification_no_disk_unlock) to permit encrypted / wholesome filesystem, deactivating Disk Unlock Key support, as per Librem boards who relies on USB Security dongle / Disk Recovery Key passphrase (fallback) to boot system with a feature equivalent second factor logic.

I am not against having encrypted /boot, while questioning its use case if made tamper evident.

My consequent question here would be how to instruct guix (#753) to have its /gnu/store or all boot components inside of /boot, opposedly. I think there are some guix architecture unknowns to me. If you can enlighten me on why/how those components are put on seperate partition expected to already be decrypted per bootloader (@daym? ) that would help me understand how all of it is supposed to actually work, and seems functionally flawed at first sight. My minimal understanding requirements are not met! :)

jfrederickson commented 4 years ago

@tlaurion Yeah - everything under an encrypted /dev/sda1 would work in my case. As would unencrypted /boot with encrypted /root, so long as it's acceptable for the kernel/initrd to be on a separate encrypted filesystem.

Not to blur the lines between this and #753 too much, but... Guix System places all packages on the system into /gnu/store, where they're identified by (ultimately) a hash of themselves and their inputs. (It's very similar to and is somewhat descended from Nix.) The kernel/initrd are no exceptions to this.

Here's a snippet from the resulting GRUB config that Guix generates:

menuentry "GNU with Linux-Libre 5.4.44" {
  search --file --set /gnu/store/nw16iq8399sigcgf8vbf2qs5nbj4l0bl-linux-libre-5.4.44/bzImage
  linux /gnu/store/nw16iq8399sigcgf8vbf2qs5nbj4l0bl-linux-libre-5.4.44/bzImage --root=/dev/mapper/root --system=/gnu/store/xgigwm4glk7r74sy6ivx4a9xgyrjd430-system --load=/gnu/store/xgigwm4glk7r74sy6ivx4a9xgyrjd430-system/boot modprobe.blacklist=usbmouse,usbkbd quiet
  initrd /gnu/store/msq6xrcck5fh7ka7w2q5mpibrahbxc7m-raw-initrd/initrd.cpio.gz
}

submenu "GNU system, old configurations..." {
menuentry "GNU with Linux-Libre 5.4.44 (#38, 2020-06-04 10:14)" {
  search --file --set /gnu/store/nw16iq8399sigcgf8vbf2qs5nbj4l0bl-linux-libre-5.4.44/bzImage
  linux /gnu/store/nw16iq8399sigcgf8vbf2qs5nbj4l0bl-linux-libre-5.4.44/bzImage --root=/dev/mapper/root --system=/var/guix/profiles/system-38-link --load=/var/guix/profiles/system-38-link/boot modprobe.blacklist=usbmouse,usbkbd quiet
  initrd /gnu/store/msq6xrcck5fh7ka7w2q5mpibrahbxc7m-raw-initrd/initrd.cpio.gz
}
menuentry "GNU with Linux-Libre 5.4.42 (#37, 2020-05-25 20:20)" {
  search --file --set /gnu/store/7f9maqci9lvrbmmq3g7aks2dvk52zhh4-linux-libre-5.4.42/bzImage
  linux /gnu/store/7f9maqci9lvrbmmq3g7aks2dvk52zhh4-linux-libre-5.4.42/bzImage --root=/dev/mapper/root --system=/var/guix/profiles/system-37-link --load=/var/guix/profiles/system-37-link/boot modprobe.blacklist=usbmouse,usbkbd quiet
  initrd /gnu/store/q13qbcfq2xj2w4ncqw18r4vaw0vr76j2-raw-initrd/initrd.cpio.gz
}

Some things to note about this:

Regarding why the kernel/initrd are in the store and not on /boot directly, I suspect it's just because:

daym commented 4 years ago

@tlaurion:

I am not against having encrypted /boot, while questioning its use case if made tamper evident.

I think easiest would be to support Guix /boot be unencrypted (need to patch Guix to support that; huge discussion floating on guix-devel didn't see the need for unencrypted boot so far), and just sign it, to support Heads better.

My consequent question here would be how to instruct guix (#753) to have its /gnu/store or all boot components inside of /boot, opposedly.

I don't think that is possible. Guix basically takes the entire operating system, starting with the kernel, as one huge versioned state. That is, what you are selecting to boot in the Grub boot menu is not just the kernel of that day, it's everything of that day (except $HOME).

If you can enlighten me on why/how those components are put on seperate partition expected to already be decrypted per bootloader

The idea is that /gnu/store contains all the installed packages there are. Think of it like /opt was back in the day, just that the basename now contains a hash of all the sources and transitive sources.

/boot is kept as small as possible. I checked, it only has grub fonts and themes and grub.cfg in there.

grub.cfg instructs grub to

search --file --set /gnu/store/rp0bfq6016f8jsj2l0wwjis2x4v1sj2y-linux-libre-5.4.30/bzImage linux /gnu/store/rp0bfq6016f8jsj2l0wwjis2x4v1sj2y-linux-libre-5.4.30/bzImage --root=/dev/mapper/cryptroot --system=/var/guix/profiles/system-50-link --load=/var/guix/profiles/system-50-link/boot

That means one has to enter the passphrase at least twice, once in grub for /, and once in the initrd for /.

Guix is only beginning to integrate Heads properly. I don't think doing it like it is now was a conscious design decision--and in any case, adding support for unencrypted /boot is easy.

All that said, it's easy for Guix to actually find all the dependencies required to do whatever and put those in a separate volume (it already has all the tools)--but is it useful? Because for the Guix system model the dependencies required to boot a menu entry in grub is the entire operating system, including GNOME if you had it installed, your gcc if you had it installed etc.

jfrederickson commented 4 years ago

I think easiest would be to support Guix /boot be unencrypted (need to patch Guix to support that; huge discussion floating on guix-devel didn't see the need for unencrypted boot so far), and just sign it, to support Heads better.

Hmm, does Guix need patching to support this? This is the setup that I have (though I may have done a bit of hacking around during installation, I don't remember) and Pierre's post in guix-devel seems to indicate it's possible, though it does require entering your passphrase twice.

ghost commented 4 years ago

@daym @tlaurion @jfrederickson thanks for your work. please do not stop. Guixsd + Heads really would be a flame cocktail ;)

tlaurion commented 4 years ago

linked to #753

Hmm, does Guix need patching to support this? This is the setup that I have (though I may have done a bit of hacking around during installation, I don't remember) and Pierre's post in guix-devel seems to indicate it's possible, though it does require entering your passphrase twice.

@daym : I do not recall the conclusions of our discussions. Would also be linked to #818 if we want to chainload into an encrypted loop mounted LUKS encrypted heads extension payload (maybe not).

UndeadDevel commented 9 months ago

I had an idea in connection with encrypted boot, but created it as a discussion since it blows the scope of this issue somewhat.