From c16671b803cbb366fa95d2faf233ecf415d5dd50 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Tue, 5 Jul 2022 14:48:14 +0900 Subject: [PATCH] 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 c1d77f71ac2c ("efi_loader: image_loader: support image authentication") Signed-off-by: AKASHI Takahiro --- lib/efi_loader/Kconfig | 1 + lib/efi_loader/efi_image_loader.c | 62 ++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index e2a1a5a69a..e3f2402d0e 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -366,6 +366,7 @@ config EFI_SECURE_BOOT select X509_CERTIFICATE_PARSER select PKCS7_MESSAGE_PARSER select PKCS7_VERIFY + select MSCODE_PARSER select EFI_SIGNATURE_SUPPORT help Select this option to enable EFI secure boot support. 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 #include #include +#include #include #include @@ -516,6 +517,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 @@ -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"); } -- 2.39.5