summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2022-05-04 11:49:28 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2022-05-04 15:12:31 +0200
commitb2f33a4b95af0566c735cfc188dc8758636c2263 (patch)
treef1393092fe111ddebcf3c71ff482dcf2f4a840ee
parenta05ac5545c43a5420757e0f5529edea95230ced5 (diff)
downloadbarebox-b2f33a4b95af0566c735cfc188dc8758636c2263.tar.gz
rsa: Collect keys on list
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@pengutronix.de>
-rw-r--r--common/image-fit.c25
-rw-r--r--crypto/rsa.c97
-rw-r--r--include/rsa.h3
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