if (!ret) {
time_t timestamp = imagetool_get_source_date(cmdname,
time(NULL));
+ uint32_t t = cpu_to_uimage(timestamp);
- ret = fit_set_timestamp(fit, noffset, timestamp);
+ ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
+ sizeof(uint32_t));
}
if (region_prop && !ret) {
uint32_t strdata[2];
}
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, const char *engine_id)
+ const char *keydir, const char *keyfile, void *fit,
+ const char *image_name, int noffset, const char *require_keys,
+ const char *engine_id)
{
const char *node_name;
char *algo_name;
memset(info, '\0', sizeof(*info));
info->keydir = keydir;
+ info->keyfile = keyfile;
info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
info->fit = fit;
info->node_offset = noffset;
* @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,
+static int fit_image_process_sig(const char *keydir, const char *keyfile,
+ void *keydest, void *fit, const char *image_name,
int noffset, const void *data, size_t size,
const char *comment, int require_keys, const char *engine_id,
const char *cmdname)
uint value_len;
int ret;
- if (fit_image_setup_sig(&info, keydir, fit, image_name, noffset,
- require_keys ? "image" : NULL, engine_id))
+ if (fit_image_setup_sig(&info, keydir, keyfile, fit, image_name,
+ noffset, require_keys ? "image" : NULL,
+ engine_id))
return -1;
node_name = fit_get_name(fit, noffset, NULL);
/* 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;
}
/* Check that we have read all the file */
if (n != sbuf.st_size) {
- printf("Can't read all file %s (read %zd bytes, expexted %ld)\n",
- filename, n, sbuf.st_size);
+ printf("Can't read all file %s (read %zd bytes, expected %lld)\n",
+ filename, n, (long long)sbuf.st_size);
goto err;
}
return ret;
}
+static int get_random_data(void *data, int size)
+{
+ unsigned char *tmp = data;
+ struct timespec date;
+ int i, ret;
+
+ if (!tmp) {
+ printf("%s: pointer data is NULL\n", __func__);
+ ret = -1;
+ goto out;
+ }
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &date);
+ if (ret) {
+ printf("%s: clock_gettime has failed (%s)\n", __func__,
+ 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,
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 in image '%s'\n",
- image_name);
- goto out;
- }
info->fit = fit;
info->node_noffset = noffset;
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;
* 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);
* @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, const char *engine_id, const char *cmdname)
+int fit_image_add_verification_data(const char *keydir, const char *keyfile,
+ void *keydest, void *fit, int image_noffset,
+ const char *comment, int require_keys, const char *engine_id,
+ const char *cmdname)
{
const char *image_name;
const void *data;
strlen(FIT_HASH_NODENAME))) {
ret = fit_image_process_hash(fit, image_name, noffset,
data, size);
- } else if (IMAGE_ENABLE_SIGN && keydir &&
+ } else if (IMAGE_ENABLE_SIGN && (keydir || keyfile) &&
!strncmp(node_name, FIT_SIG_NODENAME,
strlen(FIT_SIG_NODENAME))) {
- ret = fit_image_process_sig(keydir, keydest,
+ ret = fit_image_process_sig(keydir, keyfile, keydest,
fit, image_name, noffset, data, size,
comment, require_keys, engine_id, cmdname);
}
return default_list;
}
+static int fit_config_add_hash(void *fit, const char *conf_name, const char *sig_name,
+ struct strlist *node_inc, const char *iname, int image_noffset)
+{
+ char name[200], path[200];
+ int noffset;
+ int hash_count;
+ int ret;
+
+ ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
+ if (ret < 0)
+ goto err_path;
+ if (strlist_add(node_inc, path))
+ goto err_mem;
+
+ snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH,
+ conf_name);
+
+ /* Add all this image's hashes */
+ hash_count = 0;
+ for (noffset = fdt_first_subnode(fit, image_noffset);
+ noffset >= 0;
+ noffset = fdt_next_subnode(fit, noffset)) {
+ const char *name = fit_get_name(fit, noffset, NULL);
+
+ if (strncmp(name, FIT_HASH_NODENAME,
+ strlen(FIT_HASH_NODENAME)))
+ continue;
+ ret = fdt_get_path(fit, noffset, path, sizeof(path));
+ if (ret < 0)
+ goto err_path;
+ if (strlist_add(node_inc, path))
+ goto err_mem;
+ hash_count++;
+ }
+
+ if (!hash_count) {
+ printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
+ conf_name, sig_name, iname);
+ 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;
+ }
+
+ return 0;
+
+err_mem:
+ printf("Out of memory processing configuration '%s/%s'\n", conf_name,
+ sig_name);
+ return -ENOMEM;
+
+err_path:
+ printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
+ iname, conf_name, sig_name, fdt_strerror(ret));
+ return -ENOENT;
+}
+
static int fit_config_get_hash_list(void *fit, int conf_noffset,
int sig_offset, struct strlist *node_inc)
{
int allow_missing;
const char *prop, *iname, *end;
const char *conf_name, *sig_name;
- char name[200], path[200];
+ char name[200];
int image_count;
int ret, len;
end = prop + len;
image_count = 0;
for (iname = prop; iname < end; iname += strlen(iname) + 1) {
- int noffset;
int image_noffset;
- int hash_count;
-
- image_noffset = fit_conf_get_prop_node(fit, conf_noffset,
- iname);
- if (image_noffset < 0) {
- printf("Failed to find image '%s' in configuration '%s/%s'\n",
- iname, conf_name, sig_name);
- if (allow_missing)
- continue;
+ int index, max_index;
- return -ENOENT;
- }
+ max_index = fdt_stringlist_count(fit, conf_noffset, iname);
- ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
- if (ret < 0)
- goto err_path;
- if (strlist_add(node_inc, path))
- goto err_mem;
+ for (index = 0; index < max_index; index++) {
+ image_noffset = fit_conf_get_prop_node_index(fit, conf_noffset,
+ iname, index);
- snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH,
- conf_name);
+ if (image_noffset < 0) {
+ printf("Failed to find image '%s' in configuration '%s/%s'\n",
+ iname, conf_name, sig_name);
+ if (allow_missing)
+ continue;
- /* Add all this image's hashes */
- hash_count = 0;
- for (noffset = fdt_first_subnode(fit, image_noffset);
- noffset >= 0;
- noffset = fdt_next_subnode(fit, noffset)) {
- const char *name = fit_get_name(fit, noffset, NULL);
+ return -ENOENT;
+ }
- if (strncmp(name, FIT_HASH_NODENAME,
- strlen(FIT_HASH_NODENAME)))
- continue;
- ret = fdt_get_path(fit, noffset, path, sizeof(path));
+ ret = fit_config_add_hash(fit, conf_name,
+ sig_name, node_inc,
+ iname, image_noffset);
if (ret < 0)
- goto err_path;
- if (strlist_add(node_inc, path))
- goto err_mem;
- hash_count++;
- }
+ return ret;
- if (!hash_count) {
- printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
- conf_name, sig_name, iname);
- return -ENOMSG;
+ image_count++;
}
-
- /* 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++;
}
if (!image_count) {
printf("Out of memory processing configuration '%s/%s'\n", conf_name,
sig_name);
return -ENOMEM;
-
-err_path:
- printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
- iname, conf_name, sig_name, fdt_strerror(ret));
- return -ENOENT;
}
static int fit_config_get_data(void *fit, int conf_noffset, int noffset,
return 0;
}
-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,
- const char *engine_id, const char *cmdname)
+static int fit_config_process_sig(const char *keydir, const char *keyfile,
+ void *keydest, void *fit, const char *conf_name,
+ int conf_noffset, int noffset, const char *comment,
+ int require_keys, const char *engine_id, const char *cmdname)
{
struct image_sign_info info;
const char *node_name;
®ion_count, ®ion_prop, ®ion_proplen))
return -1;
- if (fit_image_setup_sig(&info, keydir, fit, conf_name, noffset,
+ if (fit_image_setup_sig(&info, keydir, keyfile, fit, conf_name, noffset,
require_keys ? "conf" : NULL, engine_id))
return -1;
return 0;
}
-static int fit_config_add_verification_data(const char *keydir, void *keydest,
- void *fit, int conf_noffset, const char *comment,
- int require_keys, const char *engine_id, const char *cmdname)
+static int fit_config_add_verification_data(const char *keydir,
+ const char *keyfile, void *keydest, void *fit, int conf_noffset,
+ const char *comment, int require_keys, const char *engine_id,
+ const char *cmdname)
{
const char *conf_name;
int noffset;
node_name = fit_get_name(fit, noffset, NULL);
if (!strncmp(node_name, FIT_SIG_NODENAME,
strlen(FIT_SIG_NODENAME))) {
- ret = fit_config_process_sig(keydir, keydest,
+ ret = fit_config_process_sig(keydir, keyfile, keydest,
fit, conf_name, conf_noffset, noffset, comment,
require_keys, engine_id, cmdname);
}
return 0;
}
-int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
- const char *comment, int require_keys,
- const char *engine_id, const char *cmdname)
+int fit_add_verification_data(const char *keydir, const char *keyfile,
+ void *keydest, void *fit, const char *comment,
+ int require_keys, const char *engine_id,
+ const char *cmdname)
{
int images_noffset, confs_noffset;
int noffset;
* Direct child node of the images parent node,
* i.e. component image node.
*/
- ret = fit_image_add_verification_data(keydir, keydest,
+ ret = fit_image_add_verification_data(keydir, keyfile, keydest,
fit, noffset, comment, require_keys, engine_id,
cmdname);
if (ret)
}
/* If there are no keys, we can't sign configurations */
- if (!IMAGE_ENABLE_SIGN || !keydir)
+ if (!IMAGE_ENABLE_SIGN || !(keydir || keyfile))
return 0;
/* Find configurations parent node offset */
for (noffset = fdt_first_subnode(fit, confs_noffset);
noffset >= 0;
noffset = fdt_next_subnode(fit, noffset)) {
- ret = fit_config_add_verification_data(keydir, keydest,
+ ret = fit_config_add_verification_data(keydir, keyfile, keydest,
fit, noffset, comment,
require_keys,
engine_id, cmdname);