blob: 38129f91a94f93ab88981bfc1f62e9a777d7fa73 [file] [log] [blame]
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -06001#pragma once
Jayashankar Padatha0135602019-04-22 16:22:58 +05302#include "openssl_alloc.hpp"
Lei YU6173a072022-05-23 19:18:57 +08003#include "version.hpp"
Gunnar Millsb0ce9962018-09-07 13:39:10 -05004
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -06005#include <openssl/evp.h>
6#include <openssl/pem.h>
Gunnar Millsb0ce9962018-09-07 13:39:10 -05007#include <openssl/rsa.h>
8#include <sys/mman.h>
9#include <unistd.h>
10
Adriana Kobylakc98d9122020-05-05 10:36:01 -050011#include <filesystem>
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -060012#include <set>
Andrew Geissler9155b712020-05-16 13:04:44 -050013#include <string>
Henry Tian574f94b2021-01-06 10:33:59 +080014#include <vector>
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -060015
16namespace phosphor
17{
18namespace software
19{
20namespace image
21{
22
Adriana Kobylakc98d9122020-05-05 10:36:01 -050023namespace fs = std::filesystem;
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -060024using Key_t = std::string;
25using Hash_t = std::string;
26using PublicKeyPath = fs::path;
27using HashFilePath = fs::path;
28using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>;
29using AvailableKeyTypes = std::set<Key_t>;
Lei YU6173a072022-05-23 19:18:57 +080030using VersionPurpose =
31 sdbusplus::xyz::openbmc_project::Software::server::Version::VersionPurpose;
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -060032
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -060033// RAII support for openSSL functions.
34using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
35using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
36using EVP_MD_CTX_Ptr =
Adriana Kobylak5ed9b2d2018-09-06 13:15:34 -050037 std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -060038
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -060039/** @struct CustomFd
40 *
41 * RAII wrapper for file descriptor.
42 */
43struct CustomFd
44{
45 public:
46 CustomFd() = delete;
47 CustomFd(const CustomFd&) = delete;
48 CustomFd& operator=(const CustomFd&) = delete;
49 CustomFd(CustomFd&&) = default;
50 CustomFd& operator=(CustomFd&&) = default;
51 /** @brief Saves File descriptor and uses it to do file operation
52 *
53 * @param[in] fd - File descriptor
54 */
Lei YU0cd6d842021-12-27 11:56:02 +080055 explicit CustomFd(int fd) : fd(fd)
Adriana Kobylak58aa7502020-06-08 11:12:11 -050056 {}
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -060057
58 ~CustomFd()
59 {
60 if (fd >= 0)
61 {
62 close(fd);
63 }
64 }
65
66 int operator()() const
67 {
68 return fd;
69 }
70
71 private:
72 /** @brief File descriptor */
73 int fd = -1;
74};
75
76/** @struct CustomMap
77 *
78 * RAII wrapper for mmap.
79 */
80struct CustomMap
81{
82 private:
83 /** @brief starting address of the map */
84 void* addr;
85
86 /** @brief length of the mapping */
87 size_t length;
88
89 public:
90 CustomMap() = delete;
91 CustomMap(const CustomMap&) = delete;
92 CustomMap& operator=(const CustomMap&) = delete;
93 CustomMap(CustomMap&&) = default;
94 CustomMap& operator=(CustomMap&&) = default;
95
96 /** @brief Saves starting address of the map and
97 * and length of the file.
98 * @param[in] addr - Starting address of the map
99 * @param[in] length - length of the map
100 */
101 CustomMap(void* addr, size_t length) : addr(addr), length(length)
Adriana Kobylak58aa7502020-06-08 11:12:11 -0500102 {}
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600103
104 ~CustomMap()
105 {
106 munmap(addr, length);
107 }
108
109 void* operator()() const
110 {
111 return addr;
112 }
113};
114
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600115/** @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
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600130 /**
131 * @brief Constructs Signature.
132 * @param[in] imageDirPath - image path
133 * @param[in] signedConfPath - Path of public key
134 * hash function files
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600135 */
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600136 Signature(const fs::path& imageDirPath, const fs::path& signedConfPath);
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600137
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:
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600152 /**
153 * @brief Function used for system level file signature validation
Gunnar Millse11a2022018-03-23 12:04:48 -0500154 * of image specific publickey file and manifest file
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600155 * using the available public keys and hash functions
156 * in the system.
Gunnar Mills2bcba022018-04-08 15:02:04 -0500157 * Refer code-update documentation for more details.
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600158 */
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
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600190 /**
191 * @brief Create RSA object from the public key
192 * @param[in] - publickey
193 * @param[out] - RSA Object.
194 */
Patrick Williamsd75c8692021-12-07 16:25:10 -0600195 inline EVP_PKEY_Ptr createPublicRSA(const fs::path& publicKey);
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600196
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
George Liu0a06e972020-12-17 09:17:04 +0800205 /**
206 * @brief Verify the full file signature using public key and hash function
207 *
208 * @return true if signature verification was successful, false if not
209 */
210 bool verifyFullImage();
211
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600212 /** @brief Directory where software images are placed*/
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600213 fs::path imageDirPath;
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600214
215 /** @brief Path of public key and hash function files */
216 fs::path signedConfPath;
217
218 /** @brief key type defined in mainfest file */
219 Key_t keyType;
220
221 /** @brief Hash type defined in mainfest file */
222 Hash_t hashType;
Henry Tian574f94b2021-01-06 10:33:59 +0800223
Lei YU6173a072022-05-23 19:18:57 +0800224 /** @brief The image purpose */
225 VersionPurpose purpose;
226
Henry Tian574f94b2021-01-06 10:33:59 +0800227 /** @brief Check and Verify the required image files
228 *
229 * @param[in] filePath - BMC tarball file path
230 * @param[in] publicKeyPath - publicKey file Path
231 * @param[in] imageList - Image filenames included in the BMC tarball
Lei YU7ab55e22021-05-19 13:26:53 +0800232 * @param[out] fileFound - Indicate if the file to verify is found or not
233 *
234 * @return true if all image files are found in BMC tarball and
Henry Tian574f94b2021-01-06 10:33:59 +0800235 * Verify Sucess false if one of image files is missing
236 */
237 bool checkAndVerifyImage(const std::string& filePath,
238 const std::string& publicKeyPath,
Lei YU7ab55e22021-05-19 13:26:53 +0800239 const std::vector<std::string>& imageList,
240 bool& fileFound);
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600241};
242
243} // namespace image
244} // namespace software
245} // namespace phosphor