[PATCH v3] test_vboot.py: include test of fdt_add_pubkey tool

Simon Glass sjg at chromium.org
Sun Mar 19 20:29:28 CET 2023

Hi Ivan,

On Sun, 19 Mar 2023 at 12:42, Ivan Mikhaylov <fr0st61te at gmail.com> wrote:
> From: Roman Kopytin <Roman.Kopytin at kaspersky.com>

Please add a commit message.

> Signed-off-by: Roman Kopytin <Roman.Kopytin at kaspersky.com>
> Signed-off-by: Ivan Mikhaylov <fr0st61te at gmail.com>
> Cc: Rasmus Villemoes <rasmus.villemoes at prevas.dk>
> ---
>  test/py/tests/test_vboot.py | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
> index e3e7ca4b21..5ae622fe21 100644
> --- a/test/py/tests/test_vboot.py
> +++ b/test/py/tests/test_vboot.py
> @@ -491,6 +491,37 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required,
>          # Check that the boot fails if the global signature is not provided
>          run_bootm(sha_algo, 'global image signature', 'signature is mandatory', False)
> +    def test_fdt_add_pubkey(sha_algo, padding, sign_options):
> +        """Test fdt_add_pubkey utility with given hash algorithm and padding.
> +
> +        This function tests if fdt_add_pubkey utility may add public keys into dtb.
> +
> +        Args:
> +            sha_algo: Either 'sha1' or 'sha256', to select the algorithm to use
> +            padding: Either '' or '-pss', to select the padding to use for the
> +                    rsa signature algorithm.
> +            sign_options: Options to mkimage when signing a fit image.
> +        """
> +
> +        # Create a fresh .dtb without the public keys
> +        dtc('sandbox-u-boot.dts')
> +        make_fit('sign-configs-%s%s.its' % (sha_algo, padding))
> +
> +        # Sign images with our dev keys
> +        sign_fit(sha_algo, sign_options)
> +
> +        # Create a fresh .dtb without the public keys
> +        dtc('sandbox-u-boot.dts')
> +
> +        cons.log.action('%s: Test fdt_add_pubkey with signed configuration' % sha_algo)
> +        # Then add the dev key via the fdt_add_pubkey tool
> +        util.run_and_log(cons, [fdt_add_pubkey, '-a', '%s,%s' % ('sha256' if algo_arg else sha_algo, \
> +                                'rsa3072' if sha_algo == 'sha384' else 'rsa2048'),
> +                                '-k', tmpdir, '-n', 'dev', '-r', 'conf', dtb])
> +
> +        # Check with fit_check_sign that FIT is signed with key
> +        util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', dtb])
> +
>      cons = u_boot_console
>      tmpdir = os.path.join(cons.config.result_dir, name) + '/'
>      if not os.path.exists(tmpdir):
> @@ -500,6 +531,7 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required,
>      mkimage = cons.config.build_dir + '/tools/mkimage'
>      binman = cons.config.source_dir + '/tools/binman/binman'
>      fit_check_sign = cons.config.build_dir + '/tools/fit_check_sign'
> +    fdt_add_pubkey = cons.config.build_dir + '/tools/fdt_add_pubkey'
>      dtc_args = '-I dts -O dtb -i %s' % tmpdir
>      dtb = '%ssandbox-u-boot.dtb' % tmpdir
>      sig_node = '/configurations/conf-1/signature'
> @@ -516,6 +548,7 @@ def test_vboot(u_boot_console, name, sha_algo, padding, sign_options, required,
>      with open(evil_kernel, 'wb') as fd:
>          fd.write(500 * b'\x01')
> +    test_fdt_add_pubkey(sha_algo, padding, sign_options)
>      try:
>          # We need to use our own device tree file. Remember to restore it
>          # afterwards.
> --
> 2.39.1

I'm not sure how you are testing this, but it fails for me:

+openssl req -batch -new -x509 -key
/tmp/b/sandbox/sha256-global-sign-pss/prod.key -out
+dtc -I dts -O dtb -i /tmp/b/sandbox/sha256-global-sign-pss/
-O dtb -o /tmp/b/sandbox/sha256-global-sign-pss/sandbox-u-boot.dtb
Warning (unit_address_vs_reg): /reset at 0: node has a unit name, but no
reg or ranges property
+/tmp/b/sandbox/tools/mkimage -D -I dts -O dtb -i
/tmp/b/sandbox/sha256-global-sign-pss/ -f
FATAL ERROR: Couldn't open "sandbox-kernel.dtb": No such file or directory
/tmp/b/sandbox/tools/mkimage: Can't open
/tmp/b/sandbox/sha256-global-sign-pss/test.fit.tmp: No such file or
Error: Bad parameters for FIT image type
Usage: /tmp/b/sandbox/tools/mkimage [-T type] -l image
          -l ==> list image header information
          -T ==> parse image file as 'type'
          -q ==> quiet
       /tmp/b/sandbox/tools/mkimage [-x] -A arch -O os -T type -C comp
-a addr -e ep -n name -d data_file[:data_file...] image
          -A ==> set architecture to 'arch'
          -O ==> set operating system to 'os'
          -T ==> set image type to 'type'
          -C ==> set compression type 'comp'
          -a ==> set load address to 'addr' (hex)
          -e ==> set entry point to 'ep' (hex)
          -n ==> set image name to 'name'
          -R ==> set second image name to 'name'
          -d ==> use image data from 'datafile'
          -x ==> set XIP (execute in place)
          -s ==> create an image with no data
          -v ==> verbose
       /tmp/b/sandbox/tools/mkimage [-D dtc_options] [-f
fit-image.its|-f auto|-f auto-conf|-F] [-b <dtb> [-b <dtb>]] [-E] [-B
size] [-i <ramdisk.cpio.gz>] fit-image
           <dtb> file is used with -f auto, it may occur multiple times.
          -D => set all options for device tree compiler
          -f => input filename for FIT source
          -i => input filename for ramdisk file
          -E => place data outside of the FIT structure
          -B => align size in hex for FIT structure and header
          -b => append the device tree binary to the FIT
          -t => update the timestamp in the FIT
Signing / verified boot options: [-k keydir] [-K dtb] [ -c <comment>]
[-p addr] [-r] [-N engine]
          -k => set directory containing private keys
          -K => write public keys to this .dtb file
          -g => set key name hint
          -G => use this signing key (in lieu of -k)
          -c => add comment in signature node
          -F => re-sign existing FIT image
          -p => place external data at a static position
          -r => mark keys used as 'required' in dtb
          -N => openssl engine to use for signing
          -o => algorithm to use for signing
       /tmp/b/sandbox/tools/mkimage -V ==> print version information and exit
Use '-T list' to see a list of available image types
Long options are available; read the man page for details
Exit code: 1
================================================== short test summary
info ==================================================
FAILED test/py/tests/test_vboot.py::test_vboot[sha1-basic-sha1--None-False-True-False-False]
- ValueError: Exit code: 1
FAILED test/py/tests/test_vboot.py::test_vboot[sha1-pad-sha1---E -p
0x10000-False-False-False-False] - ValueError: Exit co...
FAILED test/py/tests/test_vboot.py::test_vboot[sha1-pss-sha1--pss-None-False-False-False-False]
- ValueError: Exit code: 1
FAILED test/py/tests/test_vboot.py::test_vboot[sha1-pss-pad-sha1--pss--E
-p 0x10000-False-False-False-False] - ValueError:...
FAILED test/py/tests/test_vboot.py::test_vboot[sha256-basic-sha256--None-False-False-False-False]
- ValueError: Exit code: 1
FAILED test/py/tests/test_vboot.py::test_vboot[sha256-pad-sha256---E
-p 0x10000-False-False-False-False] - ValueError: Exi...
FAILED test/py/tests/test_vboot.py::test_vboot[sha256-pss-sha256--pss-None-False-False-False-False]
- ValueError: Exit cod...
FAILED test/py/tests/test_vboot.py::test_vboot[sha256-pss-pad-sha256--pss--E
-p 0x10000-False-False-False-False] - ValueEr...
FAILED test/py/tests/test_vboot.py::test_vboot[sha256-pss-required-sha256--pss-None-True-False-False-False]
- ValueError: ...
FAILED test/py/tests/test_vboot.py::test_vboot[sha256-pss-pad-required-sha256--pss--E
-p 0x10000-True-True-False-False] - ...
FAILED test/py/tests/test_vboot.py::test_vboot[sha384-basic-sha384--None-False-False-False-False]
- ValueError: Exit code: 1
FAILED test/py/tests/test_vboot.py::test_vboot[sha384-pad-sha384---E
-p 0x10000-False-False-False-False] - ValueError: Exi...
FAILED test/py/tests/test_vboot.py::test_vboot[algo-arg-algo-arg---o
sha256,rsa2048-False-False-True-False] - ValueError: ...
FAILED test/py/tests/test_vboot.py::test_vboot[sha256-global-sign-sha256---False-False-False-True]
- ValueError: Exit code: 1
FAILED test/py/tests/test_vboot.py::test_vboot[sha256-global-sign-pss-sha256--pss--False-False-False-True]
- ValueError: E...

If it helps, my alias to run a test is:

# Run a pytest on sandbox
# $1: Name of test to run (optional, else run all)

function pyt {
local tests
local para

if [ "$1" = "-b" ]; then
crosfw $b || return 1

if [ "$1" = "-p" ]; then
para="-n$(nproc) -q"
echo $para $tests

test/py/test.py -B sandbox --build-dir /tmp/b/sandbox ${para}
${tests:+"-k $tests"} $@

and I build sandbox into /tmp/b/sandbox before typing 'pyt vboot' to
run the test.

Also, when I mention adding it to its own test, I mean creating a new
function (like test_vboot() but at the end of the file and without
unnecessary parameterized arguments) to do your check. There is no
need to embed it in the existing test and I think it actually confuses
things, since the existing test already adds the public key to the DT.

With a separate test you can still use some code from test_vboot() if
you need to - just break it into a separate helper that both test
functions can call. Your test should simple create a DT, add a key to
it and then check that the key is there (using fit_check_sign for that
is fine).


More information about the U-Boot mailing list