Parser grammar#
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 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:
command_file
::= pre_section_block* section_block*
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:
pre_section_block
::= options_block
| constants_block
| sources_block
| keyblob_block
referenced by:
command_file
options_block:
options_block
::= OPTIONS '{' option_def* '}'
Comments:
Example:
options {
opt1 = "some_string";
opt2 = 1234;
opt3 = 1 > 3;
...
}
referenced by:
pre_section_block
option_def:
option_def
::= IDENT '=' const_expr ';'
referenced by:
options_block
constants_block:
constants_block
::= CONSTANTS '{' constant_def* '}'
referenced by:
pre_section_block
Comments: Only numbers can be assigned to identifiers in the constants block.
constant_def:
constant_def
::= IDENT '=' bool_expr ';'
referenced by:
constants_block
sources_block:
sources_block
::= SOURCES '{' source_def* '}'
referenced by:
pre_section_block
source_def:
source_def
::= IDENT '=' source_value ( '(' option_list? ')' )? ';'
referenced by:
sources_block
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:
source_value
::= STRING_LITERAL
| EXTERN '(' int_const_expr ')'
referenced by:
source_def
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:
option_list
::= IDENT '=' const_expr ( ',' IDENT '=' const_expr )*
referenced by:
keyblob_contents
section_options
source_def
keyblob_block:
keyblob_block
::= KEYBLOB '(' int_const_expr ')' '{' keyblob_contents '}'
referenced by:
pre_section_block
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:
keyblob_contents
::= '(' option_list* ')'
referenced by:
keyblob_block
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] - counter value
byteSwap [boolean, optional] - true for byte swap
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:
section_block
::= SECTION '(' int_const_expr section_options? ')' section_contents
referenced by:
command_file
Comments:
section_options
is not supported and raises syntax error when used!
section_options:
section_options
::= ';' option_list?
referenced by:
section_block
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.
section_contents:
section_contents
::= '{' statement* '}'
| '<=' source_name ';'
referenced by:
section_block
statement:
statement
::= basic_stmt ';'
| from_stmt
| if_stmt
| keywrap_stmt
referenced by:
else_stmt
encrypt_stmt
if_stmt
keywrap_stmt
section_contents
basic_stmt:
basic_stmt
::= load_stmt
| load_ifr_stmt
| call_stmt
| jump_sp_stmt
| mode_stmt
| message_stmt
| erase_stmt
| enable_stmt
| reset_stmt
| encrypt_stmt
| keystore_stmt
referenced by:
in_from_stmt
statement
load_stmt:
load_stmt
::= LOAD load_opt load_data load_target
referenced by:
basic_stmt
load_opt:
load_opt ::= IDENT
| int_const_expr
| empty
referenced by:
load_stmt
load_data:
load_data
::= int_const_expr
| STRING_LITERAL
| IDENT
| section_list ( FROM IDENT )?
| BINARY_BLOB
referenced by:
load_stmt
load_target:
load_target
::= '>' ( '.' | address_or_range )
referenced by:
load_stmt
section_list:
section_list
::= section_ref ( ',' section_ref )*
referenced by:
load_data
section_ref:
section_ref
::= '~'? SECTION_NAME
referenced by:
section_list
erase_stmt:
erase_stmt
::= ERASE ( address_or_range | ALL )
referenced by:
basic_stmt
address_or_range:
address_or_range
::= int_const_expr ( '..' int_const_expr )?
referenced by:
erase_stmt
keystore_stmt
load_target
symbol_ref:
symbol_ref
::= IDENT '?' ':' IDENT
referenced by:
call_target
load_ifr_stmt:
load_ifr_stmt
::= LOAD IFR int_const_expr '>' int_const_expr
referenced by:
basic_stmt
call_stmt:
call_stmt
::= call_type call_target call_arg?
referenced by:
basic_stmt
call_type:
call_type
::= CALL
| JUMP
referenced by:
call_stmt
call_target:
call_target
::= int_const_expr
| symbol_ref
| IDENT
referenced by:
call_stmt
jump_sp_stmt
call_arg:
call_arg ::= '(' int_const_expr? ')'
referenced by:
call_stmt
jump_sp_stmt
jump_sp_stmt:
jump_sp_stmt
::= JUMP_SP int_const_expr call_target call_arg?
referenced by:
basic_stmt
from_stmt:
from_stmt
::= FROM IDENT '{' in_from_stmt* '}'
referenced by:
statement
in_from_stmt:
in_from_stmt
::= basic_stmt ';'
| if_stmt
referenced by:
from_stmt
mode_stmt:
mode_stmt
::= MODE int_const_expr
referenced by:
basic_stmt
message_stmt:
message_stmt
::= message_type STRING_LITERAL
referenced by:
basic_stmt
message_type:
message_type
::= INFO
| WARNING
| ERROR
referenced by:
message_stmt
keystore_stmt:
keystore_stmt
::= ( KEYSTORE_TO_NV | KEYSTORE_FROM_NV ) mem_opt address_or_range
referenced by:
basic_stmt
mem_opt:
mem_opt ::= IDENT
| '@' int_const_expr
| empty
referenced by:
keystore_stmt
if_stmt:
if_stmt ::= IF bool_expr '{' statement* '}' else_stmt?
referenced by:
else_stmt
in_from_stmt
statement
else_stmt:
else_stmt
::= ELSE ( '(' statement* ')' | if_stmt )
referenced by:
if_stmt
keywrap_stmt:
keywrap_stmt
::= KEYWRAP '(' int_const_expr ')' '{' statement* '}'
referenced by:
statement
encrypt_stmt:
encrypt_stmt
::= ENCRYPT '(' int_const_expr ')' '{' statement* '}'
referenced by:
basic_stmt
enable_stmt:
enable_stmt
::= ENABLE AT_INT_LITERAL int_const_expr
referenced by:
basic_stmt
reset_stmt:
reset_stmt
::= RESET
referenced by:
basic_stmt
ver_check_stmt:
ver_check_stmt
::= VERSION_CHECK sec_or_nsec int_const_expr
sec_or_nsec:
sec_or_nsec
::= SEC
| NSEC
referenced by:
ver_check_stmt
const_expr:
const_expr
::= STRING_LITERAL
| bool_expr
referenced by:
option_def
option_list
int_const_expr:
int_const_expr
::= expr
referenced by:
address_or_range
bool_expr
call_arg
call_target
enable_stmt
encrypt_stmt
jump_sp_stmt
keyblob_block
keywrap_stmt
load_data
load_ifr_stmt
load_opt
mem_opt
mode_stmt
section_block
source_value
ver_check_stmt
bool_expr:
bool_expr
::= ( bool_expr ( '<' | '<=' | '>' | '>=' | '==' | '!=' | '&&' | '||' ) | '!' ) bool_expr
| ( '(' bool_expr | DEFINED '(' IDENT | IDENT '(' source_name ) ')'
| int_const_expr
referenced by:
bool_expr
const_expr
constant_def
if_stmt
expr:
expr ::= expr ( ( '+' | '-' | '*' | '/' | '%' | '<<' | '>>' | '&' | '|' | '^' ) expr | '.' INT_SIZE )
| ( '(' expr | SIZEOF '(' ( SYMBOL_REF | IDENT ) ) ')'
| INT_LITERAL
| IDENT
| SYMBOL_REF
| unary_expr
referenced by:
expr
int_const_expr
unary_expr
unary_expr:
unary_expr
::= ( '+' | '-' ) expr
referenced by:
expr
#
generated by RR - Railroad Diagram Generator