grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 0/3] Add support for signing grub with an appended signature


From: Daniel Axtens
Subject: Re: [PATCH 0/3] Add support for signing grub with an appended signature
Date: Thu, 24 Sep 2020 01:11:17 +1000

Hi,

> Part of a secure boot chain is allowing boot firmware to verify the
> grub core.img. For UEFI platforms, this is done by signing the PE
> binary with a tool like pesign or sb-sign. However, for platforms that
> don't implement UEFI, an alternative scheme is required.
>
> These patches provide some infrastructure and documentation for
> signing grub's core.img with a Linux-kernel-module style appended
> signature.
>
> Because some platforms, such as powerpc-ieee1275, load grub from a raw
> disk partition rather than a filesystem, we extend grub-install to add
> an ELF note that allows us to specify the size and location of the
> signature.

This is following up on the discussion out of Linux Plumbers [1].
Hopefully I've got the main question-askers, apologies if I've missed
anyone or sent emails to the wrong people. I'm also emailing grub-devel@
in hopes of catching anyone else who is interested.

One of the big requirements I heard was a desire to support key
rotation, for example by being able to embed multiple signatures in a
single signed grub.

I checked, and this is possible with appended signatures as I have
proposed them, because the size of the full signature block is known
when grub-mkimage is called.

You do have to do a bit of magic with openssl and sign-file, but it's
not particuarly bad. This demonstrates the openssl side and it's easy
to integrate with grub-mkimage:

# sign data/hello-world with both signing1 and signing2, placing just the
# PKCS#7 message in out/double-sig.p7s
openssl cms -sign -binary -in data/hello-world \
    -signer signing1.pem -inkey signing1.key \
    -signer signing2.pem -inkey signing2.key \
    -out out/double-sig.p7s -outform DER -noattr -md sha512

# append it to data/hello-world using sign-file's -s option, creating
# out/hello-world-sha512-2keys
../tools/sign-file -s out/double-sig.p7s sha512 /dev/null data/hello-world 
out/hello-world-sha512-2keys

# to verify, extract the cryptographic message with
# extract-module-sig.pl from the kernel source

./extract-module-sig.pl -s out/hello-world-sha512-2keys > 
out/hello-world-sha512-2keys.sig 2> /dev/null
if ! cmp out/double-sig.p7s out/hello-world-sha512-2keys.sig ; then
        echo "Input signature and data from extract-module-sig.pl -s do not 
agree!"
        exit 1;
fi

# openssl's verify requires that _both_ signatures are made with
# embedded certs which validate against a trusted CA
openssl cms -verify -binary -in out/hello-world-sha512-2keys.sig -inform der \
            -content hello-world -CAfile ca.pem -out /dev/null
if [ $? -ne 0 ]; then
        echo "OpenSSL failed to verify with both keys"
        exit 1
fi

For our application, firmware will allow a grub binary to boot if any
of the signatures in the PKCS#7 message match a key that is trusted by
firmware. This should allow keys to be rotated with firmware releases
without breaking backwards compatibility.

I've updated https://github.com/daxtens/SLOF to demonstrate this: if
any signature can be validated by a built-in key, it will pass
verification.



Another thing that was raised was the ability to make multiple
signatures separated in time, where the second signer didn't have
access to the private keys for the first signer. The example given was
for someone to sign a distro binary with a second set of keys
(e.g. specific keys for a data center) - then the binary would be
bootable on machines with distro keys, and also on machines that have
only the second set of keys.

This is not so easy. For grub, with the elf note, the data over which
the signature is made contains the size of the signature. To add a
signature would be to change the size of the signature stored in the
signed data. That would either break the old signature, or we would need
to make it not a true appended signature any more: rather than being a
'dumb' signature over everything before the start of the appended
signature data, it'd be more complex. We'd need to teach the signer and
verifier how to deal with that, and then we've thrown away the
advantages of appended signatures and reinvented many of the
complexities of Authenticode.

One thing we could potentially do without going down that route is to
include a quantity of 'blank space' for signatures - we could for
example always allocate a few kilobytes for signatures. The distro
signatures would take up the first part of the buffer, leaving space
for some for 'user' signatures.

We can get this to work with the appended-signature format "as is": we
specify how big the PKCS#7 message is, and if the message happens to be
smaller than the size we give, both openssl and mbedtls will just ignore
any trailing data.

This does at least kinda-sorta work, but OpenSSL's 'cms -resign' command
only works if we include signed attributes and at the moment our mbedtls
implementation cannot handle that. I don't think the PKCS#7 standard
mandates that behaviour, so maybe we can hack around it with the OpenSSL
C API. Or maybe we can extend mbedtls to handle signed
attributes. (eek!)

The concern I have is that this approach creates a big block of
arbitrary unsigned data in the grub binary. An attacker under our threat
model (root on the host) could put any data they like into that space. I
worry that in combination with some other vulernability, this could be
used to more easily pass useful data in to grub. However, maybe that's
not that much of a win for the attacker: if they are root they also have
complete control of grub.cfg and can instruct grub to do quite a bit as
it is.

I'm also not sure that the use-case is quite as likely with Power
systems vs x86 systems. But if I'm overthinking the security
implications of a blank space in the binary, it seems like we could get
it to work and I'd be happy to chase it up further.

Thoughts? (on or off-list is fine.)

Kind regards,
Daniel

[1] https://linuxplumbersconf.org/event/7/contributions/738/
    https://youtu.be/IJUNxHnopH4?t=537

> More details are in patch 1, including a link to an open-source firmware
> capable of verifying a grub image signed this way.
>
> Daniel Axtens (2):
>   docs/grub: Document signing grub under UEFI
>   docs/grub: Document signing grub with an appended signature
>
> Rashmica Gupta (1):
>   Add suport for signing grub with an appended signature
>
>  docs/grub.texi              | 64 ++++++++++++++++++++++++++++++++++++-
>  include/grub/util/install.h |  8 +++--
>  include/grub/util/mkimage.h |  4 +--
>  util/grub-install-common.c  | 16 ++++++++--
>  util/grub-mkimage.c         | 11 +++++++
>  util/grub-mkimagexx.c       | 39 +++++++++++++++++++++-
>  util/mkimage.c              | 10 +++---
>  7 files changed, 138 insertions(+), 14 deletions(-)
>
> -- 
> 2.25.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]