Build a control devicetree with no "/signature" node and an unsigned
FIT, then check that the boot is refused when
CONFIG_FIT_REQUIRE_CONFIG_SIGS is enabled, and that the historical
fail-open behaviour with a quiet console is kept when it is not.

Signed-off-by: Eva Crystal <[email protected]>
---
 test/py/tests/test_vboot.py | 96 +++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index fd91b3f10a..a864a541f2 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -846,3 +846,99 @@ def test_fdt_add_pubkey(ubman, name, sha_algo, padding, 
sign_options, algo_arg):
     # keys created in test_vboot test
 
     test_add_pubkey(sha_algo, padding, sign_options)
+
+
[email protected]('sandbox')
[email protected]('fit_signature')
[email protected]('dtc')
[email protected]('fdtget')
[email protected]('openssl')
+def test_vboot_no_sig_node(ubman):
+    """Test a control FDT which contains no /signature node.
+
+    Both required-signature gates in fit_image_verify_required_sigs() and
+    fit_config_verify_required_keys() look up the "/signature" node of the
+    U-Boot control devicetree. When that node is absent there are no keys
+    marked 'required', so nothing downstream can fail the image, and a FIT
+    whose signatures are absent or invalid verifies successfully.
+
+    With CONFIG_FIT_REQUIRE_CONFIG_SIGS the missing node is an error and the
+    boot must be refused. Without it the historical fail-open behaviour is
+    kept, so that boards using FIT_SIGNATURE only for image hash integrity
+    keep booting and keep a quiet console.
+
+    This works using sandbox only as it needs to control the device tree
+    used by U-Boot.
+    """
+    sha_algo = 'sha256'
+
+    def run_bootm(test_type, expect_string, boots):
+        """Run a 'bootm' command in U-Boot.
+
+        Args:
+            test_type: A string identifying the test type.
+            expect_string: A string which is expected in the output.
+            boots: True if the image is expected to boot, False if the boot
+                    is expected to be refused.
+        """
+        ubman.restart_uboot()
+        with ubman.log.section('Verified boot %s %s' % (sha_algo, test_type)):
+            output = ubman.run_command_list(
+                ['host load hostfs - 100 %s' % fit,
+                 'fdt addr 100',
+                 'bootm 100'])
+        assert expect_string in ''.join(output)
+        if boots:
+            assert 'sandbox: continuing, as we cannot run' in ''.join(output)
+        else:
+            assert ('sandbox: continuing, as we cannot run'
+                    not in ''.join(output))
+
+    tmpdir = os.path.join(ubman.config.result_dir, 'no-sig-node') + '/'
+    if not os.path.exists(tmpdir):
+        os.mkdir(tmpdir)
+    datadir = ubman.config.source_dir + '/test/py/tests/vboot/'
+    fit = '%stest.fit' % tmpdir
+    mkimage = ubman.config.build_dir + '/tools/mkimage'
+    dtc_args = '-I dts -O dtb -i %s' % tmpdir
+    dtb = '%ssandbox-u-boot.dtb' % tmpdir
+
+    bcfg = ubman.config.buildconfig
+    require_config_sigs = bcfg.get('config_fit_require_config_sigs', False)
+
+    # Create a kernel image filled with zeroes
+    with open('%stest-kernel.bin' % tmpdir, 'wb') as fd:
+        fd.write(500 * b'\0')
+
+    # We need to use our own device tree file. Remember to restore it
+    # afterwards.
+    old_dtb = ubman.config.dtb
+    try:
+        ubman.config.dtb = dtb
+
+        # Compile the control devicetree. sandbox-u-boot.dts holds no keys,
+        # and mkimage is deliberately not asked to add any, so the resulting
+        # blob has no /signature node at all.
+        dtc('sandbox-kernel.dts', ubman, dtc_args, datadir, tmpdir, dtb)
+        dtc('sandbox-u-boot.dts', ubman, dtc_args, datadir, tmpdir, dtb)
+
+        # Confirm the premise of the test: no /signature node is present.
+        out = utils.run_and_log(ubman, 'fdtget -l %s /' % dtb)
+        assert 'signature' not in out
+
+        # Build a FIT whose configuration signature has no 'value', i.e. it
+        # is unsigned.
+        ubman.log.action('%s: Test unsigned FIT with no keys in control FDT'
+                         % sha_algo)
+        make_fit('sign-configs-%s.its' % sha_algo, ubman, mkimage, dtc_args,
+                 datadir, fit)
+
+        if require_config_sigs:
+            run_bootm('no signature node', 'No signature node in control FDT',
+                      False)
+        else:
+            run_bootm('no signature node', 'Verifying Hash Integrity', True)
+    finally:
+        # Go back to the original U-Boot with the correct dtb.
+        ubman.config.dtb = old_dtb
+        ubman.restart_uboot()
-- 
2.53.0

Reply via email to