diff mbox series

[v2,3/3] tools: binman: Add tests for FIT with data encrypted by mkimage

Message ID 20240805133520.1745316-3-paul.henrys_ext@softathome.com
State Changes Requested
Delegated to: Simon Glass
Headers show
Series [v2,1/3] aes: Allow to store randomly generated IV in the FIT | expand

Commit Message

Paul HENRYS Aug. 5, 2024, 1:35 p.m. UTC
Test the property 'fit,keys-directory' which, when a cipher node is
present, encrypts the data stored in the FIT.

Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
---
 tools/binman/ftest.py                         |  39 +++++++++++++
 tools/binman/test/326_fit_encrypt_data.dts    |  53 ++++++++++++++++++
 .../test/327_fit_encrypt_data_no_key.dts      |  53 ++++++++++++++++++
 tools/binman/test/aes256.bin                  | Bin 0 -> 32 bytes
 4 files changed, 145 insertions(+)
 create mode 100644 tools/binman/test/326_fit_encrypt_data.dts
 create mode 100644 tools/binman/test/327_fit_encrypt_data_no_key.dts
 create mode 100644 tools/binman/test/aes256.bin

GIT binary patch
literal 32
ncmXpsGBz<aGq<obNK8sjNli=7$jr*l$<50zC@d;2DJ=s4pC}7U

literal 0
HcmV?d00001

Comments

Simon Glass Aug. 6, 2024, 9:51 p.m. UTC | #1
Hi Paul,

On Mon, 5 Aug 2024 at 07:35, Paul HENRYS <paul.henrys_ext@softathome.com> wrote:
>
> Test the property 'fit,keys-directory' which, when a cipher node is
> present, encrypts the data stored in the FIT.
>
> Signed-off-by: Paul HENRYS <paul.henrys_ext@softathome.com>
> ---
>  tools/binman/ftest.py                         |  39 +++++++++++++
>  tools/binman/test/326_fit_encrypt_data.dts    |  53 ++++++++++++++++++
>  .../test/327_fit_encrypt_data_no_key.dts      |  53 ++++++++++++++++++
>  tools/binman/test/aes256.bin                  | Bin 0 -> 32 bytes
>  4 files changed, 145 insertions(+)
>  create mode 100644 tools/binman/test/326_fit_encrypt_data.dts
>  create mode 100644 tools/binman/test/327_fit_encrypt_data_no_key.dts
>  create mode 100644 tools/binman/test/aes256.bin

Looks OK but for nits

>
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> index 93f3d22cf57..64b7d0231de 100644
> --- a/tools/binman/ftest.py
> +++ b/tools/binman/ftest.py
> @@ -7691,5 +7691,44 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
>              self.assertIsNone(dtb.GetNode('/node/other-node'))
>
>
> +    def testSimpleFitEncryptedData(self):
> +        """Test an image with a FIT containing data to be encrypted"""
> +        data = self._DoReadFile('326_fit_encrypt_data.dts')
> +
> +        fit = fdt.Fdt.FromData(data)
> +        fit.Scan()
> +
> +        # Extract the encrypted data and the IV from the FIT

Please write out IV in full for clarity.

> +        node = fit.GetNode('/images/u-boot')
> +        subnode = fit.GetNode('/images/u-boot/cipher')
> +        data_size_unciphered = int.from_bytes(fit.GetProps(node)['data-size-unciphered'].bytes,
> +                                              byteorder='big')
> +        self.assertEqual(data_size_unciphered, len(U_BOOT_NODTB_DATA))
> +
> +        # Retrieve the key name from the FIT removing any null byte
> +        key_name = fit.GetProps(subnode)['key-name-hint'].bytes.replace(b'\x00', b'')

Why do you need to replace the nul byte? Could you use this?

fdt_util.GetString(subnode, 'key-name-hint')

> +        with open(self.TestFile(key_name.decode('ascii') + '.bin'), 'rb') as file:
> +            key = file.read()

tools.read_file(filename)

below also

