![]() |
Kinetis Bootloader Host
2.0.0
Host Tools for Kinetis devices
|
Class to manage Encore boot image files. More...
#include <EncoreBootImage.h>
Inheritance diagram for elftosb::EncoreBootImage:
Collaboration diagram for elftosb::EncoreBootImage:Classes | |
| struct | boot_command_t |
| Structure for a Piano bootloader command. More... | |
| struct | boot_image_header_t |
| Header for the entire boot image. More... | |
| union | boot_image_header_t.__unnamed__ |
| struct | boot_image_header_t.__unnamed__.__unnamed__ |
| class | BootCommand |
| Abstract base class for all bootloader commands. More... | |
| class | BootSection |
| A bootable section of an Encore boot image. More... | |
| class | CallCommand |
| Call function bootloader command. More... | |
| class | CipherBlockGenerator |
| Base class for objects that produce cipher blocks. More... | |
| class | DataSection |
| A non-bootable section of an Encore boot image. More... | |
| struct | dek_dictionary_entry_t |
| Entry in elftosb::EncoreBootImage::dek_dictionary_t. More... | |
| struct | dek_dictionary_t |
| The DEK dictionary always follows the image header, in the next cipher block. More... | |
| class | EraseCommand |
| Erase bootloader command. More... | |
| class | FillCommand |
| Pattern fill bootloader command. More... | |
| class | JumpCommand |
| Jump to address bootloader command. More... | |
| class | LoadCommand |
| Load data bootloader command. More... | |
| class | MemEnableCommand |
| Memory Enable bootloader command. More... | |
| class | ModeCommand |
| Change boot mode bootloader command. More... | |
| class | NopCommand |
| No operation bootloader command. More... | |
| class | ProgramCommand |
| Program persistent bits bootloader command. More... | |
| class | ResetCommand |
| Reset target bootloader command. More... | |
| class | Section |
| Base class for a section of an Encore boot image. More... | |
| struct | section_header_t |
| Information about each section, held in the section table. More... | |
| struct | section_table_t |
| An index of all sections within the boot image. More... | |
| class | TagCommand |
| Section tag bootloader command. More... | |
Public Types | |
| enum | { ROM_DISPLAY_PROGRESS = (1 << 0), ROM_VERBOSE_PROGRESS = (1 << 1) } |
| Flag constants for the m_flags field of elftosb::EncoreBootImage::boot_image_header_t. More... | |
| enum | { ROM_IMAGE_HEADER_SIGNATURE, ROM_IMAGE_HEADER_SIGNATURE2, ROM_BOOT_IMAGE_MAJOR_VERSION = 1, ROM_BOOT_IMAGE_MINOR_VERSION = 2 } |
| enum | { BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT = sizeof(cipher_block_t) } |
| enum | { ROM_SECTION_BOOTABLE = (1 << 0), ROM_SECTION_CLEARTEXT } |
| Section flags constants for the m_flags field of elftosb::EncoreBootImage::section_header_t. More... | |
| enum | { ROM_NOP_CMD = 0x00, ROM_TAG_CMD = 0x01, ROM_LOAD_CMD = 0x02, ROM_FILL_CMD = 0x03, ROM_JUMP_CMD = 0x04, ROM_CALL_CMD = 0x05, ROM_MODE_CMD = 0x06, ROM_ERASE_CMD = 0x07, ROM_RESET_CMD = 0x08, ROM_MEM_ENABLE_CMD = 0x09, ROM_PROG_CMD = 0x0a } |
| Bootloader command tag constants. More... | |
| enum | { ROM_LAST_TAG = (1 << 0) } |
| Flag field constants for ROM_TAG_CMD. More... | |
| enum | { ROM_LOAD_DCD = (1 << 0) } |
| Flag field constants for ROM_LOAD_CMD. More... | |
| enum | { ROM_FILL_BYTE = 0, ROM_FILL_HALF_WORD = 1, ROM_FILL_WORD = 2 } |
| Flag field constants for ROM_FILL_CMD. More... | |
| enum | { ROM_HAB_EXEC = (1 << 0), ROM_JUMP_SP_MASK = (1 << 1) } |
| Flag field constants for ROM_JUMP_CMD and ROM_CALL_CMD. More... | |
| enum | { ROM_MEM_CTRL_MASK = 0x0f, ROM_MEM_CTRL_SHIFT = 8 } |
| Memory Controller ID flags field for ROM_ERASE_CMD and ROM_MEM_ENABLE_CMD. More... | |
| enum | { ROM_MEM_SPACE_MASK = 0x0f, ROM_MEM_SPACE_SHIFT = 8 } |
| Memory Space ID flags field. More... | |
| enum | { ROM_ERASE_ALL_MASK = (1 << 0), ROM_ERASE_ALL_UNSECURE_MASK = (1 << 1) } |
| Flags for the ROM_ERASE_CMD. More... | |
| enum | { ROM_PROG_8BYTE_MASK = (1 << 0) } |
| Flags for the ROM_PROG_CMD. More... | |
| enum | { ROM_MEM_ID_QSPI = 1 } |
| Constants for Memory ID. More... | |
| enum | { ROM_MEM_SPACE_IFR = 4 } |
| Constants for Memory Space. More... | |
| typedef std::list< Section * > | section_list_t |
| List of image sections. | |
| typedef section_list_t::iterator | section_iterator_t |
| Iterator over sections. | |
| typedef section_list_t::const_iterator | const_section_iterator_t |
| Const iterator over sections. | |
| typedef std::vector< AES128Key > | key_list_t |
| List of KEKs. | |
| typedef key_list_t::iterator | key_iterator_t |
| Iterator over KEKs. | |
| typedef key_list_t::const_iterator | const_key_iterator_t |
| Const iterator over KEKs. | |
Public Member Functions | |
| EncoreBootImage () | |
| Default constructor. | |
| virtual | ~EncoreBootImage () |
| Destructor. | |
| virtual void | setDriveTag (uint16_t tag) |
| Specify the drive tag to be set in the output file header. | |
| uint32_t | getImageSize () |
| Calculates the total number of cipher blocks the image consumes. | |
| virtual std::string | getFileExtension () const |
| Returns the preferred ".sb" extension for Encore boot images. | |
| virtual void | debugPrint () const |
| Print out a string representation of the object. | |
Sections | |
| void | addSection (Section *newSection) |
| unsigned | sectionCount () const |
| section_iterator_t | beginSection () |
| section_iterator_t | endSection () |
| const_section_iterator_t | beginSection () const |
| const_section_iterator_t | endSection () const |
| section_iterator_t | findSection (Section *section) |
| uint32_t | getSectionOffset (Section *section) |
| Calculates the starting block number for the given section. More... | |
Encryption keys | |
| void | addKey (const AES128Key &newKey) |
| unsigned | keyCount () const |
| key_iterator_t | beginKeys () |
| key_iterator_t | endKeys () |
| const_key_iterator_t | beginKeys () const |
| const_key_iterator_t | endKeys () const |
| bool | isEncrypted () const |
| The image is encrypted if there is at least one key. | |
Versions | |
| virtual void | setProductVersion (const version_t &version) |
| virtual void | setComponentVersion (const version_t &version) |
Flags | |
| void | setFlags (uint16_t flags) |
| uint32_t | getFlags () const |
Output | |
| virtual void | writeToStream (std::ostream &stream) |
| Write the boot image to an output stream. More... | |
Public Member Functions inherited from elftosb::BootImage | |
| BootImage () | |
| Constructor. | |
| virtual | ~BootImage () |
| Destructor. | |
Protected Member Functions | |
| void | prepareImageHeader (boot_image_header_t &header) |
| uint64_t | getTimestamp () |
| Section * | findFirstBootableSection () |
| unsigned | getPadBlockCountForSection (Section *section, unsigned offset) |
Protected Attributes | |
| uint16_t | m_headerFlags |
| Flags field in the boot image header. | |
| version_t | m_productVersion |
| Product version. | |
| version_t | m_componentVersion |
| Component version. | |
| uint16_t | m_driveTag |
| System drive tag for this boot image. | |
| section_list_t | m_sections |
| Sections contained in this image. | |
| key_list_t | m_keys |
| List of key encryption keys. If empty, the image is unencrypted. | |
| AES128Key | m_sessionKey |
| Session key we're using. | |
Class to manage Encore boot image files.
Initially this class will only support generation of boot images, but its design will facilitate the addition of the ability to read an image and examine its contents.
A boot image is composed of the following regions:
Multiple sections are within a boot image are fully supported. Two general types of sections are supported with this class. Bootable sections, represented by the EncoreBootImage::BootSection class, contain a sequence of commands to be interpreted by the boot ROM. Data sections are represented by the EncoreBootImage::DataSection class and can contain any arbitrary data.
An image can either be encrypted or unencrypted. The image uses a session key, or DEK (data encryption key), and the key dictionary to support any number of keys using a single image. The header and section table are always unencrypted even in encrypted images. This allows host utilities to access the individual sections without needing to have access to an encryption key.
To construct a boot image, first create an instance of EncoreBootImage. Then create instances of the EncoreBootImage::BootSection or EncoreBootImage::DataSection for each of the sections in the image. For bootable sections, create and add the desired boot command objects. These are all subclasses of EncoreBootImage::BootCommand.
If the boot image is to be encrypted, you need to add keys, which are instances of the AES128Key class. If no keys are added, the entire boot image will be unencrypted.
When the image is fully constructed, it can be written to any std::ostream with a call to writeToStream(). The same image can be written to streams any number of times.
| struct elftosb::EncoreBootImage::boot_command_t |
Structure for a Piano bootloader command.
Each command is composed of a fixed length header of 16 bytes. This happens to be the size of a cipher block. Most commands will only require the header.
But some commands, i.e. the "load data" command, may require additional arbitrary amounts of data. This data is packed into the N cipher blocks that immediately follow the command header. If the length of the data is not divisible by 16, then random (not zero!) pad bytes will be added.
| struct elftosb::EncoreBootImage::boot_image_header_t |
Header for the entire boot image.
Fields of this header are arranged so that those used by the bootloader ROM all come first. They are also set up so that all fields are not split across cipher block boundaries. The fields not used by the bootloader are not subject to this restraint.
Image header size is always a round number of cipher blocks. The same also applies to the boot image itself. The padding, held in elftosb::EncoreBootImage::boot_image_header_t::m_padding0 and elftosb::EncoreBootImage::boot_image_header_t::m_padding1 is filled with random bytes.
The DEK dictionary, section table, and each section data region must all start on cipher block boundaries.
This header is not encrypted in the image file.
The m_digest field contains a SHA-1 digest of the fields of the header that follow it. It is the first field in the header so it doesn't change position or split the header in two if fields are added to the header.
Collaboration diagram for elftosb::EncoreBootImage::boot_image_header_t:| Class Members | ||
|---|---|---|
| union boot_image_header_t | __unnamed__ | |
| version_t | m_componentVersion | Component version. |
| uint16_t | m_driveTag | Drive tag for the system drive which this boot image belongs to. |
| section_id_t | m_firstBootableSectionID | ID of section to start booting from. |
| uint32_t | m_firstBootTagBlock | Offset from start of file to the first boot tag, in blocks. |
| uint16_t | m_flags | Flags or options associated with the entire image. |
| uint16_t | m_headerBlocks | Size of this header, including this size word, in blocks. |
| uint32_t | m_imageBlocks | Size of entire image in blocks. |
| uint16_t | m_keyCount | Number of entries in DEK dictionary. |
| uint16_t | m_keyDictionaryBlock | Starting block number for the key dictionary. |
| uint8_t | m_majorVersion | Major version for the image format, see ROM_BOOT_IMAGE_MAJOR_VERSION. |
| uint8_t | m_minorVersion | Minor version of the boot image format, see ROM_BOOT_IMAGE_MINOR_VERSION. |
| uint8_t | m_padding0[2] | Padding to align m_timestamp to long word. |
| uint8_t | m_padding1[6] | Padding to round up to next cipher block. |
| version_t | m_productVersion | Product version. |
| uint16_t | m_sectionCount | Number of section headers in this table. |
| uint16_t | m_sectionHeaderSize | Size in blocks of a section header. |
| uint8_t | m_signature[4] | 'STMP', see ROM_IMAGE_HEADER_SIGNATURE. |
| uint8_t | m_signature2[4] |
Second signature to distinguish this .sb format from the 36xx format, see ROM_IMAGE_HEADER_SIGNATURE2. |
| uint64_t | m_timestamp | Timestamp when image was generated in microseconds since 1-1-2000. |
| union elftosb::EncoreBootImage::boot_image_header_t.__unnamed__ |
| Class Members | ||
|---|---|---|
| __unnamed__ | __unnamed__ | |
| sha1_digest_t | m_digest | SHA-1 digest of image header. Also used as the crypto IV. |
| struct elftosb::EncoreBootImage::boot_image_header_t.__unnamed__.__unnamed__ |
| struct elftosb::EncoreBootImage::dek_dictionary_entry_t |
Entry in elftosb::EncoreBootImage::dek_dictionary_t.
The m_dek field in each entry is encrypted using the KEK with the m_iv field from the image header as the IV.
| Class Members | ||
|---|---|---|
| aes128_key_t | m_dek | AES-128 key with which the image payload is encrypted. |
| cipher_block_t | m_mac | CBC-MAC of the header. |
| struct elftosb::EncoreBootImage::dek_dictionary_t |
The DEK dictionary always follows the image header, in the next cipher block.
Collaboration diagram for elftosb::EncoreBootImage::dek_dictionary_t:| Class Members | ||
|---|---|---|
| dek_dictionary_entry_t | m_entries[1] | |
| struct elftosb::EncoreBootImage::section_header_t |
Information about each section, held in the section table.
| Class Members | ||
|---|---|---|
| uint32_t | m_flags | Section flags. |
| uint32_t | m_length | Size of section data in blocks. |
| uint32_t | m_offset | Offset to section data from start of image in blocks. |
| uint32_t | m_tag | Unique identifier for this section. High bit must be zero. |
| struct elftosb::EncoreBootImage::section_table_t |
An index of all sections within the boot image.
The section table will be padded so that its length is divisible by 16 (if necessary). Actually, each entry is padded to be a round number of cipher blocks, which automatically makes this true for the entire table.
Sections are ordered as they appear in this table, but are identified by the elftosb::EncoreBootImage::section_header_t::m_tag.
The data for each section in encrypted separately with the DEK in CBC mode using m_iv for the IV. This allows the ROM to jump to any given section without needing to read the previous cipher block. In addition, the data for each section is prefixed with a "boot tag", which describes the section which follows it. Boot tags are the same format as a boot command, and are described by the EncoreBootImage::TagCommand class.
The section table starts immediately after the image header, coming before the key dictionary (if present). The section table is not encrypted.
Collaboration diagram for elftosb::EncoreBootImage::section_table_t:| Class Members | ||
|---|---|---|
| section_header_t | m_sections[1] | The table entries. |
| anonymous enum |
Flag constants for the m_flags field of elftosb::EncoreBootImage::boot_image_header_t.
| Enumerator | |
|---|---|
| ROM_DISPLAY_PROGRESS |
Print progress reports. |
| ROM_VERBOSE_PROGRESS |
Progress reports are verbose. |
| anonymous enum |
| Enumerator | |
|---|---|
| ROM_IMAGE_HEADER_SIGNATURE |
Signature in elftosb::EncoreBootImage::boot_image_header_t::m_signature. |
| ROM_IMAGE_HEADER_SIGNATURE2 |
Value for elftosb::EncoreBootImage::boot_image_header_t::m_signature2;. |
| ROM_BOOT_IMAGE_MAJOR_VERSION |
Current boot image major version. |
| ROM_BOOT_IMAGE_MINOR_VERSION |
Current boot image minor version. |
| anonymous enum |
| anonymous enum |
Section flags constants for the m_flags field of elftosb::EncoreBootImage::section_header_t.
| Enumerator | |
|---|---|
| ROM_SECTION_BOOTABLE |
The section contains bootloader commands. |
| ROM_SECTION_CLEARTEXT |
The section is unencrypted. Applies only if the rest of the boot image is encrypted. |
| anonymous enum |
Bootloader command tag constants.
| Enumerator | |
|---|---|
| ROM_NOP_CMD |
A no-op command. |
| ROM_TAG_CMD |
Section tag command. |
| ROM_LOAD_CMD |
Load data command. |
| ROM_FILL_CMD |
Pattern fill command. |
| ROM_JUMP_CMD |
Jump to address command. |
| ROM_CALL_CMD |
Call function command. |
| ROM_MODE_CMD |
Change boot mode command. |
| ROM_ERASE_CMD |
Flash erase command. |
| ROM_RESET_CMD |
Reset command. |
| ROM_MEM_ENABLE_CMD |
Memory Enable command. |
| ROM_PROG_CMD |
Program persistent bits command. |
| anonymous enum |
Flag field constants for ROM_TAG_CMD.
| Enumerator | |
|---|---|
| ROM_LAST_TAG |
This tag command is the last one in the image. |
| anonymous enum |
Flag field constants for ROM_LOAD_CMD.
| Enumerator | |
|---|---|
| ROM_LOAD_DCD |
Execute the DCD after loading completes. |
| anonymous enum |
Flag field constants for ROM_FILL_CMD.
| Enumerator | |
|---|---|
| ROM_FILL_BYTE |
Fill with byte sized pattern. |
| ROM_FILL_HALF_WORD |
Fill with half-word sized pattern. |
| ROM_FILL_WORD |
Fill with word sized pattern. |
| anonymous enum |
Flag field constants for ROM_JUMP_CMD and ROM_CALL_CMD.
| Enumerator | |
|---|---|
| ROM_HAB_EXEC |
Changes jump or call command to a HAB jump or call. |
| ROM_JUMP_SP_MASK |
Initial stack pointer is specified for jump command. |
| anonymous enum |
Memory Controller ID flags field for ROM_ERASE_CMD and ROM_MEM_ENABLE_CMD.
| Enumerator | |
|---|---|
| ROM_MEM_CTRL_MASK |
Bit mask for mem controller ID. |
| ROM_MEM_CTRL_SHIFT |
Bit position of mem controller ID. |
| anonymous enum |
| anonymous enum |
Flags for the ROM_ERASE_CMD.
| Enumerator | |
|---|---|
| ROM_ERASE_ALL_MASK |
Erase all flash instead of just a range. |
| ROM_ERASE_ALL_UNSECURE_MASK |
Erase all unsecure (available on some Kinetis parts). |
| anonymous enum |
Flags for the ROM_PROG_CMD.
| Enumerator | |
|---|---|
| ROM_PROG_8BYTE_MASK |
Program 8 bytes instead of 4 bytes. |
| void EncoreBootImage::addSection | ( | Section * | newSection | ) |
| std::runtime_error | Raised if newSection has the same tag as a previously added section. |
|
protected |
Scans the section list looking for the first section which has the ROM_SECTION_BOOTABLE flag set on it.
|
protected |
Computes the number of blocks of padding required to align section while taking into account the boot tag that gets inserted before the section contents.
| uint32_t EncoreBootImage::getSectionOffset | ( | Section * | section | ) |
Calculates the starting block number for the given section.
The boot tag for section is taken into account, thus making the result offset point to the first block of the actual section data.
|
protected |
Returns the number of microseconds since 00:00 1-1-2000. In actuality, the timestamp is only accurate to seconds, and is simply extended out to microseconds.
|
virtual |
Write the boot image to an output stream.
Implements elftosb::BootImage.