summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-05-29 21:45:51 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2017-01-02 21:42:01 +0100
commit782d9c0d80f1edc29955dbe7e7f42770f730b597 (patch)
tree413867cea771abef21a818d7aede7cadb48e6b56
parent6e5f287606a3039ee26eb4fc8c8f7a05deebe9f0 (diff)
downloadrockbox-782d9c0d80f1edc29955dbe7e7f42770f730b597.tar.gz
rockbox-782d9c0d80f1edc29955dbe7e7f42770f730b597.zip
mkimxboot: add the concept of soft MD5 sum
Change-Id: I7e83218ce0dccc1f4c4a7a6bb9c1df00dacf260b
-rw-r--r--rbutil/mkimxboot/main.c86
-rw-r--r--rbutil/mkimxboot/mkimxboot.c101
-rw-r--r--rbutil/mkimxboot/mkimxboot.h3
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
46struct model_t
47{
48 const char *name;
49 enum imx_model_t model;
50};
51
52struct 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
46static void usage(void) 66static 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
111static 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
78int main(int argc, char *argv[]) 136int 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 */
601static 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 */
601static enum imx_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16]) 670enum 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 */
683enum 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
613static enum imx_error_t load_sb_file(const char *file, int md5_idx, 708static 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);
99enum imx_error_t extract_firmware(const char *infile, 99enum 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);
101enum imx_error_t compute_md5sum(const char *file, uint8_t file_md5sum[16]);
102enum 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}