[PATCH 2/3] tools: add fdt_add_pubkey

Alex Kiernan alex.kiernan at gmail.com
Tue Feb 11 10:54:44 CET 2020


On Tue, Feb 11, 2020 at 9:49 AM Rasmus Villemoes
<rasmus.villemoes at prevas.dk> wrote:
>
> 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.
>

Have you started looking at the required bitbake pieces? You're
definitely dealing with a piece of pain that I'd like resolved!

> 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: Rasmus Villemoes <rasmus.villemoes at prevas.dk>
> ---
>  tools/.gitignore       |  1 +
>  tools/Makefile         |  3 ++
>  tools/fdt_add_pubkey.c | 96 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 100 insertions(+)
>  create mode 100644 tools/fdt_add_pubkey.c
>
> diff --git a/tools/.gitignore b/tools/.gitignore
> index 82bdce2782..a9894db853 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 345bc84e48..d91edeaddc 100644
> --- a/tools/Makefile
> +++ b/tools/Makefile
> @@ -54,6 +54,7 @@ mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o
>
>  hostprogs-y += dumpimage mkimage
>  hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_info fit_check_sign
> +hostprogs-$(CONFIG_FIT_SIGNATURE) += fdt_add_pubkey
>
>  hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include
>
> @@ -122,6 +123,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_FIT_SIGNATURE),)
> @@ -166,6 +168,7 @@ HOSTCFLAGS_fit_image.o += -DMKIMAGE_DTC=\"$(CONFIG_MKIMAGE_DTC_PATH)\"
>  HOSTLOADLIBES_dumpimage := $(HOSTLOADLIBES_mkimage)
>  HOSTLOADLIBES_fit_info := $(HOSTLOADLIBES_mkimage)
>  HOSTLOADLIBES_fit_check_sign := $(HOSTLOADLIBES_mkimage)
> +HOSTLOADLIBES_fdt_add_pubkey := $(HOSTLOADLIBES_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 100644
> index 0000000000..45a2ce9ad2
> --- /dev/null
> +++ b/tools/fdt_add_pubkey.c
> @@ -0,0 +1,96 @@
> +#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);
> +}
> --
> 2.23.0
>


-- 
Alex Kiernan


More information about the U-Boot mailing list