diff mbox series

[15/16] test: Add a test for FDT signing

Message ID 20211112192817.199075-16-sjg@chromium.org
State Deferred
Delegated to: Tom Rini
Headers show
Series tools: Add support for signing devicetree blobs | expand

Commit Message

Simon Glass Nov. 12, 2021, 7:28 p.m. UTC
Add a test which checks that signing and checking work, including signing
an FDT twice.

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

 test/py/tests/test_fdt_sign.py   | 83 ++++++++++++++++++++++++++++++++
 test/py/tests/test_vboot.py      | 21 ++------
 test/py/tests/vboot/sign-fdt.dts | 23 +++++++++
 test/py/tests/vboot_comm.py      | 22 +++++++++
 4 files changed, 131 insertions(+), 18 deletions(-)
 create mode 100644 test/py/tests/test_fdt_sign.py
 create mode 100644 test/py/tests/vboot/sign-fdt.dts
 create mode 100644 test/py/tests/vboot_comm.py
diff mbox series

Patch

diff --git a/test/py/tests/test_fdt_sign.py b/test/py/tests/test_fdt_sign.py
new file mode 100644
index 00000000000..72d58211159
--- /dev/null
+++ b/test/py/tests/test_fdt_sign.py
@@ -0,0 +1,83 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2021 Google LLC
+#
+# U-Boot FDT-signing test
+
+import os
+
+import u_boot_utils as util
+import vboot_comm
+
+def test_fdt_sign(u_boot_console):
+    def dtc(dts):
+        """Run the device tree compiler to compile a .dts file
+
+        The output file will be the same as the input file but with a .dtb
+        extension.
+
+        Args:
+            dts: Device tree file to compile.
+        """
+        dtb = dts.replace('.dts', '.dtb')
+        util.run_and_log(cons, 'dtc %s %s%s -O dtb -p 0x1000 '
+                         '-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb))
+
+    cons = u_boot_console
+    datadir = os.path.join(cons.config.source_dir, 'test/py/tests/vboot/')
+    fdt_sign = os.path.join(cons.config.build_dir, 'tools/fdt_sign')
+    fdt_check_sign = os.path.join(cons.config.build_dir, 'tools/fdt_check_sign')
+
+    tmpdir = os.path.join(cons.config.result_dir, 'fdt_sign') + '/'
+    if not os.path.exists(tmpdir):
+        os.mkdir(tmpdir)
+
+    dtb = '%ssandbox-u-boot.dtb' % tmpdir
+    dtc_args = '-I dts -O dtb -i %s' % tmpdir
+    dtc('sign-fdt.dts')
+    dtc('sandbox-u-boot.dts')
+
+    vboot_comm.create_rsa_pair(cons, tmpdir, 'dev')
+
+    # Sign and check that it verifies
+    signed = os.path.join(tmpdir, 'sign-fdt.dtb')
+    cmd = [fdt_sign, '-f', signed, '-G', os.path.join(tmpdir, 'dev.key'),
+           '-K', dtb, '-k', tmpdir, '-r']
+    util.run_and_log(cons, ' '.join(cmd))
+
+    cmd = [fdt_check_sign, '-f', signed, '-k', dtb]
+    util.run_and_log(cons, ' '.join(cmd))
+
+    # Update the chosen node, which dpes not affect things since the signature
+    # omits that node
+    util.run_and_log(cons, 'fdtput -t bx %s /chosen fred 1' % signed)
+
+    cmd = [fdt_check_sign, '-f', signed, '-k', dtb]
+    util.run_and_log(cons, ' '.join(cmd))
+
+    # Update the alias node, which should break things because that is included
+    # in the signature
+    util.run_and_log(cons, 'fdtput -t bx %s /aliases fred 1' % signed)
+
+    cmd = [fdt_check_sign, '-f', signed, '-k', dtb]
+    util.run_and_log_expect_exception(cons, cmd, 1, 'Verification failed')
+
+    # Regenerate the original devictree and sign it
+    dtc('sign-fdt.dts')
+    dtc('sandbox-u-boot.dts')
+    out = os.path.join(tmpdir, 'out-fdt.dtb')
+    cmd = [fdt_sign, '-f', signed, '-G', os.path.join(tmpdir, 'dev.key'),
+           '-K', dtb, '-k', tmpdir, '-r', '-o', out]
+    util.run_and_log(cons, ' '.join(cmd))
+
+    cmd = [fdt_check_sign, '-f', out, '-k', dtb]
+    util.run_and_log(cons, ' '.join(cmd))
+
+    # Create a new key and sign with that too
+    vboot_comm.create_rsa_pair(cons, tmpdir, 'prod')
+    cmd = [fdt_sign, '-f', out, '-G', os.path.join(tmpdir, 'prod.key'),
+           '-K', dtb, '-k', tmpdir, '-r']
+    util.run_and_log(cons, ' '.join(cmd))
+
+    # Now check that both signatures are valid
+    cmd = [fdt_check_sign, '-f', out, '-k', dtb]
+    util.run_and_log(cons, ' '.join(cmd))
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 095e00cce36..8458210691d 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -29,6 +29,7 @@  import shutil
 import struct
 import pytest
 import u_boot_utils as util
+import vboot_comm
 import vboot_forge
 import vboot_evil
 
@@ -173,22 +174,6 @@  def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required,
             handle.write(struct.pack(">I", size))
         return struct.unpack(">I", total_size)[0]
 
-    def create_rsa_pair(name):
-        """Generate a new RSA key paid and certificate
-
-        Args:
-            name: Name of of the key (e.g. 'dev')
-        """
-        public_exponent = 65537
-        util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %s%s.key '
-                     '-pkeyopt rsa_keygen_bits:2048 '
-                     '-pkeyopt rsa_keygen_pubexp:%d' %
-                     (tmpdir, name, public_exponent))
-
-        # Create a certificate containing the public key
-        util.run_and_log(cons, 'openssl req -batch -new -x509 -key %s%s.key '
-                         '-out %s%s.crt' % (tmpdir, name, tmpdir, name))
-
     def test_with_algo(sha_algo, padding, sign_options):
         """Test verified boot with the given hash algorithm.
 
@@ -377,8 +362,8 @@  def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required,
     dtb = '%ssandbox-u-boot.dtb' % tmpdir
     sig_node = '/configurations/conf-1/signature'
 
-    create_rsa_pair('dev')
-    create_rsa_pair('prod')
+    vboot_comm.create_rsa_pair(cons, tmpdir, 'dev')
+    vboot_comm.create_rsa_pair(cons, tmpdir, 'prod')
 
     # Create a number kernel image with zeroes
     with open('%stest-kernel.bin' % tmpdir, 'wb') as fd:
diff --git a/test/py/tests/vboot/sign-fdt.dts b/test/py/tests/vboot/sign-fdt.dts
new file mode 100644
index 00000000000..2c5b84976b1
--- /dev/null
+++ b/test/py/tests/vboot/sign-fdt.dts
@@ -0,0 +1,23 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	model = "Google Snow";
+	chosen {
+		bootargs = "console=tty1";
+		stdout-path = "serial3:115200n8";
+	};
+	aliases {
+		serail0 = "/serial@12c30000";
+	};
+
+	serial@12c30000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12c30000 0x00000100>;
+		u-boot,dm-pre-reloc;
+	};
+};
diff --git a/test/py/tests/vboot_comm.py b/test/py/tests/vboot_comm.py
new file mode 100644
index 00000000000..7e1690e89f8
--- /dev/null
+++ b/test/py/tests/vboot_comm.py
@@ -0,0 +1,22 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2021 Google LLC
+#
+# Common functions
+
+import u_boot_utils as util
+
+def create_rsa_pair(cons, tmpdir, name):
+    """Generate a new RSA key pair and certificate
+
+    Args:
+        name: Name of the key (e.g. 'dev')
+    """
+    public_exponent = 65537
+    util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %s%s.key '
+                 '-pkeyopt rsa_keygen_bits:2048 '
+                 '-pkeyopt rsa_keygen_pubexp:%d' %
+                 (tmpdir, name, public_exponent))
+
+    # Create a certificate containing the public key
+    util.run_and_log(cons, 'openssl req -batch -new -x509 -key %s%s.key '
+                     '-out %s%s.crt' % (tmpdir, name, tmpdir, name))