Adventures with the UEFI shim

Paul Moore paul at paul-moore.com
Thu Oct 8 16:42:33 BST 2020


On Wed, Oct 7, 2020 at 3:17 PM Peter Jones <pjones at redhat.com> wrote:
> On Thu, Oct 01, 2020 at 03:16:08PM -0400, Paul Moore wrote:

...

> > While most shim use cases involve using shim to load GRUB which in
> > turn loads the kernel/OS, I'm looking to use shim to boot the
> > kernel/OS directly.  Specifically, I want to use shim to boot a
> > combined kernel+initrd+cmdline EFI application using the systemd-boot
> > EFI stub.  Unfortunately I've been running into problems with shim's
> > ExitBootServices hook.  Looking at the code, it would appear that shim
> > expects (and requires) that some piece of the bootloader chain calls
> > into shim's verification protocol to authorize the kernel prior to
> > calling ExitBootServices.  This would normally be handled by GRUB, or
> > any other bootloader in the chain, but if there is no bootloader
> > beyond shim things fall apart.
> >
> > If this was anything but shim, the fix would be a small and
> > straightforward patch to replacements.c:exit_boot_services() but since
> > our project would eventually like to get a shim signed by Microsoft we
> > need to find a solution that is suitable for the rhboot/shim-review
> > crowd.
>
> Let me start by saying that I don't think there's a good answer here,
> for a lot of reasons.  The biggest one is that systemd-boot is LGPL and
> linux is GPL licensed, and Microsoft has stated repeatedly that they're
> not going to sign images that are GPL licensed.  That's a part of why
> shim exists in the first place.

I think there may be a misunderstanding here, I'm not expecting
Microsoft to sign anything other than the UEFI shim.  The only
difference from the typical shim->GRUB->kernel solution is that I'm
thinking of skipping GRUB and booting the kernel+initrd+cmdline (with
the systemd-boot UEFI stub/wrapper to properly setup the
initrd/cmdline).

> If it weren't for that, I would say:
> - put a pubkey in shim like normal
> - sign your kernel with it
> - make systemd-boot call the shim lock protocol on the embedded kernel

Yes, I'm already planning on steps 1 and 2 (those are needed pretty
much regardless of the design), I was just wondering if the UEFI shim
folks would be open to working on solution that doesn't require the
"loader_is_participating" check in shim's ExitBootServices hook.
Conceptually if shim has already verified the signature on the next
stage of the boot process that would seem to imply a certain level of
trust in that binary.  Would you be open to a mechanism for post-shim
loaders to signal shim that they do not need additional verification
via the shim protocol?

> So I guess the questions are:
>
> - What's your reasoning for wanting to go the systemd-boot packed
>   binary route?  There may be more options, depending on which parts of
>   that design are critical to you.

I want to be able to verify not just the kernel, but the initrd and
kernel command line as well.  If I bundle the kernel+initrd+cmdline
together into one EFI application using the systemd-boot EFI stub (or
similar), I can sign the resulting EFI binary and load it directly.

I am open to other solutions that provide similar verification of the
kernel+initrd+cmdline.

> - If you can share, what does your timeline for needing something signed
>   look like?

It's fuzzy.  First and foremost I need to find a solution that meets
our needs, and is acceptable to Microsoft and the rhboot/shim-review
crowd.  My hope is that we can find a solution that can be integrated
directly into shim, since that seems like the quickest path forward
(least amount of changes).  If there is no acceptable way around the
"loader_is_participating" issue, then my plan B looks to be to create
a small second stage loader[1] which simply verifies a EFI binary via
the shim protocol and then hands off execution.

Parallel to the technical discussions I've been working on making sure
we have everything in place for the actual Microsoft signing.  Oddly
enough that has proved to be the easier of the two tasks.  Go figure.

[1] You may ask, why not just use GRUB?  Beyond the simple-is-good
argument, we also want some additional TPM PCR extensions beyond what
is commonly supplied by shim+GRUB.  The existing PCR7 measurements are
close, but we want more stability than PCR7 currently provides; we
want PCR stability across firmware changes and db/dbx might change
across firmware updates.  As we are not planning to use GRUB, we are
planning on using PCR8 or PCR9 to measure the SecureBoot variable, PK,
KEK, and EFI binary (kernel+initrd+cmdline) signing certificate.  The
other PCR will likely contain just a measurement of the EFI binary
itself.  In a perfect world we would also work with shim to see if we
could get these extensions into shim as a build time option, but it's
not worth discussing that if we can't find a shim-based solution to
the "loader_is_participating" issue we are facing.  I realize this
will complicate the rhboot/shim-review process, but my goal is to make
this loader as small as possible to ease review (and likely "borrow" a
lot of code from shim itself as I have no specific licensing
requirements on my end).

> > As an aside, how do people do dev/test of the UEFI shim when UEFI
> > Secure Boot is enabled?  I originally thought I could use a Microsoft
> > signed shim to boot my development shim which would finally boot the
> > kernel/OS, but I'm running afoul of the nested EFI service hooks.  Any
> > advice you can provide would be appreciated.
>
> We use Qemu with OVMF (see the "edk2" packages in fedora for example
> builds) and enroll our own certs and self-sign everything.  The biggest
> "gotcha" there is to be sure you have one cert that's in 'db' and signs
> shim, and a completely different cert that shim trusts, which signs
> anything shim might be loading.  That said, my statement here is
> obviously not written with your attempt to use systemd-boot in mind.

You wouldn't happen to have a doc/guide written up on this, would you?
 Bonus points if it uses QEMU directly and doesn't require libvirt.
The past two days I started playing around with using QEMU+OVMF to
ease UEFI development, but I haven't properly tried to get UEFI Secure
Boot working yet.

-- 
paul moore
www.paul-moore.com



More information about the Efi mailing list