[PATCH 3/3] tools: binman: fit: add support for OpenSSL engines

Peter Robinson pbrobinson at gmail.com
Mon Nov 3 17:21:40 CET 2025


Hey Quentin,

> 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.

Just to be aware this should likely be a OpenSSL provider, engines in
OpenSSL are deprecated and due to be removed in 4.0. A lot of distros
are already dropping support for engines. There's a patch [1] adding
support for Providers support to U-Boot, I suspect we shouldn't be
adding more deps on the Engine support. OpenSSL 4 is due in March.

[1] https://lists.denx.de/pipermail/u-boot/2025-October/601616.html
[2] https://openssl-library.org/roadmap/index.html

> 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 <quentin.schulz at cherry.de>
> ---
>  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
>


More information about the U-Boot mailing list