SB 2.1 generation using BD file

This is a user guide describing how to generate a secure binary rev. 2.1 based on a configuration file (a so called BD file or command file) and additional inputs like certificates, keys, binary files etc.

Supported Syntax

The syntax is written in EBNF (Extended Backus Naur Form), however, the elftosb application uses (namely SLY - python implementation of Lex/Yacc) only BNF. From this perspective the graphs visualize the EBNF form with the grammar and the conversion into BNF as well as remarks what is supported.

command_file:

         ::= pre_section_block* section_block*
         ::= pre_section_block section_block

no references

Comments:

The options block, constants block, sources block and keyblob block must be defined prior to the section block. There may be multiple blocks in any order, but all must precede the section blocks.

# options, sources, keyblob & constants must precede section block, but there may be
# multiple definitions in any order
options {

}

sources {

}

keyblob (0) {

}

constants {

}

options {

}

# Section blocks must be the very last blocks defined
section (1) {

}

section (2) {

}

pre_section_block:

         ::= options_block
           | constants_block
           | sources_block
           | keyblob_block
         ::= pre_section_block options_block
           | pre_section_block constants_block
           | pre_section_block sources_block
           | pre_section_block keyblob_block
           | empty

referenced by:


options_block:

         ::= OPTIONS '{' option_def* '}'
         ::= OPTIONS '{' option_def '}'

referenced by:


Comments:

Example:

options {
    opt1 = "some_string";
    opt2 = 1234;
    opt3 = 1 > 3;
    ...
}

option_def:

EBNF: option_def
         ::= IDENT '=' const_expr ';'
BNF: option_def
         ::= option_def IDENT '=' const_expr ';'
           | empty

referenced by:


constants_block:

         ::= CONSTANTS '{' constant_def* '}'
         ::= CONSTANTS '{' constant_def '}'

referenced by:


Comments: Only numbers can be assigned to identifiers in the constants block.

constant_def:

EBNF: constant_def
         ::= IDENT '=' bool_expr ';'
         ::= constant_def IDENT '=' bool_expr ';'
          | empty

referenced by:


sources_block:

         ::= SOURCES '{' source_def* '}'
         ::= SOURCES '{' source_def '}'

referenced by:


source_def:

EBNF: source_def
         ::= IDENT '=' source_value ( '(' option_list? ')' )? ';'
BNF: source_def
         ::= source_def IDENT '=' source_value ';'
           | source_def IDENT '=' source_value '(' option_list ')' ';'
           | empty

referenced by:


Comments:

option_list in source_def is not supported and raises syntax error when used! According to the grammar, identifiers defined in source block are referenced in the grammar as source_name, however, the grammar can’t be defined using this type of token, as there is no rule to distinguish between an identifier token and a source name token. So the grammar uses the IDENT token instead and documents this fact in description, that it’s a source_name identifier.

source_value:

EBNF: source_value
         ::= STRING_LITERAL
           | EXTERN '(' int_const_expr ')'
         ::= STRING_LITERAL
           | EXTERN '(' int_const_expr ')'

referenced by:


Comments:

The EXTERN keyword references source files defined on the command line as the very last arguments indexed from 0. In the example below, extern(1) would reference the “./file2” file provided on command line.

Command file example:

sources {
    my_binary_file = extern(1); # my_binary_file = file2.bin
}

Command line usage:

elf2sb -c.. -o.. "some/path/to/file1.bin" "./file2.bin"

option_list:

EBNF: option_list
         ::= IDENT '=' const_expr ( ',' IDENT '=' const_expr )*
         ::= IDENT '=' const_expr ',' option_list
         | IDENT '=' const_expr

referenced by:


keyblob_block:

         ::= KEYBLOB '(' int_const_expr ')' '{' keyblob_contents* '}'
         ::= KEYBLOB '(' int_const_expr ')' '{' keyblob_contents '}'

referenced by:


Comments:

The keyblob block grammar has been modified and it supports only single keyblob_contents definition, which must not be empty!

Example

keyblob (1) {
    (
        start = 0x0800000,
        end = 0x08001000,
        key = "12345678901234567890123456789012",
        counter = "1122334455667788",
        byteSwap = False
    )
    # No further definitions allowed, if present, syntax error will be raised!
}

keyblob_contents:

         ::= '(' option_list* ')'
         ::= keyblob_contents '(' option_list ')'
         | empty

