1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2014 4 * DENX Software Engineering 5 * Heiko Schocher <hs@denx.de> 6 * 7 * (C) Copyright 2008 Semihalf 8 * 9 * (C) Copyright 2000-2004 10 * DENX Software Engineering 11 * Wolfgang Denk, wd@denx.de 12 * 13 * Updated-by: Prafulla Wadaskar <prafulla@marvell.com> 14 * FIT image specific code abstracted from mkimage.c 15 * some functions added to address abstraction 16 * 17 * All rights reserved. 18 */ 19 20#include "imagetool.h" 21#include "mkimage.h" 22#include "fit_common.h" 23#include <image.h> 24#include <u-boot/crc.h> 25 26#define COPYFILE_BUFSIZE (64 * 1024) 27 28void fit_print_header(const void *fit, struct image_tool_params *params) 29{ 30 fit_print_contents(fit); 31} 32 33int fit_verify_header(unsigned char *ptr, int image_size, 34 struct image_tool_params *params) 35{ 36 int ret; 37 38 if (fdt_check_header(ptr) != EXIT_SUCCESS) 39 return EXIT_FAILURE; 40 41 ret = fit_check_format(ptr, IMAGE_SIZE_INVAL); 42 if (ret) { 43 if (ret != -EADDRNOTAVAIL) 44 return EXIT_FAILURE; 45 fprintf(stderr, "Image contains unit addresses @, this will break signing\n"); 46 } 47 48 return EXIT_SUCCESS; 49} 50 51int fit_check_image_types(uint8_t type) 52{ 53 if (type == IH_TYPE_FLATDT) 54 return EXIT_SUCCESS; 55 else 56 return EXIT_FAILURE; 57} 58 59int mmap_fdt(const char *cmdname, const char *fname, size_t size_inc, 60 void **blobp, struct stat *sbuf, bool delete_on_error, 61 bool read_only) 62{ 63 void *ptr; 64 int fd; 65 66 /* Load FIT blob into memory (we need to write hashes/signatures) */ 67 fd = open(fname, (read_only ? O_RDONLY : O_RDWR) | O_BINARY); 68 69 if (fd < 0) { 70 fprintf(stderr, "%s: Can't open %s: %s\n", 71 cmdname, fname, strerror(errno)); 72 goto err; 73 } 74 75 if (fstat(fd, sbuf) < 0) { 76 fprintf(stderr, "%s: Can't stat %s: %s\n", 77 cmdname, fname, strerror(errno)); 78 goto err; 79 } 80 81 if (size_inc) { 82 sbuf->st_size += size_inc; 83 if (ftruncate(fd, sbuf->st_size)) { 84 fprintf(stderr, "%s: Can't expand %s: %s\n", 85 cmdname, fname, strerror(errno)); 86 goto err; 87 } 88 } 89 90 errno = 0; 91 ptr = mmap(0, sbuf->st_size, 92 (read_only ? PROT_READ : PROT_READ | PROT_WRITE), MAP_SHARED, 93 fd, 0); 94 if ((ptr == MAP_FAILED) || (errno != 0)) { 95 fprintf(stderr, "%s: Can't read %s: %s\n", 96 cmdname, fname, strerror(errno)); 97 goto err; 98 } 99 100 /* check if ptr has a valid blob */ 101 if (fdt_check_header(ptr)) { 102 fprintf(stderr, "%s: Invalid FIT blob\n", cmdname); 103 goto err; 104 } 105 106 /* expand if needed */ 107 if (size_inc) { 108 int ret; 109 110 ret = fdt_open_into(ptr, ptr, sbuf->st_size); 111 if (ret) { 112 fprintf(stderr, "%s: Cannot expand FDT: %s\n", 113 cmdname, fdt_strerror(ret)); 114 goto err; 115 } 116 } 117 118 *blobp = ptr; 119 return fd; 120 121err: 122 if (fd >= 0) 123 close(fd); 124 if (delete_on_error) 125 unlink(fname); 126 127 return -1; 128} 129 130int copyfile(const char *src, const char *dst) 131{ 132 int fd_src = -1, fd_dst = -1; 133 void *buf = NULL; 134 ssize_t size; 135 size_t count; 136 int ret = -1; 137 138 fd_src = open(src, O_RDONLY); 139 if (fd_src < 0) { 140 printf("Can't open file %s (%s)\n", src, strerror(errno)); 141 goto out; 142 } 143 144 fd_dst = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0666); 145 if (fd_dst < 0) { 146 printf("Can't open file %s (%s)\n", dst, strerror(errno)); 147 goto out; 148 } 149 150 buf = calloc(1, COPYFILE_BUFSIZE); 151 if (!buf) { 152 printf("Can't allocate buffer to copy file\n"); 153 goto out; 154 } 155 156 while (1) { 157 size = read(fd_src, buf, COPYFILE_BUFSIZE); 158 if (size < 0) { 159 printf("Can't read file %s\n", src); 160 goto out; 161 } 162 if (!size) 163 break; 164 165 count = size; 166 size = write(fd_dst, buf, count); 167 if (size < 0) { 168 printf("Can't write file %s\n", dst); 169 goto out; 170 } 171 } 172 173 ret = 0; 174 175 out: 176 if (fd_src >= 0) 177 close(fd_src); 178 if (fd_dst >= 0) 179 close(fd_dst); 180 if (buf) 181 free(buf); 182 183 return ret; 184} 185 186void summary_show(struct image_summary *summary, const char *imagefile, 187 const char *keydest) 188{ 189 if (summary->sig_offset) { 190 printf("Signature written to '%s', node '%s'\n", imagefile, 191 summary->sig_path); 192 if (keydest) { 193 printf("Public key written to '%s', node '%s'\n", 194 keydest, summary->keydest_path); 195 } 196 } 197} 198