X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tools%2Fimage-host.c;h=e32cc642579ede6591e0bda065525673c66d3ee7;hb=72a1b9a977e8636b9c364f2cbf21371afe143c68;hp=4e57ddea969cb614b6ff60b22d9f44fe64147610;hpb=72188f546291cfadea99e9383c133d6aaa37d87d;p=platform%2Fkernel%2Fu-boot.git diff --git a/tools/image-host.c b/tools/image-host.c index 4e57dde..e32cc64 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -10,6 +10,7 @@ #include "mkimage.h" #include +#include #include #include @@ -292,8 +293,8 @@ static int fit_image_read_data(char *filename, unsigned char *data, /* Check file size */ if (sbuf.st_size != expected_size) { - printf("File %s don't have the expected size (size=%ld, expected=%d)\n", - filename, sbuf.st_size, expected_size); + printf("File %s don't have the expected size (size=%lld, expected=%d)\n", + filename, (long long)sbuf.st_size, expected_size); goto err; } @@ -307,8 +308,8 @@ static int fit_image_read_data(char *filename, unsigned char *data, /* Check that we have read all the file */ if (n != sbuf.st_size) { - printf("Can't read all file %s (read %ld bytes, expexted %ld)\n", - filename, n, sbuf.st_size); + printf("Can't read all file %s (read %zd bytes, expexted %lld)\n", + filename, n, (long long)sbuf.st_size); goto err; } @@ -319,18 +320,48 @@ err: return ret; } +static int get_random_data(void *data, int size) +{ + unsigned char *tmp = data; + struct timespec date; + int i, ret = 0; + + if (!tmp) { + printf("%s: pointer data is NULL\n", __func__); + ret = -1; + goto out; + } + + ret = clock_gettime(CLOCK_MONOTONIC, &date); + if (ret < 0) { + printf("%s: clock_gettime has failed (err=%d, str=%s)\n", + __func__, ret, strerror(errno)); + goto out; + } + + srandom(date.tv_nsec); + + for (i = 0; i < size; i++) { + *tmp = random() & 0xff; + tmp++; + } + + out: + return ret; +} + static int fit_image_setup_cipher(struct image_cipher_info *info, const char *keydir, void *fit, const char *image_name, int image_noffset, - const char *node_name, int noffset) + int noffset) { char *algo_name; char filename[128]; int ret = -1; if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) { - printf("Can't get algo name for cipher '%s' in image '%s'\n", - node_name, image_name); + printf("Can't get algo name for cipher in image '%s'\n", + image_name); goto out; } @@ -339,18 +370,18 @@ static int fit_image_setup_cipher(struct image_cipher_info *info, /* Read the key name */ info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL); if (!info->keyname) { - printf("Can't get key name for cipher '%s' in image '%s'\n", - node_name, image_name); + printf("Can't get key name for cipher in image '%s'\n", + image_name); goto out; } - /* Read the IV name */ + /* + * Read the IV name + * + * If this property is not provided then mkimage will generate + * a random IV and store it in the FIT image + */ info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL); - if (!info->ivname) { - printf("Can't get iv name for cipher '%s' in image '%s'\n", - node_name, image_name); - goto out; - } info->fit = fit; info->node_noffset = noffset; @@ -376,17 +407,23 @@ static int fit_image_setup_cipher(struct image_cipher_info *info, if (ret < 0) goto out; - /* Read the IV in the file */ - snprintf(filename, sizeof(filename), "%s/%s%s", - info->keydir, info->ivname, ".bin"); info->iv = malloc(info->cipher->iv_len); if (!info->iv) { printf("Can't allocate memory for iv\n"); ret = -1; goto out; } - ret = fit_image_read_data(filename, (unsigned char *)info->iv, - info->cipher->iv_len); + + if (info->ivname) { + /* Read the IV in the file */ + snprintf(filename, sizeof(filename), "%s/%s%s", + info->keydir, info->ivname, ".bin"); + ret = fit_image_read_data(filename, (unsigned char *)info->iv, + info->cipher->iv_len); + } else { + /* Generate an ramdom IV */ + ret = get_random_data((void *)info->iv, info->cipher->iv_len); + } out: return ret; @@ -398,23 +435,24 @@ int fit_image_write_cipher(void *fit, int image_noffset, int noffset, { int ret = -1; - /* Remove unciphered data */ - ret = fdt_delprop(fit, image_noffset, FIT_DATA_PROP); - if (ret) { - printf("Can't remove data (err = %d)\n", ret); - goto out; - } - - /* Add ciphered data */ + /* Replace data with ciphered data */ ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP, data_ciphered, data_ciphered_len); + if (ret == -FDT_ERR_NOSPACE) { + ret = -ENOSPC; + goto out; + } if (ret) { - printf("Can't add ciphered data (err = %d)\n", ret); + printf("Can't replace data with ciphered data (err = %d)\n", ret); goto out; } /* add non ciphered data size */ ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size); + if (ret == -FDT_ERR_NOSPACE) { + ret = -ENOSPC; + goto out; + } if (ret) { printf("Can't add unciphered data size (err = %d)\n", ret); goto out; @@ -427,8 +465,7 @@ int fit_image_write_cipher(void *fit, int image_noffset, int noffset, static int fit_image_process_cipher(const char *keydir, void *keydest, void *fit, const char *image_name, int image_noffset, - const char *node_name, int node_noffset, - const void *data, size_t size, + int node_noffset, const void *data, size_t size, const char *cmdname) { struct image_cipher_info info; @@ -439,7 +476,7 @@ fit_image_process_cipher(const char *keydir, void *keydest, void *fit, memset(&info, 0, sizeof(info)); ret = fit_image_setup_cipher(&info, keydir, fit, image_name, - image_noffset, node_name, node_noffset); + image_noffset, node_noffset); if (ret) goto out; @@ -452,9 +489,10 @@ fit_image_process_cipher(const char *keydir, void *keydest, void *fit, * Write the public key into the supplied FDT file; this might fail * several times, since we try signing with successively increasing * size values + * And, if needed, write the iv in the FIT file */ if (keydest) { - ret = info.cipher->add_cipher_data(&info, keydest); + ret = info.cipher->add_cipher_data(&info, keydest, fit, node_noffset); if (ret) { printf("Failed to add verification data for cipher '%s' in image '%s'\n", info.keyname, image_name); @@ -481,7 +519,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest, const char *image_name; const void *data; size_t size; - int node_noffset; + int cipher_node_offset, len; /* Get image name */ image_name = fit_get_name(fit, image_noffset, NULL); @@ -496,32 +534,33 @@ int fit_image_cipher_data(const char *keydir, void *keydest, return -1; } - /* Process all hash subnodes of the component image node */ - for (node_noffset = fdt_first_subnode(fit, image_noffset); - node_noffset >= 0; - node_noffset = fdt_next_subnode(fit, node_noffset)) { - const char *node_name; - int ret = 0; - - node_name = fit_get_name(fit, node_noffset, NULL); - if (!node_name) { - printf("Can't get node name\n"); - return -1; - } - - if (IMAGE_ENABLE_ENCRYPT && keydir && - !strncmp(node_name, FIT_CIPHER_NODENAME, - strlen(FIT_CIPHER_NODENAME))) - ret = fit_image_process_cipher(keydir, keydest, - fit, image_name, - image_noffset, - node_name, node_noffset, - data, size, cmdname); - if (ret) - return ret; + /* + * Don't cipher ciphered data. + * + * If the data-size-unciphered property is present the data for this + * image is already encrypted. This is important as 'mkimage -F' can be + * run multiple times on a FIT image. + */ + if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len)) + return 0; + if (len != -FDT_ERR_NOTFOUND) { + printf("Failure testing for data-size-unciphered\n"); + return -1; } - return 0; + /* Process cipher node if present */ + cipher_node_offset = fdt_subnode_offset(fit, image_noffset, + FIT_CIPHER_NODENAME); + if (cipher_node_offset == -FDT_ERR_NOTFOUND) + return 0; + if (cipher_node_offset < 0) { + printf("Failure getting cipher node\n"); + return -1; + } + if (!IMAGE_ENABLE_ENCRYPT || !keydir) + return 0; + return fit_image_process_cipher(keydir, keydest, fit, image_name, + image_noffset, cipher_node_offset, data, size, cmdname); } /** @@ -742,6 +781,23 @@ static int fit_config_get_hash_list(void *fit, int conf_noffset, return -ENOMSG; } + /* Add this image's cipher node if present */ + noffset = fdt_subnode_offset(fit, image_noffset, + FIT_CIPHER_NODENAME); + if (noffset != -FDT_ERR_NOTFOUND) { + if (noffset < 0) { + printf("Failed to get cipher node in configuration '%s/%s' image '%s': %s\n", + conf_name, sig_name, iname, + fdt_strerror(noffset)); + return -EIO; + } + ret = fdt_get_path(fit, noffset, path, sizeof(path)); + if (ret < 0) + goto err_path; + if (strlist_add(node_inc, path)) + goto err_mem; + } + image_count++; }