diff options
Diffstat (limited to 'rbutil/mkamsboot/mkamsboot.c')
-rw-r--r-- | rbutil/mkamsboot/mkamsboot.c | 102 |
1 files changed, 88 insertions, 14 deletions
diff --git a/rbutil/mkamsboot/mkamsboot.c b/rbutil/mkamsboot/mkamsboot.c index e4b6e09782..5733db5f2a 100644 --- a/rbutil/mkamsboot/mkamsboot.c +++ b/rbutil/mkamsboot/mkamsboot.c | |||
@@ -87,6 +87,8 @@ execution to the uncompressed firmware. | |||
87 | 87 | ||
88 | /* Headers for ARM code binaries */ | 88 | /* Headers for ARM code binaries */ |
89 | #include "uclimg.h" | 89 | #include "uclimg.h" |
90 | #include "md5.h" | ||
91 | |||
90 | #include "bootimg_clip.h" | 92 | #include "bootimg_clip.h" |
91 | #include "bootimg_e200v2.h" | 93 | #include "bootimg_e200v2.h" |
92 | #include "bootimg_m200v2.h" | 94 | #include "bootimg_m200v2.h" |
@@ -165,6 +167,39 @@ static const int rb_model_num[] = | |||
165 | 0 | 167 | 0 |
166 | }; | 168 | }; |
167 | 169 | ||
170 | struct md5sums { | ||
171 | int model; | ||
172 | char *version; | ||
173 | int fw_version; | ||
174 | char *md5; | ||
175 | }; | ||
176 | |||
177 | /* Checksums of unmodified original firmwares - for safety, and device | ||
178 | detection */ | ||
179 | static struct md5sums sansasums[] = { | ||
180 | /* NOTE: Different regional versions of the firmware normally only | ||
181 | differ in the filename - the md5sums are identical */ | ||
182 | { MODEL_E200, "3.01.11", 1, "e622ca8cb6df423f54b8b39628a1f0a3" }, | ||
183 | { MODEL_E200, "3.01.14", 1, "2c1d0383fc3584b2cc83ba8cc2243af6" }, | ||
184 | { MODEL_E200, "3.01.16", 1, "12563ad71b25a1034cf2092d1e0218c4" }, | ||
185 | |||
186 | { MODEL_FUZE, "1.01.11", 1, "cac8ffa03c599330ac02c4d41de66166" }, | ||
187 | { MODEL_FUZE, "1.01.15", 1, "df0e2c1612727f722c19a3c764cff7f2" }, | ||
188 | |||
189 | { MODEL_C200, "3.02.05", 1, "b6378ebd720b0ade3fad4dc7ab61c1a5" }, | ||
190 | |||
191 | { MODEL_M200, "4.00.45", 1, "82e3194310d1514e3bbcd06e84c4add3" }, | ||
192 | { MODEL_M200, "4.01.08-A", 1, "fc9dd6116001b3e6a150b898f1b091f0" }, | ||
193 | { MODEL_M200, "4.01.08-E", 1, "d3fb7d8ec8624ee65bc99f8dab0e2369" }, | ||
194 | |||
195 | { MODEL_CLIP, "1.01.17", 1, "12caad785d506219d73f538772afd99e" }, | ||
196 | { MODEL_CLIP, "1.01.18", 1, "d720b266bd5afa38a198986ef0508a45" }, | ||
197 | { MODEL_CLIP, "1.01.20", 1, "236d8f75189f468462c03f6d292cf2ac" }, | ||
198 | { MODEL_CLIP, "1.01.29", 1, "b07fe36b338241944c241de21fb1e490" }, | ||
199 | { MODEL_CLIP, "1.01.30", 1, "f2974d47c536549c9d8259170f1dbe4d" }, | ||
200 | }; | ||
201 | |||
202 | #define NUM_MD5S (sizeof(sansasums)/sizeof(sansasums[0])) | ||
168 | 203 | ||
169 | static off_t filesize(int fd) { | 204 | static off_t filesize(int fd) { |
170 | struct stat buf; | 205 | struct stat buf; |
@@ -195,6 +230,21 @@ static void put_uint32le(unsigned char* p, uint32_t x) | |||
195 | p[3] = (x >> 24) & 0xff; | 230 | p[3] = (x >> 24) & 0xff; |
196 | } | 231 | } |
197 | 232 | ||
233 | void calc_MD5(unsigned char* buf, int len, char *md5str) | ||
234 | { | ||
235 | int i; | ||
236 | md5_context ctx; | ||
237 | unsigned char md5sum[16]; | ||
238 | |||
239 | md5_starts(&ctx); | ||
240 | md5_update(&ctx, buf, len); | ||
241 | md5_finish(&ctx, md5sum); | ||
242 | |||
243 | for (i = 0; i < 16; ++i) | ||
244 | sprintf(md5str + 2*i, "%02x", md5sum[i]); | ||
245 | } | ||
246 | |||
247 | |||
198 | static uint32_t calc_checksum(unsigned char* buf, uint32_t n) | 248 | static uint32_t calc_checksum(unsigned char* buf, uint32_t n) |
199 | { | 249 | { |
200 | uint32_t sum = 0; | 250 | uint32_t sum = 0; |
@@ -375,6 +425,7 @@ int main(int argc, char* argv[]) | |||
375 | int totalsize; | 425 | int totalsize; |
376 | unsigned char* p; | 426 | unsigned char* p; |
377 | uint32_t checksum; | 427 | uint32_t checksum; |
428 | char md5sum[33]; /* 32 hex digits, plus terminating zero */ | ||
378 | 429 | ||
379 | fprintf(stderr,"mkamsboot v" VERSION " - (C) Dave Chapman and Rafaël Carré 2008\n"); | 430 | fprintf(stderr,"mkamsboot v" VERSION " - (C) Dave Chapman and Rafaël Carré 2008\n"); |
380 | fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); | 431 | fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); |
@@ -397,26 +448,48 @@ int main(int argc, char* argv[]) | |||
397 | return 1; | 448 | return 1; |
398 | } | 449 | } |
399 | 450 | ||
400 | /* TODO: Do some more sanity checks on the OF image. Some images (like m200v2) dont have a checksum at the end, only padding (0xdeadbeef). */ | 451 | /* Calculate MD5 checksum of OF */ |
401 | checksum = get_uint32le(buf + len - 4); | 452 | calc_MD5(buf, len, md5sum); |
402 | if (checksum != 0xefbeadde && checksum != calc_checksum(buf, len - 4)) { | ||
403 | 453 | ||
404 | fprintf(stderr,"[ERR] Whole file checksum failed - %s\n",infile); | 454 | fprintf(stderr,"[INFO] MD5 sum - %s\n",md5sum); |
405 | return 1; | 455 | |
406 | } | 456 | i = 0; |
457 | while ((i < NUM_MD5S) && (strcmp(sansasums[i].md5, md5sum) != 0)) | ||
458 | i++; | ||
407 | 459 | ||
408 | if (get_uint32le(&buf[0x204])==0x0000f000) { | 460 | if (i < NUM_MD5S) { |
409 | fw_version = 2; | 461 | model = sansasums[i].model; |
410 | model_id = buf[0x219]; | 462 | fw_version = sansasums[i].fw_version; |
463 | fprintf(stderr,"[INFO] Original firmware MD5 checksum match - %s %s\n", | ||
464 | model_names[model], sansasums[i].version); | ||
411 | } else { | 465 | } else { |
412 | fw_version = 1; | 466 | fprintf(stderr,"[WARN] ****** Original firmware unknown ******\n"); |
413 | model_id = buf[0x215]; | 467 | |
468 | if (get_uint32le(&buf[0x204])==0x0000f000) { | ||
469 | fw_version = 2; | ||
470 | model_id = buf[0x219]; | ||
471 | } else { | ||
472 | fw_version = 1; | ||
473 | model_id = buf[0x215]; | ||
474 | } | ||
475 | |||
476 | model = get_model(model_id); | ||
477 | |||
478 | if (model == MODEL_UNKNOWN) { | ||
479 | fprintf(stderr,"[ERR] Unknown firmware - model id 0x%02x\n", | ||
480 | model_id); | ||
481 | free(buf); | ||
482 | return 1; | ||
483 | } | ||
414 | } | 484 | } |
485 | |||
415 | 486 | ||
416 | model = get_model(model_id); | 487 | /* TODO: Do some more sanity checks on the OF image. Some images (like m200v2) dont have a checksum at the end, only padding (0xdeadbeef). */ |
488 | checksum = get_uint32le(buf + len - 4); | ||
489 | if (checksum != 0xefbeadde && checksum != calc_checksum(buf, len - 4)) { | ||
417 | 490 | ||
418 | if (model == MODEL_UNKNOWN) { | 491 | fprintf(stderr,"[ERR] Whole file checksum failed - %s\n",infile); |
419 | fprintf(stderr,"[ERR] Unknown firmware - model id 0x%02x\n",model_id); | 492 | free(buf); |
420 | return 1; | 493 | return 1; |
421 | } | 494 | } |
422 | 495 | ||
@@ -430,6 +503,7 @@ int main(int argc, char* argv[]) | |||
430 | rb_unpacked = load_rockbox_file(bootfile, model, &bootloader_size); | 503 | rb_unpacked = load_rockbox_file(bootfile, model, &bootloader_size); |
431 | if (rb_unpacked == NULL) { | 504 | if (rb_unpacked == NULL) { |
432 | fprintf(stderr,"[ERR] Could not load %s\n",bootfile); | 505 | fprintf(stderr,"[ERR] Could not load %s\n",bootfile); |
506 | free(buf); | ||
433 | return 1; | 507 | return 1; |
434 | } | 508 | } |
435 | 509 | ||