U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Eddie Kovsky <ekovsky@redhat.com>
To: Tom Rini <trini@konsulko.com>, Tobias Olausson <tobias@eub.se>,
	Paul HENRYS <paul.henrys_ext@softathome.com>,
	Simon Glass <sjg@chromium.org>, Jan Stancek <jstancek@redhat.com>,
	Enric Balletbo i Serra <eballetb@redhat.com>,
	a.fatoum@pengutronix.de, mark.kettenis@xs4all.nl,
	Mattijs Korpershoek <mkorpershoek@kernel.org>,
	Johannes Schneider <johannes.schneider@leica-geosystems.com>
Cc: u-boot@lists.u-boot-project.org,
	Quentin Schulz <quentin.schulz@cherry.de>,
	Bastian <bst@pengutronix.de>, Rasmus Villemoes <ravi@prevas.dk>,
	Jaipaul Cheernam <jaipaul.cheernam@est.tech>
Subject: [PATCH v5 3/3] rsa: load a pkcs11 token key through OSSL_STORE in the provider path
Date: Thu, 29 Oct 2026 14:13:43 -0600	[thread overview]
Message-ID: <20261029201348.730274-4-ekovsky@redhat.com> (raw)
In-Reply-To: <20261029201348.730274-1-ekovsky@redhat.com>

From: Johannes Schneider <johannes.schneider@leica-geosystems.com>

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
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 <johannes.schneider@leica-geosystems.com>
Co-developed-by: Eddie Kovsky <ekovsky@redhat.com>
Signed-off-by: Eddie Kovsky <ekovsky@redhat.com>
---
 lib/rsa/rsa-sign.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 361ed0647bc6..c39a2a11652f 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -92,6 +92,52 @@ static int rsa_pem_get_pub_key(const char *keydir, const char *name, EVP_PKEY **
 		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=public", 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_PUBKEY)
+				p11_key = OSSL_STORE_INFO_get1_PUBKEY(info);
+			OSSL_STORE_INFO_free(info);
+			if (p11_key)
+				break;
+		}
+		OSSL_STORE_close(p11_store);
+		if (!p11_key) {
+			fprintf(stderr, "No public key found at '%s'\n", uri);
+			return -EPROTO;
+		}
+		*evpp = p11_key;
+		return 0;
+	}
+
+#endif
 	snprintf(path, sizeof(path), "%s/%s.crt", keydir, name);
 	f = fopen(path, "r");
 	if (!f) {
@@ -237,6 +283,52 @@ static int rsa_pem_get_priv_key(const char *keydir, const char *name,
 		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)
-- 
2.56.0


  parent reply	other threads:[~2026-10-29 20:25 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29 20:13 [PATCH v5 0/3] Add support for OpenSSL Provider API Eddie Kovsky
2026-10-29 20:13 ` [PATCH v5 1/3] " Eddie Kovsky
2026-10-29 20:13 ` [PATCH v5 2/3] Add pkcs11-provider package to build dependencies Eddie Kovsky
2026-10-29 20:13 ` Eddie Kovsky [this message]
2026-10-30  9:57 ` [PATCH v5 0/3] Add support for OpenSSL Provider API Quentin Schulz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261029201348.730274-4-ekovsky@redhat.com \
    --to=ekovsky@redhat.com \
    --cc=a.fatoum@pengutronix.de \
    --cc=bst@pengutronix.de \
    --cc=eballetb@redhat.com \
    --cc=jaipaul.cheernam@est.tech \
    --cc=johannes.schneider@leica-geosystems.com \
    --cc=jstancek@redhat.com \
    --cc=mark.kettenis@xs4all.nl \
    --cc=mkorpershoek@kernel.org \
    --cc=paul.henrys_ext@softathome.com \
    --cc=quentin.schulz@cherry.de \
    --cc=ravi@prevas.dk \
    --cc=sjg@chromium.org \
    --cc=tobias@eub.se \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.u-boot-project.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox