[Top][All Lists]

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

[PATCH 00/18] Verify appended signatures from grub

From: Daniel Axtens
Subject: [PATCH 00/18] Verify appended signatures from grub
Date: Fri, 2 Oct 2020 15:13:03 +1000

Part of a secure boot chain is allowing grub to verify the boot
kernel. For UEFI platforms, this is usually delegated to the shim: see
shim_lock.c. However, for platforms that do not implement UEFI, an
alternative scheme is required.

This series teaches grub how to verify Linux kernel-style 'appended
signatures'. I talked about this in my recent Linux Plumbers talk: and

In very short, an appended signature is a 'dumb' signature over the
contents of a file. (It is distinct from schemes like Authenticode
that are aware of the structure of the file and only sign certain
parts.) The signature is wrapped in a PKCS#7 message, and is appended
to the signed file along with some metadata and a magic string. The
signatures are validated against a public key which is usually
provided as an x509 certificate. Kernels on powerpc are already signed
with this scheme and can be verified by IMA for kexec.

As PKCS#7 messages and x509 certificates are both based on ASN.1, we
import libtasn1 to parse them. Because ASN.1 isn't self-documenting,
we import from GNUTLS the information we need to navigate their

This is a long series but it breaks down into some nice 'chunks':

 - patches 1 and 2 fix some documentation quirks I encountered
 - patch 3 is a small fix to allow persistent modules to work on the
   emu target.

 - patches 4 to 6 are small refactorings, mostly so I can reuse some
   code later.

 - patch 7 prepares posix_wrap for importing libtasn1

 - patches 8 through 12 import libtasn1 and add tests. I've taken a
   different approach from gcrypt. We import gcrypt via a script that
   transforms the code into something that works for grub. We import
   libtasn1 through first just copying a subset of the code in (patch
   8), then disabling parts we don't need for grub (patch 9), making
   changes for grub compatibility (patch 10) and then compiling it
   into a module (patch 11) and testing it (patch 12).

   This means that should we want to upgrade our version of libtasn1,
   we should be able to copy the new files in (repeat the process in
   patch 8) and then just cherry-pick/reapply patches 9 and 10 to
   repeat the process of disabling unused code and making grub
   compatiblity fixes. Hopefully that makes sense!

 - patch 13 allows x509 certificates to be built in to the grub core
   in much the same way as PGP keys.

 - patch 14 brings in the code from GNUTLS that allows us to parse
   PKCS#7 and x509 with libtasn1.

 - patch 15 is our PKCS#7 and x509 parser. They're minimal and fairly
   strict parsers that extract only the bits we need to verify the

 - patch 16 is the guts of the appended signature verifier. It uses
   the verifier infrastructure like shim_lock and pgp, and adds a
   number of user-friendly commands that mirror the pgp module.

 - patch 17 adds tests, and patch 18 adds documentation.

The series applies on top of the previous series to allow grub itself
to be signed with an appended signature:
The only dependency is that both that series and patch 13 of this
series touch the grub-install/grub-mkimage code.

I'm a little worried that patch 8 won't make it to the mailing list
due to its size, so I've also pushed this to
That branch also contains the previous series.

This patch series is easy to experiment with: it doesn't require any
particular platform. It works under emu and passes tests under

(Ironically, if you want to experiment with it on powerpc, you will
need another patch to allocate more than 32MB of memory. You can
grub-core/kern/ieee1275/init.c, or there's an even crazier patch in my
github branch that just grabs ~half of all available memory. We're
working internally on what the 'right' solution is and will send a
followup patch.)

This series implements enforcement similarly to the PGP verifier:
enforcement is controlled by an environment variable that can be reset
on the command line or via load_env. The series does not - in current
form - provide the same sort of guarantees as UEFI secure boot. I've
done this because I'm conscious of the long history of software
freedom concerns that have accompanied strong secure-boot

