cmd: env: use appropriate guid for authenticated UEFI variable
[oweals/u-boot.git] / tools / fit_image.c
index e55a8943e764f6e32e740455d5ab1ae2fea6b122..dd61a816c93f65c141326f28ad9eea0028ed7488 100644 (file)
@@ -33,7 +33,8 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
        void *ptr;
        int ret = 0;
 
-       tfd = mmap_fdt(params->cmdname, tmpfile, size_inc, &ptr, &sbuf, true);
+       tfd = mmap_fdt(params->cmdname, tmpfile, size_inc, &ptr, &sbuf, true,
+                      false);
        if (tfd < 0)
                return -EIO;
 
@@ -41,7 +42,8 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
                struct stat dest_sbuf;
 
                destfd = mmap_fdt(params->cmdname, params->keydest, size_inc,
-                                 &dest_blob, &dest_sbuf, false);
+                                 &dest_blob, &dest_sbuf, false,
+                                 false);
                if (destfd < 0) {
                        ret = -EIO;
                        goto err_keydest;
@@ -51,15 +53,25 @@ 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) {
-               time_t time = imagetool_get_source_date(params, sbuf.st_mtime);
+               time_t time = imagetool_get_source_date(params->cmdname,
+                                                       sbuf.st_mtime);
                ret = fit_set_timestamp(ptr, 0, time);
        }
 
+       if (!ret) {
+               ret = fit_cipher_data(params->keydir, dest_blob, ptr,
+                                     params->comment,
+                                     params->require_keys,
+                                     params->engine_id,
+                                     params->cmdname);
+       }
+
        if (!ret) {
                ret = fit_add_verification_data(params->keydir, dest_blob, ptr,
                                                params->comment,
                                                params->require_keys,
-                                               params->engine_id);
+                                               params->engine_id,
+                                               params->cmdname);
        }
 
        if (dest_blob) {
@@ -70,7 +82,6 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
 err_keydest:
        munmap(ptr, sbuf.st_size);
        close(tfd);
-
        return ret;
 }
 
@@ -200,21 +211,22 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
        typename = genimg_get_type_short_name(params->fit_image_type);
        snprintf(str, sizeof(str), "%s-1", typename);
        fdt_begin_node(fdt, str);
