Secure Binary 2.1
Version 2.1 added support for digital signatures.
The SB 2.0 and 2.1 file format also uses AES encryption for confidentiality and HMAC for extending trust from the signed part of the SB file to the command and data part of the SB file. These two keys (AES decrypt key and HMAC key) are wrapped in the RFC3394 key blob, for which the key wrapping key is the SBKEK key
SB2 generation using BD file
The tool uses an input command file to control the sequence of bootloader commands present in the output file. This command file is called a “boot descriptor file” or BD file for short. The image location is stated in the “sources” section of the .bd file. The SB key in the text file is used for encryption with the nxpimage command line tool.
It is possible to use NXP elftosb tool user guide located here.
Note
Please note that some functionality described in the UG may not be supported in SPSDK SB2 parser.
For more information about the Secure boot setup for LPC55Sxx family follow the AN12283.
Supported Commands
Supported commands for SB2.1
Command |
Description |
Example |
|---|---|---|
load |
The load statement is used to store data into the memory. The load command is also used to write to the flash memory. When loading to the flash memory, the region being loaded to must be erased before to the load operation. The most common form of a load statement is loading a source file by name. |
|
fill |
Fill is a type of load command used for filling a region of memory with pattern. |
|
erase |
The erase statement inserts a bootloader command to erase the flash memory. There are two forms of the erase statement. The simplest form (erase all) creates a command that erases the available flash memory. The actual effect of this command depends on the runtime settings of the bootloader and whether the bootloader resides in the flash, ROM, or RAM. |
|
enable |
Enable statement is used for initialization of external memories using a parameter block that was previously loaded to RAM. |
|
encrypt |
Encrypt holds an ID, which is a reference to keyblob to be used for encryption. So the encrypt command requires a list of keyblobs, the keyblob ID and load command. |
|
keywrap |
Keywrap holds keyblob ID to be encoded by a value stored in load command and stored to address defined in the load command. |
|
keystore_to_nv |
The keystore_to_nv statement instructs the bootloader to load the backed up keystore values back into keystore memory region on non-volatile memory. |
|
keystore_from_nv |
The keystore_to_nv statement instructs the bootloader to load the backed up keystore values back into keystore memory region on non-volatile memory. |
|
version_check |
Validates version of secure or non-secure firmware. The command fails if version is < expected. |
|
jump |
The “jump” command produces the ROM_JUMP_CMD. See the boot image format design document for specific details about these commands, such as the function prototypes they expect. |
|
Example of SB2 generation for 4 root keys
nxpimage: nxpimage sb21 export -k "sbkek.txt" -c "commandFile.bd" -o "output.sb2" -s private_key_1_2048.pem
-S certificate_1_2048.der.crt -R certificate_1_2048.der.crt -R
certificate_2_2048.der.crt -R certificate_3_2048.der.crt -R certificate_4_2048.der.crt -h "RHKT.bin"
"input.bin"
Created SB2 file can be loaded into the device using blhost receive-sb-file command.
blhost -p COMxx receive-sb-file <path to the secured binary(.sb2)>
Description of how to use BD file is in bellow chapter.
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 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.
EBNF:
command_file
BNF:
command_file
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) {
}
EBNF:
pre_section_block
::=
options_block
BNF:
pre_section_block
|
empty
referenced by:
EBNF: options_block
::=
OPTIONS '{'
option_def* '}'
BNF: options_block
::=
OPTIONS '{'
option_def '}'
referenced by:
Comments:
Example:
options {
opt1 = "some_string";
opt2 = 1234;
opt3 = 1 > 3;
...
}
EBNF: option_def
::=
IDENT '='
const_expr ';'
BNF: option_def
|
empty
referenced by:
EBNF: constants_block
::=
CONSTANTS '{'
constant_def* '}'
BNF: constants_block
::=
CONSTANTS '{'
constant_def '}'
referenced by:
Comments: Only numbers can be assigned to identifiers in the constants block.
EBNF: constant_def
BNF: constant_def
|
empty
referenced by:
EBNF: sources_block
::=
SOURCES '{'
source_def* '}'
BNF: sources_block
::=
SOURCES '{'
source_def '}'
referenced by:
EBNF: source_def
BNF: source_def
|
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.
EBNF: source_value
::=
STRING_LITERAL
|
EXTERN '('
int_const_expr ')'
BNF: source_value
::=
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"
EBNF: option_list
BNF: option_list
|
IDENT '='
const_expr
referenced by:
EBNF: keyblob_block
BNF: keyblob_block
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!
}
EBNF: keyblob_contents
::= '('
option_list* ')'
BNF: keyblob_contents
::=
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.
EBNF: section_block
BNF: section_block
|
empty
referenced by:
Comments:
section_options is not supported and raises syntax error when used!
EBNF: section_options
::= ';'
option_list?
BNF: section_options
::= ';'
option_list
|
';'
|
empty
referenced by:
EBNF: section_contents
::= '{'
statement* '}'
|
'<=' IDENT ';'
BNF: section_contents
::= '{'
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.
EBNF: statement
::=
basic_stmt ';'
|
if_stmt
referenced by:
EBNF: basic_stmt
::=
load_stmt
BNF: basic_stmt
::=
load_stmt
referenced by:
EBNF: load_stmt
BNF: load_stmt
referenced by:
EBNF: load_data
::=
int_const_expr
|
IDENT
BNF: load_data
::=
int_const_expr
|
IDENT
referenced by:
EBNF: load_target
::= '>' ( '.' |
address_or_range )
BNF: load_target
::= '>' '.'
| '>'
address_or_range
| '>'
empty
referenced by:
EBNF: section_list
::=
section_ref ( ','
section_ref )*
BNF: section_list
::=
section_list ','
section_ref
referenced by:
EBNF: section_ref
::= '~'?
SECTION_NAME
BNF: section_ref
::= '~'
SECTION_NAME
referenced by:
EBNF: erase_stmt
BNF: erase_stmt
|
ALL
referenced by:
EBNF: address_or_range
::=
int_const_expr ( '..'
int_const_expr )?
BNF: address_or_range
::=
int_const_expr
|
int_const_expr '..'
int_const_expr
referenced by:
EBNF: symbol_ref
BNF: symbol_ref
referenced by:
EBNF: load_ifr_stmt
BNF: load_ifr_stmt
referenced by:
EBNF: call_stmt
BNF: call_stmt
referenced by:
referenced by:
EBNF: call_target
::=
int_const_expr
|
IDENT
BNF: call_target
::=
int_const_expr
|
IDENT
referenced by:
EBNF: call_arg ::= '('
int_const_expr? ')'
BNF: call_arg ::= '(' ')'
|
'(' int_const_expr ')'
|
empty
referenced by:
EBNF: jump_sp_stmt
BNF: jump_sp_stmt
referenced by:
EBNF: from_stmt
BNF: from_stmt
referenced by:
EBNF: in_from_stmt
::=
basic_stmt ';'
|
if_stmt
BNF: in_from_stmt
::=
in_from_stmt
basic_stmt ';'
|
empty
referenced by:
EBNF: mode_stmt
::=
MODE
int_const_expr
BNF: mode_stmt
::=
MODE
int_const_expr
referenced by:
EBNF: message_stmt
BNF: message_stmt
referenced by:
EBNF: message_type
::=
INFO
|
WARNING
|
ERROR
BNF: message_type
::=
INFO
|
WARNING
|
ERROR
no references
referenced by:
referenced by:
EBNF: encrypt_stmt
BNF: encrypt_stmt
referenced by:
EBNF: enable_stmt
BNF: enable_stmt
referenced by:
EBNF: reset_stmt
::=
RESET
BNF: reset_stmt
::=
RESET
referenced by:
EBNF: const_expr
::=
STRING_LITERAL
BNF: const_expr
::=
STRING_LITERAL
referenced by:
EBNF: int_const_expr
::=
expr
BNF: int_const_expr
::=
expr
referenced by:
- address_or_range
- bool_expr
- call_arg
- call_target
- enable_stmt
- encrypt_stmt
- jump_sp_stmt
- keyblob_block
- load_data
- load_ifr_stmt
- mode_stmt
- section_block
- source_value
EBNF: bool_expr
referenced by:
BNF: expr
|
'(' expr ')'
|
IDENT
|
SIZEOF '(' SYMBOL_REF ')'
referenced by:
EBNF: unary_expr
::= ( '+' | '-' ) expr
BNF: unary_expr
::=
'+' expr
|
'-' expr
referenced by:
|
|
|