Hi Johannes,
On 10/11/26 10:27 AM, Johannes Schneider wrote:
[You don't often get email from [email protected]. Learn
why this is important at https://aka.ms/LearnAboutSenderIdentification ]
The OpenSSL Provider API support routes FIT signing-key loading through
OSSL_STORE on OpenSSL >= 3 (USE_PKCS11_PROVIDER), but only for key files:
rsa_pem_get_priv_key() fopen()s the path before OSSL_STORE_open(), so a pkcs11:
token URI fails with -ENOENT. The legacy engine path that handled tokens is
Yes, this was reported in the original series already.
compiled out on OpenSSL >= 3, so FIT signing with a token key silently produces
an unsigned FIT (a configuration signature node with no value or
hashed-strings).
Load a pkcs11: key URI in the provider path directly through OSSL_STORE and the
pkcs11 provider: skip the fopen, append ";type=private" if absent. The PIN
travels in the URI (pin-value=); MKIMAGE_SIGN_PIN is unaffected.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Johannes Schneider <[email protected]>
---
Follow-up to Eddie Kovsky's "rsa: Add support for OpenSSL Provider API"
(https://lore.kernel.org/u-boot/[email protected]).
Please do not base a new series on another series that has clearly been
marked as rejected in its current version. Work on the original series
with the original contributor(s) to get things going. At the very least,
mark this one here as RFC to highlight this isn't ready to be merged.
See
https://git.u-boot-project.org/u-boot/custodians/u-boot-rockchip/-/tree/openssl-providers
for the work I've done on my side to have parity with OpenSSL engine
signing. This includes PKCS#11 signing and associated tests.
Cheers,
Quentin
How we use it: our build signs production FIT images with an RSA key kept on a
PKCS#11 token, so the private key never lands on the build host or in CI
artifacts. mkimage gets the key as a "pkcs11:...;type=private" URI; the
provider path today handles file keys only, so with the engine gone on
OpenSSL >= 3 a token-backed FIT silently comes out unsigned -- this closes that
gap.
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -237,6 +237,49 @@
return -EINVAL;
*evpp = NULL;
+
+#ifdef USE_PKCS11_PROVIDER
+ /* A pkcs11: token URI is not a file: load it via OSSL_STORE + the
pkcs11 provider instead of fopen (PIN in the URI, pin-value=). */
+ if (keydir && !strncmp(keydir, "pkcs11:", 7)) {
+ char uri[1200];
+ OSSL_STORE_CTX *p11_store;
+ EVP_PKEY *p11_key = NULL;
+
+ if (strstr(keydir, "type="))
+ snprintf(uri, sizeof(uri), "%s", keydir);
+ else
+ snprintf(uri, sizeof(uri), "%s;type=private", keydir);
+
+ if (!OSSL_PROVIDER_try_load(NULL, "default", true))
+ ERR(1, "OSSL_PROVIDER_try_load(default)");
+ if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true))
+ ERR(1, "OSSL_PROVIDER_try_load(pkcs11)");
+
+ p11_store = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL);
+ ERR(!p11_store, "OSSL_STORE_open(%s)", uri);
+ while (!OSSL_STORE_eof(p11_store)) {
+ OSSL_STORE_INFO *info = OSSL_STORE_load(p11_store);
+
+ if (!info) {
+ if (OSSL_STORE_error(p11_store))
+ break;
+ continue;
+ }
+ if (OSSL_STORE_INFO_get_type(info) ==
OSSL_STORE_INFO_PKEY)
+ p11_key = OSSL_STORE_INFO_get1_PKEY(info);
+ OSSL_STORE_INFO_free(info);
+ if (p11_key)
+ break;
+ }
+ OSSL_STORE_close(p11_store);
+ if (!p11_key) {
+ fprintf(stderr, "No private key found at '%s'\n", uri);
+ return -EPROTO;
+ }
+ *evpp = p11_key;
+ return 0;
+ }
+#endif
if (keydir && name)
snprintf(path, sizeof(path), "%s/%s.key", keydir, name);
else if (keyfile)