Message ID | 20240719-b4-dynamic-uuid-v5-3-8a83de3fe3dc@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | efi: CapsuleUpdate: support for dynamic UUIDs | expand |
Hi Caleb, > +/** > + * efi_capsule_update_info_gen_ids - 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_capsule_update_info_gen_ids(void) I think efi_gen_capsule_guids() is a better name > +{ > + 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_UNSUPPORTED; EFI_INVALID_PARAMETER is a better return code for this and the check that follows > + } > + > + compatible = ofnode_read_string(ofnode_root(), "compatible"); > + if (!compatible) { > + log_debug("%s: model or compatible not defined\n", __func__); > + return EFI_UNSUPPORTED; > + } > + > + 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 > @@ -282,8 +331,11 @@ static efi_status_t efi_fill_image_desc_array( > return EFI_BUFFER_TOO_SMALL; > } > *image_info_size = total_size; > > + if (efi_capsule_update_info_gen_ids() != EFI_SUCCESS) > + return EFI_UNSUPPORTED; When you make the changes above do ret = efi_gen_capsule_guids() if (ret != EFI_SUCESS) 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); > > -- > 2.45.2 > Other than that, this patch looks ok Cheers /Ilias
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 2fb24d7af9a4..4735f877c709 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -235,8 +235,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..81d060b47a34 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_capsule_update_info_gen_ids - 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_capsule_update_info_gen_ids(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_UNSUPPORTED; + } + + compatible = ofnode_read_string(ofnode_root(), "compatible"); + if (!compatible) { + log_debug("%s: model or compatible not defined\n", __func__); + return EFI_UNSUPPORTED; + } + + 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 @@ -282,8 +331,11 @@ static efi_status_t efi_fill_image_desc_array( return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; + if (efi_capsule_update_info_gen_ids() != EFI_SUCCESS) + return EFI_UNSUPPORTED; + fw_array = update_info.images; *descriptor_count = update_info.num_images; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; *descriptor_size = sizeof(*image_info);
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. 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 | 52 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+)