]> Git Repo - J-u-boot.git/blobdiff - tools/fit_image.c
global: Rename SPL_ to XPL_
[J-u-boot.git] / tools / fit_image.c
index a082d9386d200d095753eae45fec826b1a718269..0fccfbb4ebda47f6a43f21b6a4e4064797597d13 100644 (file)
@@ -22,7 +22,7 @@
 #include <version.h>
 #include <u-boot/crc.h>
 
-static image_header_t header;
+static struct legacy_img_hdr header;
 
 static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
                             const char *tmpfile)
@@ -36,8 +36,10 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
 
        tfd = mmap_fdt(params->cmdname, tmpfile, size_inc, &ptr, &sbuf, true,
                       false);
-       if (tfd < 0)
+       if (tfd < 0) {
+               fprintf(stderr, "Cannot map FDT file '%s'\n", tmpfile);
                return -EIO;
+       }
 
        if (params->keydest) {
                struct stat dest_sbuf;
@@ -53,12 +55,15 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
        }
 
        /* for first image creation, add a timestamp at offset 0 i.e., root  */
-       if (params->datafile) {
+       if (params->datafile || params->reset_timestamp) {
                time_t time = imagetool_get_source_date(params->cmdname,
                                                        sbuf.st_mtime);
                ret = fit_set_timestamp(ptr, 0, time);
        }
 
+       if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && !ret)
+               ret = fit_pre_load_data(params->keydir, dest_blob, ptr);
+
        if (!ret) {
                ret = fit_cipher_data(params->keydir, dest_blob, ptr,
                                      params->comment,
@@ -68,11 +73,14 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
        }
 
        if (!ret) {
-               ret = fit_add_verification_data(params->keydir, dest_blob, ptr,
+               ret = fit_add_verification_data(params->keydir,
+                                               params->keyfile, dest_blob, ptr,
                                                params->comment,
                                                params->require_keys,
                                                params->engine_id,
-                                               params->cmdname);
+                                               params->cmdname,
+                                               params->algo_name,
+                                               &params->summary);
        }
 
        if (dest_blob) {
@@ -129,7 +137,7 @@ static int fdt_property_file(struct image_tool_params *params,
        int ret;
        int fd;
 
-       fd = open(fname, O_RDWR | O_BINARY);
+       fd = open(fname, O_RDONLY | O_BINARY);
        if (fd < 0) {
                fprintf(stderr, "%s: Can't open %s: %s\n",
                        params->cmdname, fname, strerror(errno));
@@ -193,15 +201,59 @@ static void get_basename(char *str, int size, const char *fname)
 }
 
 /**
- * add_crc_node() - Add a hash node to request a CRC checksum for an image
+ * fit_add_hash_or_sign() - Add a hash or signature node
  *
+ * @params: Image parameters
  * @fdt: Device tree to add to (in sequential-write mode)
+ * @is_images_subnode: true to add hash even if key name hint is provided
+ *
+ * If do_add_hash is false (default) and there is a key name hint, try to add
+ * a sign node to parent. Otherwise, just add a CRC. Rationale: if conf have
+ * to be signed, image/dt have to be hashed even if there is a key name hint.
  */
-static void add_crc_node(void *fdt)
+static void fit_add_hash_or_sign(struct image_tool_params *params, void *fdt,
+                                bool is_images_subnode)
 {
-       fdt_begin_node(fdt, "hash-1");
-       fdt_property_string(fdt, FIT_ALGO_PROP, "crc32");
-       fdt_end_node(fdt);
+       const char *hash_algo = "crc32";
+       bool do_hash = false;
+       bool do_sign = false;
+
+       switch (params->auto_fit) {
+       case AF_OFF:
+               break;
+       case AF_HASHED_IMG:
+               do_hash = is_images_subnode;
+               break;
+       case AF_SIGNED_IMG:
+               do_sign = is_images_subnode;
+               break;
+       case AF_SIGNED_CONF:
+               if (is_images_subnode) {
+                       do_hash = true;
+                       hash_algo = "sha1";
+               } else {
+                       do_sign = true;
+               }
+               break;
+       default:
+               fprintf(stderr,
+                       "%s: Unsupported auto FIT mode %u\n",
+                       params->cmdname, params->auto_fit);
+               break;
+       }
+
+       if (do_hash) {
+               fdt_begin_node(fdt, FIT_HASH_NODENAME);
+               fdt_property_string(fdt, FIT_ALGO_PROP, hash_algo);
+               fdt_end_node(fdt);
+       }
+
+       if (do_sign) {
+               fdt_begin_node(fdt, FIT_SIG_NODENAME);
+               fdt_property_string(fdt, FIT_ALGO_PROP, params->algo_name);
+               fdt_property_string(fdt, FIT_KEY_HINT, params->keyname);
+               fdt_end_node(fdt);
+       }
 }
 
 /**
@@ -242,7 +294,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
        ret = fdt_property_file(params, fdt, FIT_DATA_PROP, params->datafile);
        if (ret)
                return ret;
-       add_crc_node(fdt);
+       fit_add_hash_or_sign(params, fdt, true);
        fdt_end_node(fdt);
 
        /* Now the device tree files if available */
@@ -265,7 +317,9 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
                                    genimg_get_arch_short_name(params->arch));
                fdt_property_string(fdt, FIT_COMP_PROP,
                                    genimg_get_comp_short_name(IH_COMP_NONE));
-               add_crc_node(fdt);
+               fit_add_hash_or_sign(params, fdt, true);
+               if (ret)
+                       return ret;
                fdt_end_node(fdt);
        }
 
@@ -283,7 +337,9 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
                                        params->fit_ramdisk);
                if (ret)
                        return ret;
