From: Quentin Schulz <foss+uboot@0leil.net>
To: u-boot@lists.denx.de
Cc: Tom Rini <trini@konsulko.com>,
Aristo Chen <jj251510319013@gmail.com>,
Rasmus Villemoes <ravi@prevas.dk>,
Marek Vasut <marek.vasut+renesas@mailbox.org>,
Simon Glass <sjg@chromium.org>,
Paul HENRYS <paul.henrys_ext@softathome.com>,
Heinrich Schuchardt <xypron.glpk@gmx.de>,
Shiji Yang <yangshiji66@outlook.com>,
Anton Moryakov <ant.v.moryakov@gmail.com>,
Alper Nebi Yasak <alpernebiyasak@gmail.com>,
Alice Guo <alice.guo@nxp.com>, Bryan Brattlof <bb@ti.com>,
Wolfgang Wallner <wolfgang.wallner@br-automation.com>,
Peter Robinson <pbrobinson@gmail.com>,
Eddie Kovsky <ekovsky@redhat.com>,
Kever Yang <kever.yang@rock-chips.com>,
Yannic Moog <y.moog@phytec.de>,
Quentin Schulz <quentin.schulz@cherry.de>
Subject: [PATCH v3 3/4] tools: binman: fit: add support for OpenSSL engines
Date: Fri, 21 Nov 2025 18:14:59 +0100 [thread overview]
Message-ID: <20251121-binman-engine-v3-3-b80180aaa783@cherry.de> (raw)
In-Reply-To: <20251121-binman-engine-v3-0-b80180aaa783@cherry.de>
From: Quentin Schulz <quentin.schulz@cherry.de>
This adds support for using an OpenSSL engine for signing a FIT image.
To use it, one should set the fit,engine property at the FIT node level
with the engine to use. This will in turn call mkimage with the -N
option.
The -k argument to mkimage can be specified via fit,engine-keydir. If
not specified, -k is not passed to mkimage. This property is especially
useful for pkcs11 engine to specify slots, token label, etc...
As far as I could tell, mkimage encrypts and signs a FIT in one go, thus
the -k argument applies to both signing and encrypting. Considering we
reuse the -k argument for two different meanings (info to pass to the
engine when using an engine otherwise the directory where keys are
stored), we cannot reasonably encrypt using local keys and signing with
an engine, hence the enforced check. I believe it should be possible to
support encrypting and signing with the same engine (using different
key pairs of course, via different key-name-hint likely), but this is
left for the next person to implement.
This is why the property is named fit,engine and not fit,sign-engine.
Ditto for fit,engine-keydir.
The public key (with .crt extension) is still required if it needs to be
embedded in the SPL DTB for example. We could probably support
retrieving the public key from an engine, but this is a change to make
to fdt_add_pubkey.c.
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
tools/binman/entries.rst | 54 +++++++++++++++++++++++++--
tools/binman/etype/fit.py | 93 +++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 140 insertions(+), 7 deletions(-)
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 8922d6cd070..a81fcbd3891 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,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,53 @@ 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,engine.
+
+ fit,engine
+ Indicates the OpenSSL engine to use for signing the FIT image. This
+ is passed to mkimage via the `-N` flag. Example::
+
+ fit,engine = "my-engine";
+
+ A `-k` argument for mkimage may be passed via `fit,engine-keydir`.
+
+ When `fit,engine` is set to `pkcs11`, the following applies:
+
+ - If `fit,engine-keydir` is absent, the value of `key-name-hint` is
+ prefixed with `pkcs11:object=` before being passed to the OpenSSL
+ engine API::
+
+ pkcs11:object=<key-name-hint>
+
+ - If `fit,engine-keydir` contains either `object=` or `id=`, its
+ value is passed verbatim to the OpenSSL engine API,
+
+ - Otherwise, the value of `fit,engine-keydir` is followed by
+ `;object=` and the value of `key-name-hint` before being passed
+ to the OpenSSL engine API::
+
+ <fit,engine-keydir>;object=<key-name-hint>
+
+ If `fit,engine` is set to something different than `pkcs11`, the
+ value of `key-name-hint` (prefixed with the value of
+ `fit,engine-keydir` if present) and passed verbatim to the OpenSSL
+ engine API.
+
+ Depends on fit,sign.
+
+ Incompatible with fit,encrypt.
+
+ fit,engine-keydir
+ Indicates the `-k` argument to pass to mkimage if an OpenSSL engine
+ is to be used for signing the FIT image. Example::
+
+ fit,engine-keydir = "pkcs11:model=xxx;manufacturer=xxx";
+
+ Read `fit,engine` documentation for more info on special cases when
+ using `pkcs11` as engine.
+
+ Depends on fit,engine.
+
Substitutions
~~~~~~~~~~~~~
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index db40479d30e..f28b1e6b4cb 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,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,53 @@ 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,engine.
+
+ fit,engine
+ Indicates the OpenSSL engine to use for signing the FIT image. This
+ is passed to mkimage via the `-N` flag. Example::
+
+ fit,engine = "my-engine";
+
+ A `-k` argument for mkimage may be passed via `fit,engine-keydir`.
+
+ When `fit,engine` is set to `pkcs11`, the following applies:
+
+ - If `fit,engine-keydir` is absent, the value of `key-name-hint` is
+ prefixed with `pkcs11:object=` before being passed to the OpenSSL
+ engine API::
+
+ pkcs11:object=<key-name-hint>
+
+ - If `fit,engine-keydir` contains either `object=` or `id=`, its
+ value is passed verbatim to the OpenSSL engine API,
+
+ - Otherwise, the value of `fit,engine-keydir` is followed by
+ `;object=` and the value of `key-name-hint` before being passed to
+ the OpenSSL engine API::
+
+ <fit,engine-keydir>;object=<key-name-hint>
+
+ If `fit,engine` is set to something different than `pkcs11`, the
+ value of `key-name-hint` (prefixed with the value of
+ `fit,engine-keydir` if present) and passed verbatim to the OpenSSL
+ engine API.
+
+ Depends on fit,sign.
+
+ Incompatible with fit,encrypt.
+
+ fit,engine-keydir
+ Indicates the `-k` argument to pass to mkimage if an OpenSSL engine
+ is to be used for signing the FIT image. Example::
+
+ fit,engine-keydir = "pkcs11:model=xxx;manufacturer=xxx";
+
+ Read `fit,engine` documentation for more info on special cases when
+ using `pkcs11` as engine.
+
+ Depends on fit,engine.
+
Substitutions
~~~~~~~~~~~~~
@@ -588,6 +636,29 @@ class Entry_fit(Entry_section):
return paths[0] if len(paths) else None
+ def _get_fit_engine(self):
+ """Detect whether an OpenSSL engine is to be used for the FIT
+
+ Returns:
+ Tuple(str, str): Name of the engine to use, as first element of the
+ Tuple. None if no engine to use.
+ keydir arguments to pass with the engine to the
+ OpenSSL API, as second element of the Tuple. None
+ if no keydir to pass.
+ """
+ engine = None
+ engine_keydir = None
+
+ prop = self._fit_props.get('fit,engine')
+ if prop is not None:
+ engine = prop.value
+
+ prop = self._fit_props.get('fit,engine-keydir')
+ if prop is not None:
+ engine_keydir = prop.value
+
+ return engine, engine_keydir
+
def BuildSectionData(self, required):
"""Build FIT entry contents
@@ -620,7 +691,21 @@ 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
+ keydir = None
+
+ # Engine only supported for signing for now
+ if self._fit_props.get('fit,sign') is not None:
+ engine, keydir = self._get_fit_engine()
+
+ args.update({'engine': engine})
+ # If no engine, keys must exist locally, find them
+ if engine is None:
+ keydir = self._get_keys_dir(data)
+ elif self._fit_props.get('fit,encrypt') is not None:
+ self.Raise('fit,engine currently does not support encryption')
+
+ args.update({'keys_dir': keydir})
if self.mkimage.run(reset_timestamp=True, output_fname=output_fname,
**args) is None:
if not self.GetAllowMissing():
--
2.51.1
next prev parent reply other threads:[~2025-11-21 17:15 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-21 17:14 [PATCH v3 0/4] fit: allow signing with an OpenSSL engine Quentin Schulz
2025-11-21 17:14 ` [PATCH v3 1/4] fit: support signing with only an engine_id Quentin Schulz
2025-11-21 17:14 ` [PATCH v3 2/4] tools: binman: mkimage: add support for passing the engine Quentin Schulz
2025-11-21 17:14 ` Quentin Schulz [this message]
2025-11-25 22:15 ` [PATCH v3 3/4] tools: binman: fit: add support for OpenSSL engines Simon Glass
2025-11-26 11:28 ` Quentin Schulz
2025-11-21 17:15 ` [PATCH v3 4/4] tools: binman: fit: add tests for signing with an OpenSSL engine Quentin Schulz
2025-11-25 22:15 ` Simon Glass
2025-11-26 11:44 ` Quentin Schulz
2025-12-02 20:06 ` Simon Glass
2025-12-02 20:14 ` Tom Rini
2025-12-04 11:52 ` Quentin Schulz
2025-12-04 14:25 ` Tom Rini
2025-12-10 12:32 ` Simon Glass
2025-12-04 11:50 ` Quentin Schulz
2025-12-10 12:32 ` Simon Glass
2025-12-10 14:29 ` Tom Rini
2025-12-07 14:04 ` [PATCH v3 0/4] fit: allow " Tom Rini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251121-binman-engine-v3-3-b80180aaa783@cherry.de \
--to=foss+uboot@0leil.net \
--cc=alice.guo@nxp.com \
--cc=alpernebiyasak@gmail.com \
--cc=ant.v.moryakov@gmail.com \
--cc=bb@ti.com \
--cc=ekovsky@redhat.com \
--cc=jj251510319013@gmail.com \
--cc=kever.yang@rock-chips.com \
--cc=marek.vasut+renesas@mailbox.org \
--cc=paul.henrys_ext@softathome.com \
--cc=pbrobinson@gmail.com \
--cc=quentin.schulz@cherry.de \
--cc=ravi@prevas.dk \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
--cc=wolfgang.wallner@br-automation.com \
--cc=xypron.glpk@gmx.de \
--cc=y.moog@phytec.de \
--cc=yangshiji66@outlook.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox