blob: 0675eaaf869517e6b6e7cc0c896212207d5ea06a [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 =
Patrick Williams1e9a5f12023-08-23 16:53:06 -050031 sdbusplus::server::xyz::openbmc_project::software::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 */
Patrick Williamsd5e8e732023-05-10 07:50:18 -050055 explicit CustomFd(int fd) : fd(fd) {}
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -060056
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 */
Patrick Williamsd5e8e732023-05-10 07:50:18 -0500100 CustomMap(void* addr, size_t length) : addr(addr), length(length) {}
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600101
102 ~CustomMap()
103 {
104 munmap(addr, length);
105 }
106
107 void* operator()() const
108 {
109 return addr;
110 }
111};
112
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600113/** @class Signature
114 * @brief Contains signature verification functions.
115 * @details The software image class that contains the signature
116 * verification functions for signed image.
117 */
118class Signature
119{
120 public:
121 Signature() = delete;
122 Signature(const Signature&) = delete;
123 Signature& operator=(const Signature&) = delete;
124 Signature(Signature&&) = default;
125 Signature& operator=(Signature&&) = default;
126 ~Signature() = default;
127
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600128 /**
129 * @brief Constructs Signature.
130 * @param[in] imageDirPath - image path
131 * @param[in] signedConfPath - Path of public key
132 * hash function files
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600133 */
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600134 Signature(const fs::path& imageDirPath, const fs::path& signedConfPath);
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600135
136 /**
137 * @brief Image signature verification function.
138 * Verify the Manifest and public key file signature using the
139 * public keys available in the system first. After successful
140 * validation, continue the whole image files signature
141 * validation using the image specific public key and the
142 * hash function.
143 *
144 * @return true if signature verification was successful,
145 * false if not
146 */
147 bool verify();
148
149 private:
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600150 /**
151 * @brief Function used for system level file signature validation
Gunnar Millse11a2022018-03-23 12:04:48 -0500152 * of image specific publickey file and manifest file
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600153 * using the available public keys and hash functions
154 * in the system.
Gunnar Mills2bcba022018-04-08 15:02:04 -0500155 * Refer code-update documentation for more details.
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600156 */
157 bool systemLevelVerify();
158
159 /**
160 * @brief Return all key types stored in the BMC based on the
161 * public key and hashfunc files stored in the BMC.
162 *
163 * @return list
164 */
165 AvailableKeyTypes getAvailableKeyTypesFromSystem() const;
166
167 /**
168 * @brief Return public key and hash function file names for the
169 * corresponding key type
170 *
171 * @param[in] key - key type
172 * @return Pair of hash and public key file names
173 */
174 inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const;
175
176 /**
177 * @brief Verify the file signature using public key and hash function
178 *
179 * @param[in] - Image file path
180 * @param[in] - Signature file path
181 * @param[in] - Public key
182 * @param[in] - Hash function name
183 * @return true if signature verification was successful, false if not
184 */
185 bool verifyFile(const fs::path& file, const fs::path& signature,
186 const fs::path& publicKey, const std::string& hashFunc);
187
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600188 /**
189 * @brief Create RSA object from the public key
190 * @param[in] - publickey
191 * @param[out] - RSA Object.
192 */
Patrick Williamsd75c8692021-12-07 16:25:10 -0600193 inline EVP_PKEY_Ptr createPublicRSA(const fs::path& publicKey);
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600194
195 /**
196 * @brief Memory map the file
197 * @param[in] - file path
198 * @param[in] - file size
199 * @param[out] - Custom Mmap address
200 */
201 CustomMap mapFile(const fs::path& path, size_t size);
202
George Liu0a06e972020-12-17 09:17:04 +0800203 /**
204 * @brief Verify the full file signature using public key and hash function
205 *
206 * @return true if signature verification was successful, false if not
207 */
208 bool verifyFullImage();
209
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600210 /** @brief Directory where software images are placed*/
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600211 fs::path imageDirPath;
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600212
213 /** @brief Path of public key and hash function files */
214 fs::path signedConfPath;
215
Manojkiran Eda19dd56b2024-06-17 14:29:52 +0530216 /** @brief key type defined in manifest file */
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600217 Key_t keyType;
218
Manojkiran Eda19dd56b2024-06-17 14:29:52 +0530219 /** @brief Hash type defined in manifest file */
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600220 Hash_t hashType;
Henry Tian574f94b2021-01-06 10:33:59 +0800221
Lei YU6173a072022-05-23 19:18:57 +0800222 /** @brief The image purpose */
223 VersionPurpose purpose;
224
Henry Tian574f94b2021-01-06 10:33:59 +0800225 /** @brief Check and Verify the required image files
226 *
227 * @param[in] filePath - BMC tarball file path
228 * @param[in] publicKeyPath - publicKey file Path
229 * @param[in] imageList - Image filenames included in the BMC tarball
Lei YU7ab55e22021-05-19 13:26:53 +0800230 * @param[out] fileFound - Indicate if the file to verify is found or not
231 *
232 * @return true if all image files are found in BMC tarball and
Manojkiran Eda19dd56b2024-06-17 14:29:52 +0530233 * Verify Success false if one of image files is missing
Henry Tian574f94b2021-01-06 10:33:59 +0800234 */
235 bool checkAndVerifyImage(const std::string& filePath,
236 const std::string& publicKeyPath,
Lei YU7ab55e22021-05-19 13:26:53 +0800237 const std::vector<std::string>& imageList,
238 bool& fileFound);
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600239};
240
241} // namespace image
242} // namespace software
243} // namespace phosphor