image: Combine image_sig_algo with image_sign_info
authorAndrew Duda <aduda@meraki.com>
Tue, 8 Nov 2016 18:53:41 +0000 (18:53 +0000)
committerTom Rini <trini@konsulko.com>
Mon, 21 Nov 2016 19:07:31 +0000 (14:07 -0500)
Remove the need to explicitly add SHA/RSA pairings. Invalid SHA/RSA
pairings will still fail on verify operations when the hash length is
longer than the key length.

Follow the same naming scheme "checksum,crytpo" without explicitly
defining the string.

Indirectly adds support for "sha1,rsa4096" signing/verification.

Signed-off-by: Andrew Duda <aduda@meraki.com>
Signed-off-by: aduda <aduda@meraki.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
common/image-sig.c
include/image.h
lib/rsa/rsa-sign.c
lib/rsa/rsa-verify.c
tools/image-host.c

index 8b4314de09ded29dcc6c6322fb5ed835eab201f5..455f2b96294985af5fb7fb9011bb45e2bc8b33b3 100644 (file)
@@ -72,32 +72,36 @@ struct crypto_algo crypto_algos[] = {
 
 };
 
-struct image_sig_algo image_sig_algos[] = {
-       {
-               "sha1,rsa2048",
-               &crypto_algos[0],
-               &checksum_algos[0],
-       },
-       {
-               "sha256,rsa2048",
-               &crypto_algos[0],
-               &checksum_algos[1],
-       },
-       {
-               "sha256,rsa4096",
-               &crypto_algos[1],
-               &checksum_algos[1],
+struct checksum_algo *image_get_checksum_algo(const char *full_name)
+{
+       int i;
+       const char *name;
+
+       for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
+               name = checksum_algos[i].name;
+               /* Make sure names match and next char is a comma */
+               if (!strncmp(name, full_name, strlen(name)) &&
+                   full_name[strlen(name)] == ',')
+                       return &checksum_algos[i];
        }
 
-};
+       return NULL;
+}
 
