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