summaryrefslogtreecommitdiff
path: root/utils/imxtools/sbtools/sbtoelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/imxtools/sbtools/sbtoelf.c')
-rw-r--r--utils/imxtools/sbtools/sbtoelf.c173
1 files changed, 147 insertions, 26 deletions
diff --git a/utils/imxtools/sbtools/sbtoelf.c b/utils/imxtools/sbtools/sbtoelf.c
index 0170ea1836..0445c4a366 100644
--- a/utils/imxtools/sbtools/sbtoelf.c
+++ b/utils/imxtools/sbtools/sbtoelf.c
@@ -40,6 +40,7 @@
40#include "crypto.h" 40#include "crypto.h"
41#include "elf.h" 41#include "elf.h"
42#include "sb.h" 42#include "sb.h"
43#include "sb1.h"
43#include "misc.h" 44#include "misc.h"
44 45
45/* all blocks are sized as a multiple of 0x1ff */ 46/* all blocks are sized as a multiple of 0x1ff */
@@ -156,6 +157,15 @@ static void extract_sb_file(struct sb_file_t *file)
156 extract_sb_section(&file->sections[i]); 157 extract_sb_section(&file->sections[i]);
157} 158}
158 159
160static void extract_sb1_file(struct sb1_file_t *file)
161{
162 FILE *f = fopen(g_out_prefix, "wb");
163 if(f == NULL)
164 bugp("Cannot open %s for writing\n", g_out_prefix);
165 fwrite(file->data, file->data_size, 1, f);
166 fclose(f);
167}
168
159static void usage(void) 169static void usage(void)
160{ 170{
161 printf("Usage: sbtoelf [options] sb-file\n"); 171 printf("Usage: sbtoelf [options] sb-file\n");
@@ -170,6 +180,8 @@ static void usage(void)
170 printf(" -n/--no-color\tDisable output colors\n"); 180 printf(" -n/--no-color\tDisable output colors\n");
171 printf(" -l/--loopback <file>\tProduce sb file out of extracted description*\n"); 181 printf(" -l/--loopback <file>\tProduce sb file out of extracted description*\n");
172 printf(" -f/--force\tForce reading even without a key*\n"); 182 printf(" -f/--force\tForce reading even without a key*\n");
183 printf(" -1/--v1\tForce to read file as a version 1 file\n");
184 printf(" -2/--v2\tForce to read file as a version 2 file\n");
173 printf("Options marked with a * are for debug purpose only\n"); 185 printf("Options marked with a * are for debug purpose only\n");
174 exit(1); 186 exit(1);
175} 187}
@@ -191,11 +203,72 @@ static struct crypto_key_t g_zero_key =
191 .u.key = {0} 203 .u.key = {0}
192}; 204};
193 205
206static struct crypto_key_t g_default_xor_key =
207{
208 .method = CRYPTO_XOR_KEY,
209 .u.xor_key =
210 {
211 {.k = {0x67ECAEF6, 0xB31FB961, 0x118A9F4C, 0xA32A97DA,
212 0x6CC39617, 0x5BC00314, 0x9D430685, 0x4D7DB502,
213 0xA347685E, 0x3C87E86C, 0x8987AAA0, 0x24B78EF1,
214 0x893B9605, 0x9BB8C2BE, 0x6D9544E2, 0x375B525C}},
215 {.k = {0x3F424704, 0x53B5A331, 0x6AD345A5, 0x20DCEC51,
216 0x743C8D3B, 0x444B3792, 0x0AF429569, 0xB7EE1111,
217 0x583BF768, 0x9683BF9A, 0x0B032D799, 0xFE4E78ED,
218 0xF20D08C2, 0xFA0BE4A2, 0x4D89C317, 0x887B2D6F}}
219 }
220};
221
222enum sb_version_guess_t
223{
224 SB_VERSION_1,
225 SB_VERSION_2,
226 SB_VERSION_UNK,
227};
228
229enum sb_version_guess_t guess_sb_version(const char *filename)
230{
231 FILE *f = fopen(filename, "rb");
232 if(f == NULL)
233 bugp("Cannot open file for reading\n");
234 // check signature
235 uint8_t sig[4];
236 if(fseek(f, 20, SEEK_SET))
237 return SB_VERSION_UNK;
238 if(fread(sig, 4, 1, f) != 1)
239 return SB_VERSION_UNK;
240 if(memcmp(sig, "STMP", 4) != 0)
241 return SB_VERSION_UNK;
242 // check header size (v1)
243 uint32_t hdr_size;
244 if(fseek(f, 8, SEEK_SET))
245 return SB_VERSION_UNK;
246 if(fread(&hdr_size, 4, 1, f) != 1)
247 return SB_VERSION_UNK;
248 if(hdr_size == 0x34)
249 return SB_VERSION_1;
250 // check header size (v2)
251 if(fseek(f, 32, SEEK_SET))
252 return SB_VERSION_UNK;
253 if(fread(&hdr_size, 4, 1, f) != 1)
254 return SB_VERSION_UNK;
255 if(hdr_size == 0xc)
256 return SB_VERSION_2;
257 return SB_VERSION_UNK;
258}
259
194int main(int argc, char **argv) 260int main(int argc, char **argv)
195{ 261{
196 bool raw_mode = false; 262 bool raw_mode = false;
197 const char *loopback = NULL; 263 const char *loopback = NULL;
198 264 bool force_sb1 = false;
265 bool force_sb2 = false;
266
267 /* decrypt the xor key which is xor'ed */
268 for(int i = 0; i < 2; i++)
269 for(int j = 0; j < 16; j++)
270 g_default_xor_key.u.xor_key[i].k[j] ^= 0xaa55aa55;
271
199 while(1) 272 while(1)
200 { 273 {
201 static struct option long_options[] = 274 static struct option long_options[] =
@@ -205,11 +278,13 @@ int main(int argc, char **argv)
205 {"add-key", required_argument, 0, 'a'}, 278 {"add-key", required_argument, 0, 'a'},
206 {"no-color", no_argument, 0, 'n'}, 279 {"no-color", no_argument, 0, 'n'},
207 {"loopback", required_argument, 0, 'l'}, 280 {"loopback", required_argument, 0, 'l'},
208 {"force", no_argument, 0, 'f' }, 281 {"force", no_argument, 0, 'f'},
282 {"v1", no_argument, 0, '1'},
283 {"v2", no_argument, 0, '2'},
209 {0, 0, 0, 0} 284 {0, 0, 0, 0}
210 }; 285 };
211 286
212 int c = getopt_long(argc, argv, "?do:k:zra:nl:f", long_options, NULL); 287 int c = getopt_long(argc, argv, "?do:k:zra:nl:f12x", long_options, NULL);
213 if(c == -1) 288 if(c == -1)
214 break; 289 break;
215 switch(c) 290 switch(c)
@@ -243,10 +318,11 @@ int main(int argc, char **argv)
243 break; 318 break;
244 } 319 }
245 case 'z': 320 case 'z':
246 {
247 add_keys(&g_zero_key, 1); 321 add_keys(&g_zero_key, 1);
248 break; 322 break;
249 } 323 case 'x':
324 add_keys(&g_default_xor_key, 1);
325 break;
250 case 'r': 326 case 'r':
251 raw_mode = true; 327 raw_mode = true;
252 break; 328 break;
@@ -261,11 +337,20 @@ int main(int argc, char **argv)
261 add_keys(&key, 1); 337 add_keys(&key, 1);
262 break; 338 break;
263 } 339 }
340 case '1':
341 force_sb1 = true;
342 break;
343 case '2':
344 force_sb2 = true;
345 break;
264 default: 346 default:
265 abort(); 347 abort();
266 } 348 }
267 } 349 }
268 350
351 if(force_sb1 && force_sb2)
352 bug("You cannot force both version 1 and 2\n");
353
269 if(argc - optind != 1) 354 if(argc - optind != 1)
270 { 355 {
271 usage(); 356 usage();
@@ -274,34 +359,70 @@ int main(int argc, char **argv)
274 359
275 const char *sb_filename = argv[optind]; 360 const char *sb_filename = argv[optind];
276 361
277 enum sb_error_t err; 362 enum sb_version_guess_t ver = guess_sb_version(sb_filename);
278 struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, sb_printf, &err); 363
279 if(file == NULL) 364 if(force_sb2 || ver == SB_VERSION_2)
280 { 365 {
366 enum sb_error_t err;
367 struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, sb_printf, &err);
368 if(file == NULL)
369 {
370 color(OFF);
371 printf("SB read failed: %d\n", err);
372 return 1;
373 }
374
281 color(OFF); 375 color(OFF);
282 printf("SB read failed: %d\n", err); 376 if(g_out_prefix)
283 return 1; 377 extract_sb_file(file);
378 if(g_debug)
379 {
380 color(GREY);
381 printf("[Debug output]\n");
382 sb_dump(file, NULL, sb_printf);
383 }
384 if(loopback)
385 {
386 /* sb_read_file will fill real key and IV but we don't want to override
387 * them when looping back otherwise the output will be inconsistent and
388 * garbage */
389 file->override_real_key = false;
390 file->override_crypto_iv = false;
391 sb_write_file(file, loopback);
392 }
393 sb_free(file);
284 } 394 }
285 395 else if(force_sb1 || ver == SB_VERSION_1)
286 color(OFF);
287 if(g_out_prefix)
288 extract_sb_file(file);
289 if(g_debug)
290 { 396 {
291 color(GREY); 397 enum sb1_error_t err;
292 printf("[Debug output]\n"); 398 struct sb1_file_t *file = sb1_read_file(sb_filename, NULL, sb_printf, &err);
293 sb_dump(file, NULL, sb_printf); 399 if(file == NULL)
400 {
401 color(OFF);
402 printf("SB read failed: %d\n", err);
403 return 1;
404 }
405
406 color(OFF);
407 if(g_out_prefix)
408 extract_sb1_file(file);
409 if(g_debug)
410 {
411 color(GREY);
412 printf("[Debug output]\n");
413 sb1_dump(file, NULL, sb_printf);
414 }
415 if(loopback)
416 sb1_write_file(file, loopback);
417
418 sb1_free(file);
294 } 419 }
295 if(loopback) 420 else
296 { 421 {
297 /* sb_read_file will fill real key and IV but we don't want to override 422 color(OFF);
298 * them when looping back otherwise the output will be inconsistent and 423 printf("Cannot guess file type, are you sure it's a valid image ?\n");
299 * garbage */ 424 return 1;
300 file->override_real_key = false;
301 file->override_crypto_iv = false;
302 sb_write_file(file, loopback);
303 } 425 }
304 sb_free(file);
305 clear_keys(); 426 clear_keys();
306 427
307 return 0; 428 return 0;