summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_image_loader.c
diff options
context:
space:
mode:
authorAKASHI Takahiro <takahiro.akashi@linaro.org>2022-07-05 08:48:14 +0300
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2022-07-05 15:37:16 +0300
commit634f6b2fb1056021fba603ccb7488d1864787576 (patch)
tree055a12c85f577b63233ec6f8a35658cf5c134ae5 /lib/efi_loader/efi_image_loader.c
parentb72d09fa7df75d56d2b618ce029bc8b001ed276b (diff)
downloadu-boot-634f6b2fb1056021fba603ccb7488d1864787576.tar.xz
efi_loader: image_loader: add a missing digest verification for signed PE image
At the last step of PE image authentication, an image's hash value must be compared with a message digest stored as the content (of SpcPeImageData type) of pkcs7's contentInfo. Fixes: commit 4540dabdcaca ("efi_loader: image_loader: support image authentication") 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.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index fe8e4a8908..eaf75a5803 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -16,6 +16,7 @@
#include <malloc.h>
#include <pe.h>
#include <sort.h>
+#include <crypto/mscode.h>
#include <crypto/pkcs7_parser.h>
#include <linux/err.h>
@@ -517,6 +518,51 @@ err:
#ifdef CONFIG_EFI_SECURE_BOOT
/**
+ * efi_image_verify_digest - verify image's message digest
+ * @regs: Array of memory regions to digest
+ * @msg: Signature in pkcs7 structure
+ *
+ * @regs contains all the data in a PE image to digest. Calculate
+ * a hash value based on @regs and compare it with a messaged digest
+ * in the content (SpcPeImageData) of @msg's contentInfo.
+ *
+ * Return: true if verified, false if not
+ */
+static bool efi_image_verify_digest(struct efi_image_regions *regs,
+ struct pkcs7_message *msg)
+{
+ struct pefile_context ctx;
+ void *hash;
+ int hash_len, ret;
+
+ const void *data;
+ size_t data_len;
+ size_t asn1hdrlen;
+
+ /* get pkcs7's contentInfo */
+ ret = pkcs7_get_content_data(msg, &data, &data_len, &asn1hdrlen);
+ if (ret < 0 || !data)
+ return false;
+
+ /* parse data and retrieve a message digest into ctx */
+ ret = mscode_parse(&ctx, data, data_len, asn1hdrlen);
+ if (ret < 0)
+ return false;
+
+ /* calculate a hash value of PE image */
+ hash = NULL;
+ if (!efi_hash_regions(regs->reg, regs->num, &hash, ctx.digest_algo,
+ &hash_len))
+ return false;
+
+ /* match the digest */
+ if (ctx.digest_len != hash_len || memcmp(ctx.digest, hash, hash_len))
+ return false;
+
+ return true;
+}
+
+/**
* efi_image_authenticate() - verify a signature of signed image
* @efi: Pointer to image
* @efi_size: Size of @efi
@@ -645,6 +691,9 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
}
/*
+ * verify signatures in pkcs7's signedInfos which are
+ * to authenticate the integrity of pkcs7's contentInfo.
+ *
* NOTE:
* UEFI specification defines two signature types possible
* in signature database:
@@ -677,12 +726,21 @@ static bool efi_image_authenticate(void *efi, size_t efi_size)
}
/* try white-list */
- if (efi_signature_verify(regs, msg, db, dbx)) {
+ if (!efi_signature_verify(regs, msg, db, dbx)) {
+ log_debug("Signature was not verified by \"db\"\n");
+ continue;
+ }
+
+ /*
+ * now calculate an image's hash value and compare it with
+ * a messaged digest embedded in pkcs7's contentInfo
+ */
+ if (efi_image_verify_digest(regs, msg)) {
ret = true;
continue;
}
- log_debug("Signature was not verified by \"db\"\n");
+ log_debug("Message digest doesn't match\n");
}