Skip to content

Add a utility to choose between Secure Boot loaders.#294

Merged
vathpela merged 29 commits intorhboot:mainfrom
vathpela:sbchooser
Mar 17, 2026
Merged

Add a utility to choose between Secure Boot loaders.#294
vathpela merged 29 commits intorhboot:mainfrom
vathpela:sbchooser

Conversation

@vathpela
Copy link
Copy Markdown
Member

@vathpela vathpela commented Mar 3, 2026

This adds a utility to choose between bootloaders based on UEFI trust databases, either enrolled on the local system or specified manually.

The idea here is that a distro will provide several of the same shim binary in their packaging, i.e. shimx64.msft2011.efi, shimx64.msft2023.efi, shimx64.msft2011.msft2023.efi, and it'll sort them by how appropriate they are for the current system (or test databases provided on the command line), so then the OS packaging or installer can determine what to actually install as the bootloader.

Note that this is on top of #298 .

@vathpela vathpela force-pushed the sbchooser branch 11 times, most recently from 0bbee93 to e74939b Compare March 4, 2026 19:29
@vathpela vathpela marked this pull request as ready for review March 4, 2026 19:45
@vathpela vathpela requested a review from nfrayer March 4, 2026 19:45
Comment thread docs/sbchooser.1.mdoc Outdated
@vathpela vathpela force-pushed the sbchooser branch 2 times, most recently from 0120844 to 162c9eb Compare March 9, 2026 17:24
@vathpela vathpela requested a review from jsetje March 9, 2026 17:24
Comment thread src/sbchooser.c
@marta-lewandowska
Copy link
Copy Markdown

sbchooser is working well for me now. Thank you for the changes. I also like the --explain option: it works well.

@Foxboron
Copy link
Copy Markdown

Fwiw, I ran this on my local machine with self-enrolled keys. Not the intended purpose for this tool, but it works and the output is sensible.

Signed-off-by: Peter Jones <pjones@redhat.com>
This adds a man page for sbchooser, including examples.

Signed-off-by: Peter Jones <pjones@redhat.com>
This is enough to describe basic signed PE binaries, I think.

Signed-off-by: Peter Jones <pjones@redhat.com>
This gets us a binary that builds for sbchooser, but doesn't add any
functionality yet.

Signed-off-by: Peter Jones <pjones@redhat.com>
This adds loading for db and dbx, either from efivars (default) or from
files on the command line.

v2 with suggestions from Morten Linderud <morten@linderud.pw>

Signed-off-by: Peter Jones <pjones@redhat.com>
This parses the db and dbx entries, extracts the relevant authenticode
hashes and x509 details, and provides the comparitor for determining
which certificate has the highest security strength based on its digest
and encryption algorithms.

Signed-off-by: Peter Jones <pjones@redhat.com>
This adds the main functions to parse a PE file.

Signed-off-by: Peter Jones <pjones@redhat.com>
This actually uses the PE loader and adds command line support for
loading some of them.

Signed-off-by: Peter Jones <pjones@redhat.com>
This allows us to use the sbchooser utility with a workflow like "sort".

Signed-off-by: Peter Jones <pjones@redhat.com>
vathpela added 20 commits March 17, 2026 16:21
This adds the authenticode hash algorithm itself, and also the code to
generate sha256, sha384, and sha512 hashes on a pe_file_t.

Signed-off-by: Peter Jones <pjones@redhat.com>
This adds checking for binaries with their hashes in db and/or dbx, and
helper functions to do something with the data which are currently
unused.

That includes the initial "scoring" of PE binaries, in this case just
based on if the hashes are in dbx or db.

Signed-off-by: Peter Jones <pjones@redhat.com>
This adds the infrastructure to sort according to how much we prefer
each PE file.

Currently the sort criteria is:

- revoked comes after non-revoked
- trusted comes before non-trusted
- lower security strength comes after higher security strength

And then revoked binaries and untrusted binaries are filtered on the
output pass.

