summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-11-06 01:49:13 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-11-06 01:49:13 +0000
commit5827937270bac874ae9e04679b3130fef9e306c4 (patch)
tree51bc262dedecdb7620300b46f23005c4b0eed311
parent33d6bd61b51178b42a07a97118a689d849666331 (diff)
downloadrockbox-5827937270bac874ae9e04679b3130fef9e306c4.tar.gz
rockbox-5827937270bac874ae9e04679b3130fef9e306c4.zip
sbtools: rename to imxtools, move imx_hid_recovery to imxtools/sbloader, fix tools to correctly handle/free memory, properly return error codes
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30907 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--utils/imx_hid_recovery/Makefile15
-rw-r--r--utils/imxtools/Makefile (renamed from utils/sbtools/Makefile)8
-rw-r--r--utils/imxtools/README (renamed from utils/sbtools/README)0
-rw-r--r--utils/imxtools/aes128.c (renamed from utils/sbtools/aes128.c)0
-rw-r--r--utils/imxtools/crc.c (renamed from utils/sbtools/crc.c)0
-rw-r--r--utils/imxtools/crypto.c (renamed from utils/sbtools/crypto.c)0
-rw-r--r--utils/imxtools/crypto.h (renamed from utils/sbtools/crypto.h)1
-rw-r--r--utils/imxtools/dbparser.c (renamed from utils/sbtools/dbparser.c)164
-rw-r--r--utils/imxtools/dbparser.h (renamed from utils/sbtools/dbparser.h)4
-rw-r--r--utils/imxtools/elf.c (renamed from utils/sbtools/elf.c)21
-rw-r--r--utils/imxtools/elf.h (renamed from utils/sbtools/elf.h)0
-rw-r--r--utils/imxtools/elftosb.c (renamed from utils/sbtools/elftosb.c)24
-rw-r--r--utils/imxtools/fuze+_key_file.txt (renamed from utils/sbtools/fuze+_key_file.txt)0
-rw-r--r--utils/imxtools/misc.c (renamed from utils/sbtools/misc.c)14
-rw-r--r--utils/imxtools/misc.h (renamed from utils/sbtools/misc.h)2
-rw-r--r--utils/imxtools/sb.c (renamed from utils/sbtools/sb.c)285
-rw-r--r--utils/imxtools/sb.h (renamed from utils/sbtools/sb.h)26
-rw-r--r--utils/imxtools/sbloader.c (renamed from utils/imx_hid_recovery/imx_hid_recovery.c)0
-rw-r--r--utils/imxtools/sbtoelf.c (renamed from utils/sbtools/sbtoelf.c)18
-rw-r--r--utils/imxtools/sha1.c (renamed from utils/sbtools/sha1.c)0
20 files changed, 388 insertions, 194 deletions
diff --git a/utils/imx_hid_recovery/Makefile b/utils/imx_hid_recovery/Makefile
deleted file mode 100644
index 24d0b8e3d3..0000000000
--- a/utils/imx_hid_recovery/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
1CC=gcc
2LD=gcc
3
4all: imx_hid_recovery
5
6imx_hid_recovery.o: imx_hid_recovery.c
7 $(CC) -c -Wall -O2 -std=c99 `pkg-config --cflags libusb-1.0` -o $@ $<
8
9imx_hid_recovery: imx_hid_recovery.o
10 $(LD) -o $@ $< `pkg-config --libs libusb-1.0`
11
12clean:
13 rm -rf imx_hid_recovery.o
14
15
diff --git a/utils/sbtools/Makefile b/utils/imxtools/Makefile
index 69e63c9ac2..7a09d86d24 100644
--- a/utils/sbtools/Makefile
+++ b/utils/imxtools/Makefile
@@ -3,8 +3,9 @@ CC=gcc
3LD=gcc 3LD=gcc
4CFLAGS=-g -std=c99 -W -Wall `pkg-config --cflags libusb-1.0` $(DEFINES) 4CFLAGS=-g -std=c99 -W -Wall `pkg-config --cflags libusb-1.0` $(DEFINES)
5LDFLAGS=`pkg-config --libs libusb-1.0` 5LDFLAGS=`pkg-config --libs libusb-1.0`
6BINS=elftosb sbtoelf sbloader
6 7
7all: elftosb sbtoelf 8all: $(BINS)
8 9
9%.o: %.c 10%.o: %.c
10 $(CC) $(CFLAGS) -c -o $@ $< 11 $(CC) $(CFLAGS) -c -o $@ $<
@@ -15,8 +16,11 @@ sbtoelf: sbtoelf.o crc.o crypto.o aes128.o sha1.o elf.o misc.o sb.o
15elftosb: elftosb.o crc.o crypto.o aes128.o sha1.o elf.o dbparser.o misc.o sb.o 16elftosb: elftosb.o crc.o crypto.o aes128.o sha1.o elf.o dbparser.o misc.o sb.o
16 $(LD) -o $@ $^ $(LDFLAGS) 17 $(LD) -o $@ $^ $(LDFLAGS)
17 18
19sbloader: sbloader.o
20 $(LD) -o $@ $^ $(LDFLAGS)
21
18clean: 22clean:
19 rm -fr *.o 23 rm -fr *.o
20 24
21veryclean: 25veryclean:
22 rm -rf sbtoelf elftosb 26 rm -rf $(BINS)
diff --git a/utils/sbtools/README b/utils/imxtools/README
index 8bf6fd5f8e..8bf6fd5f8e 100644
--- a/utils/sbtools/README
+++ b/utils/imxtools/README
diff --git a/utils/sbtools/aes128.c b/utils/imxtools/aes128.c
index 5870813db8..5870813db8 100644
--- a/utils/sbtools/aes128.c
+++ b/utils/imxtools/aes128.c
diff --git a/utils/sbtools/crc.c b/utils/imxtools/crc.c
index eaf257ddfe..eaf257ddfe 100644
--- a/utils/sbtools/crc.c
+++ b/utils/imxtools/crc.c
diff --git a/utils/sbtools/crypto.c b/utils/imxtools/crypto.c
index d4afc6c816..d4afc6c816 100644
--- a/utils/sbtools/crypto.c
+++ b/utils/imxtools/crypto.c
diff --git a/utils/sbtools/crypto.h b/utils/imxtools/crypto.h
index 51f44406db..452db6a28d 100644
--- a/utils/sbtools/crypto.h
+++ b/utils/imxtools/crypto.h
@@ -63,6 +63,7 @@ void crypto_setup(enum crypto_method_t method, void *param);
63#define CRYPTO_ERROR_DEVREJECT -5 /* device rejected cypto operation */ 63#define CRYPTO_ERROR_DEVREJECT -5 /* device rejected cypto operation */
64#define CRYPTO_ERROR_DEVSILENT -6 /* device did not notify completion */ 64#define CRYPTO_ERROR_DEVSILENT -6 /* device did not notify completion */
65#define CRYPTO_ERROR_DEVERR -7 /* device did something wrong (like return too small buffer) */ 65#define CRYPTO_ERROR_DEVERR -7 /* device did something wrong (like return too small buffer) */
66#define CRYPTO_NUM_ERRORS 8
66/* return 0 on success, <0 on error */ 67/* return 0 on success, <0 on error */
67int crypto_apply( 68int crypto_apply(
68 byte *in_data, /* Input data */ 69 byte *in_data, /* Input data */
diff --git a/utils/sbtools/dbparser.c b/utils/imxtools/dbparser.c
index 3cd0652d49..b2027e5ad7 100644
--- a/utils/sbtools/dbparser.c
+++ b/utils/imxtools/dbparser.c
@@ -19,6 +19,7 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#define _POSIX_C_SOURCE 200809L /* for strdup */
22#include <stdio.h> 23#include <stdio.h>
23#include <ctype.h> 24#include <ctype.h>
24#include <stdint.h> 25#include <stdint.h>
@@ -48,6 +49,7 @@ enum lexem_type_t
48struct lexem_t 49struct lexem_t
49{ 50{
50 enum lexem_type_t type; 51 enum lexem_type_t type;
52 /* if str is not NULL, it must be a malloc'd pointer */
51 char *str; 53 char *str;
52 uint32_t num; 54 uint32_t num;
53 int line; 55 int line;
@@ -390,8 +392,15 @@ struct lex_ctx_t
390 struct lexem_t lexem; 392 struct lexem_t lexem;
391}; 393};
392 394
393static inline void next(struct lex_ctx_t *ctx) 395/* When lexems hold strings (like identifier), it might be useful to steal
396 * the pointer and don't clean the lexem but in other case, one don't want
397 * to keep the pointer to the string and just want to release the memory.
398 * Thus clean_lexem should be true except when one keeps a pointer */
399static inline void next(struct lex_ctx_t *ctx, bool clean_lexem)
394{ 400{
401 if(clean_lexem)
402 free(ctx->lexem.str);
403 memset(&ctx->lexem, 0, sizeof(struct lexem_t));
395 next_lexem(&ctx->ctx, &ctx->lexem); 404 next_lexem(&ctx->ctx, &ctx->lexem);
396} 405}
397 406
@@ -411,7 +420,7 @@ static uint32_t parse_term_expr(struct lex_ctx_t *ctx, struct cmd_option_t *cons
411 } 420 }
412 else 421 else
413 parse_error(ctx->lexem, "Number or constant identifier expected\n"); 422 parse_error(ctx->lexem, "Number or constant identifier expected\n");
414 next(ctx); 423 next(ctx, true);
415 return ret; 424 return ret;
416} 425}
417 426
@@ -420,7 +429,7 @@ static uint32_t parse_shift_expr(struct lex_ctx_t *ctx, struct cmd_option_t *con
420 uint32_t v = parse_term_expr(ctx, const_list); 429 uint32_t v = parse_term_expr(ctx, const_list);
421 while(ctx->lexem.type == LEX_LSHIFT) 430 while(ctx->lexem.type == LEX_LSHIFT)
422 { 431 {
423 next(ctx); 432 next(ctx, true);
424 v <<= parse_term_expr(ctx, const_list); 433 v <<= parse_term_expr(ctx, const_list);
425 } 434 }
426 return v; 435 return v;
@@ -431,7 +440,7 @@ static uint32_t parse_or_expr(struct lex_ctx_t *ctx, struct cmd_option_t *const_
431 uint32_t v = parse_shift_expr(ctx, const_list); 440 uint32_t v = parse_shift_expr(ctx, const_list);
432 while(ctx->lexem.type == LEX_OR) 441 while(ctx->lexem.type == LEX_OR)
433 { 442 {
434 next(ctx); 443 next(ctx, true);
435 v |= parse_shift_expr(ctx, const_list); 444 v |= parse_shift_expr(ctx, const_list);
436 } 445 }
437 return v; 446 return v;
@@ -470,7 +479,7 @@ struct cmd_file_t *db_parse_file(const char *file)
470 { 479 {
471 struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t)); 480 struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t));
472 memset(opt, 0, sizeof(struct cmd_option_t)); 481 memset(opt, 0, sizeof(struct cmd_option_t));
473 opt->name = init_const_name[i]; 482 opt->name = strdup(init_const_name[i]);
474 opt->is_string = false; 483 opt->is_string = false;
475 opt->val = init_const_value[i]; 484 opt->val = init_const_value[i];
476 opt->next = cmd_file->constant_list; 485 opt->next = cmd_file->constant_list;
@@ -483,14 +492,14 @@ struct cmd_file_t *db_parse_file(const char *file)
483 lctx.ctx.begin = buf; 492 lctx.ctx.begin = buf;
484 lctx.ctx.ptr = buf; 493 lctx.ctx.ptr = buf;
485 lctx.ctx.end = buf + size; 494 lctx.ctx.end = buf + size;
486 #define next() next(&lctx) 495 #define next(clean_lexem) next(&lctx, clean_lexem)
487 #define lexem lctx.lexem 496 #define lexem lctx.lexem
488 /* init lexer */ 497 /* init lexer */
489 next(); 498 next(false); /* don't clean init lexem because it doesn't exist */
490 /* constants ? */ 499 /* constants ? */
491 if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "constants")) 500 if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "constants"))
492 { 501 {
493 next(); 502 next(true);
494 if(lexem.type != LEX_LBRACE) 503 if(lexem.type != LEX_LBRACE)
495 parse_error(lexem, "'{' expected after 'constants'\n"); 504 parse_error(lexem, "'{' expected after 'constants'\n");
496 505
@@ -498,16 +507,16 @@ struct cmd_file_t *db_parse_file(const char *file)
498 { 507 {
499 struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t)); 508 struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t));
500 memset(opt, 0, sizeof(struct cmd_option_t)); 509 memset(opt, 0, sizeof(struct cmd_option_t));
501 next(); 510 next(true);
502 if(lexem.type == LEX_RBRACE) 511 if(lexem.type == LEX_RBRACE)
503 break; 512 break;
504 if(lexem.type != LEX_IDENTIFIER) 513 if(lexem.type != LEX_IDENTIFIER)
505 parse_error(lexem, "Identifier expected in constants\n"); 514 parse_error(lexem, "Identifier expected in constants\n");
506 opt->name = lexem.str; 515 opt->name = lexem.str;
507 next(); 516 next(false); /* lexem string is kept as option name */
508 if(lexem.type != LEX_EQUAL) 517 if(lexem.type != LEX_EQUAL)
509 parse_error(lexem, "'=' expected after identifier\n"); 518 parse_error(lexem, "'=' expected after identifier\n");
510 next(); 519 next(true);
511 opt->is_string = false; 520 opt->is_string = false;
512 opt->val = parse_intexpr(&lctx, cmd_file->constant_list); 521 opt->val = parse_intexpr(&lctx, cmd_file->constant_list);
513 opt->next = cmd_file->constant_list; 522 opt->next = cmd_file->constant_list;
@@ -515,34 +524,34 @@ struct cmd_file_t *db_parse_file(const char *file)
515 if(lexem.type != LEX_SEMICOLON) 524 if(lexem.type != LEX_SEMICOLON)
516 parse_error(lexem, "';' expected after string\n"); 525 parse_error(lexem, "';' expected after string\n");
517 } 526 }
518 next(); 527 next(true);
519 } 528 }
520 /* options ? */ 529 /* options ? */
521 if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "options")) 530 if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "options"))
522 { 531 {
523 next(); 532 next(true);
524 if(lexem.type != LEX_LBRACE) 533 if(lexem.type != LEX_LBRACE)
525 parse_error(lexem, "'{' expected after 'options'\n"); 534 parse_error(lexem, "'{' expected after 'options'\n");
526 535
527 while(true) 536 while(true)
528 { 537 {
529 struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t)); 538 next(true);
530 memset(opt, 0, sizeof(struct cmd_option_t));
531 next();
532 if(lexem.type == LEX_RBRACE) 539 if(lexem.type == LEX_RBRACE)
533 break; 540 break;
541 struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t));
542 memset(opt, 0, sizeof(struct cmd_option_t));
534 if(lexem.type != LEX_IDENTIFIER) 543 if(lexem.type != LEX_IDENTIFIER)
535 parse_error(lexem, "Identifier expected in options\n"); 544 parse_error(lexem, "Identifier expected in options\n");
536 opt->name = lexem.str; 545 opt->name = lexem.str;
537 next(); 546 next(false); /* lexem string is kept as option name */
538 if(lexem.type != LEX_EQUAL) 547 if(lexem.type != LEX_EQUAL)
539 parse_error(lexem, "'=' expected after identifier\n"); 548 parse_error(lexem, "'=' expected after identifier\n");
540 next(); 549 next(true);
541 if(lexem.type == LEX_STRING) 550 if(lexem.type == LEX_STRING)
542 { 551 {
543 opt->is_string = true; 552 opt->is_string = true;
544 opt->str = lexem.str; 553 opt->str = lexem.str;
545 next(); 554 next(false); /* lexem string is kept as option name */
546 } 555 }
547 else 556 else
548 { 557 {
@@ -554,18 +563,18 @@ struct cmd_file_t *db_parse_file(const char *file)
554 if(lexem.type != LEX_SEMICOLON) 563 if(lexem.type != LEX_SEMICOLON)
555 parse_error(lexem, "';' expected after string\n"); 564 parse_error(lexem, "';' expected after string\n");
556 } 565 }
557 next(); 566 next(true);
558 } 567 }
559 /* sources */ 568 /* sources */
560 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources")) 569 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources"))
561 parse_error(lexem, "'sources' expected\n"); 570 parse_error(lexem, "'sources' expected\n");
562 next(); 571 next(true);
563 if(lexem.type != LEX_LBRACE) 572 if(lexem.type != LEX_LBRACE)
564 parse_error(lexem, "'{' expected after 'sources'\n"); 573 parse_error(lexem, "'{' expected after 'sources'\n");
565 574
566 while(true) 575 while(true)
567 { 576 {
568 next(); 577 next(true);
569 if(lexem.type == LEX_RBRACE) 578 if(lexem.type == LEX_RBRACE)
570 break; 579 break;
571 struct cmd_source_t *src = xmalloc(sizeof(struct cmd_source_t)); 580 struct cmd_source_t *src = xmalloc(sizeof(struct cmd_source_t));
@@ -573,28 +582,28 @@ struct cmd_file_t *db_parse_file(const char *file)
573 if(lexem.type != LEX_IDENTIFIER) 582 if(lexem.type != LEX_IDENTIFIER)
574 parse_error(lexem, "identifier expected in sources\n"); 583 parse_error(lexem, "identifier expected in sources\n");
575 src->identifier = lexem.str; 584 src->identifier = lexem.str;
576 next(); 585 next(false); /* lexem string is kept as source name */
577 if(lexem.type != LEX_EQUAL) 586 if(lexem.type != LEX_EQUAL)
578 parse_error(lexem, "'=' expected after identifier\n"); 587 parse_error(lexem, "'=' expected after identifier\n");
579 next(); 588 next(true);
580 if(lexem.type == LEX_STRING) 589 if(lexem.type == LEX_STRING)
581 { 590 {
582 src->is_extern = false; 591 src->is_extern = false;
583 src->filename = lexem.str; 592 src->filename = lexem.str;
584 next(); 593 next(false); /* lexem string is kept as file name */
585 } 594 }
586 else if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "extern")) 595 else if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "extern"))
587 { 596 {
588 src->is_extern = true; 597 src->is_extern = true;
589 src->filename = "<extern>"; 598 src->filename = strdup("<extern>"); /* duplicate because it will be free'd */
590 next(); 599 next(true);
591 if(lexem.type != LEX_LPAREN) 600 if(lexem.type != LEX_LPAREN)
592 parse_error(lexem, "'(' expected after 'extern'\n"); 601 parse_error(lexem, "'(' expected after 'extern'\n");
593 next(); 602 next(true);
594 src->extern_nr = parse_intexpr(&lctx, cmd_file->constant_list); 603 src->extern_nr = parse_intexpr(&lctx, cmd_file->constant_list);
595 if(lexem.type != LEX_RPAREN) 604 if(lexem.type != LEX_RPAREN)
596 parse_error(lexem, "')' expected\n"); 605 parse_error(lexem, "')' expected\n");
597 next(); 606 next(true);
598 } 607 }
599 else 608 else
600 parse_error(lexem, "String or 'extern' expected after '='\n"); 609 parse_error(lexem, "String or 'extern' expected after '='\n");
@@ -612,18 +621,18 @@ struct cmd_file_t *db_parse_file(const char *file)
612 struct cmd_section_t *end_sec = NULL; 621 struct cmd_section_t *end_sec = NULL;
613 while(true) 622 while(true)
614 { 623 {
624 next(true);
625 if(lexem.type == LEX_EOF)
626 break;
615 struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t)); 627 struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t));
616 struct cmd_inst_t *end_list = NULL; 628 struct cmd_inst_t *end_list = NULL;
617 memset(sec, 0, sizeof(struct cmd_section_t)); 629 memset(sec, 0, sizeof(struct cmd_section_t));
618 next();
619 if(lexem.type == LEX_EOF)
620 break;
621 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0) 630 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0)
622 parse_error(lexem, "'section' expected\n"); 631 parse_error(lexem, "'section' expected\n");
623 next(); 632 next(true);
624 if(lexem.type != LEX_LPAREN) 633 if(lexem.type != LEX_LPAREN)
625 parse_error(lexem, "'(' expected after 'section'\n"); 634 parse_error(lexem, "'(' expected after 'section'\n");
626 next(); 635 next(true);
627 /* can be any number */ 636 /* can be any number */
628 sec->identifier = parse_intexpr(&lctx, cmd_file->constant_list); 637 sec->identifier = parse_intexpr(&lctx, cmd_file->constant_list);
629 /* options ? */ 638 /* options ? */
@@ -631,21 +640,21 @@ struct cmd_file_t *db_parse_file(const char *file)
631 { 640 {
632 do 641 do
633 { 642 {
634 next(); 643 next(true);
635 struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t)); 644 struct cmd_option_t *opt = xmalloc(sizeof(struct cmd_option_t));
636 memset(opt, 0, sizeof(struct cmd_option_t)); 645 memset(opt, 0, sizeof(struct cmd_option_t));
637 if(lexem.type != LEX_IDENTIFIER) 646 if(lexem.type != LEX_IDENTIFIER)
638 parse_error(lexem, "Identifier expected for section option\n"); 647 parse_error(lexem, "Identifier expected for section option\n");
639 opt->name = lexem.str; 648 opt->name = lexem.str;
640 next(); 649 next(false); /* lexem string is kept as option name */
641 if(lexem.type != LEX_EQUAL) 650 if(lexem.type != LEX_EQUAL)
642 parse_error(lexem, "'=' expected after option identifier\n"); 651 parse_error(lexem, "'=' expected after option identifier\n");
643 next(); 652 next(true);
644 if(lexem.type == LEX_STRING) 653 if(lexem.type == LEX_STRING)
645 { 654 {
646 opt->is_string = true; 655 opt->is_string = true;
647 opt->str = lexem.str; 656 opt->str = lexem.str;
648 next(); 657 next(false); /* lexem string is kept as option string */
649 } 658 }
650 else 659 else
651 { 660 {
@@ -658,18 +667,18 @@ struct cmd_file_t *db_parse_file(const char *file)
658 } 667 }
659 if(lexem.type != LEX_RPAREN) 668 if(lexem.type != LEX_RPAREN)
660 parse_error(lexem, "')' expected after section identifier\n"); 669 parse_error(lexem, "')' expected after section identifier\n");
661 next(); 670 next(true);
662 if(lexem.type == LEX_LBRACE) 671 if(lexem.type == LEX_LBRACE)
663 { 672 {
664 sec->is_data = false; 673 sec->is_data = false;
665 /* commands */ 674 /* commands */
666 while(true) 675 while(true)
667 { 676 {
668 struct cmd_inst_t *inst = xmalloc(sizeof(struct cmd_inst_t)); 677 next(true);
669 memset(inst, 0, sizeof(struct cmd_inst_t));
670 next();
671 if(lexem.type == LEX_RBRACE) 678 if(lexem.type == LEX_RBRACE)
672 break; 679 break;
680 struct cmd_inst_t *inst = xmalloc(sizeof(struct cmd_inst_t));
681 memset(inst, 0, sizeof(struct cmd_inst_t));
673 if(lexem.type != LEX_IDENTIFIER) 682 if(lexem.type != LEX_IDENTIFIER)
674 parse_error(lexem, "Instruction expected in section\n"); 683 parse_error(lexem, "Instruction expected in section\n");
675 if(strcmp(lexem.str, "load") == 0) 684 if(strcmp(lexem.str, "load") == 0)
@@ -682,7 +691,7 @@ struct cmd_file_t *db_parse_file(const char *file)
682 inst->type = CMD_MODE; 691 inst->type = CMD_MODE;
683 else 692 else
684 parse_error(lexem, "Instruction expected in section\n"); 693 parse_error(lexem, "Instruction expected in section\n");
685 next(); 694 next(true);
686 695
687 if(inst->type == CMD_LOAD) 696 if(inst->type == CMD_LOAD)
688 { 697 {
@@ -691,12 +700,12 @@ struct cmd_file_t *db_parse_file(const char *file)
691 inst->identifier = lexem.str; 700 inst->identifier = lexem.str;
692 if(db_find_source_by_id(cmd_file, inst->identifier) == NULL) 701 if(db_find_source_by_id(cmd_file, inst->identifier) == NULL)
693 parse_error(lexem, "Undefined reference to source '%s'\n", inst->identifier); 702 parse_error(lexem, "Undefined reference to source '%s'\n", inst->identifier);
694 next(); 703 next(false); /* lexem string kept as identifier */
695 if(lexem.type == LEX_RANGLE) 704 if(lexem.type == LEX_RANGLE)
696 { 705 {
697 // load at 706 // load at
698 inst->type = CMD_LOAD_AT; 707 inst->type = CMD_LOAD_AT;
699 next(); 708 next(true);
700 inst->addr = parse_intexpr(&lctx, cmd_file->constant_list); 709 inst->addr = parse_intexpr(&lctx, cmd_file->constant_list);
701 } 710 }
702 if(lexem.type != LEX_SEMICOLON) 711 if(lexem.type != LEX_SEMICOLON)
@@ -709,7 +718,7 @@ struct cmd_file_t *db_parse_file(const char *file)
709 inst->identifier = lexem.str; 718 inst->identifier = lexem.str;
710 if(db_find_source_by_id(cmd_file, inst->identifier) == NULL) 719 if(db_find_source_by_id(cmd_file, inst->identifier) == NULL)
711 parse_error(lexem, "Undefined reference to source '%s'\n", inst->identifier); 720 parse_error(lexem, "Undefined reference to source '%s'\n", inst->identifier);
712 next(); 721 next(false); /* lexem string kept as identifier */
713 } 722 }
714 else 723 else
715 { 724 {
@@ -719,11 +728,11 @@ struct cmd_file_t *db_parse_file(const char *file)
719 728
720 if(lexem.type == LEX_LPAREN) 729 if(lexem.type == LEX_LPAREN)
721 { 730 {
722 next(); 731 next(true);
723 inst->argument = parse_intexpr(&lctx, cmd_file->constant_list); 732 inst->argument = parse_intexpr(&lctx, cmd_file->constant_list);
724 if(lexem.type != LEX_RPAREN) 733 if(lexem.type != LEX_RPAREN)
725 parse_error(lexem, "Expected closing brace\n"); 734 parse_error(lexem, "Expected closing brace\n");
726 next(); 735 next(true);
727 } 736 }
728 if(lexem.type != LEX_SEMICOLON) 737 if(lexem.type != LEX_SEMICOLON)
729 parse_error(lexem, "';' expected after command\n"); 738 parse_error(lexem, "';' expected after command\n");
@@ -751,11 +760,11 @@ struct cmd_file_t *db_parse_file(const char *file)
751 else if(lexem.type == LEX_LE) 760 else if(lexem.type == LEX_LE)
752 { 761 {
753 sec->is_data = true; 762 sec->is_data = true;
754 next(); 763 next(true);
755 if(lexem.type != LEX_IDENTIFIER) 764 if(lexem.type != LEX_IDENTIFIER)
756 parse_error(lexem, "Identifier expected after '<='\n"); 765 parse_error(lexem, "Identifier expected after '<='\n");
757 sec->source_id = lexem.str; 766 sec->source_id = lexem.str;
758 next(); 767 next(false); /* lexem string is kept as source id */
759 if(lexem.type != LEX_SEMICOLON) 768 if(lexem.type != LEX_SEMICOLON)
760 parse_error(lexem, "';' expected after identifier\n"); 769 parse_error(lexem, "';' expected after identifier\n");
761 } 770 }
@@ -776,6 +785,7 @@ struct cmd_file_t *db_parse_file(const char *file)
776 #undef lexem 785 #undef lexem
777 #undef next 786 #undef next
778 787
788 free(buf);
779 return cmd_file; 789 return cmd_file;
780} 790}
781 791
@@ -783,3 +793,57 @@ void db_generate_default_sb_version(struct sb_version_t *ver)
783{ 793{
784 ver->major = ver->minor = ver->revision = 0x999; 794 ver->major = ver->minor = ver->revision = 0x999;
785} 795}
796
797void db_free_option_list(struct cmd_option_t *opt_list)
798{
799 while(opt_list)
800 {
801 struct cmd_option_t *next = opt_list->next;
802 fflush(stdout);
803 free(opt_list->name);
804 free(opt_list->str);
805 free(opt_list);
806 opt_list = next;
807 }
808}
809
810void db_free(struct cmd_file_t *file)
811{
812 db_free_option_list(file->opt_list);
813 db_free_option_list(file->constant_list);
814 struct cmd_source_t *src = file->source_list;
815 while(src)
816 {
817 struct cmd_source_t *next = src->next;
818 free(src->identifier);
819 fflush(stdout);
820 free(src->filename);
821 if(src->loaded)
822 {
823 if(src->type == CMD_SRC_BIN)
824 free(src->bin.data);
825 if(src->type == CMD_SRC_ELF)
826 elf_release(&src->elf);
827 }
828 free(src);
829 src = next;
830 }
831 struct cmd_section_t *sec = file->section_list;
832 while(sec)
833 {
834 struct cmd_section_t *next = sec->next;
835 db_free_option_list(sec->opt_list);
836 free(sec->source_id);
837 struct cmd_inst_t *inst = sec->inst_list;
838 while(inst)
839 {
840 struct cmd_inst_t *next = inst->next;
841 free(inst->identifier);
842 free(inst);
843 inst = next;
844 }
845 free(sec);
846 sec = next;
847 }
848 free(file);
849}
diff --git a/utils/sbtools/dbparser.h b/utils/imxtools/dbparser.h
index cfb1a692fa..4a36861583 100644
--- a/utils/sbtools/dbparser.h
+++ b/utils/imxtools/dbparser.h
@@ -102,7 +102,7 @@ struct cmd_section_t
102struct cmd_file_t 102struct cmd_file_t
103{ 103{
104 struct cmd_option_t *opt_list; 104 struct cmd_option_t *opt_list;
105 struct cmd_option_t *constant_list; /* constant all always integers */ 105 struct cmd_option_t *constant_list; /* constant are always integers */
106 struct cmd_source_t *source_list; 106 struct cmd_source_t *source_list;
107 struct cmd_section_t *section_list; 107 struct cmd_section_t *section_list;
108}; 108};
@@ -112,5 +112,7 @@ struct cmd_option_t *db_find_option_by_id(struct cmd_option_t *opt, const char *
112bool db_parse_sb_version(struct sb_version_t *ver, char *str); 112bool db_parse_sb_version(struct sb_version_t *ver, char *str);
113void db_generate_default_sb_version(struct sb_version_t *ver); 113void db_generate_default_sb_version(struct sb_version_t *ver);
114struct cmd_file_t *db_parse_file(const char *file); 114struct cmd_file_t *db_parse_file(const char *file);
115void db_free_option_list(struct cmd_option_t *opt_list);
116void db_free(struct cmd_file_t *file);
115 117
116#endif /* __DBPARSER__ */ 118#endif /* __DBPARSER__ */
diff --git a/utils/sbtools/elf.c b/utils/imxtools/elf.c
index 91b5d74848..481ab98dd6 100644
--- a/utils/sbtools/elf.c
+++ b/utils/imxtools/elf.c
@@ -153,10 +153,7 @@ typedef struct
153 153
154void elf_init(struct elf_params_t *params) 154void elf_init(struct elf_params_t *params)
155{ 155{
156 params->has_start_addr = false; 156 memset(params, 0, sizeof(struct elf_params_t));
157 params->start_addr = 0;
158 params->first_section = NULL;
159 params->last_section = NULL;
160} 157}
161 158
162extern void *xmalloc(size_t s); 159extern void *xmalloc(size_t s);
@@ -463,6 +460,7 @@ bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read,
463 if(!read(user, shdr.sh_offset, data, shdr.sh_size)) 460 if(!read(user, shdr.sh_offset, data, shdr.sh_size))
464 error_printf("error read self section data\n"); 461 error_printf("error read self section data\n");
465 elf_add_load_section(params, shdr.sh_addr, shdr.sh_size, data); 462 elf_add_load_section(params, shdr.sh_addr, shdr.sh_size, data);
463 free(data);
466 464
467 if(strtab) 465 if(strtab)
468 printf(user, false, "create load segment for %s\n", &strtab[shdr.sh_name]); 466 printf(user, false, "create load segment for %s\n", &strtab[shdr.sh_name]);
@@ -480,6 +478,7 @@ bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read,
480 } 478 }
481 479
482 } 480 }
481 free(strtab);
483 /* run through segments */ 482 /* run through segments */
484 for(int i = 1; i < ehdr.e_phnum; i++) 483 for(int i = 1; i < ehdr.e_phnum; i++)
485 { 484 {
@@ -557,16 +556,20 @@ int elf_get_nr_sections(struct elf_params_t *params)
557 556
558void elf_release(struct elf_params_t *params) 557void elf_release(struct elf_params_t *params)
559{ 558{
560 struct elf_section_t *sec, *next_sec; 559 struct elf_section_t *sec = params->first_section;
561 sec = params->first_section;
562 while(sec) 560 while(sec)
563 { 561 {
564 next_sec = sec->next; 562 struct elf_section_t *next_sec = sec->next;
565 if(sec->type == EST_LOAD) 563 if(sec->type == EST_LOAD)
566 free(sec->section); 564 free(sec->section);
567 free(sec); 565 free(sec);
568 sec = next_sec; 566 sec = next_sec;
569 } 567 }
570 params->first_section = NULL; 568 struct elf_segment_t *seg = params->first_segment;
571 params->last_section = NULL; 569 while(seg)
570 {
571 struct elf_segment_t *next_seg = seg->next;
572 free(seg);
573 seg = next_seg;
574 }
572} 575}
diff --git a/utils/sbtools/elf.h b/utils/imxtools/elf.h
index 2166833276..2166833276 100644
--- a/utils/sbtools/elf.h
+++ b/utils/imxtools/elf.h
diff --git a/utils/sbtools/elftosb.c b/utils/imxtools/elftosb.c
index b8d68b82e7..2f8700551f 100644
--- a/utils/sbtools/elftosb.c
+++ b/utils/imxtools/elftosb.c
@@ -20,6 +20,7 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#define _ISOC99_SOURCE 22#define _ISOC99_SOURCE
23#define _POSIX_C_SOURCE 200809L /* for strdup */
23#include <stdio.h> 24#include <stdio.h>
24#include <errno.h> 25#include <errno.h>
25#include <stdlib.h> 26#include <stdlib.h>
@@ -77,7 +78,9 @@ static void resolve_extern(struct cmd_source_t *src)
77 src->is_extern = false; 78 src->is_extern = false;
78 if(src->extern_nr < 0 || src->extern_nr >= g_extern_count) 79 if(src->extern_nr < 0 || src->extern_nr >= g_extern_count)
79 bug("There aren't enough file on command file to resolve extern(%d)\n", src->extern_nr); 80 bug("There aren't enough file on command file to resolve extern(%d)\n", src->extern_nr);
80 src->filename = g_extern[src->extern_nr]; 81 /* first free the old src->filename content */
82 free(src->filename);
83 src->filename = strdup(g_extern[src->extern_nr]);
81} 84}
82 85
83static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id) 86static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
@@ -206,7 +209,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
206 209
207 sec->insts[0].inst = SB_INST_DATA; 210 sec->insts[0].inst = SB_INST_DATA;
208 sec->insts[0].size = bin->size; 211 sec->insts[0].size = bin->size;
209 sec->insts[0].data = bin->data; 212 sec->insts[0].data = memdup(bin->data, bin->size);
210 } 213 }
211 else 214 else
212 { 215 {
@@ -266,7 +269,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
266 sec->insts[idx].inst = SB_INST_LOAD; 269 sec->insts[idx].inst = SB_INST_LOAD;
267 sec->insts[idx].addr = esec->addr; 270 sec->insts[idx].addr = esec->addr;
268 sec->insts[idx].size = esec->size; 271 sec->insts[idx].size = esec->size;
269 sec->insts[idx++].data = esec->section; 272 sec->insts[idx++].data = memdup(esec->section, esec->size);
270 } 273 }
271 else if(esec->type == EST_FILL) 274 else if(esec->type == EST_FILL)
272 { 275 {
@@ -296,7 +299,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
296 struct bin_param_t *bin = &db_find_source_by_id(cmd_file, cinst->identifier)->bin; 299 struct bin_param_t *bin = &db_find_source_by_id(cmd_file, cinst->identifier)->bin;
297 sec->insts[idx].inst = SB_INST_LOAD; 300 sec->insts[idx].inst = SB_INST_LOAD;
298 sec->insts[idx].addr = cinst->addr; 301 sec->insts[idx].addr = cinst->addr;
299 sec->insts[idx].data = bin->data; 302 sec->insts[idx].data = memdup(bin->data, bin->size);
300 sec->insts[idx++].size = bin->size; 303 sec->insts[idx++].size = bin->size;
301 } 304 }
302 else if(cinst->type == CMD_MODE) 305 else if(cinst->type == CMD_MODE)
@@ -431,11 +434,18 @@ int main(int argc, char **argv)
431 434
432 struct cmd_file_t *cmd_file = db_parse_file(cmd_filename); 435 struct cmd_file_t *cmd_file = db_parse_file(cmd_filename);
433 struct sb_file_t *sb_file = apply_cmd_file(cmd_file); 436 struct sb_file_t *sb_file = apply_cmd_file(cmd_file);
437 db_free(cmd_file);
434 438
435 if(real_key.method == CRYPTO_KEY) 439 if(real_key.method == CRYPTO_KEY)
436 sb_file->real_key = &real_key.u.key; 440 {
441 sb_file->override_real_key = true;
442 memcpy(sb_file->real_key, real_key.u.key, 16);
443 }
437 if(crypto_iv.method == CRYPTO_KEY) 444 if(crypto_iv.method == CRYPTO_KEY)
438 sb_file->crypto_iv = &crypto_iv.u.key; 445 {
446 sb_file->override_crypto_iv = true;
447 memcpy(sb_file->crypto_iv, crypto_iv.u.key, 16);
448 }
439 449
440 /* fill with default parameters since there is no command file support for them */ 450 /* fill with default parameters since there is no command file support for them */
441 sb_file->drive_tag = 0; 451 sb_file->drive_tag = 0;
@@ -444,6 +454,8 @@ int main(int argc, char **argv)
444 sb_file->minor_version = 1; 454 sb_file->minor_version = 1;
445 455
446 sb_write_file(sb_file, output_filename); 456 sb_write_file(sb_file, output_filename);
457 sb_free(sb_file);
458 clear_keys();
447 459
448 return 0; 460 return 0;
449} 461}
diff --git a/utils/sbtools/fuze+_key_file.txt b/utils/imxtools/fuze+_key_file.txt
index a965e715f7..a965e715f7 100644
--- a/utils/sbtools/fuze+_key_file.txt
+++ b/utils/imxtools/fuze+_key_file.txt
diff --git a/utils/sbtools/misc.c b/utils/imxtools/misc.c
index 4eeda4ef33..8d7cea89d7 100644
--- a/utils/sbtools/misc.c
+++ b/utils/imxtools/misc.c
@@ -29,6 +29,14 @@ bool g_debug = false;
29/** 29/**
30 * Misc 30 * Misc
31 */ 31 */
32
33void *memdup(void *p, size_t len)
34{
35 void *cpy = xmalloc(len);
36 memcpy(cpy, p, len);
37 return cpy;
38}
39
32void generate_random_data(void *buf, size_t sz) 40void generate_random_data(void *buf, size_t sz)
33{ 41{
34 FILE *rand_fd = fopen("/dev/urandom", "rb"); 42 FILE *rand_fd = fopen("/dev/urandom", "rb");
@@ -144,6 +152,12 @@ void add_keys(key_array_t ka, int kac)
144 g_nr_keys += kac; 152 g_nr_keys += kac;
145} 153}
146 154
155void clear_keys()
156{
157 free(g_key_array);
158 g_nr_keys = 0;
159}
160
147void add_keys_from_file(const char *key_file) 161void add_keys_from_file(const char *key_file)
148{ 162{
149 int size; 163 int size;
diff --git a/utils/sbtools/misc.h b/utils/imxtools/misc.h
index 9f14497680..b0b7dfeba6 100644
--- a/utils/sbtools/misc.h
+++ b/utils/imxtools/misc.h
@@ -38,6 +38,7 @@ typedef struct crypto_key_t *key_array_t;
38int g_nr_keys; 38int g_nr_keys;
39key_array_t g_key_array; 39key_array_t g_key_array;
40 40
41void *memdup(void *p, size_t len);
41void *augment_array(void *arr, size_t elem_sz, size_t cnt, void *aug, size_t aug_cnt); 42void *augment_array(void *arr, size_t elem_sz, size_t cnt, void *aug, size_t aug_cnt);
42void generate_random_data(void *buf, size_t sz); 43void generate_random_data(void *buf, size_t sz);
43void *xmalloc(size_t s); 44void *xmalloc(size_t s);
@@ -47,6 +48,7 @@ void add_keys(key_array_t ka, int kac);
47bool parse_key(char **str, struct crypto_key_t *key); 48bool parse_key(char **str, struct crypto_key_t *key);
48void add_keys_from_file(const char *key_file); 49void add_keys_from_file(const char *key_file);
49void print_key(struct crypto_key_t *key, bool newline); 50void print_key(struct crypto_key_t *key, bool newline);
51void clear_keys();
50 52
51typedef char color_t[]; 53typedef char color_t[];
52 54
diff --git a/utils/sbtools/sb.c b/utils/imxtools/sb.c
index d620c00f42..44db56b7d1 100644
--- a/utils/sbtools/sb.c
+++ b/utils/imxtools/sb.c
@@ -138,7 +138,7 @@ static void compute_sb_offsets(struct sb_file_t *sb)
138 if(sb->sections[i].is_data) 138 if(sb->sections[i].is_data)
139 { 139 {
140 nr_aug_insts = 1; 140 nr_aug_insts = 1;
141 aug_insts = malloc(sizeof(struct sb_inst_t)); 141 aug_insts = xmalloc(sizeof(struct sb_inst_t));
142 memset(aug_insts, 0, sizeof(struct sb_inst_t)); 142 memset(aug_insts, 0, sizeof(struct sb_inst_t));
143 aug_insts[0].inst = SB_INST_DATA; 143 aug_insts[0].inst = SB_INST_DATA;
144 aug_insts[0].size = missing_sz * BLOCK_SIZE; 144 aug_insts[0].size = missing_sz * BLOCK_SIZE;
@@ -150,7 +150,7 @@ static void compute_sb_offsets(struct sb_file_t *sb)
150 else 150 else
151 { 151 {
152 nr_aug_insts = missing_sz; 152 nr_aug_insts = missing_sz;
153 aug_insts = malloc(sizeof(struct sb_inst_t) * nr_aug_insts); 153 aug_insts = xmalloc(sizeof(struct sb_inst_t) * nr_aug_insts);
154 memset(aug_insts, 0, sizeof(struct sb_inst_t) * nr_aug_insts); 154 memset(aug_insts, 0, sizeof(struct sb_inst_t) * nr_aug_insts);
155 for(int j = 0; j < nr_aug_insts; j++) 155 for(int j = 0; j < nr_aug_insts; j++)
156 { 156 {
@@ -163,6 +163,7 @@ static void compute_sb_offsets(struct sb_file_t *sb)
163 sb->sections[i].insts = augment_array(sb->sections[i].insts, sizeof(struct sb_inst_t), 163 sb->sections[i].insts = augment_array(sb->sections[i].insts, sizeof(struct sb_inst_t),
164 sb->sections[i].nr_insts, aug_insts, nr_aug_insts); 164 sb->sections[i].nr_insts, aug_insts, nr_aug_insts);
165 sb->sections[i].nr_insts += nr_aug_insts; 165 sb->sections[i].nr_insts += nr_aug_insts;
166 free(aug_insts);
166 167
167 /* augment image and section size */ 168 /* augment image and section size */
168 sb->image_size += missing_sz; 169 sb->image_size += missing_sz;
@@ -299,12 +300,8 @@ void produce_sb_instruction(struct sb_inst_t *inst,
299 cmd->hdr.checksum = instruction_checksum(&cmd->hdr); 300 cmd->hdr.checksum = instruction_checksum(&cmd->hdr);
300} 301}
301 302
302void sb_write_file(struct sb_file_t *sb, const char *filename) 303enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename)
303{ 304{
304 FILE *fd = fopen(filename, "wb");
305 if(fd == NULL)
306 bugp("cannot open output file");
307
308 struct crypto_key_t real_key; 305 struct crypto_key_t real_key;
309 real_key.method = CRYPTO_KEY; 306 real_key.method = CRYPTO_KEY;
310 byte crypto_iv[16]; 307 byte crypto_iv[16];
@@ -324,8 +321,13 @@ void sb_write_file(struct sb_file_t *sb, const char *filename)
324 /* produce and write header */ 321 /* produce and write header */
325 struct sb_header_t sb_hdr; 322 struct sb_header_t sb_hdr;
326 produce_sb_header(sb, &sb_hdr); 323 produce_sb_header(sb, &sb_hdr);
324 /* allocate image */
325 byte *buf = xmalloc(sb_hdr.image_size * BLOCK_SIZE);
326 byte *buf_p = buf;
327 #define write(p, sz) do { memcpy(buf_p, p, sz); buf_p += sz; } while(0)
328
327 sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr)); 329 sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr));
328 fwrite(&sb_hdr, 1, sizeof(sb_hdr), fd); 330 write(&sb_hdr, sizeof(sb_hdr));
329 331
330 memcpy(crypto_iv, &sb_hdr, 16); 332 memcpy(crypto_iv, &sb_hdr, 16);
331 333
@@ -340,7 +342,7 @@ void sb_write_file(struct sb_file_t *sb, const char *filename)
340 struct sb_section_header_t sb_sec_hdr; 342 struct sb_section_header_t sb_sec_hdr;
341 produce_sb_section_header(&sb->sections[i], &sb_sec_hdr); 343 produce_sb_section_header(&sb->sections[i], &sb_sec_hdr);
342 sha_1_update(&file_sha1, (byte *)&sb_sec_hdr, sizeof(sb_sec_hdr)); 344 sha_1_update(&file_sha1, (byte *)&sb_sec_hdr, sizeof(sb_sec_hdr));
343 fwrite(&sb_sec_hdr, 1, sizeof(sb_sec_hdr), fd); 345 write(&sb_sec_hdr, sizeof(sb_sec_hdr));
344 /* update CBC-MACs */ 346 /* update CBC-MACs */
345 for(int j = 0; j < g_nr_keys; j++) 347 for(int j = 0; j < g_nr_keys; j++)
346 crypto_cbc((byte *)&sb_sec_hdr, NULL, sizeof(sb_sec_hdr) / BLOCK_SIZE, 348 crypto_cbc((byte *)&sb_sec_hdr, NULL, sizeof(sb_sec_hdr) / BLOCK_SIZE,
@@ -354,16 +356,18 @@ void sb_write_file(struct sb_file_t *sb, const char *filename)
354 crypto_cbc(real_key.u.key, entry.key, 1, &g_key_array[i], 356 crypto_cbc(real_key.u.key, entry.key, 1, &g_key_array[i],
355 crypto_iv, NULL, 1); 357 crypto_iv, NULL, 1);
356 358
357 fwrite(&entry, 1, sizeof(entry), fd); 359 write(&entry, sizeof(entry));
358 sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry)); 360 sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry));
359 } 361 }
360 362
363 free(cbc_macs);
364
361 /* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK */ 365 /* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK */
362 /* Image crafting, don't use it unless you understand what you do */ 366 /* Image crafting, don't use it unless you understand what you do */
363 if(sb->real_key != NULL) 367 if(sb->override_real_key)
364 memcpy(real_key.u.key, *sb->real_key, 16); 368 memcpy(real_key.u.key, sb->real_key, 16);
365 if(sb->crypto_iv != NULL) 369 if(sb->override_crypto_iv)
366 memcpy(crypto_iv, *sb->crypto_iv, 16); 370 memcpy(crypto_iv, sb->crypto_iv, 16);
367 /* KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH */ 371 /* KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH */
368 if(g_debug) 372 if(g_debug)
369 { 373 {
@@ -386,7 +390,7 @@ void sb_write_file(struct sb_file_t *sb, const char *filename)
386 crypto_cbc((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE, 390 crypto_cbc((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE,
387 &real_key, crypto_iv, NULL, 1); 391 &real_key, crypto_iv, NULL, 1);
388 sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd)); 392 sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd));
389 fwrite(&tag_cmd, 1, sizeof(tag_cmd), fd); 393 write(&tag_cmd, sizeof(tag_cmd));
390 /* produce other commands */ 394 /* produce other commands */
391 byte cur_cbc_mac[16]; 395 byte cur_cbc_mac[16];
392 memcpy(cur_cbc_mac, crypto_iv, 16); 396 memcpy(cur_cbc_mac, crypto_iv, 16);
@@ -402,7 +406,7 @@ void sb_write_file(struct sb_file_t *sb, const char *filename)
402 crypto_cbc((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE, 406 crypto_cbc((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE,
403 &real_key, cur_cbc_mac, &cur_cbc_mac, 1); 407 &real_key, cur_cbc_mac, &cur_cbc_mac, 1);
404 sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); 408 sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd));
405 fwrite(&cmd, 1, sizeof(cmd), fd); 409 write(&cmd, sizeof(cmd));
406 } 410 }
407 /* data */ 411 /* data */
408 if(inst->inst == SB_INST_LOAD || inst->inst == SB_INST_DATA) 412 if(inst->inst == SB_INST_LOAD || inst->inst == SB_INST_DATA)
@@ -415,7 +419,7 @@ void sb_write_file(struct sb_file_t *sb, const char *filename)
415 crypto_cbc(data, data, sz / BLOCK_SIZE, 419 crypto_cbc(data, data, sz / BLOCK_SIZE,
416 &real_key, cur_cbc_mac, &cur_cbc_mac, 1); 420 &real_key, cur_cbc_mac, &cur_cbc_mac, 1);
417 sha_1_update(&file_sha1, data, sz); 421 sha_1_update(&file_sha1, data, sz);
418 fwrite(data, 1, sz, fd); 422 write(data, sz);
419 free(data); 423 free(data);
420 } 424 }
421 } 425 }
@@ -427,22 +431,35 @@ void sb_write_file(struct sb_file_t *sb, const char *filename)
427 generate_random_data(final_sig + 20, 12); 431 generate_random_data(final_sig + 20, 12);
428 if(g_nr_keys > 0) 432 if(g_nr_keys > 0)
429 crypto_cbc(final_sig, final_sig, 2, &real_key, crypto_iv, NULL, 1); 433 crypto_cbc(final_sig, final_sig, 2, &real_key, crypto_iv, NULL, 1);
430 fwrite(final_sig, 1, 32, fd); 434 write(final_sig, 32);
435
436 if(buf_p - buf != sb_hdr.image_size * BLOCK_SIZE)
437 bug("SB image buffer was not entirely filled !");
431 438
439 FILE *fd = fopen(filename, "wb");
440 if(fd == NULL)
441 return SB_OPEN_ERROR;
442 if(fwrite(buf, sb_hdr.image_size * BLOCK_SIZE, 1, fd) != 1)
443 {
444 free(buf);
445 return SB_WRITE_ERROR;
446 }
432 fclose(fd); 447 fclose(fd);
433} 448 free(buf);
434 449
435static void *memdup(void *p, size_t len) 450 return SB_SUCCESS;
436{
437 void *cpy = xmalloc(len);
438 memcpy(cpy, p, len);
439 return cpy;
440} 451}
441 452
442static struct sb_section_t *read_section(bool data_sec, uint32_t id, byte *buf, 453static struct sb_section_t *read_section(bool data_sec, uint32_t id, byte *buf,
443 int size, const char *indent, void *u, sb_color_printf cprintf) 454 int size, const char *indent, void *u, sb_color_printf cprintf, enum sb_error_t *err)
444{ 455{
445 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__) 456 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
457 #define fatal(e, ...) \
458 do { if(err) *err = e; \
459 cprintf(u, true, GREY, __VA_ARGS__); \
460 sb_free_section(*sec); \
461 free(sec); \
462 return NULL; } while(0)
446 463
447 struct sb_section_t *sec = xmalloc(sizeof(struct sb_section_t)); 464 struct sb_section_t *sec = xmalloc(sizeof(struct sb_section_t));
448 memset(sec, 0, sizeof(struct sb_section_t)); 465 memset(sec, 0, sizeof(struct sb_section_t));
@@ -474,7 +491,7 @@ static struct sb_section_t *read_section(bool data_sec, uint32_t id, byte *buf,
474 printf(OFF, "%s", indent); 491 printf(OFF, "%s", indent);
475 uint8_t checksum = instruction_checksum(hdr); 492 uint8_t checksum = instruction_checksum(hdr);
476 if(checksum != hdr->checksum) 493 if(checksum != hdr->checksum)
477 printf(GREY, "[Bad checksum]"); 494 fatal(SB_CHECKSUM_ERROR, "Bad instruction checksum");
478 if(hdr->flags != 0) 495 if(hdr->flags != 0)
479 { 496 {
480 printf(GREY, "["); 497 printf(GREY, "[");
@@ -501,7 +518,10 @@ static struct sb_section_t *read_section(bool data_sec, uint32_t id, byte *buf,
501 if(load->crc == computed_crc) 518 if(load->crc == computed_crc)
502 printf(RED, " Ok\n"); 519 printf(RED, " Ok\n");
503 else 520 else
521 {
504 printf(RED, " Failed (crc=0x%08x)\n", computed_crc); 522 printf(RED, " Failed (crc=0x%08x)\n", computed_crc);
523 fatal(SB_CHECKSUM_ERROR, "Instruction data crc error\n");
524 }
505 525
506 pos += load->len + sizeof(struct sb_instruction_load_t); 526 pos += load->len + sizeof(struct sb_instruction_load_t);
507 } 527 }
@@ -559,7 +579,7 @@ static struct sb_section_t *read_section(bool data_sec, uint32_t id, byte *buf,
559 } 579 }
560 else 580 else
561 { 581 {
562 printf(RED, "Unknown instruction %d at address 0x%08lx\n", hdr->opcode, (unsigned long)pos); 582 fatal(SB_FORMAT_ERROR, "Unknown instruction %d at address 0x%08lx\n", hdr->opcode, (unsigned long)pos);
563 break; 583 break;
564 } 584 }
565 585
@@ -569,6 +589,7 @@ static struct sb_section_t *read_section(bool data_sec, uint32_t id, byte *buf,
569 589
570 return sec; 590 return sec;
571 #undef printf 591 #undef printf
592 #undef fatal
572} 593}
573 594
574void sb_fill_section_name(char name[5], uint32_t identifier) 595void sb_fill_section_name(char name[5], uint32_t identifier)
@@ -595,25 +616,37 @@ static uint32_t guess_alignment(uint32_t off)
595} 616}
596 617
597struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u, 618struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
598 sb_color_printf cprintf) 619 sb_color_printf cprintf, enum sb_error_t *err)
599{ 620{
621 uint8_t *buf = NULL;
622 struct sb_file_t *sb_file = NULL;
623
600 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__) 624 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
601 #define fatal(...) do { cprintf(u, true, GREY, __VA_ARGS__); return NULL; } while(0) 625 #define fatal(e, ...) \
626 do { if(err) *err = e; \
627 cprintf(u, true, GREY, __VA_ARGS__); \
628 free(buf); \
629 sb_free(sb_file); \
630 return NULL; } while(0)
602 #define print_hex(c, p, len, nl) \ 631 #define print_hex(c, p, len, nl) \
603 do { printf(c, ""); print_hex(p, len, nl); } while(0) 632 do { printf(c, ""); print_hex(p, len, nl); } while(0)
604 633
605 FILE *f = fopen(filename, "rb"); 634 FILE *f = fopen(filename, "rb");
606 if(f == NULL) 635 if(f == NULL)
607 fatal("Cannot open file for reading\n"); 636 fatal(SB_OPEN_ERROR, "Cannot open file for reading\n");
608 fseek(f, 0, SEEK_END); 637 fseek(f, 0, SEEK_END);
609 long filesize = ftell(f); 638 long filesize = ftell(f);
610 fseek(f, 0, SEEK_SET); 639 fseek(f, 0, SEEK_SET);
611 uint8_t *buf = xmalloc(filesize); 640 buf = xmalloc(filesize);
612 fread(buf, 1, filesize, f); 641 if(fread(buf, filesize, 1, f) != 1)
642 {
643 fclose(f);
644 fatal(SB_READ_ERROR, "Cannot read file\n");
645 }
613 fclose(f); 646 fclose(f);
614 647
615 struct sha_1_params_t sha_1_params; 648 struct sha_1_params_t sha_1_params;
616 struct sb_file_t *sb_file = xmalloc(sizeof(struct sb_file_t)); 649 sb_file = xmalloc(sizeof(struct sb_file_t));
617 memset(sb_file, 0, sizeof(struct sb_file_t)); 650 memset(sb_file, 0, sizeof(struct sb_file_t));
618 struct sb_header_t *sb_header = (struct sb_header_t *)buf; 651 struct sb_header_t *sb_header = (struct sb_header_t *)buf;
619 652
@@ -624,13 +657,13 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
624 sb_file->first_boot_sec_id = sb_header->first_boot_sec_id; 657 sb_file->first_boot_sec_id = sb_header->first_boot_sec_id;
625 658
626 if(memcmp(sb_header->signature, "STMP", 4) != 0) 659 if(memcmp(sb_header->signature, "STMP", 4) != 0)
627 fatal("Bad signature\n"); 660 fatal(SB_FORMAT_ERROR, "Bad signature\n");
628 if(sb_header->image_size * BLOCK_SIZE > filesize) 661 if(sb_header->image_size * BLOCK_SIZE > filesize)
629 fatal("File too small mismatch"); 662 fatal(SB_FORMAT_ERROR, "File too small");
630 if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t)) 663 if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t))
631 fatal("Bad header size"); 664 fatal(SB_FORMAT_ERROR, "Bad header size");
632 if(sb_header->sec_hdr_size * BLOCK_SIZE != sizeof(struct sb_section_header_t)) 665 if(sb_header->sec_hdr_size * BLOCK_SIZE != sizeof(struct sb_section_header_t))
633 fatal("Bad section header size"); 666 fatal(SB_FORMAT_ERROR, "Bad section header size");
634 667
635 if(filesize > sb_header->image_size * BLOCK_SIZE) 668 if(filesize > sb_header->image_size * BLOCK_SIZE)
636 { 669 {
@@ -707,86 +740,106 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
707 /* encryption cbc-mac */ 740 /* encryption cbc-mac */
708 byte real_key[16]; 741 byte real_key[16];
709 bool valid_key = false; /* false until a matching key was found */ 742 bool valid_key = false; /* false until a matching key was found */
743
710 if(sb_header->nr_keys > 0) 744 if(sb_header->nr_keys > 0)
711 { 745 {
712 if(sb_header->nr_keys > g_nr_keys) 746 byte (*cbcmacs)[16] = xmalloc(16 * g_nr_keys);
713 { 747 printf(BLUE, "Encryption keys\n");
714 fatal("SB file has %d keys but only %d were specified\n", 748 for(int i = 0; i < g_nr_keys; i++)
715 sb_header->nr_keys, g_nr_keys);
716 }
717 printf(BLUE, "Encryption data\n");
718 for(int i = 0; i < sb_header->nr_keys; i++)
719 { 749 {
720 printf(RED, " Key %d: ", i); 750 printf(RED, " Key %d: ", i);
721 printf(YELLOW, ""); 751 printf(YELLOW, "");
722 print_key(&g_key_array[i], true); 752 print_key(&g_key_array[i], true);
723 printf(GREEN, " CBC-MAC of headers: "); 753 printf(GREEN, " CBC-MAC: ");
754 /* check it */
755 byte zero[16];
756 memset(zero, 0, 16);
757 int ret = crypto_cbc(buf, NULL, sb_header->header_size + sb_header->nr_sections,
758 &g_key_array[i], zero, &cbcmacs[i], 1);
759 if(ret != CRYPTO_ERROR_SUCCESS)
760 {
761 free(cbcmacs);
762 fatal(SB_FIRST_CRYPTO_ERROR + ret, "Crypto error: %d", ret);
763 }
764 print_hex(YELLOW, cbcmacs[i], 16, true);
765 }
724 766
767 printf(BLUE, "DEK\n");
768 for(int i = 0; i < sb_header->nr_keys; i++)
769 {
770 printf(RED, " Entry %d\n", i);
725 uint32_t ofs = sizeof(struct sb_header_t) 771 uint32_t ofs = sizeof(struct sb_header_t)
726 + sizeof(struct sb_section_header_t) * sb_header->nr_sections 772 + sizeof(struct sb_section_header_t) * sb_header->nr_sections
727 + sizeof(struct sb_key_dictionary_entry_t) * i; 773 + sizeof(struct sb_key_dictionary_entry_t) * i;
728 struct sb_key_dictionary_entry_t *dict_entry = 774 struct sb_key_dictionary_entry_t *dict_entry =
729 (struct sb_key_dictionary_entry_t *)&buf[ofs]; 775 (struct sb_key_dictionary_entry_t *)&buf[ofs];
730 /* cbc mac */ 776 /* cbc mac */
777 printf(GREEN, " Encrypted key: ");
778 print_hex(YELLOW, dict_entry->key, 16, true);
779 printf(GREEN, " CBC-MAC : ");
731 print_hex(YELLOW, dict_entry->hdr_cbc_mac, 16, false); 780 print_hex(YELLOW, dict_entry->hdr_cbc_mac, 16, false);
732 /* check it */ 781 /* check it */
733 byte computed_cbc_mac[16]; 782 int idx = 0;
734 byte zero[16]; 783 while(idx < g_nr_keys && memcmp(dict_entry->hdr_cbc_mac, cbcmacs[idx], 16) != 0)
735 memset(zero, 0, 16); 784 idx++;
736 crypto_cbc(buf, NULL, sb_header->header_size + sb_header->nr_sections, 785 if(idx != g_nr_keys)
737 &g_key_array[i], zero, &computed_cbc_mac, 1);
738
739 bool ok = memcmp(dict_entry->hdr_cbc_mac, computed_cbc_mac, 16) == 0;
740 if(ok)
741 {
742 valid_key = true;
743 printf(RED, " Ok\n");
744 }
745 else
746 printf(RED, " Failed\n");
747
748 printf(GREEN, " Encrypted key : ");
749 print_hex(YELLOW, dict_entry->key, 16, true);
750 /* decrypt */
751 byte decrypted_key[16];
752 byte iv[16];
753 memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */
754 crypto_cbc(dict_entry->key, decrypted_key, 1, &g_key_array[i], iv, NULL, 0);
755 printf(GREEN, " Decrypted key : ");
756 print_hex(YELLOW, decrypted_key, 16, false);
757 /* cross-check or copy */
758 if(valid_key && ok)
759 memcpy(real_key, decrypted_key, 16);
760 else if(valid_key)
761 { 786 {
762 if(memcmp(real_key, decrypted_key, 16) == 0) 787 printf(RED, " Match\n");
763 printf(RED, " Cross-Check Ok"); 788 /* decrypt */
789 byte decrypted_key[16];
790 byte iv[16];
791 memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */
792 int ret = crypto_cbc(dict_entry->key, decrypted_key, 1, &g_key_array[idx], iv, NULL, 0);
793 if(ret != CRYPTO_ERROR_SUCCESS)
794 {
795 free(cbcmacs);
796 fatal(SB_FIRST_CRYPTO_ERROR + ret, "Crypto error: %d\n", ret);
797 }
798 printf(GREEN, " Decrypted key: ");
799 print_hex(YELLOW, decrypted_key, 16, false);
800 if(valid_key)
801 {
802 if(memcmp(real_key, decrypted_key, 16) == 0)
803 printf(RED, " Cross-Check Ok");
804 else
805 printf(RED, " Cross-Check Failed");
806 }
764 else 807 else
765 printf(RED, " Cross-Check Failed"); 808 {
809 memcpy(real_key, decrypted_key, 16);
810 valid_key = true;
811 }
812 printf(OFF, "\n");
766 } 813 }
767 printf(OFF, "\n"); 814 else
815 printf(RED, " Don't Match\n");
768 } 816 }
769 }
770 817
771 if(getenv("SB_REAL_KEY") != 0) 818 free(cbcmacs);
772 { 819
773 struct crypto_key_t k; 820 if(!valid_key)
774 char *env = getenv("SB_REAL_KEY"); 821 fatal(SB_NO_VALID_KEY, "No valid key found\n");
775 if(!parse_key(&env, &k) || *env) 822
776 bug("Invalid SB_REAL_KEY\n"); 823 if(getenv("SB_REAL_KEY") != 0)
777 memcpy(real_key, k.u.key, 16); 824 {
778 } 825 struct crypto_key_t k;
826 char *env = getenv("SB_REAL_KEY");
827 if(!parse_key(&env, &k) || *env)
828 bug("Invalid SB_REAL_KEY\n");
829 memcpy(real_key, k.u.key, 16);
830 }
779 831
780 printf(RED, " Summary:\n"); 832 printf(RED, " Summary:\n");
781 printf(GREEN, " Real key: "); 833 printf(GREEN, " Real key: ");
782 print_hex(YELLOW, real_key, 16, true); 834 print_hex(YELLOW, real_key, 16, true);
783 printf(GREEN, " IV : "); 835 printf(GREEN, " IV : ");
784 print_hex(YELLOW, buf, 16, true); 836 print_hex(YELLOW, buf, 16, true);
785 837
786 sb_file->real_key = xmalloc(16); 838 sb_file->override_real_key = true;
787 memcpy(*sb_file->real_key, real_key, 16); 839 memcpy(sb_file->real_key, real_key, 16);
788 sb_file->crypto_iv = xmalloc(16); 840 sb_file->override_crypto_iv = true;
789 memcpy(*sb_file->crypto_iv, buf, 16); 841 memcpy(sb_file->crypto_iv, buf, 16);
842 }
790 843
791 /* sections */ 844 /* sections */
792 if(!raw_mode) 845 if(!raw_mode)
@@ -831,7 +884,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
831 memcpy(sec, buf + pos, size); 884 memcpy(sec, buf + pos, size);
832 885
833 struct sb_section_t *s = read_section(data_sec, sec_hdr->identifier, 886 struct sb_section_t *s = read_section(data_sec, sec_hdr->identifier,
834 sec, size, " ", u, cprintf); 887 sec, size, " ", u, cprintf, err);
835 if(s) 888 if(s)
836 { 889 {
837 s->is_cleartext = !encrypted; 890 s->is_cleartext = !encrypted;
@@ -839,6 +892,8 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
839 memcpy(&sb_file->sections[i], s, sizeof(struct sb_section_t)); 892 memcpy(&sb_file->sections[i], s, sizeof(struct sb_section_t));
840 free(s); 893 free(s);
841 } 894 }
895 else
896 fatal(*err, "Error reading section\n");
842 897
843 free(sec); 898 free(sec);
844 } 899 }
@@ -919,7 +974,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
919 memcpy(sec, buf + pos, size); 974 memcpy(sec, buf + pos, size);
920 975
921 struct sb_section_t *s = read_section(data_sec, tag->identifier, 976 struct sb_section_t *s = read_section(data_sec, tag->identifier,
922 sec, size, " ", u, cprintf); 977 sec, size, " ", u, cprintf, err);
923 if(s) 978 if(s)
924 { 979 {
925 s->is_cleartext = !encrypted; 980 s->is_cleartext = !encrypted;
@@ -929,6 +984,8 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
929 s, 1); 984 s, 1);
930 free(s); 985 free(s);
931 } 986 }
987 else
988 fatal(*err, "Error reading section\n");
932 free(sec); 989 free(sec);
933 990
934 /* last one ? */ 991 /* last one ? */
@@ -938,7 +995,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
938 } 995 }
939 else 996 else
940 { 997 {
941 printf(RED, "Unknown instruction %d at address 0x%08lx\n", hdr->opcode, (long)offset); 998 fatal(SB_FORMAT_ERROR, "Unknown instruction %d at address 0x%08lx\n", hdr->opcode, (long)offset);
942 break; 999 break;
943 } 1000 }
944 } 1001 }
@@ -970,7 +1027,10 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
970 if(memcmp(decrypted_block, computed_sha1, 20) == 0) 1027 if(memcmp(decrypted_block, computed_sha1, 20) == 0)
971 printf(RED, " Ok\n"); 1028 printf(RED, " Ok\n");
972 else 1029 else
1030 {
973 printf(RED, " Failed\n"); 1031 printf(RED, " Failed\n");
1032 fatal(SB_CHECKSUM_ERROR, "File SHA-1 error\n");
1033 }
974 free(buf); 1034 free(buf);
975 1035
976 return sb_file; 1036 return sb_file;
@@ -979,6 +1039,27 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
979 #undef print_hex 1039 #undef print_hex
980} 1040}
981 1041
1042void sb_free_section(struct sb_section_t sec)
1043{
1044 for(int j = 0; j < sec.nr_insts; j++)
1045 {
1046 free(sec.insts[j].padding);
1047 free(sec.insts[j].data);
1048 }
1049 free(sec.insts);
1050}
1051
1052void sb_free(struct sb_file_t *file)
1053{
1054 if(!file) return;
1055
1056 for(int i = 0; i < file->nr_sections; i++)
1057 sb_free_section(file->sections[i]);
1058
1059 free(file->sections);
1060 free(file);
1061}
1062
982void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf) 1063void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf)
983{ 1064{
984 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__) 1065 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
@@ -1007,17 +1088,17 @@ void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf)
1007 sb_fill_section_name(name, file->first_boot_sec_id); 1088 sb_fill_section_name(name, file->first_boot_sec_id);
1008 printf(TEXT, "%08x (%s)\n", file->first_boot_sec_id, name); 1089 printf(TEXT, "%08x (%s)\n", file->first_boot_sec_id, name);
1009 1090
1010 if(file->real_key) 1091 if(file->override_real_key)
1011 { 1092 {
1012 printf(TREE, "+-"); 1093 printf(TREE, "+-");
1013 printf(HEADER, "Real key: "); 1094 printf(HEADER, "Real key: ");
1014 print_hex(TEXT, *file->real_key, 16, true); 1095 print_hex(TEXT, file->real_key, 16, true);
1015 } 1096 }
1016 if(file->crypto_iv) 1097 if(file->override_crypto_iv)
1017 { 1098 {
1018 printf(TREE, "+-"); 1099 printf(TREE, "+-");
1019 printf(HEADER, "IV : "); 1100 printf(HEADER, "IV : ");
1020 print_hex(TEXT, *file->crypto_iv, 16, true); 1101 print_hex(TEXT, file->crypto_iv, 16, true);
1021 } 1102 }
1022 printf(TREE, "+-"); 1103 printf(TREE, "+-");
1023 printf(HEADER, "Product Version: "); 1104 printf(HEADER, "Product Version: ");
diff --git a/utils/sbtools/sb.h b/utils/imxtools/sb.h
index 39bb8ce59b..ced6481a80 100644
--- a/utils/sbtools/sb.h
+++ b/utils/imxtools/sb.h
@@ -191,9 +191,11 @@ struct sb_section_t
191struct sb_file_t 191struct sb_file_t
192{ 192{
193 /* override real, otherwise it is randomly generated */ 193 /* override real, otherwise it is randomly generated */
194 uint8_t (*real_key)[16]; 194 bool override_real_key;
195 uint8_t real_key[16];
195 /* override crypto IV, use with caution ! Use NULL to generate it */ 196 /* override crypto IV, use with caution ! Use NULL to generate it */
196 uint8_t (*crypto_iv)[16]; 197 bool override_crypto_iv;
198 uint8_t crypto_iv[16];
197 199
198 int nr_sections; 200 int nr_sections;
199 uint16_t drive_tag; 201 uint16_t drive_tag;
@@ -207,13 +209,29 @@ struct sb_file_t
207 uint32_t image_size; /* in blocks */ 209 uint32_t image_size; /* in blocks */
208}; 210};
209 211
210void sb_write_file(struct sb_file_t *sb, const char *filename); 212enum sb_error_t
213{
214 SB_SUCCESS = 0,
215 SB_ERROR = -1,
216 SB_OPEN_ERROR = -2,
217 SB_READ_ERROR = -3,
218 SB_WRITE_ERROR = -4,
219 SB_FORMAT_ERROR = -5,
220 SB_CHECKSUM_ERROR = -6,
221 SB_NO_VALID_KEY = -7,
222 SB_FIRST_CRYPTO_ERROR = -8,
223 SB_LAST_CRYPTO_ERROR = SB_FIRST_CRYPTO_ERROR - CRYPTO_NUM_ERRORS,
224};
225
226enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename);
211 227
212typedef void (*sb_color_printf)(void *u, bool err, color_t c, const char *f, ...); 228typedef void (*sb_color_printf)(void *u, bool err, color_t c, const char *f, ...);
213struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u, 229struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
214 sb_color_printf printf); 230 sb_color_printf printf, enum sb_error_t *err);
215 231
216void sb_fill_section_name(char name[5], uint32_t identifier); 232void sb_fill_section_name(char name[5], uint32_t identifier);
217void sb_dump(struct sb_file_t *file, void *u, sb_color_printf printf); 233void sb_dump(struct sb_file_t *file, void *u, sb_color_printf printf);
234void sb_free_section(struct sb_section_t file);
235void sb_free(struct sb_file_t *file);
218 236
219#endif /* __SB_H__ */ 237#endif /* __SB_H__ */
diff --git a/utils/imx_hid_recovery/imx_hid_recovery.c b/utils/imxtools/sbloader.c
index ba4645f8ab..ba4645f8ab 100644
--- a/utils/imx_hid_recovery/imx_hid_recovery.c
+++ b/utils/imxtools/sbloader.c
diff --git a/utils/sbtools/sbtoelf.c b/utils/imxtools/sbtoelf.c
index 179f91262f..fda70b1180 100644
--- a/utils/sbtools/sbtoelf.c
+++ b/utils/imxtools/sbtoelf.c
@@ -268,7 +268,15 @@ int main(int argc, char **argv)
268 268
269 const char *sb_filename = argv[optind]; 269 const char *sb_filename = argv[optind];
270 270
271 struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, sb_printf); 271 enum sb_error_t err;
272 struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, sb_printf, &err);
273 if(file == NULL)
274 {
275 color(OFF);
276 printf("SB read failed: %d\n", err);
277 return 1;
278 }
279
272 color(OFF); 280 color(OFF);
273 if(g_out_prefix) 281 if(g_out_prefix)
274 extract_sb_file(file); 282 extract_sb_file(file);
@@ -283,12 +291,12 @@ int main(int argc, char **argv)
283 /* sb_read_file will fill real key and IV but we don't want to override 291 /* sb_read_file will fill real key and IV but we don't want to override
284 * them when looping back otherwise the output will be inconsistent and 292 * them when looping back otherwise the output will be inconsistent and
285 * garbage */ 293 * garbage */
286 free(file->real_key); 294 file->override_real_key = false;
287 file->real_key = NULL; 295 file->override_crypto_iv = false;
288 free(file->crypto_iv);
289 file->crypto_iv = NULL;
290 sb_write_file(file, loopback); 296 sb_write_file(file, loopback);
291 } 297 }
298 sb_free(file);
299 clear_keys();
292 300
293 return 0; 301 return 0;
294} 302}
diff --git a/utils/sbtools/sha1.c b/utils/imxtools/sha1.c
index 0ad05bb5cd..0ad05bb5cd 100644
--- a/utils/sbtools/sha1.c
+++ b/utils/imxtools/sha1.c