Right now, mkimage can only create pre-load header
using rsa. We add the support of ecdsa.

Signed-off-by: Philippe Reynes <[email protected]>
---
v3:
- initial version

 lib/ecdsa/ecdsa-libcrypto.c | 29 ++++++++++----
 tools/image-host.c          | 78 +++++++++++++++++++++++++++++++------
 2 files changed, 88 insertions(+), 19 deletions(-)

diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c
index f8ed694595c..ff396ef9987 100644
--- a/lib/ecdsa/ecdsa-libcrypto.c
+++ b/lib/ecdsa/ecdsa-libcrypto.c
@@ -463,14 +463,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) {
@@ -505,6 +500,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 8b550af0dc1..9e7f756a276 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>
@@ -1244,13 +1245,62 @@ 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 keynode;
+
+       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);
+       info.crypto = image_get_crypto_algo(algo_name);
+
+       keynode = fdt_path_offset(keydest, IMAGE_PRE_LOAD_PATH);
+       if (keynode < 0) {
+               fprintf(stderr, "Cannot select keys key_node: %s\n",
+                       fdt_strerror(keynode));
+               return keynode;
+       }
+
+       info.required_keynode = keynode;
+
+       ecdsa_add_verify_data(&info, keydest);
+
+       return 0;
+}
+
 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;
@@ -1277,17 +1327,21 @@ 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)
-               goto out;
+       /* Is it a RSA or an ECDSA key */
+       name = strchr((const char *)algo_name, ',');
+       if (!name)
+               return -EINVAL;
+       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

Reply via email to