blob: 1187058091e04b76d9200fcb413782326a4fd385 [file] [log] [blame]
Karl Kurbjund07ea9a2009-08-30 23:24:22 +00001/***************************************************************************
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) */
27struct patch_single hack[] = { {0x29B28, 0xE12FFF30},
28 {0x2F960, 0xE12FFF30} };
29
30static 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
44void 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 */
56int 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