diff options
Diffstat (limited to 'utils/sbinfo/sbinfo.c')
-rw-r--r-- | utils/sbinfo/sbinfo.c | 92 |
1 files changed, 63 insertions, 29 deletions
diff --git a/utils/sbinfo/sbinfo.c b/utils/sbinfo/sbinfo.c index 710c481deb..351847f19b 100644 --- a/utils/sbinfo/sbinfo.c +++ b/utils/sbinfo/sbinfo.c | |||
@@ -88,6 +88,9 @@ const char *key_file; | |||
88 | #define SB_INST_CALL 0x5 | 88 | #define SB_INST_CALL 0x5 |
89 | #define SB_INST_MODE 0x6 | 89 | #define SB_INST_MODE 0x6 |
90 | 90 | ||
91 | #define ROM_SECTION_BOOTABLE (1 << 0) | ||
92 | #define ROM_SECTION_CLEARTEXT (1 << 1) | ||
93 | |||
91 | struct sb_instruction_header_t | 94 | struct sb_instruction_header_t |
92 | { | 95 | { |
93 | uint8_t checksum; | 96 | uint8_t checksum; |
@@ -265,11 +268,12 @@ static void elf_write(void *user, uint32_t addr, const void *buf, size_t count) | |||
265 | fwrite(buf, count, 1, f); | 268 | fwrite(buf, count, 1, f); |
266 | } | 269 | } |
267 | 270 | ||
268 | static void extract_elf_section(struct elf_params_t *elf, int count, const char *prefix) | 271 | static void extract_elf_section(struct elf_params_t *elf, int count, const char *prefix, |
272 | const char *indent) | ||
269 | { | 273 | { |
270 | char *filename = xmalloc(strlen(prefix) + 32); | 274 | char *filename = xmalloc(strlen(prefix) + 32); |
271 | sprintf(filename, "%s.%d.elf", prefix, count); | 275 | sprintf(filename, "%s.%d.elf", prefix, count); |
272 | printf("write %s\n", filename); | 276 | printf("%swrite %s\n", indent, filename); |
273 | 277 | ||
274 | FILE *fd = fopen(filename, "wb"); | 278 | FILE *fd = fopen(filename, "wb"); |
275 | free(filename); | 279 | free(filename); |
@@ -385,7 +389,7 @@ static void extract_section(int data_sec, char name[5], byte *buf, int size, con | |||
385 | 389 | ||
386 | /* elf construction */ | 390 | /* elf construction */ |
387 | elf_set_start_addr(&elf, call->addr); | 391 | elf_set_start_addr(&elf, call->addr); |
388 | extract_elf_section(&elf, elf_count++, filename); | 392 | extract_elf_section(&elf, elf_count++, filename, indent); |
389 | elf_release(&elf); | 393 | elf_release(&elf); |
390 | elf_init(&elf); | 394 | elf_init(&elf); |
391 | 395 | ||
@@ -402,7 +406,7 @@ static void extract_section(int data_sec, char name[5], byte *buf, int size, con | |||
402 | } | 406 | } |
403 | 407 | ||
404 | if(!elf_is_empty(&elf)) | 408 | if(!elf_is_empty(&elf)) |
405 | extract_elf_section(&elf, elf_count++, filename); | 409 | extract_elf_section(&elf, elf_count++, filename, indent); |
406 | elf_release(&elf); | 410 | elf_release(&elf); |
407 | } | 411 | } |
408 | 412 | ||
@@ -413,7 +417,7 @@ static void extract(unsigned long filesize) | |||
413 | color(BLUE); | 417 | color(BLUE); |
414 | printf("Basic info:\n"); | 418 | printf("Basic info:\n"); |
415 | color(GREEN); | 419 | color(GREEN); |
416 | printf("\tHeader SHA-1: "); | 420 | printf(" Header SHA-1: "); |
417 | byte *hdr_sha1 = &g_buf[0]; | 421 | byte *hdr_sha1 = &g_buf[0]; |
418 | color(YELLOW); | 422 | color(YELLOW); |
419 | print_sha1(hdr_sha1); | 423 | print_sha1(hdr_sha1); |
@@ -429,27 +433,39 @@ static void extract(unsigned long filesize) | |||
429 | else | 433 | else |
430 | printf(" Failed\n"); | 434 | printf(" Failed\n"); |
431 | color(GREEN); | 435 | color(GREEN); |
432 | printf("\tFlags: "); | 436 | printf(" Flags: "); |
437 | color(YELLOW); | ||
433 | printhex(0x18, 4); | 438 | printhex(0x18, 4); |
434 | printf("\tTotal file size : %ld\n", filesize); | 439 | color(GREEN); |
440 | printf(" Total file size : "); | ||
441 | color(YELLOW); | ||
442 | printf("%ld\n", filesize); | ||
435 | 443 | ||
436 | /* Sizes and offsets */ | 444 | /* Sizes and offsets */ |
437 | color(BLUE); | 445 | color(BLUE); |
438 | printf("Sizes and offsets:\n"); | 446 | printf("Sizes and offsets:\n"); |
439 | color(GREEN); | 447 | color(GREEN); |
440 | int num_enc = get16le(0x28); | 448 | int num_enc = get16le(0x28); |
441 | printf("\t# of encryption keys = %d\n", num_enc); | 449 | printf(" # of encryption keys = "); |
450 | color(YELLOW); | ||
451 | printf("%d\n", num_enc); | ||
452 | color(GREEN); | ||
442 | int num_chunks = get16le(0x2E); | 453 | int num_chunks = get16le(0x2E); |
443 | printf("\t# of chunk headers = %d\n", num_chunks); | 454 | printf(" # of chunk headers = "); |
455 | color(YELLOW); | ||
456 | printf("%d\n", num_chunks); | ||
444 | 457 | ||
445 | /* Versions */ | 458 | /* Versions */ |
446 | color(BLUE); | 459 | color(BLUE); |
447 | printf("Versions\n"); | 460 | printf("Versions\n"); |
448 | color(GREEN); | 461 | color(GREEN); |
449 | 462 | ||
450 | printf("\tRandom 1: "); | 463 | printf(" Random 1: "); |
464 | color(YELLOW); | ||
451 | printhex(0x32, 6); | 465 | printhex(0x32, 6); |
452 | printf("\tRandom 2: "); | 466 | color(GREEN); |
467 | printf(" Random 2: "); | ||
468 | color(YELLOW); | ||
453 | printhex(0x5A, 6); | 469 | printhex(0x5A, 6); |
454 | 470 | ||
455 | uint64_t micros_l = get32le(0x38); | 471 | uint64_t micros_l = get32le(0x38); |
@@ -459,7 +475,9 @@ static void extract(unsigned long filesize) | |||
459 | seconds += 946684800; /* 2000/1/1 0:00:00 */ | 475 | seconds += 946684800; /* 2000/1/1 0:00:00 */ |
460 | struct tm *time = gmtime(&seconds); | 476 | struct tm *time = gmtime(&seconds); |
461 | color(GREEN); | 477 | color(GREEN); |
462 | printf("\tCreation date/time = %s", asctime(time)); | 478 | printf(" Creation date/time = "); |
479 | color(YELLOW); | ||
480 | printf("%s", asctime(time)); | ||
463 | 481 | ||
464 | int p_maj = get32le(0x40); | 482 | int p_maj = get32le(0x40); |
465 | int p_min = get32le(0x44); | 483 | int p_min = get32le(0x44); |
@@ -468,8 +486,13 @@ static void extract(unsigned long filesize) | |||
468 | int c_min = get32le(0x50); | 486 | int c_min = get32le(0x50); |
469 | int c_sub = get32le(0x54); | 487 | int c_sub = get32le(0x54); |
470 | color(GREEN); | 488 | color(GREEN); |
471 | printf("\tProduct version = %X.%X.%X\n", p_maj, p_min, p_sub); | 489 | printf(" Product version = "); |
472 | printf("\tComponent version = %X.%X.%X\n", c_maj, c_min, c_sub); | 490 | color(YELLOW); |
491 | printf("%X.%X.%X\n", p_maj, p_min, p_sub); | ||
492 | color(GREEN); | ||
493 | printf(" Component version = "); | ||
494 | color(YELLOW); | ||
495 | printf("%X.%X.%X\n", c_maj, c_min, c_sub); | ||
473 | 496 | ||
474 | /* encryption cbc-mac */ | 497 | /* encryption cbc-mac */ |
475 | key_array_t keys = NULL; /* array of 16-bytes keys */ | 498 | key_array_t keys = NULL; /* array of 16-bytes keys */ |
@@ -482,11 +505,11 @@ static void extract(unsigned long filesize) | |||
482 | for(int i = 0; i < num_enc; i++) | 505 | for(int i = 0; i < num_enc; i++) |
483 | { | 506 | { |
484 | color(RED); | 507 | color(RED); |
485 | printf("\tKey %d: ", i); | 508 | printf(" Key %d: ", i); |
486 | print_key(keys[i]); | 509 | print_key(keys[i]); |
487 | printf("\n"); | 510 | printf("\n"); |
488 | color(GREEN); | 511 | color(GREEN); |
489 | printf("\t\tCBC-MAC of headers: "); | 512 | printf(" CBC-MAC of headers: "); |
490 | /* copy the cbc mac */ | 513 | /* copy the cbc mac */ |
491 | byte hdr_cbc_mac[16]; | 514 | byte hdr_cbc_mac[16]; |
492 | memcpy(hdr_cbc_mac, &g_buf[0x60 + 16 * num_chunks + 32 * i], 16); | 515 | memcpy(hdr_cbc_mac, &g_buf[0x60 + 16 * num_chunks + 32 * i], 16); |
@@ -504,7 +527,7 @@ static void extract(unsigned long filesize) | |||
504 | printf(" Failed\n"); | 527 | printf(" Failed\n"); |
505 | color(GREEN); | 528 | color(GREEN); |
506 | 529 | ||
507 | printf("\t\tEncrypted key : "); | 530 | printf(" Encrypted key : "); |
508 | byte (*encrypted_key)[16]; | 531 | byte (*encrypted_key)[16]; |
509 | encrypted_key = (key_array_t)&g_buf[0x60 + 16 * num_chunks + 32 * i + 16]; | 532 | encrypted_key = (key_array_t)&g_buf[0x60 + 16 * num_chunks + 32 * i + 16]; |
510 | color(YELLOW); | 533 | color(YELLOW); |
@@ -516,7 +539,7 @@ static void extract(unsigned long filesize) | |||
516 | byte iv[16]; | 539 | byte iv[16]; |
517 | memcpy(iv, g_buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */ | 540 | memcpy(iv, g_buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */ |
518 | cbc_mac(*encrypted_key, decrypted_key, 1, keys[i], iv, NULL, 0); | 541 | cbc_mac(*encrypted_key, decrypted_key, 1, keys[i], iv, NULL, 0); |
519 | printf("\t\tDecrypted key : "); | 542 | printf(" Decrypted key : "); |
520 | color(YELLOW); | 543 | color(YELLOW); |
521 | print_key(decrypted_key); | 544 | print_key(decrypted_key); |
522 | /* cross-check or copy */ | 545 | /* cross-check or copy */ |
@@ -548,14 +571,25 @@ static void extract(unsigned long filesize) | |||
548 | int pos = 16 * get32le(ofs + 4); | 571 | int pos = 16 * get32le(ofs + 4); |
549 | int size = 16 * get32le(ofs + 8); | 572 | int size = 16 * get32le(ofs + 8); |
550 | int flags = get32le(ofs + 12); | 573 | int flags = get32le(ofs + 12); |
551 | int data_sec = (flags == 2); | 574 | int data_sec = !(flags & ROM_SECTION_BOOTABLE); |
552 | int encrypted = !data_sec && (num_enc > 0); | 575 | int encrypted = !(flags & ROM_SECTION_CLEARTEXT); |
553 | 576 | ||
554 | color(GREEN); | 577 | color(GREEN); |
555 | printf("\tChunk '%s'\n", name); | 578 | printf(" Chunk "); |
556 | printf("\t\tpos = %8x - %8x\n", pos, pos+size); | 579 | color(YELLOW); |
557 | printf("\t\tlen = %8x\n", size); | 580 | printf("'%s'\n", name); |
558 | printf("\t\tflags = %8x", flags); | 581 | color(GREEN); |
582 | printf(" pos = "); | ||
583 | color(YELLOW); | ||
584 | printf("%8x - %8x\n", pos, pos+size); | ||
585 | color(GREEN); | ||
586 | printf(" len = "); | ||
587 | color(YELLOW); | ||
588 | printf("%8x\n", size); | ||
589 | color(GREEN); | ||
590 | printf(" flags = "); | ||
591 | color(YELLOW); | ||
592 | printf("%8x", flags); | ||
559 | color(RED); | 593 | color(RED); |
560 | if(data_sec) | 594 | if(data_sec) |
561 | printf(" Data Section"); | 595 | printf(" Data Section"); |
@@ -572,7 +606,7 @@ static void extract(unsigned long filesize) | |||
572 | else | 606 | else |
573 | memcpy(sec, g_buf + pos, size); | 607 | memcpy(sec, g_buf + pos, size); |
574 | 608 | ||
575 | extract_section(data_sec, name, sec, size, "\t\t\t"); | 609 | extract_section(data_sec, name, sec, size, " "); |
576 | free(sec); | 610 | free(sec); |
577 | } | 611 | } |
578 | 612 | ||
@@ -580,18 +614,18 @@ static void extract(unsigned long filesize) | |||
580 | color(BLUE); | 614 | color(BLUE); |
581 | printf("Final signature:\n"); | 615 | printf("Final signature:\n"); |
582 | color(GREEN); | 616 | color(GREEN); |
583 | printf("\tEncrypted signature:\n"); | 617 | printf(" Encrypted signature:\n"); |
584 | color(YELLOW); | 618 | color(YELLOW); |
585 | printf("\t\t"); | 619 | printf(" "); |
586 | printhex(filesize - 32, 16); | 620 | printhex(filesize - 32, 16); |
587 | printf("\t\t"); | 621 | printf(" "); |
588 | printhex(filesize - 16, 16); | 622 | printhex(filesize - 16, 16); |
589 | /* decrypt it */ | 623 | /* decrypt it */ |
590 | byte *encrypted_block = &g_buf[filesize - 32]; | 624 | byte *encrypted_block = &g_buf[filesize - 32]; |
591 | byte decrypted_block[32]; | 625 | byte decrypted_block[32]; |
592 | cbc_mac(encrypted_block, decrypted_block, 2, real_key, g_buf, NULL, 0); | 626 | cbc_mac(encrypted_block, decrypted_block, 2, real_key, g_buf, NULL, 0); |
593 | color(GREEN); | 627 | color(GREEN); |
594 | printf("\tDecrypted SHA-1:\n\t\t"); | 628 | printf(" Decrypted SHA-1:\n "); |
595 | color(YELLOW); | 629 | color(YELLOW); |
596 | print_sha1(decrypted_block); | 630 | print_sha1(decrypted_block); |
597 | /* check it */ | 631 | /* check it */ |