Provide a mechanism for a physically present end user to disable the use
of db when doing signature verification. This is handled by the OS passing
down a variable that contains a UINT32 and a SHA256 hash. If this variable
is present, MokManager prompts the user to choose whether to enable or
disable the use of db for verification purposes (depending on the value of
the UINT32). They are then asked to type the passphrase that matches the
hash. This then saves a boot services variable which is checked by shim,
and if set will cause shim to not use db for verification purposes. If
db is to be ignored, shim will export a runtime variable called
'MokIgnoreDB' for the OS to query at runtime.
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
This shouldn't be exploitable unless you've got a way to make
InstallProtocol fail and still, for example, have memory free to
actually load and run something.
Signed-off-by: Peter Jones <pjones@redhat.com>
It works like this: during startup of shim, we hook into the system's
ExitBootServices() and StartImage(). If the system's StartImage() is
called, we automatically unhook, because we're chainloading to something
the system can verify.
When shim's verify is called, we record what kind of certificate the
image was verified against. If the call /succeeds/, we remove our
hooks.
If ExitBootServices() is called, we check how the bootloader verified
whatever it is loading. If it was verified by its hash, we unhook
everything and call the system's EBS(). If it was verified by
certificate, we check if it has called shim_verify(). If it has, we
unhook everything and call the system's EBS()
If the bootloader has not verified anything, and is itself verified by
a certificate, we display a security violation warning and halt the
machine.
This moves them both to be computed at runtime from a pointer+offset
rather than just a pointer, so that their real address can be entirely
derived from the section they're in.
This means you can replace the whole .vendor_cert section with a new one
with certs that don't have the same size.
- The file path from DevicePathToStr may use slash as the file
seperator. Change all slashes to backslashes to avoid the strange
bootpath.
- Remove the redundant backslashes.
- ImagePath no longer requires the leading backslash.
- Fix a memory leak
Based on the patch from Michal Marek <mmarek@suse.com>
A wrong pointer was being passed to EFI_PXE_BASE_CODE_TFTP_READ_FILE,
preventing us from getting the file size back from the tftp call, ensuring
that we don't have enough information to properly secureboot-validate the
retrieved image.
Right now the CA is checking if shim builds expose a particular version
of the shim protocol. To do this, they're looking for SHIM_LOCK_GUID's
value in the resulting binary.
Currently, with SHIM_LOCK_GUID as a macro that gets assigned to local
variables, that means they have to compensate for mov instructions mixed
in with the actual value. This is completely absurd, so promote it to a
first-class object with a symbol to make it both easy to find and
continuous.
Signed-off-by: Peter Jones <pjones@redhat.com>
The previous commit, 14d4b8e, caused shim failed to parse the name
of the 2nd stage loader in UEFI shell. Amend parsing of the name the
2nd stage loader to be compatible with UEFI shell.
To create an boot entry for elilo.efi:
# efibootmgr -c -L "shim elilo" -l "efi\\shim.efi" -u "shim.efi elilo.efi"
Sometimes when we're creating paths, the ImagePath can contain the
directory name already. If that happens, don't add it in again.
Signed-off-by: Peter Jones <pjones@redhat.com>
If li->LoadOptions tells us to execute our own binary, it's clearly not
what we want to do for the second stage. So simply ignore that case.
Signed-off-by: Peter Jones <pjones@redhat.com>
This commit replaces the 2nd stage loader path with the first
argument in the Load Options and moves the rest arguments (if any)
to the Load Options for the 2nd stage loader.
For example, to make shim to load elilo.efi, just create a new
boot entry with efibootmgr:
# efibootmgr -c -L "shim elilo" -l "efi\\shim.efi" -u "elilo.efi"
shim needs to verify that MokManager hasn't been modified, but we want to
be able to support configurations where shim is shipped without a vendor
certificate. This patch adds support for generating a certificate at build
time, incorporating the public half into shim and signing MokManager with
the private half. It uses pesign and nss, but still requires openssl for
key generation. Anyone using sbsign will need to figure this out for
themselves.
Cert needs to be modified inside the Index loop, not outside it. This is unlikely to
ever trigger since there will typically only be one X509 certificate per
EFI_SIGNATURE_LIST, but fix it anyway.
read_header would fail if the binary was unsigned, even if we weren't then
going to verify the signature. Move that check to the verify function
instead.
In some rare corner cases, it's useful to add a blacklist of things that
were allowed by a copy of shim that was never signed by the UEFI signing
service. In these cases it's okay for them to go into a local dbx,
rather than taking up precious flash.
Signed-off-by: Peter Jones <pjones@redhat.com>
Add support for setting an MOK password. The OS passes down a password hash.
MokManager then presents an option for setting a password. Selecting it
prompts the user for the same password again. If they match, the hash is
enrolled into a boot services variable and MokManager will prompt for the
password whenever it's started.
Provide a mechanism for a physically present end user to disable signature
verification. This is handled by the OS passing down a variable that
contains a UINT32 and a SHA256 hash. If this variable is present, MokManager
prompts the user to choose whether to enable or disable signature validation
(depending on the value of the UINT32). They are then asked to type the
passphrase that matches the hash. This then saves a boot services variable
which is checked by shim, and if set will skip verification of signatures.
Some systems will show an error dialog if LoadImage() returned
EFI_ACCESS_DENIED, which then requires physical user interaction to skip.
Let's just remove the LoadImage/StartImage code, since the built-in code
is theoretically equivalent.
Using the same format as the UEFI key databases makes it easier for the
kernel to parse and extract keys from MOK, and also permits MOK to contain
multiple key or hash types. Additionally, add support for enrolling hashes.
If we can't verify grub, fall back to MokManager. This permits shipping a
copy of shim and MokManager without distributing a key, letting
distributions provide their own for user installation.
The break in check_db_cert is at the wrong level due to a typo in
indentation, and as a result only the last cert in the list can
correctly match. Rectify that.
Signed-off-by: Peter Jones <pjones@redhat.com>