diff options
Diffstat (limited to 'lib/efi_loader')
-rw-r--r-- | lib/efi_loader/Kconfig | 10 | ||||
-rw-r--r-- | lib/efi_loader/Makefile | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_file.c | 2 | ||||
-rw-r--r-- | lib/efi_loader/efi_freestanding.c | 8 | ||||
-rw-r--r-- | lib/efi_loader/efi_gop.c | 2 | ||||
-rw-r--r-- | lib/efi_loader/efi_image_loader.c | 8 | ||||
-rw-r--r-- | lib/efi_loader/efi_riscv.c | 60 | ||||
-rw-r--r-- | lib/efi_loader/efi_setup.c | 6 | ||||
-rw-r--r-- | lib/efi_loader/efi_signature.c | 54 | ||||
-rw-r--r-- | lib/efi_loader/helloworld.c | 2 |
10 files changed, 134 insertions, 19 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 24f9a2b..e5e35fe 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -369,4 +369,14 @@ config EFI_ESRT help Enabling this option creates the ESRT UEFI system table. +config EFI_RISCV_BOOT_PROTOCOL + bool "RISCV_EFI_BOOT_PROTOCOL support" + default y + depends on RISCV + help + The EFI_RISCV_BOOT_PROTOCOL is used to transfer the boot hart ID + to the next boot stage. It should be enabled as it is meant to + replace the transfer via the device-tree. The latter is not + possible on systems using ACPI. + endif diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index fd344ce..b2c664d 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_GENERATE_ACPI_TABLE) += efi_acpi.o obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o +obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += efi_signature.o diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 9aa0030..7a7077e 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -1084,7 +1084,7 @@ static const struct efi_file_handle efi_file_handle_protocol = { * efi_file_from_path() - open file via device path * * @fp: device path - * @return: EFI_FILE_PROTOCOL for the file or NULL + * Return: EFI_FILE_PROTOCOL for the file or NULL */ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) { diff --git a/lib/efi_loader/efi_freestanding.c b/lib/efi_loader/efi_freestanding.c index bd0dff1..c85df02 100644 --- a/lib/efi_loader/efi_freestanding.c +++ b/lib/efi_loader/efi_freestanding.c @@ -97,8 +97,8 @@ void *memset(void *s, int c, size_t n) * * We do nothing here. * - * @param func_ptr Pointer to function being entered - * @param caller Pointer to function which called this function + * func_ptr: Pointer to function being entered + * caller: Pointer to function which called this function */ void __attribute__((no_instrument_function)) __cyg_profile_func_enter(void *func_ptr, void *caller) @@ -113,8 +113,8 @@ __cyg_profile_func_enter(void *func_ptr, void *caller) * * We do nothing here. * - * @param func_ptr Pointer to function being entered - * @param caller Pointer to function which called this function + * func_ptr: Pointer to function being entered + * caller: Pointer to function which called this function */ void __attribute__((no_instrument_function)) __cyg_profile_func_exit(void *func_ptr, void *caller) diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c index 7683a34..2c81859 100644 --- a/lib/efi_loader/efi_gop.c +++ b/lib/efi_loader/efi_gop.c @@ -407,7 +407,7 @@ out: * @width: width of rectangle * @height: height of rectangle * @delta: length in bytes of a line in the pixel buffer (optional) - * @return: status code + * Return: status code */ efi_status_t EFIAPI gop_blt(struct efi_gop *this, struct efi_gop_pixel *buffer, u32 operation, efi_uintn_t sx, diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 255613e..f43dfb3 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -545,13 +545,13 @@ static bool efi_image_unsigned_authenticate(struct efi_image_regions *regs) } /* try black-list first */ - if (efi_signature_lookup_digest(regs, dbx)) { + if (efi_signature_lookup_digest(regs, dbx, true)) { EFI_PRINT("Image is not signed and its digest found in \"dbx\"\n"); goto out; } /* try white-list */ - if (efi_signature_lookup_digest(regs, db)) + if (efi_signature_lookup_digest(regs, db, false)) ret = true; else EFI_PRINT("Image is not signed and its digest not found in \"db\" or \"dbx\"\n"); @@ -633,7 +633,7 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) goto err; } - if (efi_signature_lookup_digest(regs, dbx)) { + if (efi_signature_lookup_digest(regs, dbx, true)) { EFI_PRINT("Image's digest was found in \"dbx\"\n"); goto err; } @@ -734,7 +734,7 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) EFI_PRINT("Signature was not verified by \"db\"\n"); - if (efi_signature_lookup_digest(regs, db)) { + if (efi_signature_lookup_digest(regs, db, false)) { ret = true; break; } diff --git a/lib/efi_loader/efi_riscv.c b/lib/efi_loader/efi_riscv.c new file mode 100644 index 0000000..bccfefd --- /dev/null +++ b/lib/efi_loader/efi_riscv.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Defines APIs that allow an OS to interact with UEFI firmware to query + * information about the boot hart ID. + * + * Copyright (c) 2022, Ventana Micro Systems Inc + */ + +#define LOG_CATEGORY LOGC_EFI +#include <common.h> +#include <efi_loader.h> +#include <efi_variable.h> +#include <log.h> +#include <asm/global_data.h> +#include <efi_riscv.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const efi_guid_t efi_guid_riscv_boot_protocol = RISCV_EFI_BOOT_PROTOCOL_GUID; + +/** + * efi_riscv_get_boot_hartid() - return boot hart ID + * @this: RISCV_EFI_BOOT_PROTOCOL instance + * @boot_hartid: caller allocated memory to return boot hart id + * Return: status code + */ +static efi_status_t EFIAPI +efi_riscv_get_boot_hartid(struct riscv_efi_boot_protocol *this, + efi_uintn_t *boot_hartid) +{ + EFI_ENTRY("%p, %p", this, boot_hartid); + + if (this != &riscv_efi_boot_prot || !boot_hartid) + return EFI_INVALID_PARAMETER; + + *boot_hartid = gd->arch.boot_hart; + + return EFI_EXIT(EFI_SUCCESS); +} + +struct riscv_efi_boot_protocol riscv_efi_boot_prot = { + .revision = RISCV_EFI_BOOT_PROTOCOL_REVISION, + .get_boot_hartid = efi_riscv_get_boot_hartid +}; + +/** + * efi_riscv_register() - register RISCV_EFI_BOOT_PROTOCOL + * + * Return: status code + */ +efi_status_t efi_riscv_register(void) +{ + efi_status_t ret = EFI_SUCCESS; + + ret = efi_add_protocol(efi_root, &efi_guid_riscv_boot_protocol, + (void *)&riscv_efi_boot_prot); + if (ret != EFI_SUCCESS) + log_err("Cannot install RISCV_EFI_BOOT_PROTOCOL\n"); + return ret; +} diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 49172e3..380adc1 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -247,6 +247,12 @@ efi_status_t efi_init_obj_list(void) goto out; } + if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) { + ret = efi_riscv_register(); + if (ret != EFI_SUCCESS) + goto out; + } + /* Secure boot */ ret = efi_init_secure_boot(); if (ret != EFI_SUCCESS) diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c index 3243e2c..1bd1fdc 100644 --- a/lib/efi_loader/efi_signature.c +++ b/lib/efi_loader/efi_signature.c @@ -147,9 +147,34 @@ static bool efi_hash_regions(struct image_region *regs, int count, } /** + * hash_algo_supported - check if the requested hash algorithm is supported + * @guid: guid of the algorithm + * + * Return: true if supported false otherwise + */ +static bool hash_algo_supported(const efi_guid_t guid) +{ + int i; + const efi_guid_t unsupported_hashes[] = { + EFI_CERT_SHA1_GUID, + EFI_CERT_SHA224_GUID, + EFI_CERT_SHA384_GUID, + EFI_CERT_SHA512_GUID, + }; + + for (i = 0; i < ARRAY_SIZE(unsupported_hashes); i++) { + if (!guidcmp(&unsupported_hashes[i], &guid)) + return false; + } + + return true; +} + +/** * efi_signature_lookup_digest - search for an image's digest in sigdb * @regs: List of regions to be authenticated * @db: Signature database for trusted certificates + * @dbx Caller needs to set this to true if he is searching dbx * * A message digest of image pointed to by @regs is calculated and * its hash value is compared to entries in signature database pointed @@ -158,13 +183,16 @@ static bool efi_hash_regions(struct image_region *regs, int count, * Return: true if found, false if not */ bool efi_signature_lookup_digest(struct efi_image_regions *regs, - struct efi_signature_store *db) + struct efi_signature_store *db, + bool dbx) + { struct efi_signature_store *siglist; struct efi_sig_data *sig_data; void *hash = NULL; size_t size = 0; bool found = false; + bool hash_done = false; EFI_PRINT("%s: Enter, %p, %p\n", __func__, regs, db); @@ -172,17 +200,27 @@ bool efi_signature_lookup_digest(struct efi_image_regions *regs, goto out; for (siglist = db; siglist; siglist = siglist->next) { - /* TODO: support other hash algorithms */ - if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) { - EFI_PRINT("Digest algorithm is not supported: %pUs\n", - &siglist->sig_type); - break; - } + /* + * if the hash algorithm is unsupported and we get an entry in + * dbx reject the image + */ + if (dbx && !hash_algo_supported(siglist->sig_type)) { + found = true; + continue; + }; + /* + * Only support sha256 for now, that's what + * hash-to-efi-sig-list produces + */ + if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) + continue; - if (!efi_hash_regions(regs->reg, regs->num, &hash, &size)) { + if (!hash_done && + !efi_hash_regions(regs->reg, regs->num, &hash, &size)) { EFI_PRINT("Digesting an image failed\n"); break; } + hash_done = true; for (sig_data = siglist->sig_data_list; sig_data; sig_data = sig_data->next) { diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c index 3f215e2..33e4fbc 100644 --- a/lib/efi_loader/helloworld.c +++ b/lib/efi_loader/helloworld.c @@ -133,7 +133,7 @@ efi_status_t print_device_path(struct efi_device_path *device_path, * * @handle: handle of the loaded image * @systab: system table - * @return: status code + * Return: status code */ efi_status_t EFIAPI efi_main(efi_handle_t handle, struct efi_system_table *systab) |