[PATCH v8 00/11] efi: CapsuleUpdate: support for dynamic UUIDs

As more boards adopt support for the EFI CapsuleUpdate mechanism, there is a growing issue of being able to target updates to them properly. The current mechanism of hardcoding UUIDs for each board at compile time is unsustainable, and maintaining lists of GUIDs is similarly cumbersome.
In this series, I propose that we adopt v5 GUIDs, these are generated by using a well-known salt GUID as well as board specific information the DT root compatible string, these are hashed together and the result is truncated to form a new UUID.
The well-known salt GUID can be specific to the architecture (SoC vendor), or OEM. It is defined in the board defconfig so that vendors can easily bring their own.
Specifically, the following fields are used to generate a GUID for a particular fw_image:
* namespace salt * board compatible (usually the first entry in the dt root compatible array). * fw_image name (the string identifying the specific image, especially relevant for board that can update multiple images).
== Usage ==
Boards can enable dynamic UUID support by simply not setting the efi_fw_image image_type_id property. Vendors may also wish to set a custom namespace GUID (by setting CONFIG_EFI_CAPSULE_NAMESPACE_GUID).
== Limitations ==
* Changing GUIDs
The primary limitation with this approach is that if any of the source fields change, so will the GUID for the board. It is therefore pretty important to ensure that GUID changes are caught during development.
* Supporting multiple boards with a single image
This now requires having an entry with the GUID for every board which might lead to larger UpdateCapsule images.
== Tooling ==
The mkeficapsule command is updated to add a new guidgen subcommand, this can generate GUIDs that match those the board would generate at runtime. It accepts an optional namespace GUID (if the default isn't used), a path to the board DTB, and a list of firmware image names.
This series follows a related discussion started by Ilias: https://lore.kernel.org/u-boot/CAC_iWjJNHa4gMF897MqYZNdbgjFG8K4kwGsTXWuy72Wk...
CI run for this series (only v7): https://source.denx.de/u-boot/custodians/u-boot-snapdragon/-/pipelines/21944
--- Changes in v8: - Rebase on next Aug 30 - Address checkpatch warnings - Link to v7: https://lore.kernel.org/r/20240809-b4-dynamic-uuid-v7-0-8c44ab1f06a5@linaro....
Changes in v7: - Minor adjustments to fix CI on some 32-bit ARM platforms - Link to v6: https://lore.kernel.org/r/20240808-b4-dynamic-uuid-v6-0-9332e7237119@linaro....
Changes in v6: - FWU -> Firmware Update in docs - Make v5 GUIDs explicitly LE - Link to v5: https://lore.kernel.org/r/20240719-b4-dynamic-uuid-v5-0-8a83de3fe3dc@linaro....
Changes in v5: - Clean up mkeficapsule genguid patch - Add explicit tests validating the GUID type bits - Link to v4: https://lore.kernel.org/r/20240702-b4-dynamic-uuid-v4-0-a00c82d1f504@linaro....
Changes in v4: - Make UUID v5 support always enabled rather than being optional. - Fix endianness issues (thanks Vincent and Ilias) - Merge genguid tool into mkeficapsule. - And move mkeficapsule over to using U-Boot's UUID code rather than libuuid. - Provide a default namespace UUID for all U-Boot boards. - Link to v3: https://lore.kernel.org/r/20240531-b4-dynamic-uuid-v3-0-ca4a4865db00@linaro....
Changes in v3: - Add manpage for genguid - Add dedicated CONFIG_TOOLS_GENGUID option - Minor code fixes addressing v2 feedback - Link to v2: https://lore.kernel.org/r/20240529-b4-dynamic-uuid-v2-0-c26f31057bbe@linaro....
Changes in v2: - Move namespace UUID to be defined in defconfig - Add tests and tooling - Only use the first board compatible to generate UUID. - Link to v1: https://lore.kernel.org/r/20240426-b4-dynamic-uuid-v1-0-e8154e00ec44@linaro....
--- Caleb Connolly (11): efi: define struct efi_guid lib: uuid: add UUID v5 support efi: add a helper to generate dynamic UUIDs doc: uefi: document dynamic UUID generation sandbox: switch to dynamic UUIDs lib: uuid: supporting building as part of host tools include: export uuid.h tools: mkeficapsule: use u-boot UUID library tools: mkeficapsule: support generating dynamic GUIDs test: lib/uuid: add unit tests for dynamic UUIDs test: lib/uuid: add tests for UUID version/variant bits
arch/arm/mach-rockchip/board.c | 2 +- board/cobra5272/flash.c | 2 +- board/gardena/smart-gateway-mt7688/board.c | 2 +- board/sandbox/sandbox.c | 16 -- board/socrates/socrates.c | 2 +- board/xilinx/common/board.c | 2 +- cmd/efi.c | 2 +- cmd/efi_common.c | 2 +- cmd/flash.c | 2 +- cmd/gpt.c | 2 +- cmd/nvedit_efi.c | 2 +- cmd/x86/hob.c | 2 +- common/flash.c | 2 +- disk/part_efi.c | 2 +- doc/develop/uefi/uefi.rst | 27 +++ doc/mkeficapsule.1 | 23 +++ drivers/firmware/arm-ffa/arm-ffa-uclass.c | 2 +- env/sf.c | 2 +- fs/btrfs/btrfs.c | 2 +- fs/btrfs/compat.h | 2 +- fs/btrfs/disk-io.c | 2 +- fs/ext4/ext4fs.c | 2 +- include/efi.h | 2 +- include/fwu.h | 2 +- include/part.h | 2 +- include/rkmtd.h | 2 +- include/sandbox_efi_capsule.h | 6 +- include/{ => u-boot}/uuid.h | 21 ++- lib/Kconfig | 1 + lib/acpi/acpi_dp.c | 2 +- lib/acpi/acpigen.c | 2 +- lib/efi/efi_app.c | 2 +- lib/efi_loader/Kconfig | 12 ++ lib/efi_loader/efi_capsule.c | 1 + lib/efi_loader/efi_device_path.c | 2 +- lib/efi_loader/efi_firmware.c | 55 +++++- lib/efi_loader/efi_variable.c | 2 +- lib/fwu_updates/fwu_mtd.c | 2 +- lib/uuid.c | 103 +++++++--- lib/vsprintf.c | 2 +- net/bootp.c | 2 +- test/dm/acpi_dp.c | 2 +- test/dm/acpigen.c | 2 +- test/lib/uuid.c | 125 ++++++++++++- .../test_efi_capsule/test_capsule_firmware_fit.py | 2 +- .../test_efi_capsule/test_capsule_firmware_raw.py | 8 +- .../test_capsule_firmware_signed_fit.py | 2 +- .../test_capsule_firmware_signed_raw.py | 4 +- test/py/tests/test_efi_capsule/version.dtso | 6 +- tools/Makefile | 8 +- tools/binman/etype/efi_capsule.py | 2 +- tools/binman/ftest.py | 2 +- tools/eficapsule.h | 2 +- tools/mkeficapsule.c | 208 +++++++++++++++------ 54 files changed, 551 insertions(+), 149 deletions(-) --- change-id: 20240422-b4-dynamic-uuid-1a5ab1486c27 base-commit: e83ced1a24095de66e526bd6c10f0f24584baaee
// Caleb (they/them)

This let's us forward declare efi_guid_t in the UUID code without pulling in efi.h
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- include/efi.h | 2 +- tools/eficapsule.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/efi.h b/include/efi.h index d5af21399468..84640cf7b252 100644 --- a/include/efi.h +++ b/include/efi.h @@ -73,9 +73,9 @@ struct efi_device_path { * EDK2 reference implementation both define EFI_GUID as * struct { u32 a; u16; b; u16 c; u8 d[8]; }; which is 4-byte * aligned. */ -typedef struct { +typedef struct efi_guid { u8 b[16]; } efi_guid_t __attribute__((aligned(4)));
static inline int guidcmp(const void *g1, const void *g2) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 6efd07d2eb6b..97d077536d5b 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -23,9 +23,9 @@ #endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-typedef struct { +typedef struct efi_guid { uint8_t b[16]; } efi_guid_t __aligned(8);
#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \

Add support for generating version 5 UUIDs, these are determistic and work by hashing a "namespace" UUID together with some unique data. One intended usecase is to allow for dynamically generate payload UUIDs for UEFI capsule updates, so that supported boards can have their own UUIDs without needing to hardcode them.
In addition, move the common bit twiddling code from gen_ran_uuid into a separate function and rewrite it not to use clrsetbits (which is not available when building as part of host tools).
Tests for this are added in an upcoming patch.
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- include/uuid.h | 17 +++++++++++++++-- lib/Kconfig | 1 + lib/uuid.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/include/uuid.h b/include/uuid.h index f5a941250f48..1f4fa103b5e9 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -10,8 +10,9 @@ #ifndef __UUID_H__ #define __UUID_H__
#include <linux/bitops.h> +#include <linux/kconfig.h>
/* * UUID - Universally Unique IDentifier - 128 bits unique number. * There are 5 versions and one variant of UUID defined by RFC4122 @@ -45,10 +46,10 @@ * where x is a hexadecimal character. Fields are separated by '-'s. * When converting to a binary UUID, le means the field should be converted * to little endian and be means it should be converted to big endian. * - * UUID is also used as GUID (Globally Unique Identifier) with the same binary - * format but it differs in string format like below. + * UUID is also used as GUID (Globally Unique Identifier) with the same format + * but with some fields stored in little endian. * * GUID: * 0 9 14 19 24 * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx @@ -142,8 +143,20 @@ void gen_rand_uuid(unsigned char *uuid_bin); * @param - uuid output type: UUID - 0, GUID - 1 */ void gen_rand_uuid_str(char *uuid_str, int str_format);
+struct efi_guid; + +/** + * gen_v5_guid() - generate little endian v5 GUID from namespace and other seed data. + * + * @namespace: pointer to UUID namespace salt + * @guid: pointer to allocated GUID output + * @...: NULL terminated list of seed data as pairs of pointers + * to data and their lengths + */ +void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...); + /** * uuid_str_to_le_bin() - Convert string UUID to little endian binary data. * @uuid_str: pointer to UUID string * @uuid_bin: pointer to allocated array for little endian output [16B] diff --git a/lib/Kconfig b/lib/Kconfig index 2059219a1207..5a48c016d2c5 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -72,8 +72,9 @@ config HAVE_PRIVATE_LIBGCC bool
config LIB_UUID bool + select SHA1
config RANDOM_UUID bool "GPT Random UUID generation" select LIB_UUID diff --git a/lib/uuid.c b/lib/uuid.c index dfa2320ba267..c9dfdf007a18 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -21,8 +21,9 @@ #include <part_efi.h> #include <malloc.h> #include <dm/uclass.h> #include <rng.h> +#include <u-boot/sha1.h>
int uuid_str_valid(const char *uuid) { int i, valid; @@ -368,8 +369,58 @@ void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str, } } }
+static void configure_uuid(struct uuid *uuid, unsigned char version) +{ + uint16_t tmp; + + /* Configure variant/version bits */ + tmp = be16_to_cpu(uuid->time_hi_and_version); + tmp = (tmp & ~UUID_VERSION_MASK) | (version << UUID_VERSION_SHIFT); + uuid->time_hi_and_version = cpu_to_be16(tmp); + + uuid->clock_seq_hi_and_reserved &= ~UUID_VARIANT_MASK; + uuid->clock_seq_hi_and_reserved |= (UUID_VARIANT << UUID_VARIANT_SHIFT); +} + +void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...) +{ + sha1_context ctx; + va_list args; + const uint8_t *data; + uint32_t *tmp32; + uint16_t *tmp16; + uint8_t hash[SHA1_SUM_LEN]; + + sha1_starts(&ctx); + /* Hash the namespace UUID as salt */ + sha1_update(&ctx, (unsigned char *)namespace, UUID_BIN_LEN); + va_start(args, guid); + + while ((data = va_arg(args, const uint8_t *))) { + unsigned int len = va_arg(args, size_t); + + sha1_update(&ctx, data, len); + } + + va_end(args); + sha1_finish(&ctx, hash); + + /* Truncate the hash into output UUID, it is already big endian */ + memcpy(guid, hash, sizeof(*guid)); + + configure_uuid((struct uuid *)guid, 5); + + /* Make little endian */ + tmp32 = (uint32_t *)&guid->b[0]; + *tmp32 = cpu_to_le32(be32_to_cpu(*tmp32)); + tmp16 = (uint16_t *)&guid->b[4]; + *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16)); + tmp16 = (uint16_t *)&guid->b[6]; + *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16)); +} + #if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID) void gen_rand_uuid(unsigned char *uuid_bin) { u32 ptr[4]; @@ -394,15 +445,9 @@ void gen_rand_uuid(unsigned char *uuid_bin) /* Set all fields randomly */ for (i = 0; i < 4; i++) ptr[i] = rand();
- clrsetbits_be16(&uuid->time_hi_and_version, - UUID_VERSION_MASK, - UUID_VERSION << UUID_VERSION_SHIFT); - - clrsetbits_8(&uuid->clock_seq_hi_and_reserved, - UUID_VARIANT_MASK, - UUID_VARIANT << UUID_VARIANT_SHIFT); + configure_uuid(uuid, UUID_VERSION);
memcpy(uuid_bin, uuid, 16); }

