Right now, mkimage can only create pre-load header using rsa. We add the support of ecdsa.
Reviewed-by: Simon Glass <[email protected]> Reviewed-by: Raymond Mao <[email protected]> Signed-off-by: Philippe Reynes <[email protected]> --- v3: - initial version v4: - use pre_load_noffset (do not compute it again) - release memory allocated with strdup - clean code v5: - check checksum and algo before using them v6: - no change v6: - no change lib/ecdsa/ecdsa-libcrypto.c | 29 +++++++++--- tools/image-host.c | 92 ++++++++++++++++++++++++++++++++----- 2 files changed, 103 insertions(+), 18 deletions(-) diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c index 89c1851b71d..4a1d0caf502 100644 --- a/lib/ecdsa/ecdsa-libcrypto.c +++ b/lib/ecdsa/ecdsa-libcrypto.c @@ -507,14 +507,9 @@ int ecdsa_verify(struct image_sign_info *info, return ret; } -static int do_add(struct signer *ctx, void *fdt, const char *key_node_name, - struct image_sign_info *info) +static int search_key_node(void *fdt, const char *key_node_name) { - int signature_node, key_node, ret, key_bits; - const char *curve_name; - const EC_GROUP *group; - const EC_POINT *point; - BIGNUM *x, *y; + int signature_node, key_node; signature_node = fdt_subnode_offset(fdt, 0, FIT_SIG_NODENAME); if (signature_node == -FDT_ERR_NOTFOUND) { @@ -549,6 +544,26 @@ static int do_add(struct signer *ctx, void *fdt, const char *key_node_name, return key_node; } + return key_node; +} + +static int do_add(struct signer *ctx, void *fdt, const char *key_node_name, + struct image_sign_info *info) +{ + int key_node, ret, key_bits; + const char *curve_name; + const EC_GROUP *group; + const EC_POINT *point; + BIGNUM *x, *y; + + if (info->required_keynode >= 0) { + key_node = info->required_keynode; + } else { + key_node = search_key_node(fdt, key_node_name); + if (key_node < 0) + return key_node; + } + group = EC_KEY_get0_group(ctx->ecdsa_key); key_bits = EC_GROUP_order_bits(group); curve_name = OBJ_nid2sn(EC_GROUP_get_curve_name(group)); diff --git a/tools/image-host.c b/tools/image-host.c index f5681d6c1f9..ae35a75d5a6 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -13,6 +13,7 @@ #include <fdt_region.h> #include <image.h> #include <version.h> +#include <u-boot/ecdsa.h> #if CONFIG_IS_ENABLED(FIT_SIGNATURE) #include <openssl/pem.h> @@ -1245,13 +1246,74 @@ err_cert: return ret; } +static int fit_pre_load_data_key_rsa(const char *keydir, void *keydest, + int pre_load_noffset, const void *key_name) +{ + unsigned char *pubkey = NULL; + int ret, pubkey_len; + + /* Read public key */ + ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len); + if (ret < 0) + goto out; + + /* Add the public key to the device tree */ + ret = fdt_setprop(keydest, pre_load_noffset, "public-key", + pubkey, pubkey_len); + if (ret) + fprintf(stderr, "Can't set public-key in node %s (ret = %d)\n", + IMAGE_PRE_LOAD_PATH, ret); + out: + return ret; +} + +static int fit_pre_load_data_key_ecdsa(const char *keydir, void *keydest, + int pre_load_noffset, const void *key_name, + const void *algo_name) +{ + struct image_sign_info info; + int node, ret = 0; + + memset(&info, 0, sizeof(info)); + info.keydir = keydir; + info.keyname = strdup(key_name); + info.name = strdup(algo_name); + info.checksum = image_get_checksum_algo(algo_name); + if (!info.checksum) { + fprintf(stderr, "Can't find valid checksum from %s\n", + (char *)algo_name); + ret = -EINVAL; + goto out; + } + info.crypto = image_get_crypto_algo(algo_name); + if (!info.crypto) { + fprintf(stderr, "Can't find valid crypto from %s\n", + (char *)algo_name); + ret = -EINVAL; + goto out; + } + info.required_keynode = pre_load_noffset; + + node = ecdsa_add_verify_data(&info, keydest); + if (node < 0) { + fprintf(stderr, "Can't add verify data: err = %d\n", node); + ret = -EIO; + } + + out: + free((void *)info.keyname); + free((void *)info.name); + + return ret; +} + int fit_pre_load_data(const char *keydir, void *keydest, void *fit) { int pre_load_noffset; const void *algo_name; const void *key_name; - unsigned char *pubkey = NULL; - int ret, pubkey_len; + char *name; + int ret; if (!keydir || !keydest || !fit) return 0; @@ -1278,17 +1340,25 @@ int fit_pre_load_data(const char *keydir, void *keydest, void *fit) goto out; } - /* Read public key */ - ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len); - if (ret < 0) + /* Is it a RSA or an ECDSA key */ + name = strchr((const char *)algo_name, ','); + if (!name) { + fprintf(stderr, "The name of the algo is invalid: %s\n", + (char *)algo_name); + ret = -EINVAL; goto out; + } + name += 1; - /* Add the public key to the device tree */ - ret = fdt_setprop(keydest, pre_load_noffset, "public-key", - pubkey, pubkey_len); - if (ret) - fprintf(stderr, "Can't set public-key in node %s (ret = %d)\n", - IMAGE_PRE_LOAD_PATH, ret); + if (!strncmp(name, "rsa", 3)) { + ret = fit_pre_load_data_key_rsa(keydir, keydest, pre_load_noffset, key_name); + } else if (!strncmp(name, "ecdsa", 5)) { + ret = fit_pre_load_data_key_ecdsa(keydir, keydest, pre_load_noffset, + key_name, algo_name); + } else { + fprintf(stderr, "The algo %s is not supported\n", (char *)algo_name); + ret = -EINVAL; + } out: return ret; -- 2.43.0

