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