However, I'm also conscious of user requirements for UEFI-style secure
boot chains. I'll be posting another patch in the coming days that
links signature enforcement to a device-tree property
(/ibm,secure-boot) which is set on Power LPAR secure boot. If that
property is set, the forthcoming patch also prevents enforcement from
being disabled on the command line. My hope is that by doing this in
two stages, we can discuss whether this series is acceptable for
upstream separately from any discussions about whether linking
platform-secure-boot to signature enforcement is acceptable.

I'm not expecting this to land upstream for 2.06. Patches 1 and 2
might be suitable but I don't really mind either way. Having said
that, I'd appreciate any feedback before then.

Alastair D'Silva (1):
  grub-install: support embedding x509 certificates

Daniel Axtens (17):
  docs/grub: grub-install is no longer a shell script
  docs/grub: --pubkey has been supported for some time
  dl: provide a fake grub_dl_set_persistent for the emu target
  verifiers: factor unsafe module handling out of shim_lock
  pgp: factor out rsa_pad
  crypto: move storage for grub_crypto_pk_* to crypto.c
  posix_wrap: tweaks in preparation for libtasn1
  libtasn1: import libtasn1-4.16.0
  libtasn1: disable code not needed in grub
  libtasn1: changes for grub compatibility
  libtasn1: compile into asn1 module
  test_asn1: test module for libtasn1
  appended signatures: import GNUTLS's ASN.1 description files
  appended signatures: parse PKCS#7 signedData and X.509 certificates
  appended signatures: support verifying appended signatures
  appended signatures: verification tests
  appended signatures: documentation

 .gitignore                                    |    1 +
 Makefile.util.def                             |    6 +
 docs/grub.texi                                |  208 +-
 grub-core/Makefile.core.def                   |   54 +
 grub-core/commands/appendedsig/appendedsig.c  |  644 +++++
 grub-core/commands/appendedsig/appendedsig.h  |  110 +
 grub-core/commands/appendedsig/asn1util.c     |  102 +
 .../commands/appendedsig/gnutls_asn1_tab.c    |  121 +
 grub-core/commands/appendedsig/pkcs7.c        |  305 ++
 .../commands/appendedsig/pkix_asn1_tab.c      |  484 ++++
 grub-core/commands/appendedsig/x509.c         |  958 +++++++
 grub-core/commands/efi/shim_lock.c            |   45 +-
 grub-core/commands/pgp.c                      |   34 +-
 grub-core/commands/verifiers.c                |   46 +
 grub-core/lib/crypto.c                        |    4 +
 grub-core/lib/libtasn1/LICENSE                |   16 +
 grub-core/lib/libtasn1/              |   91 +
 grub-core/lib/libtasn1/lib/coding.c           | 1423 ++++++++++
 grub-core/lib/libtasn1/lib/decoding.c         | 2481 +++++++++++++++++
 grub-core/lib/libtasn1/lib/element.c          | 1112 ++++++++
 grub-core/lib/libtasn1/lib/element.h          |   40 +
 grub-core/lib/libtasn1/lib/errors.c           |  103 +
 grub-core/lib/libtasn1/lib/gstr.c             |   74 +
 grub-core/lib/libtasn1/lib/gstr.h             |   47 +
 grub-core/lib/libtasn1/lib/int.h              |  221 ++
 grub-core/lib/libtasn1/lib/parser_aux.c       | 1174 ++++++++
 grub-core/lib/libtasn1/lib/parser_aux.h       |  172 ++
 grub-core/lib/libtasn1/lib/structure.c        | 1222 ++++++++
 grub-core/lib/libtasn1/lib/structure.h        |   45 +
 .../tests/CVE-2018-1000654-1_asn1_tab.h       |   32 +
 .../tests/CVE-2018-1000654-2_asn1_tab.h       |   36 +
 .../libtasn1_wrap/tests/CVE-2018-1000654.c    |   61 +
 .../lib/libtasn1_wrap/tests/Test_overflow.c   |  138 +
 .../lib/libtasn1_wrap/tests/Test_simple.c     |  207 ++
 .../lib/libtasn1_wrap/tests/Test_strings.c    |  150 +
 .../libtasn1_wrap/tests/object-id-decoding.c  |  116 +
 .../libtasn1_wrap/tests/object-id-encoding.c  |  120 +
 .../lib/libtasn1_wrap/tests/octet-string.c    |  211 ++
 .../lib/libtasn1_wrap/tests/reproducers.c     |   81 +
 grub-core/lib/libtasn1_wrap/wrap.c            |   26 +
 grub-core/lib/libtasn1_wrap/wrap_tests.c      |   75 +
 grub-core/lib/libtasn1_wrap/wrap_tests.h      |   38 +
 grub-core/lib/pkcs1_v15.c                     |   59 +
 grub-core/lib/posix_wrap/limits.h             |    1 +
 grub-core/lib/posix_wrap/stdlib.h             |    8 +
 grub-core/lib/posix_wrap/sys/types.h          |    1 +
 grub-core/tests/appended_signature_test.c     |  250 ++
 grub-core/tests/appended_signatures.h         |  483 ++++
 grub-core/tests/lib/functional_test.c         |    1 +
 include/grub/dl.h                             |   11 +
 include/grub/file.h                           |    2 +
 include/grub/kernel.h                         |    3 +-
 include/grub/libtasn1.h                       |  589 ++++
 include/grub/pkcs1_v15.h                      |   27 +
 include/grub/util/install.h                   |    7 +-
 include/grub/verify.h                         |   13 +
 tests/                            |   12 +
 util/grub-install-common.c                    |   23 +-
 util/grub-mkimage.c                           |   15 +-
 util/mkimage.c                                |   41 +-
 60 files changed, 14080 insertions(+), 100 deletions(-)
 create mode 100644 grub-core/commands/appendedsig/appendedsig.c
 create mode 100644 grub-core/commands/appendedsig/appendedsig.h
 create mode 100644 grub-core/commands/appendedsig/asn1util.c
 create mode 100644 grub-core/commands/appendedsig/gnutls_asn1_tab.c
 create mode 100644 grub-core/commands/appendedsig/pkcs7.c
 create mode 100644 grub-core/commands/appendedsig/pkix_asn1_tab.c
 create mode 100644 grub-core/commands/appendedsig/x509.c
 create mode 100644 grub-core/lib/libtasn1/LICENSE
 create mode 100644 grub-core/lib/libtasn1/
 create mode 100644 grub-core/lib/libtasn1/lib/coding.c
 create mode 100644 grub-core/lib/libtasn1/lib/decoding.c
 create mode 100644 grub-core/lib/libtasn1/lib/element.c
 create mode 100644 grub-core/lib/libtasn1/lib/element.h
 create mode 100644 grub-core/lib/libtasn1/lib/errors.c
 create mode 100644 grub-core/lib/libtasn1/lib/gstr.c
 create mode 100644 grub-core/lib/libtasn1/lib/gstr.h
 create mode 100644 grub-core/lib/libtasn1/lib/int.h
 create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.c
 create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.h
 create mode 100644 grub-core/lib/libtasn1/lib/structure.c
 create mode 100644 grub-core/lib/libtasn1/lib/structure.h
 create mode 100644 
 create mode 100644 
 create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c
 create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_overflow.c
 create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_simple.c
 create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_strings.c
 create mode 100644 grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c
 create mode 100644 grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c
 create mode 100644 grub-core/lib/libtasn1_wrap/tests/octet-string.c
 create mode 100644 grub-core/lib/libtasn1_wrap/tests/reproducers.c
 create mode 100644 grub-core/lib/libtasn1_wrap/wrap.c
 create mode 100644 grub-core/lib/libtasn1_wrap/wrap_tests.c
 create mode 100644 grub-core/lib/libtasn1_wrap/wrap_tests.h
 create mode 100644 grub-core/lib/pkcs1_v15.c
 create mode 100644 grub-core/tests/appended_signature_test.c
 create mode 100644 grub-core/tests/appended_signatures.h
 create mode 100644 include/grub/libtasn1.h
 create mode 100644 include/grub/pkcs1_v15.h
 create mode 100644 tests/


reply via email to

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