[PATCH v2 03/10] boot: image: add FIT decrypt-to-buffer helper

Simon Glass sjg at chromium.org
Thu Jul 9 20:36:53 CEST 2026


Hi James,

On 2026-07-03T01:49:45, James Hilliard <james.hilliard1 at gmail.com> wrote:
> boot: image: add FIT decrypt-to-buffer helper
>
> FIT cipher support currently allocates the output buffer inside the AES
> helper. SPL often needs to decrypt directly into a caller-selected
> buffer, for example a load buffer or a scratch buffer used before
> decompression.
>
> Add a decrypt_to callback to the FIT cipher algorithm and wire it up for
> AES. The existing allocating decrypt path becomes a wrapper around the
> new helper.
>
> Validate the FIT cipher key length, IV length and unciphered-size
> property while preparing decryption, and build lib/aes/ by phase when
> FIT_CIPHER is enabled so the target-side decrypt helper is available to
> SPL builds.
>
> When DM_AES is enabled, try the first UCLASS_AES provider before using
> the software AES fallback in U-Boot proper. If a provider is present,
> ask the provider for the software-provided key slot before loading the
> FIT key, so hardware-specific reserved or preloaded slot policy stays in
> [...]
>
> boot/image-cipher.c              |  38 ++++++++++++--
>  boot/image-fit.c                 |  33 ++++++++++--
>  drivers/crypto/aes/aes-sw.c      |   6 +++
>  drivers/crypto/aes/aes-uclass.c  |  15 ++++++
>  drivers/crypto/tegra/tegra_aes.c |   7 +++
>  include/image.h                  |  39 ++++++++++++--
>  include/u-boot/aes.h             |  10 ++++
>  include/uboot_aes.h              |  38 ++++++++++++--
>  lib/Makefile                     |   2 +-
>  lib/aes/aes-decrypt.c            | 108 +++++++++++++++++++++++++++++++++------
>  10 files changed, 266 insertions(+), 30 deletions(-)

> diff --git a/lib/aes/aes-decrypt.c b/lib/aes/aes-decrypt.c
> @@ -4,37 +4,115 @@
> +int image_aes_decrypt_to(struct image_cipher_info *info,
> +                      const void *cipher, size_t cipher_len,
> +                      void *data, size_t *size)
> +{
> +#ifndef USE_HOSTCC
> +     unsigned int aes_blocks, key_len = info->cipher->key_len;
> +     int ret;

...
> +     return -ENOSYS;
> +#endif
> +
> +     return -ENOSYS;
> +}

Please flip this to '#ifdef USE_HOSTCC / return -ENOSYS; / #else ... /
#endif' with a single return. The double return either side of the
'#endif' is confusing since only one is ever reachable per build.

> diff --git a/lib/aes/aes-decrypt.c b/lib/aes/aes-decrypt.c
> @@ -4,37 +4,115 @@
> +             ret = uclass_first_device_err(UCLASS_AES, &dev);
> +             if (!ret) {
> +                     u8 slot;
> +
> +                     ret = dm_aes_get_software_key_slot(dev);
> +                     if (ret < 0)
> +                             return ret;
> +                     if (ret > 0xff)
> +                             return -ERANGE;
> +                     slot = ret;
> +
> +                     ret = dm_aes_set_key_for_key_slot(dev, key_len * 8,
> +                                                       (u8 *)info->key,
> +                                                       slot);

Since fit_image_uncipher() now hands in 'data == cipher' whenever the
payload sits in DRAM, every UCLASS_AES provider consumed here must
support in-place CBC decrypt with fully overlapping src and dst. The
software path in aes_cbc_decrypt_blocks() snapshots each block first,
so it copes, but the aes_ops contract does not spell this out. Please
document this on struct aes_ops (or on aes_cbc_decrypt()), otherwise
the sun8i-ce driver added later in the series becomes the de-facto
reference for an unwritten rule.

> diff --git a/lib/aes/aes-decrypt.c b/lib/aes/aes-decrypt.c
> @@ -4,37 +4,115 @@
> +     ret = image_aes_validate_lengths(info, cipher_len);
> +     if (ret)
> +             return ret;
> +
>       *data = malloc(cipher_len);
>       if (!*data) {
>               printf("Can't allocate memory to decrypt\n");
>               return -ENOMEM;
>       }
> -     *size = info->size_unciphered;
>
> -     memcpy(&key_exp[0], info->key, key_len);
> -
> -     /* First we expand the key. */
> -     aes_expand_key((u8 *)info->key, key_len, key_exp);
> -
> -     /* Calculate the number of AES blocks to encrypt. */
> -     aes_blocks = DIV_ROUND_UP(cipher_len, AES_BLOCK_LENGTH);
> +     ret = image_aes_decrypt_to(info, cipher, cipher_len, *data, size);

image_aes_decrypt() validates the lengths, then image_aes_decrypt_to()
validates them again. Please drop the outer call and let decrypt_to()
be the single point of validation, otherwise the two copies will
drift.

With those resolved:

Reviewed-by: Simon Glass <sjg at chromium.org>

Regards,
Simon


More information about the U-Boot mailing list