1 /* 2 * File: EncoreBootImage.h 3 * 4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 * See included license file for license details. 6 */ 7 #if !defined(_EncoreBootImage_h_) 8 #define _EncoreBootImage_h_ 9 10 #include <list> 11 #include <vector> 12 #include <string> 13 #include <iostream> 14 #include <fstream> 15 #include <string.h> 16 #include "BootImage.h" 17 #include "rijndael.h" 18 #include "smart_ptr.h" 19 #include "AESKey.h" 20 #include "StExecutableImage.h" 21 22 namespace elftosb 23 { 24 25 //! An AES-128 cipher block is 16 bytes. 26 typedef uint8_t cipher_block_t[16]; 27 28 //! A SHA-1 digest is 160 bits, or 20 bytes. 29 typedef uint8_t sha1_digest_t[20]; 30 31 //! Unique identifier type for a section. 32 typedef uint32_t section_id_t; 33 34 //! Utility to return the byte length of a number of cipher blocks. 35 inline size_t sizeOfCipherBlocks(unsigned count) { return sizeof(cipher_block_t) * count; } 36 37 //! Utility to return the number of cipher blocks required to hold an object 38 //! that is \a s bytes long. 39 inline size_t numberOfCipherBlocks(size_t s) { return (s + sizeof(cipher_block_t) - 1) / sizeof(cipher_block_t); } 40 41 //! Utility to calculate the byte length for the cipher blocks required to hold 42 //! and object that is \a bytes long. 43 inline size_t sizeInCipherBlocks(size_t s) { return (unsigned)sizeOfCipherBlocks(numberOfCipherBlocks(s)); } 44 45 //! Utility to return the number of bytes of padding required to fill out 46 //! the last cipher block in a set of cipher blocks large enough to hold 47 //! an object that is \a s bytes large. The result may be 0 if \a s is 48 //! an even multiple of the cipher block size. 49 inline size_t sizeOfPaddingForCipherBlocks(size_t s) { return sizeInCipherBlocks(s) - s; } 50 51 /*! 52 * \brief Class to manage Encore boot image files. 53 * 54 * Initially this class will only support generation of boot images, but 55 * its design will facilitate the addition of the ability to read an 56 * image and examine its contents. 57 * 58 * A boot image is composed of the following regions: 59 * - Header 60 * - Section table 61 * - Key dictionary 62 * - Section data 63 * - Authentication 64 * 65 * Multiple sections are within a boot image are fully supported. Two general types 66 * of sections are supported with this class. Bootable sections, represented by the 67 * EncoreBootImage::BootSection class, contain a sequence of commands to be 68 * interpreted by the boot ROM. Data sections are represented by the 69 * EncoreBootImage::DataSection class and can contain any arbitrary data. 70 * 71 * An image can either be encrypted or unencrypted. The image uses a session key, 72 * or DEK (data encryption key), and the key dictionary to support any number of keys 73 * using a single image. The header and section table are always unencrypted even 74 * in encrypted images. This allows host utilities to access the individual 75 * sections without needing to have access to an encryption key. 76 * 77 * To construct a boot image, first create an instance of EncoreBootImage. Then 78 * create instances of the EncoreBootImage::BootSection or EncoreBootImage::DataSection 79 * for each of the sections in the image. For bootable sections, create and add 80 * the desired boot command objects. These are all subclasses of 81 * EncoreBootImage::BootCommand. 82 * 83 * If the boot image is to be encrypted, you need to add keys, which are instances 84 * of the AES128Key class. If no keys are added, the entire boot image will be unencrypted. 85 * 86 * When the image is fully constructed, it can be written to any std::ostream with 87 * a call to writeToStream(). The same image can be written to streams any 88 * number of times. 89 */ 90 class EncoreBootImage : public BootImage 91 { 92 public: 93 //! \brief Flag constants for the m_flags field of #elftosb::EncoreBootImage::boot_image_header_t. 94 enum 95 { 96 ROM_DISPLAY_PROGRESS = (1 << 0), //!< Print progress reports. 97 ROM_VERBOSE_PROGRESS = (1 << 1) //!< Progress reports are verbose. 98 }; 99 100 #define ROM_IMAGE_HEADER_SIGNATURE "STMP" //!< Signature in #elftosb::EncoreBootImage::boot_image_header_t::m_signature. 101 #define ROM_IMAGE_HEADER_SIGNATURE2 "sgtl" //!< Value for #elftosb::EncoreBootImage::boot_image_header_t::m_signature2; 102 #define ROM_BOOT_IMAGE_MAJOR_VERSION 1 //!< Current boot image major version. 103 #define ROM_BOOT_IMAGE_MINOR_VERSION 1 //!< Current boot image minor version. 104 105 enum { 106 //! Minimum alignment for a section is 16 bytes. 107 BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT = sizeof(cipher_block_t) 108 }; 109 110 // All of these structures are packed to byte alignment in order to match 111 // the structure on disk. 112 #pragma pack(1) 113 114 //! \brief Header for the entire boot image. 115 //! 116 //! Fields of this header are arranged so that those used by the bootloader ROM all come 117 //! first. They are also set up so that all fields are not split across cipher block 118 //! boundaries. The fields not used by the bootloader are not subject to this 119 //! restraint. 120 //! 121 //! Image header size is always a round number of cipher blocks. The same also applies to 122 //! the boot image itself. The padding, held in #elftosb::EncoreBootImage::boot_image_header_t::m_padding0 123 //! and #elftosb::EncoreBootImage::boot_image_header_t::m_padding1 is filled with random bytes. 124 //! 125 //! The DEK dictionary, section table, and each section data region must all start on 126 //! cipher block boundaries. 127 //! 128 //! This header is not encrypted in the image file. 129 //! 130 //! The m_digest field contains a SHA-1 digest of the fields of the header that follow it. 131 //! It is the first field in the header so it doesn't change position or split the header 132 //! in two if fields are added to the header. 133 struct boot_image_header_t 134 { 135 union 136 { 137 sha1_digest_t m_digest; //!< SHA-1 digest of image header. Also used as the crypto IV. 138 struct 139 { 140 cipher_block_t m_iv; //!< The first 16 bytes of the digest form the initialization vector. 141 uint8_t m_extra[4]; //!< The leftover top four bytes of the SHA-1 digest. 142 }; 143 }; 144 uint8_t m_signature[4]; //!< 'STMP', see #ROM_IMAGE_HEADER_SIGNATURE. 145 uint8_t m_majorVersion; //!< Major version for the image format, see #ROM_BOOT_IMAGE_MAJOR_VERSION. 146 uint8_t m_minorVersion; //!< Minor version of the boot image format, see #ROM_BOOT_IMAGE_MINOR_VERSION. 147 uint16_t m_flags; //!< Flags or options associated with the entire image. 148 uint32_t m_imageBlocks; //!< Size of entire image in blocks. 149 uint32_t m_firstBootTagBlock; //!< Offset from start of file to the first boot tag, in blocks. 150 section_id_t m_firstBootableSectionID; //!< ID of section to start booting from. 151 uint16_t m_keyCount; //!< Number of entries in DEK dictionary. 152 uint16_t m_keyDictionaryBlock; //!< Starting block number for the key dictionary. 153 uint16_t m_headerBlocks; //!< Size of this header, including this size word, in blocks. 154 uint16_t m_sectionCount; //!< Number of section headers in this table. 155 uint16_t m_sectionHeaderSize; //!< Size in blocks of a section header. 156 uint8_t m_padding0[2]; //!< Padding to align #m_timestamp to long word. 157 uint8_t m_signature2[4]; //!< Second signature to distinguish this .sb format from the 36xx format, see #ROM_IMAGE_HEADER_SIGNATURE2. 158 uint64_t m_timestamp; //!< Timestamp when image was generated in microseconds since 1-1-2000. 159 version_t m_productVersion; //!< Product version. 160 version_t m_componentVersion; //!< Component version. 161 uint16_t m_driveTag; //!< Drive tag for the system drive which this boot image belongs to. 162 uint8_t m_padding1[6]; //!< Padding to round up to next cipher block. 163 }; 164 165 //! \brief Entry in #elftosb::EncoreBootImage::dek_dictionary_t. 166 //! 167 //! The m_dek field in each entry is encrypted using the KEK with the m_iv field from 168 //! the image header as the IV. 169 struct dek_dictionary_entry_t 170 { 171 cipher_block_t m_mac; //!< CBC-MAC of the header. 172 aes128_key_t m_dek; //!< AES-128 key with which the image payload is encrypted. 173 }; 174 175 //! \brief The DEK dictionary always follows the image header, in the next cipher block. 176 struct dek_dictionary_t 177 { 178 dek_dictionary_entry_t m_entries[1]; 179 }; 180 181 //! \brief Section flags constants for the m_flags field of #elftosb::EncoreBootImage::section_header_t. 182 enum 183 { 184 ROM_SECTION_BOOTABLE = (1 << 0), //!< The section contains bootloader commands. 185 ROM_SECTION_CLEARTEXT = (1 << 1) //!< The section is unencrypted. Applies only if the rest of the boot image is encrypted. 186 }; 187 188 //! \brief Information about each section, held in the section table. 189 //! \see section_table_t 190 struct section_header_t 191 { 192 uint32_t m_tag; //!< Unique identifier for this section. High bit must be zero. 193 uint32_t m_offset; //!< Offset to section data from start of image in blocks. 194 uint32_t m_length; //!< Size of section data in blocks. 195 uint32_t m_flags; //!< Section flags. 196 }; 197 198 //! \brief An index of all sections within the boot image. 199 //! 200 //! The section table will be padded so that its length is divisible by 16 (if necessary). 201 //! Actually, each entry is padded to be a round number of cipher blocks, which 202 //! automatically makes this true for the entire table. 203 //! 204 //! Sections are ordered as they appear in this table, but are identified by the 205 //! #elftosb::EncoreBootImage::section_header_t::m_tag. 206 //! 207 //! The data for each section in encrypted separately with the DEK in CBC mode using 208 //! m_iv for the IV. This allows the ROM to jump to any given section without needing 209 //! to read the previous cipher block. In addition, the data for each section is 210 //! prefixed with a "boot tag", which describes the section which follows it. Boot 211 //! tags are the same format as a boot command, and are described by the 212 //! EncoreBootImage::TagCommand class. 213 //! 214 //! The section table starts immediately after the image header, coming before the 215 //! key dictionary (if present). The section table is not encrypted. 216 struct section_table_t 217 { 218 section_header_t m_sections[1]; //!< The table entries. 219 }; 220 221 //! \brief Structure for a Piano bootloader command. 222 //! 223 //! Each command is composed of a fixed length header of 16 bytes. This happens to be 224 //! the size of a cipher block. Most commands will only require the header. 225 //! 226 //! But some commands, i.e. the "load data" command, may require additional arbitrary 227 //! amounts of data. This data is packed into the N cipher blocks that immediately 228 //! follow the command header. If the length of the data is not divisible by 16, then 229 //! random (not zero!) pad bytes will be added. 230 struct boot_command_t 231 { 232 uint8_t m_checksum; //!< Simple checksum over other command fields. 233 uint8_t m_tag; //!< Tag telling which command this is. 234 uint16_t m_flags; //!< Flags for this command. 235 uint32_t m_address; //!< Target address. 236 uint32_t m_count; //!< Number of bytes on which to operate. 237 uint32_t m_data; //!< Additional data used by certain commands. 238 }; 239 240 #pragma pack() 241 242 //! \brief Bootloader command tag constants. 243 enum 244 { 245 ROM_NOP_CMD = 0x00, //!< A no-op command. 246 ROM_TAG_CMD = 0x01, //!< Section tag command. 247 ROM_LOAD_CMD = 0x02, //!< Load data command. 248 ROM_FILL_CMD = 0x03, //!< Pattern fill command. 249 ROM_JUMP_CMD = 0x04, //!< Jump to address command. 250 ROM_CALL_CMD = 0x05, //!< Call function command. 251 ROM_MODE_CMD = 0x06 //!< Change boot mode command. 252 }; 253 254 //! \brief Flag field constants for #ROM_TAG_CMD. 255 enum 256 { 257 ROM_LAST_TAG = (1 << 0) //!< This tag command is the last one in the image. 258 }; 259 260 //! \brief Flag field constants for #ROM_LOAD_CMD. 261 enum 262 { 263 ROM_LOAD_DCD = (1 << 0) //!< Execute the DCD after loading completes. 264 }; 265 266 //! \brief Flag field constants for #ROM_FILL_CMD. 267 enum 268 { 269 ROM_FILL_BYTE = 0, //!< Fill with byte sized pattern. 270 ROM_FILL_HALF_WORD = 1, //!< Fill with half-word sized pattern. 271 ROM_FILL_WORD = 2 //!< Fill with word sized pattern. 272 }; 273 274 //! brief Flag field constants for #ROM_JUMP_CMD and #ROM_CALL_CMD. 275 enum 276 { 277 ROM_HAB_EXEC = (1 << 0) //!< Changes jump or call command to a HAB jump or call. 278 }; 279 280 public: 281 // Forward declaration. 282 class Section; 283 284 /*! 285 * \brief Base class for objects that produce cipher blocks. 286 */ 287 class CipherBlockGenerator 288 { 289 public: 290 291 //! \name Cipher blocks 292 //@{ 293 //! \brief Returns the total number of cipher blocks. 294 //! 295 //! The default implementation returns 0, indicating that no blocks are 296 //! available. 297 virtual unsigned getBlockCount() const { return 0; } 298 299 //! \brief Returns the contents of up to \a maxCount cipher blocks. 300 //! 301 //! Up to \a maxCount cipher blocks are copied into the buffer pointed to by 302 //! the \a data argument. This is only a request for \a maxCount blocks, 303 //! the subclass implementation of this method is free to return any number 304 //! of blocks from 0 up to \a maxCount. A return value of 0 indicates that 305 //! no more blocks are available. The index of the first block to copy is 306 //! held in the \a offset argument. 307 //! 308 //! \param offset Starting block number to copy. Zero means the first available block. 309 //! \param maxCount Up to this number of blocks may be copied into \a data. Must be 1 or greater. 310 //! \param data Buffer for outgoing cipher blocks. Must have enough room to hold 311 //! \a maxCount blocks. 312 //! 313 //! \return The number of cipher blocks copied into \a data. 314 //! \retval 0 No more blocks are available and nothing was written to \a data. 315 virtual unsigned getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data) { return 0; } 316 //@} 317 318 //! \brief Print out a string representation of the object. 319 virtual void debugPrint() const {} 320 }; 321 322 /*! 323 * \brief Abstract base class for all bootloader commands. 324 */ 325 class BootCommand : public CipherBlockGenerator 326 { 327 public: 328 //! \brief Creates the correct subclass of BootCommand for the given raw data. 329 static BootCommand * createFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed); 330 331 public: 332 //! \brief Default constructor. 333 BootCommand() : CipherBlockGenerator() {} 334 335 //! \brief Destructor. 336 virtual ~BootCommand() {} 337 338 //! \brief Read the command contents from raw data. 339 //! 340 //! The subclass implementations should validate the contents of the command, including 341 //! the fields of the command header in the first block. It should be assumed that 342 //! only the tag field was examined to determine which subclass of BootCommand 343 //! should be created. 344 //! 345 //! \param blocks Pointer to the raw data blocks. 346 //! \param count Number of blocks pointed to by \a blocks. 347 //! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied 348 //! by the command. Should be at least 1 for every command. This must not be NULL 349 //! on entry! 350 virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)=0; 351 352 //! \name Header 353 //@{ 354 //! \brief Pure virtual method to return the tag value for this command. 355 virtual uint8_t getTag() const = 0; 356 357 //! \brief Pure virtual method to construct the header for this boot command. 358 virtual void fillCommandHeader(boot_command_t & header) = 0; 359 360 //! \brief Calculates the checksum for the given command header. 361 virtual uint8_t calculateChecksum(const boot_command_t & header); 362 //@} 363 364 //! \name Cipher blocks 365 //@{ 366 //! \brief Returns the total number of cipher blocks. 367 virtual unsigned getBlockCount() const; 368 369 //! \brief Returns the contents of up to \a maxCount cipher blocks. 370 virtual unsigned getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data); 371 //@} 372 373 //! \name Data blocks 374 //@{ 375 //! \brief Returns the number of data cipher blocks that follow this command. 376 //! 377 //! The default implementation returns 0, indicating that no data blocks are 378 //! available. 379 virtual unsigned getDataBlockCount() const { return 0; } 380 381 //! \brief Returns the contents of up to \a maxCount data blocks. 382 //! 383 //! Up to \a maxCount data blocks are copied into the buffer pointed to by 384 //! the \a data argument. This is only a request for \a maxCount blocks, 385 //! the subclass implementation of this method is free to return any number 386 //! of blocks from 0 up to \a maxCount. A return value of 0 indicates that 387 //! no more blocks are available. The index of the first block to copy is 388 //! held in the \a offset argument. 389 //! 390 //! \param offset Starting block number to copy. Zero means the first available block. 391 //! \param maxCount Up to this number of blocks may be copied into \a data. Must be 1 or greater. 392 //! \param data Buffer for outgoing data blocks. Must have enough room to hold 393 //! \a maxCount blocks. 394 //! 395 //! \return The number of data blocks copied into \a data. 396 //! \retval 0 No more blocks are available and nothing was written to \a data. 397 virtual unsigned getDataBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data) { return 0; } 398 //@} 399 400 protected: 401 //! The flag bit values for the \a whichFields parameter of validateHeader(). 402 enum 403 { 404 CMD_TAG_FIELD = 1, 405 CMD_FLAGS_FIELD = 2, 406 CMD_ADDRESS_FIELD = 4, 407 CMD_COUNT_FIELD = 8, 408 CMD_DATA_FIELD = 16 409 }; 410 411 //! \brief 412 void validateHeader(const boot_command_t * modelHeader, const boot_command_t * testHeader, unsigned whichFields); 413 }; 414 415 /*! 416 * \brief No operation bootloader command. 417 */ 418 class NopCommand : public BootCommand 419 { 420 public: 421 //! \brief Default constructor. 422 NopCommand() : BootCommand() {} 423 424 //! \brief Read the command contents from raw data. 425 virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed); 426 427 //! \name Header 428 //@{ 429 //! \brief Returns the tag value for this command. 430 virtual uint8_t getTag() const { return ROM_NOP_CMD; } 431 432 //! \brief Constructs the header for this boot command. 433 virtual void fillCommandHeader(boot_command_t & header); 434 //@} 435 436 //! \brief Print out a string representation of the object. 437 virtual void debugPrint() const; 438 }; 439 440 /*! 441 * \brief Section tag bootloader command. 442 */ 443 class TagCommand : public BootCommand 444 { 445 public: 446 //! \brief Default constructor. 447 TagCommand() : BootCommand() {} 448 449 //! \brief Constructor taking a section object. 450 TagCommand(const Section & section); 451 452 //! \brief Read the command contents from raw data. 453 virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed); 454 455 //! \name Header 456 //@{ 457 //! \brief Returns the tag value for this command. 458 virtual uint8_t getTag() const { return ROM_TAG_CMD; } 459 460 //! \brief Constructs the header for this boot command. 461 virtual void fillCommandHeader(boot_command_t & header); 462 //@} 463 464 //! \name Field accessors 465 //@{ 466 inline void setSectionIdentifier(uint32_t identifier) { m_sectionIdentifier = identifier; } 467 inline void setSectionLength(uint32_t length) { m_sectionLength = length; } 468 inline void setSectionFlags(uint32_t flags) { m_sectionFlags = flags; } 469 inline void setLast(bool isLast) { m_isLast = isLast; } 470 //@} 471 472 //! \brief Print out a string representation of the object. 473 virtual void debugPrint() const; 474 475 protected: 476 uint32_t m_sectionIdentifier; //!< Unique identifier for the section containing this command. 477 uint32_t m_sectionLength; //!< Number of cipher blocks this section occupies. 478 uint32_t m_sectionFlags; //!< Flags pertaining to this section. 479 bool m_isLast; //!< Is this the last tag command? 480 }; 481 482 /*! 483 * \brief Load data bootloader command. 484 */ 485 class LoadCommand : public BootCommand 486 { 487 public: 488 //! \brief Default constructor. 489 LoadCommand(); 490 491 //! \brief Constructor. 492 LoadCommand(uint32_t address, const uint8_t * data, uint32_t length); 493 494 //! \brief Read the command contents from raw data. 495 virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed); 496 497 //! \name Header 498 //@{ 499 //! \brief Returns the tag value for this command. 500 virtual uint8_t getTag() const { return ROM_LOAD_CMD; } 501 502 //! \brief Constructs the header for this boot command. 503 virtual void fillCommandHeader(boot_command_t & header); 504 505 //! \brief Sets the load-dcd flag. 506 inline void setDCD(bool isDCD) { m_loadDCD = isDCD; } 507 //@} 508 509 //! \name Address 510 //@{ 511 inline void setLoadAddress(uint32_t address) { m_address = address; } 512 inline uint32_t getLoadAddress() const { return m_address; } 513 //@} 514 515 //! \name Load data 516 //@{ 517 //! \brief Set the data for the command to load. 518 void setData(const uint8_t * data, uint32_t length); 519 520 inline uint8_t * getData() { return m_data; } 521 inline const uint8_t * getData() const { return m_data; } 522 inline uint32_t getLength() const { return m_length; } 523 //@} 524 525 //! \name Data blocks 526 //@{ 527 //! \brief Returns the number of data cipher blocks that follow this command. 528 virtual unsigned getDataBlockCount() const; 529 530 //! \brief Returns the contents of up to \a maxCount data blocks. 531 virtual unsigned getDataBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data); 532 //@} 533 534 //! \brief Print out a string representation of the object. 535 virtual void debugPrint() const; 536 537 protected: 538 smart_array_ptr<uint8_t> m_data; //!< Pointer to data to load. 539 uint8_t m_padding[15]; //!< Up to 15 pad bytes may be required. 540 unsigned m_padCount; //!< Number of pad bytes. 541 uint32_t m_length; //!< Number of bytes to load. 542 uint32_t m_address; //!< Address to which data will be loaded. 543 bool m_loadDCD; //!< Whether to execute the DCD after loading. 544 545 void fillPadding(); 546 uint32_t calculateCRC() const; 547 }; 548 549 /*! 550 * \brief Pattern fill bootloader command. 551 */ 552 class FillCommand : public BootCommand 553 { 554 public: 555 //! \brief Default constructor. 556 FillCommand(); 557 558 //! \brief Read the command contents from raw data. 559 virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed); 560 561 //! \name Header 562 //@{ 563 //! \brief Returns the tag value for this command. 564 virtual uint8_t getTag() const { return ROM_FILL_CMD; } 565 566 //! \brief Constructs the header for this boot command. 567 virtual void fillCommandHeader(boot_command_t & header); 568 //@} 569 570 //! \name Address range 571 //@{ 572 inline void setAddress(uint32_t address) { m_address = address; }; 573 inline uint32_t getAddress() const { return m_address; } 574 575 inline void setFillCount(uint32_t count) { m_count = count; } 576 inline uint32_t getFillCount() const { return m_count; } 577 //@} 578 579 //! \name Pattern 580 //@{ 581 void setPattern(uint8_t pattern); 582 void setPattern(uint16_t pattern); 583 void setPattern(uint32_t pattern); 584 585 inline uint32_t getPattern() const { return m_pattern; } 586 //@} 587 588 //! \brief Print out a string representation of the object. 589 virtual void debugPrint() const; 590 591 protected: 592 uint32_t m_address; //!< Fill start address. 593 uint32_t m_count; //!< Number of bytes to fill. 594 uint32_t m_pattern; //!< Fill pattern. 595 }; 596 597 /*! 598 * \brief Change boot mode bootloader command. 599 */ 600 class ModeCommand : public BootCommand 601 { 602 public: 603 //! \brief Default constructor. 604 ModeCommand() : BootCommand(), m_mode(0) {} 605 606 //! \brief Read the command contents from raw data. 607 virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed); 608 609 //! \name Header 610 //@{ 611 //! \brief Returns the tag value for this command. 612 virtual uint8_t getTag() const { return ROM_MODE_CMD; } 613 614 //! \brief Constructs the header for this boot command. 615 virtual void fillCommandHeader(boot_command_t & header); 616 //@} 617 618 //! \name Boot mode 619 //@{ 620 inline void setBootMode(uint32_t mode) { m_mode = mode; } 621 inline uint32_t getBootMode() const { return m_mode; } 622 //@} 623 624 //! \brief Print out a string representation of the object. 625 virtual void debugPrint() const; 626 627 protected: 628 uint32_t m_mode; //!< New boot mode. 629 }; 630 631 /*! 632 * \brief Jump to address bootloader command. 633 */ 634 class JumpCommand : public BootCommand 635 { 636 public: 637 //! \brief Default constructor. 638 JumpCommand() : BootCommand(), m_address(0), m_argument(0), m_isHAB(false), m_ivtSize(0) {} 639 640 //! \brief Read the command contents from raw data. 641 virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed); 642 643 //! \name Header 644 //@{ 645 //! \brief Returns the tag value for this command. 646 virtual uint8_t getTag() const { return ROM_JUMP_CMD; } 647 648 //! \brief Constructs the header for this boot command. 649 virtual void fillCommandHeader(boot_command_t & header); 650 //@} 651 652 //! \name Accessors 653 //@{ 654 inline void setAddress(uint32_t address) { m_address = address; } 655 inline uint32_t getAddress() const { return m_address; } 656 657 inline void setArgument(uint32_t argument) { m_argument = argument; } 658 inline uint32_t getArgument() const { return m_argument; } 659 660 inline void setIsHAB(bool isHAB) { m_isHAB = isHAB; } 661 inline bool isHAB() const { return m_isHAB; } 662 663 inline void setIVTSize(uint32_t ivtSize) { m_ivtSize = ivtSize; } 664 inline uint32_t getIVTSize() const { return m_ivtSize; } 665 //@} 666 667 //! \brief Print out a string representation of the object. 668 virtual void debugPrint() const; 669 670 protected: 671 uint32_t m_address; //!< Address of the code to execute. 672 uint32_t m_argument; //!< Sole argument to pass to code. 673 bool m_isHAB; //!< Whether this jump/call is a special HAB jump/call. When this flag is set, m_address becomes the IVT address and m_ivtSize is the IVT size. 674 uint32_t m_ivtSize; //!< Size of the IVT for a HAB jump/call. 675 }; 676 677 /*! 678 * \brief Call function bootloader command. 679 */ 680 class CallCommand : public JumpCommand 681 { 682 public: 683 //! \brief Default constructor. 684 CallCommand() : JumpCommand() {} 685 686 //! \brief Returns the tag value for this command. 687 virtual uint8_t getTag() const { return ROM_CALL_CMD; } 688 689 //! \brief Print out a string representation of the object. 690 virtual void debugPrint() const; 691 }; 692 693 /*! 694 * \brief Base class for a section of an Encore boot image. 695 * 696 * Provides methods to manage the unique identifier that all sections have, and 697 * to set the boot image object which owns the section. There are also virtual 698 * methods to get header flags and fill in the header used in the section 699 * table. Subclasses must implement at least fillSectionHeader(). 700 */ 701 class Section : public CipherBlockGenerator 702 { 703 public: 704 //! \brief Default constructor. 705 Section() : CipherBlockGenerator(), m_identifier(0), m_image(0), m_alignment(BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT), m_flags(0), m_leaveUnencrypted(false) {} 706 707 //! \brief Constructor taking the unique identifier for this section. 708 Section(uint32_t identifier) : CipherBlockGenerator(), m_identifier(identifier), m_image(0), m_alignment(BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT), m_flags(0), m_leaveUnencrypted(false) {} 709 710 //! \name Identifier 711 //@{ 712 inline void setIdentifier(uint32_t identifier) { m_identifier = identifier; } 713 inline uint32_t getIdentifier() const { return m_identifier; } 714 //@} 715 716 //! \name Header 717 //@{ 718 //! \brief Sets explicit flags for this section. 719 virtual void setFlags(uint32_t flags) { m_flags = flags; } 720 721 //! \brief Returns the flags for this section. 722 //! 723 //! The return value consists of the flags set with setFlags() possibly or-ed 724 //! with #ROM_SECTION_CLEARTEXT if the section has been set to be left 725 //! unencrypted. 726 virtual uint32_t getFlags() const { return m_flags | ( m_leaveUnencrypted ? ROM_SECTION_CLEARTEXT : 0); } 727 728 //! \brief Pure virtual method to construct the header for this section. 729 virtual void fillSectionHeader(section_header_t & header); 730 //@} 731 732 //! \name Owner image 733 //@{ 734 //! \brief Called when the section is added to an image. 735 void setImage(EncoreBootImage * image) { m_image = image; } 736 737 //! \brief Returns a pointer to the image that this section belongs to. 738 EncoreBootImage * getImage() const { return m_image; } 739 //@} 740 741 //! \name Alignment 742 //@{ 743 //! \brief Sets the required alignment in the output file for this section. 744 void setAlignment(unsigned alignment); 745 746 //! \brief Returns the current alignment, the minimum of which will be 16. 747 unsigned getAlignment() const { return m_alignment; } 748 749 //! \brief Computes padding amount for alignment requirement. 750 unsigned getPadBlockCountForOffset(unsigned offset); 751 //@} 752 753 //! \name Leave unencrypted flag 754 //@{ 755 //! \brief Sets whether the section will be left unencrypted. 756 void setLeaveUnencrypted(unsigned flag) { m_leaveUnencrypted = flag; } 757 758 //! \brief Returns true if the section will remain unencrypted. 759 bool getLeaveUnencrypted() const { return m_leaveUnencrypted; } 760 //@} 761 762 protected: 763 uint32_t m_identifier; //!< Unique identifier for this section. 764 EncoreBootImage * m_image; //!< The image to which this section belongs. 765 unsigned m_alignment; //!< Alignment requirement for the start of this section. 766 uint32_t m_flags; //!< Section flags set by the user. 767 bool m_leaveUnencrypted; //!< Set to true to prevent this section from being encrypted. 768 }; 769 770 /*! 771 * \brief A bootable section of an Encore boot image. 772 */ 773 class BootSection : public Section 774 { 775 public: 776 typedef std::list<BootCommand*> command_list_t; 777 typedef command_list_t::iterator iterator_t; 778 typedef command_list_t::const_iterator const_iterator_t; 779 780 public: 781 //! \brief Default constructor. 782 BootSection() : Section() {} 783 784 //! \brief Constructor taking the unique identifier for this section. 785 BootSection(uint32_t identifier) : Section(identifier) {} 786 787 //! \brief Destructor. 788 virtual ~BootSection(); 789 790 //! \brief Load the section from raw data. 791 virtual void fillFromData(const cipher_block_t * blocks, unsigned count); 792 793 //! \name Header 794 //@{ 795 //! \brief Returns the flags for this section. 796 virtual uint32_t getFlags() const { return Section::getFlags() | ROM_SECTION_BOOTABLE; } 797 //@} 798 799 //! \name Commands 800 //@{ 801 //! \brief Append a new command to the section. 802 //! 803 //! The section takes ownership of the command and will delete it when 804 //! the section is destroyed. 805 void addCommand(BootCommand * command) { m_commands.push_back(command); } 806 807 //! \brief Returns the number of commands in this section, excluding the tag command. 808 unsigned getCommandCount() const { return (unsigned)m_commands.size(); } 809 810 iterator_t begin() { return m_commands.begin(); } 811 iterator_t end() { return m_commands.end(); } 812 813 const_iterator_t begin() const { return m_commands.begin(); } 814 const_iterator_t end() const { return m_commands.end(); } 815 //@} 816 817 //! \name Cipher blocks 818 //@{ 819 //! \brief Returns the total number of cipher blocks occupied by this section. 820 virtual unsigned getBlockCount() const; 821 822 //! \brief Returns the contents of up to \a maxCount cipher blocks. 823 virtual unsigned getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data); 824 //@} 825 826 //! \brief Print out a string representation of the object. 827 virtual void debugPrint() const; 828 829 protected: 830 command_list_t m_commands; //!< Commands held in this section. 831 832 protected: 833 //! \brief Remove all commands from the section. 834 void deleteCommands(); 835 }; 836 837 /*! 838 * \brief A non-bootable section of an Encore boot image. 839 */ 840 class DataSection : public Section 841 { 842 public: 843 //! \brief Default constructor. 844 DataSection() : Section(), m_data(), m_length(0) {} 845 846 //! \brief Constructor taking the unique identifier for this section. 847 DataSection(uint32_t identifier) : Section(identifier), m_data(), m_length(0) {} 848 849 //! \brief Set the data section's contents. 850 void setData(const uint8_t * data, unsigned length); 851 852 //! \brief Set the data section's contents without copying \a data. 853 void setDataNoCopy(const uint8_t * data, unsigned length); 854 855 //! \name Cipher blocks 856 //@{ 857 //! \brief Returns the total number of cipher blocks occupied by this section. 858 virtual unsigned getBlockCount() const; 859 860 //! \brief Returns the contents of up to \a maxCount cipher blocks. 861 virtual unsigned getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data); 862 //@} 863 864 //! \brief Print out a string representation of the object. 865 virtual void debugPrint() const; 866 867 protected: 868 smart_array_ptr<uint8_t> m_data; //!< The section's contents. 869 unsigned m_length; //!< Number of bytes of data. 870 }; 871 872 public: 873 typedef std::list<Section*> section_list_t; //!< List of image sections. 874 typedef section_list_t::iterator section_iterator_t; //!< Iterator over sections. 875 typedef section_list_t::const_iterator const_section_iterator_t; //!< Const iterator over sections. 876 877 typedef std::vector<AES128Key> key_list_t; //!< List of KEKs. 878 typedef key_list_t::iterator key_iterator_t; //!< Iterator over KEKs. 879 typedef key_list_t::const_iterator const_key_iterator_t; //!< Const iterator over KEKs. 880 881 public: 882 //! \brief Default constructor. 883 EncoreBootImage(); 884 885 //! \brief Destructor. 886 virtual ~EncoreBootImage(); 887 888 //! \name Sections 889 //@{ 890 void addSection(Section * newSection); 891 inline unsigned sectionCount() const { return (unsigned)m_sections.size(); } 892 893 inline section_iterator_t beginSection() { return m_sections.begin(); } 894 inline section_iterator_t endSection() { return m_sections.end(); } 895 inline const_section_iterator_t beginSection() const { return m_sections.begin(); } 896 inline const_section_iterator_t endSection() const { return m_sections.end(); } 897 898 section_iterator_t findSection(Section * section); 899 900 //! \brief Calculates the starting block number for the given section. 901 uint32_t getSectionOffset(Section * section); 902 //@} 903 904 //! \name Encryption keys 905 //@{ 906 inline void addKey(const AES128Key & newKey) { m_keys.push_back(newKey); } 907 inline unsigned keyCount() const { return (unsigned)m_keys.size(); } 908 909 inline key_iterator_t beginKeys() { return m_keys.begin(); } 910 inline key_iterator_t endKeys() { return m_keys.end(); } 911 inline const_key_iterator_t beginKeys() const { return m_keys.begin(); } 912 inline const_key_iterator_t endKeys() const { return m_keys.end(); } 913 914 //! \brief The image is encrypted if there is at least one key. 915 inline bool isEncrypted() const { return m_keys.size() != 0; } 916 //@} 917 918 //! \name Versions 919 //@{ 920 virtual void setProductVersion(const version_t & version); 921 virtual void setComponentVersion(const version_t & version); 922 //@} 923 924 //! \name Flags 925 //@{ 926 inline void setFlags(uint16_t flags) { m_headerFlags = flags; } 927 inline uint32_t getFlags() const { return m_headerFlags; } 928 //@} 929 930 //! \brief Specify the drive tag to be set in the output file header. 931 virtual void setDriveTag(uint16_t tag) { m_driveTag = tag; } 932 933 //! \brief Calculates the total number of cipher blocks the image consumes. 934 uint32_t getImageSize(); 935 936 //! \brief Returns the preferred ".sb" extension for Encore boot images. 937 virtual std::string getFileExtension() const { return ".sb"; } 938 939 //! \name Output 940 //@{ 941 //! \brief Write the boot image to an output stream. 942 virtual void writeToStream(std::ostream & stream); 943 //@} 944 945 //! \brief Print out a string representation of the object. 946 virtual void debugPrint() const; 947 948 protected: 949 uint16_t m_headerFlags; //!< Flags field in the boot image header. 950 version_t m_productVersion; //!< Product version. 951 version_t m_componentVersion; //!< Component version. 952 uint16_t m_driveTag; //!< System drive tag for this boot image. 953 section_list_t m_sections; //!< Sections contained in this image. 954 key_list_t m_keys; //!< List of key encryption keys. If empty, the image is unencrypted. 955 AES128Key m_sessionKey; //!< Session key we're using. 956 957 void prepareImageHeader(boot_image_header_t & header); 958 uint64_t getTimestamp(); 959 Section * findFirstBootableSection(); 960 unsigned getPadBlockCountForSection(Section * section, unsigned offset); 961 }; 962 963 }; // namespace elftosb 964 965 #endif // _EncoreBootImage_h_ 966