[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