[PATCH v6 10/15] tools: mkimage: pre-load: add support of ecdsa
Raymond Mao
raymondmaoca at gmail.com
Mon May 25 17:34:35 CEST 2026
Hi Philippe,
On Mon, May 25, 2026 at 9:52 AM Philippe Reynes
<philippe.reynes at softathome.com> wrote:
>
> Right now, mkimage can only create pre-load header
> using rsa. We add the support of ecdsa.
>
> Reviewed-by: Simon Glass <sjg at chromium.org>
> Signed-off-by: Philippe Reynes <philippe.reynes at softathome.com>
> ---
> 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
>
> lib/ecdsa/ecdsa-libcrypto.c | 29 +++++++++---
> tools/image-host.c | 92 ++++++++++++++++++++++++++++++++-----
> 2 files changed, 103 insertions(+), 18 deletions(-)
>
Looks good to me. Thanks!
Reviewed-by: Raymond Mao <raymondmaoca at gmail.com>
> 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
>
More information about the U-Boot
mailing list