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
