diff options
Diffstat (limited to 'tools/mk500boot.c')
-rw-r--r-- | tools/mk500boot.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/tools/mk500boot.c b/tools/mk500boot.c new file mode 100644 index 0000000000..1187058091 --- /dev/null +++ b/tools/mk500boot.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2009 by Karl Kurbjun | ||
10 | * $Id$ | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include <stdio.h> | ||
21 | #include <errno.h> | ||
22 | #include <inttypes.h> | ||
23 | #include <string.h> | ||
24 | #include "mr500.h" | ||
25 | |||
26 | /* This is the patch necessary for the SVG exploit (decrypted) */ | ||
27 | struct patch_single hack[] = { {0x29B28, 0xE12FFF30}, | ||
28 | {0x2F960, 0xE12FFF30} }; | ||
29 | |||
30 | static void usage(void) | ||
31 | { | ||
32 | printf( "Usage: mk500boot <options> <input file> [output file]\n" | ||
33 | "options:\n" | ||
34 | "\t-decrypt Decrypt the input file and save the output file\n" | ||
35 | "\t-encrypt Encrypt the input file and save the output file\n" | ||
36 | "\t-patch Patch the input file with the SVF hack\n\n"); | ||
37 | |||
38 | exit(1); | ||
39 | } | ||
40 | |||
41 | /* This is a fake flag that is used to let the tool know what's up */ | ||
42 | #define HEADER_DECRYPTED 0x8000 | ||
43 | |||
44 | void display_header(struct olympus_header *header) { | ||
45 | printf("Magic Name: \t%s\n", header->magic_name); | ||
46 | printf("Unknown: \t0x%08hX\n", header->unknown); | ||
47 | printf("Header Length: \t0x%04X\n", header->header_length); | ||
48 | printf("Flags: \t\t0x%04X\n", header->flags); | ||
49 | printf("Unknonwn Zeros: 0x%08X\n", header->unknown_zeros); | ||
50 | printf("Image Length: \t0x%08X\n", header->image_length); | ||
51 | } | ||
52 | |||
53 | /* This is a demonstration of the encryption and decryption process. | ||
54 | * It patches a FW image to include the SVG exploit. | ||
55 | */ | ||
56 | int main (int argc, char *argv[]) { | ||
57 | uint32_t checksum; | ||
58 | uint32_t stored_crc; | ||
59 | |||
60 | enum operations { | ||
61 | decrypt, | ||
62 | encrypt, | ||
63 | patch | ||
64 | } operation; | ||
65 | |||
66 | char *encrypt_file; | ||
67 | char *decrypt_file; | ||
68 | |||
69 | struct olympus_header header; | ||
70 | |||
71 | if (argc < 2) { | ||
72 | usage(); | ||
73 | return -1; | ||
74 | } | ||
75 | |||
76 | if(!strcmp(argv[1], "-decrypt")) { | ||
77 | if(argc < 3) { | ||
78 | usage(); | ||
79 | return -1; | ||
80 | } | ||
81 | encrypt_file=argv[2]; | ||
82 | decrypt_file=argv[3]; | ||
83 | operation = decrypt; | ||
84 | } else if(!strcmp(argv[1], "-encrypt")) { | ||
85 | if(argc < 3) { | ||
86 | usage(); | ||
87 | return -1; | ||
88 | } | ||
89 | decrypt_file = argv[2]; | ||
90 | encrypt_file = argv[3]; | ||
91 | operation = encrypt; | ||
92 | } else if(!strcmp(argv[1], "-patch")) { | ||
93 | decrypt_file = argv[2]; | ||
94 | encrypt_file = argv[3]; | ||
95 | operation = patch; | ||
96 | } else { | ||
97 | return -1; | ||
98 | } | ||
99 | |||
100 | /* Initialize encryption/decryption routine */ | ||
101 | mr500_init(); | ||
102 | |||
103 | if(operation == decrypt) { | ||
104 | /* Read in the header of the encrypted file */ | ||
105 | if(mr500_read_header(encrypt_file, &header) < 0 ) { | ||
106 | printf("ERROR: Unable to read header: %s\n", strerror(errno)); | ||
107 | return -1; | ||
108 | } | ||
109 | |||
110 | /* Read CRC of encrypted file */ | ||
111 | if(mr500_read_crc(encrypt_file, | ||
112 | header.header_length+header.image_length, &stored_crc) < 0 ) { | ||
113 | printf("ERROR: Unable to read CRC: %s\n", strerror(errno)); | ||
114 | return -1; | ||
115 | } | ||
116 | |||
117 | /* Display the header information */ | ||
118 | printf("File format:\n"); | ||
119 | |||
120 | printf("*****Header*****\n"); | ||
121 | display_header(&header); | ||
122 | printf("****************\n\n"); | ||
123 | |||
124 | printf("*****Image******\n\n"); | ||
125 | |||
126 | printf("*****Footer*****\n"); | ||
127 | printf("Checksum: \t0x%08X\n", stored_crc); | ||
128 | printf("****************\n\n"); | ||
129 | |||
130 | printf("Writing Decrypted file...\n"); | ||
131 | |||
132 | /********************************************************************* | ||
133 | * Save a decrypted file | ||
134 | **********************************************************************/ | ||
135 | |||
136 | /* Check to make sure this is a encrypted file (bogus flag not set) */ | ||
137 | if(header.flags & HEADER_DECRYPTED) { | ||
138 | printf("ERROR: This appears to be a decrypted file! Quitting\n"); | ||
139 | return -1; | ||
140 | } | ||
141 | |||
142 | /* Check to make sure MAGIC string matches expected*/ | ||
143 | if(strncmp((char *)header.magic_name, "OIMCFWUP", 8)) { | ||
144 | printf("ERROR: Magic string does not match expected! Quitting\n"); | ||
145 | return -1; | ||
146 | } | ||
147 | |||
148 | /* Set a bogus flag to let the tool know that this is a decrypted file*/ | ||
149 | header.flags |= HEADER_DECRYPTED; | ||
150 | |||
151 | /* Start by writing out the header */ | ||
152 | if(mr500_save_header(decrypt_file, &header) < 0 ) { | ||
153 | printf("ERROR: Unable to save header: %s\n", strerror(errno)); | ||
154 | return -1; | ||
155 | } | ||
156 | |||
157 | /* Read encrypted data and save decrypted data */ | ||
158 | if(mr500_save_data( encrypt_file, decrypt_file, header.header_length, | ||
159 | header.image_length, decrypt_array) < 0 ) { | ||
160 | printf("ERROR: Unable to save decrypted data: %s\n", strerror(errno)); | ||
161 | return -1; | ||
162 | } | ||
163 | |||
164 | printf("Calculating Checksum...\n"); | ||
165 | /* Calculate CRC of decrypted data */ | ||
166 | if(mr500_calculate_crc( decrypt_file, header.header_length, | ||
167 | header.image_length, &checksum) < 0 ) { | ||
168 | printf("ERROR: Unable to calculate CRC: %s\n", strerror(errno)); | ||
169 | return -1; | ||
170 | } | ||
171 | |||
172 | printf("Calculated Checksum: \n\t\t0x%08X\n", checksum); | ||
173 | |||
174 | /* Double check to make sure that the two CRCs match */ | ||
175 | if(checksum!=stored_crc) { | ||
176 | printf("\tERROR: \tCalculated checksum: \t0x%08X and\n", checksum); | ||
177 | printf("\t\tStored checksum: \t0x%08X do not match\n", stored_crc); | ||
178 | return -1; | ||
179 | } else { | ||
180 | printf("\tOK: Calculated checksum and stored checksum match.\n"); | ||
181 | } | ||
182 | |||
183 | printf("Saving Checksum...\n"); | ||
184 | /* Save the calculated CRC to the file */ | ||
185 | if(mr500_save_crc(decrypt_file, header.header_length+header.image_length, | ||
186 | &checksum) < 0 ) { | ||
187 | printf("ERROR: Unable to save CRC: %s\n", strerror(errno)); | ||
188 | return -1; | ||
189 | } | ||
190 | |||
191 | } else if(operation == patch) { | ||
192 | |||
193 | /********************************************************************** | ||
194 | * Patch decryped file with SVG exploit | ||
195 | **********************************************************************/ | ||
196 | printf("Patching decrypted file.\n"); | ||
197 | |||
198 | /* Read in the header of the encrypted file */ | ||
199 | if(mr500_read_header(decrypt_file, &header) < 0 ) { | ||
200 | printf("ERROR: Unable to read header: %s\n", strerror(errno)); | ||
201 | return -1; | ||
202 | } | ||
203 | |||
204 | /* Check to make sure this is a decrypted file (bogus flag not set) */ | ||
205 | if(!(header.flags & HEADER_DECRYPTED)) { | ||
206 | printf("ERROR: This appears to be a encrypted file! Quitting\n"); | ||
207 | return -1; | ||
208 | } | ||
209 | |||
210 | /* Check to make sure MAGIC string matches expected*/ | ||
211 | if(strncmp((char *)header.magic_name, "OIMCFWUP", 8)) { | ||
212 | printf("ERROR: Magic string does not match expected! Quitting\n"); | ||
213 | return -1; | ||
214 | } | ||
215 | |||
216 | printf("File Header:\n"); | ||
217 | display_header(&header); | ||
218 | |||
219 | if(mr500_patch_file (decrypt_file, hack, 2) < 0 ) { | ||
220 | printf("ERROR: Unable to patch file: %s\n", strerror(errno)); | ||
221 | return -1; | ||
222 | } | ||
223 | |||
224 | printf("\nCalculating new CRC\n"); | ||
225 | |||
226 | /* Calculate the 'CRC' of the patched file */ | ||
227 | if(mr500_calculate_crc( decrypt_file, header.header_length, | ||
228 | header.image_length, &checksum) < 0 ) { | ||
229 | printf("ERROR: Unable to calculate CRC: %s\n", strerror(errno)); | ||
230 | return -1; | ||
231 | } | ||
232 | |||
233 | printf("Calculated CRC: \n\t\t0x%08X\n", checksum); | ||
234 | /* Store the calculated 'CRC' (not encrypted) */ | ||
235 | if(mr500_save_crc(decrypt_file, header.header_length+header.image_length, | ||
236 | &checksum) < 0 ) { | ||
237 | printf("ERROR: Unable to save CRC: %s\n", strerror(errno)); | ||
238 | return -1; | ||
239 | } | ||
240 | |||
241 | } else if(operation == encrypt) { | ||
242 | |||
243 | /********************************************************************** | ||
244 | * Save an encrypted file | ||
245 | **********************************************************************/ | ||
246 | printf("Saving Encrypted file\n"); | ||
247 | |||
248 | /* Read in the header of the encrypted file */ | ||
249 | if(mr500_read_header(decrypt_file, &header) < 0 ) { | ||
250 | printf("ERROR: Unable to read header: %s\n", strerror(errno)); | ||
251 | return -1; | ||
252 | } | ||
253 | |||
254 | /* Check to make sure this is a decrypted file (bogus flag not set) */ | ||
255 | if(!(header.flags & HEADER_DECRYPTED)) { | ||
256 | printf("ERROR: This appears to be a encrypted file! Quitting\n"); | ||
257 | return -1; | ||
258 | } | ||
259 | |||
260 | /* Check to make sure MAGIC string matches expected*/ | ||
261 | if(strncmp((char *)header.magic_name, "OIMCFWUP", 7)) { | ||
262 | printf("ERROR: Magic string does not match expected! Quitting\n"); | ||
263 | return -1; | ||
264 | } | ||
265 | |||
266 | /* Remove the bogus flag */ | ||
267 | header.flags &= ~HEADER_DECRYPTED; | ||
268 | |||
269 | printf("File Header:\n"); | ||
270 | display_header(&header); | ||
271 | |||
272 | /* Header is not encrypted, save it */ | ||
273 | if(mr500_save_header(encrypt_file, &header) < 0 ) { | ||
274 | printf("ERROR: Unable to save header: %s\n", strerror(errno)); | ||
275 | return -1; | ||
276 | } | ||
277 | |||
278 | /* Read CRC of decrypted file */ | ||
279 | if(mr500_read_crc(decrypt_file, | ||
280 | header.header_length+header.image_length, &stored_crc) < 0 ) { | ||
281 | printf("ERROR: Unable to read CRC: %s\n", strerror(errno)); | ||
282 | return -1; | ||
283 | } | ||
284 | |||
285 | /* Calculate the 'CRC' of the decrypted data */ | ||
286 | if(mr500_calculate_crc( decrypt_file, header.header_length, | ||
287 | header.image_length, &checksum) < 0 ) { | ||
288 | printf("ERROR: Unable to calculate CRC: %s\n", strerror(errno)); | ||
289 | return -1; | ||
290 | } | ||
291 | |||
292 | if(stored_crc != checksum) { | ||
293 | printf("\nERROR: Stored and calculated checksums do not match!\n" | ||
294 | "\tFile has been improperly modified. Quitting\n"); | ||
295 | return -1; | ||
296 | } | ||
297 | |||
298 | printf("Encrypting data...\n"); | ||
299 | |||
300 | /* Write the encrypted data to a file */ | ||
301 | if(mr500_save_data( decrypt_file, encrypt_file, header.header_length, | ||
302 | header.image_length, encrypt_array) < 0 ) { | ||
303 | printf("ERROR: Unable to save encrypted data: %s\n", strerror(errno)); | ||
304 | return -1; | ||
305 | } | ||
306 | |||
307 | printf("Saving CRC\n"); | ||
308 | |||
309 | /* Store the calculated 'CRC' (not encrypted) */ | ||
310 | if(mr500_save_crc(encrypt_file, header.header_length+header.image_length, | ||
311 | &checksum) < 0 ) { | ||
312 | printf("ERROR: Unable to save CRC: %s\n", strerror(errno)); | ||
313 | return -1; | ||
314 | } | ||
315 | |||
316 | printf("File sucesfully encrypted!\n"); | ||
317 | } | ||
318 | |||
319 | printf("Done\n"); | ||
320 | return 0; | ||
321 | } | ||
322 | |||