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 main(int argc, char **argv) { int ffd = -1; int kfd = -1; struct stat fsbuf; struct stat ksbuf; void *fit_blob; char *fdtfile = NULL; char *keyfile = NULL; char cmdname[256]; int ret; void *key_blob; int c; strncpy(cmdname, *argv, sizeof(cmdname) - 1); cmdname[sizeof(cmdname) - 1] = '\0'; while ((c = getopt(argc, argv, "f:k:")) != -1) switch (c) { case 'f': fdtfile = optarg; break; case 'k': keyfile = optarg; break; default: usage(cmdname); break; } ffd = mmap_fdt(cmdname, fdtfile, &fit_blob, &fsbuf, 0); if (ffd < 0) return EXIT_FAILURE; kfd = mmap_fdt(cmdname, keyfile, &key_blob, &ksbuf, 0); if (ffd < 0) return EXIT_FAILURE; image_set_host_blob(key_blob); ret = fit_check_sign(fit_blob, key_blob); if (ret) ret = EXIT_SUCCESS; else ret = EXIT_FAILURE; (void) munmap((void *)fit_blob, fsbuf.st_size); (void) munmap((void *)key_blob, ksbuf.st_size); close(ffd); close(kfd); exit(ret); }
int main(int argc, char **argv) { int ffd = -1; struct stat fsbuf; void *fit_blob; int len; int nodeoffset; /* node offset from libfdt */ const void *nodep; /* property node pointer */ char *fdtfile = NULL; char *nodename = NULL; char *propertyname = NULL; char cmdname[50]; int c; strcpy(cmdname, *argv); while ((c = getopt(argc, argv, "f:n:p:")) != -1) switch (c) { case 'f': fdtfile = optarg; break; case 'n': nodename = optarg; break; case 'p': propertyname = optarg; break; default: usage(cmdname); break; } ffd = mmap_fdt(cmdname, fdtfile, &fit_blob, &fsbuf, 0); if (ffd < 0) { printf("Could not open %s\n", fdtfile); exit(EXIT_FAILURE); } nodeoffset = fdt_path_offset(fit_blob, nodename); if (nodeoffset < 0) { printf("%s not found.", nodename); exit(EXIT_FAILURE); } nodep = fdt_getprop(fit_blob, nodeoffset, propertyname, &len); if (len == 0) { printf("len == 0 %s\n", propertyname); exit(EXIT_FAILURE); } printf("NAME: %s\n", fit_get_name(fit_blob, nodeoffset, NULL)); printf("LEN: %d\n", len); printf("OFF: %d\n", (int)(nodep - fit_blob)); (void) munmap((void *)fit_blob, fsbuf.st_size); close(ffd); exit(EXIT_SUCCESS); }
int fit_list_image(int argc, char **argv) { if(argc - optind != 1) { fprintf(stderr, "Usage:\n" " %s -l [fit_image].itb\n", argv[0]); return -1; } char *filename = argv[optind]; void *fit; struct stat sbuf; if(mmap_fdt(filename, &fit, &sbuf) < 0) { printf("failed to mmap file\n"); return -1; } time_t t; int noffset = fdt_path_offset(fit, "/"); const char *description = fdt_getprop(fit, noffset, "description", NULL); if(!description) { description = "Unavailable"; } const char *timestamp = "Unavailable"; const fdt32_t *time_fdt = fdt_getprop(fit, noffset, "timestamp", NULL); if(time_fdt) { t = fdt32_to_cpu(*time_fdt); timestamp = ctime(&t); } printf("FIT description : %s\n", description); printf("Generated : %s", timestamp); int images_offset = fdt_path_offset(fit, "/images"); if(images_offset < 0) { fprintf(stderr, "Can't find /images node in %s\n", filename); return -1; } fit_list_images(fit, images_offset); int configs_offset = fdt_path_offset(fit, "/configurations"); fit_list_configs(fit, configs_offset); return 0; }
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_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 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; }