summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-05-16 11:23:30 -0400
committerTom Rini <trini@konsulko.com>2023-05-16 11:23:30 -0400
commit6e1852ca2c418e2536ead4b51c4d84a59926b3f1 (patch)
tree4e832f1a587f2d4b80ee85cc246fe5d83b5a334b
parent5645a50a8639a53856bcda60f5eb9e07a5bd31a9 (diff)
parentc7c0ca37673d8f1ae1c54dad1869101f566923f7 (diff)
downloadu-boot-master.tar.gz
Merge tag 'efi-2023-07-rc3' of https://source.denx.de/u-boot/custodians/u-boot-efiHEADmaster
Pull request efi-2023-07-rc3 Documentation: * update the description of signature algorithms UEFI: * fix unaligned access to GUID in HII database protocol * fix launching EFI binaries loaded via semihosting * fix filling of file path in loaded image protocol for non-block devices
-rw-r--r--cmd/bootefi.c2
-rw-r--r--doc/develop/devicetree/control.rst2
-rw-r--r--doc/uImage.FIT/signature.txt15
-rw-r--r--include/efi_api.h28
-rw-r--r--include/efi_loader.h2
-rw-r--r--lib/efi_loader/efi_bootmgr.c13
-rw-r--r--lib/efi_loader/efi_device_path.c92
-rw-r--r--lib/efi_loader/helloworld.c8
-rw-r--r--lib/fwu_updates/Kconfig2
9 files changed, 77 insertions, 87 deletions
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 8aa15a64c8..5c0afec154 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -589,7 +589,7 @@ static efi_status_t bootefi_test_prepare
if (!bootefi_device_path)
return EFI_OUT_OF_RESOURCES;
- bootefi_image_path = efi_dp_from_file(NULL, 0, path);
+ bootefi_image_path = efi_dp_from_file(NULL, path);
if (!bootefi_image_path) {
ret = EFI_OUT_OF_RESOURCES;
goto failure;
diff --git a/doc/develop/devicetree/control.rst b/doc/develop/devicetree/control.rst
index 0b3b32be1b..cbb65c9b17 100644
--- a/doc/develop/devicetree/control.rst
+++ b/doc/develop/devicetree/control.rst
@@ -100,7 +100,7 @@ and development only and is not recommended for production devices.
If CONFIG_OF_SEPARATE is defined, then it will be built and placed in
a u-boot.dtb file alongside u-boot-nodtb.bin with the combined result placed
-in u-boot.bin so you can still just flash u-boot,bin onto your board. If you are
+in u-boot.bin so you can still just flash u-boot.bin onto your board. If you are
using CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device
tree binary.
diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt
index c71280b63b..21eb3894aa 100644
--- a/doc/uImage.FIT/signature.txt
+++ b/doc/uImage.FIT/signature.txt
@@ -42,8 +42,8 @@ device.
Algorithms
----------
In principle any suitable algorithm can be used to sign and verify a hash.
-At present only one class of algorithms is supported: SHA1 hashing with RSA.
-This works by hashing the image to produce a 20-byte hash.
+U-Boot supports a few hashing and verification algorithms. See below for
+details.
While it is acceptable to bring in large cryptographic libraries such as
openssl on the host side (e.g. mkimage), it is not desirable for U-Boot.
@@ -56,10 +56,10 @@ of data from the FDT and exponentiation mod n. Code size impact is a little
under 5KB on Tegra Seaboard, for example.
It is relatively straightforward to add new algorithms if required. If
-another RSA variant is needed, then it can be added to the table in
-image-sig.c. If another algorithm is needed (such as DSA) then it can be
-placed alongside rsa.c, and its functions added to the table in image-sig.c
-also.
+another RSA variant is needed, then it can be added with the
+U_BOOT_CRYPTO_ALGO() macro. If another algorithm is needed (such as DSA) then
+it can be placed in a directory alongside lib/rsa/, and its functions added
+using U_BOOT_CRYPTO_ALGO().
Creating an RSA key pair and certificate
@@ -439,6 +439,7 @@ be enabled:
CONFIG_FIT_SIGNATURE - enable signing and verification in FITs
CONFIG_RSA - enable RSA algorithm for signing
+CONFIG_ECDSA - enable ECDSA algorithm for signing
WARNING: When relying on signed FIT images with required signature check
the legacy image format is default disabled by not defining
@@ -694,8 +695,6 @@ bootm.
Possible Future Work
--------------------
-- Add support for other RSA/SHA variants, such as rsa4096,sha512.
-- Other algorithms besides RSA
- More sandbox tests for failure modes
- Passwords for keys/certificates
- Perhaps implement OAEP
diff --git a/include/efi_api.h b/include/efi_api.h
index 2fd0221c1c..55a4c989fc 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -1170,7 +1170,33 @@ struct efi_key_descriptor {
struct efi_hii_keyboard_layout {
u16 layout_length;
- efi_guid_t guid;
+ /*
+ * The EFI spec defines this as efi_guid_t.
+ * clang and gcc both report alignment problems here.
+ * clang with -Wunaligned-access
+ * warning: field guid within 'struct efi_hii_keyboard_layout' is less
+ * aligned than 'efi_guid_t' and is usually due to
+ * 'struct efi_hii_keyboard_layout' being packed, which can lead to
+ * unaligned accesses
+ *
+ * GCC with -Wpacked-not-aligned -Waddress-of-packed-member
+ * 'efi_guid_t' offset 2 in 'struct efi_hii_keyboard_layout'
+ * isn't aligned to 4
+ *
+ * Removing the alignment from efi_guid_t is not an option, since
+ * it is also used in non-packed structs and that would break
+ * calculations with offsetof
+ *
+ * This is the only place we get a report for. That happens because
+ * all other declarations of efi_guid_t within a packed struct happens
+ * to be 4-byte aligned. i.e a u32, a u64 a 2 * u16 or any combination
+ * that ends up landing efi_guid_t on a 4byte boundary precedes.
+ *
+ * Replace this with a 1-byte aligned counterpart of b[16]. This is a
+ * packed struct so the memory placement of efi_guid_t should not change
+ *
+ */
+ u8 guid[16];
u32 layout_descriptor_string_offset;
u8 descriptor_count;
/* struct efi_key_descriptor descriptors[]; follows here */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index b395eef9e7..38d7f66bab 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -810,7 +810,7 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp);
struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
/* Create a device node for a block device partition. */
struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
-struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
+struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
const char *path);
struct efi_device_path *efi_dp_from_eth(void);
struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 4b24b41047..7ac5f89f76 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -47,7 +47,7 @@ const efi_guid_t efi_guid_bootmenu_auto_generated =
static
struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
{
- struct efi_device_path *dp, *rem, *full_path;
+ struct efi_device_path *rem, *full_path;
efi_handle_t handle;
if (!device_path)
@@ -58,15 +58,12 @@ struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
* simple file system protocol, append a default file name to support
* booting from removable media.
*/
- dp = device_path;
- handle = efi_dp_find_obj(dp, &efi_simple_file_system_protocol_guid,
- &rem);
+ handle = efi_dp_find_obj(device_path,
+ &efi_simple_file_system_protocol_guid, &rem);
if (handle) {
if (rem->type == DEVICE_PATH_TYPE_END) {
- dp = efi_dp_from_file(NULL, 0,
- "/EFI/BOOT/" BOOTEFI_NAME);
- full_path = efi_dp_append(device_path, dp);
- efi_free_pool(dp);
+ full_path = efi_dp_from_file(device_path,
+ "/EFI/BOOT/" BOOTEFI_NAME);
} else {
full_path = efi_dp_dup(device_path);
}
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index e2e98a39be..71923b1127 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -1002,59 +1002,45 @@ static void path_to_uefi(void *uefi, const char *src)
}
/**
- * efi_dp_from_file() - create device path for file
+ * efi_dp_from_file() - append file path node to device path.
*
- * The function creates a device path from the block descriptor @desc and the
- * partition number @part and appends a device path node created describing the
- * file path @path.
- *
- * If @desc is NULL, the device path will not contain nodes describing the
- * partition.
- * If @path is an empty string "", the device path will not contain a node
- * for the file path.
- *
- * @desc: block device descriptor or NULL
- * @part: partition number
- * @path: file path on partition or ""
+ * @dp: device path or NULL
+ * @path: file path or NULL
* Return: device path or NULL in case of an error
*/
-struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
- const char *path)
+struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
+ const char *path)
{
struct efi_device_path_file_path *fp;
- void *buf, *start;
- size_t dpsize = 0, fpsize;
-
- if (desc)
- dpsize = dp_part_size(desc, part);
+ void *buf, *pos;
+ size_t dpsize, fpsize;
+ dpsize = efi_dp_size(dp);
fpsize = sizeof(struct efi_device_path) +
2 * (utf8_utf16_strlen(path) + 1);
if (fpsize > U16_MAX)
return NULL;
- dpsize += fpsize;
-
- start = buf = efi_alloc(dpsize + sizeof(END));
+ buf = efi_alloc(dpsize + fpsize + sizeof(END));
if (!buf)
return NULL;
- if (desc)
- buf = dp_part_fill(buf, desc, part);
+ memcpy(buf, dp, dpsize);
+ pos = buf + dpsize;
/* add file-path: */
if (*path) {
- fp = buf;
+ fp = pos;
fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
fp->dp.length = (u16)fpsize;
path_to_uefi(fp->str, path);
- buf += fpsize;
+ pos += fpsize;
}
- *((struct efi_device_path *)buf) = END;
+ memcpy(pos, &END, sizeof(END));
- return start;
+ return buf;
}
struct efi_device_path *efi_dp_from_uart(void)
@@ -1079,8 +1065,7 @@ struct efi_device_path *efi_dp_from_uart(void)
return buf;
}
-#ifdef CONFIG_NETDEVICES
-struct efi_device_path *efi_dp_from_eth(void)
+struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
{
void *buf, *start;
unsigned dpsize = 0;
@@ -1099,7 +1084,6 @@ struct efi_device_path *efi_dp_from_eth(void)
return start;
}
-#endif
/* Construct a device-path for memory-mapped image */
struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
@@ -1185,58 +1169,42 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
struct efi_device_path **file)
{
struct blk_desc *desc = NULL;
+ struct efi_device_path *dp;
struct disk_partition fs_partition;
size_t image_size;
void *image_addr;
int part = 0;
- char *filename;
- char *s;
if (path && !file)
return EFI_INVALID_PARAMETER;
- if (!strcmp(dev, "Net")) {
-#ifdef CONFIG_NETDEVICES
- if (device)
- *device = efi_dp_from_eth();
-#endif
- } else if (!strcmp(dev, "Uart")) {
- if (device)
- *device = efi_dp_from_uart();
- } else if (!strcmp(dev, "Mem")) {
+ if (!strcmp(dev, "Mem") || !strcmp(dev, "hostfs")) {
+ /* loadm command and semihosting */
efi_get_image_parameters(&image_addr, &image_size);
- if (device)
- *device = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
- (uintptr_t)image_addr,
- image_size);
+ dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
+ (uintptr_t)image_addr, image_size);
+ } else if (IS_ENABLED(CONFIG_NETDEVICES) && !strcmp(dev, "Net")) {
+ dp = efi_dp_from_eth();
+ } else if (!strcmp(dev, "Uart")) {
+ dp = efi_dp_from_uart();
} else {
part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
1);
if (part < 0 || !desc)
return EFI_INVALID_PARAMETER;
- if (device)
- *device = efi_dp_from_part(desc, part);
+ dp = efi_dp_from_part(desc, part);
}
+ if (device)
+ *device = dp;
if (!path)
return EFI_SUCCESS;
- filename = calloc(1, strlen(path) + 1);
- if (!filename)
- return EFI_OUT_OF_RESOURCES;
-
- sprintf(filename, "%s", path);
- /* DOS style file path: */
- s = filename;
- while ((s = strchr(s, '/')))
- *s++ = '\\';
- *file = efi_dp_from_file(desc, part, filename);
- free(filename);
-
+ *file = efi_dp_from_file(dp, path);
if (!*file)
- return EFI_INVALID_PARAMETER;
+ return EFI_OUT_OF_RESOURCES;
return EFI_SUCCESS;
}
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
index 6405f58ec3..bd72822c0b 100644
--- a/lib/efi_loader/helloworld.c
+++ b/lib/efi_loader/helloworld.c
@@ -216,6 +216,10 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
(con_out, u"Cannot open device path to text protocol\r\n");
goto out;
}
+ con_out->output_string(con_out, u"File path: ");
+ ret = print_device_path(loaded_image->file_path, device_path_to_text);
+ if (ret != EFI_SUCCESS)
+ goto out;
if (!loaded_image->device_handle) {
con_out->output_string
(con_out, u"Missing device handle\r\n");
@@ -234,10 +238,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
ret = print_device_path(device_path, device_path_to_text);
if (ret != EFI_SUCCESS)
goto out;
- con_out->output_string(con_out, u"File path: ");
- ret = print_device_path(loaded_image->file_path, device_path_to_text);
- if (ret != EFI_SUCCESS)
- goto out;
out:
boottime->exit(handle, ret, 0, NULL);
diff --git a/lib/fwu_updates/Kconfig b/lib/fwu_updates/Kconfig
index 78759e6618..71f34793d9 100644
--- a/lib/fwu_updates/Kconfig
+++ b/lib/fwu_updates/Kconfig
@@ -2,7 +2,7 @@ config FWU_MULTI_BANK_UPDATE
bool "Enable FWU Multi Bank Update Feature"
depends on EFI_CAPSULE_ON_DISK
select PARTITION_TYPE_GUID
- select EFI_SETUP_EARLY
+ select FWU_MDATA
imply EFI_CAPSULE_ON_DISK_EARLY
select EVENT
help