From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4475C433F5 for ; Wed, 17 Nov 2021 17:54:14 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2C1E661283 for ; Wed, 17 Nov 2021 17:54:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2C1E661283 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=softathome.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2EEEB82F8B; Wed, 17 Nov 2021 18:53:57 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=softathome.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 8A45E806A7; Wed, 17 Nov 2021 18:52:51 +0100 (CET) Received: from smtp.smtpout.orange.fr (smtp01.smtpout.orange.fr [80.12.242.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 5588982EC6 for ; Wed, 17 Nov 2021 18:52:35 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=softathome.com Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=philippe.reynes@softathome.com Received: from localhost.localdomain ([90.0.151.89]) by smtp.orange.fr with ESMTPA id nP6emD1hA1UGBnP6omXdH5; Wed, 17 Nov 2021 18:52:34 +0100 X-ME-Helo: localhost.localdomain X-ME-Auth: ZDI3NDIxNif3YzVhYiQzN2FlZDdmZTc4NTQ2Nic3MzI2ZDdk X-ME-Date: Wed, 17 Nov 2021 18:52:34 +0100 X-ME-IP: 90.0.151.89 From: Philippe Reynes To: sjg@chromium.org, mr.nuke.me@gmail.com, joel.peshkin@broadcom.com Cc: u-boot@lists.denx.de, Philippe Reynes Subject: [RFC PATCH v3 7/8] mkimage: add public key for image pre-load stage Date: Wed, 17 Nov 2021 18:52:14 +0100 Message-Id: <20211117175215.24262-8-philippe.reynes@softathome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211117175215.24262-1-philippe.reynes@softathome.com> References: <20211117175215.24262-1-philippe.reynes@softathome.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.2 at phobos.denx.de X-Virus-Status: Clean This commit enhances mkimage to update the node /image/pre-load/sig with the public key. Signed-off-by: Philippe Reynes --- include/image.h | 15 ++++++ tools/fit_image.c | 3 ++ tools/image-host.c | 116 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+) diff --git a/include/image.h b/include/image.h index 42fb01ab07..ac27e7acb2 100644 --- a/include/image.h +++ b/include/image.h @@ -1019,6 +1019,21 @@ int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value, int fit_set_timestamp(void *fit, int noffset, time_t timestamp); +/** + * fit_pre_load_data() - add public key to fdt blob + * + * @keydir: Directory containing keys + * @keydest: FDT blob to write public key + * @fit: Pointer to the FIT format image header + * + * Adds public key to the node pre load. + * + * returns: + * 0, on success + * < 0, on failure + */ +int fit_pre_load_data(const char *keydir, void *keydest, void *fit); + int fit_cipher_data(const char *keydir, void *keydest, void *fit, const char *comment, int require_keys, const char *engine_id, const char *cmdname); diff --git a/tools/fit_image.c b/tools/fit_image.c index f4f372ba62..43ce41efbe 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -59,6 +59,9 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, ret = fit_set_timestamp(ptr, 0, time); } + if (!ret) + ret = fit_pre_load_data(params->keydir, dest_blob, ptr); + if (!ret) { ret = fit_cipher_data(params->keydir, dest_blob, ptr, params->comment, diff --git a/tools/image-host.c b/tools/image-host.c index a6b0a94420..20e59c14a9 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -14,6 +14,11 @@ #include #include +#include +#include + +#define IMAGE_PRE_LOAD_PATH "/image/pre-load/sig" + /** * fit_set_hash_value - set hash value in requested has node * @fit: pointer to the FIT format image header @@ -1020,6 +1025,117 @@ static int fit_config_add_verification_data(const char *keydir, return 0; } +/* + * 0) open file (open) + * 1) read certificate (PEM_read_X509) + * 2) get public key (X509_get_pubkey) + * 3) provide der format (d2i_RSAPublicKey) + */ +static int read_pub_key(const char *keydir, const void *name, + unsigned char **pubkey, int *pubkey_len) +{ + char path[1024]; + EVP_PKEY *key = NULL; + X509 *cert; + FILE *f; + int ret; + + memset(path, 0, 1024); + snprintf(path, sizeof(path), "%s/%s.crt", keydir, (char *)name); + + /* Open certificate file */ + f = fopen(path, "r"); + if (!f) { + fprintf(stderr, "Couldn't open RSA certificate: '%s': %s\n", + path, strerror(errno)); + return -EACCES; + } + + /* Read the certificate */ + cert = NULL; + if (!PEM_read_X509(f, &cert, NULL, NULL)) { + printf("Couldn't read certificate"); + ret = -EINVAL; + goto err_cert; + } + + /* Get the public key from the certificate. */ + key = X509_get_pubkey(cert); + if (!key) { + printf("Couldn't read public key\n"); + ret = -EINVAL; + goto err_pubkey; + } + + /* Get DER form */ + ret = i2d_PublicKey(key, pubkey); + if (ret < 0) { + printf("Couldn't get DER form\n"); + ret = -EINVAL; + goto err_pubkey; + } + + *pubkey_len = ret; + ret = 0; + +err_pubkey: + X509_free(cert); +err_cert: + fclose(f); + return ret; +} + +int fit_pre_load_data(const char *keydir, void *keydest, void *fit) +{ + int pre_load_noffset; + const void *header_size, *algo_name; + const void *key_name; + unsigned char *pubkey = NULL; + int ret, pubkey_len; + + if (!keydir || !keydest || !fit) + return 0; + + /* Search node pre-load sig */ + pre_load_noffset = fdt_path_offset(keydest, IMAGE_PRE_LOAD_PATH); + if (pre_load_noffset < 0) { + ret = 0; + goto out; + } + + header_size = fdt_getprop(keydest, pre_load_noffset, "header-size", NULL); + algo_name = fdt_getprop(keydest, pre_load_noffset, "algo-name", NULL); + key_name = fdt_getprop(keydest, pre_load_noffset, "key-name", NULL); + + /* Check that all mandatory properties are present */ + if (!header_size || !algo_name || !key_name) { + if (!header_size) + printf("The property header-size is missing in the node %s\n", + IMAGE_PRE_LOAD_PATH); + if (!algo_name) + printf("The property algo-name is missing in the node %s\n", + IMAGE_PRE_LOAD_PATH); + if (!key_name) + printf("The property key-name is missing in the node %s\n", + IMAGE_PRE_LOAD_PATH); + ret = -ENODATA; + goto out; + } + + /* Read public key */ + ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len); + if (ret < 0) + goto out; + + /* Add the public key to the device tree */ + ret = fdt_setprop(keydest, pre_load_noffset, "public-key", pubkey, pubkey_len); + if (ret) + printf("Can't set public-key in node %s\n", IMAGE_PRE_LOAD_PATH); + + out: + return ret; +} + int fit_cipher_data(const char *keydir, void *keydest, void *fit, const char *comment, int require_keys, const char *engine_id, const char *cmdname) -- 2.17.1