Introduce a new helper efi_capsule_update_info_gen_ids() which populates the capsule update fw images image_type_id field. This allows for determinstic UUIDs to be used that can scale to a large number of different boards and board variants without the need to maintain a big list.
We call this from efi_fill_image_desc_array() to populate the UUIDs lazily on-demand.
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- lib/efi_loader/Kconfig | 12 ++++++++++ lib/efi_loader/efi_capsule.c | 1 + lib/efi_loader/efi_firmware.c | 55 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 1179c31bb136..85a31113fcf0 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -236,8 +236,20 @@ config EFI_CAPSULE_ON_DISK_EARLY If this option is enabled, capsules will be enforced to be executed as part of U-Boot initialisation so that they will surely take place whatever is set to distro_bootcmd.
+config EFI_CAPSULE_NAMESPACE_GUID + string "Namespace for dynamic capsule GUIDs" + # v4 UUID as a default for upstream U-Boot boards + default "8c9f137e-91dc-427b-b2d6-b420faebaf2a" + depends on EFI_HAVE_CAPSULE_SUPPORT + help + Define the namespace or "salt" GUID used to generate the per-image + GUIDs. This should be a GUID in the standard 8-4-4-4-12 format. + + Device vendors are expected to generate their own namespace GUID + to avoid conflicts with upstream/community images. + config EFI_CAPSULE_FIRMWARE bool
config EFI_CAPSULE_FIRMWARE_MANAGEMENT diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 635088f25a13..f3a2388506cc 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -19,8 +19,9 @@ #include <mapmem.h> #include <sort.h> #include <sysreset.h> #include <asm/global_data.h> +#include <uuid.h>
#include <crypto/pkcs7.h> #include <crypto/pkcs7_parser.h> #include <linux/err.h> diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index ba5aba098c0f..6650c2b8071d 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -244,8 +244,57 @@ void efi_firmware_fill_version_info(struct efi_firmware_image_descriptor *image_
free(var_state); }
+/** + * efi_gen_capsule_guids - generate GUIDs for the images + * + * Generate the image_type_id for each image in the update_info.images array + * using the first compatible from the device tree and a salt + * UUID defined at build time. + * + * Returns: status code + */ +static efi_status_t efi_gen_capsule_guids(void) +{ + int ret, i; + struct uuid namespace; + const char *compatible; /* Full array including null bytes */ + struct efi_fw_image *fw_array; + + fw_array = update_info.images; + /* Check if we need to run (there are images and we didn't already generate their IDs) */ + if (!update_info.num_images || + memchr_inv(&fw_array[0].image_type_id, 0, sizeof(fw_array[0].image_type_id))) + return EFI_SUCCESS; + + ret = uuid_str_to_bin(CONFIG_EFI_CAPSULE_NAMESPACE_GUID, + (unsigned char *)&namespace, UUID_STR_FORMAT_GUID); + if (ret) { + log_debug("%s: EFI_CAPSULE_NAMESPACE_GUID is invalid: %d\n", __func__, ret); + return EFI_INVALID_PARAMETER; + } + + compatible = ofnode_read_string(ofnode_root(), "compatible"); + if (!compatible) { + log_debug("%s: model or compatible not defined\n", __func__); + return EFI_INVALID_PARAMETER; + } + + for (i = 0; i < update_info.num_images; i++) { + gen_v5_guid(&namespace, + &fw_array[i].image_type_id, + compatible, strlen(compatible), + fw_array[i].fw_name, u16_strlen(fw_array[i].fw_name) * sizeof(uint16_t), + NULL); + + log_debug("Image %ls UUID %pUl\n", fw_array[i].fw_name, + &fw_array[i].image_type_id); + } + + return EFI_SUCCESS; +} + /** * efi_fill_image_desc_array - populate image descriptor array * @image_info_size: Size of @image_info * @image_info: Image information @@ -271,9 +320,9 @@ static efi_status_t efi_fill_image_desc_array( u16 **package_version_name) { size_t total_size; struct efi_fw_image *fw_array; - int i; + int i, ret;
total_size = sizeof(*image_info) * update_info.num_images;
if (*image_info_size < total_size) { @@ -282,8 +331,12 @@ static efi_status_t efi_fill_image_desc_array( return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size;
+ ret = efi_gen_capsule_guids(); + if (ret != EFI_SUCCESS) + return ret; + fw_array = update_info.images; *descriptor_count = update_info.num_images; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; *descriptor_size = sizeof(*image_info);

Document how platforms can generate GUIDs at runtime rather than maintaining a list of UUIDs per-board.
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- doc/develop/uefi/uefi.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index d450b12bf801..944827585731 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -448,8 +448,35 @@ the location of the firmware updates is not a very secure practice. Getting this information from the firmware itself is more secure, assuming the firmware has been verified by a previous stage boot loader.
+Dynamic Firmware Update GUIDs +***************************** + +The image_type_id contains a GUID value which is specific to the image +and board being updated, that is to say it should uniquely identify the +board model (and revision if relevant) and image pair. Traditionally, +these GUIDs are generated manually and hardcoded on a per-board basis, +however this scheme makes it difficult to scale up to support many +boards. + +To address this, v5 GUIDs can be used to generate board-specific GUIDs +at runtime, based on the board's devicetree root compatible +(e.g. "qcom,qrb5165-rb5"). + +These strings are combined with the fw_image name to generate GUIDs for +each image. Support for dynamic UUIDs can be enabled by generating a new +namespace UUID and setting EFI_CAPSULE_NAMESPACE_GUID to it. Dynamic GUID +generation is only enabled if the image_type_id property is unset for your +firmware images, this is to avoid breaking existing boards with hardcoded +GUIDs. + +The mkeficapsule tool can be used to determine the GUIDs for a particular +board and image. It can be found in the tools directory. + +Firmware update images +********************** + The firmware images structure defines the GUID values, image index values and the name of the images that are to be updated through the capsule update feature. These values are to be defined as part of an array. These GUID values would be used by the Firmware Management

Migrate sandbox over to generating it's capsule update image GUIDs dynamically from the namespace and board/image info. Update the reference and tests to use the new GUIDs.
Acked-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- board/sandbox/sandbox.c | 16 ---------------- include/sandbox_efi_capsule.h | 6 +++--- .../tests/test_efi_capsule/test_capsule_firmware_fit.py | 2 +- .../tests/test_efi_capsule/test_capsule_firmware_raw.py | 8 ++++---- .../test_efi_capsule/test_capsule_firmware_signed_fit.py | 2 +- .../test_efi_capsule/test_capsule_firmware_signed_raw.py | 4 ++-- test/py/tests/test_efi_capsule/version.dtso | 6 +++--- tools/binman/etype/efi_capsule.py | 2 +- tools/binman/ftest.py | 2 +- 9 files changed, 16 insertions(+), 32 deletions(-)
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c index 802596569c64..d97945e58fcf 100644 --- a/board/sandbox/sandbox.c +++ b/board/sandbox/sandbox.c @@ -31,36 +31,20 @@ */ gd_t *gd;
#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) -/* GUIDs for capsule updatable firmware images */ -#define SANDBOX_UBOOT_IMAGE_GUID \ - EFI_GUID(0x09d7cf52, 0x0720, 0x4710, 0x91, 0xd1, \ - 0x08, 0x46, 0x9b, 0x7f, 0xe9, 0xc8) - -#define SANDBOX_UBOOT_ENV_IMAGE_GUID \ - EFI_GUID(0x5a7021f5, 0xfef2, 0x48b4, 0xaa, 0xba, \ - 0x83, 0x2e, 0x77, 0x74, 0x18, 0xc0) - -#define SANDBOX_FIT_IMAGE_GUID \ - EFI_GUID(0x3673b45d, 0x6a7c, 0x46f3, 0x9e, 0x60, \ - 0xad, 0xab, 0xb0, 0x3f, 0x79, 0x37) - struct efi_fw_image fw_images[] = { #if defined(CONFIG_EFI_CAPSULE_FIRMWARE_RAW) { - .image_type_id = SANDBOX_UBOOT_IMAGE_GUID, .fw_name = u"SANDBOX-UBOOT", .image_index = 1, }, { - .image_type_id = SANDBOX_UBOOT_ENV_IMAGE_GUID, .fw_name = u"SANDBOX-UBOOT-ENV", .image_index = 2, }, #elif defined(CONFIG_EFI_CAPSULE_FIRMWARE_FIT) { - .image_type_id = SANDBOX_FIT_IMAGE_GUID, .fw_name = u"SANDBOX-FIT", .image_index = 1, }, #endif diff --git a/include/sandbox_efi_capsule.h b/include/sandbox_efi_capsule.h index 3e288e8a84a2..84d45ec5cfd5 100644 --- a/include/sandbox_efi_capsule.h +++ b/include/sandbox_efi_capsule.h @@ -5,11 +5,11 @@
#if !defined(_SANDBOX_EFI_CAPSULE_H_) #define _SANDBOX_EFI_CAPSULE_H_
-#define SANDBOX_UBOOT_IMAGE_GUID "09d7cf52-0720-4710-91d1-08469b7fe9c8" -#define SANDBOX_UBOOT_ENV_IMAGE_GUID "5a7021f5-fef2-48b4-aaba-832e777418c0" -#define SANDBOX_FIT_IMAGE_GUID "3673b45d-6a7c-46f3-9e60-adabb03f7937" +#define SANDBOX_UBOOT_IMAGE_GUID "985f2937-7c2e-5e9a-8a5e-8e063312964b" +#define SANDBOX_UBOOT_ENV_IMAGE_GUID "9e339473-c2eb-530a-a69b-0cd6bbbed40e" +#define SANDBOX_FIT_IMAGE_GUID "46610520-469e-59dc-a8dd-c11832b877ea" #define SANDBOX_INCORRECT_GUID "058b7d83-50d5-4c47-a195-60d86ad341c4"
#define UBOOT_FIT_IMAGE "u-boot_bin_env.itb"
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py index 11bcdc2bb293..a726c71c1138 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py @@ -146,9 +146,9 @@ class TestEfiCapsuleFirmwareFit(): verify_content(u_boot_console, '100000', 'u-boot:Old') verify_content(u_boot_console, '150000', 'u-boot-env:Old') else: # ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT. - assert '3673B45D-6A7C-46F3-9E60-ADABB03F7937' in ''.join(output) + assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output) assert 'ESRT: fw_version=5' in ''.join(output) assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
verify_content(u_boot_console, '100000', 'u-boot:New') diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py index f3a2dff5c2c8..8a790405c7c4 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py @@ -144,12 +144,12 @@ class TestEfiCapsuleFirmwareRaw: 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', 'efidebug capsule esrt'])
# ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT. - assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output) + assert '9E339473-C2EB-530A-A69B-0CD6BBBED40E' in ''.join(output)
# ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT. - assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output) + assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output)
check_file_removed(u_boot_console, disk_img, capsule_files)
expected = 'u-boot:Old' if capsule_auth else 'u-boot:New' @@ -198,14 +198,14 @@ class TestEfiCapsuleFirmwareRaw: verify_content(u_boot_console, '100000', 'u-boot:Old') verify_content(u_boot_console, '150000', 'u-boot-env:Old') else: # ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT. - assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output) + assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output) assert 'ESRT: fw_version=5' in ''.join(output) assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
# ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT. - assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output) + assert '9E339473-C2EB-530A-A69B-0CD6BBBED40E' in ''.join(output) assert 'ESRT: fw_version=10' in ''.join(output) assert 'ESRT: lowest_supported_fw_version=7' in ''.join(output)
verify_content(u_boot_console, '100000', 'u-boot:New') diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py index 44a58baa3106..debbce8bdbdf 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py @@ -156,9 +156,9 @@ class TestEfiCapsuleFirmwareSignedFit(): 'u-boot-env raw 0x150000 0x200000"', 'efidebug capsule esrt'])
# ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT. - assert '3673B45D-6A7C-46F3-9E60-ADABB03F7937' in ''.join(output) + assert '46610520-469E-59DC-A8DD-C11832B877EA' in ''.join(output) assert 'ESRT: fw_version=5' in ''.join(output) assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
verify_content(u_boot_console, '100000', 'u-boot:New') diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py index 83a10e160b8c..439bd71b3a7d 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py @@ -150,14 +150,14 @@ class TestEfiCapsuleFirmwareSignedRaw(): 'u-boot-env raw 0x150000 0x200000"', 'efidebug capsule esrt'])
# ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT. - assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output) + assert '985F2937-7C2E-5E9A-8A5E-8E063312964B' in ''.join(output) assert 'ESRT: fw_version=5' in ''.join(output) assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output)
# ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT. - assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output) + assert '9E339473-C2EB-530A-A69B-0CD6BBBED40E' in ''.join(output) assert 'ESRT: fw_version=10' in ''.join(output) assert 'ESRT: lowest_supported_fw_version=7' in ''.join(output)
verify_content(u_boot_console, '100000', 'u-boot:New') diff --git a/test/py/tests/test_efi_capsule/version.dtso b/test/py/tests/test_efi_capsule/version.dtso index 07850cc6064c..3aebb5b64fbd 100644 --- a/test/py/tests/test_efi_capsule/version.dtso +++ b/test/py/tests/test_efi_capsule/version.dtso @@ -7,18 +7,18 @@ firmware-version { image1 { lowest-supported-version = <3>; image-index = <1>; - image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + image-type-id = "985F2937-7C2E-5E9A-8A5E-8E063312964B"; }; image2 { lowest-supported-version = <7>; image-index = <2>; - image-type-id = "5A7021F5-FEF2-48B4-AABA-832E777418C0"; + image-type-id = "9E339473-C2EB-530A-A69B-0CD6BBBED40E"; }; image3 { lowest-supported-version = <3>; image-index = <1>; - image-type-id = "3673B45D-6A7C-46F3-9E60-ADABB03F7937"; + image-type-id = "46610520-469E-59DC-A8DD-C11832B877EA"; }; }; }; diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py index 5941545d0b29..768e006dc50d 100644 --- a/tools/binman/etype/efi_capsule.py +++ b/tools/binman/etype/efi_capsule.py @@ -23,9 +23,9 @@ def get_binman_test_guid(type_str): Returns: The actual GUID value (str) """ TYPE_TO_GUID = { - 'binman-test' : '09d7cf52-0720-4710-91d1-08469b7fe9c8' + 'binman-test' : '985f2937-7c2e-5e9a-8a5e-8e063312964b' }
return TYPE_TO_GUID[type_str]
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 93f3d22cf573..2577c0016c0c 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -124,9 +124,9 @@ TEE_ADDR = 0x5678
# Firmware Management Protocol(FMP) GUID FW_MGMT_GUID = '6dcbd5ed-e82d-4c44-bda1-7194199ad92a' # Image GUID specified in the DTS -CAPSULE_IMAGE_GUID = '09d7cf52-0720-4710-91d1-08469b7fe9c8' +CAPSULE_IMAGE_GUID = '985F2937-7C2E-5E9A-8A5E-8E063312964B' # Windows cert GUID WIN_CERT_TYPE_EFI_GUID = '4aafd29d-68df-49ee-8aa9-347d375665a7' # Empty capsule GUIDs EMPTY_CAPSULE_ACCEPT_GUID = '0c996046-bcc0-4d04-85ec-e1fcedf1c6f8'

Adjust the UUID library code so that it can be compiled as part of a host tool.
This removes the one redundant log_debug() call, as well as the incorrectly defined LOG_CATEGORY.
In general this is a fairly trivial change, just adjusting includes and disabling list_guid.
This will be used by a new genguid tool to generate v5 GUIDs that match those generated by U-Boot at runtime.
Acked-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- include/uuid.h | 4 ++-- lib/uuid.c | 44 ++++++++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/include/uuid.h b/include/uuid.h index 1f4fa103b5e9..7f8414dc906c 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -69,10 +69,10 @@ struct uuid { } __packed;
/* Bits of a bitmask specifying the output format for GUIDs */ #define UUID_STR_FORMAT_STD 0 -#define UUID_STR_FORMAT_GUID BIT(0) -#define UUID_STR_UPPER_CASE BIT(1) +#define UUID_STR_FORMAT_GUID 0x1 +#define UUID_STR_UPPER_CASE 0x2
/* Use UUID_STR_LEN + 1 for string space */ #define UUID_STR_LEN 36 #define UUID_BIN_LEN sizeof(struct uuid) diff --git a/lib/uuid.c b/lib/uuid.c index c9dfdf007a18..6fdae7997702 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -6,25 +6,38 @@ * Authors: * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com */
-#define LOG_CATEGOT LOGC_CORE - +#ifndef USE_HOSTCC #include <command.h> #include <efi_api.h> #include <env.h> #include <rand.h> #include <time.h> -#include <uuid.h> -#include <linux/ctype.h> -#include <errno.h> #include <asm/io.h> #include <part_efi.h> #include <malloc.h> #include <dm/uclass.h> #include <rng.h> +#include <linux/ctype.h> +#include <hexdump.h> +#else +#include <stdarg.h> +#include <stdint.h> +#include <eficapsule.h> +#include <ctype.h> +#endif +#include <linux/types.h> +#include <errno.h> +#include <linux/kconfig.h> +#include <uuid.h> #include <u-boot/sha1.h>
+#ifdef USE_HOSTCC +/* polyfill hextoul to avoid pulling in strto.c */ +#define hextoul(cp, endp) strtoul(cp, endp, 16) +#endif + int uuid_str_valid(const char *uuid) { int i, valid;
@@ -51,8 +64,9 @@ int uuid_str_valid(const char *uuid) static const struct { const char *string; efi_guid_t guid; } list_guid[] = { +#ifndef USE_HOSTCC #ifdef CONFIG_PARTITION_TYPE_GUID {"system", PARTITION_SYSTEM_GUID}, {"mbr", LEGACY_MBR_PARTITION_GUID}, {"msft", PARTITION_MSFT_RESERVED_GUID}, @@ -231,8 +245,9 @@ static const struct { { "EFI_MEMORY_TYPE", EFI_MEMORY_TYPE }, { "EFI_MEM_STATUS_CODE_REC", EFI_MEM_STATUS_CODE_REC }, { "EFI_GUID_EFI_ACPI1", EFI_GUID_EFI_ACPI1 }, #endif +#endif /* !USE_HOSTCC */ };
int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin) { @@ -266,9 +281,8 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, uint32_t tmp32; uint64_t tmp64;
if (!uuid_str_valid(uuid_str)) { - log_debug("not valid\n"); #ifdef CONFIG_PARTITION_TYPE_GUID if (!uuid_guid_get_bin(uuid_str, uuid_bin)) return 0; #endif @@ -297,19 +311,19 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin,
tmp16 = cpu_to_be16(hextoul(uuid_str + 19, NULL)); memcpy(uuid_bin + 8, &tmp16, 2);
- tmp64 = cpu_to_be64(simple_strtoull(uuid_str + 24, NULL, 16)); + tmp64 = cpu_to_be64(hextoul(uuid_str + 24, NULL)); memcpy(uuid_bin + 10, (char *)&tmp64 + 2, 6);
return 0; }
int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin) { - u16 tmp16; - u32 tmp32; - u64 tmp64; + uint16_t tmp16; + uint32_t tmp32; + uint64_t tmp64;
if (!uuid_str_valid(uuid_str) || !uuid_bin) return -EINVAL;
@@ -324,22 +338,22 @@ int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin)
tmp16 = cpu_to_le16(hextoul(uuid_str + 19, NULL)); memcpy(uuid_bin + 8, &tmp16, 2);
- tmp64 = cpu_to_le64(simple_strtoull(uuid_str + 24, NULL, 16)); + tmp64 = cpu_to_le64(hextoul(uuid_str + 24, NULL)); memcpy(uuid_bin + 10, &tmp64, 6);
return 0; }
void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str, int str_format) { - const u8 uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, + const uint8_t uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - const u8 guid_char_order[UUID_BIN_LEN] = {3, 2, 1, 0, 5, 4, 7, 6, 8, + const uint8_t guid_char_order[UUID_BIN_LEN] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15}; - const u8 *char_order; + const uint8_t *char_order; const char *format; int i;
/* @@ -419,8 +433,9 @@ void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...) tmp16 = (uint16_t *)&guid->b[6]; *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16)); }
+#ifndef USE_HOSTCC #if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID) void gen_rand_uuid(unsigned char *uuid_bin) { u32 ptr[4]; @@ -502,4 +517,5 @@ U_BOOT_CMD(guid, CONFIG_SYS_MAXARGS, 1, do_uuid, "e.g. guid guid_env" ); #endif /* CONFIG_CMD_UUID */ #endif /* CONFIG_RANDOM_UUID || CONFIG_CMD_UUID */ +#endif /* !USE_HOSTCC */

Hi,
This patch seens cause problemes for STM32MP1 platforms, AARCH32
For FIP UUID configuration.
On 8/30/24 14:34, Caleb Connolly wrote:
Adjust the UUID library code so that it can be compiled as part of a host tool.
This removes the one redundant log_debug() call, as well as the incorrectly defined LOG_CATEGORY.
In general this is a fairly trivial change, just adjusting includes and disabling list_guid.
This will be used by a new genguid tool to generate v5 GUIDs that match those generated by U-Boot at runtime.
Acked-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
include/uuid.h | 4 ++-- lib/uuid.c | 44 ++++++++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/include/uuid.h b/include/uuid.h index 1f4fa103b5e9..7f8414dc906c 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -69,10 +69,10 @@ struct uuid { } __packed;
/* Bits of a bitmask specifying the output format for GUIDs */ #define UUID_STR_FORMAT_STD 0 -#define UUID_STR_FORMAT_GUID BIT(0) -#define UUID_STR_UPPER_CASE BIT(1) +#define UUID_STR_FORMAT_GUID 0x1 +#define UUID_STR_UPPER_CASE 0x2
/* Use UUID_STR_LEN + 1 for string space */ #define UUID_STR_LEN 36 #define UUID_BIN_LEN sizeof(struct uuid) diff --git a/lib/uuid.c b/lib/uuid.c index c9dfdf007a18..6fdae7997702 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -6,25 +6,38 @@
- Authors:
- Abdellatif El Khlifi abdellatif.elkhlifi@arm.com
*/
-#define LOG_CATEGOT LOGC_CORE
+#ifndef USE_HOSTCC #include <command.h> #include <efi_api.h> #include <env.h> #include <rand.h> #include <time.h> -#include <uuid.h> -#include <linux/ctype.h> -#include <errno.h> #include <asm/io.h> #include <part_efi.h> #include <malloc.h> #include <dm/uclass.h> #include <rng.h> +#include <linux/ctype.h> +#include <hexdump.h> +#else +#include <stdarg.h> +#include <stdint.h> +#include <eficapsule.h> +#include <ctype.h> +#endif +#include <linux/types.h> +#include <errno.h> +#include <linux/kconfig.h> +#include <uuid.h> #include <u-boot/sha1.h>
+#ifdef USE_HOSTCC +/* polyfill hextoul to avoid pulling in strto.c */ +#define hextoul(cp, endp) strtoul(cp, endp, 16) +#endif
- int uuid_str_valid(const char *uuid) { int i, valid;
@@ -51,8 +64,9 @@ int uuid_str_valid(const char *uuid) static const struct { const char *string; efi_guid_t guid; } list_guid[] = { +#ifndef USE_HOSTCC #ifdef CONFIG_PARTITION_TYPE_GUID {"system", PARTITION_SYSTEM_GUID}, {"mbr", LEGACY_MBR_PARTITION_GUID}, {"msft", PARTITION_MSFT_RESERVED_GUID}, @@ -231,8 +245,9 @@ static const struct { { "EFI_MEMORY_TYPE", EFI_MEMORY_TYPE }, { "EFI_MEM_STATUS_CODE_REC", EFI_MEM_STATUS_CODE_REC }, { "EFI_GUID_EFI_ACPI1", EFI_GUID_EFI_ACPI1 }, #endif +#endif /* !USE_HOSTCC */ };
int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin) { @@ -266,9 +281,8 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, uint32_t tmp32; uint64_t tmp64;
if (!uuid_str_valid(uuid_str)) {
#ifdef CONFIG_PARTITION_TYPE_GUID if (!uuid_guid_get_bin(uuid_str, uuid_bin)) return 0; #endiflog_debug("not valid\n");
@@ -297,19 +311,19 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin,
tmp16 = cpu_to_be16(hextoul(uuid_str + 19, NULL)); memcpy(uuid_bin + 8, &tmp16, 2);
- tmp64 = cpu_to_be64(simple_strtoull(uuid_str + 24, NULL, 16));
tmp64 = cpu_to_be64(hextoul(uuid_str + 24, NULL)); memcpy(uuid_bin + 10, (char *)&tmp64 + 2, 6);
return 0; }
int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin) {
- u16 tmp16;
- u32 tmp32;
- u64 tmp64;
uint16_t tmp16;
uint32_t tmp32;
uint64_t tmp64;
if (!uuid_str_valid(uuid_str) || !uuid_bin) return -EINVAL;
@@ -324,22 +338,22 @@ int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin)
tmp16 = cpu_to_le16(hextoul(uuid_str + 19, NULL)); memcpy(uuid_bin + 8, &tmp16, 2);
- tmp64 = cpu_to_le64(simple_strtoull(uuid_str + 24, NULL, 16));
- tmp64 = cpu_to_le64(hextoul(uuid_str + 24, NULL));
Here you change
simple_strtoull => return unsigned long long
to
hextoul => return unsigned long
for 32bits system that can the cause of issue I think
with UUID defined in stm32prog command, with use a gpt create command with UUID define in
./arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
/* FIP type partition UUID used by TF-A*/ #define FIP_TYPE_UUID "19D5DF83-11B0-457B-BE2C-7559C13142A5"
/* unique partition guid (uuid) for FIP partitions A/B */ #define FIP_A_UUID \ EFI_GUID(0x4FD84C93, 0x54EF, 0x463F, \ 0xA7, 0xEF, 0xAE, 0x25, 0xFF, 0x88, 0x70, 0x87)
with the patch the GPT partition is create with incorrect UUID (type and partion) with "0000" in last field.
$> BAD Partition GUID code: 19D5DF83-11B0-457B-BE2C-0000C13142A5 Partition unique GUID: 4FD84C93-54EF-463F-A7EF-0000FF887087
before the patch
$> OK Partition GUID code: 19D5DF83-11B0-457B-BE2C-7559C13142A5 Partition unique GUID: 4FD84C93-54EF-463F-A7EF-AE25FF887087
for 32bits platform, we must use simple_strtoull and not
ulong hextoul(const char *cp, char **endp) { return simple_strtoul(cp, endp, 16); }
for define hextoull()
what do you thin, of this issue ?
memcpy(uuid_bin + 10, &tmp64, 6);
return 0; }
void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str, int str_format) {
- const u8 uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
- const uint8_t uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
- const u8 guid_char_order[UUID_BIN_LEN] = {3, 2, 1, 0, 5, 4, 7, 6, 8,
- const uint8_t guid_char_order[UUID_BIN_LEN] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15};
- const u8 *char_order;
const uint8_t *char_order; const char *format; int i;
/*
@@ -419,8 +433,9 @@ void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...) tmp16 = (uint16_t *)&guid->b[6]; *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16)); }
+#ifndef USE_HOSTCC #if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID) void gen_rand_uuid(unsigned char *uuid_bin) { u32 ptr[4]; @@ -502,4 +517,5 @@ U_BOOT_CMD(guid, CONFIG_SYS_MAXARGS, 1, do_uuid, "e.g. guid guid_env" ); #endif /* CONFIG_CMD_UUID */ #endif /* CONFIG_RANDOM_UUID || CONFIG_CMD_UUID */ +#endif /* !USE_HOSTCC */

Hey Patrick,
Wow thanks for tracking this one down.
On 28/10/2024 15:14, Patrick DELAUNAY wrote:
Hi,
This patch seens cause problemes for STM32MP1 platforms, AARCH32
For FIP UUID configuration.
On 8/30/24 14:34, Caleb Connolly wrote:
Adjust the UUID library code so that it can be compiled as part of a host tool.
This removes the one redundant log_debug() call, as well as the incorrectly defined LOG_CATEGORY.
In general this is a fairly trivial change, just adjusting includes and disabling list_guid.
This will be used by a new genguid tool to generate v5 GUIDs that match those generated by U-Boot at runtime.
Acked-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org
include/uuid.h | 4 ++-- lib/uuid.c | 44 ++++++++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/include/uuid.h b/include/uuid.h index 1f4fa103b5e9..7f8414dc906c 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -69,10 +69,10 @@ struct uuid { } __packed; /* Bits of a bitmask specifying the output format for GUIDs */ #define UUID_STR_FORMAT_STD 0 -#define UUID_STR_FORMAT_GUID BIT(0) -#define UUID_STR_UPPER_CASE BIT(1) +#define UUID_STR_FORMAT_GUID 0x1 +#define UUID_STR_UPPER_CASE 0x2 /* Use UUID_STR_LEN + 1 for string space */ #define UUID_STR_LEN 36 #define UUID_BIN_LEN sizeof(struct uuid) diff --git a/lib/uuid.c b/lib/uuid.c index c9dfdf007a18..6fdae7997702 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -6,25 +6,38 @@ * Authors: * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com */ -#define LOG_CATEGOT LOGC_CORE
+#ifndef USE_HOSTCC #include <command.h> #include <efi_api.h> #include <env.h> #include <rand.h> #include <time.h> -#include <uuid.h> -#include <linux/ctype.h> -#include <errno.h> #include <asm/io.h> #include <part_efi.h> #include <malloc.h> #include <dm/uclass.h> #include <rng.h> +#include <linux/ctype.h> +#include <hexdump.h> +#else +#include <stdarg.h> +#include <stdint.h> +#include <eficapsule.h> +#include <ctype.h> +#endif +#include <linux/types.h> +#include <errno.h> +#include <linux/kconfig.h> +#include <uuid.h> #include <u-boot/sha1.h> +#ifdef USE_HOSTCC +/* polyfill hextoul to avoid pulling in strto.c */ +#define hextoul(cp, endp) strtoul(cp, endp, 16) +#endif
int uuid_str_valid(const char *uuid) { int i, valid; @@ -51,8 +64,9 @@ int uuid_str_valid(const char *uuid) static const struct { const char *string; efi_guid_t guid; } list_guid[] = { +#ifndef USE_HOSTCC #ifdef CONFIG_PARTITION_TYPE_GUID {"system", PARTITION_SYSTEM_GUID}, {"mbr", LEGACY_MBR_PARTITION_GUID}, {"msft", PARTITION_MSFT_RESERVED_GUID}, @@ -231,8 +245,9 @@ static const struct { { "EFI_MEMORY_TYPE", EFI_MEMORY_TYPE }, { "EFI_MEM_STATUS_CODE_REC", EFI_MEM_STATUS_CODE_REC }, { "EFI_GUID_EFI_ACPI1", EFI_GUID_EFI_ACPI1 }, #endif +#endif /* !USE_HOSTCC */ }; int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin) { @@ -266,9 +281,8 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, uint32_t tmp32; uint64_t tmp64; if (!uuid_str_valid(uuid_str)) { - log_debug("not valid\n"); #ifdef CONFIG_PARTITION_TYPE_GUID if (!uuid_guid_get_bin(uuid_str, uuid_bin)) return 0; #endif @@ -297,19 +311,19 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, tmp16 = cpu_to_be16(hextoul(uuid_str + 19, NULL)); memcpy(uuid_bin + 8, &tmp16, 2); - tmp64 = cpu_to_be64(simple_strtoull(uuid_str + 24, NULL, 16)); + tmp64 = cpu_to_be64(hextoul(uuid_str + 24, NULL)); memcpy(uuid_bin + 10, (char *)&tmp64 + 2, 6); return 0; } int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin) { - u16 tmp16; - u32 tmp32; - u64 tmp64; + uint16_t tmp16; + uint32_t tmp32; + uint64_t tmp64; if (!uuid_str_valid(uuid_str) || !uuid_bin) return -EINVAL; @@ -324,22 +338,22 @@ int uuid_str_to_le_bin(const char *uuid_str, unsigned char *uuid_bin) tmp16 = cpu_to_le16(hextoul(uuid_str + 19, NULL)); memcpy(uuid_bin + 8, &tmp16, 2); - tmp64 = cpu_to_le64(simple_strtoull(uuid_str + 24, NULL, 16)); + tmp64 = cpu_to_le64(hextoul(uuid_str + 24, NULL));
Here you change
simple_strtoull => return unsigned long long
to
hextoul => return unsigned long
for 32bits system that can the cause of issue I think
Yep that would do it, damn! I think I seriously just misread "strtoull" as "strtoul" and didn't notice :(
I've sent https://lore.kernel.org/u-boot/20241030003317.2901772-2-caleb.connolly@linar... which should address this. I would greatly appreciate it if you could give it a test.
Kind regards,
with UUID defined in stm32prog command, with use a gpt create command with UUID define in
./arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
/* FIP type partition UUID used by TF-A*/ #define FIP_TYPE_UUID "19D5DF83-11B0-457B-BE2C-7559C13142A5"
/* unique partition guid (uuid) for FIP partitions A/B */ #define FIP_A_UUID \ EFI_GUID(0x4FD84C93, 0x54EF, 0x463F, \ 0xA7, 0xEF, 0xAE, 0x25, 0xFF, 0x88, 0x70, 0x87)
with the patch the GPT partition is create with incorrect UUID (type and partion) with "0000" in last field.
$> BAD Partition GUID code: 19D5DF83-11B0-457B-BE2C-0000C13142A5 Partition unique GUID: 4FD84C93-54EF-463F-A7EF-0000FF887087
before the patch
$> OK Partition GUID code: 19D5DF83-11B0-457B-BE2C-7559C13142A5 Partition unique GUID: 4FD84C93-54EF-463F-A7EF-AE25FF887087
for 32bits platform, we must use simple_strtoull and not
ulong hextoul(const char *cp, char **endp) { return simple_strtoul(cp, endp, 16); }
for define hextoull()
what do you thin, of this issue ?
memcpy(uuid_bin + 10, &tmp64, 6); return 0; } void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str, int str_format) { - const u8 uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, + const uint8_t uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - const u8 guid_char_order[UUID_BIN_LEN] = {3, 2, 1, 0, 5, 4, 7, 6, 8, + const uint8_t guid_char_order[UUID_BIN_LEN] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15}; - const u8 *char_order; + const uint8_t *char_order; const char *format; int i; /* @@ -419,8 +433,9 @@ void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...) tmp16 = (uint16_t *)&guid->b[6]; *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16)); } +#ifndef USE_HOSTCC #if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID) void gen_rand_uuid(unsigned char *uuid_bin) { u32 ptr[4]; @@ -502,4 +517,5 @@ U_BOOT_CMD(guid, CONFIG_SYS_MAXARGS, 1, do_uuid, "e.g. guid guid_env" ); #endif /* CONFIG_CMD_UUID */ #endif /* CONFIG_RANDOM_UUID || CONFIG_CMD_UUID */ +#endif /* !USE_HOSTCC */

Move this header to include/u-boot/ so that it can be used by external tools.
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- arch/arm/mach-rockchip/board.c | 2 +- board/cobra5272/flash.c | 2 +- board/gardena/smart-gateway-mt7688/board.c | 2 +- board/socrates/socrates.c | 2 +- board/xilinx/common/board.c | 2 +- cmd/efi.c | 2 +- cmd/efi_common.c | 2 +- cmd/flash.c | 2 +- cmd/gpt.c | 2 +- cmd/nvedit_efi.c | 2 +- cmd/x86/hob.c | 2 +- common/flash.c | 2 +- disk/part_efi.c | 2 +- drivers/firmware/arm-ffa/arm-ffa-uclass.c | 2 +- env/sf.c | 2 +- fs/btrfs/btrfs.c | 2 +- fs/btrfs/compat.h | 2 +- fs/btrfs/disk-io.c | 2 +- fs/ext4/ext4fs.c | 2 +- include/fwu.h | 2 +- include/part.h | 2 +- include/rkmtd.h | 2 +- include/{ => u-boot}/uuid.h | 0 lib/acpi/acpi_dp.c | 2 +- lib/acpi/acpigen.c | 2 +- lib/efi/efi_app.c | 2 +- lib/efi_loader/efi_capsule.c | 2 +- lib/efi_loader/efi_device_path.c | 2 +- lib/efi_loader/efi_variable.c | 2 +- lib/fwu_updates/fwu_mtd.c | 2 +- lib/uuid.c | 2 +- lib/vsprintf.c | 2 +- net/bootp.c | 2 +- test/dm/acpi_dp.c | 2 +- test/dm/acpigen.c | 2 +- test/lib/uuid.c | 2 +- 36 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c index 8a57b8217ff2..0fdf9365b41e 100644 --- a/arch/arm/mach-rockchip/board.c +++ b/arch/arm/mach-rockchip/board.c @@ -24,9 +24,9 @@ #include <misc.h> #include <part.h> #include <ram.h> #include <syscon.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <u-boot/crc.h> #include <u-boot/sha256.h> #include <asm/cache.h> #include <asm/io.h> diff --git a/board/cobra5272/flash.c b/board/cobra5272/flash.c index 616842e62f4e..f16f2f1184f3 100644 --- a/board/cobra5272/flash.c +++ b/board/cobra5272/flash.c @@ -10,9 +10,9 @@ #include <flash.h> #include <irq_func.h> #include <stdio.h> #include <time.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <vsprintf.h> #include <linux/delay.h> #include <linux/string.h>
diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c index c6b14bed41fb..eb7fcd630a10 100644 --- a/board/gardena/smart-gateway-mt7688/board.c +++ b/board/gardena/smart-gateway-mt7688/board.c @@ -15,9 +15,9 @@ #include <spi_flash.h> #include <linux/delay.h> #include <linux/stringify.h> #include <u-boot/crc.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <linux/ctype.h> #include <linux/io.h>
#define MT76XX_AGPIO_CFG 0x1000003c diff --git a/board/socrates/socrates.c b/board/socrates/socrates.c index 6e6e276cc741..5e5a45ee00db 100644 --- a/board/socrates/socrates.c +++ b/board/socrates/socrates.c @@ -14,9 +14,9 @@ #include <clock_legacy.h> #include <env.h> #include <init.h> #include <pci.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <asm/global_data.h> #include <asm/processor.h> #include <asm/immap_85xx.h> #include <ioports.h> diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 0b43407b9e94..8cec455ae984 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -30,9 +30,9 @@ #include <slre.h> #include <soc.h> #include <linux/ctype.h> #include <linux/kernel.h> -#include <uuid.h> +#include <u-boot/uuid.h>
#include "fru.h"
#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) diff --git a/cmd/efi.c b/cmd/efi.c index 6bed2d743ba6..687ccb520428 100644 --- a/cmd/efi.c +++ b/cmd/efi.c @@ -10,9 +10,9 @@ #include <errno.h> #include <log.h> #include <malloc.h> #include <sort.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/cmd/efi_common.c b/cmd/efi_common.c index c46764e6eea7..d2f2b59e9e3b 100644 --- a/cmd/efi_common.c +++ b/cmd/efi_common.c @@ -7,9 +7,9 @@ */
#include <efi.h> #include <efi_api.h> -#include <uuid.h> +#include <u-boot/uuid.h>
void efi_show_tables(struct efi_system_table *systab) { int i; diff --git a/cmd/flash.c b/cmd/flash.c index de0e04f09cfb..fd660ec477c9 100644 --- a/cmd/flash.c +++ b/cmd/flash.c @@ -9,9 +9,9 @@ */ #include <command.h> #include <log.h> #include <vsprintf.h> -#include <uuid.h> +#include <u-boot/uuid.h>
#if defined(CONFIG_CMD_MTDPARTS) #include <jffs2/jffs2.h>
diff --git a/cmd/gpt.c b/cmd/gpt.c index 86b7701886a3..27aea2df197c 100644 --- a/cmd/gpt.c +++ b/cmd/gpt.c @@ -18,9 +18,9 @@ #include <part.h> #include <part_efi.h> #include <part.h> #include <exports.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <linux/ctype.h> #include <div64.h> #include <memalign.h> #include <linux/compat.h> diff --git a/cmd/nvedit_efi.c b/cmd/nvedit_efi.c index 64ae2ad2ce24..32b7d0490747 100644 --- a/cmd/nvedit_efi.c +++ b/cmd/nvedit_efi.c @@ -14,9 +14,9 @@ #include <hexdump.h> #include <malloc.h> #include <mapmem.h> #include <rtc.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <linux/kernel.h>
/* * From efi_variable.c, diff --git a/cmd/x86/hob.c b/cmd/x86/hob.c index 2dd30808bd10..d3713cef3312 100644 --- a/cmd/x86/hob.c +++ b/cmd/x86/hob.c @@ -4,9 +4,9 @@ */
#include <command.h> #include <efi.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <asm/global_data.h> #include <asm/hob.h> #include <asm/fsp/fsp_hob.h>
diff --git a/common/flash.c b/common/flash.c index 24ddc8bee724..226646c6868f 100644 --- a/common/flash.c +++ b/common/flash.c @@ -7,9 +7,9 @@ /* #define DEBUG */
#include <flash.h> #include <log.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <linux/string.h>
#include <mtd/cfi_flash.h>
diff --git a/disk/part_efi.c b/disk/part_efi.c index b1a03bd165e0..580821a6ee9c 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -14,9 +14,9 @@
#include <blk.h> #include <log.h> #include <part.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <asm/cache.h> #include <asm/global_data.h> #include <asm/unaligned.h> #include <command.h> diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c b/drivers/firmware/arm-ffa/arm-ffa-uclass.c index e0767fc75517..96c64964bb73 100644 --- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c +++ b/drivers/firmware/arm-ffa/arm-ffa-uclass.c @@ -10,9 +10,9 @@ #include <dm.h> #include <log.h> #include <malloc.h> #include <string.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <asm/global_data.h> #include <dm/device-internal.h> #include <dm/devres.h> #include <dm/root.h> diff --git a/env/sf.c b/env/sf.c index 906b85b0db44..21ac0c202e73 100644 --- a/env/sf.c +++ b/env/sf.c @@ -15,9 +15,9 @@ #include <spi.h> #include <spi_flash.h> #include <search.h> #include <errno.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <asm/cache.h> #include <asm/global_data.h> #include <dm/device-internal.h> #include <u-boot/crc.h> diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c index 1149a3b20077..350cff0cbca0 100644 --- a/fs/btrfs/btrfs.c +++ b/fs/btrfs/btrfs.c @@ -6,9 +6,9 @@ */
#include <config.h> #include <malloc.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <linux/time.h> #include "btrfs.h" #include "crypto/hash.h" #include "disk-io.h" diff --git a/fs/btrfs/compat.h b/fs/btrfs/compat.h index 02173dea5f48..4596b9d1dd39 100644 --- a/fs/btrfs/compat.h +++ b/fs/btrfs/compat.h @@ -4,9 +4,9 @@ #define __BTRFS_COMPAT_H__
#include <linux/errno.h> #include <fs_internal.h> -#include <uuid.h> +#include <u-boot/uuid.h>
/* Provide a compatibility layer to make code syncing easier */
/* A simple wraper to for error() used in btrfs-progs */ diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 34d9d5351216..14efe7218df5 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0+ #include <fs_internal.h> #include <log.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <memalign.h> #include "kernel-shared/btrfs_tree.h" #include "common/rbtree-utils.h" #include "disk-io.h" diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c index da59cb008fce..15587e92e3e7 100644 --- a/fs/ext4/ext4fs.c +++ b/fs/ext4/ext4fs.c @@ -26,9 +26,9 @@ #include "ext4_common.h" #include <div64.h> #include <malloc.h> #include <part.h> -#include <uuid.h> +#include <u-boot/uuid.h>
int ext4fs_symlinknest; struct ext_filesystem ext_fs;
diff --git a/include/fwu.h b/include/fwu.h index 77ec65e61807..c317613eaaab 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -9,9 +9,9 @@ #include <blk.h> #include <efi.h> #include <fwu_mdata.h> #include <mtd.h> -#include <uuid.h> +#include <u-boot/uuid.h>
#include <linux/types.h>
struct fwu_mdata; diff --git a/include/part.h b/include/part.h index 54b986cee631..797b542ef1ff 100644 --- a/include/part.h +++ b/include/part.h @@ -7,9 +7,9 @@ #define _PART_H
#include <blk.h> #include <ide.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <linker_lists.h> #include <linux/errno.h> #include <linux/list.h>
diff --git a/include/rkmtd.h b/include/rkmtd.h index 145fede6c840..b7479036b397 100644 --- a/include/rkmtd.h +++ b/include/rkmtd.h @@ -10,9 +10,9 @@ #ifndef __RKMTD__ #define __RKMTD__
#include <part_efi.h> -#include <uuid.h> +#include <u-boot/uuid.h>
#define LBA 64 + 512 + 33
#define RK_TAG 0xFCDC8C3B diff --git a/include/uuid.h b/include/u-boot/uuid.h similarity index 100% rename from include/uuid.h rename to include/u-boot/uuid.h diff --git a/lib/acpi/acpi_dp.c b/lib/acpi/acpi_dp.c index 6733809986ae..5714acce0882 100644 --- a/lib/acpi/acpi_dp.c +++ b/lib/acpi/acpi_dp.c @@ -8,9 +8,9 @@
#include <dm.h> #include <log.h> #include <malloc.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <acpi/acpigen.h> #include <acpi/acpi_dp.h> #include <dm/acpi.h>
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c index b95cabb91493..ecff5a50d504 100644 --- a/lib/acpi/acpigen.c +++ b/lib/acpi/acpigen.c @@ -9,9 +9,9 @@ #define LOG_CATEGORY LOGC_ACPI
#include <dm.h> #include <log.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <acpi/acpigen.h> #include <acpi/acpi_device.h> #include <acpi/acpi_table.h> #include <dm/acpi.h> diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index 88332c3c910a..9b94a93ee4f1 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -16,9 +16,9 @@ #include <errno.h> #include <init.h> #include <malloc.h> #include <sysreset.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <asm/global_data.h> #include <linux/err.h> #include <linux/types.h> #include <asm/global_data.h> diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index f3a2388506cc..a4ea28730387 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -19,9 +19,9 @@ #include <mapmem.h> #include <sort.h> #include <sysreset.h> #include <asm/global_data.h> -#include <uuid.h> +#include <u-boot/uuid.h>
#include <crypto/pkcs7.h> #include <crypto/pkcs7_parser.h> #include <linux/err.h> diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 0f684590f22a..9de3b95d073b 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -16,9 +16,9 @@ #include <mmc.h> #include <nvme.h> #include <efi_loader.h> #include <part.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <asm-generic/unaligned.h> #include <linux/compat.h> /* U16_MAX */
/* template END node: */ diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index e888c52efe3e..f3533f4def3a 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -15,9 +15,9 @@ #include <log.h> #include <malloc.h> #include <rtc.h> #include <search.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <crypto/pkcs7_parser.h> #include <linux/compat.h> #include <u-boot/crc.h> #include <asm/sections.h> diff --git a/lib/fwu_updates/fwu_mtd.c b/lib/fwu_updates/fwu_mtd.c index ccaba3f3115a..11b42a3d796c 100644 --- a/lib/fwu_updates/fwu_mtd.c +++ b/lib/fwu_updates/fwu_mtd.c @@ -9,9 +9,9 @@ #include <fwu_mdata.h> #include <log.h> #include <malloc.h> #include <mtd.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <stdio.h>
#include <dm/ofnode.h>
diff --git a/lib/uuid.c b/lib/uuid.c index 6fdae7997702..11b86ffb02e6 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -28,9 +28,9 @@ #endif #include <linux/types.h> #include <errno.h> #include <linux/kconfig.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <u-boot/sha1.h>
#ifdef USE_HOSTCC /* polyfill hextoul to avoid pulling in strto.c */ diff --git a/lib/vsprintf.c b/lib/vsprintf.c index cfd1f1914edf..e5802866632e 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -17,9 +17,9 @@ #include <efi_loader.h> #include <div64.h> #include <hexdump.h> #include <stdarg.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <stdio.h> #include <vsprintf.h> #include <linux/ctype.h> #include <linux/err.h> diff --git a/net/bootp.c b/net/bootp.c index 9dfb50749b49..512ab2ed7c81 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -14,9 +14,9 @@ #include <efi_loader.h> #include <log.h> #include <net.h> #include <rand.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <linux/delay.h> #include <net/tftp.h> #include "bootp.h" #ifdef CONFIG_LED_STATUS diff --git a/test/dm/acpi_dp.c b/test/dm/acpi_dp.c index eaeda2b8a7af..038806004b55 100644 --- a/test/dm/acpi_dp.c +++ b/test/dm/acpi_dp.c @@ -6,9 +6,9 @@ * Written by Simon Glass sjg@chromium.org */
#include <dm.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <acpi/acpigen.h> #include <acpi/acpi_dp.h> #include <asm/unaligned.h> #include <dm/acpi.h> diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c index 3e912fadaef8..23c16bd98669 100644 --- a/test/dm/acpigen.c +++ b/test/dm/acpigen.c @@ -8,9 +8,9 @@
#include <dm.h> #include <irq.h> #include <malloc.h> -#include <uuid.h> +#include <u-boot/uuid.h> #include <acpi/acpigen.h> #include <acpi/acpi_device.h> #include <acpi/acpi_table.h> #include <asm/gpio.h> diff --git a/test/lib/uuid.c b/test/lib/uuid.c index 8fe65dbf78ba..3d62e18bcfee 100644 --- a/test/lib/uuid.c +++ b/test/lib/uuid.c @@ -7,9 +7,9 @@ * Authors: * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com */
-#include <uuid.h> +#include <u-boot/uuid.h> #include <test/lib.h> #include <test/test.h> #include <test/ut.h>

Replace the use of libuuid with U-Boot's own UUID library. This prepares us to add support for generating v5 GUIDs.
Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- tools/Makefile | 8 ++++---- tools/mkeficapsule.c | 52 +++++----------------------------------------------- 2 files changed, 9 insertions(+), 51 deletions(-)
diff --git a/tools/Makefile b/tools/Makefile index 6a4280e3668f..ee08a9675df8 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -245,14 +245,14 @@ hostprogs-$(CONFIG_ASN1_COMPILER) += asn1_compiler HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include
HOSTCFLAGS_mkeficapsule.o += \ $(shell pkg-config --cflags gnutls 2> /dev/null || echo "") -HOSTCFLAGS_mkeficapsule.o += \ - $(shell pkg-config --cflags uuid 2> /dev/null || echo "") HOSTLDLIBS_mkeficapsule += \ $(shell pkg-config --libs gnutls 2> /dev/null || echo "-lgnutls") -HOSTLDLIBS_mkeficapsule += \ - $(shell pkg-config --libs uuid 2> /dev/null || echo "-luuid") +mkeficapsule-objs := generated/lib/uuid.o \ + generated/lib/sha1.o \ + $(LIBFDT_OBJS) \ + mkeficapsule.o hostprogs-$(CONFIG_TOOLS_MKEFICAPSULE) += mkeficapsule
mkfwumdata-objs := mkfwumdata.o generated/lib/crc32.o HOSTLDLIBS_mkfwumdata += -luuid diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index f28008a0829f..68c97cfb9db4 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -14,15 +14,15 @@ #include <linux/types.h>
#include <sys/stat.h> #include <sys/types.h> -#include <uuid/uuid.h>
#include <gnutls/gnutls.h> #include <gnutls/pkcs7.h> #include <gnutls/abstract.h>
#include <version.h> +#include <u-boot/uuid.h>
#include "eficapsule.h"
static const char *tool_name = "mkeficapsule"; @@ -576,39 +576,8 @@ err:
return ret; }
-/** - * convert_uuid_to_guid() - convert UUID to GUID - * @buf: UUID binary - * - * UUID and GUID have the same data structure, but their binary - * formats are different due to the endianness. See lib/uuid.c. - * Since uuid_parse() can handle only UUID, this function must - * be called to get correct data for GUID when parsing a string. - * - * The correct data will be returned in @buf. - */ -void convert_uuid_to_guid(unsigned char *buf) -{ - unsigned char c; - - c = buf[0]; - buf[0] = buf[3]; - buf[3] = c; - c = buf[1]; - buf[1] = buf[2]; - buf[2] = c; - - c = buf[4]; - buf[4] = buf[5]; - buf[5] = c; - - c = buf[6]; - buf[6] = buf[7]; - buf[7] = c; -} - static int create_empty_capsule(char *path, efi_guid_t *guid, bool fw_accept) { struct efi_capsule_header header = { 0 }; FILE *f = NULL; @@ -652,22 +621,12 @@ err: }
static void print_guid(void *ptr) { - int i; - efi_guid_t *guid = ptr; - const uint8_t seq[] = { - 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, - '-', 8, 9, '-', 10, 11, 12, 13, 14, 15 }; + static char buf[37] = { 0 };
- for (i = 0; i < ARRAY_SIZE(seq); i++) { - if (seq[i] == '-') - putchar(seq[i]); - else - printf("%02X", guid->b[seq[i]]); - } - - printf("\n"); + uuid_bin_to_str(ptr, buf, UUID_STR_FORMAT_GUID | UUID_STR_UPPER_CASE); + printf("%s\n", buf); }
static uint32_t dump_fmp_payload_header( struct fmp_payload_header *fmp_payload_hdr) @@ -905,13 +864,12 @@ int main(int argc, char **argv) fprintf(stderr, "Image type already specified\n"); exit(EXIT_FAILURE); } - if (uuid_parse(optarg, uuid_buf)) { + if (uuid_str_to_bin(optarg, uuid_buf, UUID_STR_FORMAT_GUID)) { fprintf(stderr, "Wrong guid format\n"); exit(EXIT_FAILURE); } - convert_uuid_to_guid(uuid_buf); guid = (efi_guid_t *)uuid_buf; break; case 'i': index = strtoul(optarg, NULL, 0);

Add support for generating GUIDs that match those generated internally by U-Boot for capsule update fw_images when using dynamic UUIDs.
Dynamic UUIDs in U-Boot work by taking a namespace UUID and hashing it with the board compatible and fw_image name. This feature just provides a way to determine the UUIDs for a particular board without having to actually boot U-Boot on it.
Acked-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- doc/mkeficapsule.1 | 23 ++++++++ tools/mkeficapsule.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 174 insertions(+), 5 deletions(-)
diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1 index c3d0f21488ad..a5545f7898a8 100644 --- a/doc/mkeficapsule.1 +++ b/doc/mkeficapsule.1 @@ -9,8 +9,11 @@ mkeficapsule - Generate EFI capsule file for U-Boot .SH SYNOPSIS .B mkeficapsule .RI [ options ] " " [ image-blob ] " " capsule-file
+.B mkeficapsule +.RI guidgen " " [ GUID ] " " DTB " " IMAGE_NAME... + .SH "DESCRIPTION" The .B mkeficapsule command is used to create an EFI capsule file to be used by U-Boot for firmware @@ -41,8 +44,12 @@ format is the same as used in the new uImage format and allows for multiple binary blobs in a single capsule file. This type of image file can be generated by .BR mkimage .
+mkeficapsule can also be used to simulate the dynamic GUID generation used to +identify firmware images in capsule updates by providing the namespace guid, dtb +for the board, and a list of firmware images. + .SH "OPTIONS"
.TP .BI "-g\fR,\fB --guid " guid-string @@ -116,8 +123,24 @@ at every firmware update. .TP .B "-d\fR,\fB --dump_sig" Dump signature data into *.p7 file
+.SH "GUIDGEN OPTIONS" + +.TP +.B "[GUID]" +The namespace/salt GUID, by default this is EFI_CAPSULE_NAMESPACE_GUID. +The format is: + xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + +.TP +.B DTB +The device tree blob file for the board. + +.TP +.B IMAGE_NAME... +The names of the firmware images to generate GUIDs for. + .PP .SH FILES .TP .I /EFI/UpdateCapsule diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index 68c97cfb9db4..7068c936c530 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -20,12 +20,16 @@ #include <gnutls/pkcs7.h> #include <gnutls/abstract.h>
#include <version.h> +#include <libfdt.h> #include <u-boot/uuid.h>
#include "eficapsule.h"
+// Matches CONFIG_EFI_CAPSULE_NAMESPACE_GUID +#define DEFAULT_NAMESPACE_GUID "8c9f137e-91dc-427b-b2d6-b420faebaf2a" + static const char *tool_name = "mkeficapsule";
efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; @@ -54,11 +58,22 @@ static struct option options[] = { {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, };
-static void print_usage(void) +static void print_usage_guidgen(void) { - fprintf(stderr, "Usage: %s [options] <image blob> <output file>\n" + fprintf(stderr, "%s guidgen [GUID] DTB IMAGE_NAME...\n" + "Options:\n" + + "\tGUID Namespace GUID (default: %s)\n" + "\tDTB Device Tree Blob\n" + "\tIMAGE_NAME... One or more names of fw_images to generate GUIDs for\n", + tool_name, DEFAULT_NAMESPACE_GUID); +} + +static void print_usage_mkeficapsule(void) +{ + fprintf(stderr, "Usage:\n\n%s [options] <image blob> <output file>\n" "Options:\n"
"\t-g, --guid <guid string> guid for image blob type\n" "\t-i, --index <index> update image index\n" @@ -72,10 +87,11 @@ static void print_usage(void) "\t-R, --fw-revert firmware revert capsule, takes no GUID, no image blob\n" "\t-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff\n" "\t-D, --dump-capsule dump the contents of the capsule headers\n" "\t-V, --version show version number\n" - "\t-h, --help print a help message\n", + "\t-h, --help print a help message\n\n", tool_name); + print_usage_guidgen(); }
/** * auth_context - authentication context @@ -818,8 +834,131 @@ static void dump_capsule_contents(char *capsule_file) exit(EXIT_FAILURE); } }
+static struct fdt_header *load_dtb(const char *path) +{ + struct fdt_header *dtb; + ssize_t dtb_size; + FILE *f; + + /* Open and parse DTB */ + f = fopen(path, "r"); + if (!f) { + fprintf(stderr, "Cannot open %s\n", path); + return NULL; + } + + if (fseek(f, 0, SEEK_END)) { + fprintf(stderr, "Cannot seek to the end of %s: %s\n", + path, strerror(errno)); + return NULL; + } + + dtb_size = ftell(f); + if (dtb_size < 0) { + fprintf(stderr, "Cannot ftell %s: %s\n", + path, strerror(errno)); + return NULL; + } + + fseek(f, 0, SEEK_SET); + + dtb = malloc(dtb_size); + if (!dtb) { + fprintf(stderr, "Can't allocated %ld\n", dtb_size); + return NULL; + } + + if (fread(dtb, dtb_size, 1, f) != 1) { + fprintf(stderr, "Can't read %ld bytes from %s\n", + dtb_size, path); + free(dtb); + return NULL; + } + + fclose(f); + + return dtb; +} + +#define MAX_IMAGE_NAME_LEN 128 +static int genguid(int argc, char **argv) +{ + int idx = 2, ret; + unsigned char namespace[16]; + struct efi_guid image_type_id; + const char *dtb_path; + struct fdt_header *dtb; + const char *compatible; + int compatlen, namelen; + uint16_t fw_image[MAX_IMAGE_NAME_LEN]; + + if (argc < 2) { + fprintf(stderr, "Usage: "); + print_usage_guidgen(); + return -1; + } + + if (uuid_str_to_bin(argv[1], namespace, UUID_STR_FORMAT_GUID)) { + uuid_str_to_bin(DEFAULT_NAMESPACE_GUID, namespace, UUID_STR_FORMAT_GUID); + dtb_path = argv[1]; + } else { + dtb_path = argv[2]; + idx = 3; + } + + if (idx == argc) { + fprintf(stderr, "Usage: "); + print_usage_guidgen(); + return -1; + } + + dtb = load_dtb(dtb_path); + if (!dtb) + return -1; + + ret = fdt_check_header(dtb); + if (ret) { + fprintf(stderr, "Invalid DTB header: %d\n", ret); + return -1; + } + + compatible = fdt_getprop(dtb, 0, "compatible", &compatlen); + if (!compatible) { + fprintf(stderr, "No compatible string found in DTB\n"); + return -1; + } + if (strnlen(compatible, compatlen) >= compatlen) { + fprintf(stderr, "Compatible string not null-terminated\n"); + return -1; + } + + printf("Generating GUIDs for %s with namespace %s:\n", + compatible, DEFAULT_NAMESPACE_GUID); + for (; idx < argc; idx++) { + memset(fw_image, 0, sizeof(fw_image)); + namelen = strlen(argv[idx]); + if (namelen > MAX_IMAGE_NAME_LEN) { + fprintf(stderr, "Image name too long: %s\n", argv[idx]); + return -1; + } + + for (int i = 0; i < namelen; i++) + fw_image[i] = (uint16_t)argv[idx][i]; + + gen_v5_guid((struct uuid *)&namespace, &image_type_id, + compatible, strlen(compatible), + fw_image, namelen * sizeof(uint16_t), + NULL); + + printf("%s: ", argv[idx]); + print_guid(&image_type_id); + } + + return 0; +} + /** * main - main entry function of mkeficapsule * @argc: Number of arguments * @argv: Array of pointers to arguments @@ -842,8 +981,15 @@ int main(int argc, char **argv) char *privkey_file, *cert_file; int c, idx; struct fmp_payload_header_params fmp_ph_params = { 0 };
+ /* Generate dynamic GUIDs */ + if (argc > 1 && !strcmp(argv[1], "guidgen")) { + if (genguid(argc - 1, argv + 1)) + exit(EXIT_FAILURE); + exit(EXIT_SUCCESS); + } + guid = NULL; index = 0; instance = 0; mcount = 0; @@ -933,9 +1079,9 @@ int main(int argc, char **argv) case 'V': printf("mkeficapsule version %s\n", PLAIN_VERSION); exit(EXIT_SUCCESS); default: - print_usage(); + print_usage_mkeficapsule(); exit(EXIT_FAILURE); } }
@@ -956,9 +1102,9 @@ int main(int argc, char **argv) (capsule_type != CAPSULE_NORMAL_BLOB && ((argc != optind + 1) || ((capsule_type == CAPSULE_ACCEPT) && !guid) || ((capsule_type == CAPSULE_REVERT) && guid)))) { - print_usage(); + print_usage_mkeficapsule(); exit(EXIT_FAILURE); }
if (capsule_type != CAPSULE_NORMAL_BLOB) {

Add some basic unit tests to validate that the UUID generation behaves as expected. This matches the implementation in efi_loader for sandbox and a Qualcomm board and should catch any regressions.
Acked-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- test/lib/uuid.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+)
diff --git a/test/lib/uuid.c b/test/lib/uuid.c index 3d62e18bcfee..4a1a16b4f315 100644 --- a/test/lib/uuid.c +++ b/test/lib/uuid.c @@ -7,15 +7,20 @@ * Authors: * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com */
+#include <charset.h> #include <u-boot/uuid.h> #include <test/lib.h> #include <test/test.h> #include <test/ut.h>
+#include <efi.h> + /* test UUID */ #define TEST_SVC_UUID "ed32d533-4209-99e6-2d72-cdd998a79cc0" +/* U-Boot default fw image namespace */ +#define DEFAULT_FW_IMAGE_NAMESPACE "8c9f137e-91dc-427b-b2d6-b420faebaf2a"
#define UUID_SIZE 16
/* The UUID binary data (little-endian format) */ @@ -36,4 +41,81 @@ static int lib_test_uuid_to_le(struct unit_test_state *uts)
return 0; } LIB_TEST(lib_test_uuid_to_le, 0); + +struct dynamic_uuid_test_data { + const char *compatible; + const u16 *images[4]; + const char *expected_uuids[4]; +}; + +static int lib_test_dynamic_uuid_case(struct unit_test_state *uts, + const struct dynamic_uuid_test_data *data) +{ + struct uuid namespace; + int j; + + ut_assertok(uuid_str_to_bin(DEFAULT_FW_IMAGE_NAMESPACE, (unsigned char *)&namespace, + UUID_STR_FORMAT_GUID)); + + for (j = 0; data->images[j]; j++) { + const char *expected_uuid = data->expected_uuids[j]; + const u16 *image = data->images[j]; + efi_guid_t uuid; + char uuid_str[37]; + + gen_v5_guid(&namespace, &uuid, + data->compatible, strlen(data->compatible), + image, u16_strlen(image) * sizeof(uint16_t), + NULL); + uuid_bin_to_str((unsigned char *)&uuid, uuid_str, UUID_STR_FORMAT_GUID); + + ut_asserteq_str(expected_uuid, uuid_str); + } + + return 0; +} + +static int lib_test_dynamic_uuid(struct unit_test_state *uts) +{ + int ret, i; + const struct dynamic_uuid_test_data test_data[] = { + { + .compatible = "sandbox", + .images = { + u"SANDBOX-UBOOT", + u"SANDBOX-UBOOT-ENV", + u"SANDBOX-FIT", + NULL, + }, + .expected_uuids = { + "985f2937-7c2e-5e9a-8a5e-8e063312964b", + "9e339473-c2eb-530a-a69b-0cd6bbbed40e", + "46610520-469e-59dc-a8dd-c11832b877ea", + NULL, + } + }, + { + .compatible = "qcom,qrb4210-rb2", + .images = { + u"QUALCOMM-UBOOT", + NULL, + }, + .expected_uuids = { + "d5021fac-8dd0-5ed7-90c2-763c304aaf86", + NULL, + } + }, + }; + + for (i = 0; i < ARRAY_SIZE(test_data); i++) { + ret = lib_test_dynamic_uuid_case(uts, &test_data[i]); + if (ret) + return ret; + } + + return 0; +} + +LIB_TEST(lib_test_dynamic_uuid, 0); +

Add a test to check the version/variant bits of v4 and v5 UUIDs.
Acked-by: Ilias Apalodimas ilias.apalodimas@linaro.org Signed-off-by: Caleb Connolly caleb.connolly@linaro.org --- test/lib/uuid.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/test/lib/uuid.c b/test/lib/uuid.c index 4a1a16b4f315..bf5d5afdb521 100644 --- a/test/lib/uuid.c +++ b/test/lib/uuid.c @@ -42,8 +42,49 @@ static int lib_test_uuid_to_le(struct unit_test_state *uts) return 0; } LIB_TEST(lib_test_uuid_to_le, 0);
+#if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID) +/* Test UUID attribute bits (version, variant) */ +static int lib_test_uuid_bits(struct unit_test_state *uts) +{ + unsigned char uuid[16]; + efi_guid_t guid; + int i; + + /* + * Reduce the chance of a randomly generated UUID disguising + * a regression by testing multiple times. + */ + for (i = 0; i < 5; i++) { + /* Test UUID v4 */ + gen_rand_uuid((unsigned char *)&uuid); + + printf("v4 UUID: %pUb\n", (efi_guid_t *)uuid); + + /* version 4 */ + ut_assert((uuid[6] & 0xf0) == 0x40); + /* variant 1 */ + ut_assert((uuid[8] & UUID_VARIANT_MASK) == (UUID_VARIANT << UUID_VARIANT_SHIFT)); + + /* Test v5, use the v4 UUID as the namespace */ + gen_v5_guid((struct uuid *)uuid, + &guid, "test", 4, NULL); + + printf("v5 GUID: %pUl\n", (efi_guid_t *)uuid); + + /* This is a GUID so bits 6 and 7 are swapped (little endian). Version 5 */ + ut_assert((guid.b[7] & 0xf0) == 0x50); + /* variant 1 */ + ut_assert((guid.b[8] & UUID_VARIANT_MASK) == (UUID_VARIANT << UUID_VARIANT_SHIFT)); + } + + return 0; +} + +LIB_TEST(lib_test_uuid_bits, 0); +#endif + struct dynamic_uuid_test_data { const char *compatible; const u16 *images[4]; const char *expected_uuids[4];
participants (2)
-
Caleb Connolly
-
Patrick DELAUNAY