# Copyright (c) 2016, Google Inc.
#
# SPDX-License-Identifier:	GPL-2.0+
#
# U-Boot Verified Boot Test

"""
This tests verified boot in the following ways:

For image verification:
- Create FIT (unsigned) with mkimage
- Check that verification shows that no keys are verified
- Sign image
- Check that verification shows that a key is now verified

For configuration verification:
- Corrupt signature and check for failure
- Create FIT (with unsigned configuration) with mkimage
- Check that image verification works
- Sign the FIT and mark the key as 'required' for verification
- Check that image verification works
- Corrupt the signature
- Check that image verification no-longer works

Tests run with both SHA1 and SHA256 hashing.
"""

import pytest
import sys
import u_boot_utils as util

@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('fit_signature')
def test_vboot(u_boot_console):
    """Test verified boot signing with mkimage and verification with 'bootm'.

    This works using sandbox only as it needs to update the device tree used
    by U-Boot to hold public keys from the signing process.

    The SHA1 and SHA256 tests are combined into a single test since the
    key-generation process is quite slow and we want to avoid doing it twice.
    """
    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 '
                         '-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb))

    def run_bootm(sha_algo, test_type, expect_string):
        """Run a 'bootm' command U-Boot.

        This always starts a fresh U-Boot instance since the device tree may
        contain a new public key.

        Args:
            test_type: A string identifying the test type.
            expect_string: A string which is expected in the output.
            sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
                    use.
        """
        cons.restart_uboot()
        with cons.log.section('Verified boot %s %s' % (sha_algo, test_type)):
            output = cons.run_command_list(
                ['sb load hostfs - 100 %stest.fit' % tmpdir,
                'fdt addr 100',
                'bootm 100'])
        assert(expect_string in ''.join(output))

    def make_fit(its):
        """Make a new FIT from the .its source file.

        This runs 'mkimage -f' to create a new FIT.

        Args:
            its: Filename containing .its source.
        """
        util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f',
                                '%s%s' % (datadir, its), fit])

    def sign_fit(sha_algo):
        """Sign the FIT

        Signs the FIT and writes the signature into it. It also writes the
        public key into the dtb.

        Args:
            sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
                    use.
        """
        cons.log.action('%s: Sign images' % sha_algo)
        util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
                                '-r', fit])

    def test_with_algo(sha_algo):
        """Test verified boot with the given hash algorithm.

        This is the main part of the test code. The same procedure is followed
        for both hashing algorithms.

        Args:
            sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
                    use.
        """
        # Compile our device tree files for kernel and U-Boot. These are
        # regenerated here since mkimage will modify them (by adding a
        # public key) below.
        dtc('sandbox-kernel.dts')
        dtc('sandbox-u-boot.dts')

        # Build the FIT, but don't sign anything yet
        cons.log.action('%s: Test FIT with signed images' % sha_algo)
        make_fit('sign-images-%s.its' % sha_algo)
        run_bootm(sha_algo, 'unsigned images', 'dev-')

        # Sign images with our dev keys
        sign_fit(sha_algo)
        run_bootm(sha_algo, 'signed images', 'dev+')

        # Create a fresh .dtb without the public keys
        dtc('sandbox-u-boot.dts')

        cons.log.action('%s: Test FIT with signed configuration' % sha_algo)
        make_fit('sign-configs-%s.its' % sha_algo)
        run_bootm(sha_algo, 'unsigned config', '%s+ OK' % sha_algo)

        # Sign images with our dev keys
        sign_fit(sha_algo)
        run_bootm(sha_algo, 'signed config', 'dev+')

        cons.log.action('%s: Check signed config on the host' % sha_algo)

        util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', tmpdir,
                                '-k', dtb])

        # Increment the first byte of the signature, which should cause failure
        sig = util.run_and_log(cons, 'fdtget -t bx %s %s value' %
                               (fit, sig_node))
        byte_list = sig.split()
        byte = int(byte_list[0], 16)
        byte_list[0] = '%x' % (byte + 1)
        sig = ' '.join(byte_list)
        util.run_and_log(cons, 'fdtput -t bx %s %s value %s' %
                         (fit, sig_node, sig))

        run_bootm(sha_algo, 'Signed config with bad hash', 'Bad Data Hash')

        cons.log.action('%s: Check bad config on the host' % sha_algo)
        util.run_and_log_expect_exception(cons, [fit_check_sign, '-f', fit,
                '-k', dtb], 1, 'Failed to verify required signature')

    cons = u_boot_console
    tmpdir = cons.config.result_dir + '/'
    tmp = tmpdir + 'vboot.tmp'
    datadir = cons.config.source_dir + '/test/py/tests/vboot/'
    fit = '%stest.fit' % tmpdir
    mkimage = cons.config.build_dir + '/tools/mkimage'
    fit_check_sign = cons.config.build_dir + '/tools/fit_check_sign'
    dtc_args = '-I dts -O dtb -i %s' % tmpdir
    dtb = '%ssandbox-u-boot.dtb' % tmpdir
    sig_node = '/configurations/conf@1/signature@1'

    # Create an RSA key pair
    public_exponent = 65537
    util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %sdev.key '
                     '-pkeyopt rsa_keygen_bits:2048 '
                     '-pkeyopt rsa_keygen_pubexp:%d '
                     '2>/dev/null'  % (tmpdir, public_exponent))

    # Create a certificate containing the public key
    util.run_and_log(cons, 'openssl req -batch -new -x509 -key %sdev.key -out '
                     '%sdev.crt' % (tmpdir, tmpdir))

    # Create a number kernel image with zeroes
    with open('%stest-kernel.bin' % tmpdir, 'w') as fd:
        fd.write(5000 * chr(0))

    try:
        # We need to use our own device tree file. Remember to restore it
        # afterwards.
        old_dtb = cons.config.dtb
        cons.config.dtb = dtb
        test_with_algo('sha1')
        test_with_algo('sha256')
    finally:
        # Go back to the original U-Boot with the correct dtb.
        cons.config.dtb = old_dtb
        cons.restart_uboot()
