1 // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
2 // Licensed under the terms of the GNU GPL, version 2
3 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
11 #define ERROR(s) do { fprintf(stderr, s "\n"); exit(1); } while (0)
15 static u8 md5_blanker
[16];
19 static u32 files_size
;
20 static u32 total_size
;
22 static void output_image(u8
*data
, u32 w
, u32 h
, const char *name
)
27 fp
= fopen(name
, "wb");
29 fprintf(fp
, "P6 %d %d 255\n", w
, h
);
31 for (y
= 0; y
< h
; y
++)
32 for (x
= 0; x
< w
; x
++) {
35 u32 x0
, x1
, y0
, y1
, off
;
41 off
= x0
+ 4 * y0
+ 16 * x1
+ 4 * w
* y1
;
43 raw
= be16(data
+ 2*off
);
47 pix
[0] = (raw
>> 7) & 0xf8;
48 pix
[1] = (raw
>> 2) & 0xf8;
49 pix
[2] = (raw
<< 3) & 0xf8;
51 pix
[0] = (raw
>> 4) & 0xf0;
53 pix
[2] = (raw
<< 4) & 0xf0;
56 fwrite(pix
, 1, 3, fp
);
62 static void do_file_header(void)
68 fread(header
, 1, sizeof header
, fp
);
70 aes_cbc_dec(sd_key
, sd_iv
, header
, sizeof header
, header
);
72 memcpy(md5_file
, header
+ 0x0e, 16);
73 memcpy(header
+ 0x0e, md5_blanker
, 16);
74 md5(header
, sizeof header
, md5_calc
);
76 if (memcmp(md5_file
, md5_calc
, 0x10))
77 ERROR("MD5 mismatch");
79 output_image(header
+ 0xc0, 192, 64, "###banner###.ppm");
80 output_image(header
+ 0x60c0, 48, 48, "###icon###.ppm");
83 static void do_backup_header(void)
87 fread(header
, 1, sizeof header
, fp
);
89 if (be32(header
+ 4) != 0x426b0001)
90 ERROR("no Bk header");
91 if (be32(header
) != 0x70)
92 ERROR("wrong Bk header size");
94 fprintf(stderr
, "NG id: %08x\n", be32(header
+ 8));
96 n_files
= be32(header
+ 0x0c);
97 files_size
= be32(header
+ 0x10);
98 total_size
= be32(header
+ 0x1c);
100 fprintf(stderr
, "%d files\n", n_files
);
103 static void do_file(void)
113 fread(header
, 1, sizeof header
, fp
);
115 if (be32(header
) != 0x03adf17e)
116 ERROR("bad file header");
118 size
= be32(header
+ 4);
124 fprintf(stderr
, "file: size=%08x perm=%02x attr=%02x type=%02x name=%s\n", size
, perm
, attr
, type
, name
);
127 ERROR("unhandled: file type != 1");
129 rounded_size
= (size
+ 63) & ~63;
130 data
= malloc(rounded_size
);
131 fread(data
, 1, rounded_size
, fp
);
133 aes_cbc_dec(sd_key
, header
+ 0x50, data
, rounded_size
, data
);
135 out
= fopen(name
, "wb");
136 fwrite(data
, 1, size
, out
);
142 static void do_sig(void)
152 fread(sig
, 1, sizeof sig
, fp
);
153 fread(ng_cert
, 1, sizeof ng_cert
, fp
);
154 fread(ap_cert
, 1, sizeof ap_cert
, fp
);
156 data_size
= total_size
- 0x340;
158 data
= malloc(data_size
);
159 fseek(fp
, 0xf0c0, SEEK_SET
);
160 fread(data
, 1, data_size
, fp
);
161 sha(data
, data_size
, hash
);
165 ok
= check_ec(ng_cert
, ap_cert
, sig
, hash
);
166 printf("ok: %d\n", ok
);
169 int main(int argc
, char **argv
)
173 get_key("sd-key", sd_key
, 16);
174 get_key("sd-iv", sd_iv
, 16);
175 get_key("md5-blanker", md5_blanker
, 16);
177 fp
= fopen(argv
[1], "rb");
181 for (i
= 0; i
< n_files
; i
++)