]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
efi: add a helper to generate dynamic UUIDs
authorCaleb Connolly <caleb.connolly@linaro.org>
Fri, 30 Aug 2024 12:34:33 +0000 (13:34 +0100)
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Thu, 12 Sep 2024 15:35:37 +0000 (17:35 +0200)
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
lib/efi_loader/efi_capsule.c
lib/efi_loader/efi_firmware.c

index ab961a8e150512c92aeff7926aeb222898736c7e..e58b882560537ec43b8f6df37d9906c69afbd59c 100644 (file)
@@ -272,6 +272,18 @@ config EFI_CAPSULE_ON_DISK_EARLY
          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
 
index 635088f25a13a28284d8daa45fb0b0f48634f448..f3a2388506cc75a81b21bd5510edfa2febb7f220 100644 (file)
@@ -20,6 +20,7 @@
 #include <sort.h>
 #include <sysreset.h>
 #include <asm/global_data.h>
+#include <uuid.h>
 
 #include <crypto/pkcs7.h>
 #include <crypto/pkcs7_parser.h>
index ba5aba098c0fcac04b5ecb46c76627953c4b6381..6650c2b8071def7bab88beacae84ee046b8795d0 100644 (file)
@@ -245,6 +245,55 @@ 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
@@ -272,7 +321,7 @@ static efi_status_t efi_fill_image_desc_array(
 {
        size_t total_size;
        struct efi_fw_image *fw_array;
-       int i;
+       int i, ret;
 
        total_size = sizeof(*image_info) * update_info.num_images;
 
@@ -283,6 +332,10 @@ static efi_status_t efi_fill_image_desc_array(
        }
        *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;