mbox series

[v2,0/7] efi: CapsuleUpdate: support for dynamic UUIDs

Message ID 20240529-b4-dynamic-uuid-v2-0-c26f31057bbe@linaro.org
Headers show
Series efi: CapsuleUpdate: support for dynamic UUIDs | expand

Message

Caleb Connolly May 29, 2024, 2:48 p.m. UTC
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
(like the model/revision), 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 integrate dynamic UUID support as follows:

1. Adjust Kconfig to depend on EFI_CAPSULE_DYNAMIC_UUIDS if
   EFI_HAVE_CAPSULE_SUPPORT.
2. Skip setting the fw_images image_type_id property.
3. Generate a UUID and set CONFIG_EFI_CAPSULE_NAMESPACE_UUID in your
   defconfig.

== 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 ==

This series introduces a new tool: genguid. This can be used to generate
the same GUIDs that the board would at runtime.

This series follows a related discussion started by Ilias:
https://lore.kernel.org/u-boot/CAC_iWjJNHa4gMF897MqYZNdbgjFG8K4kwGsTXWuy72WkYLizrw@mail.gmail.com/

To: Tom Rini <trini@konsulko.com>
To: Heinrich Schuchardt <xypron.glpk@gmx.de>
To: Ilias Apalodimas <ilias.apalodimas@linaro.org>
To: Simon Glass <sjg@chromium.org>
To: Mario Six <mario.six@gdsys.cc>
To: Alper Nebi Yasak <alpernebiyasak@gmail.com>
To: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Cc: Richard Hughes <hughsient@gmail.com>
Cc: u-boot@lists.denx.de

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.org

---
Caleb Connolly (7):
      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
      tools: add genguid tool
      test: lib/uuid: add unit tests for dynamic UUIDs

 arch/Kconfig                                       |   1 +
 board/sandbox/sandbox.c                            |  16 ---
 configs/sandbox_defconfig                          |   1 +
 configs/sandbox_flattree_defconfig                 |   1 +
 doc/develop/uefi/uefi.rst                          |  31 +++++
 include/sandbox_efi_capsule.h                      |   6 +-
 include/uuid.h                                     |  21 ++-
 lib/Kconfig                                        |   8 ++
 lib/efi_loader/Kconfig                             |  23 +++
 lib/efi_loader/efi_capsule.c                       |   1 +
 lib/efi_loader/efi_firmware.c                      |  66 +++++++++
 lib/uuid.c                                         |  81 +++++++++--
 test/lib/uuid.c                                    |  90 ++++++++++++
 .../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.dts         |   6 +-
 tools/Makefile                                     |   3 +
 tools/binman/etype/efi_capsule.py                  |   2 +-
 tools/binman/ftest.py                              |   2 +-
 tools/genguid.c                                    | 154 +++++++++++++++++++++
 22 files changed, 481 insertions(+), 48 deletions(-)
---
change-id: 20240422-b4-dynamic-uuid-1a5ab1486c27
base-commit: 2e682a4a406fc81ef32e05c28542cc8067f1e15f

// Caleb (they/them)

Comments

Simon Glass May 29, 2024, 4:30 p.m. UTC | #1
Hi Caleb,

