From patchwork Wed Mar 8 01:13:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Mikhaylov X-Patchwork-Id: 1754086 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=ls6hZSvk; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PWtJR6RHcz1yWt for ; Thu, 9 Mar 2023 00:21:59 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 243E485E72; Wed, 8 Mar 2023 14:20:53 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ls6hZSvk"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C4F4685C31; Tue, 7 Mar 2023 23:13:57 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A384285AB0 for ; Tue, 7 Mar 2023 23:13:52 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=fr0st61te@gmail.com Received: by mail-lf1-x12a.google.com with SMTP id g17so19026590lfv.4 for ; Tue, 07 Mar 2023 14:13:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678227232; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Wm5mJ/YUiTmYpQ/iOd7xloI1fWGwuTiYDBss8sH/4Nw=; b=ls6hZSvkMEP7kE3m4pqSHcnng9uOFnBnKPbLA/SDokhrNF0q96fWuulrbHQhgMIqMW jfPMw+OTBql0ciJqonKeXvq5+ehtROthTJJwL++yzz2cFrU1VbnZTDygNtaUVeyJ0NQK 0QLKxFSqxM3dbv5Az50IBBwPVL45nRaum3BGctQUnztJBiVOcKcGoQ9uSEjy+P7FmLYj iE2pTvF60YdV1VmD21jEC9ikn9fRVJqFtiKZojqCkmXmSdOXTw+mrhRTkbKBpRGs9H8Z OD+af6qEMEDrHxQWAXRFuSr1bUD39x2fsKR8QJP4IjYJb6PwHXccwqD3f3GVQ6FXKgyR S0VA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678227232; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Wm5mJ/YUiTmYpQ/iOd7xloI1fWGwuTiYDBss8sH/4Nw=; b=QidT1a/CijZANbQGXbV3K+tu6oK5V3jfmAPu1D3DLnmwlUCNR1o4Szs5dwhfe1GwSG uerRvElGUUQgQ5cB2AYlDStqDqsrNjQ3C/GttzqKTU1FXYjKPiTEG84Fhby/c7PioI4h 4K7Wxj7fUXW4FF7vjXKhg8lSzgEw/j1ONMHIWUhlnktgSYgU8jsEx0bXTC1GPRVplZrV ZUuVFlu8prEuit8EjFr6+L+5FKCkrdKHdChTF7Tf4CiPFdpd8uIfE2QIZ+MsZG8DI7+N a2QOUGXMee/bo5cnWMoxGMkrkyOkbNT0cLtKV1wvNT6WXpKSyypNK52cFTSb3kZuVulK UIWQ== X-Gm-Message-State: AO0yUKWVpdKB4b6Na2sIUwfuyC3f40Rh/B/pX9k+oJP9FMSjkQg/9WuF ZkRoYBBqf8vzhhIA+JRUEUk= X-Google-Smtp-Source: AK7set9jibl91gzXN1ZzhNlbq4jMJpVu8saUQvwyEFMrOaOFgWDKFVADd907ily1JoKkVUbDliwShQ== X-Received: by 2002:ac2:44d7:0:b0:4d8:68f5:747b with SMTP id d23-20020ac244d7000000b004d868f5747bmr4168626lfm.37.1678227231770; Tue, 07 Mar 2023 14:13:51 -0800 (PST) Received: from localhost.localdomain (95-31-185-99.broadband.corbina.ru. [95.31.185.99]) by smtp.googlemail.com with ESMTPSA id l8-20020a19c208000000b004db3890cb53sm2159726lfc.223.2023.03.07.14.13.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 14:13:51 -0800 (PST) From: Ivan Mikhaylov To: Simon Glass , Jan Kiszka Cc: u-boot@lists.denx.de, Roman Kopytin , Ivan Mikhaylov , Rasmus Villemoes Subject: [PATCH v2 4/5] tools: add fdt_add_pubkey Date: Wed, 8 Mar 2023 01:13:41 +0000 Message-Id: <20230308011342.21992-5-fr0st61te@gmail.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230308011342.21992-1-fr0st61te@gmail.com> References: <20230308011342.21992-1-fr0st61te@gmail.com> MIME-Version: 1.0 X-Mailman-Approved-At: Wed, 08 Mar 2023 14:20:15 +0100 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean From: Roman Kopytin 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 Signed-off-by: Ivan Mikhaylov Signed-off-by: Jan Kiszka Cc: Rasmus Villemoes Signed-off-by: Roman Kopytin Signed-off-by: Ivan Mikhaylov Signed-off-by: Jan Kiszka --- tools/.gitignore | 1 + tools/Makefile | 3 + tools/fdt_add_pubkey.c | 138 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 tools/fdt_add_pubkey.c diff --git a/tools/.gitignore b/tools/.gitignore index 788ea260a0..cda3ea628c 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 e13effbb66..38699b069d 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -65,6 +65,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 ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST)$(CONFIG_FWU_MDATA_GPT_BLK),) hostprogs-y += file2include @@ -150,6 +151,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),) @@ -187,6 +189,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 100644 index 0000000000..999f5a7e83 --- /dev/null +++ b/tools/fdt_add_pubkey.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include "fit_common.h" + +static const char *cmdname; + +static const char *algo_name = "sha1,rsa2048"; /* -a */ +static const char *keydir = "."; /* -k */ +static const char *keyname = "key"; /* -n */ +static const char *require_keys; /* -r */ +static const char *keydest; /* argv[n] */ + +static void print_usage(const char *msg) +{ + fprintf(stderr, "Error: %s\n", msg); + fprintf(stderr, "Usage: %s [-a ] [-k ] [-n ] [-r ]" + " \n", cmdname); + fprintf(stderr, "Help information: %s [-h]\n", cmdname); + exit(EXIT_FAILURE); +} + +static void print_help(void) +{ + fprintf(stderr, "Options:\n" + "\t-a Cryptographic algorithm. Optional parameter, default value: sha1,rsa2048\n" + "\t-k Directory with public key. Optional parameter, default value: .\n" + "\t-n Public key name. Optional parameter, default value: key\n" + "\t-r Required: If present this indicates that the key must be verified for the image / configuration to be considered valid.\n" + "\t FDT blob file for adding of the public key. Required parameter.\n"); + exit(EXIT_FAILURE); +} + +static void process_args(int argc, char *argv[]) +{ + int opt; + + while ((opt = getopt(argc, argv, "a:k:n:r:h")) != -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; + case 'h': + print_help(); + default: + print_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) + print_usage("Missing dtb file to update"); +} + +static void reset_info(struct image_sign_info *info) +{ + if (!info) + fprintf(stderr, "Error: info is NULL in %s\n", __func__); + + memset(info, 0, sizeof(struct image_sign_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); + } +} + +static int add_pubkey(struct image_sign_info *info) +{ + int destfd = -1, ret; + void *dest_blob = NULL; + struct stat dest_sbuf; + size_t size_inc = 0; + + if (!info) + fprintf(stderr, "Error: info is NULL in %s\n", __func__); + + do { + if (destfd >= 0) { + munmap(dest_blob, dest_sbuf.st_size); + close(destfd); + + fprintf(stderr, ".dtb too small, increasing size by 1024 bytes\n"); + size_inc = 1024; + } + + 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); + if (ret == -ENOSPC) + continue; + else if (ret < 0) + break; + } while (ret == -ENOSPC); + + return ret; +} + +int main(int argc, char *argv[]) +{ + struct image_sign_info info; + int ret; + + cmdname = argv[0]; + + process_args(argc, argv); + reset_info(&info); + ret = add_pubkey(&info); + + if (ret < 0) { + fprintf(stderr, "%s: Cannot add public key to FIT blob: %s\n", + cmdname, strerror(ret)); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} +