mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 2/5] public-keys: move list out of struct public_key
Date: Mon, 20 Oct 2025 13:30:59 +0200	[thread overview]
Message-ID: <20251020-public-keys-const-v1-2-301de7918b06@pengutronix.de> (raw)
In-Reply-To: <20251020-public-keys-const-v1-0-301de7918b06@pengutronix.de>

struct public_key contains a list entry which prevents us from putting
the struct into the RO data section. Use idr to keep the list outside
the struct. With this we also no longer have to duplicate the keys but
can use them in place instead.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/keys.c             |  3 ++-
 common/image-fit.c          |  4 +--
 crypto/Kconfig              |  1 +
 crypto/public-keys.c        | 61 ++++++---------------------------------------
 include/crypto/public_key.h |  8 +++---
 5 files changed, 17 insertions(+), 60 deletions(-)

diff --git a/commands/keys.c b/commands/keys.c
index 2d85e8124ff57ecc8ef7364f083b3439e3b958e4..616d44c25a9bb092b6f3f1fb0f3ac8bd66c8f0df 100644
--- a/commands/keys.c
+++ b/commands/keys.c
@@ -5,8 +5,9 @@
 static int do_keys(int argc, char *argv[])
 {
 	const struct public_key *key;
+	int id;
 
-	for_each_public_key(key) {
+	for_each_public_key(key, id) {
 		printf("KEY: %*phN", key->hashlen, key->hash);
 
 		if (key->key_name_hint)
diff --git a/common/image-fit.c b/common/image-fit.c
index 6b44a79e9d1cb8528c08c40ea043e01364664320..a4a490b03e68acc0929ecf58b2f09f592450afc5 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -266,7 +266,7 @@ static int fit_check_signature(struct fit_handle *handle, struct device_node *si
 	const char *key_name = NULL;
 	int sig_len;
 	const char *sig_value;
-	int ret;
+	int id, ret;
 
 	sig_value = of_get_property(sig_node, "value", &sig_len);
 	if (!sig_value) {
@@ -287,7 +287,7 @@ static int fit_check_signature(struct fit_handle *handle, struct device_node *si
 		}
 	}
 
-	for_each_public_key(key) {
+	for_each_public_key(key, id) {
 		fail_reason = "verification failed";
 
 		if (key_name && !strcmp(key->key_name_hint, key_name))
diff --git a/crypto/Kconfig b/crypto/Kconfig
index a79525b4d4d1920e36b3fad367297bed1e2a5b76..dd14a2532ce630ab17f3ec195ff895297ecd09c7 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -129,6 +129,7 @@ config CRYPTO_ECDSA
 config CRYPTO_BUILTIN_KEYS
 	bool "builtin keys"
 	select KEYTOC
+	select IDR
 
 config CRYPTO_PUBLIC_KEYS
 	depends on CRYPTO_BUILTIN_KEYS
diff --git a/crypto/public-keys.c b/crypto/public-keys.c
index 8884e263b3655b023b17a7d3ba0e29bcf8e0ca65..6d86be8d34e164f46ccb2b53cc4c1c0ed5744987 100644
--- a/crypto/public-keys.c
+++ b/crypto/public-keys.c
@@ -6,22 +6,14 @@
 #include <crypto/rsa.h>
 #include <crypto/ecdsa.h>
 
-static LIST_HEAD(public_keys);
-
-const struct public_key *public_key_next(const struct public_key *prev)
-{
-	prev = list_prepare_entry(prev, &public_keys, list);
-	list_for_each_entry_continue(prev, &public_keys, list)
-		return prev;
-
-	return NULL;
-}
+DEFINE_IDR(public_keys);
 
 const struct public_key *public_key_get(const char *name)
 {
 	const struct public_key *key;
+	int id;
 
-	list_for_each_entry(key, &public_keys, list) {
+	for_each_public_key(key, id) {
 		if (!strcmp(key->key_name_hint, name))
 			return key;
 	}
@@ -34,42 +26,7 @@ int public_key_add(struct public_key *key)
 	if (public_key_get(key->key_name_hint))
 		return -EEXIST;
 
-	list_add_tail(&key->list, &public_keys);
-
-	return 0;
-}
-
-static struct public_key *public_key_dup(const struct public_key *key)
-{
-	struct public_key *k = xzalloc(sizeof(*k));
-
-	k->type = key->type;
-	if (key->key_name_hint)
-		k->key_name_hint = xstrdup(key->key_name_hint);
-	k->hash = xmemdup(key->hash, key->hashlen);
-	k->hashlen = key->hashlen;
-
-	switch (key->type) {
-	case PUBLIC_KEY_TYPE_RSA:
-		k->rsa = rsa_key_dup(key->rsa);
-		if (!k->rsa)
-			goto err;
-		break;
-	case PUBLIC_KEY_TYPE_ECDSA:
-		k->ecdsa = ecdsa_key_dup(key->ecdsa);
-		if (!k->ecdsa)
-			goto err;
-		break;
-	default:
-		goto err;
-	}
-
-	return k;
-err:
-	free(k->key_name_hint);
-	free(k);
-
-	return NULL;
+	return idr_alloc(&public_keys, key, 0, INT_MAX, GFP_NOWAIT);
 }
 
 int public_key_verify(const struct public_key *key, const uint8_t *sig,
@@ -92,16 +49,12 @@ extern struct public_key * __public_keys_end[];
 static int init_public_keys(void)
 {
 	struct public_key * const *iter;
+	int ret;
 
 	for (iter = __public_keys_start; iter != __public_keys_end; iter++) {
-		struct public_key *key = public_key_dup(*iter);
-
-		if (!key) {
+		ret = idr_alloc(&public_keys, *iter, 0, INT_MAX, GFP_NOWAIT);
+		if (ret)
 			pr_warn("error while adding key\n");
-			continue;
-		}
-
-		public_key_add(key);
 	}
 
 	return 0;
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 7edea2d69190cb30f328510f905bab3054ad5845..3a484eced110b179c5c411c4e06c47770e965613 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -2,6 +2,7 @@
 #define __CRYPTO_PUBLIC_KEY_H
 
 #include <digest.h>
+#include <linux/idr.h>
 
 struct rsa_public_key;
 struct ecdsa_public_key;
@@ -13,7 +14,6 @@ enum public_key_type {
 
 struct public_key {
 	enum public_key_type type;
-	struct list_head list;
 	char *key_name_hint;
 	unsigned char *hash;
 	unsigned int hashlen;
@@ -28,8 +28,10 @@ int public_key_add(struct public_key *key);
 const struct public_key *public_key_get(const char *name);
 const struct public_key *public_key_next(const struct public_key *prev);
 
-#define for_each_public_key(key) \
-		for (key = public_key_next(NULL); key; key = public_key_next(key))
+extern struct idr public_keys;
+
+#define for_each_public_key(key, id) \
+		idr_for_each_entry(&public_keys, key, id)
 
 int public_key_verify(const struct public_key *key, const uint8_t *sig,
 		      const uint32_t sig_len, const uint8_t *hash,

-- 
2.47.3




  parent reply	other threads:[~2025-10-20 12:59 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-20 11:30 [PATCH 0/5] public_keys: make const Sascha Hauer
2025-10-20 11:30 ` [PATCH 1/5] public-keys: ecdsa: remove list in ecdsa keys Sascha Hauer
2025-10-20 11:30 ` Sascha Hauer [this message]
2025-10-20 11:31 ` [PATCH 3/5] public-keys: rsa: allow struct public_key to be const Sascha Hauer
2025-10-20 11:31 ` [PATCH 4/5] public-keys: rsa: remove unused functions Sascha Hauer
2025-10-20 11:31 ` [PATCH 5/5] public-keys: make const Sascha Hauer

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=20251020-public-keys-const-v1-2-301de7918b06@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.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