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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 6D381CCF9FE for ; Fri, 31 Oct 2025 15:23:38 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id DF036839A1; Fri, 31 Oct 2025 16:23:15 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=0leil.net 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 48A3F83980; Fri, 31 Oct 2025 16:23:13 +0100 (CET) Received: from smtp-1909.mail.infomaniak.ch (smtp-1909.mail.infomaniak.ch [IPv6:2001:1600:7:10::1909]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 3949A83984 for ; Fri, 31 Oct 2025 16:23:10 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=0leil.net Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=foss+uboot@0leil.net Received: from smtp-4-0000.mail.infomaniak.ch (unknown [IPv6:2001:1600:7:10::a6b]) by smtp-4-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4cyl9T6Dpdz4gD; Fri, 31 Oct 2025 16:23:09 +0100 (CET) Received: from unknown by smtp-4-0000.mail.infomaniak.ch (Postfix) with ESMTPA id 4cyl9T0lNtzZD6; Fri, 31 Oct 2025 16:23:09 +0100 (CET) From: Quentin Schulz Date: Fri, 31 Oct 2025 16:23:00 +0100 Subject: [PATCH 3/3] tools: binman: fit: add support for OpenSSL engines MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20251031-binman-engine-v1-3-c13c1b5dac43@cherry.de> References: <20251031-binman-engine-v1-0-c13c1b5dac43@cherry.de> In-Reply-To: <20251031-binman-engine-v1-0-c13c1b5dac43@cherry.de> To: u-boot@lists.denx.de Cc: Tom Rini , Aristo Chen , Rasmus Villemoes , Marek Vasut , Simon Glass , Paul HENRYS , Heinrich Schuchardt , Shiji Yang , Anton Moryakov , Alper Nebi Yasak , Alice Guo , Bryan Brattlof , Quentin Schulz X-Mailer: b4 0.14.3 X-Infomaniak-Routing: alpha 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: Quentin Schulz This adds support for using an OpenSSL engine for signing a FIT image. To use it, one should set the fit,sign-engine property at the FIT node level with the engine to use. This will in turn call mkimage with the -N option. The key-name-hint property in the signature node will be used verbatim as key_id in OpenSSL engine API. We could somehow still decide to pass some keys_dir to mkimage when signing with an engine is enabled (mkimage does support that!), unfortunately binman resolves key paths absolutely. I don't believe an OpenSSL engine will happen to have the exact same key_id than the path to the encryption key, so fit,encrypt and fit,sign-engine cannot cohabit. The public key (with .crt extension) is still required if it needs to be embedded in the SPL DTB for example. Signed-off-by: Quentin Schulz --- tools/binman/entries.rst | 22 +++++++++++++++++++--- tools/binman/etype/fit.py | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index 8922d6cd070..7b162a3edb8 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -885,9 +885,10 @@ The top-level 'fit' node supports the following special properties: fit,sign Enable signing FIT images via mkimage as described in - verified-boot.rst. If the property is found, the private keys path - is detected among binman include directories and passed to mkimage - via -k flag. All the keys required for signing FIT must be + verified-boot.rst. + If the property is found and fit,sign-engine is not set, the private + keys path is detected among binman include directories and passed to + mkimage via -k flag. All the keys required for signing FIT must be available at time of signing and must be located in single include directory. @@ -898,6 +899,21 @@ The top-level 'fit' node supports the following special properties: required for encrypting the FIT must be available at the time of encrypting and must be located in a single include directory. + Incompatible with fit,sign-engine. + + fit,sign-engine + Indicates the OpenSSL engine to use for signing the FIT image. This + is passed to mkimage via the `-N` flag. Example:: + + fit,sign-engine = "my-engine"; + + No `-k` argument will be passed to mkimage. The key_id passed to the + OpenSSL engine API is the verbatim value of the key-name-hint property. + + Depends on fit,sign. + + Incompatible with fit,encrypt. + Substitutions ~~~~~~~~~~~~~ diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py index db40479d30e..df4cc9b749c 100644 --- a/tools/binman/etype/fit.py +++ b/tools/binman/etype/fit.py @@ -104,9 +104,10 @@ class Entry_fit(Entry_section): fit,sign Enable signing FIT images via mkimage as described in - verified-boot.rst. If the property is found, the private keys path - is detected among binman include directories and passed to mkimage - via -k flag. All the keys required for signing FIT must be + verified-boot.rst. + If the property is found and fit,sign-engine is not set, the private + keys path is detected among binman include directories and passed to + mkimage via -k flag. All the keys required for signing FIT must be available at time of signing and must be located in single include directory. @@ -117,6 +118,21 @@ class Entry_fit(Entry_section): required for encrypting the FIT must be available at the time of encrypting and must be located in a single include directory. + Incompatible with fit,sign-engine. + + fit,sign-engine + Indicates the OpenSSL engine to use for signing the FIT image. This + is passed to mkimage via the `-N` flag. Example:: + + fit,sign-engine = "my-engine"; + + No `-k` argument will be passed to mkimage. The key_id passed to the + OpenSSL engine API is the verbatim value of the key-name-hint property. + + Depends on fit,sign. + + Incompatible with fit,encrypt. + Substitutions ~~~~~~~~~~~~~ @@ -620,7 +636,24 @@ class Entry_fit(Entry_section): args.update({'align': fdt_util.fdt32_to_cpu(align.value)}) if (self._fit_props.get('fit,sign') is not None or self._fit_props.get('fit,encrypt') is not None): - args.update({'keys_dir': self._get_keys_dir(data)}) + engine = None + if self._fit_props.get('fit,sign') is not None: + engine_prop = self._fit_props.get('fit,sign-engine') + if engine_prop is not None: + engine = engine_prop.value + args.update({'engine': engine}) + # Don't pass a key-dir to mkimage in case an engine is used to sign + # as we don't need a private key on storage anyway. + # Additionally, binman pass an absolute path as keys_dir which is + # highly unlikely to actually make sense for engines. + # Because of that limitation, we currently cannot support at the + # same time fit,encrypt and fit,sign-engine. + # mkimage will read key-name-hint and pass it verbatim to the engine + # as key_id in the OpenSSL engine API instead. + if engine is None: + args.update({'keys_dir': self._get_keys_dir(data)}) + elif self._fit_props.get('fit,encrypt') is not None: + self.Raise('Cannot have both fit,encrypt and fit,sign-engine') if self.mkimage.run(reset_timestamp=True, output_fname=output_fname, **args) is None: if not self.GetAllowMissing(): -- 2.51.0