From 1e4a948673d709a2f8fcb9229b3cca77f3a25d51 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Oct 2019 11:48:43 +0200 Subject: command: Use array of pointers to commands We used to store the commands as a linker array. One problem with this is that on X86_64 for unknown reasons the linker uses a different struct alignment than the compiler, so when we use the linker to compose the array and the compiler to iterate over it we have to play tricks with manually adjusting the alignment. The other problem is that we declare the commands as const (and also put it in .rodata), but in fact we do not treat it as const: we put the commands onto a list which modifies the struct list_head list member of struct command. With this patch we no longer put the command themselves into an array, but instead create an array of pointers to the commands. This inherently solves the second issue as well. Signed-off-by: Sascha Hauer --- common/command.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'common') diff --git a/common/command.c b/common/command.c index d9cc4a6d48..49845938ae 100644 --- a/common/command.c +++ b/common/command.c @@ -149,12 +149,12 @@ EXPORT_SYMBOL(find_cmd); */ static int init_command_list(void) { - struct command *cmdtp; + struct command * const *cmdtp; - for (cmdtp = &__barebox_cmd_start; - cmdtp != &__barebox_cmd_end; + for (cmdtp = __barebox_cmd_start; + cmdtp != __barebox_cmd_end; cmdtp++) - register_command(cmdtp); + register_command(*cmdtp); return 0; } -- cgit v1.2.3 From d091a81f3ece732826dd4dec0b241624159ae1d6 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 1 Oct 2019 23:36:26 +0200 Subject: rsa: let rsa_of_read_key() return a fully allocated key Until now rsa_of_read_key() took a pointer to a key and filled the struct rsa_public_key members with allocated values. So far we have never freed these values. Change rsa_of_read_key() to always return a fully allocated key and provide rsa_key_free() to free it. Let the FIT image code free the key after usage. Signed-off-by: Sascha Hauer --- common/image-fit.c | 10 ++++++---- crypto/rsa.c | 26 ++++++++++++++++++++++---- include/rsa.h | 3 ++- 3 files changed, 30 insertions(+), 9 deletions(-) (limited to 'common') diff --git a/common/image-fit.c b/common/image-fit.c index 6ac4644686..71053fbef5 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -269,7 +269,7 @@ 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 = {}; + struct rsa_public_key *key; const char *key_name; char *key_path; struct device_node *key_node; @@ -296,18 +296,20 @@ static int fit_check_rsa_signature(struct device_node *sig_node, } free(key_path); - ret = rsa_of_read_key(key_node, &key); - if (ret) { + 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; } - ret = rsa_verify(&key, sig_value, sig_len, hash, algo); + ret = rsa_verify(key, sig_value, sig_len, hash, algo); if (ret) pr_err("image signature BAD\n"); else pr_info("image signature OK\n"); + rsa_key_free(key); + return ret; } diff --git a/crypto/rsa.c b/crypto/rsa.c index 591d15c415..2e70c8127d 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -380,11 +380,15 @@ static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len) dst[i] = fdt32_to_cpu(src[len - 1 - i]); } -int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key) +struct rsa_public_key *rsa_of_read_key(struct device_node *node) { const void *modulus, *rr; const uint64_t *public_exponent; int length; + struct rsa_public_key *key; + int err; + + key = xzalloc(sizeof(*key)); of_property_read_u32(node, "rsa,num-bits", &key->len); of_property_read_u32(node, "rsa,n0-inverse", &key->n0inv); @@ -400,14 +404,16 @@ int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key) if (!key->len || !modulus || !rr) { debug("%s: Missing RSA key info", __func__); - return -EFAULT; + err = -EFAULT; + goto out; } /* Sanity check for stack size */ if (key->len > RSA_MAX_KEY_BITS || key->len < RSA_MIN_KEY_BITS) { debug("RSA key bits %u outside allowed range %d..%d\n", key->len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS); - return -EFAULT; + err = -EFAULT; + goto out; } key->len /= sizeof(uint32_t) * 8; @@ -418,5 +424,17 @@ int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key) rsa_convert_big_endian(key->modulus, modulus, key->len); rsa_convert_big_endian(key->rr, rr, key->len); - return 0; + err = 0; +out: + if (err) + free(key); + + return err ? ERR_PTR(err) : key; +} + +void rsa_key_free(struct rsa_public_key *key) +{ + free(key->modulus); + free(key->rr); + free(key); } diff --git a/include/rsa.h b/include/rsa.h index feb8c31200..cf2e6c7e08 100644 --- a/include/rsa.h +++ b/include/rsa.h @@ -49,6 +49,7 @@ int rsa_verify(const struct rsa_public_key *key, const uint8_t *sig, /* This is the maximum signature length that we support, in bits */ #define RSA_MAX_SIG_BITS 4096 -int rsa_of_read_key(struct device_node *node, struct rsa_public_key *key); +struct rsa_public_key *rsa_of_read_key(struct device_node *node); +void rsa_key_free(struct rsa_public_key *key); #endif -- cgit v1.2.3 From 9341918ba869bcbdd1b9147d1ae85f1f27440557 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 1 Oct 2019 23:45:37 +0200 Subject: fit-image: Use compiled-in keys The compiled-in keys can be retrieved with rsa_get_key(). Try to use them first before falling back to looking up the keys in the device tree. Signed-off-by: Sascha Hauer --- common/image-fit.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'common') diff --git a/common/image-fit.c b/common/image-fit.c index 71053fbef5..2681d62a9a 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -287,19 +287,24 @@ static int fit_check_rsa_signature(struct device_node *sig_node, pr_err("key name not found in %s\n", sig_node->full_name); return -EINVAL; } - 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); + key = rsa_get_key(key_name); if (IS_ERR(key)) { - pr_info("failed to read key in %s\n", key_node->full_name); - return -ENOENT; + 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; + } } ret = rsa_verify(key, sig_value, sig_len, hash, algo); -- cgit v1.2.3