elftosb::EncoreBootImage Class Reference

Class to manage Encore boot image files. More...

`#include <EncoreBootImage.h>`

Inheritance diagram for elftosb::EncoreBootImage:
[legend]
Collaboration diagram for elftosb::EncoreBootImage:
[legend]

## 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.

## Detailed Description

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:

- Header
- Section table
- Key dictionary
- Section data
- Authentication

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.

## Class Documentation

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.

Class Members
uint32_t | m_address | Target address.
uint8_t | m_checksum | Simple checksum over other command fields.
uint32_t | m_count | Number of bytes on which to operate.
uint32_t | m_data | Additional data used by certain commands.
uint16_t | m_flags | Flags for this command.
uint8_t | m_tag | Tag telling which command this is.

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:
[legend]

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__

Class Members
uint8_t | m_extra[4] | The leftover top four bytes of the SHA-1 digest.
cipher_block_t | m_iv | The first 16 bytes of the digest form the initialization vector.

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:
[legend]

Class Members
dek_dictionary_entry_t | m_entries[1] |

struct elftosb::EncoreBootImage::section_header_t

Information about each section, held in the section table.

See also
  section_table_t

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:
[legend]

Class Members
section_header_t | m_sections[1] | The table entries.

## Member Enumeration Documentation

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

Enumerator
BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT | Minimum alignment for a section is 16 bytes.

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

Memory Space ID flags field.

Enumerator
ROM_MEM_SPACE_MASK | Bit mask for mem space ID.
ROM_MEM_SPACE_SHIFT | Bit position of mem space ID.

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.

anonymous enum

Constants for Memory ID.

Enumerator
ROM_MEM_ID_QSPI | External QuadSpi controller.

anonymous enum

Constants for Memory Space.

Enumerator
ROM_MEM_SPACE_IFR | IFR memory.

## Member Function Documentation

void EncoreBootImage::addSection | ( | Section * | newSection | ) |

Exceptions

  std::runtime_error | Raised if newSection has the same tag as a previously added section.

EncoreBootImage::Section * EncoreBootImage::findFirstBootableSection | ( |  | ) |

protected

Scans the section list looking for the first section which has the ROM_SECTION_BOOTABLE flag set on it.

unsigned EncoreBootImage::getPadBlockCountForSection | ( | Section * | section,
|  | unsigned | offset
| ) |  |

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.

Note
  The offset will only be valid if all encryption keys and all sections have already been added to the image.

uint64_t EncoreBootImage::getTimestamp | ( |  | ) |

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.

Bug:
  The timestamp might be off an hour.

void EncoreBootImage::writeToStream | ( | std::ostream & | stream | ) |

virtual

Write the boot image to an output stream.

Implements elftosb::BootImage.

The documentation for this class was generated from the following files:

- EncoreBootImage.h
- EncoreBootImage.cpp