referenced by:


Comments:

The keyblob contents must define:

start [integer] - start address 'maintained' by this keyblob
end [integer] - end address 'maintained' by this keyblob
key [string] - key used to encode data stored into address range defined by this keyblob
counter [string] - TODO
byteSwap [boolean, optional] - TODO

Anything else defined under keyblob is ignored. If definition of keywords listed above, except ‘byteSwap’ is missing, a syntax error will be raised.

section_block:

         | empty

referenced by:


Comments:

section_options is not supported and raises syntax error when used!

section_options:

         ::= ';' option_list?
         ::= ';' option_list
         | ';'
         | empty

referenced by:


section_contents:

         ::= '{' statement* '}'
           | '<=' IDENT ';'
         ::= '{' statement '}'
           | '<=' IDENT ';'

referenced by:


Comments:

<= IDENT is not supported and raises syntax error when used!

The IDENT in <= IDENT must be an identifier defined in the sources block, otherwise an error is raised.

statement:

EBNF: statement
         ::= basic_stmt ';'
           | from_stmt
           | if_stmt
BNF: statement
         ::= statement basic_stmt ';'
           | statement from_stmt
           | statement if_stmt
           | empty

referenced by:


basic_stmt:

EBNF: basic_stmt
         ::= load_stmt
           | load_ifr_stmt
           | call_stmt
           | jump_sp_stmt
           | mode_stmt
           | message_stmt
           | erase_stmt
           | enable_stmt
           | reset_stmt
           | encrypt_stmt
BNF: basic_stmt
         ::= load_stmt
           | load_ifr_stmt
           | call_stmt
           | jump_sp_stmt
           | mode_stmt
           | message_stmt
           | erase_stmt
           | enable_stmt
           | reset_stmt
           | encrypt_stmt

referenced by:


load_stmt:

EBNF: load_stmt
         ::= LOAD load_data load_target
BNF: load_stmt
         ::= LOAD load_data load_target

referenced by:


load_data:

EBNF: load_data
         ::= int_const_expr
           | STRING_LITERAL
           | IDENT
           | section_list ( FROM IDENT )?
           | BINARY_BLOB
BNF: load_data
         ::= int_const_expr
           | STRING_LITERAL
           | IDENT
           | section_list
           | section_list FROM IDENT
           | BINARY_BLOB

referenced by:


load_target:

EBNF: load_target
         ::= '>' ( '.' | address_or_range )
         ::= '>' '.'
         | '>' address_or_range
         | '>' empty

referenced by:


section_list:

EBNF: section_list
         ::= section_ref ( ',' section_ref )*
         ::= section_list ',' section_ref
         | section_ref

referenced by:


section_ref:

EBNF: section_ref
         ::= '~'? SECTION_NAME
         ::= '~' SECTION_NAME
         | SECTION_NAME

referenced by:


erase_stmt:

EBNF: erase_stmt
         ::= ERASE ( address_or_range | ALL )
BNF: erase_stmt
         ::= ERASE address_or_range
         | ALL

referenced by:


address_or_range:

         ::= int_const_expr ( '..' int_const_expr )?
         ::= int_const_expr
         | int_const_expr '..' int_const_expr

referenced by:


symbol_ref:

EBNF: symbol_ref
         ::= IDENT '?' ':' IDENT
BNF: symbol_ref
         ::= IDENT '?' ':' IDENT

referenced by:


load_ifr_stmt:

         ::= LOAD IFR int_const_expr '>' int_const_expr
         ::= LOAD IFR int_const_expr '>' int_const_expr

referenced by:


call_stmt:

EBNF: call_stmt
         ::= call_type call_target call_arg?
BNF: call_stmt
         ::= call_type call_target call_arg

referenced by:


call_type:

EBNF: call_type
         ::= CALL
           | JUMP
BNF: call_type
         ::= CALL
           | JUMP

referenced by:


call_target:

EBNF: call_target
         ::= int_const_expr
           | symbol_ref
           | IDENT
         ::= int_const_expr
           | symbol_ref
           | IDENT

referenced by:


call_arg:

EBNF: call_arg ::= '(' int_const_expr? ')'
BNF: call_arg ::= '(' ')'
           | '(' int_const_expr ')'
           | empty

referenced by:


jump_sp_stmt:

