* [PATCH v5 1/6] tools: mkeficapsule: Add support for pkcs11
2026-01-28 8:05 [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Wojciech Dubowik
@ 2026-01-28 8:05 ` Wojciech Dubowik
2026-02-13 12:56 ` Ilias Apalodimas
2026-01-28 8:05 ` [PATCH v5 2/6] binman: Accept pkcs11 URI tokens for capsule updates Wojciech Dubowik
` (5 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Wojciech Dubowik @ 2026-01-28 8:05 UTC (permalink / raw)
To: u-boot; +Cc: Wojciech Dubowik, trini, simon.glass, quentin.schulz
With pkcs11 support it's now possible to specify keys
with URI format. To use this feature the filename must
begin "pkcs11:.." and have valid URI pointing to certificate
and private key in HSM.
The environment variable PKCS11_MODULE_PATH must point to the
right pkcs11 provider i.e. with softhsm:
export PKCS11_MODULE_PATH=<path>/libsofthsm2.so
Example command line:
tools/mkeficapsule --monotonic-count 1 \
--private-key "pkcs11:token=EX;object=capsule;type=private;pin-source=pin.txt" \
--certificate "pkcs11:token=EX;object=capsule;type=cert;pin-source=pin.txt" \
--index 1 \
--guid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX \
"capsule-payload" \
"capsule.cap"
Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
---
tools/mkeficapsule.c | 110 +++++++++++++++++++++++++++++++++----------
1 file changed, 84 insertions(+), 26 deletions(-)
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 0f41cdb64f54..a61557b73bef 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -228,21 +228,54 @@ static int create_auth_data(struct auth_context *ctx)
gnutls_pkcs7_t pkcs7;
gnutls_datum_t data;
gnutls_datum_t signature;
+ gnutls_pkcs11_obj_t *obj_list;
+ unsigned int obj_list_size = 0;
+ const char *lib;
int ret;
+ bool pkcs11_cert = false;
+ bool pkcs11_key = false;
- ret = read_bin_file(ctx->cert_file, &cert.data, &file_size);
- if (ret < 0)
- return -1;
- if (file_size > UINT_MAX)
- return -1;
- cert.size = file_size;
+ if (!strncmp(ctx->cert_file, "pkcs11:", 7))
+ pkcs11_cert = true;
- ret = read_bin_file(ctx->key_file, &key.data, &file_size);
- if (ret < 0)
- return -1;
- if (file_size > UINT_MAX)
- return -1;
- key.size = file_size;
+ if (!strncmp(ctx->key_file, "pkcs11:", 7))
+ pkcs11_key = true;
+
+ if (pkcs11_cert || pkcs11_key) {
+ lib = getenv("PKCS11_MODULE_PATH");
+ if (!lib) {
+ fprintf(stdout,
+ "PKCS11_MODULE_PATH not set in the environment\n");
+ return -1;
+ }
+
+ gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+ gnutls_global_init();
+
+ ret = gnutls_pkcs11_add_provider(lib, "trusted");
+ if (ret < 0) {
+ fprintf(stdout, "Failed to add pkcs11 provider\n");
+ return -1;
+ }
+ }
+
+ if (!pkcs11_cert) {
+ ret = read_bin_file(ctx->cert_file, &cert.data, &file_size);
+ if (ret < 0)
+ return -1;
+ if (file_size > UINT_MAX)
+ return -1;
+ cert.size = file_size;
+ }
+
+ if (!pkcs11_key) {
+ ret = read_bin_file(ctx->key_file, &key.data, &file_size);
+ if (ret < 0)
+ return -1;
+ if (file_size > UINT_MAX)
+ return -1;
+ key.size = file_size;
+ }
/*
* For debugging,
@@ -265,22 +298,42 @@ static int create_auth_data(struct auth_context *ctx)
return -1;
}
- /* load a private key */
- ret = gnutls_privkey_import_x509_raw(pkey, &key, GNUTLS_X509_FMT_PEM,
- 0, 0);
- if (ret < 0) {
- fprintf(stderr,
- "error in gnutls_privkey_import_x509_raw(): %s\n",
- gnutls_strerror(ret));
- return -1;
+ /* load x509 certificate */
+ if (pkcs11_cert) {
+ ret = gnutls_pkcs11_obj_list_import_url4(&obj_list, &obj_list_size,
+ ctx->cert_file, 0);
+ if (ret < 0 || obj_list_size == 0) {
+ fprintf(stdout, "Failed to import crt_file URI objects\n");
+ return -1;
+ }
+
+ gnutls_x509_crt_import_pkcs11(x509, obj_list[0]);
+ } else {
+ ret = gnutls_x509_crt_import(x509, &cert, GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ fprintf(stderr, "error in gnutls_x509_crt_import(): %s\n",
+ gnutls_strerror(ret));
+ return -1;
+ }
}
- /* load x509 certificate */
- ret = gnutls_x509_crt_import(x509, &cert, GNUTLS_X509_FMT_PEM);
- if (ret < 0) {
- fprintf(stderr, "error in gnutls_x509_crt_import(): %s\n",
- gnutls_strerror(ret));
- return -1;
+ /* load a private key */
+ if (pkcs11_key) {
+ ret = gnutls_privkey_import_pkcs11_url(pkey, ctx->key_file);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d: %s\n", __LINE__,
+ gnutls_strerror(ret));
+ return -1;
+ }
+ } else {
+ ret = gnutls_privkey_import_x509_raw(pkey, &key, GNUTLS_X509_FMT_PEM,
+ 0, 0);
+ if (ret < 0) {
+ fprintf(stderr,
+ "error in gnutls_privkey_import_x509_raw(): %s\n",
+ gnutls_strerror(ret));
+ return -1;
+ }
}
/* generate a PKCS #7 structure */
@@ -349,6 +402,11 @@ static int create_auth_data(struct auth_context *ctx)
* gnutls_free(signature.data);
*/
+ if (pkcs11_cert || pkcs11_key) {
+ gnutls_global_deinit();
+ gnutls_pkcs11_deinit();
+ }
+
return 0;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v5 1/6] tools: mkeficapsule: Add support for pkcs11
2026-01-28 8:05 ` [PATCH v5 1/6] tools: mkeficapsule: Add support for pkcs11 Wojciech Dubowik
@ 2026-02-13 12:56 ` Ilias Apalodimas
2026-02-16 9:01 ` EXTERNAL - " Wojciech Dubowik
0 siblings, 1 reply; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-13 12:56 UTC (permalink / raw)
To: Wojciech Dubowik, simon.glass, u-boot; +Cc: trini, quentin.schulz
Hi Wojciech,
On Wed Jan 28, 2026 at 10:05 AM EET, Wojciech Dubowik wrote:
> With pkcs11 support it's now possible to specify keys
> with URI format. To use this feature the filename must
> begin "pkcs11:.." and have valid URI pointing to certificate
> and private key in HSM.
>
> The environment variable PKCS11_MODULE_PATH must point to the
> right pkcs11 provider i.e. with softhsm:
> export PKCS11_MODULE_PATH=<path>/libsofthsm2.so
>
>
[...]
> - ret = read_bin_file(ctx->cert_file, &cert.data, &file_size);
> - if (ret < 0)
> - return -1;
> - if (file_size > UINT_MAX)
> - return -1;
> - cert.size = file_size;
> + if (!strncmp(ctx->cert_file, "pkcs11:", 7))
Can we do strlen() instead of 7 ?
> + pkcs11_cert = true;
>
> - ret = read_bin_file(ctx->key_file, &key.data, &file_size);
> - if (ret < 0)
> - return -1;
> - if (file_size > UINT_MAX)
> - return -1;
> - key.size = file_size;
> + if (!strncmp(ctx->key_file, "pkcs11:", 7))
Same
> + pkcs11_key = true;
> +
> + if (pkcs11_cert || pkcs11_key) {
Don't you need both the cert & key to sign the capsule?
I'd simplify the logic here. Instead of having both a pkcs_key and a pkcs_cert,
replace the variables with is_pcks and have that set to true if both the key
and cert have been found.
Then the if/else cases later will become a bit easier to read since you'll have
to load the private key & crt on a single if/else cases depending on is_pkcs.
> + lib = getenv("PKCS11_MODULE_PATH");
> + if (!lib) {
[...]
Thanks
/Ilias
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: EXTERNAL - [PATCH v5 1/6] tools: mkeficapsule: Add support for pkcs11
2026-02-13 12:56 ` Ilias Apalodimas
@ 2026-02-16 9:01 ` Wojciech Dubowik
2026-02-16 9:52 ` Ilias Apalodimas
0 siblings, 1 reply; 15+ messages in thread
From: Wojciech Dubowik @ 2026-02-16 9:01 UTC (permalink / raw)
To: Ilias Apalodimas; +Cc: simon.glass, u-boot, trini, quentin.schulz
On Fri, Feb 13, 2026 at 02:56:48PM +0200, Ilias Apalodimas wrote:
Hi Ilias,
> Hi Wojciech,
>
> On Wed Jan 28, 2026 at 10:05 AM EET, Wojciech Dubowik wrote:
> > With pkcs11 support it's now possible to specify keys
> > with URI format. To use this feature the filename must
> > begin "pkcs11:.." and have valid URI pointing to certificate
> > and private key in HSM.
> >
> > The environment variable PKCS11_MODULE_PATH must point to the
> > right pkcs11 provider i.e. with softhsm:
> > export PKCS11_MODULE_PATH=<path>/libsofthsm2.so
> >
> >
>
> [...]
>
> > - ret = read_bin_file(ctx->cert_file, &cert.data, &file_size);
> > - if (ret < 0)
> > - return -1;
> > - if (file_size > UINT_MAX)
> > - return -1;
> > - cert.size = file_size;
> > + if (!strncmp(ctx->cert_file, "pkcs11:", 7))
>
> Can we do strlen() instead of 7 ?
Will do in the next iteration.
>
> > + pkcs11_cert = true;
> >
> > - ret = read_bin_file(ctx->key_file, &key.data, &file_size);
> > - if (ret < 0)
> > - return -1;
> > - if (file_size > UINT_MAX)
> > - return -1;
> > - key.size = file_size;
> > + if (!strncmp(ctx->key_file, "pkcs11:", 7))
>
> Same
>
> > + pkcs11_key = true;
> > +
> > + if (pkcs11_cert || pkcs11_key) {
>
> Don't you need both the cert & key to sign the capsule?
> I'd simplify the logic here. Instead of having both a pkcs_key and a pkcs_cert,
> replace the variables with is_pcks and have that set to true if both the key
> and cert have been found.
This is what I have done in the first iteration. Later I have learned that there
is a need for mixed pkcs11/local file usage. The HSM devices are very expensive
(at least some of them) and have limited memory. It's quite common to use private
key from HSM over pkcs11 protocol and all the public stuff locally.
The test is implemented so at the moment.
Regards,
Wojtek
>
> Then the if/else cases later will become a bit easier to read since you'll have
> to load the private key & crt on a single if/else cases depending on is_pkcs.
>
> > + lib = getenv("PKCS11_MODULE_PATH");
> > + if (!lib) {
>
> [...]
>
> Thanks
> /Ilias
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: EXTERNAL - [PATCH v5 1/6] tools: mkeficapsule: Add support for pkcs11
2026-02-16 9:01 ` EXTERNAL - " Wojciech Dubowik
@ 2026-02-16 9:52 ` Ilias Apalodimas
0 siblings, 0 replies; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-16 9:52 UTC (permalink / raw)
To: Wojciech Dubowik, simon.glass; +Cc: u-boot, trini, quentin.schulz
Hi Wojciech
[...]
> >
> > Can we do strlen() instead of 7 ?
>
> Will do in the next iteration.
Thanks
> >
> > > + pkcs11_cert = true;
> > >
> > > - ret = read_bin_file(ctx->key_file, &key.data, &file_size);
> > > - if (ret < 0)
> > > - return -1;
> > > - if (file_size > UINT_MAX)
> > > - return -1;
> > > - key.size = file_size;
> > > + if (!strncmp(ctx->key_file, "pkcs11:", 7))
> >
> > Same
> >
> > > + pkcs11_key = true;
> > > +
> > > + if (pkcs11_cert || pkcs11_key) {
> >
> > Don't you need both the cert & key to sign the capsule?
> > I'd simplify the logic here. Instead of having both a pkcs_key and a pkcs_cert,
> > replace the variables with is_pcks and have that set to true if both the key
> > and cert have been found.
> This is what I have done in the first iteration. Later I have learned that there
> is a need for mixed pkcs11/local file usage. The HSM devices are very expensive
> (at least some of them) and have limited memory. It's quite common to use private
> key from HSM over pkcs11 protocol and all the public stuff locally.
>
> The test is implemented so at the moment.
Yea that was one of the things I was thinking to justify why it's
implemented like that.
Since that's a requirement the code is fine as is.
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
>
> Regards,
> Wojtek
> >
> > Then the if/else cases later will become a bit easier to read since you'll have
> > to load the private key & crt on a single if/else cases depending on is_pkcs.
> >
> > > + lib = getenv("PKCS11_MODULE_PATH");
> > > + if (!lib) {
> >
> > [...]
> >
> > Thanks
> > /Ilias
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v5 2/6] binman: Accept pkcs11 URI tokens for capsule updates
2026-01-28 8:05 [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Wojciech Dubowik
2026-01-28 8:05 ` [PATCH v5 1/6] tools: mkeficapsule: Add support for pkcs11 Wojciech Dubowik
@ 2026-01-28 8:05 ` Wojciech Dubowik
2026-01-28 8:05 ` [PATCH v5 3/6] tools: mkeficapsule: Fix dump signature long option Wojciech Dubowik
` (4 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Wojciech Dubowik @ 2026-01-28 8:05 UTC (permalink / raw)
To: u-boot; +Cc: Wojciech Dubowik, trini, simon.glass, quentin.schulz
With pkcs11 support in mkeficapsule we can now accept URI
tokens and not only files.
Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
Reviewed-by: Simon Glass <simon.glass@canonical.com>
---
tools/binman/etype/efi_capsule.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py
index 9f06cc88e6e5..3b30c12ea514 100644
--- a/tools/binman/etype/efi_capsule.py
+++ b/tools/binman/etype/efi_capsule.py
@@ -125,10 +125,14 @@ class Entry_efi_capsule(Entry_section):
private_key = ''
public_key_cert = ''
if self.auth:
- if not os.path.isabs(self.private_key):
+ if not os.path.isabs(self.private_key) and not 'pkcs11:' in self.private_key:
private_key = tools.get_input_filename(self.private_key)
- if not os.path.isabs(self.public_key_cert):
+ if not os.path.isabs(self.public_key_cert) and not 'pkcs11:' in self.public_key_cert:
public_key_cert = tools.get_input_filename(self.public_key_cert)
+ if 'pkcs11:' in self.private_key:
+ private_key = self.private_key
+ if 'pkcs11:' in self.public_key_cert:
+ public_key_cert = self.public_key_cert
data, payload, uniq = self.collect_contents_to_file(
self._entries.values(), 'capsule_in')
outfile = self._filename if self._filename else 'capsule.%s' % uniq
--
2.47.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v5 3/6] tools: mkeficapsule: Fix dump signature long option
2026-01-28 8:05 [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Wojciech Dubowik
2026-01-28 8:05 ` [PATCH v5 1/6] tools: mkeficapsule: Add support for pkcs11 Wojciech Dubowik
2026-01-28 8:05 ` [PATCH v5 2/6] binman: Accept pkcs11 URI tokens for capsule updates Wojciech Dubowik
@ 2026-01-28 8:05 ` Wojciech Dubowik
2026-02-13 12:41 ` Ilias Apalodimas
2026-01-28 8:05 ` [PATCH v5 4/6] binman: Add dump signature option to mkeficapsule Wojciech Dubowik
` (3 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Wojciech Dubowik @ 2026-01-28 8:05 UTC (permalink / raw)
To: u-boot; +Cc: Wojciech Dubowik, trini, simon.glass, quentin.schulz
Only short option has been present. Also rename dump_sig
to dump-sig to match with other parameter names.
Fixes: 16abff246b40 ("tools: mkeficapsule: add firmware image signing")
Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
---
doc/mkeficapsule.1 | 4 ++--
tools/binman/btool/mkeficapsule.py | 2 +-
tools/mkeficapsule.c | 3 ++-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
index a726149ba2ce..d6653ec42472 100644
--- a/doc/mkeficapsule.1
+++ b/doc/mkeficapsule.1
@@ -121,8 +121,8 @@ Specify a monotonic count which is set to be monotonically incremented
at every firmware update.
.TP
-.B "-d\fR,\fB --dump_sig"
-Dump signature data into *.p7 file
+.B "-d\fR,\fB --dump-sig"
+Dump signature data into <capsule-file-name>.p7 file
.SH "GUIDGEN OPTIONS"
diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
index f7e5a8868495..f2ac654db81e 100644
--- a/tools/binman/btool/mkeficapsule.py
+++ b/tools/binman/btool/mkeficapsule.py
@@ -16,7 +16,7 @@ Options:
-p, --private-key <privkey file> private key file
-c, --certificate <cert file> signer's certificate file
-m, --monotonic-count <count> monotonic count
- -d, --dump_sig dump signature (*.p7)
+ -d, --dump-sig dump signature to <output file>.p7
-A, --fw-accept firmware accept capsule, requires GUID, no image blob
-R, --fw-revert firmware revert capsule, takes no GUID, no image blob
-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index a61557b73bef..e9b9ffe9b774 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -56,6 +56,7 @@ static struct option options[] = {
{"fw-revert", no_argument, NULL, 'R'},
{"capoemflag", required_argument, NULL, 'o'},
{"dump-capsule", no_argument, NULL, 'D'},
+ {"dump-sig", no_argument, NULL, 'd'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0},
};
@@ -83,7 +84,7 @@ static void print_usage_mkeficapsule(void)
"\t-p, --private-key <privkey file> private key file\n"
"\t-c, --certificate <cert file> signer's certificate file\n"
"\t-m, --monotonic-count <count> monotonic count\n"
- "\t-d, --dump_sig dump signature (*.p7)\n"
+ "\t-d, --dump-sig dump signature to <output file>.p7\n"
"\t-A, --fw-accept firmware accept capsule, requires GUID, no image blob\n"
"\t-R, --fw-revert firmware revert capsule, takes no GUID, no image blob\n"
"\t-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff\n"
--
2.47.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v5 3/6] tools: mkeficapsule: Fix dump signature long option
2026-01-28 8:05 ` [PATCH v5 3/6] tools: mkeficapsule: Fix dump signature long option Wojciech Dubowik
@ 2026-02-13 12:41 ` Ilias Apalodimas
0 siblings, 0 replies; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-13 12:41 UTC (permalink / raw)
To: Wojciech Dubowik, u-boot; +Cc: trini, simon.glass, quentin.schulz
On Wed Jan 28, 2026 at 10:05 AM EET, Wojciech Dubowik wrote:
> Only short option has been present. Also rename dump_sig
> to dump-sig to match with other parameter names.
>
> Fixes: 16abff246b40 ("tools: mkeficapsule: add firmware image signing")
>
> Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
> ---
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> doc/mkeficapsule.1 | 4 ++--
> tools/binman/btool/mkeficapsule.py | 2 +-
> tools/mkeficapsule.c | 3 ++-
> 3 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
> index a726149ba2ce..d6653ec42472 100644
> --- a/doc/mkeficapsule.1
> +++ b/doc/mkeficapsule.1
> @@ -121,8 +121,8 @@ Specify a monotonic count which is set to be monotonically incremented
> at every firmware update.
>
> .TP
> -.B "-d\fR,\fB --dump_sig"
> -Dump signature data into *.p7 file
> +.B "-d\fR,\fB --dump-sig"
> +Dump signature data into <capsule-file-name>.p7 file
>
> .SH "GUIDGEN OPTIONS"
>
> diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
> index f7e5a8868495..f2ac654db81e 100644
> --- a/tools/binman/btool/mkeficapsule.py
> +++ b/tools/binman/btool/mkeficapsule.py
> @@ -16,7 +16,7 @@ Options:
> -p, --private-key <privkey file> private key file
> -c, --certificate <cert file> signer's certificate file
> -m, --monotonic-count <count> monotonic count
> - -d, --dump_sig dump signature (*.p7)
> + -d, --dump-sig dump signature to <output file>.p7
> -A, --fw-accept firmware accept capsule, requires GUID, no image blob
> -R, --fw-revert firmware revert capsule, takes no GUID, no image blob
> -o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff
> diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
> index a61557b73bef..e9b9ffe9b774 100644
> --- a/tools/mkeficapsule.c
> +++ b/tools/mkeficapsule.c
> @@ -56,6 +56,7 @@ static struct option options[] = {
> {"fw-revert", no_argument, NULL, 'R'},
> {"capoemflag", required_argument, NULL, 'o'},
> {"dump-capsule", no_argument, NULL, 'D'},
> + {"dump-sig", no_argument, NULL, 'd'},
> {"help", no_argument, NULL, 'h'},
> {NULL, 0, NULL, 0},
> };
> @@ -83,7 +84,7 @@ static void print_usage_mkeficapsule(void)
> "\t-p, --private-key <privkey file> private key file\n"
> "\t-c, --certificate <cert file> signer's certificate file\n"
> "\t-m, --monotonic-count <count> monotonic count\n"
> - "\t-d, --dump_sig dump signature (*.p7)\n"
> + "\t-d, --dump-sig dump signature to <output file>.p7\n"
> "\t-A, --fw-accept firmware accept capsule, requires GUID, no image blob\n"
> "\t-R, --fw-revert firmware revert capsule, takes no GUID, no image blob\n"
> "\t-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff\n"
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v5 4/6] binman: Add dump signature option to mkeficapsule
2026-01-28 8:05 [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Wojciech Dubowik
` (2 preceding siblings ...)
2026-01-28 8:05 ` [PATCH v5 3/6] tools: mkeficapsule: Fix dump signature long option Wojciech Dubowik
@ 2026-01-28 8:05 ` Wojciech Dubowik
2026-01-28 8:05 ` [PATCH v5 5/6] binman: DTS: Add dump-signature option for capsules Wojciech Dubowik
` (2 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Wojciech Dubowik @ 2026-01-28 8:05 UTC (permalink / raw)
To: u-boot; +Cc: Wojciech Dubowik, trini, simon.glass, quentin.schulz
It will be used to capsule signature verification.
Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
---
tools/binman/btool/mkeficapsule.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
index f2ac654db81e..7638c941a8ee 100644
--- a/tools/binman/btool/mkeficapsule.py
+++ b/tools/binman/btool/mkeficapsule.py
@@ -38,7 +38,8 @@ class Bintoolmkeficapsule(bintool.Bintool):
def generate_capsule(self, image_index, image_guid, hardware_instance,
payload, output_fname, priv_key, pub_key,
- monotonic_count=0, version=0, oemflags=0):
+ monotonic_count=0, version=0, oemflags=0,
+ dump_sig=False):
"""Generate a capsule through commandline-provided parameters
Args:
@@ -53,6 +54,7 @@ class Bintoolmkeficapsule(bintool.Bintool):
monotonic_count (int): Count used when signing an image
version (int): Image version (Optional)
oemflags (int): Optional 16 bit OEM flags
+ dump_sig (bool): Dump signature to a file (Optional). Default no.
Returns:
str: Tool output
@@ -73,6 +75,8 @@ class Bintoolmkeficapsule(bintool.Bintool):
f'--private-key={priv_key}',
f'--certificate={pub_key}'
]
+ if dump_sig:
+ args += [f'--dump-sig']
args += [
payload,
--
2.47.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v5 5/6] binman: DTS: Add dump-signature option for capsules
2026-01-28 8:05 [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Wojciech Dubowik
` (3 preceding siblings ...)
2026-01-28 8:05 ` [PATCH v5 4/6] binman: Add dump signature option to mkeficapsule Wojciech Dubowik
@ 2026-01-28 8:05 ` Wojciech Dubowik
2026-01-28 8:05 ` [PATCH v5 6/6] test: binman: Add test for pkcs11 signed capsule Wojciech Dubowik
2026-02-13 12:40 ` [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Ilias Apalodimas
6 siblings, 0 replies; 15+ messages in thread
From: Wojciech Dubowik @ 2026-01-28 8:05 UTC (permalink / raw)
To: u-boot; +Cc: Wojciech Dubowik, trini, simon.glass, quentin.schulz
Mkeficapsule can dump signature for signed capsules. It can
be used in test to validate signature i.e. with openssl.
Add an entry for device tree node.
Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
---
tools/binman/entries.rst | 4 ++++
tools/binman/etype/efi_capsule.py | 9 ++++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index a81fcbd3891f..91f855f6d7a3 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -552,6 +552,10 @@ Properties / Entry arguments:
- public-key-cert: Path to PEM formatted .crt public key certificate
file. Mandatory property for generating signed capsules.
- oem-flags - OEM flags to be passed through capsule header.
+ - dump-signature: Optional boolean (default: false). Instruct
+ mkeficapsule to write signature data to a separate file. The
+ filename will be <capsule file>.p7. It might be used to verify
+ capsule authentication with external tools.
Since this is a subclass of Entry_section, all properties of the parent
class also apply here. Except for the properties stated as mandatory, the
diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py
index 3b30c12ea514..022d57ee5519 100644
--- a/tools/binman/etype/efi_capsule.py
+++ b/tools/binman/etype/efi_capsule.py
@@ -53,6 +53,10 @@ class Entry_efi_capsule(Entry_section):
- public-key-cert: Path to PEM formatted .crt public key certificate
file. Mandatory property for generating signed capsules.
- oem-flags - OEM flags to be passed through capsule header.
+ - dump-signature: Optional boolean (default: false). Instruct
+ mkeficapsule to write signature data to a separate file. The
+ filename will be <capsule file>.p7. It might be used to verify
+ capsule authentication with external tools.
Since this is a subclass of Entry_section, all properties of the parent
class also apply here. Except for the properties stated as mandatory, the
@@ -101,6 +105,7 @@ class Entry_efi_capsule(Entry_section):
self.private_key = ''
self.public_key_cert = ''
self.auth = 0
+ self.dump_signature = False
def ReadNode(self):
super().ReadNode()
@@ -111,6 +116,7 @@ class Entry_efi_capsule(Entry_section):
self.hardware_instance = fdt_util.GetInt(self._node, 'hardware-instance')
self.monotonic_count = fdt_util.GetInt(self._node, 'monotonic-count')
self.oem_flags = fdt_util.GetInt(self._node, 'oem-flags')
+ self.dump_signature = fdt_util.GetBool(self._node, 'dump-signature')
self.private_key = fdt_util.GetString(self._node, 'private-key')
self.public_key_cert = fdt_util.GetString(self._node, 'public-key-cert')
@@ -150,7 +156,8 @@ class Entry_efi_capsule(Entry_section):
public_key_cert,
self.monotonic_count,
self.fw_version,
- self.oem_flags)
+ self.oem_flags,
+ self.dump_signature)
if ret is not None:
return tools.read_file(capsule_fname)
else:
--
2.47.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH v5 6/6] test: binman: Add test for pkcs11 signed capsule
2026-01-28 8:05 [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Wojciech Dubowik
` (4 preceding siblings ...)
2026-01-28 8:05 ` [PATCH v5 5/6] binman: DTS: Add dump-signature option for capsules Wojciech Dubowik
@ 2026-01-28 8:05 ` Wojciech Dubowik
2026-02-13 17:52 ` Simon Glass
2026-02-13 12:40 ` [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Ilias Apalodimas
6 siblings, 1 reply; 15+ messages in thread
From: Wojciech Dubowik @ 2026-01-28 8:05 UTC (permalink / raw)
To: u-boot; +Cc: Wojciech Dubowik, trini, simon.glass, quentin.schulz
Test pkcs11 URI support for UEFI capsule generation. For
simplicity only private key is defined in binman section
as softhsm tool doesn't support certificate import (yet).
Add bintool support for p11-kit as it's needed in the test
to find library path for softhsm2 module.
Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
Reviewed-by: Simon Glass <simon.glass@canonical.com>
---
tools/binman/btool/p11_kit.py | 21 ++++++
tools/binman/ftest.py | 66 +++++++++++++++++++
.../binman/test/351_capsule_signed_pkcs11.dts | 22 +++++++
3 files changed, 109 insertions(+)
create mode 100644 tools/binman/btool/p11_kit.py
create mode 100644 tools/binman/test/351_capsule_signed_pkcs11.dts
diff --git a/tools/binman/btool/p11_kit.py b/tools/binman/btool/p11_kit.py
new file mode 100644
index 000000000000..9d8d5d848b44
--- /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/ftest.py b/tools/binman/ftest.py
index 21ec48d86fd1..a66030c7a56f 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,71 @@ 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("key.key"))
+ private_key = self._MakeInputFile("key.key", data)
+ data = tools.read_file(self.TestFile("key.pem"))
+ cert_file = self._MakeInputFile("key.crt", data)
+
+ softhsm2_util = bintool.Bintool.create('softhsm2_util')
+ self._CheckBintool(softhsm2_util)
+
+ prefix = "testPkcs11SignedCapsuleGen."
+ # Configure SoftHSMv2
+ data = tools.read_file(self.TestFile('340_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('softhsm2-util', '--import', private_key, '--token',
+ 'U-Boot token', '--label', 'test_key', '--id', '999999',
+ '--pin', '1111')
+ data = self._DoReadFile('351_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('313_capsule_version.dts')
diff --git a/tools/binman/test/351_capsule_signed_pkcs11.dts b/tools/binman/test/351_capsule_signed_pkcs11.dts
new file mode 100644
index 000000000000..ae93bf83936f
--- /dev/null
+++ b/tools/binman/test/351_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 = "key.crt";
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
--
2.47.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v5 6/6] test: binman: Add test for pkcs11 signed capsule
2026-01-28 8:05 ` [PATCH v5 6/6] test: binman: Add test for pkcs11 signed capsule Wojciech Dubowik
@ 2026-02-13 17:52 ` Simon Glass
2026-02-16 8:49 ` EXTERNAL - " Wojciech Dubowik
0 siblings, 1 reply; 15+ messages in thread
From: Simon Glass @ 2026-02-13 17:52 UTC (permalink / raw)
To: Wojciech Dubowik; +Cc: u-boot, trini, simon.glass, quentin.schulz
Hi Wojciech,
On Wed, 28 Jan 2026 at 01:06, Wojciech Dubowik <Wojciech.Dubowik@mt.com> wrote:
>
> Test pkcs11 URI support for UEFI capsule generation. For
> simplicity only private key is defined in binman section
> as softhsm tool doesn't support certificate import (yet).
>
> Add bintool support for p11-kit as it's needed in the test
> to find library path for softhsm2 module.
>
> Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
> Reviewed-by: Simon Glass <simon.glass@canonical.com>
> ---
> tools/binman/btool/p11_kit.py | 21 ++++++
> tools/binman/ftest.py | 66 +++++++++++++++++++
> .../binman/test/351_capsule_signed_pkcs11.dts | 22 +++++++
> 3 files changed, 109 insertions(+)
> create mode 100644 tools/binman/btool/p11_kit.py
> create mode 100644 tools/binman/test/351_capsule_signed_pkcs11.dts
>
> diff --git a/tools/binman/btool/p11_kit.py b/tools/binman/btool/p11_kit.py
> new file mode 100644
> index 000000000000..9d8d5d848b44
> --- /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/ftest.py b/tools/binman/ftest.py
> index 21ec48d86fd1..a66030c7a56f 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,71 @@ 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("key.key"))
> + private_key = self._MakeInputFile("key.key", data)
> + data = tools.read_file(self.TestFile("key.pem"))
> + cert_file = self._MakeInputFile("key.crt", data)
> +
> + softhsm2_util = bintool.Bintool.create('softhsm2_util')
> + self._CheckBintool(softhsm2_util)
> +
> + prefix = "testPkcs11SignedCapsuleGen."
> + # Configure SoftHSMv2
> + data = tools.read_file(self.TestFile('340_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('softhsm2-util', '--import', private_key, '--token',
> + 'U-Boot token', '--label', 'test_key', '--id', '999999',
> + '--pin', '1111')
> + data = self._DoReadFile('351_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('313_capsule_version.dts')
> diff --git a/tools/binman/test/351_capsule_signed_pkcs11.dts b/tools/binman/test/351_capsule_signed_pkcs11.dts
> new file mode 100644
> index 000000000000..ae93bf83936f
> --- /dev/null
> +++ b/tools/binman/test/351_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 = "key.crt";
> +
> + blob {
> + filename = "capsule_input.bin";
> + };
> + };
> + };
> +};
> --
> 2.47.3
>
I tried this out but I got a test-coverage failure (binman test -T):
tools/binman/etype/efi_capsule.py 65 1 98%
Regards,
Simon
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: EXTERNAL - [PATCH v5 6/6] test: binman: Add test for pkcs11 signed capsule
2026-02-13 17:52 ` Simon Glass
@ 2026-02-16 8:49 ` Wojciech Dubowik
0 siblings, 0 replies; 15+ messages in thread
From: Wojciech Dubowik @ 2026-02-16 8:49 UTC (permalink / raw)
To: Simon Glass; +Cc: u-boot, trini, simon.glass, quentin.schulz
On Fri, Feb 13, 2026 at 10:52:44AM -0700, Simon Glass wrote:
Hi Simon,
> Hi Wojciech,
>
> On Wed, 28 Jan 2026 at 01:06, Wojciech Dubowik <Wojciech.Dubowik@mt.com> wrote:
> >
> > Test pkcs11 URI support for UEFI capsule generation. For
> > simplicity only private key is defined in binman section
> > as softhsm tool doesn't support certificate import (yet).
> >
> > Add bintool support for p11-kit as it's needed in the test
> > to find library path for softhsm2 module.
> >
> > Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
> > Reviewed-by: Simon Glass <simon.glass@canonical.com>
> > ---
> > tools/binman/btool/p11_kit.py | 21 ++++++
> > tools/binman/ftest.py | 66 +++++++++++++++++++
> > .../binman/test/351_capsule_signed_pkcs11.dts | 22 +++++++
> > 3 files changed, 109 insertions(+)
> > create mode 100644 tools/binman/btool/p11_kit.py
> > create mode 100644 tools/binman/test/351_capsule_signed_pkcs11.dts
> >
> > diff --git a/tools/binman/btool/p11_kit.py b/tools/binman/btool/p11_kit.py
> > new file mode 100644
> > index 000000000000..9d8d5d848b44
> > --- /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/ftest.py b/tools/binman/ftest.py
> > index 21ec48d86fd1..a66030c7a56f 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,71 @@ 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("key.key"))
> > + private_key = self._MakeInputFile("key.key", data)
> > + data = tools.read_file(self.TestFile("key.pem"))
> > + cert_file = self._MakeInputFile("key.crt", data)
> > +
> > + softhsm2_util = bintool.Bintool.create('softhsm2_util')
> > + self._CheckBintool(softhsm2_util)
> > +
> > + prefix = "testPkcs11SignedCapsuleGen."
> > + # Configure SoftHSMv2
> > + data = tools.read_file(self.TestFile('340_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('softhsm2-util', '--import', private_key, '--token',
> > + 'U-Boot token', '--label', 'test_key', '--id', '999999',
> > + '--pin', '1111')
> > + data = self._DoReadFile('351_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('313_capsule_version.dts')
> > diff --git a/tools/binman/test/351_capsule_signed_pkcs11.dts b/tools/binman/test/351_capsule_signed_pkcs11.dts
> > new file mode 100644
> > index 000000000000..ae93bf83936f
> > --- /dev/null
> > +++ b/tools/binman/test/351_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 = "key.crt";
> > +
> > + blob {
> > + filename = "capsule_input.bin";
> > + };
> > + };
> > + };
> > +};
> > --
> > 2.47.3
> >
>
> I tried this out but I got a test-coverage failure (binman test -T):
>
> tools/binman/etype/efi_capsule.py 65 1 98%
It's because I test only private-key, public-key-cert is still using local file
and not pkcs11 token. For the latter one needs to import public key certificate
and it's supported only from softhsm2 version 2.7.0.
I didn't want to introduce yet another tool to do the job so this variable is
not yet covered by the test. I just wanted to start with something simple.
So we can leave it and I will adapt it once new softhsm tool is widespread or
I could rewrite it with pkcs11 tool.
Regards,
Wojtek
>
> Regards,
> Simon
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v5 0/6] UEFI Capsule - PKCS11 Support
2026-01-28 8:05 [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Wojciech Dubowik
` (5 preceding siblings ...)
2026-01-28 8:05 ` [PATCH v5 6/6] test: binman: Add test for pkcs11 signed capsule Wojciech Dubowik
@ 2026-02-13 12:40 ` Ilias Apalodimas
2026-02-13 20:20 ` Simon Glass
6 siblings, 1 reply; 15+ messages in thread
From: Ilias Apalodimas @ 2026-02-13 12:40 UTC (permalink / raw)
To: Wojciech Dubowik, simon.glass, u-boot; +Cc: trini, quentin.schulz
Simon,
This has ended up on my patchwork, but I wasn't cc'ed.
I'll have a look at the mkeficapsule changes soon, but do you mind if I
re-assign it you since it's mostly binman changes?
Thanks
/Ilias
On Wed Jan 28, 2026 at 10:05 AM EET, Wojciech Dubowik wrote:
> Add support for pkcs11 URI's when generating UEFI capsules and
> accept URI's for certificate in dts capsule nodes.
> Example:
> export PKCS11_MODULE_PATH=<pkcs11 provider path>/libsofthsm2.so
> tools/mkeficapsule --monotonic-count 1 \
> --private-key "pkcs11:token=EX;object=capsule;type=private;pin-source=pin.txt" \
> --certificate "pkcs11:token=EX;object=capsule;type=cert;pin-source=pin.txt" \
> --index 1 \
> --guid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX \
> "capsule-payload" \
> "capsule.cap
> Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
> ---
> Changes in v5:
> * add bin wrappers in test for all external tools
> * improve error handling in python test
> * fix data types in python
> * standardize option name in mkeficapsule
> * fix typos
> Changes in v4:
> * adapt mkeficapsule python support to dump detached signature
> for authenticated capsules
> * verify detached capsule signature with openssl after generation
> * use p11-kit to figure out location of softhsm2 library
> * fix missing long option for dumping signatures in mkeficapsule
> Changes in v3:
> * fix write file encoding, env setting and extra line in binman test
> after review
> Changes in v2:
> * allow mixed file/pkcs11 URI as key specification in mkeficapsule
> * fix logic for accepting pkcs11 URI in binman device tree sections
> * add binman test for UEFI capsule signature where private key comes
> from softHSM
> ---
> Wojciech Dubowik (6):
> tools: mkeficapsule: Add support for pkcs11
> binman: Accept pkcs11 URI tokens for capsule updates
> tools: mkeficapsule: Fix dump signature long option
> binman: Add dump signature option to mkeficapsule
> binman: DTS: Add dump-signature option for capsules
> test: binman: Add test for pkcs11 signed capsule
>
> doc/mkeficapsule.1 | 4 +-
> tools/binman/btool/mkeficapsule.py | 8 +-
> tools/binman/btool/p11_kit.py | 21 ++++
> tools/binman/entries.rst | 4 +
> tools/binman/etype/efi_capsule.py | 17 ++-
> tools/binman/ftest.py | 66 ++++++++++
> .../binman/test/351_capsule_signed_pkcs11.dts | 22 ++++
> tools/mkeficapsule.c | 113 +++++++++++++-----
> 8 files changed, 221 insertions(+), 34 deletions(-)
> create mode 100644 tools/binman/btool/p11_kit.py
> create mode 100644 tools/binman/test/351_capsule_signed_pkcs11.dts
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH v5 0/6] UEFI Capsule - PKCS11 Support
2026-02-13 12:40 ` [PATCH v5 0/6] UEFI Capsule - PKCS11 Support Ilias Apalodimas
@ 2026-02-13 20:20 ` Simon Glass
0 siblings, 0 replies; 15+ messages in thread
From: Simon Glass @ 2026-02-13 20:20 UTC (permalink / raw)
To: Ilias Apalodimas
Cc: Wojciech Dubowik, simon.glass, u-boot, trini, quentin.schulz
Hi Ilias,
On Fri, 13 Feb 2026 at 05:41, Ilias Apalodimas
<ilias.apalodimas@linaro.org> wrote:
>
> Simon,
> This has ended up on my patchwork, but I wasn't cc'ed.
> I'll have a look at the mkeficapsule changes soon, but do you mind if I
> re-assign it you since it's mostly binman changes?
Yes that's fine (we synced up on irc).
Regards,
Simon
>
> Thanks
> /Ilias
> On Wed Jan 28, 2026 at 10:05 AM EET, Wojciech Dubowik wrote:
> > Add support for pkcs11 URI's when generating UEFI capsules and
> > accept URI's for certificate in dts capsule nodes.
> > Example:
> > export PKCS11_MODULE_PATH=<pkcs11 provider path>/libsofthsm2.so
> > tools/mkeficapsule --monotonic-count 1 \
> > --private-key "pkcs11:token=EX;object=capsule;type=private;pin-source=pin.txt" \
> > --certificate "pkcs11:token=EX;object=capsule;type=cert;pin-source=pin.txt" \
> > --index 1 \
> > --guid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX \
> > "capsule-payload" \
> > "capsule.cap
> > Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik@mt.com>
> > ---
> > Changes in v5:
> > * add bin wrappers in test for all external tools
> > * improve error handling in python test
> > * fix data types in python
> > * standardize option name in mkeficapsule
> > * fix typos
> > Changes in v4:
> > * adapt mkeficapsule python support to dump detached signature
> > for authenticated capsules
> > * verify detached capsule signature with openssl after generation
> > * use p11-kit to figure out location of softhsm2 library
> > * fix missing long option for dumping signatures in mkeficapsule
> > Changes in v3:
> > * fix write file encoding, env setting and extra line in binman test
> > after review
> > Changes in v2:
> > * allow mixed file/pkcs11 URI as key specification in mkeficapsule
> > * fix logic for accepting pkcs11 URI in binman device tree sections
> > * add binman test for UEFI capsule signature where private key comes
> > from softHSM
> > ---
> > Wojciech Dubowik (6):
> > tools: mkeficapsule: Add support for pkcs11
> > binman: Accept pkcs11 URI tokens for capsule updates
> > tools: mkeficapsule: Fix dump signature long option
> > binman: Add dump signature option to mkeficapsule
> > binman: DTS: Add dump-signature option for capsules
> > test: binman: Add test for pkcs11 signed capsule
> >
> > doc/mkeficapsule.1 | 4 +-
> > tools/binman/btool/mkeficapsule.py | 8 +-
> > tools/binman/btool/p11_kit.py | 21 ++++
> > tools/binman/entries.rst | 4 +
> > tools/binman/etype/efi_capsule.py | 17 ++-
> > tools/binman/ftest.py | 66 ++++++++++
> > .../binman/test/351_capsule_signed_pkcs11.dts | 22 ++++
> > tools/mkeficapsule.c | 113 +++++++++++++-----
> > 8 files changed, 221 insertions(+), 34 deletions(-)
> > create mode 100644 tools/binman/btool/p11_kit.py
> > create mode 100644 tools/binman/test/351_capsule_signed_pkcs11.dts
>
^ permalink raw reply [flat|nested] 15+ messages in thread