> +        iv = fit.GetProps(subnode)['iv'].bytes.hex()
> +        enc_data = fit.GetProps(node)['data'].bytes
> +        outdir = tools.get_output_dir()
> +        enc_data_file = os.path.join(outdir, 'encrypted_data.bin')
> +        tools.write_file(enc_data_file, enc_data)
> +        data_file = os.path.join(outdir, 'data.bin')
> +
> +        # Decrypt the encrypted data from the FIT and compare the data
> +        tools.run('openssl', 'enc', '-aes-256-cbc', '-nosalt', '-d', '-in',
> +                  enc_data_file, '-out', data_file, '-K', key.hex(), '-iv', iv)
> +        with open(data_file, 'r') as file:
> +            dec_data = file.read()
> +        self.assertEqual(U_BOOT_NODTB_DATA, dec_data.encode('ascii'))
> +
> +    def testSimpleFitEncryptedDataMissingKey(self):
> +        """Test an image with a FIT containing data to be encrypted but with a missing key"""
> +        with self.assertRaises(ValueError) as e:
> +            self._DoReadFile('327_fit_encrypt_data_no_key.dts')
> +
> +        self.assertIn("Can't open file ./aes256.bin (err=2 => No such file or directory)", str(e.exception))
> +
>  if __name__ == "__main__":
>      unittest.main()
> diff --git a/tools/binman/test/326_fit_encrypt_data.dts b/tools/binman/test/326_fit_encrypt_data.dts
> new file mode 100644
> index 00000000000..3cd890063cd
> --- /dev/null
> +++ b/tools/binman/test/326_fit_encrypt_data.dts
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       binman {
> +               fit {
> +                       fit,keys-directory = "tools/binman/test";
> +                       description = "Test a FIT with encrypted data";
> +                       #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";
> +                                       };
> +                               };
> +                       };
> +
> +                       configurations {
> +                               default = "conf-1";
> +                               conf-1 {
> +                                       description = "Boot U-Boot with FDT blob";
> +                                       firmware = "u-boot";
> +                                       fdt = "fdt-1";
> +                               };
> +                       };
> +               };
> +       };
> +};
> diff --git a/tools/binman/test/327_fit_encrypt_data_no_key.dts b/tools/binman/test/327_fit_encrypt_data_no_key.dts
> new file mode 100644
> index 00000000000..b92cd2e4bd6
> --- /dev/null
> +++ b/tools/binman/test/327_fit_encrypt_data_no_key.dts
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       binman {
> +               fit {
> +                       fit,keys-directory = ".";
> +                       description = "Test a FIT with encrypted data";
> +                       #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";
> +                                       };
> +                               };
> +                       };
> +
> +                       configurations {
> +                               default = "conf-1";
> +                               conf-1 {
> +                                       description = "Boot U-Boot with FDT blob";
> +                                       firmware = "u-boot";
> +                                       fdt = "fdt-1";
> +                               };
> +                       };
> +               };
> +       };
> +};
> diff --git a/tools/binman/test/aes256.bin b/tools/binman/test/aes256.bin
> new file mode 100644
> index 0000000000000000000000000000000000000000..09b8bf6254ada5c084039f32916bc7d30233bb2c
> GIT binary patch
> literal 32
> ncmXpsGBz<aGq<obNK8sjNli=7$jr*l$<50zC@d;2DJ=s4pC}7U
>
> literal 0
> HcmV?d00001
>
> --
> 2.25.1
>
> -- This message and any attachments herein are confidential, intended solely for the addressees and are SoftAtHome’s ownership. Any unauthorized use or dissemination is prohibited. If you are not the intended addressee of this message, please cancel it immediately and inform the sender.

Regards,
Simon
diff mbox series

Patch

diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 93f3d22cf57..64b7d0231de 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -7691,5 +7691,44 @@  fdt         fdtmap                Extract the devicetree blob from the fdtmap
             self.assertIsNone(dtb.GetNode('/node/other-node'))
 
 
+    def testSimpleFitEncryptedData(self):
+        """Test an image with a FIT containing data to be encrypted"""
+        data = self._DoReadFile('326_fit_encrypt_data.dts')
+
+        fit = fdt.Fdt.FromData(data)
+        fit.Scan()
+
+        # Extract the encrypted data and the IV from the FIT
+        node = fit.GetNode('/images/u-boot')
+        subnode = fit.GetNode('/images/u-boot/cipher')
+        data_size_unciphered = int.from_bytes(fit.GetProps(node)['data-size-unciphered'].bytes,
+                                              byteorder='big')
+        self.assertEqual(data_size_unciphered, len(U_BOOT_NODTB_DATA))
+
+        # Retrieve the key name from the FIT removing any null byte
+        key_name = fit.GetProps(subnode)['key-name-hint'].bytes.replace(b'\x00', b'')
+        with open(self.TestFile(key_name.decode('ascii') + '.bin'), 'rb') as file:
+            key = file.read()
+        iv = fit.GetProps(subnode)['iv'].bytes.hex()
+        enc_data = fit.GetProps(node)['data'].bytes
+        outdir = tools.get_output_dir()
+        enc_data_file = os.path.join(outdir, 'encrypted_data.bin')
+        tools.write_file(enc_data_file, enc_data)
+        data_file = os.path.join(outdir, 'data.bin')
+
+        # Decrypt the encrypted data from the FIT and compare the data
+        tools.run('openssl', 'enc', '-aes-256-cbc', '-nosalt', '-d', '-in',
+                  enc_data_file, '-out', data_file, '-K', key.hex(), '-iv', iv)
+        with open(data_file, 'r') as file:
+            dec_data = file.read()
+        self.assertEqual(U_BOOT_NODTB_DATA, dec_data.encode('ascii'))
+
+    def testSimpleFitEncryptedDataMissingKey(self):
+        """Test an image with a FIT containing data to be encrypted but with a missing key"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFile('327_fit_encrypt_data_no_key.dts')
+
+        self.assertIn("Can't open file ./aes256.bin (err=2 => No such file or directory)", str(e.exception))
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/326_fit_encrypt_data.dts b/tools/binman/test/326_fit_encrypt_data.dts
new file mode 100644
index 00000000000..3cd890063cd
--- /dev/null
+++ b/tools/binman/test/326_fit_encrypt_data.dts
@@ -0,0 +1,53 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		fit {
+			fit,keys-directory = "tools/binman/test";
+			description = "Test a FIT with encrypted data";
+			#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";
+					};
+				};
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "Boot U-Boot with FDT blob";
+					firmware = "u-boot";
+					fdt = "fdt-1";
+				};
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/327_fit_encrypt_data_no_key.dts b/tools/binman/test/327_fit_encrypt_data_no_key.dts
new file mode 100644
index 00000000000..b92cd2e4bd6
--- /dev/null
+++ b/tools/binman/test/327_fit_encrypt_data_no_key.dts
@@ -0,0 +1,53 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		fit {
+			fit,keys-directory = ".";
+			description = "Test a FIT with encrypted data";
+			#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";
+					};
+				};
+			};
+
+			configurations {
+				default = "conf-1";
+				conf-1 {
+					description = "Boot U-Boot with FDT blob";
+					firmware = "u-boot";
+					fdt = "fdt-1";
+				};
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/aes256.bin b/tools/binman/test/aes256.bin
new file mode 100644
index 0000000000000000000000000000000000000000..09b8bf6254ada5c084039f32916bc7d30233bb2c