summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojciech Dubowik <[email protected]>2026-02-20 10:15:16 +0100
committerSimon Glass <[email protected]>2026-03-18 06:14:17 -0600
commite73443167be055c646dfd7d5a79bc30ac33e31d5 (patch)
tree1ec17cb80fc58b6cab471efc3243f9ec687ffd2a
parente2c46d33cfbb92f493b520524a099fdf9af0a056 (diff)
test: binman: Add test for pkcs11 signed capsule
Test pkcs11 URI support for UEFI capsule generation. Both public certificate and private key are used over pkcs11 protocol. Pkcs11-tool has been introduced as softhsm tool doesn't have functionality to import certificates in commonly distributed version (only in the latest). Signed-off-by: Wojciech Dubowik <[email protected]> Reviewed-by: Simon Glass <[email protected]>
-rw-r--r--tools/binman/btool/p11_kit.py21
-rw-r--r--tools/binman/btool/pkcs11_tool.py21
-rw-r--r--tools/binman/ftest.py73
-rw-r--r--tools/binman/test/capsule/signed_pkcs11.dts22
4 files changed, 137 insertions, 0 deletions
diff --git a/tools/binman/btool/p11_kit.py b/tools/binman/btool/p11_kit.py
new file mode 100644
index 00000000000..9d8d5d848b4
--- /dev/null
+++ b/tools/binman/btool/p11_kit.py
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright 2026 Mettler Toledo Technologies GmbH
+#
+"""Bintool implementation for p11-kit"""
+
+from binman import bintool
+
+
+class Bintoolp11_kit(bintool.Bintool):
+ """p11-kit -- support tool for pkcs#11 libraries"""
+ def __init__(self, name):
+ super().__init__('p11-kit',
+ 'Pkcs11 library modules tool',
+ version_args='list modules')
+
+ def fetch(self, method):
+ """Install p11-kit via APT """
+ if method != bintool.FETCH_BIN:
+ return None
+
+ return self.apt_install('p11-kit')
diff --git a/tools/binman/btool/pkcs11_tool.py b/tools/binman/btool/pkcs11_tool.py
new file mode 100644
index 00000000000..673c0ea0ac3
--- /dev/null
+++ b/tools/binman/btool/pkcs11_tool.py
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright 2026 Mettler Toledo Technologies GmbH
+#
+"""Bintool implementation for pkcs11-tool"""
+
+from binman import bintool
+
+
+class Bintoolpkcs11_tool(bintool.Bintool):
+ """pkcs11-tool -- support tool for managing pkcs#11 tokens"""
+ def __init__(self, name):
+ super().__init__('pkcs11-tool',
+ 'PKCS #11 tokens managing tool',
+ version_args='--show-info')
+
+ def fetch(self, method):
+ """Install opensc via APT """
+ if method != bintool.FETCH_BIN:
+ return None
+
+ return self.apt_install('opensc')
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 9cc1a97f95c..ca5149ee654 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -7,6 +7,7 @@
# python -m unittest func_test.TestFunctional.testHelp
import collections
+import configparser
import glob
import gzip
import hashlib
@@ -7532,6 +7533,78 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self._CheckCapsule(data, signed_capsule=True)
+ def testPkcs11SignedCapsuleGen(self):
+ """Test generation of EFI capsule (with PKCS11)"""
+ data = tools.read_file(self.TestFile("security/key.key"))
+ private_key = self._MakeInputFile("key.key", data)
+ data = tools.read_file(self.TestFile("security/key.pem"))
+ cert_file = self._MakeInputFile("key.crt", data)
+
+ softhsm2_util = bintool.Bintool.create('softhsm2_util')
+ self._CheckBintool(softhsm2_util)
+
+ pkcs11_tool = bintool.Bintool.create('pkcs11-tool')
+ self._CheckBintool(pkcs11_tool)
+
+ prefix = "testPkcs11SignedCapsuleGen."
+ # Configure SoftHSMv2
+ 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')
+
+ # Find the path to softhsm2 library
+ p11_kit = bintool.Bintool.create('p11-kit')
+ self._CheckBintool(p11_kit)
+
+ p11_kit_config = configparser.ConfigParser()
+ out = tools.run('p11-kit', 'print-config')
+ p11_kit_config.read_string(out)
+ softhsm2_lib = p11_kit_config.get('softhsm2', 'module',
+ fallback=None)
+ self.assertIsNotNone(softhsm2_lib)
+
+ with unittest.mock.patch.dict('os.environ',
+ {'SOFTHSM2_CONF': softhsm2_conf,
+ 'PKCS11_MODULE_PATH': softhsm2_lib}):
+ tools.run('softhsm2-util', '--init-token', '--free', '--label',
+ 'U-Boot token', '--pin', '1111', '--so-pin',
+ '222222')
+ tools.run('pkcs11-tool', '--module', softhsm2_lib,
+ '--write-object', cert_file, '--pin', '1111',
+ '--type', 'cert', '--id', '999999', '--label',
+ 'test_cert', '--login')
+ tools.run('softhsm2-util', '--import', private_key, '--token',
+ 'U-Boot token', '--label', 'test_key', '--id', '999999',
+ '--pin', '1111')
+ data = self._DoReadFile('capsule/signed_pkcs11.dts')
+
+ self._CheckCapsule(data, signed_capsule=True)
+
+ hdr = self._GetCapsuleHeaders(data)
+ monotonic_count = hdr['EFI_FIRMWARE_IMAGE_AUTH.MONOTONIC_COUNT']
+
+ # UEFI standard requires that signature is checked over payload followed
+ # by a monotonic count as little endian 64-bit integer.
+ sig_input = self._MakeInputFile("sig_input", EFI_CAPSULE_DATA)
+ with open(sig_input, 'ab') as f:
+ f.write(struct.pack('<Q', int(monotonic_count, 16)))
+
+ # Verify dumped capsule signature dumped by meficapsule during
+ # generation
+ openssl = bintool.Bintool.create('openssl')
+ self._CheckBintool(openssl)
+ openssl_args = ['smime', '-verify', '-inform', 'DER',
+ '-in', tools.get_output_filename('capsule.efi-capsule.p7'),
+ '-content', sig_input, '-CAfile', cert_file,
+ '-no_check_time',
+ '-out', tools.get_output_filename('decoded-capsule.bin')]
+ result = openssl.run_cmd_result(*openssl_args)
+ self.assertIsNotNone(result.stdout)
+ self.assertIn('Verification successful', result.stderr)
+
def testCapsuleGenVersionSupport(self):
"""Test generation of EFI capsule with version support"""
data = self._DoReadFile('capsule/version.dts')
diff --git a/tools/binman/test/capsule/signed_pkcs11.dts b/tools/binman/test/capsule/signed_pkcs11.dts
new file mode 100644
index 00000000000..bb87e18a15f
--- /dev/null
+++ b/tools/binman/test/capsule/signed_pkcs11.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ binman {
+ efi-capsule {
+ image-index = <0x1>;
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ hardware-instance = <0x0>;
+ monotonic-count = <0x1>;
+ dump-signature;
+ private-key = "pkcs11:token=U-Boot%20token;object=test_key;type=private;pin-value=1111";
+ public-key-cert = "pkcs11:token=U-Boot%20token;object=test_cert;type=cert;pin-value=1111";
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};