
testtest
Roman Kopytin (2): tools: add fdt_add_pubkey test_vboot.py: include test of fdt_add_pubkey tool
test/py/tests/test_vboot.py | 8 +++ tools/.gitignore | 1 + tools/Makefile | 3 ++ tools/fdt_add_pubkey.c | 97 +++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100755 tools/fdt_add_pubkey.c

Having to use the -K option to mkimage to populate U-Boot's .dtb with the public key while signing the kernel FIT image is often a little awkward. In particular, when using a meta-build system such as bitbake/Yocto, having the tasks of the kernel and U-Boot recipes intertwined, modifying deployed artifacts and rebuilding U-Boot with an updated .dtb is quite cumbersome. Also, in some scenarios one may wish to build U-Boot complete with the public key(s) embedded in the .dtb without the corresponding private keys being present on the same build host.
So this adds a simple tool that allows one to disentangle the kernel and U-Boot builds, by simply copy-pasting just enough of the mkimage code to allow one to add a public key to a .dtb. When using mkimage, some of the information is taken from the .its used to build the kernel (algorithm and key name), so that of course needs to be supplied on the command line.
Signed-off-by: Roman Kopytin Roman.Kopytin@kaspersky.com Cc: Rasmus Villemoes rasmus.villemoes@prevas.dk --- tools/.gitignore | 1 + tools/Makefile | 3 ++ tools/fdt_add_pubkey.c | 97 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100755 tools/fdt_add_pubkey.c
diff --git a/tools/.gitignore b/tools/.gitignore index a88453f64d..f312b760e4 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -6,6 +6,7 @@ /dumpimage /easylogo/easylogo /envcrc +/fdt_add_pubkey /fdtgrep /file2include /fit_check_sign diff --git a/tools/Makefile b/tools/Makefile index 4a86321f64..44f25dda18 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -73,6 +73,7 @@ mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o
hostprogs-y += dumpimage mkimage hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign +hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fdt_add_pubkey
hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include
@@ -153,6 +154,7 @@ dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o mkimage-objs := $(dumpimage-mkimage-objs) mkimage.o fit_info-objs := $(dumpimage-mkimage-objs) fit_info.o fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o +fdt_add_pubkey-objs := $(dumpimage-mkimage-objs) fdt_add_pubkey.o file2include-objs := file2include.o
ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_TOOLS_LIBCRYPTO),) @@ -190,6 +192,7 @@ HOSTCFLAGS_fit_image.o += -DMKIMAGE_DTC="$(CONFIG_MKIMAGE_DTC_PATH)" HOSTLDLIBS_dumpimage := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fit_info := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fit_check_sign := $(HOSTLDLIBS_mkimage) +HOSTLDLIBS_fdt_add_pubkey := $(HOSTLDLIBS_mkimage)
hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl diff --git a/tools/fdt_add_pubkey.c b/tools/fdt_add_pubkey.c new file mode 100755 index 0000000000..9306ecedd1 --- /dev/null +++ b/tools/fdt_add_pubkey.c @@ -0,0 +1,97 @@ +#include <image.h> +#include "fit_common.h" + +static const char *cmdname; + +static const char *algo_name = "sha1,rsa2048"; /* -a <algo> */ +static const char *keydir = "."; /* -k <keydir> */ +static const char *keyname = "key"; /* -n <keyname> */ +static const char *require_keys; /* -r <conf|image> */ +static const char *keydest; /* argv[n] */ + +static void usage(const char *msg) +{ + fprintf(stderr, "Error: %s\n", msg); + fprintf(stderr, "Usage: %s [-a <algo>] [-k <keydir>] [-n <keyname>] [-r <conf|image>] <fdt blob>\n", + cmdname); + exit(EXIT_FAILURE); +} + +static void process_args(int argc, char *argv[]) +{ + int opt; + + while((opt = getopt(argc, argv, "a:k:n:r:")) != -1) { + switch (opt) { + case 'k': + keydir = optarg; + break; + case 'a': + algo_name = optarg; + break; + case 'n': + keyname = optarg; + break; + case 'r': + require_keys = optarg; + break; + default: + usage("Invalid option"); + } + } + /* The last parameter is expected to be the .dtb to add the public key to */ + if (optind < argc) + keydest = argv[optind]; + + if (!keydest) + usage("Missing dtb file to update"); +} + +int main(int argc, char *argv[]) +{ + struct image_sign_info info; + int destfd, ret; + void *dest_blob = NULL; + struct stat dest_sbuf; + size_t size_inc = 0; + + cmdname = argv[0]; + + process_args(argc, argv); + + memset(&info, 0, sizeof(info)); + + info.keydir = keydir; + info.keyname = keyname; + info.name = algo_name; + info.require_keys = require_keys; + info.crypto = image_get_crypto_algo(algo_name); + if (!info.crypto) { + fprintf(stderr, "Unsupported signature algorithm '%s'\n", algo_name); + exit(EXIT_FAILURE); + } + + while (1) { + destfd = mmap_fdt(cmdname, keydest, size_inc, &dest_blob, &dest_sbuf, false, false); + if (destfd < 0) + exit(EXIT_FAILURE); + + ret = info.crypto->add_verify_data(&info, dest_blob); + + munmap(dest_blob, dest_sbuf.st_size); + close(destfd); + if (!ret || ret != -ENOSPC) + break; + fprintf(stderr, ".dtb too small, increasing size by 1024 bytes\n"); + size_inc = 1024; + } + + if (ret) { + fprintf(stderr, "%s: Cannot add public key to FIT blob: %s\n", + cmdname, strerror(-ret)); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} +

Signed-off-by: Roman Kopytin Roman.Kopytin@kaspersky.com Cc: Rasmus Villemoes rasmus.villemoes@prevas.dk --- test/py/tests/test_vboot.py | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index 6dff6779d1..cf7416b39a 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -230,6 +230,13 @@ def test_vboot(u_boot_console, sha_algo, padding, sign_options, required, cons.log.action('%s: Check signed config on the host' % sha_algo)
util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', dtb]) + + # Create a fresh .dtb without the public keys + dtc('sandbox-u-boot.dts') + # Then add the dev key via the fdt_add_pubkey tool + util.run_and_log(cons, [fdt_add_pubkey, '-a', '%s,rsa2048' % sha_algo, + '-k', tmpdir, '-n', 'dev', '-r', 'conf', dtb]) + util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', dtb])
if full_test: # Make sure that U-Boot checks that the config is in the list of @@ -370,6 +377,7 @@ def test_vboot(u_boot_console, sha_algo, padding, sign_options, required, fit = '%stest.fit' % tmpdir mkimage = cons.config.build_dir + '/tools/mkimage' 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'
participants (1)
-
Roman Kopytin