X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=tools%2Ffit_image.c;h=3ececf913ff4c4fe2c1c2457f3f5b5ccbfa195fb;hb=686dca0fc4eb077b089c7507f899097d001c8ce3;hp=cc123dd37adf81996346e7f776f72f21dee8f4f8;hpb=10e167329b029890a4c704f094822da5f259b886;p=u-boot diff --git a/tools/fit_image.c b/tools/fit_image.c index cc123dd37a..3ececf913f 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -11,82 +11,63 @@ * * All rights reserved. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ +#include "imagetool.h" +#include "fit_common.h" #include "mkimage.h" #include #include static image_header_t header; -static int fit_verify_header (unsigned char *ptr, int image_size, - struct mkimage_params *params) -{ - return fdt_check_header ((void *)ptr); -} - -static int fit_check_image_types (uint8_t type) -{ - if (type == IH_TYPE_FLATDT) - return EXIT_SUCCESS; - else - return EXIT_FAILURE; -} - -int mmap_fdt(struct mkimage_params *params, const char *fname, void **blobp, - struct stat *sbuf) +static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, + const char *tmpfile) { + int tfd, destfd = 0; + void *dest_blob = NULL; + off_t destfd_size = 0; + struct stat sbuf; void *ptr; - int fd; + int ret = 0; - /* Load FIT blob into memory (we need to write hashes/signatures) */ - fd = open(fname, O_RDWR | O_BINARY); - - if (fd < 0) { - fprintf(stderr, "%s: Can't open %s: %s\n", - params->cmdname, fname, strerror(errno)); - unlink(fname); - return -1; + tfd = mmap_fdt(params->cmdname, tmpfile, size_inc, &ptr, &sbuf, true); + if (tfd < 0) + return -EIO; + + if (params->keydest) { + struct stat dest_sbuf; + + destfd = mmap_fdt(params->cmdname, params->keydest, size_inc, + &dest_blob, &dest_sbuf, false); + if (destfd < 0) { + ret = -EIO; + goto err_keydest; + } + destfd_size = dest_sbuf.st_size; } - if (fstat(fd, sbuf) < 0) { - fprintf(stderr, "%s: Can't stat %s: %s\n", - params->cmdname, fname, strerror(errno)); - unlink(fname); - return -1; - } + /* for first image creation, add a timestamp at offset 0 i.e., root */ + if (params->datafile) + ret = fit_set_timestamp(ptr, 0, sbuf.st_mtime); - ptr = mmap(0, sbuf->st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (ptr == MAP_FAILED) { - fprintf(stderr, "%s: Can't read %s: %s\n", - params->cmdname, fname, strerror(errno)); - unlink(fname); - return -1; + if (!ret) { + ret = fit_add_verification_data(params->keydir, dest_blob, ptr, + params->comment, + params->require_keys); } - /* check if ptr has a valid blob */ - if (fdt_check_header(ptr)) { - fprintf(stderr, "%s: Invalid FIT blob\n", params->cmdname); - unlink(fname); - return -1; + if (dest_blob) { + munmap(dest_blob, destfd_size); + close(destfd); } - *blobp = ptr; - return fd; +err_keydest: + munmap(ptr, sbuf.st_size); + close(tfd); + + return ret; } /** @@ -101,13 +82,12 @@ int mmap_fdt(struct mkimage_params *params, const char *fname, void **blobp, * returns: * only on success, otherwise calls exit (EXIT_FAILURE); */ -static int fit_handle_file (struct mkimage_params *params) +static int fit_handle_file(struct image_tool_params *params) { char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; - int tfd; - struct stat sbuf; - void *ptr; + size_t size_inc; + int ret; /* Flattened Image Tree (FIT) format handling */ debug ("FIT format handling\n"); @@ -122,37 +102,43 @@ static int fit_handle_file (struct mkimage_params *params) } sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX); - /* dtc -I dts -O dtb -p 500 datafile > tmpfile */ - sprintf (cmd, "%s %s %s > %s", - MKIMAGE_DTC, params->dtc, params->datafile, tmpfile); - debug ("Trying to execute \"%s\"\n", cmd); + /* We either compile the source file, or use the existing FIT image */ + if (params->datafile) { + /* dtc -I dts -O dtb -p 500 datafile > tmpfile */ + snprintf(cmd, sizeof(cmd), "%s %s %s > %s", + MKIMAGE_DTC, params->dtc, params->datafile, tmpfile); + debug("Trying to execute \"%s\"\n", cmd); + } else { + snprintf(cmd, sizeof(cmd), "cp %s %s", + params->imagefile, tmpfile); + } if (system (cmd) == -1) { fprintf (stderr, "%s: system(%s) failed: %s\n", params->cmdname, cmd, strerror(errno)); goto err_system; } - tfd = mmap_fdt(params, tmpfile, &ptr, &sbuf); - if (tfd < 0) - goto err_mmap; - - /* set hashes for images in the blob */ - if (fit_add_verification_data(ptr)) { - fprintf (stderr, "%s Can't add hashes to FIT blob", - params->cmdname); - goto err_add_hashes; + /* + * Set hashes for images in the blob. Unfortunately we may need more + * space in either FDT, so keep trying until we succeed. + * + * Note: this is pretty inefficient for signing, since we must + * calculate the signature every time. It would be better to calculate + * all the data and then store it in a separate step. However, this + * would be considerably more complex to implement. Generally a few + * steps of this loop is enough to sign with several keys. + */ + for (size_inc = 0; size_inc < 64 * 1024; size_inc += 1024) { + ret = fit_add_file_data(params, size_inc, tmpfile); + if (!ret || ret != -ENOSPC) + break; } - /* add a timestamp at offset 0 i.e., root */ - if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) { - fprintf (stderr, "%s: Can't add image timestamp\n", - params->cmdname); - goto err_add_timestamp; + if (ret) { + fprintf(stderr, "%s Can't add hashes to FIT blob\n", + params->cmdname); + goto err_system; } - debug ("Added timestamp successfully\n"); - - munmap ((void *)ptr, sbuf.st_size); - close (tfd); if (rename (tmpfile, params->imagefile) == -1) { fprintf (stderr, "%s: Can't rename %s to %s: %s\n", @@ -160,20 +146,16 @@ static int fit_handle_file (struct mkimage_params *params) strerror (errno)); unlink (tmpfile); unlink (params->imagefile); - return (EXIT_FAILURE); + return EXIT_FAILURE; } - return (EXIT_SUCCESS); + return EXIT_SUCCESS; -err_add_timestamp: -err_add_hashes: - munmap(ptr, sbuf.st_size); -err_mmap: err_system: unlink(tmpfile); return -1; } -static int fit_check_params (struct mkimage_params *params) +static int fit_check_params(struct image_tool_params *params) { return ((params->dflag && (params->fflag || params->lflag)) || (params->fflag && (params->dflag || params->lflag)) || @@ -194,5 +176,5 @@ static struct image_type_params fitimage_params = { void init_fit_image_type (void) { - mkimage_register (&fitimage_params); + register_image_type(&fitimage_params); }