On Wed, 29 May 2024 at 08:49, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> 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
> (like the model/revision), 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 integrate dynamic UUID support as follows:
>
> 1. Adjust Kconfig to depend on EFI_CAPSULE_DYNAMIC_UUIDS if
>    EFI_HAVE_CAPSULE_SUPPORT.
> 2. Skip setting the fw_images image_type_id property.
> 3. Generate a UUID and set CONFIG_EFI_CAPSULE_NAMESPACE_UUID in your
>    defconfig.
>
> == 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 ==
>
> This series introduces a new tool: genguid. This can be used to generate
> the same GUIDs that the board would at runtime.
>
> This series follows a related discussion started by Ilias:
> https://lore.kernel.org/u-boot/CAC_iWjJNHa4gMF897MqYZNdbgjFG8K4kwGsTXWuy72WkYLizrw@mail.gmail.com/
>
> To: Tom Rini <trini@konsulko.com>
> To: Heinrich Schuchardt <xypron.glpk@gmx.de>
> To: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> To: Simon Glass <sjg@chromium.org>
> To: Mario Six <mario.six@gdsys.cc>
> To: Alper Nebi Yasak <alpernebiyasak@gmail.com>
> To: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
> Cc: Richard Hughes <hughsient@gmail.com>
> Cc: u-boot@lists.denx.de
>
> 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.org
>
> ---
> Caleb Connolly (7):
>       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
>       tools: add genguid tool
>       test: lib/uuid: add unit tests for dynamic UUIDs
>
>  arch/Kconfig                                       |   1 +
>  board/sandbox/sandbox.c                            |  16 ---
>  configs/sandbox_defconfig                          |   1 +
>  configs/sandbox_flattree_defconfig                 |   1 +
>  doc/develop/uefi/uefi.rst                          |  31 +++++
>  include/sandbox_efi_capsule.h                      |   6 +-
>  include/uuid.h                                     |  21 ++-
>  lib/Kconfig                                        |   8 ++
>  lib/efi_loader/Kconfig                             |  23 +++
>  lib/efi_loader/efi_capsule.c                       |   1 +
>  lib/efi_loader/efi_firmware.c                      |  66 +++++++++
>  lib/uuid.c                                         |  81 +++++++++--
>  test/lib/uuid.c                                    |  90 ++++++++++++
>  .../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.dts         |   6 +-
>  tools/Makefile                                     |   3 +
>  tools/binman/etype/efi_capsule.py                  |   2 +-
>  tools/binman/ftest.py                              |   2 +-
>  tools/genguid.c                                    | 154 +++++++++++++++++++++
>  22 files changed, 481 insertions(+), 48 deletions(-)
> ---
> change-id: 20240422-b4-dynamic-uuid-1a5ab1486c27
> base-commit: 2e682a4a406fc81ef32e05c28542cc8067f1e15f
>

How about using the compatible string, instead of a GUID? Is that possible?

Regards,
Simon
Caleb Connolly May 29, 2024, 7:03 p.m. UTC | #2
> 
> How about using the compatible string, instead of a GUID? Is that possible?

Could you elaborate?
> 
> Regards,
> Simon
Simon Glass May 29, 2024, 7:49 p.m. UTC | #3
Hi Caleb,

On Wed, 29 May 2024 at 13:04, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
>
> >
> > How about using the compatible string, instead of a GUID? Is that possible?
>
> Could you elaborate?

Well, the compatible string (in the root node) is how we normally
decide which DT to use and which machine we are targeting. So I am
wondering if we can somehow use that, rather than producing a GUID
from it?

Regards,
Simon
Caleb Connolly May 29, 2024, 9:55 p.m. UTC | #4
On 29/05/2024 21:49, Simon Glass wrote:
> Hi Caleb,
> 
> On Wed, 29 May 2024 at 13:04, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>>
>>
>>>
>>> How about using the compatible string, instead of a GUID? Is that possible?
>>
>> Could you elaborate?
> 
> Well, the compatible string (in the root node) is how we normally
> decide which DT to use and which machine we are targeting. So I am
> wondering if we can somehow use that, rather than producing a GUID
> from it?

No, we can't. The GUIDs are required as part of the EFI FMP spec. We 
currently hardcode these GUIDs per-board (meaning if a vendor productize 
some board they need to make source modifications to replace the GUIDs). 
This series generates those GUIDs deterministically at runtime so we 
don't need to maintain a big list.
> 
> Regards,
> Simon
Simon Glass May 30, 2024, 12:24 p.m. UTC | #5
Hi Caleb,

On Wed, 29 May 2024 at 15:55, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
>
>
> On 29/05/2024 21:49, Simon Glass wrote:
> > Hi Caleb,
> >
> > On Wed, 29 May 2024 at 13:04, Caleb Connolly <caleb.connolly@linaro.org> wrote:
> >>
> >>
> >>>
> >>> How about using the compatible string, instead of a GUID? Is that possible?
> >>
> >> Could you elaborate?
> >
> > Well, the compatible string (in the root node) is how we normally
> > decide which DT to use and which machine we are targeting. So I am
> > wondering if we can somehow use that, rather than producing a GUID
> > from it?
>
> No, we can't. The GUIDs are required as part of the EFI FMP spec. We
> currently hardcode these GUIDs per-board (meaning if a vendor productize
> some board they need to make source modifications to replace the GUIDs).
> This series generates those GUIDs deterministically at runtime so we
> don't need to maintain a big list.

OK thanks for the info.

Regards,
Simon