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