1 #pragma once
2 #include "utils.hpp"
3 
4 #include <openssl/evp.h>
5 #include <openssl/pem.h>
6 #include <openssl/rsa.h>
7 #include <sys/mman.h>
8 #include <unistd.h>
9 
10 #include <filesystem>
11 #include <set>
12 #include <string>
13 
14 namespace openpower
15 {
16 namespace software
17 {
18 namespace image
19 {
20 
21 using Key_t = std::string;
22 using Hash_t = std::string;
23 using PublicKeyPath = std::filesystem::path;
24 using HashFilePath = std::filesystem::path;
25 using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>;
26 using AvailableKeyTypes = std::set<Key_t>;
27 
28 // RAII support for openSSL functions.
29 using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
30 using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
31 using EVP_MD_CTX_Ptr =
32     std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;
33 
34 /** @struct CustomFd
35  *
36  *  RAII wrapper for file descriptor.
37  */
38 struct CustomFd
39 {
40   public:
41     CustomFd() = delete;
42     CustomFd(const CustomFd&) = delete;
43     CustomFd& operator=(const CustomFd&) = delete;
44     CustomFd(CustomFd&&) = default;
45     CustomFd& operator=(CustomFd&&) = default;
46     /** @brief Saves File descriptor and uses it to do file operation
47      *
48      *  @param[in] fd - File descriptor
49      */
CustomFdopenpower::software::image::CustomFd50     explicit CustomFd(int fd) : fd(fd) {}
51 
~CustomFdopenpower::software::image::CustomFd52     ~CustomFd()
53     {
54         if (fd >= 0)
55         {
56             close(fd);
57         }
58     }
59 
operator ()openpower::software::image::CustomFd60     int operator()() const
61     {
62         return fd;
63     }
64 
65   private:
66     /** @brief File descriptor */
67     int fd = -1;
68 };
69 
70 /** @struct CustomMap
71  *
72  *  RAII wrapper for mmap.
73  */
74 struct CustomMap
75 {
76   private:
77     /** @brief starting address of the map   */
78     void* addr;
79 
80     /** @brief length of the mapping   */
81     size_t length;
82 
83   public:
84     CustomMap() = delete;
85     CustomMap(const CustomMap&) = delete;
86     CustomMap& operator=(const CustomMap&) = delete;
87     CustomMap(CustomMap&&) = default;
88     CustomMap& operator=(CustomMap&&) = default;
89 
90     /** @brief Saves starting address of the map and
91      *         and length of the file.
92      *  @param[in]  addr - Starting address of the map
93      *  @param[in]  length - length of the map
94      */
CustomMapopenpower::software::image::CustomMap95     CustomMap(void* addr, size_t length) : addr(addr), length(length) {}
96 
~CustomMapopenpower::software::image::CustomMap97     ~CustomMap()
98     {
99         munmap(addr, length);
100     }
101 
operator ()openpower::software::image::CustomMap102     void* operator()() const
103     {
104         return addr;
105     }
106 };
107 
108 /** @class Signature
109  *  @brief Contains signature verification functions.
110  *  @details The software image class that contains the signature
111  *           verification functions for signed image.
112  */
113 class Signature
114 {
115   public:
116     Signature() = delete;
117     Signature(const Signature&) = delete;
118     Signature& operator=(const Signature&) = delete;
119     Signature(Signature&&) = default;
120     Signature& operator=(Signature&&) = default;
121     ~Signature() = default;
122 
123     /**
124      * @brief Constructs Signature.
125      * @param[in]  imageDirPath - image path
126      * @param[in]  signedConfPath - Path of public key
127      *                              hash function files
128      */
129     explicit Signature(const std::filesystem::path& imageDirPath,
130                        const std::string& pnorFileName,
131                        const std::filesystem::path& signedConfPath);
132 
133     /**
134      * @brief Image signature verification function.
135      *        Verify the Manifest and public key file signature using the
136      *        public keys available in the system first. After successful
137      *        validation, continue the whole image files signature
138      *        validation using the image specific public key and the
139      *        hash function.
140      *
141      *        @return true if signature verification was successful,
142      *                     false if not
143      */
144     bool verify();
145 
146   private:
147     /**
148      * @brief Function used for system level file signature validation
149      *        of image specific publickey file and manifest file
150      *        using the available public keys and hash functions
151      *        in the system.
152      *        Refer code-update documentation for more details.
153      */
154     bool systemLevelVerify();
155 
156     /**
157      *  @brief Return all key types stored in the BMC based on the
158      *         public key and hashfunc files stored in the BMC.
159      *
160      *  @return list
161      */
162     AvailableKeyTypes getAvailableKeyTypesFromSystem() const;
163 
164     /**
165      *  @brief Return public key and hash function file names for the
166      *  corresponding key type
167      *
168      *  @param[in]  key - key type
169      *  @return Pair of hash and public key file names
170      */
171     inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const;
172 
173     /**
174      * @brief Verify the file signature using public key and hash function
175      *
176      * @param[in]  - Image file path
177      * @param[in]  - Signature file path
178      * @param[in]  - Public key
179      * @param[in]  - Hash function name
180      * @return true if signature verification was successful, false if not
181      */
182     bool verifyFile(const std::filesystem::path& file,
183                     const std::filesystem::path& signature,
184                     const std::filesystem::path& publicKey,
185                     const std::string& hashFunc);
186 
187     /**
188      * @brief Create RSA object from the public key
189      * @param[in]  - publickey
190      * @param[out] - RSA Object.
191      */
192     inline EVP_PKEY_Ptr createPublicRSA(const std::filesystem::path& publicKey);
193 
194     /**
195      * @brief Memory map the  file
196      * @param[in]  - file path
197      * @param[in]  - file size
198      * @param[out] - Custom Mmap address
199      */
200     CustomMap mapFile(const std::filesystem::path& path, size_t size);
201 
202     /** @brief Directory where software images are placed*/
203     std::filesystem::path imageDirPath;
204 
205     /** @brief The PNOR file name in imageDirPath */
206     std::string pnorFileName;
207 
208     /** @brief Path of public key and hash function files */
209     std::filesystem::path signedConfPath;
210 
211     /** @brief key type defined in manifest file */
212     Key_t keyType;
213 
214     /** @brief Hash type defined in manifest file */
215     Hash_t hashType;
216 };
217 
218 } // namespace image
219 } // namespace software
220 } // namespace openpower
221