diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2014-05-29 21:45:51 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-02 21:42:01 +0100 |
commit | 782d9c0d80f1edc29955dbe7e7f42770f730b597 (patch) | |
tree | 413867cea771abef21a818d7aede7cadb48e6b56 | |
parent | 6e5f287606a3039ee26eb4fc8c8f7a05deebe9f0 (diff) | |
download | rockbox-782d9c0d80f1edc29955dbe7e7f42770f730b597.tar.gz rockbox-782d9c0d80f1edc29955dbe7e7f42770f730b597.zip |
mkimxboot: add the concept of soft MD5 sum
Change-Id: I7e83218ce0dccc1f4c4a7a6bb9c1df00dacf260b
-rw-r--r-- | rbutil/mkimxboot/main.c | 86 | ||||
-rw-r--r-- | rbutil/mkimxboot/mkimxboot.c | 101 | ||||
-rw-r--r-- | rbutil/mkimxboot/mkimxboot.h | 3 |
3 files changed, 187 insertions, 3 deletions
diff --git a/rbutil/mkimxboot/main.c b/rbutil/mkimxboot/main.c index bcc443d7f2..611715f7c1 100644 --- a/rbutil/mkimxboot/main.c +++ b/rbutil/mkimxboot/main.c | |||
@@ -43,6 +43,26 @@ static struct imx_variant_t imx_variants[] = | |||
43 | 43 | ||
44 | #define NR_VARIANTS sizeof(imx_variants) / sizeof(imx_variants[0]) | 44 | #define NR_VARIANTS sizeof(imx_variants) / sizeof(imx_variants[0]) |
45 | 45 | ||
46 | struct model_t | ||
47 | { | ||
48 | const char *name; | ||
49 | enum imx_model_t model; | ||
50 | }; | ||
51 | |||
52 | struct model_t imx_models[] = | ||
53 | { | ||
54 | { "unknown", MODEL_UNKNOWN }, | ||
55 | { "fuzeplus", MODEL_FUZEPLUS }, | ||
56 | { "zenxfi2", MODEL_ZENXFI2 }, | ||
57 | { "zenxfi3", MODEL_ZENXFI3 }, | ||
58 | { "zenxfistyle", MODEL_ZENXFISTYLE }, | ||
59 | { "zenstyle", MODEL_ZENSTYLE }, | ||
60 | { "nwze370", MODEL_NWZE370 }, | ||
61 | { "nwze360", MODEL_NWZE360 }, | ||
62 | }; | ||
63 | |||
64 | #define NR_MODELS sizeof(imx_models) / sizeof(imx_models[0]) | ||
65 | |||
46 | static void usage(void) | 66 | static void usage(void) |
47 | { | 67 | { |
48 | printf("Usage: mkimxboot [options | file]...\n"); | 68 | printf("Usage: mkimxboot [options | file]...\n"); |
@@ -57,6 +77,8 @@ static void usage(void) | |||
57 | printf(" -x Dump device informations\n"); | 77 | printf(" -x Dump device informations\n"); |
58 | printf(" -w Extract the original firmware\n"); | 78 | printf(" -w Extract the original firmware\n"); |
59 | printf(" -p <ver> Force product and component version\n"); | 79 | printf(" -p <ver> Force product and component version\n"); |
80 | printf(" -5 <type> Compute <type> MD5 sum of the input file\n"); | ||
81 | printf(" -m <model> Specify model (useful for soft MD5 sum)\n"); | ||
60 | printf("Supported variants: (default is standard)\n"); | 82 | printf("Supported variants: (default is standard)\n"); |
61 | printf(" "); | 83 | printf(" "); |
62 | for(size_t i = 0; i < NR_VARIANTS; i++) | 84 | for(size_t i = 0; i < NR_VARIANTS; i++) |
@@ -66,15 +88,51 @@ static void usage(void) | |||
66 | printf("%s", imx_variants[i].name); | 88 | printf("%s", imx_variants[i].name); |
67 | } | 89 | } |
68 | printf("\n"); | 90 | printf("\n"); |
91 | printf("Supported models: (default is unknown)\n"); | ||
92 | for(size_t i = 0; i < NR_MODELS; i++) | ||
93 | { | ||
94 | if(i != 0) | ||
95 | printf(", "); | ||
96 | printf("%s", imx_models[i].name); | ||
97 | } | ||
98 | printf("\n"); | ||
69 | printf("By default a dualboot image is built\n"); | 99 | printf("By default a dualboot image is built\n"); |
70 | printf("This tools supports the following format for the boot file:\n"); | 100 | printf("This tools supports the following format for the boot file:\n"); |
71 | printf("- rockbox scramble format\n"); | 101 | printf("- rockbox scramble format\n"); |
72 | printf("- elf format\n"); | 102 | printf("- elf format\n"); |
73 | printf("Additional checks will be performed on rockbox scramble format to\n"); | 103 | printf("Additional checks will be performed on rockbox scramble format to\n"); |
74 | printf("ensure soundness of operation.\n"); | 104 | printf("ensure soundness of operation.\n"); |
105 | printf("There are two types of MD5 sums: 'full' or 'soft'.\n"); | ||
106 | printf("- full MD5 sum applies to the whole file\n"); | ||
107 | printf("- soft MD5 sum for SB files accounts for relevant parts only\n"); | ||
75 | exit(1); | 108 | exit(1); |
76 | } | 109 | } |
77 | 110 | ||
111 | static int print_md5(const char *file, enum imx_model_t model, const char *type) | ||
112 | { | ||
113 | uint8_t md5sum[16]; | ||
114 | enum imx_error_t err; | ||
115 | if(strcmp(type, "full") == 0) | ||
116 | err = compute_md5sum(file, md5sum); | ||
117 | else if(strcmp(type, "soft") == 0) | ||
118 | err = compute_soft_md5sum(file, model, md5sum); | ||
119 | else | ||
120 | { | ||
121 | printf("Invalid md5sum type '%s'\n", type); | ||
122 | return 1; | ||
123 | } | ||
124 | if(err != IMX_SUCCESS) | ||
125 | { | ||
126 | printf("There was an error when computing the MD5 sum: %d\n", err); | ||
127 | return 2; | ||
128 | } | ||
129 | printf("%s MD5 sum: ", type); | ||
130 | for(int i = 0; i < 16; i++) | ||
131 | printf("%02x", md5sum[i]); | ||
132 | printf("\n"); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
78 | int main(int argc, char *argv[]) | 136 | int main(int argc, char *argv[]) |
79 | { | 137 | { |
80 | char *infile = NULL; | 138 | char *infile = NULL; |
@@ -82,8 +140,10 @@ int main(int argc, char *argv[]) | |||
82 | char *bootfile = NULL; | 140 | char *bootfile = NULL; |
83 | enum imx_firmware_variant_t variant = VARIANT_DEFAULT; | 141 | enum imx_firmware_variant_t variant = VARIANT_DEFAULT; |
84 | enum imx_output_type_t type = IMX_DUALBOOT; | 142 | enum imx_output_type_t type = IMX_DUALBOOT; |
143 | enum imx_model_t model = MODEL_UNKNOWN; | ||
85 | bool debug = false; | 144 | bool debug = false; |
86 | bool extract_of = false; | 145 | bool extract_of = false; |
146 | const char *md5type = NULL; | ||
87 | const char *force_version = NULL; | 147 | const char *force_version = NULL; |
88 | 148 | ||
89 | if(argc == 1) | 149 | if(argc == 1) |
@@ -101,10 +161,12 @@ int main(int argc, char *argv[]) | |||
101 | {"type", required_argument, 0, 't'}, | 161 | {"type", required_argument, 0, 't'}, |
102 | {"variant", required_argument, 0, 'v'}, | 162 | {"variant", required_argument, 0, 'v'}, |
103 | {"dev-info", no_argument, 0, 'x'}, | 163 | {"dev-info", no_argument, 0, 'x'}, |
164 | {"model", required_argument, 0, 'm'}, | ||
165 | {"md5", required_argument, 0, '5'}, | ||
104 | {0, 0, 0, 0} | 166 | {0, 0, 0, 0} |
105 | }; | 167 | }; |
106 | 168 | ||
107 | int c = getopt_long(argc, argv, "?di:o:b:t:v:xwp:", long_options, NULL); | 169 | int c = getopt_long(argc, argv, "?di:o:b:t:v:xwp:m:5:", long_options, NULL); |
108 | if(c == -1) | 170 | if(c == -1) |
109 | break; | 171 | break; |
110 | switch(c) | 172 | switch(c) |
@@ -167,6 +229,24 @@ int main(int argc, char *argv[]) | |||
167 | case 'p': | 229 | case 'p': |
168 | force_version = optarg; | 230 | force_version = optarg; |
169 | break; | 231 | break; |
232 | case '5': | ||
233 | md5type = optarg; | ||
234 | break; | ||
235 | case 'm': | ||
236 | if(model != MODEL_UNKNOWN) | ||
237 | { | ||
238 | printf("You cannot specify two models\n"); | ||
239 | return 1; | ||
240 | } | ||
241 | for(int i = 0; i < NR_MODELS; i++) | ||
242 | if(strcmp(optarg, imx_models[i].name) == 0) | ||
243 | { | ||
244 | model = imx_models[i].model; | ||
245 | break; | ||
246 | } | ||
247 | if(model == MODEL_UNKNOWN) | ||
248 | printf("Unknown model '%s'\n", optarg); | ||
249 | break; | ||
170 | default: | 250 | default: |
171 | abort(); | 251 | abort(); |
172 | } | 252 | } |
@@ -177,6 +257,10 @@ int main(int argc, char *argv[]) | |||
177 | printf("You must specify an input file\n"); | 257 | printf("You must specify an input file\n"); |
178 | return 1; | 258 | return 1; |
179 | } | 259 | } |
260 | |||
261 | if(md5type) | ||
262 | return print_md5(infile, md5type); | ||
263 | |||
180 | if(!outfile) | 264 | if(!outfile) |
181 | { | 265 | { |
182 | printf("You must specify an output file\n"); | 266 | printf("You must specify an output file\n"); |
diff --git a/rbutil/mkimxboot/mkimxboot.c b/rbutil/mkimxboot/mkimxboot.c index 436b3ebff4..909dad8641 100644 --- a/rbutil/mkimxboot/mkimxboot.c +++ b/rbutil/mkimxboot/mkimxboot.c | |||
@@ -597,8 +597,77 @@ static enum imx_error_t compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md | |||
597 | return IMX_SUCCESS; | 597 | return IMX_SUCCESS; |
598 | } | 598 | } |
599 | 599 | ||
600 | /* compute MD5 sum of a buffer */ | ||
601 | static enum imx_error_t compute_soft_md5sum_buf(struct sb_file_t *sb, uint8_t file_md5sum[16]) | ||
602 | { | ||
603 | md5_context ctx; | ||
604 | md5_starts(&ctx); | ||
605 | #define hash(obj) \ | ||
606 | md5_update(&ctx, (void *)&obj, sizeof(obj)) | ||
607 | /* various header fiels */ | ||
608 | hash(sb->timestamp); | ||
609 | hash(sb->drive_tag); | ||
610 | hash(sb->drive_tag); | ||
611 | hash(sb->first_boot_sec_id); | ||
612 | hash(sb->flags); | ||
613 | hash(sb->product_ver); | ||
614 | hash(sb->component_ver); | ||
615 | |||
616 | for(int i = 0; i < sb->nr_sections; i++) | ||
617 | { | ||
618 | struct sb_section_t *sec = &sb->sections[i]; | ||
619 | hash(sec->identifier); | ||
620 | uint32_t flags = sec->other_flags; | ||
621 | if(!sec->is_data) | ||
622 | flags |= SECTION_BOOTABLE; | ||
623 | if(sec->is_cleartext) | ||
624 | flags |= SECTION_CLEARTEXT; | ||
625 | hash(flags); | ||
626 | |||
627 | for(int j = 0; j < sec->nr_insts; j++) | ||
628 | { | ||
629 | struct sb_inst_t *inst = &sec->insts[j]; | ||
630 | switch(inst->inst) | ||
631 | { | ||
632 | case SB_INST_NOP: | ||
633 | /* ignore them totally because they are used for padding */ | ||
634 | break; | ||
635 | case SB_INST_LOAD: | ||
636 | hash(inst->inst); | ||
637 | hash(inst->addr); | ||
638 | md5_update(&ctx, inst->data, inst->size); | ||
639 | break; | ||
640 | case SB_INST_FILL: | ||
641 | hash(inst->inst); | ||
642 | hash(inst->addr); | ||
643 | hash(inst->pattern); | ||
644 | break; | ||
645 | case SB_INST_JUMP: | ||
646 | case SB_INST_CALL: | ||
647 | hash(inst->inst); | ||
648 | hash(inst->addr); | ||
649 | hash(inst->argument); | ||
650 | break; | ||
651 | case SB_INST_MODE: | ||
652 | hash(inst->inst); | ||
653 | hash(inst->argument); | ||
654 | break; | ||
655 | case SB_INST_DATA: | ||
656 | md5_update(&ctx, inst->data, inst->size); | ||
657 | break; | ||
658 | default: | ||
659 | printf("[ERR][INTERNAL] Unexpected instruction %d\n", inst->inst); | ||
660 | return IMX_ERROR; | ||
661 | } | ||
662 | } | ||
663 | } | ||
664 | #undef hash | ||
665 | md5_finish(&ctx, file_md5sum); | ||
666 | return IMX_SUCCESS; | ||
667 | } | ||
668 | |||
600 | /* compute MD5 of a file */ | 669 | /* compute MD5 of a file */ |
601 | static enum imx_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16]) | 670 | enum imx_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16]) |
602 | { | 671 | { |
603 | void *buf; | 672 | void *buf; |
604 | size_t sz; | 673 | size_t sz; |
@@ -610,6 +679,32 @@ static enum imx_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16] | |||
610 | return IMX_SUCCESS; | 679 | return IMX_SUCCESS; |
611 | } | 680 | } |
612 | 681 | ||
682 | /* compute soft MD5 of a file */ | ||
683 | enum imx_error_t compute_soft_md5sum(const char *file, enum imx_model_t model, | ||
684 | uint8_t soft_md5sum[16]) | ||
685 | { | ||
686 | if(model == MODEL_UNKNOWN) | ||
687 | { | ||
688 | printf("[ERR] Cannot compute soft MD5 without knowing the model\n"); | ||
689 | return IMX_ERROR; | ||
690 | } | ||
691 | clear_keys(); | ||
692 | add_keys(imx_models[model].keys, imx_models[model].nr_keys); | ||
693 | /* read file */ | ||
694 | enum sb_error_t err; | ||
695 | struct sb_file_t *sb = sb_read_file(file, false, NULL, generic_std_printf, &err); | ||
696 | if(sb == NULL) | ||
697 | { | ||
698 | printf("[ERR] Cannot load SB file: %d\n", err); | ||
699 | return err; | ||
700 | } | ||
701 | /* compute sum */ | ||
702 | err = compute_soft_md5sum_buf(sb, soft_md5sum); | ||
703 | /* release file */ | ||
704 | sb_free(sb); | ||
705 | return err; | ||
706 | } | ||
707 | |||
613 | static enum imx_error_t load_sb_file(const char *file, int md5_idx, | 708 | static enum imx_error_t load_sb_file(const char *file, int md5_idx, |
614 | struct imx_option_t opt, struct sb_file_t **sb_file) | 709 | struct imx_option_t opt, struct sb_file_t **sb_file) |
615 | { | 710 | { |
@@ -792,7 +887,9 @@ enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | |||
792 | if(ret != IMX_SUCCESS) | 887 | if(ret != IMX_SUCCESS) |
793 | return ret; | 888 | return ret; |
794 | printf("[INFO] MD5 sum of the file: "); | 889 | printf("[INFO] MD5 sum of the file: "); |
795 | print_hex(NULL, misc_std_printf, file_md5sum, 16, true); | 890 | for(int i = 0; i < 16; i++) |
891 | printf("%02x", file_md5sum[i]); | ||
892 | printf("\n"); | ||
796 | /* find model */ | 893 | /* find model */ |
797 | int md5_idx; | 894 | int md5_idx; |
798 | ret = find_model_by_md5sum(file_md5sum, &md5_idx); | 895 | ret = find_model_by_md5sum(file_md5sum, &md5_idx); |
diff --git a/rbutil/mkimxboot/mkimxboot.h b/rbutil/mkimxboot/mkimxboot.h index 512a658c35..3157bd7daa 100644 --- a/rbutil/mkimxboot/mkimxboot.h +++ b/rbutil/mkimxboot/mkimxboot.h | |||
@@ -98,6 +98,9 @@ enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | |||
98 | const char *outfile, struct imx_option_t opt); | 98 | const char *outfile, struct imx_option_t opt); |
99 | enum imx_error_t extract_firmware(const char *infile, | 99 | enum imx_error_t extract_firmware(const char *infile, |
100 | enum imx_firmware_variant_t fw_variant, const char *outfile); | 100 | enum imx_firmware_variant_t fw_variant, const char *outfile); |
101 | enum imx_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16]); | ||
102 | enum imx_error_t compute_soft_md5sum(const char *file, enum imx_model_t model, | ||
103 | uint8_t soft_md5sum[16]); | ||
101 | 104 | ||
102 | #ifdef __cplusplus | 105 | #ifdef __cplusplus |
103 | } | 106 | } |