Signed-off-by: Peter Jones <pjones@redhat.com>
db.msft2011					- db with the 2011 MS UEFI CA
db.msft2023					- db with 2023 UEFI CA
db.shim-13-0.2.fedora.x64.sha256		- db for shim-13 by sha256
db.shim-13-0.2.fedora.x64.sha384		- db for shim-13 by sha384
db.shim-13-0.2.fedora.x64.sha512		- db for shim-13 by sha512
db.shim-15-7.el7_2.x64.sha256			- db for shim-15-7 by sha256
db.shim-15-7.el7_2.x64.sha384			- db for shim-15-7 by sha384
db.shim-15-7.el7_2.x64.sha512			- db for shim-15-7 by sha512
shim-13-0.2.fedora.x64.nosigs.efi		- shim-13 with no signatures
shim-15-7.el7_2.x64.msft2011.efi		- shim-15-7 with 2011 sigs
shim-15-7.el7_2.x64.nosigs.efi			- shim-15-7 without sigs
shim-16.1-4.el10.x64.msft2011.efi		- shim with 2011 sig
shim-16.1-4.el10.x64.msft2023.efi		- shim with 2023 sig
shim-16.1-4.el10.x64.msft2011.msft2023.efi	- shim with both sigs

Signed-off-by: Peter Jones <pjones@redhat.com>
This test submits the following shims, each listed twice, in a random
order:

  shim-13-0.2.fedora.x64.nosigs.efi
  shim-15-7.el7_2.x64.nosigs.efi

Against a "db" which includes:
  The 2011 UEFI CA cert
  The 2023 UEFI CA cert
  The sha512 digest of shim-15-7.el7_2.x64.nosigs.efi
  The sha256 digest of shim-13-0.2.fedora.x64.nosigs.efi

This should produce the following output (annotated here):

shim-15-7.el7_2.x64.nosigs.efi - allowed by sha512 digest
shim-15-7.el7_2.x64.nosigs.efi - same
shim-13-0.2.fedora.x64.nosigs.efi - allowed by sha256
shim-13-0.2.fedora.x64.nosigs.efi - same

Signed-off-by: Peter Jones <pjones@redhat.com>
This parses the PE signatures and their participant certificates, but
it's not a hater.  It doesn't judge.  That's for later.

Signed-off-by: Peter Jones <pjones@redhat.com>
This adds helpers to determine if our certificates participating in PE
signatures are trusted or revoked by db or dbx.  They're not used just
yet.

Signed-off-by: Peter Jones <pjones@redhat.com>
This adds more helpers to propagate the trust information from our
certificates up to our signatures, and adds that evaluation to our PE
binary before doing comparisons.

A signature is trusted if any of the certificates participating in the
signature are trusted and none are revoked.

Signed-off-by: Peter Jones <pjones@redhat.com>
This evaluates how many bits of security each signature has, and adds
that and our certificate and signature trust metrics to the sorting
function for PEs.

Signed-off-by: Peter Jones <pjones@redhat.com>
This propagates the not_before and not_after dates on each certificate
up through signatures to the PE files themselves as
"earliest_not_before" and "latest_not_after", and adds those as
comparisons of last resort when sorting PE binaries.

Signed-off-by: Peter Jones <pjones@redhat.com>
This test submits the following shims, each listed twice, in a random
order:

  shim-13-0.2.fedora.x64.nosigs.efi
  shim-15-7.el7_2.x64.nosigs.efi

Against a "db" which includes:
  The 2011 UEFI CA cert
  The 2023 UEFI CA cert
  The sha512 digest of shim-15-7.el7_2.x64.nosigs.efi

This should produce the following output (annotated here):

shim-15-7.el7_2.x64.nosigs.efi - allowed by sha512 digest
shim-15-7.el7_2.x64.nosigs.efi - same

Signed-off-by: Peter Jones <pjones@redhat.com>
This test submits the following shims, each listed twice, in a random
order:

  shim-13-0.2.fedora.x64.nosigs.efi
  shim-15-7.el7_2.x64.nosigs.efi

Against a "db" which includes:
  The 2011 UEFI CA cert
  The 2023 UEFI CA cert
  The sha512 digest of shim-15-7.el7_2.x64.nosigs.efi
  The sha256 digest of shim-13-0.2.fedora.x64.nosigs.efi

And a "dbx" which includes:
  The sha256 digest of shim-13-0.2.fedora.x64.nosigs.efi

This should produce the following output (annotated here):

shim-15-7.el7_2.x64.nosigs.efi - allowed by sha512 digest
shim-15-7.el7_2.x64.nosigs.efi - same

Signed-off-by: Peter Jones <pjones@redhat.com>
This test submits the following shims, each listed twice, in a random
order:

  shim-13-0.2.fedora.x64.nosigs.efi
  shim-15-7.el7_2.x64.msft2011.efi

Against a "db" which includes:
  The 2011 UEFI CA cert
  The sha512 digest of shim-13-0.2.fedora.x64.nosigs.efi

This should produce the following output (annotated here):

