All of 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: 4+ 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]

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.