-               add_crc_node(fdt);
+               fit_add_hash_or_sign(params, fdt, true);
+               if (ret)
+                       return ret;
                fdt_end_node(fdt);
        }
 
@@ -333,6 +389,7 @@ static void fit_write_configs(struct image_tool_params *params, char *fdt)
 
                snprintf(str, sizeof(str), FIT_FDT_PROP "-%d", upto);
                fdt_property_string(fdt, FIT_FDT_PROP, str);
+               fit_add_hash_or_sign(params, fdt, false);
                fdt_end_node(fdt);
        }
 
@@ -345,6 +402,7 @@ static void fit_write_configs(struct image_tool_params *params, char *fdt)
                if (params->fit_ramdisk)
                        fdt_property_string(fdt, FIT_RAMDISK_PROP,
                                            FIT_RAMDISK_PROP "-1");
+               fit_add_hash_or_sign(params, fdt, false);
 
                fdt_end_node(fdt);
        }
@@ -388,7 +446,7 @@ static int fit_build(struct image_tool_params *params, const char *fname)
        size = fit_calc_size(params);
        if (size < 0)
                return -1;
-       buf = malloc(size);
+       buf = calloc(1, size);
        if (!buf) {
                fprintf(stderr, "%s: Out of memory (%d bytes)\n",
                        params->cmdname, size);
@@ -439,7 +497,7 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
 {
        void *buf = NULL;
        int buf_ptr;
-       int fit_size, new_size;
+       int fit_size, unpadded_size, new_size, pad_boundary;
        int fd;
        struct stat sbuf;
        void *fdt;
@@ -467,7 +525,7 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
         * Allocate space to hold the image data we will extract,
         * extral space allocate for image alignment to prevent overflow.
         */
-       buf = malloc(fit_size + (align_size * image_number));
+       buf = calloc(1, fit_size + (align_size * image_number));
        if (!buf) {
                ret = -ENOMEM;
                goto err_munmap;
@@ -506,9 +564,13 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
        /* Pack the FDT and place the data after it */
        fdt_pack(fdt);
 
-       new_size = fdt_totalsize(fdt);
-       new_size = ALIGN(new_size, align_size);
+       unpadded_size = fdt_totalsize(fdt);
+       new_size = ALIGN(unpadded_size, align_size);
        fdt_set_totalsize(fdt, new_size);
+       if (unpadded_size < fit_size) {
+               pad_boundary = new_size < fit_size ? new_size : fit_size;
+               memset(fdt + unpadded_size, 0, pad_boundary - unpadded_size);
+       }
        debug("Size reduced from %x to %x\n", fit_size, fdt_totalsize(fdt));
        debug("External data size %x\n", buf_ptr);
        munmap(fdt, sbuf.st_size);
@@ -523,8 +585,9 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
        /* Check if an offset for the external data was set. */
        if (params->external_offset > 0) {
                if (params->external_offset < new_size) {
-                       debug("External offset %x overlaps FIT length %x",
-                             params->external_offset, new_size);
+                       fprintf(stderr,
+                               "External offset %x overlaps FIT length %x\n",
+                               params->external_offset, new_size);
                        ret = -EINVAL;
                        goto err;
                }
@@ -557,6 +620,8 @@ err:
 static int fit_import_data(struct image_tool_params *params, const char *fname)
 {
        void *fdt, *old_fdt;
+       void *data = NULL;
+       const char *ext_data_prop = NULL;
        int fit_size, new_size, size, data_base;
        int fd;
        struct stat sbuf;
@@ -572,7 +637,7 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
 
        /* Allocate space to hold the new FIT */
        size = sbuf.st_size + 16384;
-       fdt = malloc(size);
+       fdt = calloc(1, size);
        if (!fdt) {
                fprintf(stderr, "%s: Failed to allocate memory (%d bytes)\n",
                        __func__, size);
@@ -600,14 +665,28 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
                int buf_ptr;
                int len;
 
-               buf_ptr = fdtdec_get_int(fdt, node, "data-offset", -1);
-               len = fdtdec_get_int(fdt, node, "data-size", -1);
-               if (buf_ptr == -1 || len == -1)
+               /*
+                * FIT_DATA_OFFSET_PROP and FIT_DATA_POSITION_PROP are never both present,
+                *  but if they are, prefer FIT_DATA_OFFSET_PROP as it was there first
+                */
+               buf_ptr = fdtdec_get_int(fdt, node, FIT_DATA_POSITION_PROP, -1);
+               if (buf_ptr != -1) {
+                       ext_data_prop = FIT_DATA_POSITION_PROP;
+                       data = old_fdt + buf_ptr;
+               }
+               buf_ptr = fdtdec_get_int(fdt, node, FIT_DATA_OFFSET_PROP, -1);
+               if (buf_ptr != -1) {
+                       ext_data_prop = FIT_DATA_OFFSET_PROP;
+                       data = old_fdt + data_base + buf_ptr;
+               }
+               len = fdtdec_get_int(fdt, node, FIT_DATA_SIZE_PROP, -1);
+               if (!data || len == -1)
                        continue;
                debug("Importing data size %x\n", len);
 
-               ret = fdt_setprop(fdt, node, "data", fdt + data_base + buf_ptr,
-                                 len);
+               ret = fdt_setprop(fdt, node, FIT_DATA_PROP, data, len);
+               ret = fdt_delprop(fdt, node, ext_data_prop);
+
                if (ret) {
                        debug("%s: Failed to write property: %s\n", __func__,
                              fdt_strerror(ret));
@@ -653,62 +732,6 @@ err:
        return ret;
 }
 
-static int copyfile(const char *src, const char *dst)
-{
-       int fd_src = -1, fd_dst = -1;
-       void *buf = NULL;
-       ssize_t size;
-       size_t count;
-       int ret = -1;
-
-       fd_src = open(src, O_RDONLY);
-       if (fd_src < 0) {
-               printf("Can't open file %s (%s)\n", src, strerror(errno));
-               goto out;
-       }
-
-       fd_dst = open(dst, O_WRONLY | O_CREAT, 0666);
-       if (fd_dst < 0) {
-               printf("Can't open file %s (%s)\n", dst, strerror(errno));
-               goto out;
-       }
-
-       buf = malloc(512);
-       if (!buf) {
-               printf("Can't allocate buffer to copy file\n");
-               goto out;
-       }
-
-       while (1) {
-               size = read(fd_src, buf, 512);
-               if (size < 0) {
-                       printf("Can't read file %s\n", src);
-                       goto out;
-               }
-               if (!size)
-                       break;
-
-               count = size;
-               size = write(fd_dst, buf, count);
-               if (size < 0) {
-                       printf("Can't write file %s\n", dst);
-                       goto out;
-               }
-       }
-
-       ret = 0;
-
- out:
-       if (fd_src >= 0)
-               close(fd_src);
-       if (fd_dst >= 0)
-               close(fd_dst);
-       if (buf)
-               free(buf);
-
-       return ret;
-}
-
 /**
  * fit_handle_file - main FIT file processing function
  *
@@ -736,14 +759,14 @@ static int fit_handle_file(struct image_tool_params *params)
        if (strlen (params->imagefile) +
                strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) {
                fprintf (stderr, "%s: Image file name (%s) too long, "
-                               "can't create tmpfile",
+                               "can't create tmpfile.\n",
                                params->imagefile, params->cmdname);
                return (EXIT_FAILURE);
        }
        sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX);
 
        /* We either compile the source file, or use the existing FIT image */
-       if (params->auto_its) {
+       if (params->auto_fit) {
                if (fit_build(params, tmpfile)) {
                        fprintf(stderr, "%s: failed to build FIT\n",
                                params->cmdname);
@@ -883,11 +906,6 @@ static int fit_extract_contents(void *ptr, struct image_tool_params *params)
        /* Indent string is defined in header image.h */
        p = IMAGE_INDENT_STRING;
 
-       if (!fit_check_format(fit)) {
-               printf("Bad FIT image format\n");
-               return -1;
-       }
-
        /* Find images parent node offset */
        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
        if (images_noffset < 0) {
@@ -932,7 +950,7 @@ static int fit_extract_contents(void *ptr, struct image_tool_params *params)
 
 static int fit_check_params(struct image_tool_params *params)
 {
-       if (params->auto_its)
+       if (params->auto_fit)
                return 0;
        return  ((params->dflag && params->fflag) ||
                 (params->fflag && params->lflag) ||
@@ -942,11 +960,11 @@ static int fit_check_params(struct image_tool_params *params)
 U_BOOT_IMAGE_TYPE(
        fitimage,
        "FIT Image support",
-       sizeof(image_header_t),
+       sizeof(struct legacy_img_hdr),
        (void *)&header,
        fit_check_params,
        fit_verify_header,
-       fit_print_contents,
+       fit_print_header,
        NULL,
        fit_extract_contents,
        fit_check_image_types,
This page took 0.075241 seconds and 4 git commands to generate.