On 21-01-2020 01:57, Matthew Garrett wrote:
Measured boot involves generating cryptographic measurements of boot
components and configuration and using that to either control access to
a local secret (in the case of sealing secrets to a TPM) or proving to
another device (eg, a remote server or a local phone) what was booted.
We're shipping most of the infrastructure to do this, but we're still
left with a pretty fundamental problem - we need to know what the
expected values are in order to know whether something's been tampered
with or not.
For many components this isn't a huge problem (we build and distribute
the files - users can extract them and calculate the appropriate
measurements, and maybe long term we'll be able to ship the measurements
in a digestable way), but our initramfs images are generated on the user
system and include system-specific data. This makes it impractical to
know the expected measurements in advance.
I've been thinking about ways to solve this for a while, and I'm coming
to the conclusion that the best plan is probably to just ship pre-built
initramfs images. I can think of three main reasons to want to use
1) They're smaller. By default we're already generating a generic image
for rescue purposes, so disk space isn't the concern here - we're
largely looking at losing boot speed. As machines have got faster this
is probably not a huge deal.
Using pre-generated initrds is something which comes up from time to time
and I do believe it is something which we want to move towards.
For the size problem one approach which I think is worthwhile at least
for the x86/workstation case is making one initrd with the most common
stuff in there (say i915,nouveau and amd GPU drivers + NVME and AHCI
disk support, maybe some eMMC support) and another which contains
"everything" and then rework the dracut host-only code so that we can
leverage it to figure out which variant we want.
2) They contain machine-specific configuration. Some of this can be
passed on the kernel command line instead (eg, the machine ID), but we'd
need answers for the rest. I can think of a couple of solutions:
a) Stick the config in UEFI variables. It's small enough that we
wouldn't run out.
b) Extend grub to read some config files and synthesise an initramfs
image for them. If we measure the paths that those images use then
we don't need to worry about the contents as long as the tools that
read the config can't be subverted via that configuration.
We still have quite a lot of users using classic BIOS boot (and early
x86_64 hw does not do UEFI at all) so a) is not really an option as
I would like to see a common approach here for both UEFI + classic
BIOS, moreover we also have other architectures and if we change this
we should really change it everywhere rather then have multiple code
paths to support.
So b it is, I actually suggested b. on a discussion about how to set
the keyboard map for the initrd (for full disk encryption) which currently
is a problem for rpm-ostree / SilverBlue which uses pre-generated
initrds with no custom config in there.
3) User customisation, such as including extra tooling. grub
loading multiple initramfs images. Packages that right now install stuff
in the initramfs could instead ship a prebuilt image that grub could
append to the main initramfs. This would allow for things like
overriding Plymouth themes, and we could ship the measurements for these
pre-built images in order to allow them to be validated.
Ack for using appended initrds for this, this also mixes well with my
preferred solution for 2.