[PATCH 4/8] rsa: Collect keys on list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently there is no way to iterate over all available RSA keys.
This patch collects all keys on a list so we can add an iterator
in the next step.

Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
---
 common/image-fit.c | 25 ++----------
 crypto/rsa.c       | 97 ++++++++++++++++++++++++++++++++++++++--------
 include/rsa.h      |  3 +-
 3 files changed, 86 insertions(+), 39 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 38a372ff52..152d066f47 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -255,10 +255,8 @@ static struct digest *fit_alloc_digest(struct device_node *sig_node,
 static int fit_check_rsa_signature(struct device_node *sig_node,
 				   enum hash_algo algo, void *hash)
 {
-	struct rsa_public_key *key;
+	const struct rsa_public_key *key;
 	const char *key_name;
-	char *key_path;
-	struct device_node *key_node;
 	int sig_len;
 	const char *sig_value;
 	int ret;
@@ -275,22 +273,9 @@ static int fit_check_rsa_signature(struct device_node *sig_node,
 	}
 
 	key = rsa_get_key(key_name);
-	if (IS_ERR(key)) {
-		key_path = xasprintf("/signature/key-%s", key_name);
-		key_node = of_find_node_by_path(key_path);
-		if (!key_node) {
-			pr_info("failed to find key node %s\n", key_path);
-			free(key_path);
-			return -ENOENT;
-		}
-		free(key_path);
-
-		key = rsa_of_read_key(key_node);
-
-		if (IS_ERR(key)) {
-			pr_info("failed to read key in %s\n", key_node->full_name);
-			return -ENOENT;
-		}
+	if (!key) {
+		pr_err("No such key: %s\n", key_name);
+		return -ENOENT;
 	}
 
 	ret = rsa_verify(key, sig_value, sig_len, hash, algo);
@@ -299,8 +284,6 @@ static int fit_check_rsa_signature(struct device_node *sig_node,
 	else
 		pr_info("image signature OK\n");
 
-	rsa_key_free(key);
-
 	return ret;
 }
 
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 1aea738e52..4e2d463b54 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -388,8 +388,13 @@ struct rsa_public_key *rsa_of_read_key(struct device_node *node)
 	struct rsa_public_key *key;
 	int err;
 
+	if (strncmp(node->name, "key-", 4))
+		return ERR_PTR(-EINVAL);
+
 	key = xzalloc(sizeof(*key));
 
+	key->key_name_hint = xstrdup(node->name + 4);
+
 	of_property_read_u32(node, "rsa,num-bits", &key->len);
 	of_property_read_u32(node, "rsa,n0-inverse", &key->n0inv);
 
@@ -439,35 +444,93 @@ void rsa_key_free(struct rsa_public_key *key)
 	free(key);
 }
 
-#ifdef CONFIG_CRYPTO_RSA_BUILTIN_KEYS
-#include "rsa-keys.h"
-
-extern const struct rsa_public_key * const __rsa_keys_start;
-extern const struct rsa_public_key * const __rsa_keys_end;
+static LIST_HEAD(rsa_keys);
 
-struct rsa_public_key *rsa_get_key(const char *name)
+const struct rsa_public_key *rsa_get_key(const char *name)
 {
 	const struct rsa_public_key *key;
-	struct rsa_public_key *new;
-	const struct rsa_public_key * const *iter;
 
-	for (iter = &__rsa_keys_start; iter != &__rsa_keys_end; iter++) {
-		key = *iter;
-		if (!strcmp(name, key->key_name_hint))
-			goto found;
+	list_for_each_entry(key, &rsa_keys, list) {
+		if (!strcmp(key->key_name_hint, name))
+			return key;
 	}
 
-	return ERR_PTR(-ENOENT);
-found:
+	return NULL;
+}
+
+static int rsa_key_add(struct rsa_public_key *key)
+{
+	if (rsa_get_key(key->key_name_hint))
+		return -EEXIST;
+
+	list_add_tail(&key->list, &rsa_keys);
+
+	return 0;
+}
+
+static struct rsa_public_key *rsa_key_dup(const struct rsa_public_key *key)
+{
+	struct rsa_public_key *new;
+
 	new = xmemdup(key, sizeof(*key));
 	new->modulus = xmemdup(key->modulus, key->len * sizeof(uint32_t));
 	new->rr = xmemdup(key->rr, key->len  * sizeof(uint32_t));
 
 	return new;
 }
-#else
-struct rsa_public_key *rsa_get_key(const char *name)
+
+extern const struct rsa_public_key * const __rsa_keys_start;
+extern const struct rsa_public_key * const __rsa_keys_end;
+
+static void rsa_init_keys_of(void)
 {
-	return ERR_PTR(-ENOENT);
+	struct device_node *sigs, *sig;
+	struct rsa_public_key *key;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_OFTREE))
+		return;
+
+	sigs = of_find_node_by_path("/signature");
+	if (!sigs)
+		return;
+
+	for_each_child_of_node(sigs, sig) {
+		key = rsa_of_read_key(sig);
+		if (IS_ERR(key)) {
+			pr_err("Cannot read rsa key from %s: %pe\n",
+			       sig->full_name, key);
+			continue;
+		}
+
+		ret = rsa_key_add(key);
+		if (ret)
+			pr_err("Cannot add rsa key %s: %s\n",
+				key->key_name_hint, strerror(-ret));
+	}
 }
+
+static int rsa_init_keys(void)
+{
+	const struct rsa_public_key * const *iter;
+	struct rsa_public_key *key;
+	int ret;
+
+	for (iter = &__rsa_keys_start; iter != &__rsa_keys_end; iter++) {
+		key = rsa_key_dup(*iter);
+		ret = rsa_key_add(key);
+		if (ret)
+			pr_err("Cannot add rsa key %s: %s\n",
+			       key->key_name_hint, strerror(-ret));
+	}
+
+	rsa_init_keys_of();
+
+	return 0;
+}
+
+device_initcall(rsa_init_keys);
+
+#ifdef CONFIG_CRYPTO_RSA_BUILTIN_KEYS
+#include "rsa-keys.h"
 #endif
diff --git a/include/rsa.h b/include/rsa.h
index 803660d19a..4ef16ea5a8 100644
--- a/include/rsa.h
+++ b/include/rsa.h
@@ -29,6 +29,7 @@ struct rsa_public_key {
 	uint32_t *rr;		/* R^2 as little endian array */
 	uint64_t exponent;	/* public exponent */
 	char *key_name_hint;
+	struct list_head list;
 };
 
 /**
@@ -52,6 +53,6 @@ int rsa_verify(const struct rsa_public_key *key, const uint8_t *sig,
 
 struct rsa_public_key *rsa_of_read_key(struct device_node *node);
 void rsa_key_free(struct rsa_public_key *key);
-struct rsa_public_key *rsa_get_key(const char *name);
+const struct rsa_public_key *rsa_get_key(const char *name);
 
 #endif
-- 
2.30.2


_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux