aboutsummaryrefslogtreecommitdiff
path: root/lib/efi_loader
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-01-29 13:50:19 -0500
committerTom Rini <trini@konsulko.com>2022-01-29 13:50:19 -0500
commitc7d042f315d89ab2f0122920829f18a8f8897a05 (patch)
tree380446358ad24e2ed24e1696d898b019d82eb6cd /lib/efi_loader
parent98a90b2730696c1ba773359b7944f6685ae13344 (diff)
parent5ee900c14ff57b8c9201d7d42f018b33df3ea42a (diff)
downloadu-boot-WIP/29Jan2022.zip
u-boot-WIP/29Jan2022.tar.gz
u-boot-WIP/29Jan2022.tar.bz2
Merge tag 'efi-2022-04-rc1-3' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/29Jan2022
Pull request for efi-2022-04-rc1-3 Documentation: * update Nokia RX-51 documentation and move it to rst * describe boot switch settings for HiFive Unmatched board UEFI: * fix the checking of images hashes and signatures * provide the RISCV_EFI_BOOT_PROTOCOL
Diffstat (limited to 'lib/efi_loader')
-rw-r--r--lib/efi_loader/Kconfig10
-rw-r--r--lib/efi_loader/Makefile1
-rw-r--r--lib/efi_loader/efi_file.c2
-rw-r--r--lib/efi_loader/efi_freestanding.c8
-rw-r--r--lib/efi_loader/efi_gop.c2
-rw-r--r--lib/efi_loader/efi_image_loader.c8
-rw-r--r--lib/efi_loader/efi_riscv.c60
-rw-r--r--lib/efi_loader/efi_setup.c6
-rw-r--r--lib/efi_loader/efi_signature.c54
-rw-r--r--lib/efi_loader/helloworld.c2
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)