summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_image_loader.c
diff options
context:
space:
mode:
authorAKASHI Takahiro <takahiro.akashi@linaro.org>2020-07-08 08:01:56 +0300
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2020-07-12 00:14:15 +0300
commit11bafb259648dea054e07dc5c8003eb8c736f36c (patch)
tree4e66b928a431a4643041e53126d9a64cd61aff39 /lib/efi_loader/efi_image_loader.c
parent1e64d0b5a4ca8de67e79f332dd4d51a243f51eb8 (diff)
downloadu-boot-11bafb259648dea054e07dc5c8003eb8c736f36c.tar.xz
efi_loader: image_loader: verification for all signatures should pass
A signed image may have multiple signatures in - each WIN_CERTIFICATE in authenticode, and/or - each SignerInfo in pkcs7 SignedData (of WIN_CERTIFICATE) In the initial implementation of efi_image_authenticate(), the criteria of verification check for multiple signatures case is a bit ambiguous and it may cause inconsistent result. With this patch, we will make sure that verification check in efi_image_authenticate() should pass against all the signatures. The only exception would be - the case where a digest algorithm used in signature is not supported by U-Boot, or - the case where parsing some portion of authenticode has failed In those cases, we don't know how the signature be handled and should just ignore them. Please note that, due to this change, efi_signature_verify_with_sigdb()'s function prototype will be modified, taking "dbx" as well as "db" instead of outputing a "certificate." If "dbx" is null, the behavior would be the exact same as before. The function's name will be changed to efi_signature_verify() once current efi_signature_verify() has gone due to further improvement in intermediate certificates support. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Diffstat (limited to 'lib/efi_loader/efi_image_loader.c')
-rw-r--r--lib/efi_loader/efi_image_loader.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index de230409e3..058359fc25 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -448,13 +448,13 @@ static bool efi_image_unsigned_authenticate(struct efi_image_regions *regs)
}
/* try black-list first */
- if (efi_signature_verify_with_sigdb(regs, NULL, dbx, NULL)) {
+ if (efi_signature_verify_one(regs, NULL, dbx)) {
EFI_PRINT("Image is not signed and rejected by \"dbx\"\n");
goto out;
}
/* try white-list */
- if (efi_signature_verify_with_sigdb(regs, NULL, db, NULL))
+ if (efi_signature_verify_one(regs, NULL, db))
ret = true;
else
EFI_PRINT("Image is not signed and not found in \"db\" or \"dbx\"\n");
@@ -494,12 +494,13 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
size_t wincerts_len;
struct pkcs7_message *msg = NULL;
struct efi_signature_store *db = NULL, *dbx = NULL;
- struct x509_certificate *cert = NULL;
void *new_efi = NULL;
u8 *auth, *wincerts_end;
size_t new_efi_size, auth_size;
bool ret = false;
+ debug("%s: Enter, %d\n", __func__, ret);
+
if (!efi_secure_boot_enabled())
return true;
@@ -545,7 +546,17 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
goto err;
}
- /* go through WIN_CERTIFICATE list */
+ /*
+ * go through WIN_CERTIFICATE list
+ * NOTE:
+ * We may have multiple signatures either as WIN_CERTIFICATE's
+ * 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
+ */
for (wincert = wincerts, wincerts_end = (u8 *)wincerts + wincerts_len;
(u8 *)wincert < wincerts_end;
wincert = (WIN_CERTIFICATE *)
@@ -595,42 +606,32 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
}
/* try black-list first */
- if (efi_signature_verify_with_sigdb(regs, msg, dbx, NULL)) {
+ if (efi_signature_verify_one(regs, msg, dbx)) {
EFI_PRINT("Signature was rejected by \"dbx\"\n");
goto err;
}
- if (!efi_signature_verify_signers(msg, dbx)) {
- EFI_PRINT("Signer was rejected by \"dbx\"\n");
+ if (!efi_signature_check_signers(msg, dbx)) {
+ EFI_PRINT("Signer(s) in \"dbx\"\n");
goto err;
- } else {
- ret = true;
}
/* try white-list */
- if (!efi_signature_verify_with_sigdb(regs, msg, db, &cert)) {
- EFI_PRINT("Verifying signature with \"db\" failed\n");
+ if (!efi_signature_verify_with_sigdb(regs, msg, db, dbx)) {
+ EFI_PRINT("Signature was not verified by \"db\"\n");
goto err;
- } else {
- ret = true;
- }
-
- if (!efi_signature_verify_cert(cert, dbx)) {
- EFI_PRINT("Certificate was rejected by \"dbx\"\n");
- goto err;
- } else {
- ret = true;
}
}
+ ret = true;
err:
- x509_free_certificate(cert);
efi_sigstore_free(db);
efi_sigstore_free(dbx);
pkcs7_free_message(msg);
free(regs);
free(new_efi);
+ debug("%s: Exit, %d\n", __func__, ret);
return ret;
}
#else