shim-13-0.2.fedora.x64.nosigs.efi - allowed by sha512 digest (strength 256)
shim-13-0.2.fedora.x64.nosigs.efi - same
shim-15-7.el7_2.x64.msft2011.efi - allowed by cert (strength 112)
shim-15-7.el7_2.x64.msft2011.efi - same

Signed-off-by: Peter Jones <pjones@redhat.com>
This test submits the following shims, each listed twice, in a random
order:

  shim-15-7.el7_2.x64.msft2011.efi
  shim-16.1-4.el10.x64.msft2011.msft2023.efi

Against a "db" which includes:
  The 2011 UEFI CA cert
  The 2023 UEFI CA cert

and a "dbx" which includes:
  The 2011 UEFI CA cert

This should produce the following output (annotated here):

shim-16.1-4.el10.x64.msft2011.msft2023.efi - allowed by 2023 cert
shim-16.1-4.el10.x64.msft2011.msft2023.efi - same

Signed-off-by: Peter Jones <pjones@redhat.com>
This test submits the following shims, each listed twice, in a random
order:

  shim-16.1-4.el10.x64.msft2011.efi
  shim-16.1-4.el10.x64.msft2011.msft2023.efi
  shim-16.1-4.el10.x64.msft2023.efi

Against a "db" which includes:
  The 2011 UEFI CA cert
  The 2023 UEFI CA cert

and a "dbx" which includes:
  The 2011 UEFI CA cert

This should produce the following output (annotated here):

shim-16.1-4.el10.x64.msft2011.msft2023.efi - allowed by 2023 cert
shim-16.1-4.el10.x64.msft2011.msft2023.efi - same
shim-16.1-4.el10.x64.msft2023.efi - allowed by 2023 cert but starts later
shim-16.1-4.el10.x64.msft2023.efi - same

Signed-off-by: Peter Jones <pjones@redhat.com>
On some truly buggy machines, I still think[0] we might see a case where
only the first signature is trusted.  This lets us build the support for
a user to permanently tell us to only use the first signature.

[0] Despite /some/ growing amount of evidence

Signed-off-by: Peter Jones <pjones@redhat.com>
This test submits the following shims, each listed twice, in a random
order:

  shim-16.1-4.el10.x64.msft2011.efi
  shim-16.1-4.el10.x64.msft2011.msft2023.efi
  shim-16.1-4.el10.x64.msft2023.efi

Against a "db" which includes:
  The 2023 UEFI CA cert

This test puts "--first-sig-only" on the sbchooser command line, so all
but the first signature on each input should be ignored.

This should produce the following output (annotated here):

shim-16.1-4.el10.x64.msft2023.efi - allowed by 2023 cert
shim-16.1-4.el10.x64.msft2023.efi - same

Note that shim-16.1-4.el10.x64.msft2011.msft2023.efi is not included,
because its first signature is with the 2011 cert.

Signed-off-by: Peter Jones <pjones@redhat.com>
This adds an explainer mode to sbchooser, which attempts to tell the
user which PE binaries are allowed based on which db entries they are
trusted or revoked by.

v2 with suggestions from Morten Linderud <morten@linderud.pw>

Signed-off-by: Peter Jones <pjones@redhat.com>
"pesign -u 1 -r -i shimx64.msft2011.msft2023.efi -o shimx64.msft2011.efi"
leaves a security directory with one byte of padding at the end, causing
the parser here to read off the end of the binary and treat that as the
cert length, which makes it spin forever.

This patch checks for if there's actually enough size for the wincert
header and stops if there's not.

Additionally, I don't see anything in the spec that says it couldn't be
zero-padded quite a bit more, so if we find wincert->length to be 0, we
also stop iterating.

Signed-off-by: Peter Jones <pjones@redhat.com>
This test submits the following shims, each listed twice, in a random
order:

  shim-16.1-6.x64.onesig.efi
  shim-16.1-6.x64.onesig.efi

Against a "db" which includes:
  The 2011 UEFI CA cert

and a "dbx" which includes:
  nothing

This should produce the following output:

shim-16.1-6.x64.onesig.efi is trusted because cert "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Windows UEFI Driver Publisher" is trusted by "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Corporation UEFI CA 2011" in db
shim-16.1-6.x64.onesig.efi is trusted because cert "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Windows UEFI Driver Publisher" is trusted by "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Corporation UEFI CA 2011" in db

Signed-off-by: Peter Jones <pjones@redhat.com>
@vathpela vathpela merged commit ac9cc70 into rhboot:main Mar 17, 2026
6 checks passed
@vathpela vathpela deleted the sbchooser branch March 17, 2026 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants