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 ret = 0; 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; } /* for first image creation, add a timestamp at offset 0 i.e., root */ if (params->datafile) { time_t time = imagetool_get_source_date(params->cmdname, sbuf.st_mtime); ret = fit_set_timestamp(ptr, 0, time); } if (!ret) { ret = fit_add_verification_data(params->keydir, dest_blob, ptr, params->comment, params->require_keys, params->engine_id, params->cmdname); } if (dest_blob) { munmap(dest_blob, destfd_size); close(destfd); } err_keydest: munmap(ptr, sbuf.st_size); close(tfd); return ret; }
int fit_image(int argc, char **argv) { if(argc - optind != 2) { fprintf(stderr, "Usage:\n" " %s -f [fit_source].its [fit_image].itb\n", argv[0]); return -1; } char *source = argv[optind]; char *dest = argv[optind+1]; char commandline[4096]; snprintf(commandline, 4096, "../dtc/dtc -S dts -O dtb -p 500 %s -o %s", source, dest); if(system(commandline) < 0) { fprintf(stderr, "Failed to execute the dtc: %s (%s)\n", commandline, strerror(errno)); return -1; } void *ptr; struct stat sbuf; int tfd = mmap_fdt(dest, &ptr, &sbuf); if(tfd < 0) { goto err_mmap; } if(fit_add_verification_data(ptr, "no comment")) { fprintf(stderr, "Failed to add hashes to FIT blob\n"); goto err_add_hashes; } fit_set_timestamp(ptr, 0, sbuf.st_mtime); return 0; err_add_hashes: munmap(ptr, sbuf.st_size); err_mmap: return -1; }
/** * fit_image_write_sig() - write the signature to a FIT * * This writes the signature and signer data to the FIT. * * @fit: pointer to the FIT format image header * @noffset: hash node offset * @value: signature value to be set * @value_len: signature value length * @comment: Text comment to write (NULL for none) * * returns * 0, on success * -FDT_ERR_..., on failure */ static int fit_image_write_sig(void *fit, int noffset, uint8_t *value, int value_len, const char *comment, const char *region_prop, int region_proplen) { int string_size; int ret; /* * Get the current string size, before we update the FIT and add * more */ string_size = fdt_size_dt_strings(fit); ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len); if (!ret) { ret = fdt_setprop_string(fit, noffset, "signer-name", "mkimage"); } if (!ret) { ret = fdt_setprop_string(fit, noffset, "signer-version", PLAIN_VERSION); } if (comment && !ret) ret = fdt_setprop_string(fit, noffset, "comment", comment); if (!ret) ret = fit_set_timestamp(fit, noffset, time(NULL)); if (region_prop && !ret) { uint32_t strdata[2]; ret = fdt_setprop(fit, noffset, "hashed-nodes", region_prop, region_proplen); strdata[0] = 0; strdata[1] = cpu_to_fdt32(string_size); if (!ret) { ret = fdt_setprop(fit, noffset, "hashed-strings", strdata, sizeof(strdata)); } } return ret; }
/** * 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 int fit_handle_file (struct mkimage_params *params) { char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; int tfd, destfd = 0; void *dest_blob = NULL; struct stat sbuf; void *ptr; off_t destfd_size = 0; /* Flattened Image Tree (FIT) format handling */ debug ("FIT format handling\n"); /* call dtc to include binary properties into the tmp file */ if (strlen (params->imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) { fprintf (stderr, "%s: Image file name (%s) too long, " "can't create tmpfile", 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->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; } if (params->keydest) { destfd = mmap_fdt(params, params->keydest, &dest_blob, &sbuf); if (destfd < 0) goto err_keydest; destfd_size = sbuf.st_size; } 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(params->keydir, dest_blob, ptr, params->comment, params->require_keys)) { fprintf(stderr, "%s Can't add hashes to FIT blob\n", params->cmdname); goto err_add_hashes; } /* for first image creation, add a timestamp at offset 0 i.e., root */ if (params->datafile && fit_set_timestamp(ptr, 0, sbuf.st_mtime)) { fprintf (stderr, "%s: Can't add image timestamp\n", params->cmdname); goto err_add_timestamp; } debug ("Added timestamp successfully\n"); munmap ((void *)ptr, sbuf.st_size); close (tfd); if (dest_blob) { munmap(dest_blob, destfd_size); close(destfd); } if (rename (tmpfile, params->imagefile) == -1) { fprintf (stderr, "%s: Can't rename %s to %s: %s\n", params->cmdname, tmpfile, params->imagefile, strerror (errno)); unlink (tmpfile); unlink (params->imagefile); return (EXIT_FAILURE); } return (EXIT_SUCCESS); err_add_timestamp: err_add_hashes: munmap(ptr, sbuf.st_size); err_mmap: if (dest_blob) munmap(dest_blob, destfd_size); err_keydest: err_system: unlink(tmpfile); return -1; }
/** * 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); } }
/** * 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 int fit_handle_file (struct mkimage_params *params) { char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; int tfd; struct stat sbuf; void *ptr; /* Flattened Image Tree (FIT) format handling */ debug ("FIT format handling\n"); /* call dtc to include binary properties into the tmp file */ if (strlen (params->imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) { fprintf (stderr, "%s: Image file name (%s) too long, " "can't create tmpfile", params->imagefile, params->cmdname); return (EXIT_FAILURE); } 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); 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; } /* 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; } 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", params->cmdname, tmpfile, params->imagefile, strerror (errno)); unlink (tmpfile); unlink (params->imagefile); return (EXIT_FAILURE); } return (EXIT_SUCCESS); err_add_timestamp: err_add_hashes: munmap(ptr, sbuf.st_size); err_mmap: err_system: unlink(tmpfile); return -1; }