rhboot / shim

UEFI shim loader
Other
819 stars 289 forks source link

Support for Nested Shim Setups #549

Closed KimBrodowski closed 1 year ago

KimBrodowski commented 1 year ago

Hello,

Background

I'm currently in the process of migrating a more complex boot setup over to SecureBoot. Unfortunately, this boot process can contain a number of 3rd party applications and bootloaders, among them shim, grub and iPXE.

There is basically no reasonable way to get all components signed by Microsoft. Getting a shim with an embedded vendor certificate signed without also auditing each subsequent application in the boot path would risk the security of the ecosystem and is therefor also out of the question, not to mention guidelines preventing this from happening anyway.

Since OEMs sometimes make it impossible or extremely hard to import certificates into their db, we looked into using MOKs instead. We would prefer to just rely on importing a certificate into db, if that were possible. With users in control of MOKs, they can decide themselves whether they want to import our vendor certificate into their EFI. This process can be automated except for the confirmation part done in MokManager. Any non-audited code would be limited to systems having imported our vendor certificate, just as if they had imports into their native db.

Problem

Unlike PreLoader, shim does not overwrite the EFI's signature validation routine. This means that any intermediate bootloader like iPXE must be followed by db-signed bootloader, unless the intermediate bootloader doesn't validate signatures, making this whole exercise pointless, or the subsequent bootloader interfaces with shim's exposed signature verification functions, as grub does for example. Since we want to proceed with 3rd party applications after that, this is a problem.

The obvious solution is just to load shim a 2nd time. However, this appears to be broken right now. The 2nd shim presents an error message:

Could not install security protocol: (0x2) Invalid Parameter

Solution

It would be nice if shim would support nested setups, e.g. shim -> iPXE -> shim -> HelloWorld.efi.

Additional context

After starting experimentation, I also came across this thread on iPXE's issue tracker discussing the same idea.. My guess is though, nobody actually tried this. Otherwise I might have made a mistake here, in which case I'm thankful for any pointers in the right direction.

In any case: Thank you for your time.

Kind regards, Kim-A. Brodowski

julian-klode commented 1 year ago

We precisely do that in Ubuntu/MAAS, shim -> grub~> shim -> grub. Where the first pair lives on network and the next one on disk. This works fine though you need to disable the Exit-Bootservices check for which we added an option to upstream shim.

I suggest to stay clear of iPXE. We don't review shims that trust iPXE so there's no way to get them signed. This is partially because grub supports booting from network and accessing network storage just fine and probably can be used for what you want to do, but also because we lack knowledge of the iPXE codebase and can't review it.

KimBrodowski commented 1 year ago

This works fine though you need to disable the Exit-Bootservices check for which we added an option to upstream shim.

Does a signed version of this exist? I'll look into that. Thank you, this is very useful information.

Edit: Looking at the shim version I've used, shim.ubuntu,1,Ubuntu,shim,15.4-0ubuntu9,https://www.ubuntu.com/, and the shim submissions, I would have thought that this shim included the relevant patch. At least an earlier submission explicitly mentioned it. I have yet to verify this though.

We don't review shims that trust iPXE so there's no way to get them signed.

Again, I'm not trying to get shim signed. We planned on using a version of shim provided by another Linux distribution. In my experiments, I've used the one shipped with my local installation of Ubuntu.

I suggest to stay clear of iPXE.

We heavily make use of iPXE because it works well on a variety of hardware and offers great flexibility, which we do need. I'm sure some of that could be implemented in grub as well, but I highly doubt all of it. Particularly, we heavily rely on obtaining configuration via HTTP at runtime. I have my doubts that the workarounds for buggy EFI implementations can be easily achieved in grub due to missing information about installed hardware etc.

I'll give that more thoughts though.

Edit: Clarified why we use iPXE.

KimBrodowski commented 1 year ago

Based on further testing, this appears to be an issue with iPXE. Nested grub setups do work. Thank you for your help!