public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header
@ 2026-04-02 19:24 yan wang
  2026-04-02 19:24 ` [PATCH v2 2/3] binman: Generate preload header and sign data only once yan wang
                   ` (3 more replies)
  0 siblings, 4 replies; 38+ messages in thread
From: yan wang @ 2026-04-02 19:24 UTC (permalink / raw)
  To: trini+nodisclaimer, sjg+nodisclaimer, alpernebiyasak+nodisclaimer
  Cc: philippe.reynes+nodisclaimer, paul.henrys_ext+nodisclaimer,
	u-boot+nodisclaimer, Paul HENRYS

From: Paul HENRYS <paul.henrys_ext@softathome.com>

Add a test to verify the preload header correctly signs an encrypted
FIT. This test exercises the case where encryption uses random IVs that
would change between mkimage calls.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---
Changes for v2:
- Rename test file as 351_pre_load_fit_encrypted.dts
- Update the commit message according to the remarks made

 tools/binman/ftest.py                         | 17 +++++
 .../test/351_pre_load_fit_encrypted.dts       | 63 +++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 tools/binman/test/351_pre_load_fit_encrypted.dts

diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index a53e37f31b3..dcfe97f0444 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5894,6 +5894,23 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
             data = self._DoReadFileDtb('236_pre_load_invalid_key.dts',
                                        entry_args=entry_args)
 
