X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=tools%2Fimage-host.c;h=d42c1cae4ee9e6751f99989b96e86d8b450d33a8;hb=6793d017a7679477402f5d30229651dba0db5ed2;hp=0eff720b62178972aa92290aea457590c8c42b56;hpb=d6694aff569a0838a9d0ef352128f5aa309d73ff;p=people%2Fms%2Fu-boot.git diff --git a/tools/image-host.c b/tools/image-host.c index 0eff720b62..d42c1cae4e 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -38,7 +38,7 @@ static int fit_set_hash_value(void *fit, int noffset, uint8_t *value, printf("Can't set hash '%s' property for '%s' node(%s)\n", FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL), fdt_strerror(ret)); - return -1; + return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO; } return 0; @@ -64,25 +64,27 @@ static int fit_image_process_hash(void *fit, const char *image_name, const char *node_name; int value_len; char *algo; + int ret; node_name = fit_get_name(fit, noffset, NULL); if (fit_image_hash_get_algo(fit, noffset, &algo)) { printf("Can't get hash algo property for '%s' hash node in '%s' image node\n", node_name, image_name); - return -1; + return -ENOENT; } if (calculate_hash(data, size, algo, value, &value_len)) { printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n", algo, node_name, image_name); - return -1; + return -EPROTONOSUPPORT; } - if (fit_set_hash_value(fit, noffset, value, value_len)) { + ret = fit_set_hash_value(fit, noffset, value, value_len); + if (ret) { printf("Can't set hash value for '%s' hash node in '%s' image node\n", node_name, image_name); - return -1; + return ret; } return 0; @@ -147,7 +149,7 @@ static int fit_image_write_sig(void *fit, int noffset, uint8_t *value, static int fit_image_setup_sig(struct image_sign_info *info, const char *keydir, void *fit, const char *image_name, - int noffset, const char *require_keys) + int noffset, const char *require_keys, const char *engine_id) { const char *node_name; char *algo_name; @@ -164,9 +166,12 @@ 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 = strdup(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) { + info->engine_id = engine_id; + 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; @@ -190,12 +195,13 @@ static int fit_image_setup_sig(struct image_sign_info *info, * @size: size of data in bytes * @comment: Comment to add to signature nodes * @require_keys: Mark all keys as 'required' + * @engine_id: Engine to use for signing * @return 0 if ok, -1 on error */ static int fit_image_process_sig(const char *keydir, void *keydest, void *fit, const char *image_name, int noffset, const void *data, size_t size, - const char *comment, int require_keys) + const char *comment, int require_keys, const char *engine_id) { struct image_sign_info info; struct image_region region; @@ -205,13 +211,13 @@ static int fit_image_process_sig(const char *keydir, void *keydest, int ret; if (fit_image_setup_sig(&info, keydir, fit, image_name, noffset, - require_keys ? "image" : NULL)) + require_keys ? "image" : NULL, engine_id)) return -1; node_name = fit_get_name(fit, noffset, NULL); region.data = data; region.size = size; - ret = info.algo->sign(&info, ®ion, 1, &value, &value_len); + ret = info.crypto->sign(&info, ®ion, 1, &value, &value_len); if (ret) { printf("Failed to sign '%s' signature node in '%s' image node: %d\n", node_name, image_name, ret); @@ -236,11 +242,18 @@ static int fit_image_process_sig(const char *keydir, void *keydest, /* Get keyname again, as FDT has changed and invalidated our pointer */ info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); - /* Write the public key into the supplied FDT file */ - if (keydest && info.algo->add_verify_data(&info, keydest)) { - printf("Failed to add verification data for '%s' signature node in '%s' image node\n", - node_name, image_name); - return -1; + /* + * Write the public key into the supplied FDT file; this might fail + * several times, since we try signing with successively increasing + * size values + */ + if (keydest) { + ret = info.crypto->add_verify_data(&info, keydest); + if (ret) { + printf("Failed to add verification data for '%s' signature node in '%s' image node\n", + node_name, image_name); + return ret; + } } return 0; @@ -278,11 +291,12 @@ static int fit_image_process_sig(const char *keydir, void *keydest, * @image_noffset: Requested component image node * @comment: Comment to add to signature nodes * @require_keys: Mark all keys as 'required' + * @engine_id: Engine to use for signing * @return: 0 on success, <0 on failure */ int fit_image_add_verification_data(const char *keydir, void *keydest, void *fit, int image_noffset, const char *comment, - int require_keys) + int require_keys, const char *engine_id) { const char *image_name; const void *data; @@ -319,10 +333,10 @@ int fit_image_add_verification_data(const char *keydir, void *keydest, strlen(FIT_SIG_NODENAME))) { ret = fit_image_process_sig(keydir, keydest, fit, image_name, noffset, data, size, - comment, require_keys); + comment, require_keys, engine_id); } if (ret) - return -1; + return ret; } return 0; @@ -500,7 +514,7 @@ static int fit_config_get_data(void *fit, int conf_noffset, int noffset, int ret, len; conf_name = fit_get_name(fit, conf_noffset, NULL); - sig_name = fit_get_name(fit, conf_noffset, NULL); + sig_name = fit_get_name(fit, noffset, NULL); debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name); /* Get a list of nodes we want to hash */ @@ -559,7 +573,8 @@ static int fit_config_get_data(void *fit, int conf_noffset, int noffset, static int fit_config_process_sig(const char *keydir, void *keydest, void *fit, const char *conf_name, int conf_noffset, - int noffset, const char *comment, int require_keys) + int noffset, const char *comment, int require_keys, + const char *engine_id) { struct image_sign_info info; const char *node_name; @@ -577,10 +592,11 @@ static int fit_config_process_sig(const char *keydir, void *keydest, return -1; if (fit_image_setup_sig(&info, keydir, fit, conf_name, noffset, - require_keys ? "conf" : NULL)) + require_keys ? "conf" : NULL, engine_id)) return -1; - ret = info.algo->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", @@ -609,7 +625,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->add_verify_data(&info, keydest); + ret = info.crypto->add_verify_data(&info, keydest); if (ret == -ENOSPC) return -ENOSPC; if (ret) { @@ -624,7 +640,7 @@ static int fit_config_process_sig(const char *keydir, void *keydest, static int fit_config_add_verification_data(const char *keydir, void *keydest, void *fit, int conf_noffset, const char *comment, - int require_keys) + int require_keys, const char *engine_id) { const char *conf_name; int noffset; @@ -643,7 +659,7 @@ static int fit_config_add_verification_data(const char *keydir, void *keydest, strlen(FIT_SIG_NODENAME))) { ret = fit_config_process_sig(keydir, keydest, fit, conf_name, conf_noffset, noffset, comment, - require_keys); + require_keys, engine_id); } if (ret) return ret; @@ -653,7 +669,8 @@ static int fit_config_add_verification_data(const char *keydir, void *keydest, } int fit_add_verification_data(const char *keydir, void *keydest, void *fit, - const char *comment, int require_keys) + const char *comment, int require_keys, + const char *engine_id) { int images_noffset, confs_noffset; int noffset; @@ -676,7 +693,7 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit, * i.e. component image node. */ ret = fit_image_add_verification_data(keydir, keydest, - fit, noffset, comment, require_keys); + fit, noffset, comment, require_keys, engine_id); if (ret) return ret; } @@ -689,7 +706,7 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit, confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); if (confs_noffset < 0) { printf("Can't find images parent node '%s' (%s)\n", - FIT_IMAGES_PATH, fdt_strerror(confs_noffset)); + FIT_CONFS_PATH, fdt_strerror(confs_noffset)); return -ENOENT; } @@ -699,7 +716,8 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit, noffset = fdt_next_subnode(fit, noffset)) { ret = fit_config_add_verification_data(keydir, keydest, fit, noffset, comment, - require_keys); + require_keys, + engine_id); if (ret) return ret; }