[PATCH v2 04/10] spl: fit: support encrypted payloads
Simon Glass
sjg at chromium.org
Thu Jul 9 20:37:22 CEST 2026
Hi James,
On 2026-07-03T01:49:45, James Hilliard <james.hilliard1 at gmail.com> wrote:
> spl: fit: support encrypted payloads
>
> Add SPL_FIT_CIPHER and decrypt FIT image data before post-processing,
> decompression or moving it to the final load address.
>
> SPL cannot always allocate a new output buffer while loading FIT images,
> so use the caller-provided decrypt-to-buffer helper. External encrypted
> images are read into scratch memory first, then decrypted in place before
> the existing copy or decompression path consumes them. Embedded encrypted
> images decrypt into the final load buffer, or into scratch memory when
> decompression is still required.
>
> Use IMAGE_ENABLE_DECRYPT in the common FIT image-load path so FIT cipher
> support is selected by phase. Keep that path disabled for host tools,
> since the target-side decrypt helper depends on the U-Boot control FDT
> and runtime crypto providers.
>
> Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
>
> boot/Kconfig | 8 +++++++
> boot/image-fit.c | 2 +-
> common/spl/spl_fit.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++------
> 3 files changed, 70 insertions(+), 8 deletions(-)
> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> @@ -256,6 +281,8 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
> if (spl_decompression_enabled()) {
> fit_image_get_comp(fit, node, &image_comp);
> debug("%s ", genimg_get_comp_name(image_comp));
> + needs_decomp = image_comp == IH_COMP_GZIP ||
> + image_comp == IH_COMP_LZMA;
> }
This also drives buffer selection for the encrypted path. If someone
later adds a new compression type here (say IH_COMP_LZ4) they will
have to remember to update this test too, otherwise decrypt lands in
the load buffer and decomp then overwrites it. Please extract a small
helper like spl_image_needs_decomp(image_comp) so both sites stay in
sync.
> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> @@ -267,6 +294,10 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
> load_addr = image_info->load_addr;
> }
>
> + if (CONFIG_IS_ENABLED(FIT_CIPHER))
> + cipher_node = fdt_subnode_offset(fit, node, FIT_CIPHER_NODENAME);
> + encrypted = cipher_node >= 0;
If SPL_FIT_CIPHER is not enabled but the FIT actually carries a cipher
subnode, this silently treats the ciphertext as plaintext and hands it
to the copy/decompress path - the hash check passes (FIT hashes are
over the ciphertext) and SPL then hands garbage to U-Boot proper.
Should we have a message in that case, or can we assume that
SPL_FIT_CIPHER must be enabled whenever we encounter a FIT that might
have ciphertext?
> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> @@ -331,10 +363,32 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
> + load_ptr = map_sysmem(load_addr, length);
> + if (encrypted) {
> + void *decrypt_ptr;
> +
> + if (needs_decomp) {
> + if (external_data)
> + decrypt_ptr = src;
> + else
> + decrypt_ptr = map_sysmem(ALIGN(CONFIG_SYS_LOAD_ADDR,
> + ARCH_DMA_MINALIGN),
> + length);
> + } else if (external_data) {
> + decrypt_ptr = src;
> + } else {
> + decrypt_ptr = load_ptr;
> + }
For external_data the answer is always 'decrypt_ptr = src' regardless
of needs_decomp, so this can flatten to:
if (external_data)
decrypt_ptr = src;
else if (needs_decomp)
decrypt_ptr = map_sysmem(ALIGN(CONFIG_SYS_LOAD_ADDR,
ARCH_DMA_MINALIGN), length);
else
decrypt_ptr = load_ptr;
That also makes the intent easier to match against the "read into
scratch, decrypt in place" wording in the commit message.
> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> @@ -352,7 +406,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
> return -EIO;
> }
> length = loadEnd - CONFIG_SYS_LOAD_ADDR;
> - } else {
> + } else if (src != load_ptr) {
> memmove(load_ptr, src, length);
> }
Please add a one-line comment noting that 'src == load_ptr' only
happens when we decrypted straight into the load buffer, so the next
reader doesn't start 'fixing' the else-branch.
Regards,
Simon
More information about the U-Boot
mailing list