Kinetis Bootloader Host  2.0.0
Host Tools for Kinetis devices
elftosb::EncoreBootImage Class Reference

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< AES128Keykey_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 ()
 
SectionfindFirstBootableSection ()
 
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:

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:
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:
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:
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_errorRaised 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: