1 /*
2  * File:  EncoreBootImageReader.h
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 #if !defined(_EncoreBootImageReader_h_)
8 #define _EncoreBootImageReader_h_
9 
10 #include "EncoreBootImage.h"
11 
12 namespace elftosb
13 {
14 
15 /*!
16  * \brief Reads a Piano/Encore boot image from an input stream.
17  */
18 class EncoreBootImageReader
19 {
20 public:
21           /*!
22            * \brief Exception class used for error found while reading a boot image.
23            */
24           class read_error : public std::runtime_error
25           {
26           public:
27                     //! \brief Constructor.
read_error(const std::string & msg)28                     read_error(const std::string & msg) : std::runtime_error(msg) {}
29           };
30 
31           //! \brief An array of section headers.
32           typedef std::vector<EncoreBootImage::section_header_t> section_array_t;
33 
34           //! \brief An array of boot tags.
35           typedef std::vector<EncoreBootImage::boot_command_t> boot_tag_array_t;
36 
37 public:
38           //! \brief Default constructor.
EncoreBootImageReader(std::istream & stream)39           EncoreBootImageReader(std::istream & stream) : m_stream(stream) {}
40 
41           //! \brief Destructor.
~EncoreBootImageReader()42           virtual ~EncoreBootImageReader() {}
43 
44           //! \name Decryption key
45           //! These methods provide access to the Data Encryption Key (DEK). Normally
46           //! the DEK is discovered using the readKeyDictionary() method.
47           //@{
setKey(const AESKey<128> & key)48           inline void setKey(const AESKey<128> & key) { m_dek = key; }
getKey()49           inline const AESKey<128> & getKey() const { return m_dek; }
50           //@}
51 
52           //! \name Readers
53           //! This group of methods is responsible for reading and parsing different
54           //! pieces and parts of the boot image file.
55           //@{
56           //! \brief Reads the header from the image.
57           void readImageHeader();
58 
59           //! \brief Computes the actual SHA-1 digest of the image header.
60           void computeHeaderDigest(sha1_digest_t & digest);
61 
62           //! \brief Reads the digest at the end of the image.
63           void readImageDigest();
64 
65           //! \brief Run a SHA-1 digest over the entire image.
66           void computeImageDigest(sha1_digest_t & digest);
67 
68           //! \brief Read the plaintext section table entries.
69           void readSectionTable();
70 
71           //! \brief Reads the key dictionary, if the image is encrypted.
72           bool readKeyDictionary(const AESKey<128> & kek);
73 
74           //! \brief
75           void readBootTags();
76 
77           //! \brief
78           EncoreBootImage::Section * readSection(unsigned index);
79           //@}
80 
81           //! \name Accessors
82           //! Information retrieved with reader methods is accessible through
83           //! these methods.
84           //@{
85           //! \brief Returns whether the image is encrypted or not.
86           //! \pre The header must have been read already.
isEncrypted()87           inline bool isEncrypted() const { return m_header.m_keyCount > 0; }
88 
89           //! \brief Returns a reference to the image's header.
getHeader()90           const EncoreBootImage::boot_image_header_t & getHeader() const { return m_header; }
91 
92           //! \brief Returns a reference to the SHA-1 digest read from the image.
getDigest()93           const sha1_digest_t & getDigest() const { return m_digest; }
94 
95           //! \brief Returns a reference to the STL container holding the section headers.
getSections()96           inline const section_array_t & getSections() const { return m_sections; }
97 
98           //! \brief Returns a reference to the STL container holding the boot tags.
getBootTags()99           inline const boot_tag_array_t & getBootTags() const { return m_bootTags; }
100           //@}
101 
102 protected:
103           std::istream & m_stream;      //!< The input stream to read the image from.
104           AESKey<128> m_dek;  //!< DEK (data encryption key) read from the key dictionary.
105           EncoreBootImage::boot_image_header_t m_header;    //!< Header from the boot image.
106           sha1_digest_t m_digest;       //!< SHA-1 digest as read from the image.
107           section_array_t m_sections;   //!< The section table.
108           boot_tag_array_t m_bootTags;  //!< The array of boot tags read from the image.
109 
110 protected:
111           //! \brief Calculates the 8-bit checksum on a boot command header.
112           uint8_t calculateCommandChecksum(EncoreBootImage::boot_command_t & header);
113 };
114 
115 }; // namespace elftosb
116 
117 #endif // _EncoreBootImageReader_h_
118