mkheader.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. * Copyright (c) 2007, Google Inc.
  3. * All rights reserved.
  4. *
  5. * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in
  14. * the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of Google, Inc. nor the names of its contributors
  17. * may be used to endorse or promote products derived from this
  18. * software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  30. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <unistd.h>
  36. #include <fcntl.h>
  37. #include <string.h>
  38. #include <sys/stat.h>
  39. int print_usage()
  40. {
  41. fprintf(stderr, "usage: mkheader <bin> <hdr> <none|unified-boot>\n");
  42. fprintf(stderr, " mkheader <bin> <hdr> <unsecure-boot>"
  43. " <outbin>\n");
  44. fprintf(stderr, " mkheader <bin> <hdr> <secure-boot> <outbin>"
  45. " <maxsize>\n");
  46. fprintf(stderr, " mkheader <bin> <hdr> <secure-boot> <outbin>"
  47. " <maxsize> <certchain> <files...>\n\n");
  48. fprintf(stderr, "bin: Input raw appsbl binary\n");
  49. fprintf(stderr,
  50. "hdr: Output of appsbl header location\n");
  51. fprintf(stderr,
  52. "outbin: Output of the signed or unsigned"
  53. " apps boot location\n");
  54. fprintf(stderr,
  55. "maxsize: Maximum size for certificate" " chain\n");
  56. fprintf(stderr,
  57. "certchain: Output of the certchain location\n");
  58. fprintf(stderr,
  59. "files: Input format <bin signature>"
  60. " <certifcate file(s) for certificate chain>...\n");
  61. fprintf(stderr,
  62. "certificate chain: Files will be concatenated in order"
  63. " to create the certificate chain\n\n");
  64. return -1;
  65. }
  66. int cat(FILE * in, FILE * out, unsigned size, unsigned buff_size)
  67. {
  68. unsigned bytes_left = size;
  69. char buf[buff_size];
  70. int ret = 0;
  71. while (bytes_left) {
  72. fread(buf, sizeof(char), buff_size, in);
  73. if (!feof(in)) {
  74. bytes_left -= fwrite(buf, sizeof(char), buff_size, out);
  75. } else
  76. bytes_left = 0;
  77. }
  78. ret = ferror(in) | ferror(out);
  79. if (ret)
  80. fprintf(stderr, "ERROR: Occured during file concatenation\n");
  81. return ret;
  82. }
  83. int main(int argc, char *argv[])
  84. {
  85. struct stat s;
  86. unsigned size, base;
  87. int unified_boot = 0;
  88. unsigned unified_boot_magic[20];
  89. unsigned non_unified_boot_magic[10];
  90. unsigned magic_len = 0;
  91. unsigned *magic;
  92. unsigned cert_chain_size = 0;
  93. unsigned signature_size = 0;
  94. int secure_boot = 0;
  95. int fd;
  96. if (argc < 3) {
  97. return print_usage();
  98. }
  99. if (argc == 4) {
  100. if (!strcmp("unified-boot", argv[3])) {
  101. unified_boot = 1;
  102. } else if (!strcmp("secure-boot", argv[3])) {
  103. fprintf(stderr,
  104. "ERROR: Missing arguments: [outbin maxsize] |"
  105. " [outbin, maxsize, certchain,"
  106. " signature + certifcate(s)]\n");
  107. return print_usage();
  108. } else if (!strcmp("unsecure-boot", argv[3])) {
  109. fprintf(stderr, "ERROR: Missing arguments:"
  110. " outbin directory\n");
  111. return print_usage();
  112. }
  113. }
  114. if (argc > 4) {
  115. if (!strcmp("secure-boot", argv[3])) {
  116. if (argc < 9 && argc != 6) {
  117. fprintf(stderr,
  118. "ERROR: Missing argument(s):"
  119. " [outbin maxsize] | [outbin, maxsize,"
  120. " certchain,"
  121. " signature + certifcate(s)]\n");
  122. return print_usage();
  123. }
  124. secure_boot = 1;
  125. signature_size = 256; //Support SHA 256
  126. cert_chain_size = atoi(argv[5]);
  127. }
  128. }
  129. if (stat(argv[1], &s)) {
  130. perror("cannot stat binary");
  131. return -1;
  132. }
  133. if (unified_boot) {
  134. magic = unified_boot_magic;
  135. magic_len = sizeof(unified_boot_magic);
  136. } else {
  137. magic = non_unified_boot_magic;
  138. magic_len = sizeof(non_unified_boot_magic);
  139. }
  140. size = s.st_size;
  141. #if MEMBASE
  142. base = MEMBASE;
  143. #else
  144. base = 0;
  145. #endif
  146. printf("Image Destination Pointer: 0x%x\n", base);
  147. magic[0] = 0x00000005; /* appsbl */
  148. magic[1] = 0x00000003; //Flash_partition_version /* nand */
  149. magic[2] = 0x00000000; //image source pointer
  150. magic[3] = base; //image destination pointer
  151. magic[4] = size + cert_chain_size + signature_size; //image size
  152. magic[5] = size; //code size
  153. magic[6] = base + size;
  154. magic[7] = signature_size;
  155. magic[8] = size + base + signature_size;
  156. magic[9] = cert_chain_size;
  157. if (unified_boot == 1) {
  158. magic[10] = 0x33836685; /* cookie magic number */
  159. magic[11] = 0x00000001; /* cookie version */
  160. magic[12] = 0x00000002; /* file formats */
  161. magic[13] = 0x00000000;
  162. magic[14] = 0x00000000; /* not setting size for boot.img */
  163. magic[15] = 0x00000000;
  164. magic[16] = 0x00000000;
  165. magic[17] = 0x00000000;
  166. magic[18] = 0x00000000;
  167. magic[19] = 0x00000000;
  168. }
  169. fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
  170. if (fd < 0) {
  171. perror("cannot open header for writing");
  172. return -1;
  173. }
  174. if (write(fd, magic, magic_len) != magic_len) {
  175. perror("cannot write header");
  176. close(fd);
  177. unlink(argv[2]);
  178. return -1;
  179. }
  180. close(fd);
  181. if (secure_boot && argc > 6) {
  182. FILE *input_file;
  183. FILE *output_file;
  184. unsigned buff_size = 1;
  185. char buf[buff_size];
  186. unsigned bytes_left;
  187. unsigned current_cert_chain_size = 0;
  188. int padding_size = 0;
  189. int i;
  190. if ((output_file = fopen(argv[6], "wb")) == NULL) {
  191. perror("ERROR: Occured during fopen");
  192. return -1;
  193. }
  194. printf("Certificate Chain Output File: %s\n", argv[6]);
  195. for (i = 8; i < argc; i++) {
  196. if ((input_file = fopen(argv[i], "rb")) == NULL) {
  197. perror("ERROR: Occured during fopen");
  198. return -1;
  199. }
  200. stat(argv[i], &s);
  201. bytes_left = s.st_size;
  202. current_cert_chain_size += bytes_left;
  203. if (cat(input_file, output_file, bytes_left, buff_size))
  204. return -1;
  205. fclose(input_file);
  206. }
  207. //Pad certifcate chain to the max expected size from input
  208. memset(buf, 0xFF, sizeof(buf));
  209. padding_size = cert_chain_size - current_cert_chain_size;
  210. if (padding_size < 0) {
  211. fprintf(stderr, "ERROR: Input certificate chain"
  212. " (Size=%d) is larger than the maximum"
  213. " specified (Size=%d)\n",
  214. current_cert_chain_size, cert_chain_size);
  215. return -1;
  216. }
  217. bytes_left = (padding_size > 0) ? padding_size : 0;
  218. while (bytes_left) {
  219. if (!ferror(output_file))
  220. bytes_left -= fwrite(buf,
  221. sizeof(buf),
  222. buff_size, output_file);
  223. else {
  224. fprintf(stderr, "ERROR: Occured during"
  225. " certifcate chain padding\n");
  226. return -1;
  227. }
  228. }
  229. fclose(output_file);
  230. /* Concat and combine to signed image.
  231. * Format [HDR][RAW APPSBOOT][PADDED CERT CHAIN]
  232. */
  233. if ((output_file = fopen(argv[4], "wb")) == NULL) {
  234. perror("ERROR: Occured during fopen");
  235. return -1;
  236. }
  237. printf("Image Output File: %s\n", argv[4]);
  238. //Header
  239. if ((input_file = fopen(argv[2], "rb")) == NULL) {
  240. perror("ERROR: Occured during fopen");
  241. return -1;
  242. }
  243. stat(argv[2], &s);
  244. if (cat(input_file, output_file, s.st_size, buff_size))
  245. return -1;
  246. fclose(input_file);
  247. //Raw Appsbl
  248. if ((input_file = fopen(argv[1], "rb")) == NULL) {
  249. perror("ERROR: Occured during fopen");
  250. return -1;
  251. }
  252. stat(argv[1], &s);
  253. if (cat(input_file, output_file, s.st_size, buff_size))
  254. return -1;
  255. fclose(input_file);
  256. //Signature
  257. if ((input_file = fopen(argv[7], "rb")) == NULL) {
  258. perror("ERROR: Occured during fopen");
  259. return -1;
  260. }
  261. stat(argv[7], &s);
  262. if (cat(input_file, output_file, s.st_size, buff_size))
  263. return -1;
  264. fclose(input_file);
  265. //Certifcate Chain
  266. if ((input_file = fopen(argv[6], "rb")) == NULL) {
  267. perror("ERROR: Occured during fopen");
  268. return -1;
  269. }
  270. if (cat(input_file, output_file,
  271. (current_cert_chain_size + padding_size), buff_size))
  272. return -1;
  273. fclose(input_file);
  274. fclose(output_file);
  275. } else if (argc == 5 || argc == 6) {
  276. FILE *input_file;
  277. FILE *output_file;
  278. unsigned buff_size = 1;
  279. char buf[buff_size];
  280. /* Concat and combine to unsigned image.
  281. * Format [HDR][RAW APPSBOOT]
  282. */
  283. if ((output_file = fopen(argv[4], "wb")) == NULL) {
  284. perror("ERROR: Occured during fopen");
  285. return -1;
  286. }
  287. printf("Image Output File: %s\n", argv[4]);
  288. //Header
  289. if ((input_file = fopen(argv[2], "rb")) == NULL) {
  290. perror("ERROR: Occured during fopen");
  291. return -1;
  292. }
  293. stat(argv[2], &s);
  294. if (cat(input_file, output_file, s.st_size, buff_size))
  295. return -1;
  296. fclose(input_file);
  297. //Raw Appsbl
  298. if ((input_file = fopen(argv[1], "rb")) == NULL) {
  299. perror("ERROR: Occured during fopen");
  300. return -1;
  301. }
  302. stat(argv[1], &s);
  303. if (cat(input_file, output_file, s.st_size, buff_size))
  304. return -1;
  305. fclose(input_file);
  306. fclose(output_file);
  307. }
  308. printf("Done execution\n");
  309. return 0;
  310. }