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