[arch-releng] Secure Boot support (FS#53864)

Jonas Witschel diabonas at gmx.de
Tue Jan 22 14:46:40 UTC 2019

Hi all,

following up on FS#53864, I tried to summarise possible ways to
implement Secure Boot in Arch Linux. I apologise in advance for the very
long email... I structured the text into two possible approaches
(technically three, but the first one is not very feasible) and would
love to hear your opinion on them. If there is an interest in
implementing Secure Boot, I am happy to help out wherever I can. You
will see however that most required changes are more on the
"administrative" side rather than the "coding" side, e.g. officially
adopting packages from the AUR, creating certificates, submitting
binaries to Microsoft for review, ... I have successfully tested the
approach "Using a signed shimx64.efi built by a third party" on
different machines, with Secure Boot enabled and disabled.

Current situation
On UEFI systems, Archiso uses PreLoader.efi from efitools [1] to
chainload the systemd-boot boot loader. As the efitools EFI binaries
used in Arch Linux are built from source and not signed by Microsoft,
this procedure fails when Secure Boot is enabled because the unsigned
PreLoader.efi cannot be executed. (This makes the preloader a bit
useless, see FS#59487: systemd-boot could be directly installed as
bootx64.efi instead, as the only purpose of the preloader is to make
Secure Boot possible.) Previously, Archiso used an old version of
efitools signed by Microsoft, which is provided by Linux kernel
maintainer James Bottomley [2]: it was formerly packaged as
"prebootloader", but this package has been removed in favour of efitools

Possible solutions

Using a signed PreLoader.efi built by Arch Linux
It is possible to build UEFI binaries yourself and get them signed by
Microsoft by submitting them to [4], see [5] for the requirements that
need to be fulfilled. However, judging by [4], it seems that Microsoft
focuses on the "shim" boot loader instead of efitools, therefore I don't
know how likely it is for such a request to succeed. I therefore
concentrated on switching from efitools to shim in the next two sections.

Using a signed shimx64.efi built by a third party
The efforts regarding Secure Boot on Linux now seem to concentrate
around the shim boot loader [6], available in the AUR as shim-efi. It is
developed by Red Hat and works as a drop-in replacement for efitools:
the only difference are some name changes, i.e. "PreLoader.efi" is
called "shimx64.efi", "HashTool.efi" is "mmx64.efi", and the
second-stage boot loader needs to be called "grubx64.efi" instead of
"loader.efi" (even if it is not GRUB, but systemd-boot in case of Archiso).

This would allow to use Secure Boot by the following process, which is
also documented in the corresponding section of the Wiki [7]:

1. Boot the Arch Linux ISO with Secure Boot enabled.
2. The signed shimx64.efi tries to load grubx64.efi, which is the
systemd-boot boot loader. As systemd-boot is unsigned, this will fail,
so shimx64.efi launches mmx64.efi instead. mmx64.efi gives you the
opportunity to enroll the hashes of the boot loader (grubx64.efi) and
kernel (vmlinuz.efi). This saves their hashes in the EFI variable
"MokList", which allows them to be executed with Secure Boot enabled.
3. After a restart, shimx64.efi is now able to execute the thus approved
boot loader and kernel without further user action.
4. When the boot loader or kernel are updated, the user needs to enroll
the new binaries using the same process as in 2.

There are two possibilities to obtain a pre-built signed shimx64.efi:
there is a "generic" version built by former Red Hat employee Matthew
Garrett [8], but it is very old and might not be suitable any more. As
an alternative, we can use any newer Microsoft-signed shim built by a
distribution like Fedora [9], which is what the AUR package shim-signed

Advantages of this approach:
+ Most distributions supporting Secure Boot seem to use shim, so this
might be more well-tried than the efitools approach.
+ It should be easy to verify the authenticity of the prebuilt binaries
because the review process for shims signed by Microsoft is public [10]
and includes information about the build configuration. Detaching the
signature from the binary [11] makes it possible to verify that the
unsigned binary is reproducible from source.
- We don't have control over the build of the unsigned binary and depend
on another distribution for updates.
- Other distributions include their own signing key in the shim binary.
This allows them to sign their boot loader and kernel themselves,
avoiding the need to enroll the hashes every time (see the next
section). We cannot make use of this key ourselves, so we have a shim
that includes a superfluous (but harmless) additional public key.

Using a signed shimx64.efi built by Arch Linux
It is possible to build shim yourself and get it signed by Microsoft. To
do this, you need to submit it to Microsoft [4] and open an issue in
[10] providing all the necessary information. If the request is
approved, you receive back the signed files you can then distribute.

The easiest approach is to only get shimx64.efi signed and let users
enrol the hashes of the boot loader and kernel manually [7]. However,
with our own shim, we can do much better: it is possible to embed the
public key of a certificate into the shim binary [12]. This certificate
can be used to sign the boot loader and kernel so that Secure Boot works
completely automated out of the box, without having to enrol hashes.
This process is documented in the Wiki as well [13] (except that you
don't have to enroll "MOK.cer" manually, since it is already embedded in
the shim binary).

This approach would not only be beneficial to Archiso, it can also be
used on installed systems for Secure Boot to work out of the box!

To follow this approach, the following things need to be done:

1. Create a certificate conforming to the policy [5].
2. Build shim [6], embedding the public part of the certificate
generated in 1. [12]
3. Submit the binary "shimx64.efi" to Microsoft [4] and the shim-review
repository [10].
4. Once the signed binary is returned, verify that it matches the
submitted build [11] and distribute it as a package.
5. In Archiso, replace "PreLoader.efi" and "HashTool.efi" by
"shimx64.efi" and "mmx64.efi", rename "loader.efi" to "grubx64.efi".
6. (Optional) Sign the kernel "vmlinuz-linux" and all relevant boot
loaders (systemd-boot, GRUB, REFInd) with sbsign from the sbsigntools
package using the key generated in 1. This needs to be incorporated into
the PKGBUILD of the respective packages.

+ Full control over the distributed binaries.
+ Transparent for users, no manual enrollment is necessary.
+ Works for installed systems as well as Archiso.
- This is much more elaborate than using a pre-built signed binary, as
we need to go through the shim review process ourselves.
- Signing the kernel and boot loaders requires access to the private key
of the certificate. Depending on how the certificate is stored, this
might pose logistic problems for developers/TUs wanting to update one of
the affected packages. Note however that this part is completely
optional, users will still be able to enrol unsigned binaries using a
hash [7]. Therefore this will also still allow users running a custom
kernel or boot loader to use Secure Boot.

Suggested action
If shipping binaries built by a third party is acceptable in this
context, I would start with the approach described in "Using a signed
shimx64.efi built by a third party". This requires the least effort to
get Secure Boot working (just adopt shim-signed as an official package
and follow "Using a signed shimx64.efi built by Arch Linux", step 4.),
but will still require manual enrolment of the boot loader and kernel
hashes by the user.

If you want full control over the distributed binaries, I suggest the
approach described in "Using a signed shimx64.efi built by Arch Linux",
possibly in the following stages:

1. Adopt the AUR package shim-efi as an official package in order to
build shim from source.
2. Move Archiso from efitools to shim as described in "Using a signed
shimx64.efi built by Arch Linux", step 4.
3. Wait a couple of months to gain experience with the new preloader.
4. If all goes well, submit shim for signing as described in "Using a
signed shimx64.efi built by Arch Linux", step 3.
5. Distribute the signed shim as a package and use it in Archiso.
6. When this is up and running, gauge interest for signing the boot
loader and kernel with the key embedded in shim to remove the need to
manually enrol the hashes on every boot loader/kernel update.

If there is an interest in pursuing any of these approaches, I am happy
to submit the necessary (but fairly trivial) patch to move Archiso from
efitools to shim or to assist in the process of submitting the shim
binary for review as far as I can. Unfortunately, the main workload will
still rest on a developer/TU.

If there are any questions, don't hesitate to ask! I have successfully
tested the approach described in "Using a signed shimx64.efi built by a
third party" on multiple machines with Secure Boot enabled and disabled
and I am happy to share the necessary steps to locally build an Arch
Linux ISO which works with Secure Boot enabled.


[1] https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git
[6] https://github.com/rhboot/shim
[7] https://wiki.archlinux.org/index.php/Secure_Boot#shim_with_hash
[8] https://mjg59.dreamwidth.org/20303.html
[9] https://apps.fedoraproject.org/packages/shim/
[10] https://github.com/rhboot/shim-review
[11] https://wiki.debian.org/SecureBoot#line-160
[13] https://wiki.archlinux.org/index.php/Secure_Boot#shim_with_key

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.archlinux.org/pipermail/arch-releng/attachments/20190122/6b9692ff/attachment.asc>

More information about the arch-releng mailing list