-struct image_sig_algo *image_get_sig_algo(const char *name)
+struct crypto_algo *image_get_crypto_algo(const char *full_name)
 {
        int i;
+       const char *name;
+
+       /* Move name to after the comma */
+       name = strchr(full_name, ',');
+       if (!name)
+               return NULL;
+       name += 1;
 
-       for (i = 0; i < ARRAY_SIZE(image_sig_algos); i++) {
-               if (!strcmp(image_sig_algos[i].name, name))
-                       return &image_sig_algos[i];
+       for (i = 0; i < ARRAY_SIZE(crypto_algos); i++) {
+               if (!strcmp(crypto_algos[i].name, name))
+                       return &crypto_algos[i];
        }
 
        return NULL;
@@ -161,12 +165,14 @@ static int fit_image_setup_verify(struct image_sign_info *info,
        info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
        info->fit = (void *)fit;
        info->node_offset = noffset;
-       info->algo = image_get_sig_algo(algo_name);
+       info->name = algo_name;
+       info->checksum = image_get_checksum_algo(algo_name);
+       info->crypto = image_get_crypto_algo(algo_name);
        info->fdt_blob = gd_fdt_blob();
        info->required_keynode = required_keynode;
        printf("%s:%s", algo_name, info->keyname);
 
-       if (!info->algo) {
+       if (!info->checksum || !info->crypto) {
                *err_msgp = "Unknown signature algorithm";
                return -1;
        }
@@ -196,8 +202,7 @@ int fit_image_check_sig(const void *fit, int noffset, const void *data,
        region.data = data;
        region.size = size;
 
-       if (info.algo->crypto->verify(&info, &region, 1, fit_value,
-                                     fit_value_len)) {
+       if (info.crypto->verify(&info, &region, 1, fit_value, fit_value_len)) {
                *err_msgp = "Verification failed";
                return -1;
        }
@@ -378,8 +383,8 @@ int fit_config_check_sig(const void *fit, int noffset, int required_keynode,
        struct image_region region[count];
 
        fit_region_make_list(fit, fdt_regions, count, region);
-       if (info.algo->crypto->verify(&info, region, count, fit_value,
-                                     fit_value_len)) {
+       if (info.crypto->verify(&info, region, count, fit_value,
+                               fit_value_len)) {
                *err_msgp = "Verification failed";
                return -1;
        }
index c3c98667381685dffab676ea04fe5eb0a84ed1c6..81315959fe2a539a52ed113f6d5eef32d2f815c6 100644 (file)
@@ -1049,7 +1049,9 @@ struct image_sign_info {
        const char *keyname;            /* Name of key to use */
        void *fit;                      /* Pointer to FIT blob */
        int node_offset;                /* Offset of signature node */
-       struct image_sig_algo *algo;    /* Algorithm information */
+       const char *name;               /* Algorithm name */
+       struct checksum_algo *checksum; /* Checksum algorithm information */
+       struct crypto_algo *crypto;     /* Crypto algorithm information */
        const void *fdt_blob;           /* FDT containing public keys */
        int required_keynode;           /* Node offset of key to use: -1=any */
        const char *require_keys;       /* Value for 'required' property */
@@ -1133,21 +1135,21 @@ struct crypto_algo {
                      uint8_t *sig, uint sig_len);
 };
 
-struct image_sig_algo {
-       const char *name;
-       /* pointer to cryptosystem algorithm */
-       struct crypto_algo *crypto;
-       /* pointer to checksum algorithm */
-       struct checksum_algo *checksum;
-};
+/**
+ * image_get_checksum_algo() - Look up a checksum algorithm
+ *
+ * @param full_name    Name of algorithm in the form "checksum,crypto"
+ * @return pointer to algorithm information, or NULL if not found
+ */
+struct checksum_algo *image_get_checksum_algo(const char *full_name);
 
 /**
- * image_get_sig_algo() - Look up a signature algortihm
+ * image_get_crypto_algo() - Look up a cryptosystem algorithm
  *
- * @param name         Name of algorithm
+ * @param full_name    Name of algorithm in the form "checksum,crypto"
  * @return pointer to algorithm information, or NULL if not found
  */
-struct image_sig_algo *image_get_sig_algo(const char *name);
+struct crypto_algo *image_get_crypto_algo(const char *full_name);
 
 /**
  * fit_image_verify_required_sigs() - Verify signatures marked as 'required'
index c26f74128f2814e75e9032c89ffe569bb44eef8f..9a09280013084078ae76b17aba088cadf327784c 100644 (file)
@@ -244,7 +244,7 @@ int rsa_sign(struct image_sign_info *info,
        ret = rsa_get_priv_key(info->keydir, info->keyname, &rsa);
        if (ret)
                goto err_priv;
-       ret = rsa_sign_with_key(rsa, info->algo->checksum, region,
+       ret = rsa_sign_with_key(rsa, info->checksum, region,
                                region_count, sigp, sig_len);
        if (ret)
                goto err_sign;
@@ -508,7 +508,7 @@ int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
        }
        if (!ret) {
                ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP,
-                                        info->algo->name);
+                                        info->name);
        }
        if (!ret && info->require_keys) {
                ret = fdt_setprop_string(keydest, node, "required",
index 61dc4c2e706037ab6071d0142af00953a5b97806..0d548f8b8f93deaa313a338df0f011b234998929 100644 (file)
@@ -184,8 +184,7 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
        }
 
        ret = rsa_verify_key(&prop, sig, sig_len, hash,
-                            info->algo->crypto->key_len,
-                            info->algo->checksum);
+                            info->crypto->key_len, info->checksum);
 
        return ret;
 }
@@ -196,7 +195,7 @@ int rsa_verify(struct image_sign_info *info,
 {
        const void *blob = info->fdt_blob;
        /* Reserve memory for maximum checksum-length */
-       uint8_t hash[info->algo->crypto->key_len];
+       uint8_t hash[info->crypto->key_len];
        int ndepth, noffset;
        int sig_node, node;
        char name[100];
@@ -206,11 +205,10 @@ int rsa_verify(struct image_sign_info *info,
         * Verify that the checksum-length does not exceed the
         * rsa-signature-length
         */
-       if (info->algo->checksum->checksum_len >
-           info->algo->crypto->key_len) {
+       if (info->checksum->checksum_len >
+           info->crypto->key_len) {
                debug("%s: invlaid checksum-algorithm %s for %s\n",
-                     __func__, info->algo->checksum->name,
-                     info->algo->crypto->name);
+                     __func__, info->checksum->name, info->crypto->name);
                return -EINVAL;
        }
 
@@ -221,7 +219,7 @@ int rsa_verify(struct image_sign_info *info,
        }
 
        /* Calculate checksum with checksum-algorithm */
-       ret = info->algo->checksum->calculate(info->algo->checksum->name,
+       ret = info->checksum->calculate(info->checksum->name,
                                        region, region_count, hash);
        if (ret < 0) {
                debug("%s: Error in checksum calculation\n", __func__);
index dac85b4b747ed312f6683c1a46674fab3a171c47..c1a01225e2bf14547391217b76709bd84c790a88 100644 (file)
@@ -166,9 +166,11 @@ static int fit_image_setup_sig(struct image_sign_info *info,
        info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
        info->fit = fit;
        info->node_offset = noffset;
-       info->algo = image_get_sig_algo(algo_name);
+       info->name = algo_name;
+       info->checksum = image_get_checksum_algo(algo_name);
+       info->crypto = image_get_crypto_algo(algo_name);
        info->require_keys = require_keys;
-       if (!info->algo) {
+       if (!info->checksum || !info->crypto) {
                printf("Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n",
                       algo_name, node_name, image_name);
                return -1;
@@ -213,7 +215,7 @@ static int fit_image_process_sig(const char *keydir, void *keydest,
        node_name = fit_get_name(fit, noffset, NULL);
        region.data = data;
        region.size = size;
-       ret = info.algo->crypto->sign(&info, &region, 1, &value, &value_len);
+       ret = info.crypto->sign(&info, &region, 1, &value, &value_len);
        if (ret) {
                printf("Failed to sign '%s' signature node in '%s' image node: %d\n",
                       node_name, image_name, ret);
@@ -239,7 +241,7 @@ static int fit_image_process_sig(const char *keydir, void *keydest,
        info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
 
        if (keydest)
-               ret = info.algo->crypto->add_verify_data(&info, keydest);
+               ret = info.crypto->add_verify_data(&info, keydest);
        else
                return -1;
 
@@ -588,8 +590,8 @@ static int fit_config_process_sig(const char *keydir, void *keydest,
                                require_keys ? "conf" : NULL))
                return -1;
 
-       ret = info.algo->crypto->sign(&info, region, region_count, &value,
-                                     &value_len);
+       ret = info.crypto->sign(&info, region, region_count, &value,
+                               &value_len);
        free(region);
        if (ret) {
                printf("Failed to sign '%s' signature node in '%s' conf node\n",
@@ -618,7 +620,7 @@ static int fit_config_process_sig(const char *keydir, void *keydest,
 
        /* Write the public key into the supplied FDT file */
        if (keydest) {
-               ret = info.algo->crypto->add_verify_data(&info, keydest);
+               ret = info.crypto->add_verify_data(&info, keydest);
                if (ret == -ENOSPC)
                        return -ENOSPC;
                if (ret) {