From: Quentin Schulz <[email protected]> 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 <[email protected]> --- 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