-       fdt_property_string(fdt, "description", params->imagename);
-       fdt_property_string(fdt, "type", typename);
-       fdt_property_string(fdt, "arch",
+       fdt_property_string(fdt, FIT_DESC_PROP, params->imagename);
+       fdt_property_string(fdt, FIT_TYPE_PROP, typename);
+       fdt_property_string(fdt, FIT_ARCH_PROP,
                            genimg_get_arch_short_name(params->arch));
-       fdt_property_string(fdt, "os", genimg_get_os_short_name(params->os));
-       fdt_property_string(fdt, "compression",
+       fdt_property_string(fdt, FIT_OS_PROP,
+                           genimg_get_os_short_name(params->os));
+       fdt_property_string(fdt, FIT_COMP_PROP,
                            genimg_get_comp_short_name(params->comp));
-       fdt_property_u32(fdt, "load", params->addr);
-       fdt_property_u32(fdt, "entry", params->ep);
+       fdt_property_u32(fdt, FIT_LOAD_PROP, params->addr);
+       fdt_property_u32(fdt, FIT_ENTRY_PROP, params->ep);
 
        /*
         * Put data last since it is large. SPL may only load the first part
         * of the DT, so this way it can access all the above fields.
         */
-       ret = fdt_property_file(params, fdt, "data", params->datafile);
+       ret = fdt_property_file(params, fdt, FIT_DATA_PROP, params->datafile);
        if (ret)
                return ret;
        fdt_end_node(fdt);
@@ -224,18 +236,20 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
        for (cont = params->content_head; cont; cont = cont->next) {
                if (cont->type != IH_TYPE_FLATDT)
                        continue;
+               typename = genimg_get_type_short_name(cont->type);
                snprintf(str, sizeof(str), "%s-%d", FIT_FDT_PROP, ++upto);
                fdt_begin_node(fdt, str);
 
                get_basename(str, sizeof(str), cont->fname);
-               fdt_property_string(fdt, "description", str);
-               ret = fdt_property_file(params, fdt, "data", cont->fname);
+               fdt_property_string(fdt, FIT_DESC_PROP, str);
+               ret = fdt_property_file(params, fdt, FIT_DATA_PROP,
+                                       cont->fname);
                if (ret)
                        return ret;
-               fdt_property_string(fdt, "type", typename);
-               fdt_property_string(fdt, "arch",
+               fdt_property_string(fdt, FIT_TYPE_PROP, typename);
+               fdt_property_string(fdt, FIT_ARCH_PROP,
                                    genimg_get_arch_short_name(params->arch));
-               fdt_property_string(fdt, "compression",
+               fdt_property_string(fdt, FIT_COMP_PROP,
                                    genimg_get_comp_short_name(IH_COMP_NONE));
                fdt_end_node(fdt);
        }
@@ -244,10 +258,14 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
        if (params->fit_ramdisk) {
                fdt_begin_node(fdt, FIT_RAMDISK_PROP "-1");
 
-               fdt_property_string(fdt, "type", FIT_RAMDISK_PROP);
-               fdt_property_string(fdt, "os", genimg_get_os_short_name(params->os));
+               fdt_property_string(fdt, FIT_TYPE_PROP, FIT_RAMDISK_PROP);
+               fdt_property_string(fdt, FIT_OS_PROP,
+                                   genimg_get_os_short_name(params->os));
+               fdt_property_string(fdt, FIT_ARCH_PROP,
+                                   genimg_get_arch_short_name(params->arch));
 
-               ret = fdt_property_file(params, fdt, "data", params->fit_ramdisk);
+               ret = fdt_property_file(params, fdt, FIT_DATA_PROP,
+                                       params->fit_ramdisk);
                if (ret)
                        return ret;
 
@@ -276,7 +294,7 @@ static void fit_write_configs(struct image_tool_params *params, char *fdt)
        int upto;
 
        fdt_begin_node(fdt, "configurations");
-       fdt_property_string(fdt, "default", "conf-1");
+       fdt_property_string(fdt, FIT_DEFAULT_PROP, "conf-1");
 
        upto = 0;
        for (cont = params->content_head; cont; cont = cont->next) {
@@ -287,11 +305,12 @@ static void fit_write_configs(struct image_tool_params *params, char *fdt)
                fdt_begin_node(fdt, str);
 
                get_basename(str, sizeof(str), cont->fname);
-               fdt_property_string(fdt, "description", str);
+               fdt_property_string(fdt, FIT_DESC_PROP, str);
 
                typename = genimg_get_type_short_name(params->fit_image_type);
                snprintf(str, sizeof(str), "%s-1", typename);
                fdt_property_string(fdt, typename, str);
+               fdt_property_string(fdt, FIT_LOADABLE_PROP, str);
 
                if (params->fit_ramdisk)
                        fdt_property_string(fdt, FIT_RAMDISK_PROP,
@@ -327,7 +346,7 @@ static int fit_build_fdt(struct image_tool_params *params, char *fdt, int size)
                return ret;
        fdt_finish_reservemap(fdt);
        fdt_begin_node(fdt, "");
-       fdt_property_strf(fdt, "description",
+       fdt_property_strf(fdt, FIT_DESC_PROP,
                          "%s image with one or more FDT blobs",
                          genimg_get_type_name(params->fit_image_type));
        fdt_property_strf(fdt, "creator", "U-Boot mkimage %s", PLAIN_VERSION);
@@ -413,7 +432,7 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
        int images;
        int node;
 
-       fd = mmap_fdt(params->cmdname, fname, 0, &fdt, &sbuf, false);
+       fd = mmap_fdt(params->cmdname, fname, 0, &fdt, &sbuf, false, false);
        if (fd < 0)
                return -EIO;
        fit_size = fdt_totalsize(fdt);
@@ -439,25 +458,26 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
                const char *data;
                int len;
 
-               data = fdt_getprop(fdt, node, "data", &len);
+               data = fdt_getprop(fdt, node, FIT_DATA_PROP, &len);
                if (!data)
                        continue;
                memcpy(buf + buf_ptr, data, len);
                debug("Extracting data size %x\n", len);
 
-               ret = fdt_delprop(fdt, node, "data");
+               ret = fdt_delprop(fdt, node, FIT_DATA_PROP);
                if (ret) {
                        ret = -EPERM;
                        goto err_munmap;
                }
                if (params->external_offset > 0) {
                        /* An external offset positions the data absolutely. */
-                       fdt_setprop_u32(fdt, node, "data-position",
+                       fdt_setprop_u32(fdt, node, FIT_DATA_POSITION_PROP,
                                        params->external_offset + buf_ptr);
                } else {
-                       fdt_setprop_u32(fdt, node, "data-offset", buf_ptr);
+                       fdt_setprop_u32(fdt, node, FIT_DATA_OFFSET_PROP,
+                                       buf_ptr);
                }
-               fdt_setprop_u32(fdt, node, "data-size", len);
+               fdt_setprop_u32(fdt, node, FIT_DATA_SIZE_PROP, len);
 
                buf_ptr += (len + 3) & ~3;
        }
@@ -523,7 +543,7 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
        int images;
        int node;
 
-       fd = mmap_fdt(params->cmdname, fname, 0, &old_fdt, &sbuf, false);
+       fd = mmap_fdt(params->cmdname, fname, 0, &old_fdt, &sbuf, false, false);
        if (fd < 0)
                return -EIO;
        fit_size = fdt_totalsize(old_fdt);
@@ -608,6 +628,62 @@ err_no_fd:
        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, 0700);
+       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
  *
@@ -623,6 +699,7 @@ err_no_fd:
 static int fit_handle_file(struct image_tool_params *params)
 {
        char tmpfile[MKIMAGE_MAX_TMPFILE_LEN];
+       char bakfile[MKIMAGE_MAX_TMPFILE_LEN + 4] = {0};
        char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN];
        size_t size_inc;
        int ret;
@@ -657,6 +734,7 @@ static int fit_handle_file(struct image_tool_params *params)
                snprintf(cmd, sizeof(cmd), "cp \"%s\" \"%s\"",
                         params->imagefile, tmpfile);
        }
+
        if (*cmd && system(cmd) == -1) {
                fprintf (stderr, "%s: system(%s) failed: %s\n",
                                params->cmdname, cmd, strerror(errno));
@@ -668,6 +746,14 @@ static int fit_handle_file(struct image_tool_params *params)
        if (ret)
                goto err_system;
 
+       /*
+        * Copy the tmpfile to bakfile, then in the following loop
+        * we copy bakfile to tmpfile. So we always start from the
+        * beginning.
+        */
+       sprintf(bakfile, "%s%s", tmpfile, ".bak");
+       rename(tmpfile, bakfile);
+
        /*
         * Set hashes for images in the blob. Unfortunately we may need more
         * space in either FDT, so keep trying until we succeed.
@@ -679,6 +765,11 @@ static int fit_handle_file(struct image_tool_params *params)
         * steps of this loop is enough to sign with several keys.
         */
        for (size_inc = 0; size_inc < 64 * 1024; size_inc += 1024) {
+               if (copyfile(bakfile, tmpfile) < 0) {
+                       printf("Can't copy %s to %s\n", bakfile, tmpfile);
+                       ret = -EIO;
+                       break;
+               }
                ret = fit_add_file_data(params, size_inc, tmpfile);
                if (!ret || ret != -ENOSPC)
                        break;
@@ -702,13 +793,16 @@ static int fit_handle_file(struct image_tool_params *params)
                                params->cmdname, tmpfile, params->imagefile,
                                strerror (errno));
                unlink (tmpfile);
+               unlink(bakfile);
                unlink (params->imagefile);
                return EXIT_FAILURE;
        }
+       unlink(bakfile);
        return EXIT_SUCCESS;
 
 err_system:
        unlink(tmpfile);
+       unlink(bakfile);
        return -1;
 }
 
@@ -728,9 +822,14 @@ static int fit_image_extract(
 {
        const void *file_data;
        size_t file_size = 0;
+       int ret;
 
-       /* get the "data" property of component at offset "image_noffset" */
-       fit_image_get_data(fit, image_noffset, &file_data, &file_size);
+       /* get the data address and size of component at offset "image_noffset" */
+       ret = fit_image_get_data_and_size(fit, image_noffset, &file_data, &file_size);
+       if (ret) {
+               fprintf(stderr, "Could not get component information\n");
+               return ret;
+       }
 
        /* save the "file_data" into the file specified by "file_name" */
        return imagetool_save_subimage(file_name, (ulong) file_data, file_size);
@@ -807,9 +906,9 @@ static int fit_check_params(struct image_tool_params *params)
 {
        if (params->auto_its)
                return 0;
-       return  ((params->dflag && (params->fflag || params->lflag)) ||
-               (params->fflag && (params->dflag || params->lflag)) ||
-               (params->lflag && (params->dflag || params->fflag)));
+       return  ((params->dflag && params->fflag) ||
+                (params->fflag && params->lflag) ||
+                (params->lflag && params->dflag));
 }
 
 U_BOOT_IMAGE_TYPE(