diff options
-rw-r--r-- | utils/sbtools/elftosb.c | 54 | ||||
-rw-r--r-- | utils/sbtools/sbtoelf.c | 20 |
2 files changed, 65 insertions, 9 deletions
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c index 986376179a..17b72417cf 100644 --- a/utils/sbtools/elftosb.c +++ b/utils/sbtools/elftosb.c | |||
@@ -773,6 +773,7 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) | |||
773 | bugp("cannot open output file"); | 773 | bugp("cannot open output file"); |
774 | 774 | ||
775 | byte real_key[16]; | 775 | byte real_key[16]; |
776 | byte crypto_iv[16]; | ||
776 | byte (*cbc_macs)[16] = xmalloc(16 * g_nr_keys); | 777 | byte (*cbc_macs)[16] = xmalloc(16 * g_nr_keys); |
777 | /* init CBC-MACs */ | 778 | /* init CBC-MACs */ |
778 | for(int i = 0; i < g_nr_keys; i++) | 779 | for(int i = 0; i < g_nr_keys; i++) |
@@ -791,6 +792,9 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) | |||
791 | produce_sb_header(sb, &sb_hdr); | 792 | produce_sb_header(sb, &sb_hdr); |
792 | sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr)); | 793 | sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr)); |
793 | write(fd, &sb_hdr, sizeof(sb_hdr)); | 794 | write(fd, &sb_hdr, sizeof(sb_hdr)); |
795 | |||
796 | memcpy(crypto_iv, &sb_hdr, 16); | ||
797 | |||
794 | /* update CBC-MACs */ | 798 | /* update CBC-MACs */ |
795 | for(int i = 0; i < g_nr_keys; i++) | 799 | for(int i = 0; i < g_nr_keys; i++) |
796 | cbc_mac((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE, g_key_array[i], | 800 | cbc_mac((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE, g_key_array[i], |
@@ -814,11 +818,53 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) | |||
814 | struct sb_key_dictionary_entry_t entry; | 818 | struct sb_key_dictionary_entry_t entry; |
815 | memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16); | 819 | memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16); |
816 | cbc_mac(real_key, entry.key, sizeof(real_key) / BLOCK_SIZE, g_key_array[i], | 820 | cbc_mac(real_key, entry.key, sizeof(real_key) / BLOCK_SIZE, g_key_array[i], |
817 | (byte *)&sb_hdr, NULL, 1); | 821 | crypto_iv, NULL, 1); |
818 | 822 | ||
819 | write(fd, &entry, sizeof(entry)); | 823 | write(fd, &entry, sizeof(entry)); |
820 | sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry)); | 824 | sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry)); |
821 | } | 825 | } |
826 | |||
827 | /* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK */ | ||
828 | /* Image crafting, don't use it unless you understand what you do */ | ||
829 | if(strlen(s_getenv("SB_OVERRIDE_REAL_KEY")) != 0) | ||
830 | { | ||
831 | const char *key = s_getenv("SB_OVERRIDE_REAL_KEY"); | ||
832 | if(strlen(key) != 32) | ||
833 | bugp("Cannot override real key: invalid key length\n"); | ||
834 | for(int i = 0; i < 16; i++) | ||
835 | { | ||
836 | byte a, b; | ||
837 | if(convxdigit(key[2 * i], &a) || convxdigit(key[2 * i + 1], &b)) | ||
838 | bugp("Cannot override real key: key should be a 128-bit key written in hexadecimal\n"); | ||
839 | real_key[i] = (a << 4) | b; | ||
840 | } | ||
841 | } | ||
842 | if(strlen(s_getenv("SB_OVERRIDE_IV")) != 0) | ||
843 | { | ||
844 | const char *iv = s_getenv("SB_OVERRIDE_IV"); | ||
845 | if(strlen(iv) != 32) | ||
846 | bugp("Cannot override iv: invalid key length\n"); | ||
847 | for(int i = 0; i < 16; i++) | ||
848 | { | ||
849 | byte a, b; | ||
850 | if(convxdigit(iv[2 * i], &a) || convxdigit(iv[2 * i + 1], &b)) | ||
851 | bugp("Cannot override iv: key should be a 128-bit key written in hexadecimal\n"); | ||
852 | crypto_iv[i] = (a << 4) | b; | ||
853 | } | ||
854 | |||
855 | } | ||
856 | /* KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH */ | ||
857 | if(g_debug) | ||
858 | { | ||
859 | printf("Real key: "); | ||
860 | for(int j = 0; j < 16; j++) | ||
861 | printf("%02x", real_key[j]); | ||
862 | printf("\n"); | ||
863 | printf("IV : "); | ||
864 | for(int j = 0; j < 16; j++) | ||
865 | printf("%02x", crypto_iv[j]); | ||
866 | printf("\n"); | ||
867 | } | ||
822 | /* produce sections data */ | 868 | /* produce sections data */ |
823 | for(int i = 0; i< sb_hdr.nr_sections; i++) | 869 | for(int i = 0; i< sb_hdr.nr_sections; i++) |
824 | { | 870 | { |
@@ -827,12 +873,12 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) | |||
827 | produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections); | 873 | produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections); |
828 | if(g_nr_keys > 0) | 874 | if(g_nr_keys > 0) |
829 | cbc_mac((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE, | 875 | cbc_mac((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE, |
830 | real_key, (byte *)&sb_hdr, NULL, 1); | 876 | real_key, crypto_iv, NULL, 1); |
831 | sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd)); | 877 | sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd)); |
832 | write(fd, &tag_cmd, sizeof(tag_cmd)); | 878 | write(fd, &tag_cmd, sizeof(tag_cmd)); |
833 | /* produce other commands */ | 879 | /* produce other commands */ |
834 | byte cur_cbc_mac[16]; | 880 | byte cur_cbc_mac[16]; |
835 | memcpy(cur_cbc_mac, (byte *)&sb_hdr, 16); | 881 | memcpy(cur_cbc_mac, crypto_iv, 16); |
836 | for(int j = 0; j < sb->sections[i].nr_insts; j++) | 882 | for(int j = 0; j < sb->sections[i].nr_insts; j++) |
837 | { | 883 | { |
838 | struct sb_inst_t *inst = &sb->sections[i].insts[j]; | 884 | struct sb_inst_t *inst = &sb->sections[i].insts[j]; |
@@ -869,7 +915,7 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) | |||
869 | sha_1_output(&file_sha1, final_sig); | 915 | sha_1_output(&file_sha1, final_sig); |
870 | generate_random_data(final_sig + 20, 12); | 916 | generate_random_data(final_sig + 20, 12); |
871 | if(g_nr_keys > 0) | 917 | if(g_nr_keys > 0) |
872 | cbc_mac(final_sig, final_sig, 2, real_key, (byte *)&sb_hdr, NULL, 1); | 918 | cbc_mac(final_sig, final_sig, 2, real_key, crypto_iv, NULL, 1); |
873 | write(fd, final_sig, 32); | 919 | write(fd, final_sig, 32); |
874 | 920 | ||
875 | close(fd); | 921 | close(fd); |
diff --git a/utils/sbtools/sbtoelf.c b/utils/sbtools/sbtoelf.c index 66deb6c0ab..fb4567bed9 100644 --- a/utils/sbtools/sbtoelf.c +++ b/utils/sbtools/sbtoelf.c | |||
@@ -372,8 +372,10 @@ static void extract(unsigned long filesize) | |||
372 | 372 | ||
373 | if(memcmp(sb_header->signature, "STMP", 4) != 0) | 373 | if(memcmp(sb_header->signature, "STMP", 4) != 0) |
374 | bugp("Bad signature"); | 374 | bugp("Bad signature"); |
375 | /* | ||
375 | if(sb_header->image_size * BLOCK_SIZE > filesize) | 376 | if(sb_header->image_size * BLOCK_SIZE > filesize) |
376 | bugp("File size mismatch"); | 377 | bugp("File size mismatch"); |
378 | */ | ||
377 | if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t)) | 379 | if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t)) |
378 | bugp("Bad header size"); | 380 | bugp("Bad header size"); |
379 | if(sb_header->sec_hdr_size * BLOCK_SIZE != sizeof(struct sb_section_header_t)) | 381 | if(sb_header->sec_hdr_size * BLOCK_SIZE != sizeof(struct sb_section_header_t)) |
@@ -555,6 +557,17 @@ static void extract(unsigned long filesize) | |||
555 | } | 557 | } |
556 | } | 558 | } |
557 | 559 | ||
560 | color(RED); | ||
561 | printf(" Summary:\n"); | ||
562 | color(GREEN); | ||
563 | printf(" Real key: "); | ||
564 | color(YELLOW); | ||
565 | print_hex(real_key, 16, true); | ||
566 | color(GREEN); | ||
567 | printf(" IV : "); | ||
568 | color(YELLOW); | ||
569 | print_hex(g_buf, 16, true); | ||
570 | |||
558 | /* sections */ | 571 | /* sections */ |
559 | if(strcasecmp(s_getenv("SB_RAW_CMD"), "YES") != 0) | 572 | if(strcasecmp(s_getenv("SB_RAW_CMD"), "YES") != 0) |
560 | { | 573 | { |
@@ -615,10 +628,11 @@ static void extract(unsigned long filesize) | |||
615 | printf("Commands\n"); | 628 | printf("Commands\n"); |
616 | uint32_t offset = sb_header->first_boot_tag_off * BLOCK_SIZE; | 629 | uint32_t offset = sb_header->first_boot_tag_off * BLOCK_SIZE; |
617 | byte iv[16]; | 630 | byte iv[16]; |
618 | memcpy(iv, g_buf, 16); | ||
619 | const char *indent = " "; | 631 | const char *indent = " "; |
620 | while(true) | 632 | while(true) |
621 | { | 633 | { |
634 | /* restart with IV */ | ||
635 | memcpy(iv, g_buf, 16); | ||
622 | byte cmd[BLOCK_SIZE]; | 636 | byte cmd[BLOCK_SIZE]; |
623 | if(sb_header->nr_keys > 0) | 637 | if(sb_header->nr_keys > 0) |
624 | cbc_mac(g_buf + offset, cmd, 1, real_key, iv, &iv, 0); | 638 | cbc_mac(g_buf + offset, cmd, 1, real_key, iv, &iv, 0); |
@@ -638,8 +652,6 @@ static void extract(unsigned long filesize) | |||
638 | color(RED); | 652 | color(RED); |
639 | printf("NOOP\n"); | 653 | printf("NOOP\n"); |
640 | offset += BLOCK_SIZE; | 654 | offset += BLOCK_SIZE; |
641 | /* restart with IV */ | ||
642 | memcpy(iv, g_buf, 16); | ||
643 | } | 655 | } |
644 | else if(hdr->opcode == SB_INST_TAG) | 656 | else if(hdr->opcode == SB_INST_TAG) |
645 | { | 657 | { |
@@ -712,8 +724,6 @@ static void extract(unsigned long filesize) | |||
712 | if(tag->hdr.flags & SB_INST_LAST_TAG) | 724 | if(tag->hdr.flags & SB_INST_LAST_TAG) |
713 | break; | 725 | break; |
714 | offset += size; | 726 | offset += size; |
715 | /* restart with IV */ | ||
716 | memcpy(iv, g_buf, 16); | ||
717 | } | 727 | } |
718 | else | 728 | else |
719 | { | 729 | { |