EBNF: jump_sp_stmt
         ::= JUMP_SP int_const_expr call_target call_arg?

referenced by:


from_stmt:

EBNF: from_stmt
         ::= FROM IDENT '{' in_from_stmt* '}'
BNF: from_stmt
         ::= FROM IDENT '{' in_from_stmt '}'

referenced by:


in_from_stmt:

EBNF: in_from_stmt
         ::= basic_stmt ';'
           | if_stmt
         ::= in_from_stmt basic_stmt ';'
           | in_from_stmt if_stmt
           | empty

referenced by:


mode_stmt:

EBNF: mode_stmt
         ::= MODE int_const_expr
BNF: mode_stmt
         ::= MODE int_const_expr

referenced by:


message_stmt:

EBNF: message_stmt
         ::= message_type STRING_LITERAL
         ::= message_type STRING_LITERAL

referenced by:


message_type:

EBNF: message_type
         ::= INFO
           | WARNING
           | ERROR
         ::= INFO
           | WARNING
           | ERROR

no references


if_stmt:

EBNF: if_stmt   ::= IF bool_expr '{' statement* '}' else_stmt?
BNF: if_stmt   ::= IF bool_expr '{' statement '}' else_stmt

referenced by:


else_stmt:

EBNF: else_stmt
         ::= ELSE ( '(' statement* ')' | if_stmt )
BNF: else_stmt
         ::= ELSE '(' statement ')'
         | ELSE if_stmt
         | empty

referenced by:


encrypt_stmt:

EBNF: encrypt_stmt
         ::= ENCRYPT '(' int_const_expr ')' '{' statement* '}'
         ::= ENCRYPT '(' int_const_expr ')' '{' statement '}'

referenced by:


enable_stmt:

EBNF: enable_stmt
         ::= ENABLE AT_INT_LITERAL int_const_expr
         ::= ENABLE AT_INT_LITERAL int_const_expr

referenced by:


reset_stmt:

EBNF: reset_stmt
         ::= RESET
BNF: reset_stmt
         ::= RESET

referenced by:


const_expr:

EBNF: const_expr
         ::= STRING_LITERAL
           | bool_expr
BNF: const_expr
         ::= STRING_LITERAL
           | bool_expr

referenced by:


int_const_expr:

         ::= expr
         ::= expr

referenced by:


bool_expr:

EBNF: bool_expr
         ::= ( bool_expr ( '<' | '<=' | '>' | '>=' | '==' | '!=' | '&&' | '||' ) | '!' ) bool_expr
           | ( '(' bool_expr | DEFINED '(' IDENT | IDENT '(' source_name ) ')'
           | int_const_expr
BNF: bool_expr
         ::= bool_expr'<' bool_expr
         | bool_expr'<=' bool_expr
         | bool_expr'>' bool_expr
         | bool_expr'>=' bool_expr
         | bool_expr'==' bool_expr
         | bool_expr'!=' bool_expr
         | bool_expr'&&' bool_expr
         | bool_expr'||' bool_expr
         | '(' bool_expr ')'
         | int_const_expr
         | '!' bool_expr
         | DEFINED '(' IDENT ')'
         | IDENT '(' IDENT ')'

referenced by:


expr:

EBNF: expr
           ::= expr ( ( '+' | '-' | '*' | '/' | '%' | '<<' | '>>' | '&' | '|' | '^' ) expr | '.' INT_SIZE )
           | ( '(' expr | SIZEOF '(' ( SYMBOL_REF | IDENT ) ) ')'
           | INT_LITERAL
           | IDENT
           | SYMBOL_REF
           | unary_expr
BNF: expr
     ::= expr '+' expr
     | expr '-' expr
     | expr '*' expr
     | expr '/' expr
     | expr '%' expr
     | expr '<<' expr
     | expr '>>' expr
     | expr '&' expr
     | expr '|' expr
     | expr '^' expr
     | expr '.' INT_SIZE
     | '(' expr ')'
     | INT_LITERAL
     | IDENT
     | SYMBOL_REF
     | unary_expr
     | SIZEOF '(' SYMBOL_REF ')'
     | SIZEOF '(' IDENT ')'

referenced by:


unary_expr:

EBNF: unary_expr
         ::= ( '+' | '-' ) expr
BNF: unary_expr
         ::= '+' expr
         | '-' expr

referenced by:



  ... generated by RR - Railroad Diagram Generator