summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_image_loader.c
diff options
context:
space:
mode:
authorAKASHI Takahiro <takahiro.akashi@linaro.org>2020-08-14 08:39:23 +0300
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2020-08-14 13:28:25 +0300
commit52956e535e65c852b1f95d2ca5044cb7c4fc6bbe (patch)
tree2e7e3317e17608b7c7c4c003fa15477b52d5b7b4 /lib/efi_loader/efi_image_loader.c
parentf68a6d583578799ec2011476ebd1e10590c6eb3c (diff)
downloadu-boot-52956e535e65c852b1f95d2ca5044cb7c4fc6bbe.tar.xz
efi_loader: signature: correct a behavior against multiple signatures
Under the current implementation, all the signatures, if any, in a signed image must be verified before loading it. Meanwhile, UEFI specification v2.8b section 32.5.3.3 says, Multiple signatures are allowed to exist in the binary’s certificate table (as per PE/COFF Section “Attribute Certificate Table”). Only one hash or signature is required to be present in db in order to pass validation, so long as neither the SHA-256 hash of the binary nor any present signature is reflected in dbx. This patch makes the semantics of signature verification compliant with the specification mentioned above. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Diffstat (limited to 'lib/efi_loader/efi_image_loader.c')
-rw-r--r--lib/efi_loader/efi_image_loader.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index 832bce9394..eea42cc204 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -546,6 +546,11 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
goto err;
}
+ if (efi_signature_lookup_digest(regs, dbx)) {
+ EFI_PRINT("Image's digest was found in \"dbx\"\n");
+ goto err;
+ }
+
/*
* go through WIN_CERTIFICATE list
* NOTE:
@@ -553,10 +558,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
* in PE header, or as pkcs7 SignerInfo's in SignedData.
* So the verification policy here is:
* - Success if, at least, one of signatures is verified
- * - unless
- * any of signatures is rejected explicitly, or
- * none of digest algorithms are supported
+ * - unless signature is rejected explicitly with its digest.
*/
+
for (wincert = wincerts, wincerts_end = (u8 *)wincerts + wincerts_len;
(u8 *)wincert < wincerts_end;
wincert = (WIN_CERTIFICATE *)
@@ -627,32 +631,29 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
/* try black-list first */
if (efi_signature_verify_one(regs, msg, dbx)) {
EFI_PRINT("Signature was rejected by \"dbx\"\n");
- goto err;
+ continue;
}
if (!efi_signature_check_signers(msg, dbx)) {
EFI_PRINT("Signer(s) in \"dbx\"\n");
- goto err;
- }
-
- if (efi_signature_lookup_digest(regs, dbx)) {
- EFI_PRINT("Image's digest was found in \"dbx\"\n");
- goto err;
+ continue;
}
/* try white-list */
- if (efi_signature_verify(regs, msg, db, dbx))
- continue;
+ if (efi_signature_verify(regs, msg, db, dbx)) {
+ ret = true;
+ break;
+ }
debug("Signature was not verified by \"db\"\n");
- if (efi_signature_lookup_digest(regs, db))
- continue;
+ if (efi_signature_lookup_digest(regs, db)) {
+ ret = true;
+ break;
+ }
debug("Image's digest was not found in \"db\" or \"dbx\"\n");
- goto err;
}
- ret = true;
err:
efi_sigstore_free(db);