+
+static void
+image_verify_header (char *ptr, int image_size)
+{
+ int len;
+ char *data;
+ uint32_t checksum;
+ image_header_t header;
+ image_header_t *hdr = &header;
+
+ /*
+ * create copy of header so that we can blank out the
+ * checksum field for checking - this can't be done
+ * on the PROT_READ mapped data.
+ */
+ memcpy (hdr, ptr, sizeof(image_header_t));
+
+ if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+ fprintf (stderr,
+ "%s: Bad Magic Number: \"%s\" is no valid image\n",
+ cmdname, imagefile);
+ exit (EXIT_FAILURE);
+ }
+
+ data = (char *)hdr;
+ len = sizeof(image_header_t);
+
+ checksum = ntohl(hdr->ih_hcrc);
+ hdr->ih_hcrc = htonl(0); /* clear for re-calculation */
+
+ if (crc32 (0, data, len) != checksum) {
+ fprintf (stderr,
+ "%s: ERROR: \"%s\" has bad header checksum!\n",
+ cmdname, imagefile);
+ exit (EXIT_FAILURE);
+ }
+
+ data = ptr + sizeof(image_header_t);
+ len = image_size - sizeof(image_header_t) ;
+
+ if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) {
+ fprintf (stderr,
+ "%s: ERROR: \"%s\" has corrupted data!\n",
+ cmdname, imagefile);
+ exit (EXIT_FAILURE);
+ }
+}
+
+/**
+ * fit_handle_file - main FIT file processing function
+ *
+ * fit_handle_file() runs dtc to convert .its to .itb, includes
+ * binary data, updates timestamp property and calculates hashes.
+ *
+ * datafile - .its file
+ * imagefile - .itb file
+ *
+ * returns:
+ * only on success, otherwise calls exit (EXIT_FAILURE);
+ */
+static void fit_handle_file (void)
+{
+ char tmpfile[MKIMAGE_MAX_TMPFILE_LEN];
+ char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN];
+ int tfd;
+ struct stat sbuf;
+ unsigned char *ptr;
+
+ /* call dtc to include binary properties into the tmp file */
+ if (strlen (imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 >
+ sizeof (tmpfile)) {
+ fprintf (stderr, "%s: Image file name (%s) too long, "
+ "can't create tmpfile",
+ imagefile, cmdname);
+ exit (EXIT_FAILURE);
+ }
+ sprintf (tmpfile, "%s%s", imagefile, MKIMAGE_TMPFILE_SUFFIX);
+
+ /* dtc -I dts -O -p 200 datafile > tmpfile */
+ sprintf (cmd, "%s %s %s > %s",
+ MKIMAGE_DTC, opt_dtc, datafile, tmpfile);
+ debug ("Trying to execute \"%s\"\n", cmd);
+ if (system (cmd) == -1) {
+ fprintf (stderr, "%s: system(%s) failed: %s\n",
+ cmdname, cmd, strerror(errno));
+ unlink (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+
+ /* load FIT blob into memory */
+ tfd = open (tmpfile, O_RDWR|O_BINARY);
+
+ if (tfd < 0) {
+ fprintf (stderr, "%s: Can't open %s: %s\n",
+ cmdname, tmpfile, strerror(errno));
+ unlink (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+
+ if (fstat (tfd, &sbuf) < 0) {
+ fprintf (stderr, "%s: Can't stat %s: %s\n",
+ cmdname, tmpfile, strerror(errno));
+ unlink (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+
+ ptr = mmap (0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, tfd, 0);
+ if (ptr == MAP_FAILED) {
+ fprintf (stderr, "%s: Can't read %s: %s\n",
+ cmdname, tmpfile, strerror(errno));
+ unlink (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+
+ /* check if ptr has a valid blob */
+ if (fdt_check_header (ptr)) {
+ fprintf (stderr, "%s: Invalid FIT blob\n", cmdname);
+ unlink (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+
+ /* set hashes for images in the blob */
+ if (fit_set_hashes (ptr)) {
+ fprintf (stderr, "%s Can't add hashes to FIT blob", cmdname);
+ unlink (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+
+ /* 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", cmdname);
+ unlink (tmpfile);
+ exit (EXIT_FAILURE);
+ }
+ debug ("Added timestamp successfully\n");
+
+ munmap ((void *)ptr, sbuf.st_size);
+ close (tfd);
+
+ if (rename (tmpfile, imagefile) == -1) {
+ fprintf (stderr, "%s: Can't rename %s to %s: %s\n",
+ cmdname, tmpfile, imagefile, strerror (errno));
+ unlink (tmpfile);
+ unlink (imagefile);
+ exit (EXIT_FAILURE);
+ }
+}