+    def testPreLoadEncryptedFit(self):
+        """Test an encrypted FIT image with a pre-load header"""
+        entry_args = {
+            'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+        }
+        data = self._DoReadFileDtb(
+            '351_pre_load_fit_encrypted.dts', entry_args=entry_args,
+            extra_indirs=[os.path.join(self._binman_dir, 'test')])[0]
+
+        image_fname = tools.get_output_filename('image.bin')
+        is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
+
+        self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
+        self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
+        self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
+        self.assertEqual(is_signed, True)
+
     def _CheckSafeUniqueNames(self, *images):
         """Check all entries of given images for unsafe unique names"""
         for image in images:
diff --git a/tools/binman/test/351_pre_load_fit_encrypted.dts b/tools/binman/test/351_pre_load_fit_encrypted.dts
new file mode 100644
index 00000000000..f5e9bf9426c
--- /dev/null
+++ b/tools/binman/test/351_pre_load_fit_encrypted.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		pre-load {
+			content = <&image>;
+			algo-name = "sha256,rsa2048";
+			key-name = "dev.key";
+			header-size = <4096>;
+			version = <0x11223344>;
+		};
+
+		image: fit {
+			fit,encrypt;
+			description = "Test a FIT with encrypted data and signed with a preload";
+			#address-cells = <1>;
+
+			images {
+				u-boot {
+					description = "U-Boot";
+					type = "firmware";
+					arch = "arm64";
+					os = "U-Boot";
+					compression = "none";
+					load = <00000000>;
+					entry = <00000000>;
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-nodtb {
+					};
+				};
+				fdt-1 {
+					description = "Flattened Device Tree blob";
+					type = "flat_dt";
+					arch = "arm64";
+					compression = "none";
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-dtb {
+					};
+				};
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "Boot U-Boot with FDT blob";
+					firmware = "u-boot";
+					fdt = "fdt-1";
+				};
+			};
+		};
+	};
+};
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 2/3] binman: Generate preload header and sign data only once
  2026-04-02 19:24 [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header yan wang
@ 2026-04-02 19:24 ` yan wang
  2026-04-03  1:02   ` Simon Glass
  2026-04-02 19:24 ` [PATCH v2 3/3] binman: collection: Set build_done on referenced entries yan wang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 38+ messages in thread
From: yan wang @ 2026-04-02 19:24 UTC (permalink / raw)
  To: trini+nodisclaimer, sjg+nodisclaimer, alpernebiyasak+nodisclaimer
  Cc: philippe.reynes+nodisclaimer, paul.henrys_ext+nodisclaimer,
	u-boot+nodisclaimer, Paul HENRYS

From: Paul HENRYS <paul.henrys_ext@softathome.com>

To optimize preload generation, generate the header and signatures only
after all data has been collected. This avoids signing the data multiple
times.

Since header_size is known upfront (from __init__), set the preload
header size in `ObtainContents()` to avoid an extra packing pass when
ProcessContentsUpdate() detects the size changed from 0 to header_size.

This reduces unnecessary repacking and signing operations.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---
Changes for v2:
- Set contents_size knowing header_size in ObtainContents()

 tools/binman/etype/pre_load.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
index 00f1a896767..34a7bc1b985 100644
--- a/tools/binman/etype/pre_load.py
+++ b/tools/binman/etype/pre_load.py
@@ -152,14 +152,14 @@ class Entry_pre_load(Entry_collection):
         return data + pad
 
     def ObtainContents(self):
-        """Obtain a placeholder for the header contents"""
-        # wait that the image is available
-        self.image = self.GetContents(False)
-        if self.image is None:
-            return False
-        self.SetContents(self._CreateHeader())
+        """Only set the known size of the preload header. The data will be
+        generated later on in ProcessContents() when the data from every entries
+        can be retrieved.
+        """
+        self.contents_size = self.header_size
         return True
 
     def ProcessContents(self):
+        self.image = self.GetContents(True)
         data = self._CreateHeader()
         return self.ProcessContentsUpdate(data)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 3/3] binman: collection: Set build_done on referenced entries
  2026-04-02 19:24 [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header yan wang
  2026-04-02 19:24 ` [PATCH v2 2/3] binman: Generate preload header and sign data only once yan wang
@ 2026-04-02 19:24 ` yan wang
  2026-04-03  1:02   ` Simon Glass
  2026-04-02 19:35 ` [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header Tom Rini
  2026-04-03  7:32 ` [PATCH v3 " Paul HENRYS
  3 siblings, 1 reply; 38+ messages in thread
From: yan wang @ 2026-04-02 19:24 UTC (permalink / raw)
  To: trini+nodisclaimer, sjg+nodisclaimer, alpernebiyasak+nodisclaimer
  Cc: philippe.reynes+nodisclaimer, paul.henrys_ext+nodisclaimer,
	u-boot+nodisclaimer, yan wang

The collection etype uses phandles in the 'content' property to
reference other entries. Mark each referenced entry with build_done
to avoid rebuilding the same entry data multiple times.

This is important for cases where rebuilding may change the data
content, e.g. due to timestamps or random IVs in encryption.

Refactor GetContentsByPhandle() to return both the entry object and
its data.

Signed-off-by: yan wang <yan.wang@softathome.com>
---
Changes for v2:
- Refactor GetContentsByPhandle() to return both the entry object and
  its data

 tools/binman/etype/collection.py | 8 ++++++--
 tools/binman/etype/section.py    | 5 +++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
index c532aafe3e7..5ea6344bd25 100644
--- a/tools/binman/etype/collection.py
+++ b/tools/binman/etype/collection.py
@@ -45,12 +45,16 @@ class Entry_collection(Entry):
         self.Info('Getting contents, required=%s' % required)
         data = bytearray()
         for entry_phandle in self.content:
-            entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
-                                                           required)
+            entry, entry_data = self.section.GetContentsByPhandle(
+                entry_phandle, self, required)
             if not required and entry_data is None:
                 self.Info('Contents not available yet')
                 # Data not available yet
                 return None
+
+            # Mark referenced entries as build_done to avoid rebuilding
+            entry.build_done = True
+
             data += entry_data
 
         self.Info('Returning contents size %x' % len(data))
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 6a26d687056..8530b7ee17f 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -557,7 +557,8 @@ class Entry_section(Entry):
                 return None
 
         Returns:
-            data from associated entry (as a string), or None if not found
+            tuple: (entry, data) where entry is the Entry object and data is
+                from that entry (as a string), or (entry, None) if data not found
         """
         node = self._node.GetFdt().LookupPhandle(phandle)
         if not node:
@@ -565,7 +566,7 @@ class Entry_section(Entry):
         entry = self.FindEntryByNode(node)
         if not entry:
             source_entry.Raise("Cannot find entry for node '%s'" % node.name)
-        return entry.GetData(required)
+        return entry, entry.GetData(required)
 
     def LookupEntry(self, entries, sym_name, msg):
         """Look up the entry for a binman symbol
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-02 19:24 [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header yan wang
  2026-04-02 19:24 ` [PATCH v2 2/3] binman: Generate preload header and sign data only once yan wang
  2026-04-02 19:24 ` [PATCH v2 3/3] binman: collection: Set build_done on referenced entries yan wang
@ 2026-04-02 19:35 ` Tom Rini
  2026-04-03  7:32 ` [PATCH v3 " Paul HENRYS
  3 siblings, 0 replies; 38+ messages in thread
From: Tom Rini @ 2026-04-02 19:35 UTC (permalink / raw)
  To: yan wang
  Cc: trini+nodisclaimer, sjg+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, paul.henrys_ext+nodisclaimer,
	u-boot+nodisclaimer, Paul HENRYS

[-- Attachment #1: Type: text/plain, Size: 969 bytes --]

On Thu, Apr 02, 2026 at 09:24:29PM +0200, yan wang wrote:

> From: Paul HENRYS <paul.henrys_ext@softathome.com>
> 
> Add a test to verify the preload header correctly signs an encrypted
> FIT. This test exercises the case where encryption uses random IVs that
> would change between mkimage calls.
> 
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
> ---
> Changes for v2:
> - Rename test file as 351_pre_load_fit_encrypted.dts
> - Update the commit message according to the remarks made
> 
>  tools/binman/ftest.py                         | 17 +++++
>  .../test/351_pre_load_fit_encrypted.dts       | 63 +++++++++++++++++++
>  2 files changed, 80 insertions(+)
>  create mode 100644 tools/binman/test/351_pre_load_fit_encrypted.dts

This should be against next, and we stopped using a numeric prefix on
test files and instead put them in to appropriate directories there (so
tools/binman/test/fit in this case), thanks.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 2/3] binman: Generate preload header and sign data only once
  2026-04-02 19:24 ` [PATCH v2 2/3] binman: Generate preload header and sign data only once yan wang
@ 2026-04-03  1:02   ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-03  1:02 UTC (permalink / raw)
  To: yan.wang
  Cc: trini+nodisclaimer, sjg+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, paul.henrys_ext+nodisclaimer,
	u-boot+nodisclaimer, Paul HENRYS, u-boot

On 2026-04-02T19:24:29, yan wang <yan.wang@softathome.com> wrote:
> binman: Generate preload header and sign data only once
>
> To optimize preload generation, generate the header and signatures only
> after all data has been collected. This avoids signing the data multiple
> times.
>
> Since header_size is known upfront (from __init__), set the preload
> header size in ObtainContents() to avoid an extra packing pass when
> ProcessContentsUpdate() detects the size changed from 0 to header_size.
>
> This reduces unnecessary repacking and signing operations.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
>
> tools/binman/etype/pre_load.py | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 3/3] binman: collection: Set build_done on referenced entries
  2026-04-02 19:24 ` [PATCH v2 3/3] binman: collection: Set build_done on referenced entries yan wang
@ 2026-04-03  1:02   ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-03  1:02 UTC (permalink / raw)
  To: yan.wang
  Cc: trini+nodisclaimer, sjg+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, paul.henrys_ext+nodisclaimer,
	u-boot+nodisclaimer, u-boot

On 2026-04-02T19:24:29, yan wang <yan.wang@softathome.com> wrote:
> binman: collection: Set build_done on referenced entries
>
> The collection etype uses phandles in the 'content' property to
> reference other entries. Mark each referenced entry with build_done
> to avoid rebuilding the same entry data multiple times.
>
> This is important for cases where rebuilding may change the data
> content, e.g. due to timestamps or random IVs in encryption.
>
> Refactor GetContentsByPhandle() to return both the entry object and
> its data.
>
> Signed-off-by: yan wang <yan.wang@softathome.com>
>
> tools/binman/etype/collection.py | 8 ++++++--
>  tools/binman/etype/section.py    | 5 +++--
>  2 files changed, 9 insertions(+), 4 deletions(-)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v3 1/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-02 19:24 [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header yan wang
                   ` (2 preceding siblings ...)
  2026-04-02 19:35 ` [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header Tom Rini
@ 2026-04-03  7:32 ` Paul HENRYS
  2026-04-03  7:32   ` [PATCH v3 2/3] binman: Generate preload header and sign data only once Paul HENRYS
                     ` (3 more replies)
  3 siblings, 4 replies; 38+ messages in thread
From: Paul HENRYS @ 2026-04-03  7:32 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, Paul HENRYS

Add a test to verify the preload header correctly signs an encrypted
FIT. This test exercises the case where encryption uses random IVs that
would change between mkimage calls.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---
Changes for v3:
- Rebase against 'next' branch
- Move test in tools/binman/test/fit without a numeric prefix
- Update encryption key path passed to _DoReadFileDtb()

 tools/binman/ftest.py                         | 21 +++++++
 .../test/fit/pre_load_fit_encrypted.dts       | 63 +++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 tools/binman/test/fit/pre_load_fit_encrypted.dts

diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ca5149ee654..301c7705837 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5895,6 +5895,27 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
             data = self._DoReadFileDtb('security/pre_load_invalid_key.dts',
                                        entry_args=entry_args)
 
+    def testPreLoadEncryptedFit(self):
+        """Test an encrypted FIT image with a pre-load header"""
+        entry_args = {
+            'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+        }
+        data = tools.read_file(self.TestFile("fit/aes256.bin"))
+        self._MakeInputFile("keys/aes256.bin", data)
+
+        keys_subdir = os.path.join(self._indir, "keys")
+        data = self._DoReadFileDtb(
+            'fit/pre_load_fit_encrypted.dts', entry_args=entry_args,
+            extra_indirs=[keys_subdir])[0]
+
+        image_fname = tools.get_output_filename('image.bin')
+        is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
+
+        self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
+        self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
+        self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
+        self.assertEqual(is_signed, True)
+
     def _CheckSafeUniqueNames(self, *images):
         """Check all entries of given images for unsafe unique names"""
         for image in images:
diff --git a/tools/binman/test/fit/pre_load_fit_encrypted.dts b/tools/binman/test/fit/pre_load_fit_encrypted.dts
new file mode 100644
index 00000000000..f5e9bf9426c
--- /dev/null
+++ b/tools/binman/test/fit/pre_load_fit_encrypted.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		pre-load {
+			content = <&image>;
+			algo-name = "sha256,rsa2048";
+			key-name = "dev.key";
+			header-size = <4096>;
+			version = <0x11223344>;
+		};
+
+		image: fit {
+			fit,encrypt;
+			description = "Test a FIT with encrypted data and signed with a preload";
+			#address-cells = <1>;
+
+			images {
+				u-boot {
+					description = "U-Boot";
+					type = "firmware";
+					arch = "arm64";
+					os = "U-Boot";
+					compression = "none";
+					load = <00000000>;
+					entry = <00000000>;
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-nodtb {
+					};
+				};
+				fdt-1 {
+					description = "Flattened Device Tree blob";
+					type = "flat_dt";
+					arch = "arm64";
+					compression = "none";
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-dtb {
+					};
+				};
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "Boot U-Boot with FDT blob";
+					firmware = "u-boot";
+					fdt = "fdt-1";
+				};
+			};
+		};
+	};
+};
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 2/3] binman: Generate preload header and sign data only once
  2026-04-03  7:32 ` [PATCH v3 " Paul HENRYS
@ 2026-04-03  7:32   ` Paul HENRYS
  2026-04-03  7:32   ` [PATCH v3 3/3] binman: collection: Set build_done on referenced entries Paul HENRYS
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 38+ messages in thread
From: Paul HENRYS @ 2026-04-03  7:32 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, Paul HENRYS

To optimize preload generation, generate the header and signatures only
after all data has been collected. This avoids signing the data multiple
times.

Since header_size is known upfront (from __init__), set the preload
header size in `ObtainContents()` to avoid an extra packing pass when
ProcessContentsUpdate() detects the size changed from 0 to header_size.

This reduces unnecessary repacking and signing operations.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---
Changes for v3:
- Rebase against 'next' branch

 tools/binman/etype/pre_load.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
index 00f1a896767..34a7bc1b985 100644
--- a/tools/binman/etype/pre_load.py
+++ b/tools/binman/etype/pre_load.py
@@ -152,14 +152,14 @@ class Entry_pre_load(Entry_collection):
         return data + pad
 
     def ObtainContents(self):
-        """Obtain a placeholder for the header contents"""
-        # wait that the image is available
-        self.image = self.GetContents(False)
-        if self.image is None:
-            return False
-        self.SetContents(self._CreateHeader())
+        """Only set the known size of the preload header. The data will be
+        generated later on in ProcessContents() when the data from every entries
+        can be retrieved.
+        """
+        self.contents_size = self.header_size
         return True
 
     def ProcessContents(self):
+        self.image = self.GetContents(True)
         data = self._CreateHeader()
         return self.ProcessContentsUpdate(data)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v3 3/3] binman: collection: Set build_done on referenced entries
  2026-04-03  7:32 ` [PATCH v3 " Paul HENRYS
  2026-04-03  7:32   ` [PATCH v3 2/3] binman: Generate preload header and sign data only once Paul HENRYS
@ 2026-04-03  7:32   ` Paul HENRYS
  2026-04-03  7:41   ` [PATCH v3 1/3] tools: binman: Test signing an encrypted FIT with a preload header Paul HENRYS
  2026-04-03  7:55   ` [PATCH v4 " Paul HENRYS
  3 siblings, 0 replies; 38+ messages in thread
From: Paul HENRYS @ 2026-04-03  7:32 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, yan wang

From: yan wang <yan.wang@softathome.com>

The collection etype uses phandles in the 'content' property to
reference other entries. Mark each referenced entry with build_done
to avoid rebuilding the same entry data multiple times.

This is important for cases where rebuilding may change the data
content, e.g. due to timestamps or random IVs in encryption.

Refactor GetContentsByPhandle() to return both the entry object and
its data.

Signed-off-by: yan wang <yan.wang@softathome.com>
---
Changes for v3:
- Rebase against 'next' branch

 tools/binman/etype/collection.py | 8 ++++++--
 tools/binman/etype/section.py    | 5 +++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
index c532aafe3e7..5ea6344bd25 100644
--- a/tools/binman/etype/collection.py
+++ b/tools/binman/etype/collection.py
@@ -45,12 +45,16 @@ class Entry_collection(Entry):
         self.Info('Getting contents, required=%s' % required)
         data = bytearray()
         for entry_phandle in self.content:
-            entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
-                                                           required)
+            entry, entry_data = self.section.GetContentsByPhandle(
+                entry_phandle, self, required)
             if not required and entry_data is None:
                 self.Info('Contents not available yet')
                 # Data not available yet
                 return None
+
+            # Mark referenced entries as build_done to avoid rebuilding
+            entry.build_done = True
+
             data += entry_data
 
         self.Info('Returning contents size %x' % len(data))
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 6a26d687056..8530b7ee17f 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -557,7 +557,8 @@ class Entry_section(Entry):
                 return None
 
         Returns:
-            data from associated entry (as a string), or None if not found
+            tuple: (entry, data) where entry is the Entry object and data is
+                from that entry (as a string), or (entry, None) if data not found
         """
         node = self._node.GetFdt().LookupPhandle(phandle)
         if not node:
@@ -565,7 +566,7 @@ class Entry_section(Entry):
         entry = self.FindEntryByNode(node)
         if not entry:
             source_entry.Raise("Cannot find entry for node '%s'" % node.name)
-        return entry.GetData(required)
+        return entry, entry.GetData(required)
 
     def LookupEntry(self, entries, sym_name, msg):
         """Look up the entry for a binman symbol
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 1/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-03  7:32 ` [PATCH v3 " Paul HENRYS
  2026-04-03  7:32   ` [PATCH v3 2/3] binman: Generate preload header and sign data only once Paul HENRYS
  2026-04-03  7:32   ` [PATCH v3 3/3] binman: collection: Set build_done on referenced entries Paul HENRYS
@ 2026-04-03  7:41   ` Paul HENRYS
  2026-04-03 14:53     ` Tom Rini
  2026-04-03  7:55   ` [PATCH v4 " Paul HENRYS
  3 siblings, 1 reply; 38+ messages in thread
From: Paul HENRYS @ 2026-04-03  7:41 UTC (permalink / raw)
  To: trini+nodisclaimer
  Cc: sjg+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, u-boot+nodisclaimer

Hi Tom,

Just after pushing the v3 I realized that this test would better go 
under tools/binman/test/security/ instead of tools/binman/test/fit/.
I am going to push a v4 with this change. Sorry for the inconvenience.

Kind regards,
Paul

On 03/04/2026 09:32, Paul HENRYS wrote:
> Add a test to verify the preload header correctly signs an encrypted
> FIT. This test exercises the case where encryption uses random IVs that
> would change between mkimage calls.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
> ---
> Changes for v3:
> - Rebase against 'next' branch
> - Move test in tools/binman/test/fit without a numeric prefix
> - Update encryption key path passed to _DoReadFileDtb()
>
>   tools/binman/ftest.py                         | 21 +++++++
>   .../test/fit/pre_load_fit_encrypted.dts       | 63 +++++++++++++++++++
>   2 files changed, 84 insertions(+)
>   create mode 100644 tools/binman/test/fit/pre_load_fit_encrypted.dts
>
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> index ca5149ee654..301c7705837 100644
> --- a/tools/binman/ftest.py
> +++ b/tools/binman/ftest.py
> @@ -5895,6 +5895,27 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
>               data = self._DoReadFileDtb('security/pre_load_invalid_key.dts',
>                                          entry_args=entry_args)
>   
> +    def testPreLoadEncryptedFit(self):
> +        """Test an encrypted FIT image with a pre-load header"""
> +        entry_args = {
> +            'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
> +        }
> +        data = tools.read_file(self.TestFile("fit/aes256.bin"))
> +        self._MakeInputFile("keys/aes256.bin", data)
> +
> +        keys_subdir = os.path.join(self._indir, "keys")
> +        data = self._DoReadFileDtb(
> +            'fit/pre_load_fit_encrypted.dts', entry_args=entry_args,
> +            extra_indirs=[keys_subdir])[0]
> +
> +        image_fname = tools.get_output_filename('image.bin')
> +        is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
> +
> +        self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
> +        self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
> +        self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
> +        self.assertEqual(is_signed, True)
> +
>       def _CheckSafeUniqueNames(self, *images):
>           """Check all entries of given images for unsafe unique names"""
>           for image in images:
> diff --git a/tools/binman/test/fit/pre_load_fit_encrypted.dts b/tools/binman/test/fit/pre_load_fit_encrypted.dts
> new file mode 100644
> index 00000000000..f5e9bf9426c
> --- /dev/null
> +++ b/tools/binman/test/fit/pre_load_fit_encrypted.dts
> @@ -0,0 +1,63 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	binman {
> +		pre-load {
> +			content = <&image>;
> +			algo-name = "sha256,rsa2048";
> +			key-name = "dev.key";
> +			header-size = <4096>;
> +			version = <0x11223344>;
> +		};
> +
> +		image: fit {
> +			fit,encrypt;
> +			description = "Test a FIT with encrypted data and signed with a preload";
> +			#address-cells = <1>;
> +
> +			images {
> +				u-boot {
> +					description = "U-Boot";
> +					type = "firmware";
> +					arch = "arm64";
> +					os = "U-Boot";
> +					compression = "none";
> +					load = <00000000>;
> +					entry = <00000000>;
> +					cipher {
> +						algo = "aes256";
> +						key-name-hint = "aes256";
> +					};
> +					u-boot-nodtb {
> +					};
> +				};
> +				fdt-1 {
> +					description = "Flattened Device Tree blob";
> +					type = "flat_dt";
> +					arch = "arm64";
> +					compression = "none";
> +					cipher {
> +						algo = "aes256";
> +						key-name-hint = "aes256";
> +					};
> +					u-boot-dtb {
> +					};
> +				};
> +			};
> +
> +			configurations {
> +				default = "conf-1";
> +				conf-1 {
> +					description = "Boot U-Boot with FDT blob";
> +					firmware = "u-boot";
> +					fdt = "fdt-1";
> +				};
> +			};
> +		};
> +	};
> +};

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v4 1/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-03  7:32 ` [PATCH v3 " Paul HENRYS
                     ` (2 preceding siblings ...)
  2026-04-03  7:41   ` [PATCH v3 1/3] tools: binman: Test signing an encrypted FIT with a preload header Paul HENRYS
@ 2026-04-03  7:55   ` Paul HENRYS
  2026-04-03  7:55     ` [PATCH v4 2/3] binman: Generate preload header and sign data only once Paul HENRYS
                       ` (2 more replies)
  3 siblings, 3 replies; 38+ messages in thread
From: Paul HENRYS @ 2026-04-03  7:55 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, Paul HENRYS

Add a test to verify the preload header correctly signs an encrypted
FIT. This test exercises the case where encryption uses random IVs that
would change between mkimage calls.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---
Changes for v4:
- Move test in tools/binman/test/security

 tools/binman/ftest.py                         | 21 +++++++
 .../test/security/pre_load_fit_encrypted.dts  | 63 +++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 tools/binman/test/security/pre_load_fit_encrypted.dts

diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ca5149ee654..da8325f820a 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5895,6 +5895,27 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
             data = self._DoReadFileDtb('security/pre_load_invalid_key.dts',
                                        entry_args=entry_args)
 
+    def testPreLoadEncryptedFit(self):
+        """Test an encrypted FIT image with a pre-load header"""
+        entry_args = {
+            'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+        }
+        data = tools.read_file(self.TestFile("fit/aes256.bin"))
+        self._MakeInputFile("keys/aes256.bin", data)
+
+        keys_subdir = os.path.join(self._indir, "keys")
+        data = self._DoReadFileDtb(
+            'security/pre_load_fit_encrypted.dts', entry_args=entry_args,
+            extra_indirs=[keys_subdir])[0]
+
+        image_fname = tools.get_output_filename('image.bin')
+        is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
+
+        self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
+        self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
+        self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
+        self.assertEqual(is_signed, True)
+
     def _CheckSafeUniqueNames(self, *images):
         """Check all entries of given images for unsafe unique names"""
         for image in images:
diff --git a/tools/binman/test/security/pre_load_fit_encrypted.dts b/tools/binman/test/security/pre_load_fit_encrypted.dts
new file mode 100644
index 00000000000..f5e9bf9426c
--- /dev/null
+++ b/tools/binman/test/security/pre_load_fit_encrypted.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		pre-load {
+			content = <&image>;
+			algo-name = "sha256,rsa2048";
+			key-name = "dev.key";
+			header-size = <4096>;
+			version = <0x11223344>;
+		};
+
+		image: fit {
+			fit,encrypt;
+			description = "Test a FIT with encrypted data and signed with a preload";
+			#address-cells = <1>;
+
+			images {
+				u-boot {
+					description = "U-Boot";
+					type = "firmware";
+					arch = "arm64";
+					os = "U-Boot";
+					compression = "none";
+					load = <00000000>;
+					entry = <00000000>;
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-nodtb {
+					};
+				};
+				fdt-1 {
+					description = "Flattened Device Tree blob";
+					type = "flat_dt";
+					arch = "arm64";
+					compression = "none";
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-dtb {
+					};
+				};
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "Boot U-Boot with FDT blob";
+					firmware = "u-boot";
+					fdt = "fdt-1";
+				};
+			};
+		};
+	};
+};
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 2/3] binman: Generate preload header and sign data only once
  2026-04-03  7:55   ` [PATCH v4 " Paul HENRYS
@ 2026-04-03  7:55     ` Paul HENRYS
  2026-04-03 13:21       ` Simon Glass
  2026-04-03  7:55     ` [PATCH v4 3/3] binman: collection: Set build_done on referenced entries Paul HENRYS
  2026-04-03 13:22     ` [PATCH v4 1/3] " Simon Glass
  2 siblings, 1 reply; 38+ messages in thread
From: Paul HENRYS @ 2026-04-03  7:55 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, Paul HENRYS

To optimize preload generation, generate the header and signatures only
after all data has been collected. This avoids signing the data multiple
times.

Since header_size is known upfront (from __init__), set the preload
header size in `ObtainContents()` to avoid an extra packing pass when
ProcessContentsUpdate() detects the size changed from 0 to header_size.

This reduces unnecessary repacking and signing operations.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---
Changes for v4:
- No change

 tools/binman/etype/pre_load.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
index 00f1a896767..34a7bc1b985 100644
--- a/tools/binman/etype/pre_load.py
+++ b/tools/binman/etype/pre_load.py
@@ -152,14 +152,14 @@ class Entry_pre_load(Entry_collection):
         return data + pad
 
     def ObtainContents(self):
-        """Obtain a placeholder for the header contents"""
-        # wait that the image is available
-        self.image = self.GetContents(False)
-        if self.image is None:
-            return False
-        self.SetContents(self._CreateHeader())
+        """Only set the known size of the preload header. The data will be
+        generated later on in ProcessContents() when the data from every entries
+        can be retrieved.
+        """
+        self.contents_size = self.header_size
         return True
 
     def ProcessContents(self):
+        self.image = self.GetContents(True)
         data = self._CreateHeader()
         return self.ProcessContentsUpdate(data)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v4 3/3] binman: collection: Set build_done on referenced entries
  2026-04-03  7:55   ` [PATCH v4 " Paul HENRYS
  2026-04-03  7:55     ` [PATCH v4 2/3] binman: Generate preload header and sign data only once Paul HENRYS
@ 2026-04-03  7:55     ` Paul HENRYS
  2026-04-03 13:22       ` Simon Glass
  2026-04-08 15:01       ` [PATCH v5 0/3] binman: Fix preload signing with encrypted FIT Paul HENRYS
  2026-04-03 13:22     ` [PATCH v4 1/3] " Simon Glass
  2 siblings, 2 replies; 38+ messages in thread
From: Paul HENRYS @ 2026-04-03  7:55 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, yan wang

From: yan wang <yan.wang@softathome.com>

The collection etype uses phandles in the 'content' property to
reference other entries. Mark each referenced entry with build_done
to avoid rebuilding the same entry data multiple times.

This is important for cases where rebuilding may change the data
content, e.g. due to timestamps or random IVs in encryption.

Refactor GetContentsByPhandle() to return both the entry object and
its data.

Signed-off-by: yan wang <yan.wang@softathome.com>
---
Changes for v4:
- No change

 tools/binman/etype/collection.py | 8 ++++++--
 tools/binman/etype/section.py    | 5 +++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
index c532aafe3e7..5ea6344bd25 100644
--- a/tools/binman/etype/collection.py
+++ b/tools/binman/etype/collection.py
@@ -45,12 +45,16 @@ class Entry_collection(Entry):
         self.Info('Getting contents, required=%s' % required)
         data = bytearray()
         for entry_phandle in self.content:
-            entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
-                                                           required)
+            entry, entry_data = self.section.GetContentsByPhandle(
+                entry_phandle, self, required)
             if not required and entry_data is None:
                 self.Info('Contents not available yet')
                 # Data not available yet
                 return None
+
+            # Mark referenced entries as build_done to avoid rebuilding
+            entry.build_done = True
+
             data += entry_data
 
         self.Info('Returning contents size %x' % len(data))
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 6a26d687056..8530b7ee17f 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -557,7 +557,8 @@ class Entry_section(Entry):
                 return None
 
         Returns:
-            data from associated entry (as a string), or None if not found
+            tuple: (entry, data) where entry is the Entry object and data is
+                from that entry (as a string), or (entry, None) if data not found
         """
         node = self._node.GetFdt().LookupPhandle(phandle)
         if not node:
@@ -565,7 +566,7 @@ class Entry_section(Entry):
         entry = self.FindEntryByNode(node)
         if not entry:
             source_entry.Raise("Cannot find entry for node '%s'" % node.name)
-        return entry.GetData(required)
+        return entry, entry.GetData(required)
 
     def LookupEntry(self, entries, sym_name, msg):
         """Look up the entry for a binman symbol
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 2/3] binman: Generate preload header and sign data only once
  2026-04-03  7:55     ` [PATCH v4 2/3] binman: Generate preload header and sign data only once Paul HENRYS
@ 2026-04-03 13:21       ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-03 13:21 UTC (permalink / raw)
  To: paul.henrys_ext
  Cc: u-boot+nodisclaimer, sjg+nodisclaimer, trini+nodisclaimer,
	alpernebiyasak+nodisclaimer, philippe.reynes+nodisclaimer, u-boot

Hi Paul,

On 2026-04-03T07:55:27, Paul HENRYS <paul.henrys_ext@softathome.com> wrote:
> binman: Generate preload header and sign data only once
>
> To optimize preload generation, generate the header and signatures only
> after all data has been collected. This avoids signing the data multiple
> times.
>
> Since header_size is known upfront (from __init__), set the preload
> header size in ObtainContents() to avoid an extra packing pass when
> ProcessContentsUpdate() detects the size changed from 0 to header_size.
>
> This reduces unnecessary repacking and signing operations.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>

> diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
> @@ -152,14 +152,14 @@ class Entry_pre_load(Entry_collection):
> +    def ObtainContents(self):
> +        """Only set the known size of the preload header. The data will be
> +        generated later on in ProcessContents() when the data from every entries
> +        can be retrieved.
> +        """
> +        self.contents_size = self.header_size
> +        return True

Setting contents_size without calling SetContents() is unusual. Most
entry types provide placeholder data so GetData() returns something
valid rather than None. While section.py handles None by substituting
pad bytes, this feels like relying on a side-effect.

Please can you call SetContents() with placeholder data of header_size
length instead, similar to image_header? That would be more consistent
with other entry types.

Also the docstring should have the summary on the first line per
Python conventions.

Regards,
Simon

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 3/3] binman: collection: Set build_done on referenced entries
  2026-04-03  7:55     ` [PATCH v4 3/3] binman: collection: Set build_done on referenced entries Paul HENRYS
@ 2026-04-03 13:22       ` Simon Glass
  2026-04-08 15:01       ` [PATCH v5 0/3] binman: Fix preload signing with encrypted FIT Paul HENRYS
  1 sibling, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-03 13:22 UTC (permalink / raw)
  To: paul.henrys_ext
  Cc: u-boot+nodisclaimer, sjg+nodisclaimer, trini+nodisclaimer,
	alpernebiyasak+nodisclaimer, philippe.reynes+nodisclaimer,
	yan wang, u-boot

On 2026-04-03T07:55:27, Paul HENRYS <paul.henrys_ext@softathome.com> wrote:
> binman: collection: Set build_done on referenced entries
>
> The collection etype uses phandles in the 'content' property to
> reference other entries. Mark each referenced entry with build_done
> to avoid rebuilding the same entry data multiple times.
>
> This is important for cases where rebuilding may change the data
> content, e.g. due to timestamps or random IVs in encryption.
>
> Refactor GetContentsByPhandle() to return both the entry object and
> its data.
>
> Signed-off-by: yan wang <yan.wang@softathome.com>
>
> tools/binman/etype/collection.py | 8 ++++++--
>  tools/binman/etype/section.py    | 5 +++--
>  2 files changed, 9 insertions(+), 4 deletions(-)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v4 1/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-03  7:55   ` [PATCH v4 " Paul HENRYS
  2026-04-03  7:55     ` [PATCH v4 2/3] binman: Generate preload header and sign data only once Paul HENRYS
  2026-04-03  7:55     ` [PATCH v4 3/3] binman: collection: Set build_done on referenced entries Paul HENRYS
@ 2026-04-03 13:22     ` Simon Glass
  2 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-03 13:22 UTC (permalink / raw)
  To: paul.henrys_ext
  Cc: u-boot+nodisclaimer, sjg+nodisclaimer, trini+nodisclaimer,
	alpernebiyasak+nodisclaimer, philippe.reynes+nodisclaimer, u-boot

Hi Paul,

On 2026-04-03T07:55:27, Paul HENRYS <paul.henrys_ext@softathome.com> wrote:
> tools: binman: Test signing an encrypted FIT with a preload header
>
> Add a test to verify the preload header correctly signs an encrypted
> FIT. This test exercises the case where encryption uses random IVs that
> would change between mkimage calls.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>

> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> @@ -5895,6 +5895,27 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
> +    def testPreLoadEncryptedFit(self):
> +        """Test an encrypted FIT image with a pre-load header"""

nit: for bisectability this should come last, since it relies on fixes
in patches 2/3 and 3/3.

Regards,
Simon

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v3 1/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-03  7:41   ` [PATCH v3 1/3] tools: binman: Test signing an encrypted FIT with a preload header Paul HENRYS
@ 2026-04-03 14:53     ` Tom Rini
  0 siblings, 0 replies; 38+ messages in thread
From: Tom Rini @ 2026-04-03 14:53 UTC (permalink / raw)
  To: Paul HENRYS
  Cc: trini+nodisclaimer, sjg+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, u-boot+nodisclaimer

[-- Attachment #1: Type: text/plain, Size: 436 bytes --]

On Fri, Apr 03, 2026 at 09:41:47AM +0200, Paul HENRYS wrote:
> Hi Tom,
> 
> Just after pushing the v3 I realized that this test would better go under
> tools/binman/test/security/ instead of tools/binman/test/fit/.
> I am going to push a v4 with this change. Sorry for the inconvenience.

Thanks. It looks like there might be a v5, so please add a cover letter
too, this will be used as part of merging the series.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v5 0/3] binman: Fix preload signing with encrypted FIT
  2026-04-03  7:55     ` [PATCH v4 3/3] binman: collection: Set build_done on referenced entries Paul HENRYS
  2026-04-03 13:22       ` Simon Glass
@ 2026-04-08 15:01       ` Paul HENRYS
  2026-04-08 15:01         ` [PATCH v5 1/3] binman: Generate preload header and sign data only once Paul HENRYS
                           ` (2 more replies)
  1 sibling, 3 replies; 38+ messages in thread
From: Paul HENRYS @ 2026-04-08 15:01 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, Paul HENRYS

This series improves the reliability and efficiency of binman preload
header generation and test it against an encrypted FIT image signed with
a preload header.

When a preload header references other entries (e.g. an encrypted FIT)
through the collection etype, the referenced entries may be rebuilt
multiple times during binman processing. This becomes problematic when
the referenced entry produces non-deterministic output, such as FIT
encryption using random IVs or timestamps, since rebuilding the entry
changes the data.

This series ensures that referenced entries are built only once and that
preload signing is performed after all data is collected. It also avoids
unnecessary repacking or repeated signing operations by the preload.

The changes include:
  * generate preload header placeholders in ObtainContents() and sign
    data only once in ProcessContentsUpdate()
  * mark referenced entries as build_done in the collection etype to
    avoid rebuilding data
  * add a functional test for signing an encrypted FIT with a preload
    header

Changes in v5:
- Generate preload placeholder in ObtainContents() to avoid unnecessary
  repacking
- Move functional test patch to the end of the series

Paul HENRYS (2):
  binman: Generate preload header and sign data only once
  tools: binman: Test signing an encrypted FIT with a preload header

Yan Wang (1):
  binman: collection: Set build_done on referenced entries

 tools/binman/etype/collection.py              |  8 ++-
 tools/binman/etype/pre_load.py                |  9 +--
 tools/binman/etype/section.py                 |  5 +-
 tools/binman/ftest.py                         | 21 +++++++
 .../test/security/pre_load_fit_encrypted.dts  | 63 +++++++++++++++++++
 5 files changed, 96 insertions(+), 10 deletions(-)
 create mode 100644 tools/binman/test/security/pre_load_fit_encrypted.dts

-- 
2.43.0


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v5 1/3] binman: Generate preload header and sign data only once
  2026-04-08 15:01       ` [PATCH v5 0/3] binman: Fix preload signing with encrypted FIT Paul HENRYS
@ 2026-04-08 15:01         ` Paul HENRYS
  2026-04-11 17:19           ` Simon Glass
  2026-04-08 15:02         ` [PATCH v5 2/3] binman: collection: Set build_done on referenced entries Paul HENRYS
  2026-04-08 15:02         ` [PATCH v5 " Paul HENRYS
  2 siblings, 1 reply; 38+ messages in thread
From: Paul HENRYS @ 2026-04-08 15:01 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, Paul HENRYS

To optimize preload generation, generate the header and signatures only
after all data has been collected in ProcessContentsUpdate(). This
avoids signing the data multiple times.

Since header_size is known upfront (from __init__), create a placeholder
in `ObtainContents()` to avoid an extra packing pass when
ProcessContentsUpdate() detects a size change.

This reduces unnecessary repacking and signing operations.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---

Changes in v5:
- Generate a placeholder in ObtainContents() to avoid unnecessary repack

 tools/binman/etype/pre_load.py | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
index 00f1a896767..0d953cb258e 100644
--- a/tools/binman/etype/pre_load.py
+++ b/tools/binman/etype/pre_load.py
@@ -152,14 +152,11 @@ class Entry_pre_load(Entry_collection):
         return data + pad
 
     def ObtainContents(self):
-        """Obtain a placeholder for the header contents"""
-        # wait that the image is available
-        self.image = self.GetContents(False)
-        if self.image is None:
-            return False
-        self.SetContents(self._CreateHeader())
+        """Create a placeholder for the header"""
+        self.SetContents(tools.get_bytes(0, self.header_size))
         return True
 
     def ProcessContents(self):
+        self.image = self.GetContents(True)
         data = self._CreateHeader()
         return self.ProcessContentsUpdate(data)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v5 2/3] binman: collection: Set build_done on referenced entries
  2026-04-08 15:01       ` [PATCH v5 0/3] binman: Fix preload signing with encrypted FIT Paul HENRYS
  2026-04-08 15:01         ` [PATCH v5 1/3] binman: Generate preload header and sign data only once Paul HENRYS
@ 2026-04-08 15:02         ` Paul HENRYS
  2026-04-11 17:18           ` Simon Glass
  2026-04-14 13:15           ` [PATCH v6 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
  2026-04-08 15:02         ` [PATCH v5 " Paul HENRYS
  2 siblings, 2 replies; 38+ messages in thread
From: Paul HENRYS @ 2026-04-08 15:02 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, yan wang

From: yan wang <yan.wang@softathome.com>

The collection etype uses phandles in the 'content' property to
reference other entries. Mark each referenced entry with build_done
to avoid rebuilding the same entry data multiple times.

This is important for cases where rebuilding may change the data
content, e.g. due to timestamps or random IVs in encryption.

Refactor GetContentsByPhandle() to return both the entry object and
its data.

Signed-off-by: yan wang <yan.wang@softathome.com>
---

Changes in v5:
- No changes

 tools/binman/etype/collection.py | 8 ++++++--
 tools/binman/etype/section.py    | 5 +++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
index c532aafe3e7..5ea6344bd25 100644
--- a/tools/binman/etype/collection.py
+++ b/tools/binman/etype/collection.py
@@ -45,12 +45,16 @@ class Entry_collection(Entry):
         self.Info('Getting contents, required=%s' % required)
         data = bytearray()
         for entry_phandle in self.content:
-            entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
-                                                           required)
+            entry, entry_data = self.section.GetContentsByPhandle(
+                entry_phandle, self, required)
             if not required and entry_data is None:
                 self.Info('Contents not available yet')
                 # Data not available yet
                 return None
+
+            # Mark referenced entries as build_done to avoid rebuilding
+            entry.build_done = True
+
             data += entry_data
 
         self.Info('Returning contents size %x' % len(data))
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 6a26d687056..8530b7ee17f 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -557,7 +557,8 @@ class Entry_section(Entry):
                 return None
 
         Returns:
-            data from associated entry (as a string), or None if not found
+            tuple: (entry, data) where entry is the Entry object and data is
+                from that entry (as a string), or (entry, None) if data not found
         """
         node = self._node.GetFdt().LookupPhandle(phandle)
         if not node:
@@ -565,7 +566,7 @@ class Entry_section(Entry):
         entry = self.FindEntryByNode(node)
         if not entry:
             source_entry.Raise("Cannot find entry for node '%s'" % node.name)
-        return entry.GetData(required)
+        return entry, entry.GetData(required)
 
     def LookupEntry(self, entries, sym_name, msg):
         """Look up the entry for a binman symbol
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v5 3/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-08 15:01       ` [PATCH v5 0/3] binman: Fix preload signing with encrypted FIT Paul HENRYS
  2026-04-08 15:01         ` [PATCH v5 1/3] binman: Generate preload header and sign data only once Paul HENRYS
  2026-04-08 15:02         ` [PATCH v5 2/3] binman: collection: Set build_done on referenced entries Paul HENRYS
@ 2026-04-08 15:02         ` Paul HENRYS
  2026-04-11 17:19           ` Simon Glass
  2 siblings, 1 reply; 38+ messages in thread
From: Paul HENRYS @ 2026-04-08 15:02 UTC (permalink / raw)
  To: u-boot+nodisclaimer
  Cc: sjg+nodisclaimer, trini+nodisclaimer, alpernebiyasak+nodisclaimer,
	philippe.reynes+nodisclaimer, Paul HENRYS

Add a test to verify the preload header correctly signs an encrypted
FIT. This test exercises the case where encryption uses random IVs that
would change between mkimage calls.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---

Changes in v5:
- No changes

 tools/binman/ftest.py                         | 21 +++++++
 .../test/security/pre_load_fit_encrypted.dts  | 63 +++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 tools/binman/test/security/pre_load_fit_encrypted.dts

diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ca5149ee654..da8325f820a 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5895,6 +5895,27 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
             data = self._DoReadFileDtb('security/pre_load_invalid_key.dts',
                                        entry_args=entry_args)
 
+    def testPreLoadEncryptedFit(self):
+        """Test an encrypted FIT image with a pre-load header"""
+        entry_args = {
+            'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+        }
+        data = tools.read_file(self.TestFile("fit/aes256.bin"))
+        self._MakeInputFile("keys/aes256.bin", data)
+
+        keys_subdir = os.path.join(self._indir, "keys")
+        data = self._DoReadFileDtb(
+            'security/pre_load_fit_encrypted.dts', entry_args=entry_args,
+            extra_indirs=[keys_subdir])[0]
+
+        image_fname = tools.get_output_filename('image.bin')
+        is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
+
+        self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
+        self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
+        self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
+        self.assertEqual(is_signed, True)
+
     def _CheckSafeUniqueNames(self, *images):
         """Check all entries of given images for unsafe unique names"""
         for image in images:
diff --git a/tools/binman/test/security/pre_load_fit_encrypted.dts b/tools/binman/test/security/pre_load_fit_encrypted.dts
new file mode 100644
index 00000000000..f5e9bf9426c
--- /dev/null
+++ b/tools/binman/test/security/pre_load_fit_encrypted.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		pre-load {
+			content = <&image>;
+			algo-name = "sha256,rsa2048";
+			key-name = "dev.key";
+			header-size = <4096>;
+			version = <0x11223344>;
+		};
+
+		image: fit {
+			fit,encrypt;
+			description = "Test a FIT with encrypted data and signed with a preload";
+			#address-cells = <1>;
+
+			images {
+				u-boot {
+					description = "U-Boot";
+					type = "firmware";
+					arch = "arm64";
+					os = "U-Boot";
+					compression = "none";
+					load = <00000000>;
+					entry = <00000000>;
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-nodtb {
+					};
+				};
+				fdt-1 {
+					description = "Flattened Device Tree blob";
+					type = "flat_dt";
+					arch = "arm64";
+					compression = "none";
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-dtb {
+					};
+				};
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "Boot U-Boot with FDT blob";
+					firmware = "u-boot";
+					fdt = "fdt-1";
+				};
+			};
+		};
+	};
+};
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v5 2/3] binman: collection: Set build_done on referenced entries
  2026-04-08 15:02         ` [PATCH v5 2/3] binman: collection: Set build_done on referenced entries Paul HENRYS
@ 2026-04-11 17:18           ` Simon Glass
  2026-04-14 13:15           ` [PATCH v6 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
  1 sibling, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-11 17:18 UTC (permalink / raw)
  To: Paul HENRYS
  Cc: u-boot+nodisclaimer, sjg+nodisclaimer, trini+nodisclaimer,
	alpernebiyasak+nodisclaimer, philippe.reynes+nodisclaimer,
	yan wang, U-Boot Mailing List

Hi Yan,

On 2026-04-08T15:02:01, Paul HENRYS <paul.henrys_ext@softathome.com> wrote:
> binman: collection: Set build_done on referenced entries
>
> The collection etype uses phandles in the 'content' property to
> reference other entries. Mark each referenced entry with build_done
> to avoid rebuilding the same entry data multiple times.
>
> This is important for cases where rebuilding may change the data
> content, e.g. due to timestamps or random IVs in encryption.
>
> Refactor GetContentsByPhandle() to return both the entry object and
> its data.
>
> Signed-off-by: yan wang <yan.wang@softathome.com>
>
> tools/binman/etype/collection.py | 8 ++++++--
>  tools/binman/etype/section.py    | 5 +++--
>  2 files changed, 9 insertions(+), 4 deletions(-)

> diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
> @@ -45,12 +45,16 @@ class Entry_collection(Entry):
> +            # Mark referenced entries as build_done to avoid rebuilding
> +            entry.build_done = True

Just a thought - have you tested this against testCollectionSection
and testMkimageCollection?

An alternative would be to set build_done only when required=True, so
it happens during ProcessContents() rather than ObtainContents():

    if required:
        entry.build_done = True

What do you think?

At some point we should try to come up with a better algorithm for
when Binman rebuilds the contents of an entry.

Regards,
Simon

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v5 1/3] binman: Generate preload header and sign data only once
  2026-04-08 15:01         ` [PATCH v5 1/3] binman: Generate preload header and sign data only once Paul HENRYS
@ 2026-04-11 17:19           ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-11 17:19 UTC (permalink / raw)
  To: paul.henrys_ext
  Cc: u-boot+nodisclaimer, sjg+nodisclaimer, trini+nodisclaimer,
	alpernebiyasak+nodisclaimer, philippe.reynes+nodisclaimer, u-boot

On 2026-04-08T15:02:01, Paul HENRYS <paul.henrys_ext@softathome.com> wrote:
> binman: Generate preload header and sign data only once
>
> To optimize preload generation, generate the header and signatures only
> after all data has been collected in ProcessContentsUpdate(). This
> avoids signing the data multiple times.
>
> Since header_size is known upfront (from __init__), create a placeholder
> in ObtainContents() to avoid an extra packing pass when
> ProcessContentsUpdate() detects a size change.
>
> This reduces unnecessary repacking and signing operations.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
>
> tools/binman/etype/pre_load.py | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v5 3/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-08 15:02         ` [PATCH v5 " Paul HENRYS
@ 2026-04-11 17:19           ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-11 17:19 UTC (permalink / raw)
  To: paul.henrys_ext
  Cc: u-boot+nodisclaimer, sjg+nodisclaimer, trini+nodisclaimer,
	alpernebiyasak+nodisclaimer, philippe.reynes+nodisclaimer, u-boot

On 2026-04-08T15:02:01, Paul HENRYS <paul.henrys_ext@softathome.com> wrote:
> tools: binman: Test signing an encrypted FIT with a preload header
>
> Add a test to verify the preload header correctly signs an encrypted
> FIT. This test exercises the case where encryption uses random IVs that
> would change between mkimage calls.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
>
> tools/binman/ftest.py                              | 21 ++++++++
>  .../test/security/pre_load_fit_encrypted.dts       | 63 ++++++++++++++++++++++
>  2 files changed, 84 insertions(+)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v6 0/3] binman: Fix preload signing with encrypted FIT
  2026-04-08 15:02         ` [PATCH v5 2/3] binman: collection: Set build_done on referenced entries Paul HENRYS
  2026-04-11 17:18           ` Simon Glass
@ 2026-04-14 13:15           ` Yan WANG
  2026-04-14 13:15             ` [PATCH v6 1/3] binman: Generate preload header and sign data only once Yan WANG
                               ` (2 more replies)
  1 sibling, 3 replies; 38+ messages in thread
From: Yan WANG @ 2026-04-14 13:15 UTC (permalink / raw)
  To: trini, sjg, alpernebiyasak; +Cc: paul.henrys_ext, u-boot, Yan WANG

This series improves the reliability and efficiency of binman preload
header generation and test it against an encrypted FIT image signed with
a preload header.

When a preload header references other entries (e.g. an encrypted FIT)
through the collection etype, the referenced entries may be rebuilt
multiple times during binman processing. This becomes problematic when
the referenced entry produces non-deterministic output, such as FIT
encryption using random IVs or timestamps, since rebuilding the entry
changes the data.

This series ensures that referenced entries are built only once and that
preload signing is performed after all data is collected. It also avoids
unnecessary repacking or repeated signing operations by the preload.

The changes include:
  * generate preload header placeholders in ObtainContents() and sign
    data only once in ProcessContentsUpdate()
  * mark referenced entries as build_done in the collection etype to
    avoid rebuilding data
  * add a functional test for signing an encrypted FIT with a preload
    header

Changes in v6:
  - set build_done only when required=True, so it happens during
    ProcessContents() rather than ObtainContents()

Paul HENRYS (2):
  binman: Generate preload header and sign data only once
  tools: binman: Test signing an encrypted FIT with a preload header

yan wang (1):
  binman: collection: Set build_done on referenced entries

 tools/binman/etype/collection.py              |  9 ++-
 tools/binman/etype/pre_load.py                |  9 +--
 tools/binman/etype/section.py                 |  5 +-
 tools/binman/ftest.py                         | 21 +++++++
 .../test/security/pre_load_fit_encrypted.dts  | 63 +++++++++++++++++++
 5 files changed, 97 insertions(+), 10 deletions(-)
 create mode 100644 tools/binman/test/security/pre_load_fit_encrypted.dts

-- 
2.25.1


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v6 1/3] binman: Generate preload header and sign data only once
  2026-04-14 13:15           ` [PATCH v6 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
@ 2026-04-14 13:15             ` Yan WANG
  2026-04-16 17:37               ` Simon Glass
  2026-04-14 13:15             ` [PATCH v6 2/3] binman: collection: Set build_done on referenced entries Yan WANG
  2026-04-14 13:15             ` [PATCH v6 " Yan WANG
  2 siblings, 1 reply; 38+ messages in thread
From: Yan WANG @ 2026-04-14 13:15 UTC (permalink / raw)
  To: trini, sjg, alpernebiyasak; +Cc: paul.henrys_ext, u-boot

From: Paul HENRYS <paul.henrys_ext@softathome.com>

To optimize preload generation, generate the header and signatures only
after all data has been collected in ProcessContentsUpdate(). This
avoids signing the data multiple times.

Since header_size is known upfront (from __init__), create a placeholder
in `ObtainContents()` to avoid an extra packing pass when
ProcessContentsUpdate() detects a size change.

This reduces unnecessary repacking and signing operations.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---

Changes in v6:
- No changes

 tools/binman/etype/pre_load.py | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
index 00f1a896767..0d953cb258e 100644
--- a/tools/binman/etype/pre_load.py
+++ b/tools/binman/etype/pre_load.py
@@ -152,14 +152,11 @@ class Entry_pre_load(Entry_collection):
         return data + pad
 
     def ObtainContents(self):
-        """Obtain a placeholder for the header contents"""
-        # wait that the image is available
-        self.image = self.GetContents(False)
-        if self.image is None:
-            return False
-        self.SetContents(self._CreateHeader())
+        """Create a placeholder for the header"""
+        self.SetContents(tools.get_bytes(0, self.header_size))
         return True
 
     def ProcessContents(self):
+        self.image = self.GetContents(True)
         data = self._CreateHeader()
         return self.ProcessContentsUpdate(data)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v6 2/3] binman: collection: Set build_done on referenced entries
  2026-04-14 13:15           ` [PATCH v6 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
  2026-04-14 13:15             ` [PATCH v6 1/3] binman: Generate preload header and sign data only once Yan WANG
@ 2026-04-14 13:15             ` Yan WANG
  2026-04-16 17:36               ` Simon Glass
  2026-04-17  8:30               ` [PATCH v7 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
  2026-04-14 13:15             ` [PATCH v6 " Yan WANG
  2 siblings, 2 replies; 38+ messages in thread
From: Yan WANG @ 2026-04-14 13:15 UTC (permalink / raw)
  To: trini, sjg, alpernebiyasak; +Cc: paul.henrys_ext, u-boot, yan wang

From: yan wang <yan.wang@softathome.com>

The collection etype uses phandles in the 'content' property to
reference other entries. Mark each referenced entry with build_done
to avoid rebuilding the same entry data multiple times.

This is important for cases where rebuilding may change the data
content, e.g. due to timestamps or random IVs in encryption.

Refactor GetContentsByPhandle() to return both the entry object and
its data.

Signed-off-by: yan wang <yan.wang@softathome.com>
---

Changes in v6:
- set build_done only when required=True, so it happens during
  ProcessContents() rather than ObtainContents()

 tools/binman/etype/collection.py | 9 +++++++--
 tools/binman/etype/section.py    | 5 +++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
index c532aafe3e7..c0ada42e3b2 100644
--- a/tools/binman/etype/collection.py
+++ b/tools/binman/etype/collection.py
@@ -45,12 +45,17 @@ class Entry_collection(Entry):
         self.Info('Getting contents, required=%s' % required)
         data = bytearray()
         for entry_phandle in self.content:
-            entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
-                                                           required)
+            entry, entry_data = self.section.GetContentsByPhandle(
+                entry_phandle, self, required)
             if not required and entry_data is None:
                 self.Info('Contents not available yet')
                 # Data not available yet
                 return None
+
+            # Mark referenced entries as build_done to avoid rebuilding
+            if required:
+                entry.build_done = True
+
             data += entry_data
 
         self.Info('Returning contents size %x' % len(data))
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 6a26d687056..8530b7ee17f 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -557,7 +557,8 @@ class Entry_section(Entry):
                 return None
 
         Returns:
-            data from associated entry (as a string), or None if not found
+            tuple: (entry, data) where entry is the Entry object and data is
+                from that entry (as a string), or (entry, None) if data not found
         """
         node = self._node.GetFdt().LookupPhandle(phandle)
         if not node:
@@ -565,7 +566,7 @@ class Entry_section(Entry):
         entry = self.FindEntryByNode(node)
         if not entry:
             source_entry.Raise("Cannot find entry for node '%s'" % node.name)
-        return entry.GetData(required)
+        return entry, entry.GetData(required)
 
     def LookupEntry(self, entries, sym_name, msg):
         """Look up the entry for a binman symbol
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v6 3/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-14 13:15           ` [PATCH v6 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
  2026-04-14 13:15             ` [PATCH v6 1/3] binman: Generate preload header and sign data only once Yan WANG
  2026-04-14 13:15             ` [PATCH v6 2/3] binman: collection: Set build_done on referenced entries Yan WANG
@ 2026-04-14 13:15             ` Yan WANG
  2026-04-16 17:37               ` Simon Glass
  2 siblings, 1 reply; 38+ messages in thread
From: Yan WANG @ 2026-04-14 13:15 UTC (permalink / raw)
  To: trini, sjg, alpernebiyasak; +Cc: paul.henrys_ext, u-boot

From: Paul HENRYS <paul.henrys_ext@softathome.com>

Add a test to verify the preload header correctly signs an encrypted
FIT. This test exercises the case where encryption uses random IVs that
would change between mkimage calls.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---

Changes in v6:
- No changes

 tools/binman/ftest.py                         | 21 +++++++
 .../test/security/pre_load_fit_encrypted.dts  | 63 +++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 tools/binman/test/security/pre_load_fit_encrypted.dts

diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ca5149ee654..da8325f820a 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5895,6 +5895,27 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
             data = self._DoReadFileDtb('security/pre_load_invalid_key.dts',
                                        entry_args=entry_args)
 
+    def testPreLoadEncryptedFit(self):
+        """Test an encrypted FIT image with a pre-load header"""
+        entry_args = {
+            'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+        }
+        data = tools.read_file(self.TestFile("fit/aes256.bin"))
+        self._MakeInputFile("keys/aes256.bin", data)
+
+        keys_subdir = os.path.join(self._indir, "keys")
+        data = self._DoReadFileDtb(
+            'security/pre_load_fit_encrypted.dts', entry_args=entry_args,
+            extra_indirs=[keys_subdir])[0]
+
+        image_fname = tools.get_output_filename('image.bin')
+        is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
+
+        self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
+        self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
+        self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
+        self.assertEqual(is_signed, True)
+
     def _CheckSafeUniqueNames(self, *images):
         """Check all entries of given images for unsafe unique names"""
         for image in images:
diff --git a/tools/binman/test/security/pre_load_fit_encrypted.dts b/tools/binman/test/security/pre_load_fit_encrypted.dts
new file mode 100644
index 00000000000..f5e9bf9426c
--- /dev/null
+++ b/tools/binman/test/security/pre_load_fit_encrypted.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		pre-load {
+			content = <&image>;
+			algo-name = "sha256,rsa2048";
+			key-name = "dev.key";
+			header-size = <4096>;
+			version = <0x11223344>;
+		};
+
+		image: fit {
+			fit,encrypt;
+			description = "Test a FIT with encrypted data and signed with a preload";
+			#address-cells = <1>;
+
+			images {
+				u-boot {
+					description = "U-Boot";
+					type = "firmware";
+					arch = "arm64";
+					os = "U-Boot";
+					compression = "none";
+					load = <00000000>;
+					entry = <00000000>;
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-nodtb {
+					};
+				};
+				fdt-1 {
+					description = "Flattened Device Tree blob";
+					type = "flat_dt";
+					arch = "arm64";
+					compression = "none";
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-dtb {
+					};
+				};
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "Boot U-Boot with FDT blob";
+					firmware = "u-boot";
+					fdt = "fdt-1";
+				};
+			};
+		};
+	};
+};
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v6 2/3] binman: collection: Set build_done on referenced entries
  2026-04-14 13:15             ` [PATCH v6 2/3] binman: collection: Set build_done on referenced entries Yan WANG
@ 2026-04-16 17:36               ` Simon Glass
  2026-04-17  8:30               ` [PATCH v7 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
  1 sibling, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-16 17:36 UTC (permalink / raw)
  To: yan.wang; +Cc: trini, sjg, alpernebiyasak, paul.henrys_ext, u-boot

Hi Yan,

On 2026-04-14T13:15:55, Yan WANG <yan.wang@softathome.com> wrote:
> binman: collection: Set build_done on referenced entries
>
> The collection etype uses phandles in the 'content' property to
> reference other entries. Mark each referenced entry with build_done
> to avoid rebuilding the same entry data multiple times.
>
> This is important for cases where rebuilding may change the data
> content, e.g. due to timestamps or random IVs in encryption.
>
> Refactor GetContentsByPhandle() to return both the entry object and
> its data.
>
> Signed-off-by: yan wang <yan.wang@softathome.com>
>
> tools/binman/etype/collection.py | 9 +++++++--
>  tools/binman/etype/section.py    | 5 +++--
>  2 files changed, 10 insertions(+), 4 deletions(-)

> diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
> @@ -45,12 +45,17 @@ class Entry_collection(Entry):
> +            # Mark referenced entries as build_done to avoid rebuilding
> +            if required:
> +                entry.build_done = True

I believe this should use mark_build_done() instead, as it recursively
marks child entries in sections.

Regards,
Simon

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v6 1/3] binman: Generate preload header and sign data only once
  2026-04-14 13:15             ` [PATCH v6 1/3] binman: Generate preload header and sign data only once Yan WANG
@ 2026-04-16 17:37               ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-16 17:37 UTC (permalink / raw)
  To: yan.wang; +Cc: trini, sjg, alpernebiyasak, paul.henrys_ext, u-boot

On 2026-04-14T13:15:55, Yan WANG <yan.wang@softathome.com> wrote:
> binman: Generate preload header and sign data only once
>
> To optimize preload generation, generate the header and signatures only
> after all data has been collected in ProcessContentsUpdate(). This
> avoids signing the data multiple times.
>
> Since header_size is known upfront (from __init__), create a placeholder
> in ObtainContents() to avoid an extra packing pass when
> ProcessContentsUpdate() detects a size change.
>
> This reduces unnecessary repacking and signing operations.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
>
> tools/binman/etype/pre_load.py | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v6 3/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-14 13:15             ` [PATCH v6 " Yan WANG
@ 2026-04-16 17:37               ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-16 17:37 UTC (permalink / raw)
  To: yan.wang; +Cc: trini, sjg, alpernebiyasak, paul.henrys_ext, u-boot

On 2026-04-14T13:15:55, Yan WANG <yan.wang@softathome.com> wrote:
> tools: binman: Test signing an encrypted FIT with a preload header
>
> Add a test to verify the preload header correctly signs an encrypted
> FIT. This test exercises the case where encryption uses random IVs that
> would change between mkimage calls.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
>
> tools/binman/ftest.py                              | 21 ++++++++
>  .../test/security/pre_load_fit_encrypted.dts       | 63 ++++++++++++++++++++++
>  2 files changed, 84 insertions(+)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v7 0/3] binman: Fix preload signing with encrypted FIT
  2026-04-14 13:15             ` [PATCH v6 2/3] binman: collection: Set build_done on referenced entries Yan WANG
  2026-04-16 17:36               ` Simon Glass
@ 2026-04-17  8:30               ` Yan WANG
  2026-04-17  8:30                 ` [PATCH v7 1/3] binman: Generate preload header and sign data only once Yan WANG
                                   ` (2 more replies)
  1 sibling, 3 replies; 38+ messages in thread
From: Yan WANG @ 2026-04-17  8:30 UTC (permalink / raw)
  To: trini, sjg, alpernebiyasak; +Cc: paul.henrys_ext, u-boot, Yan WANG

This series improves the reliability and efficiency of binman preload
header generation and test it against an encrypted FIT image signed with
a preload header.

When a preload header references other entries (e.g. an encrypted FIT)
through the collection etype, the referenced entries may be rebuilt
multiple times during binman processing. This becomes problematic when
the referenced entry produces non-deterministic output, such as FIT
encryption using random IVs or timestamps, since rebuilding the entry
changes the data.

This series ensures that referenced entries are built only once and that
preload signing is performed after all data is collected. It also avoids
unnecessary repacking or repeated signing operations by the preload.

The changes include:
  * generate preload header placeholders in ObtainContents() and sign
    data only once in ProcessContentsUpdate()
  * mark referenced entries as build_done in the collection etype to
    avoid rebuilding data
  * add a functional test for signing an encrypted FIT with a preload
    header

Changes in v7:
  - use mark_build_done() to recursively mark child entries

Paul HENRYS (2):
  binman: Generate preload header and sign data only once
  tools: binman: Test signing an encrypted FIT with a preload header

yan wang (1):
  binman: collection: Set build_done on referenced entries

 tools/binman/etype/collection.py              |  9 ++-
 tools/binman/etype/pre_load.py                |  9 +--
 tools/binman/etype/section.py                 |  5 +-
 tools/binman/ftest.py                         | 21 +++++++
 .../test/security/pre_load_fit_encrypted.dts  | 63 +++++++++++++++++++
 5 files changed, 97 insertions(+), 10 deletions(-)
 create mode 100644 tools/binman/test/security/pre_load_fit_encrypted.dts

-- 
2.25.1


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v7 1/3] binman: Generate preload header and sign data only once
  2026-04-17  8:30               ` [PATCH v7 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
@ 2026-04-17  8:30                 ` Yan WANG
  2026-04-18 18:14                   ` Simon Glass
  2026-04-17  8:30                 ` [PATCH v7 2/3] binman: collection: Set build_done on referenced entries Yan WANG
  2026-04-17  8:30                 ` [PATCH v7 3/3] tools: binman: Test signing an encrypted FIT with a preload header Yan WANG
  2 siblings, 1 reply; 38+ messages in thread
From: Yan WANG @ 2026-04-17  8:30 UTC (permalink / raw)
  To: trini, sjg, alpernebiyasak; +Cc: paul.henrys_ext, u-boot

From: Paul HENRYS <paul.henrys_ext@softathome.com>

To optimize preload generation, generate the header and signatures only
after all data has been collected in ProcessContentsUpdate(). This
avoids signing the data multiple times.

Since header_size is known upfront (from __init__), create a placeholder
in `ObtainContents()` to avoid an extra packing pass when
ProcessContentsUpdate() detects a size change.

This reduces unnecessary repacking and signing operations.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---

Changes in v7:
- No changes

 tools/binman/etype/pre_load.py | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
index 00f1a896767..0d953cb258e 100644
--- a/tools/binman/etype/pre_load.py
+++ b/tools/binman/etype/pre_load.py
@@ -152,14 +152,11 @@ class Entry_pre_load(Entry_collection):
         return data + pad
 
     def ObtainContents(self):
-        """Obtain a placeholder for the header contents"""
-        # wait that the image is available
-        self.image = self.GetContents(False)
-        if self.image is None:
-            return False
-        self.SetContents(self._CreateHeader())
+        """Create a placeholder for the header"""
+        self.SetContents(tools.get_bytes(0, self.header_size))
         return True
 
     def ProcessContents(self):
+        self.image = self.GetContents(True)
         data = self._CreateHeader()
         return self.ProcessContentsUpdate(data)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v7 2/3] binman: collection: Set build_done on referenced entries
  2026-04-17  8:30               ` [PATCH v7 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
  2026-04-17  8:30                 ` [PATCH v7 1/3] binman: Generate preload header and sign data only once Yan WANG
@ 2026-04-17  8:30                 ` Yan WANG
  2026-04-18 18:15                   ` Simon Glass
  2026-04-17  8:30                 ` [PATCH v7 3/3] tools: binman: Test signing an encrypted FIT with a preload header Yan WANG
  2 siblings, 1 reply; 38+ messages in thread
From: Yan WANG @ 2026-04-17  8:30 UTC (permalink / raw)
  To: trini, sjg, alpernebiyasak; +Cc: paul.henrys_ext, u-boot, yan wang

From: yan wang <yan.wang@softathome.com>

The collection etype uses phandles in the 'content' property to
reference other entries. Mark each referenced entry with build_done
to avoid rebuilding the same entry data multiple times.

This is important for cases where rebuilding may change the data
content, e.g. due to timestamps or random IVs in encryption.

Refactor GetContentsByPhandle() to return both the entry object and
its data.

Signed-off-by: yan wang <yan.wang@softathome.com>
---

Changes in v7:
- use mark_build_done() to recursively mark child entries

 tools/binman/etype/collection.py | 9 +++++++--
 tools/binman/etype/section.py    | 5 +++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
index c532aafe3e7..866ea8dcc1e 100644
--- a/tools/binman/etype/collection.py
+++ b/tools/binman/etype/collection.py
@@ -45,12 +45,17 @@ class Entry_collection(Entry):
         self.Info('Getting contents, required=%s' % required)
         data = bytearray()
         for entry_phandle in self.content:
-            entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
-                                                           required)
+            entry, entry_data = self.section.GetContentsByPhandle(
+                entry_phandle, self, required)
             if not required and entry_data is None:
                 self.Info('Contents not available yet')
                 # Data not available yet
                 return None
+
+            # Mark referenced entries as build_done to avoid rebuilding
+            if required:
+                entry.mark_build_done()
+
             data += entry_data
 
         self.Info('Returning contents size %x' % len(data))
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 6a26d687056..8530b7ee17f 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -557,7 +557,8 @@ class Entry_section(Entry):
                 return None
 
         Returns:
-            data from associated entry (as a string), or None if not found
+            tuple: (entry, data) where entry is the Entry object and data is
+                from that entry (as a string), or (entry, None) if data not found
         """
         node = self._node.GetFdt().LookupPhandle(phandle)
         if not node:
@@ -565,7 +566,7 @@ class Entry_section(Entry):
         entry = self.FindEntryByNode(node)
         if not entry:
             source_entry.Raise("Cannot find entry for node '%s'" % node.name)
-        return entry.GetData(required)
+        return entry, entry.GetData(required)
 
     def LookupEntry(self, entries, sym_name, msg):
         """Look up the entry for a binman symbol
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v7 3/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-17  8:30               ` [PATCH v7 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
  2026-04-17  8:30                 ` [PATCH v7 1/3] binman: Generate preload header and sign data only once Yan WANG
  2026-04-17  8:30                 ` [PATCH v7 2/3] binman: collection: Set build_done on referenced entries Yan WANG
@ 2026-04-17  8:30                 ` Yan WANG
  2026-04-18 18:15                   ` Simon Glass
  2 siblings, 1 reply; 38+ messages in thread
From: Yan WANG @ 2026-04-17  8:30 UTC (permalink / raw)
  To: trini, sjg, alpernebiyasak; +Cc: paul.henrys_ext, u-boot

From: Paul HENRYS <paul.henrys_ext@softathome.com>

Add a test to verify the preload header correctly signs an encrypted
FIT. This test exercises the case where encryption uses random IVs that
would change between mkimage calls.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---

Changes in v7:
- No changes

 tools/binman/ftest.py                         | 21 +++++++
 .../test/security/pre_load_fit_encrypted.dts  | 63 +++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 tools/binman/test/security/pre_load_fit_encrypted.dts

diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ca5149ee654..da8325f820a 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5895,6 +5895,27 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
             data = self._DoReadFileDtb('security/pre_load_invalid_key.dts',
                                        entry_args=entry_args)
 
+    def testPreLoadEncryptedFit(self):
+        """Test an encrypted FIT image with a pre-load header"""
+        entry_args = {
+            'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+        }
+        data = tools.read_file(self.TestFile("fit/aes256.bin"))
+        self._MakeInputFile("keys/aes256.bin", data)
+
+        keys_subdir = os.path.join(self._indir, "keys")
+        data = self._DoReadFileDtb(
+            'security/pre_load_fit_encrypted.dts', entry_args=entry_args,
+            extra_indirs=[keys_subdir])[0]
+
+        image_fname = tools.get_output_filename('image.bin')
+        is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
+
+        self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
+        self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
+        self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
+        self.assertEqual(is_signed, True)
+
     def _CheckSafeUniqueNames(self, *images):
         """Check all entries of given images for unsafe unique names"""
         for image in images:
diff --git a/tools/binman/test/security/pre_load_fit_encrypted.dts b/tools/binman/test/security/pre_load_fit_encrypted.dts
new file mode 100644
index 00000000000..f5e9bf9426c
--- /dev/null
+++ b/tools/binman/test/security/pre_load_fit_encrypted.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		pre-load {
+			content = <&image>;
+			algo-name = "sha256,rsa2048";
+			key-name = "dev.key";
+			header-size = <4096>;
+			version = <0x11223344>;
+		};
+
+		image: fit {
+			fit,encrypt;
+			description = "Test a FIT with encrypted data and signed with a preload";
+			#address-cells = <1>;
+
+			images {
+				u-boot {
+					description = "U-Boot";
+					type = "firmware";
+					arch = "arm64";
+					os = "U-Boot";
+					compression = "none";
+					load = <00000000>;
+					entry = <00000000>;
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-nodtb {
+					};
+				};
+				fdt-1 {
+					description = "Flattened Device Tree blob";
+					type = "flat_dt";
+					arch = "arm64";
+					compression = "none";
+					cipher {
+						algo = "aes256";
+						key-name-hint = "aes256";
+					};
+					u-boot-dtb {
+					};
+				};
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "Boot U-Boot with FDT blob";
+					firmware = "u-boot";
+					fdt = "fdt-1";
+				};
+			};
+		};
+	};
+};
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v7 1/3] binman: Generate preload header and sign data only once
  2026-04-17  8:30                 ` [PATCH v7 1/3] binman: Generate preload header and sign data only once Yan WANG
@ 2026-04-18 18:14                   ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-18 18:14 UTC (permalink / raw)
  To: yan.wang; +Cc: trini, sjg, alpernebiyasak, paul.henrys_ext, u-boot

On 2026-04-17T08:30:47, Yan WANG <yan.wang@softathome.com> wrote:
> binman: Generate preload header and sign data only once
>
> To optimize preload generation, generate the header and signatures only
> after all data has been collected in ProcessContentsUpdate(). This
> avoids signing the data multiple times.
>
> Since header_size is known upfront (from __init__), create a placeholder
> in ObtainContents() to avoid an extra packing pass when
> ProcessContentsUpdate() detects a size change.
>
> This reduces unnecessary repacking and signing operations.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
>
> tools/binman/etype/pre_load.py | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v7 2/3] binman: collection: Set build_done on referenced entries
  2026-04-17  8:30                 ` [PATCH v7 2/3] binman: collection: Set build_done on referenced entries Yan WANG
@ 2026-04-18 18:15                   ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-18 18:15 UTC (permalink / raw)
  To: yan.wang; +Cc: trini, sjg, alpernebiyasak, paul.henrys_ext, u-boot

On 2026-04-17T08:30:47, Yan WANG <yan.wang@softathome.com> wrote:
> binman: collection: Set build_done on referenced entries
>
> The collection etype uses phandles in the 'content' property to
> reference other entries. Mark each referenced entry with build_done
> to avoid rebuilding the same entry data multiple times.
>
> This is important for cases where rebuilding may change the data
> content, e.g. due to timestamps or random IVs in encryption.
>
> Refactor GetContentsByPhandle() to return both the entry object and
> its data.
>
> Signed-off-by: yan wang <yan.wang@softathome.com>
>
> tools/binman/etype/collection.py | 9 +++++++--
>  tools/binman/etype/section.py    | 5 +++--
>  2 files changed, 10 insertions(+), 4 deletions(-)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v7 3/3] tools: binman: Test signing an encrypted FIT with a preload header
  2026-04-17  8:30                 ` [PATCH v7 3/3] tools: binman: Test signing an encrypted FIT with a preload header Yan WANG
@ 2026-04-18 18:15                   ` Simon Glass
  0 siblings, 0 replies; 38+ messages in thread
From: Simon Glass @ 2026-04-18 18:15 UTC (permalink / raw)
  To: yan.wang; +Cc: trini, sjg, alpernebiyasak, paul.henrys_ext, u-boot

On 2026-04-17T08:30:47, Yan WANG <yan.wang@softathome.com> wrote:
> tools: binman: Test signing an encrypted FIT with a preload header
>
> Add a test to verify the preload header correctly signs an encrypted
> FIT. This test exercises the case where encryption uses random IVs that
> would change between mkimage calls.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
>
> tools/binman/ftest.py                              | 21 ++++++++
>  .../test/security/pre_load_fit_encrypted.dts       | 63 ++++++++++++++++++++++
>  2 files changed, 84 insertions(+)

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2026-04-18 18:15 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-02 19:24 [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header yan wang
2026-04-02 19:24 ` [PATCH v2 2/3] binman: Generate preload header and sign data only once yan wang
2026-04-03  1:02   ` Simon Glass
2026-04-02 19:24 ` [PATCH v2 3/3] binman: collection: Set build_done on referenced entries yan wang
2026-04-03  1:02   ` Simon Glass
2026-04-02 19:35 ` [PATCH v2 1/3] tools: binman: Test signing an encrypted FIT with a preload header Tom Rini
2026-04-03  7:32 ` [PATCH v3 " Paul HENRYS
2026-04-03  7:32   ` [PATCH v3 2/3] binman: Generate preload header and sign data only once Paul HENRYS
2026-04-03  7:32   ` [PATCH v3 3/3] binman: collection: Set build_done on referenced entries Paul HENRYS
2026-04-03  7:41   ` [PATCH v3 1/3] tools: binman: Test signing an encrypted FIT with a preload header Paul HENRYS
2026-04-03 14:53     ` Tom Rini
2026-04-03  7:55   ` [PATCH v4 " Paul HENRYS
2026-04-03  7:55     ` [PATCH v4 2/3] binman: Generate preload header and sign data only once Paul HENRYS
2026-04-03 13:21       ` Simon Glass
2026-04-03  7:55     ` [PATCH v4 3/3] binman: collection: Set build_done on referenced entries Paul HENRYS
2026-04-03 13:22       ` Simon Glass
2026-04-08 15:01       ` [PATCH v5 0/3] binman: Fix preload signing with encrypted FIT Paul HENRYS
2026-04-08 15:01         ` [PATCH v5 1/3] binman: Generate preload header and sign data only once Paul HENRYS
2026-04-11 17:19           ` Simon Glass
2026-04-08 15:02         ` [PATCH v5 2/3] binman: collection: Set build_done on referenced entries Paul HENRYS
2026-04-11 17:18           ` Simon Glass
2026-04-14 13:15           ` [PATCH v6 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
2026-04-14 13:15             ` [PATCH v6 1/3] binman: Generate preload header and sign data only once Yan WANG
2026-04-16 17:37               ` Simon Glass
2026-04-14 13:15             ` [PATCH v6 2/3] binman: collection: Set build_done on referenced entries Yan WANG
2026-04-16 17:36               ` Simon Glass
2026-04-17  8:30               ` [PATCH v7 0/3] binman: Fix preload signing with encrypted FIT Yan WANG
2026-04-17  8:30                 ` [PATCH v7 1/3] binman: Generate preload header and sign data only once Yan WANG
2026-04-18 18:14                   ` Simon Glass
2026-04-17  8:30                 ` [PATCH v7 2/3] binman: collection: Set build_done on referenced entries Yan WANG
2026-04-18 18:15                   ` Simon Glass
2026-04-17  8:30                 ` [PATCH v7 3/3] tools: binman: Test signing an encrypted FIT with a preload header Yan WANG
2026-04-18 18:15                   ` Simon Glass
2026-04-14 13:15             ` [PATCH v6 " Yan WANG
2026-04-16 17:37               ` Simon Glass
2026-04-08 15:02         ` [PATCH v5 " Paul HENRYS
2026-04-11 17:19           ` Simon Glass
2026-04-03 13:22     ` [PATCH v4 1/3] " Simon Glass

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox