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 3/4] public keys: rework keyrings as nested containers
Date: Wed, 27 May 2026 12:54:43 +0200	[thread overview]
Message-ID: <20260527-public-keys-v1-3-c87a1cc61d1b@pengutronix.de> (raw)
In-Reply-To: <20260527-public-keys-v1-0-c87a1cc61d1b@pengutronix.de>

Until now a keyring was just a string-valued field on each
struct public_key, and a key could only belong to a single keyring.
Switching policy at runtime required changing that string in place.

Introduce explicit struct keyring / struct keyring_link types: a
keyring is a named container of links, and each link references
either a public_key or a sub-keyring. Sub-keyring links are live
references, so adding a key to fit-devel after linking fit-devel
into fit makes the key visible via fit too.

Drop the global public_keys IDR; keyrings are tracked in a flat
name registry instead, and iteration goes through the keyring tree.

Change the "keys" command to print the current keyring hierarchy.

As a nice side effect separating the public keys entirely from the keyring
they are in allows us to put the compiled in keys into RO data.

Assisted-by: Claude Opus 4.7
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/keys.c                   |  22 ++--
 common/image-fit.c                |  15 ++-
 common/tlv/parser.c               |  13 ++-
 crypto/public-keys.c              | 218 ++++++++++++++++++++++++++++++++++----
 crypto/rsa.c                      |   3 +-
 include/asm-generic/barebox.lds.h |  11 ++
 include/crypto/public_key.h       |  87 ++++++++++++---
 scripts/keytoc.c                  |  24 +++--
 8 files changed, 336 insertions(+), 57 deletions(-)

diff --git a/commands/keys.c b/commands/keys.c
index 12cb6ea2e3..06d289f18f 100644
--- a/commands/keys.c
+++ b/commands/keys.c
@@ -4,13 +4,23 @@
 
 static int do_keys(int argc, char *argv[])
 {
-	const struct public_key *key;
-	int id;
+	const struct keyring *kr;
+	const struct keyring_link *link;
 
-	for_each_public_key(key, id) {
-		printf("KEY: %*phN\tTYPE: %s\tKEYRING: %s\tHINT: %s\n", key->hashlen,
-		       key->hash, public_key_type_string(key->type), key->keyring,
-		       key->key_name_hint ?: "");
+	for_each_keyring(kr) {
+		printf("RING: %s\n", kr->name);
+		for_each_link_in_keyring(link, kr) {
+			if (link->type == KEYRING_LINK_KEY) {
+				const struct public_key *key = link->key;
+
+				printf("    KEY:    %*phN\tTYPE: %s\tHINT: %s\n",
+				       key->hashlen, key->hash,
+				       public_key_type_string(key->type),
+				       key->key_name_hint ?: "");
+			} else {
+				printf("    RING:   %s\n", link->keyring->name);
+			}
+		}
 	}
 
 	return 0;
diff --git a/common/image-fit.c b/common/image-fit.c
index f5356be33d..b7daf433c3 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -253,10 +253,11 @@ static int fit_check_signature(struct fit_handle *handle, struct device_node *si
 {
 	const char *fail_reason;
 	const struct public_key *key;
+	const struct keyring *fit_kr;
 	const char *key_name = NULL;
 	int sig_len;
 	const char *sig_value;
-	int id, ret;
+	int ret;
 
 	sig_value = of_get_property(sig_node, "value", &sig_len);
 	if (!sig_value) {
@@ -266,10 +267,16 @@ static int fit_check_signature(struct fit_handle *handle, struct device_node *si
 
 	fail_reason = "no matching keys";
 
+	fit_kr = keyring_find("fit");
+	if (!fit_kr) {
+		pr_err("fit keyring not registered\n");
+		return -ENOKEY;
+	}
+
 	of_property_read_string(sig_node, "key-name-hint", &key_name);
 	if (key_name) {
-		key = public_key_get(key_name, "fit");
-		if (key) {
+		key = keyring_find_key(fit_kr, key_name);
+		if (!IS_ERR(key)) {
 			fail_reason = "verification failed";
 			ret = public_key_verify(key, sig_value, sig_len, hash, algo);
 			if (handle->verbose)
@@ -280,7 +287,7 @@ static int fit_check_signature(struct fit_handle *handle, struct device_node *si
 		}
 	}
 
-	for_each_public_key_keyring(key, id, "fit") {
+	for_each_key_in_keyring(key, fit_kr) {
 
 		/* Don't recheck with same key as before */
 		if (key_name && streq_ptr(key->key_name_hint, key_name))
diff --git a/common/tlv/parser.c b/common/tlv/parser.c
index 4c0b6b5c6f..d61dfa2c47 100644
--- a/common/tlv/parser.c
+++ b/common/tlv/parser.c
@@ -49,15 +49,16 @@ static int tlv_verify_try_key(const struct public_key *key, const uint8_t *sig,
 	return ret;
 }
 
-static int tlv_verify(const struct tlv_header *header, const char *keyring)
+static int tlv_verify(const struct tlv_header *header, const char *keyring_name)
 {
 	const struct public_key *key;
+	const struct keyring *kr;
 	size_t payload_sz = tlv_spki_hash_offset(header);
 	const void *spki_tlv_ptr = (void *)header + payload_sz;
 	u32 spki_tlv = get_unaligned_le32(spki_tlv_ptr);
 	int SPKI_LEN = 4;
 	u32 sig_len = get_unaligned_be16(&header->length_sig);
-	int ret, id;
+	int ret;
 	int count_spki_matches = 0;
 
 	if (!IS_ENABLED(CONFIG_TLV_SIGNATURE)) {
@@ -68,7 +69,13 @@ static int tlv_verify(const struct tlv_header *header, const char *keyring)
 		return -EPROTO;
 	}
 
-	for_each_public_key_keyring(key, id, keyring) {
+	kr = keyring_find(keyring_name);
+	if (!kr) {
+		pr_warn("TLV keyring %s not found\n", keyring_name);
+		return -ENOKEY;
+	}
+
+	for_each_key_in_keyring(key, kr) {
 		u32 spki_key = get_unaligned_le32(key->hash);
 
 		if (spki_key == spki_tlv) {
diff --git a/crypto/public-keys.c b/crypto/public-keys.c
index 2b4bac55b7..84bc03e4e3 100644
--- a/crypto/public-keys.c
+++ b/crypto/public-keys.c
@@ -5,38 +5,216 @@
 #include <crypto/public_key.h>
 #include <crypto/rsa.h>
 #include <crypto/ecdsa.h>
+#include <linux/list.h>
+#include <malloc.h>
+#include <xfuncs.h>
 
-DEFINE_IDR(public_keys);
+LIST_HEAD(keyring_registry);
 
-const struct public_key *public_key_get(const char *name, const char *keyring)
+struct keyring *keyring_find(const char *name)
+{
+	struct keyring *kr;
+
+	if (!name)
+		return NULL;
+
+	list_for_each_entry(kr, &keyring_registry, node) {
+		if (!strcmp(kr->name, name))
+			return kr;
+	}
+	return NULL;
+}
+
+struct keyring *keyring_create(const char *name)
+{
+	struct keyring *kr;
+
+	if (!name || !*name)
+		return ERR_PTR(-EINVAL);
+
+	if (keyring_find(name))
+		return ERR_PTR(-EEXIST);
+
+	kr = xzalloc(sizeof(*kr));
+	kr->name = xstrdup(name);
+	INIT_LIST_HEAD(&kr->links);
+	INIT_LIST_HEAD(&kr->node);
+	list_add_tail(&kr->node, &keyring_registry);
+
+	return kr;
+}
+
+int keyring_link_key(struct keyring *kr, const struct public_key *key)
+{
+	struct keyring_link *link;
+
+	if (!kr || !key)
+		return -EINVAL;
+
+	link = xzalloc(sizeof(*link));
+	link->type = KEYRING_LINK_KEY;
+	link->key = key;
+	list_add_tail(&link->node, &kr->links);
+
+	return 0;
+}
+
+int keyring_unlink_key(struct keyring *kr, const struct public_key *key)
+{
+	struct keyring_link *link, *n;
+
+	if (!kr || !key)
+		return -EINVAL;
+
+	list_for_each_entry_safe(link, n, &kr->links, node) {
+		if (link->type == KEYRING_LINK_KEY && link->key == key) {
+			list_del(&link->node);
+			free(link);
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+static bool keyring_contains(const struct keyring *kr, const struct keyring *target)
+{
+	const struct keyring_link *link;
+
+	if (kr == target)
+		return true;
+
+	list_for_each_entry(link, &kr->links, node) {
+		if (link->type != KEYRING_LINK_KEYRING)
+			continue;
+		if (keyring_contains(link->keyring, target))
+			return true;
+	}
+	return false;
+}
+
+int keyring_link_keyring(struct keyring *kr, const struct keyring *sub)
+{
+	struct keyring_link *link;
+
+	if (!kr || !sub)
+		return -EINVAL;
+
+	/*
+	 * Refuse to create a cycle: if sub already (transitively) contains kr
+	 * — or sub is kr itself — adding sub as a child of kr would loop.
+	 * Assuming the graph was cycle-free before, this check is enough to
+	 * keep it that way.
+	 */
+	if (keyring_contains(sub, kr))
+		return -ELOOP;
+
+	link = xzalloc(sizeof(*link));
+	link->type = KEYRING_LINK_KEYRING;
+	link->keyring = sub;
+	list_add_tail(&link->node, &kr->links);
+
+	return 0;
+}
+
+int keyring_unlink_keyring(struct keyring *kr, const struct keyring *sub)
+{
+	struct keyring_link *link, *n;
+
+	if (!kr || !sub)
+		return -EINVAL;
+
+	list_for_each_entry_safe(link, n, &kr->links, node) {
+		if (link->type == KEYRING_LINK_KEYRING && link->keyring == sub) {
+			list_del(&link->node);
+			free(link);
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+const struct public_key *keyring_iter_next(struct keyring_iter *it,
+					   const struct keyring *root)
+{
+	if (it->depth < 0) {
+		if (!root)
+			return NULL;
+		it->depth = 0;
+		it->stack[0] = root;
+		it->cursor[0] = (struct list_head *)&root->links;
+	}
+
+	while (it->depth >= 0) {
+		struct list_head *head = (struct list_head *)&it->stack[it->depth]->links;
+		struct list_head *next = it->cursor[it->depth]->next;
+		struct keyring_link *link;
+
+		if (next == head) {
+			it->depth--;
+			continue;
+		}
+
+		it->cursor[it->depth] = next;
+		link = list_entry(next, struct keyring_link, node);
+
+		if (link->type == KEYRING_LINK_KEY)
+			return link->key;
+
+		if (it->depth + 1 >= KEYRING_MAX_DEPTH) {
+			pr_warn("keyring nesting too deep, skipping %s\n",
+				link->keyring->name);
+			continue;
+		}
+
+		it->depth++;
+		it->stack[it->depth] = link->keyring;
+		it->cursor[it->depth] = (struct list_head *)&link->keyring->links;
+	}
+
+	return NULL;
+}
+
+const struct public_key *keyring_find_key(const struct keyring *kr,
+					  const char *key_name_hint)
 {
 	const struct public_key *key;
-	int id;
 
-	for_each_public_key_keyring(key, id, keyring) {
+	if (!kr || !key_name_hint)
+		return ERR_PTR(-EINVAL);
+
+	for_each_key_in_keyring(key, kr) {
 		if (!key->key_name_hint)
 			continue;
-		if (!strcmp(key->key_name_hint, name))
+		if (!strcmp(key->key_name_hint, key_name_hint))
 			return key;
 	}
 
-	return NULL;
+	return ERR_PTR(-ENOENT);
 }
 
-int public_key_add(struct public_key *key)
+int public_key_add(const char *keyring, const struct public_key *key)
 {
-	if (!key->keyring || *key->keyring == '\0') {
-		pr_warn("Aborting addition of public key: No keyring specified\n");
+	struct keyring *kr;
+	const struct public_key *conflict;
+
+	if (!keyring || !*keyring)
 		return -EINVAL;
+
+	kr = keyring_find(keyring);
+	if (!kr) {
+		kr = keyring_create(keyring);
+		if (IS_ERR(kr))
+			return PTR_ERR(kr);
 	}
 
-	if (public_key_get(key->key_name_hint, key->keyring)) {
+	conflict = keyring_find_key(kr, key->key_name_hint);
+	if (!IS_ERR(conflict)) {
 		pr_warn("Cannot add key: key_name_hint %s already exists in keyring %s\n",
-			key->key_name_hint, key->keyring);
+			key->key_name_hint, keyring);
 		return -EEXIST;
 	}
 
-	return idr_alloc(&public_keys, key, 0, INT_MAX, GFP_NOWAIT);
+	return keyring_link_key(kr, key);
 }
 
 int public_key_verify(const struct public_key *key, const uint8_t *sig,
@@ -53,18 +231,20 @@ int public_key_verify(const struct public_key *key, const uint8_t *sig,
 	return -ENOKEY;
 }
 
-extern struct public_key * __public_keys_start[];
-extern struct public_key * __public_keys_end[];
+extern const struct public_key_record __public_keys_start[];
+extern const struct public_key_record __public_keys_end[];
 
 static int init_public_keys(void)
 {
-	struct public_key * const *iter;
+	const struct public_key_record *rec;
 	int ret;
 
-	for (iter = __public_keys_start; iter != __public_keys_end; iter++) {
-		ret = idr_alloc(&public_keys, *iter, 0, INT_MAX, GFP_NOWAIT);
-		if (ret < 0)
-			pr_warn("error while adding key\n");
+	for (rec = __public_keys_start; rec != __public_keys_end; rec++) {
+		ret = public_key_add(rec->keyring, rec->key);
+		if (ret)
+			pr_warn("error while adding key %s to %s: %pe\n",
+				rec->key->key_name_hint ?: "(noname)",
+				rec->keyring, ERR_PTR(ret));
 	}
 
 	return 0;
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 0e752f11b4..0b20b59477 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -468,8 +468,7 @@ static void rsa_init_keys_of(void)
 			continue;
 		}
 
-		key->keyring = "fit";
-		ret = public_key_add(key);
+		ret = public_key_add("fit", key);
 		if (ret)
 			pr_err("Cannot add rsa key %s: %pe\n",
 				key->key_name_hint, ERR_PTR(ret));
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index 12082d567a..008217e808 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -129,7 +129,18 @@
 #endif
 
 
+/*
+ * GCC emits "const data with absolute relocations" into .data.rel.ro*
+ * (e.g. a `static const struct` that contains pointers to other symbols).
+ * In a statically linked image these are fully resolved at link time and
+ * never written at runtime, so place them with .rodata instead of letting
+ * them fall through into the writable .data section.
+ */
+#define BAREBOX_RELRO_DATA			\
+	*(.data.rel.ro .data.rel.ro.*)
+
 #define RO_DATA_SECTION				\
+	BAREBOX_RELRO_DATA			\
 	BAREBOX_INITCALLS			\
 	BAREBOX_EXITCALLS			\
 	BAREBOX_CMDS				\
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 0fd8e1e304..3866b13a75 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -2,7 +2,7 @@
 #define __CRYPTO_PUBLIC_KEY_H
 
 #include <digest.h>
-#include <linux/idr.h>
+#include <linux/list.h>
 #include <string.h>
 
 struct rsa_public_key;
@@ -28,7 +28,6 @@ static inline const char *public_key_type_string(enum public_key_type type)
 struct public_key {
 	enum public_key_type type;
 	const char *key_name_hint;
-	char *keyring;
 	const unsigned char *hash;
 	unsigned int hashlen;
 
@@ -38,21 +37,83 @@ struct public_key {
 	};
 };
 
-int public_key_add(struct public_key *key);
-const struct public_key *public_key_get(const char *name, const char *keyring);
-const struct public_key *public_key_next(const struct public_key *prev);
+/*
+ * Linker-list entry assigning a compiled-in public_key to a named keyring.
+ * Emitted by scripts/keytoc into .public_keys.rodata.* and consumed at init.
+ */
+struct public_key_record {
+	const char *keyring;
+	const struct public_key *key;
+};
+
+/*
+ * A keyring is a named container that holds keyring_link entries. Each link
+ * references either a public_key or another keyring (sub-keyring), so keyrings
+ * can be nested. A given key may be linked into any number of keyrings.
+ */
+struct keyring {
+	const char *name;
+	struct list_head links;	/* list of struct keyring_link */
+	struct list_head node;	/* link in keyring_registry */
+};
+
+enum keyring_link_type {
+	KEYRING_LINK_KEY,
+	KEYRING_LINK_KEYRING,
+};
+
+struct keyring_link {
+	enum keyring_link_type type;
+	struct list_head node;
+	union {
+		const struct public_key *key;
+		const struct keyring *keyring;
+	};
+};
+
+struct keyring *keyring_create(const char *name);
+struct keyring *keyring_find(const char *name);
+
+int keyring_link_key(struct keyring *kr, const struct public_key *key);
+int keyring_unlink_key(struct keyring *kr, const struct public_key *key);
+
+int keyring_link_keyring(struct keyring *kr, const struct keyring *sub);
+int keyring_unlink_keyring(struct keyring *kr, const struct keyring *sub);
+
+const struct public_key *keyring_find_key(const struct keyring *kr,
+					  const char *key_name_hint);
+
+#define KEYRING_MAX_DEPTH 4
+
+struct keyring_iter {
+	const struct keyring *stack[KEYRING_MAX_DEPTH];
+	struct list_head *cursor[KEYRING_MAX_DEPTH];
+	int depth;
+};
+
+const struct public_key *keyring_iter_next(struct keyring_iter *it,
+					   const struct keyring *root);
+
+/*
+ * Iterate every key reachable from @kr, recursing into sub-keyrings.
+ * The same key may be yielded more than once if it is linked into multiple
+ * (sub-)keyrings; callers that care must dedup themselves.
+ */
+#define for_each_key_in_keyring(key, kr)					\
+	for (struct keyring_iter __it = { .depth = -1 };			\
+	     ((key) = keyring_iter_next(&__it, (kr))) != NULL;			\
+	    )
 
-extern struct idr public_keys;
+/* Iterate only the direct links of @kr (does not recurse into sub-keyrings) */
+#define for_each_link_in_keyring(link, kr) \
+	list_for_each_entry(link, &(kr)->links, node)
 
-#define for_each_public_key(key, id) \
-		idr_for_each_entry(&public_keys, key, id)
+extern struct list_head keyring_registry;
 
-#define for_each_public_key_keyring(key, id, _keyring)                    \
-	for_each_public_key(key, id)                                      \
-		if (!key->keyring || strcmp(key->keyring, _keyring) != 0) \
-			continue;                                         \
-		else
+#define for_each_keyring(kr) \
+	list_for_each_entry(kr, &keyring_registry, node)
 
+int public_key_add(const char *keyring, const struct public_key *key);
 int public_key_verify(const struct public_key *key, const uint8_t *sig,
 		      const uint32_t sig_len, const uint8_t *hash,
 		      enum hash_algo algo);
diff --git a/scripts/keytoc.c b/scripts/keytoc.c
index 40601827b7..7e910422a7 100644
--- a/scripts/keytoc.c
+++ b/scripts/keytoc.c
@@ -535,7 +535,7 @@ static int gen_key_ecdsa(EVP_PKEY *key, struct keyinfo *info)
 		fprintf(stderr, "ERROR: generating a dts snippet for ECDSA keys is not yet supported\n");
 		return -EOPNOTSUPP;
 	} else {
-		fprintf(outfilep, "\nstatic unsigned char %s_hash[] = {\n\t", info->name_c);
+		fprintf(outfilep, "\nstatic const unsigned char %s_hash[] = {\n\t", info->name_c);
 
 		ret = print_hash(key);
 		if (ret)
@@ -557,24 +557,26 @@ static int gen_key_ecdsa(EVP_PKEY *key, struct keyinfo *info)
 
 		fprintf(outfilep, "\n};\n\n");
 
-		fprintf(outfilep, "static struct ecdsa_public_key %s = {\n", info->name_c);
+		fprintf(outfilep, "static const struct ecdsa_public_key %s = {\n", info->name_c);
 
 		fprintf(outfilep, "\t.curve_name = \"%s\",\n", group);
 		fprintf(outfilep, "\t.x = %s_x,\n", info->name_c);
 		fprintf(outfilep, "\t.y = %s_y,\n", info->name_c);
 		fprintf(outfilep, "};\n");
 		if (!standalone) {
-			fprintf(outfilep, "\nstatic struct public_key %s_public_key = {\n", info->name_c);
+			fprintf(outfilep, "\nstatic const struct public_key %s_public_key = {\n", info->name_c);
 			fprintf(outfilep, "\t.type = PUBLIC_KEY_TYPE_ECDSA,\n");
 			if (info->name_hint)
 				fprintf(outfilep, "\t.key_name_hint = \"%s\",\n", info->name_hint);
-			fprintf(outfilep, "\t.keyring = \"%s\",\n", info->keyring);
 			fprintf(outfilep, "\t.hash = %s_hash,\n", info->name_c);
 			fprintf(outfilep, "\t.hashlen = %u,\n", SHA256_DIGEST_LENGTH);
 			fprintf(outfilep, "\t.ecdsa = &%s,\n", info->name_c);
 			fprintf(outfilep, "};\n");
 			fprintf(outfilep, "\n");
-			fprintf(outfilep, "const struct public_key *__%s_public_key __ll_elem(.public_keys.rodata.%s) = &%s_public_key;\n", info->name_c, info->name_c, info->name_c);
+			fprintf(outfilep, "static const struct public_key_record __%s_public_key __ll_elem(.public_keys.rodata.%s) = {\n", info->name_c, info->name_c);
+			fprintf(outfilep, "\t.keyring = \"%s\",\n", info->keyring);
+			fprintf(outfilep, "\t.key = &%s_public_key,\n", info->name_c);
+			fprintf(outfilep, "};\n");
 		}
 	}
 
@@ -635,7 +637,7 @@ static int gen_key_rsa(EVP_PKEY *key, struct keyinfo *info)
 		fprintf(outfilep, "\t\t\tkey-name-hint = \"%s\";\n", info->name_c);
 		fprintf(outfilep, "\t\t};\n");
 	} else {
-		fprintf(outfilep, "\nstatic unsigned char %s_hash[] = {\n\t", info->name_c);
+		fprintf(outfilep, "\nstatic const unsigned char %s_hash[] = {\n\t", info->name_c);
 
 		ret = print_hash(key);
 		if (ret)
@@ -661,7 +663,7 @@ static int gen_key_rsa(EVP_PKEY *key, struct keyinfo *info)
 			fprintf(outfilep, "struct rsa_public_key __key_%s;\n", info->name_c);
 			fprintf(outfilep, "struct rsa_public_key __key_%s = {\n", info->name_c);
 		} else {
-			fprintf(outfilep, "static struct rsa_public_key %s = {\n", info->name_c);
+			fprintf(outfilep, "static const struct rsa_public_key %s = {\n", info->name_c);
 		}
 
 		fprintf(outfilep, "\t.len = %d,\n", bits / 32);
@@ -672,17 +674,19 @@ static int gen_key_rsa(EVP_PKEY *key, struct keyinfo *info)
 		fprintf(outfilep, "};\n");
 
 		if (!standalone) {
-			fprintf(outfilep, "\nstatic struct public_key %s_public_key = {\n", info->name_c);
+			fprintf(outfilep, "\nstatic const struct public_key %s_public_key = {\n", info->name_c);
 			fprintf(outfilep, "\t.type = PUBLIC_KEY_TYPE_RSA,\n");
 			if (info->name_hint)
 				fprintf(outfilep, "\t.key_name_hint = \"%s\",\n", info->name_hint);
-			fprintf(outfilep, "\t.keyring = \"%s\",\n", info->keyring);
 			fprintf(outfilep, "\t.hash = %s_hash,\n", info->name_c);
 			fprintf(outfilep, "\t.hashlen = %u,\n", SHA256_DIGEST_LENGTH);
 			fprintf(outfilep, "\t.rsa = &%s,\n", info->name_c);
 			fprintf(outfilep, "};\n");
 			fprintf(outfilep, "\n");
-			fprintf(outfilep, "const struct public_key *__%s_public_key __ll_elem(.public_keys.rodata.%s) = &%s_public_key;\n", info->name_c, info->name_c, info->name_c);
+			fprintf(outfilep, "static const struct public_key_record __%s_public_key __ll_elem(.public_keys.rodata.%s) = {\n", info->name_c, info->name_c);
+			fprintf(outfilep, "\t.keyring = \"%s\",\n", info->keyring);
+			fprintf(outfilep, "\t.key = &%s_public_key,\n", info->name_c);
+			fprintf(outfilep, "};\n");
 		}
 	}
 

-- 
2.47.3




  parent reply	other threads:[~2026-05-27 10:56 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-27 10:54 [PATCH 0/4] " Sascha Hauer
2026-05-27 10:54 ` [PATCH 1/4] public keys: make error message more informative Sascha Hauer
2026-05-27 10:54 ` [PATCH 2/4] public keys: make key_name_hint optional Sascha Hauer
2026-05-27 10:54 ` Sascha Hauer [this message]
2026-05-27 10:54 ` [PATCH 4/4] public keys: allow keys to be members of multiple keyrings Sascha Hauer
2026-05-29 11:43 ` [PATCH 0/4] public keys: rework keyrings as nested containers 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=20260527-public-keys-v1-3-c87a1cc61d1b@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