diff options
author | Masahisa Kojima <masahisa.kojima@linaro.org> | 2021-05-26 12:09:58 +0900 |
---|---|---|
committer | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2021-05-28 16:17:01 +0200 |
commit | 163a0d7e2cbdbdf26d90ac8d30c0495b814f3245 (patch) | |
tree | e7ea6a6d79f9e4769f7fcb0c0c909992954a2423 /lib/efi_loader/efi_image_loader.c | |
parent | 464010b0be09505aaf50ec208f996a6cf478a2dc (diff) | |
download | u-boot-163a0d7e2cbdbdf26d90ac8d30c0495b814f3245.tar.gz |
efi_loader: add PE/COFF image measurement
"TCG PC Client Platform Firmware Profile Specification"
requires to measure every attempt to load and execute
a OS Loader(a UEFI application) into PCR[4].
This commit adds the PE/COFF image measurement, extends PCR,
and appends measurement into Event Log.
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
Replace CONFIG_HASH_CALCULATE by CONFIG_HASH
Fix conversions between pointers and u64.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Diffstat (limited to 'lib/efi_loader/efi_image_loader.c')
-rw-r--r-- | lib/efi_loader/efi_image_loader.c | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index fe1ee198e2..bcd57f7fcc 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -303,6 +303,38 @@ static int cmp_pe_section(const void *arg1, const void *arg2) } /** + * efi_prepare_aligned_image() - prepare 8-byte aligned image + * @efi: pointer to the EFI binary + * @efi_size: size of @efi binary + * + * If @efi is not 8-byte aligned, this function newly allocates + * the image buffer. + * + * Return: valid pointer to a image, return NULL if allocation fails. + */ +void *efi_prepare_aligned_image(void *efi, u64 *efi_size) +{ + size_t new_efi_size; + void *new_efi; + + /* + * Size must be 8-byte aligned and the trailing bytes must be + * zero'ed. Otherwise hash value may be incorrect. + */ + if (!IS_ALIGNED(*efi_size, 8)) { + new_efi_size = ALIGN(*efi_size, 8); + new_efi = calloc(new_efi_size, 1); + if (!new_efi) + return NULL; + memcpy(new_efi, efi, *efi_size); + *efi_size = new_efi_size; + return new_efi; + } else { + return efi; + } +} + +/** * efi_image_parse() - parse a PE image * @efi: Pointer to image * @len: Size of @efi @@ -561,7 +593,7 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) struct efi_signature_store *db = NULL, *dbx = NULL; void *new_efi = NULL; u8 *auth, *wincerts_end; - size_t new_efi_size, auth_size; + size_t auth_size; bool ret = false; EFI_PRINT("%s: Enter, %d\n", __func__, ret); @@ -569,21 +601,11 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) if (!efi_secure_boot_enabled()) return true; - /* - * Size must be 8-byte aligned and the trailing bytes must be - * zero'ed. Otherwise hash value may be incorrect. - */ - if (efi_size & 0x7) { - new_efi_size = (efi_size + 0x7) & ~0x7ULL; - new_efi = calloc(new_efi_size, 1); - if (!new_efi) - return false; - memcpy(new_efi, efi, efi_size); - efi = new_efi; - efi_size = new_efi_size; - } + new_efi = efi_prepare_aligned_image(efi, (u64 *)&efi_size); + if (!new_efi) + return false; - if (!efi_image_parse(efi, efi_size, ®s, &wincerts, + if (!efi_image_parse(new_efi, efi_size, ®s, &wincerts, &wincerts_len)) { EFI_PRINT("Parsing PE executable image failed\n"); goto err; @@ -725,7 +747,8 @@ err: efi_sigstore_free(dbx); pkcs7_free_message(msg); free(regs); - free(new_efi); + if (new_efi != efi) + free(new_efi); EFI_PRINT("%s: Exit, %d\n", __func__, ret); return ret; @@ -891,6 +914,13 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, goto err; } +#if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL) + /* Measure an PE/COFF image */ + if (tcg2_measure_pe_image(efi, efi_size, handle, + loaded_image_info)) + log_err("PE image measurement failed\n"); +#endif + /* Copy PE headers */ memcpy(efi_reloc, efi, sizeof(*dos) |