Hi Lorenz,
On 2026-09-17T06:55:42, Lorenz Kofler <[email protected]> wrote:
> binman: pre-load: Test signing with an OpenSSL engine
>
> Add a test that signs a pre-load header through the pkcs11 engine, with a
> key imported into SoftHSM, like the existing FIT signature tests. It is
> skipped when softhsm2-util is not installed.
>
> Assisted-by: Claude:claude-opus-5
> Signed-off-by: Lorenz Kofler <[email protected]>
>
> tools/binman/ftest.py | 79 ++++++++++++++++++++++
> .../test/security/pre_load_engine_pkcs11.dts | 24 +++++++
> .../test/security/pre_load_engine_pkcs11_pss.dts | 24 +++++++
> 3 files changed, 127 insertions(+)
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> @@ -5937,6 +5937,85 @@ fdt fdtmap Extract the
> devicetree blob from the fdtmap
> + def _SetupPreLoadEngine(self, prefix):
> + """Set up a SoftHSM token holding the key used by the engine tests
...
> + softhsm2_util = bintool.Bintool.create('softhsm2_util')
> + self._CheckBintool(softhsm2_util)
> +
> + try:
> + tools.run('openssl', 'engine', 'dynamic', '-c', 'pkcs11')
> + except ValueError:
> + self.skipTest('PKCS11 engine setup not functional, '
> + 'did you install libengine-pkcs11-openssl?')
> +
> + data = tools.read_file(self.TestFile('fit/softhsm2.conf'))
> + softhsm2_conf = self._MakeInputFile(f'{prefix}softhsm2.conf', data)
> + softhsm2_tokens_dir = self._MakeInputDir(f'{prefix}softhsm2.tokens')
> +
> + with open(softhsm2_conf, 'a') as f:
> + f.write(f'directories.tokendir = {softhsm2_tokens_dir}\n')
You could use tools.write_file() here if you like
> +
> + with unittest.mock.patch.dict('os.environ',
> + {'SOFTHSM2_CONF': softhsm2_conf}):
> + softhsm2_util.run_cmd('--init-token', '--free', '--label',
> + 'U-Boot token', '--pin', '1111',
> + '--so-pin', '222222')
> + softhsm2_util.run_cmd('--import', self.TestFile('dev.key'),
> + '--token', 'U-Boot token', '--label',
> + 'test_key', '--id', '999999', '--pin',
> '1111')
Nearly identical to the SoftHSM setup open-coded in
testFitSignPKCS11Simple() and testFitSignPKCS11Object() (and the CI
capsule tests). Please can you factor this out to a shared
_SetupSoftHsm() helper on the base class and have both the FIT and
pre-load tests call it? Otherwise the third copy will drift from the
first two.
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> @@ -5937,6 +5937,85 @@ fdt fdtmap Extract the
> devicetree blob from the fdtmap
> + def testPreLoadEnginePkcs11(self):
> + """Test a pre-load header signed through the pkcs11 OpenSSL engine"""
> + softhsm2_conf = self._SetupPreLoadEngine('testPreLoadEnginePkcs11.')
> + self._CheckPreLoadEngine('security/pre_load_engine_pkcs11.dts',
> + softhsm2_conf, 'pkcs-1.5')
> +
> + def testPreLoadEnginePkcs11Pss(self):
> + """Test a pre-load header signed through the engine with pss
> padding"""
> + softhsm2_conf =
> self._SetupPreLoadEngine('testPreLoadEnginePkcs11Pss.')
> + self._CheckPreLoadEngine('security/pre_load_engine_pkcs11_pss.dts',
> + softhsm2_conf, 'pss')
Both DTS files use the bare key-name = "test_key" form, so only the
URI-expansion branch of _sign_engine() is exercised. The docstring in
2/3 documents key-name = "pkcs11:object=preload;type=private" as
supported - please add a case using a full PKCS#11 URI so the
startswith('pkcs11:') branch is covered.
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> @@ -5937,6 +5937,85 @@ fdt fdtmap Extract the
> devicetree blob from the fdtmap
> + def testPreLoadEngineMissingOpenssl(self):
> + """Test that a missing openssl is reported when using an engine"""
> + with terminal.capture() as (_, stderr):
> + self._DoTestFile('security/pre_load_engine_pkcs11.dts',
> + force_missing_bintools='openssl')
> + err = stderr.getvalue()
> + self.assertRegex(err, "Image 'image'.*missing bintools.*: openssl")
Nothing covers the new 'if self.engine and len(sig) !=
RSAS[sign_name]' check from patch 2 - with openssl forced missing the
stub signature is exactly RSAS[sign_name] bytes so the check never
fires. Please add a case where the engine returns a signature of the
wrong size (e.g. by mocking Bintoolopenssl.sign() to return a shorter
buffer) and assert that "don't have the expected size" is raised.
> diff --git a/tools/binman/test/security/pre_load_engine_pkcs11.dts
> b/tools/binman/test/security/pre_load_engine_pkcs11.dts
> @@ -0,0 +1,24 @@
> + pre-load {
> + content = <&image>;
> + algo-name = "sha256,rsa2048";
> + padding-name = "pkcs-1.5";
> + key-name = "test_key";
> + engine = "pkcs11";
> + header-size = <4096>;
> + version = <0x11223344>;
> + };
The two DTS files differ only in padding-name. Since
_CheckPreLoadEngine() already parametrises padding, please keep a
single DTS and inject the padding via an entry arg or a small template
rather than carrying two near-identical files.
Regards,
Simon