blob: 69c1ab6b7f05e7d7fbd4c9c0983e257bb1130119 [file] [log] [blame]
Kinson Chik18e36332011-08-15 10:07:28 -07001/*
2 * Copyright (c) 2007, Google Inc.
3 * All rights reserved.
4 *
Duy Truongf3ac7b32013-02-13 01:07:28 -08005 * Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
Kinson Chik18e36332011-08-15 10:07:28 -07006 *
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
34#include <stdio.h>
35#include <stdlib.h>
36#include <unistd.h>
37#include <fcntl.h>
38#include <string.h>
39
40#include <sys/stat.h>
41
42int print_usage(){
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,"hdr: Output of appsbl header location\n");
52 fprintf(stderr,"outbin: Output of the signed or unsigned"
53 " apps boot location\n");
54 fprintf(stderr,"maxsize: Maximum size for certificate"
55 " chain\n");
56 fprintf(stderr,"certchain: Output of the certchain location\n");
57 fprintf(stderr,"files: Input format <bin signature>"
58 " <certifcate file(s) for certificate chain>...\n");
59 fprintf(stderr,"certificate chain: Files will be concatenated in order"
60 " to create the certificate chain\n\n");
61 return -1;
62}
63
64int cat(FILE * in, FILE * out, unsigned size, unsigned buff_size){
65 unsigned bytes_left = size;
66 char buf[buff_size];
67 int ret = 0;
68
69 while(bytes_left){
70 fread(buf, sizeof(char), buff_size, in);
71 if(!feof(in)){
72 bytes_left -= fwrite(buf, sizeof(char), buff_size, out);
73 }
74 else
75 bytes_left = 0;
76 }
77 ret = ferror(in) | ferror(out);
78 if(ret)
79 fprintf(stderr, "ERROR: Occured during file concatenation\n");
80 return ret;
81}
82
83int 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
97 if(argc < 3) {
98 return print_usage();
99 }
100
101 if(argc == 4) {
102 if(!strcmp("unified-boot",argv[3])) {
103 unified_boot = 1;
104 }
105 else if(!strcmp("secure-boot",argv[3])){
106 fprintf(stderr,
107 "ERROR: Missing arguments: [outbin maxsize] |"
108 " [outbin, maxsize, certchain,"
109 " signature + certifcate(s)]\n");
110 return print_usage();
111 }
112 else if(!strcmp("unsecure-boot",argv[3])){
113 fprintf(stderr,"ERROR: Missing arguments:"
114 " outbin directory\n");
115 return print_usage();
116 }
117 }
118
119 if(argc > 4) {
120 if(!strcmp("secure-boot",argv[3])) {
121 if(argc < 9 && argc != 6){
122 fprintf(stderr,
123 "ERROR: Missing argument(s):"
124 " [outbin maxsize] | [outbin, maxsize,"
125 " certchain,"
126 " signature + certifcate(s)]\n");
127 return print_usage();
128 }
129 secure_boot = 1;
130 signature_size = 256; //Support SHA 256
131 cert_chain_size = atoi(argv[5]);
132 }
133 }
134
135 if(stat(argv[1], &s)) {
136 perror("cannot stat binary");
137 return -1;
138 }
139
140 if(unified_boot) {
141 magic = unified_boot_magic;
142 magic_len = sizeof(unified_boot_magic);
143 }
144 else {
145 magic = non_unified_boot_magic;
146 magic_len = sizeof(non_unified_boot_magic);
147 }
148
149 size = s.st_size;
150#if MEMBASE
151 base = MEMBASE;
152#else
153 base = 0;
154#endif
155
156 printf("Image Destination Pointer: 0x%x\n", base);
157
158 magic[0] = 0x00000005; /* appsbl */
159 magic[1] = 0x00000003; //Flash_partition_version /* nand */
160 magic[2] = 0x00000000; //image source pointer
161 magic[3] = base; //image destination pointer
162 magic[4] = size + cert_chain_size + signature_size; //image size
163 magic[5] = size; //code size
164 magic[6] = base + size;
165 magic[7] = signature_size;
166 magic[8] = size + base + signature_size;
167 magic[9] = cert_chain_size;
168
169 if(unified_boot == 1)
170 {
171 magic[10] = 0x33836685; /* cookie magic number */
172 magic[11] = 0x00000001; /* cookie version */
173 magic[12] = 0x00000002; /* file formats */
174 magic[13] = 0x00000000;
175 magic[14] = 0x00000000; /* not setting size for boot.img */
176 magic[15] = 0x00000000;
177 magic[16] = 0x00000000;
178 magic[17] = 0x00000000;
179 magic[18] = 0x00000000;
180 magic[19] = 0x00000000;
181 }
182
183 fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
184 if(fd < 0) {
185 perror("cannot open header for writing");
186 return -1;
187 }
188 if(write(fd, magic, magic_len) != magic_len) {
189 perror("cannot write header");
190 close(fd);
191 unlink(argv[2]);
192 return -1;
193 }
194 close(fd);
195
196 if(secure_boot && argc > 6){
197 FILE * input_file;
198 FILE * output_file;
199 unsigned buff_size = 1;
200 char buf[buff_size];
201 unsigned bytes_left;
202 unsigned current_cert_chain_size = 0;
203 int padding_size = 0;
204 int i;
205
206 if((output_file = fopen(argv[6], "wb"))==NULL){
207 perror("ERROR: Occured during fopen");
208 return -1;
209 }
210 printf("Certificate Chain Output File: %s\n", argv[6]);
211
212 for(i = 8; i < argc; i++){
213 if((input_file = fopen(argv[i], "rb"))==NULL){
214 perror("ERROR: Occured during fopen");
215 return -1;
216 }
217 stat(argv[i], &s);
218 bytes_left = s.st_size;
219 current_cert_chain_size += bytes_left;
220 if(cat(input_file, output_file, bytes_left, buff_size))
221 return -1;
222 fclose(input_file);
223 }
224
225 //Pad certifcate chain to the max expected size from input
226 memset(buf, 0xFF, sizeof(buf));
227 padding_size = cert_chain_size - current_cert_chain_size;
228
229 if(padding_size <0){
230 fprintf(stderr, "ERROR: Input certificate chain"
231 " (Size=%d) is larger than the maximum"
232 " specified (Size=%d)\n",
233 current_cert_chain_size, cert_chain_size);
234 return -1;
235 }
236
237 bytes_left = (padding_size > 0) ? padding_size : 0;
238 while(bytes_left){
239 if(!ferror(output_file))
240 bytes_left -= fwrite(buf,
241 sizeof(buf),
242 buff_size,
243 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 }
304 else if(argc == 5 || argc == 6){
305 FILE * input_file;
306 FILE * output_file;
307 unsigned buff_size = 1;
308 char buf[buff_size];
309
310 /* Concat and combine to unsigned image.
311 * Format [HDR][RAW APPSBOOT]
312 */
313 if((output_file = fopen(argv[4], "wb"))==NULL){
314 perror("ERROR: Occured during fopen");
315 return -1;
316 }
317 printf("Image Output File: %s\n", argv[4]);
318
319 //Header
320 if((input_file = fopen(argv[2], "rb"))==NULL){
321 perror("ERROR: Occured during fopen");
322 return -1;
323 }
324 stat(argv[2], &s);
325 if(cat(input_file, output_file, s.st_size, buff_size))
326 return -1;
327 fclose(input_file);
328
329 //Raw Appsbl
330 if((input_file = fopen(argv[1], "rb"))==NULL){
331 perror("ERROR: Occured during fopen");
332 return -1;
333 }
334 stat(argv[1], &s);
335 if(cat(input_file, output_file, s.st_size, buff_size))
336 return -1;
337 fclose(input_file);
338 fclose(output_file);
339 }
340
341 printf("Done execution\n");
342
343 return 0;
344}