blob: 99b35671cb3e9fbafc4ccefd906fcaf88474ccb6 [file] [log] [blame]
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -06001#pragma once
Adriana Kobylak5ed9b2d2018-09-06 13:15:34 -05002#include "utils.hpp"
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -06003#include <openssl/rsa.h>
4#include <openssl/evp.h>
5#include <openssl/pem.h>
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -06006#include <experimental/filesystem>
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -06007#include <set>
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -06008#include <unistd.h>
9#include <sys/mman.h>
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -060010
11namespace phosphor
12{
13namespace software
14{
15namespace image
16{
17
18namespace fs = std::experimental::filesystem;
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -060019using Key_t = std::string;
20using Hash_t = std::string;
21using PublicKeyPath = fs::path;
22using HashFilePath = fs::path;
23using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>;
24using AvailableKeyTypes = std::set<Key_t>;
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -060025
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -060026// RAII support for openSSL functions.
27using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
28using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
29using EVP_MD_CTX_Ptr =
Adriana Kobylak5ed9b2d2018-09-06 13:15:34 -050030 std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -060031
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -060032/** @struct CustomFd
33 *
34 * RAII wrapper for file descriptor.
35 */
36struct CustomFd
37{
38 public:
39 CustomFd() = delete;
40 CustomFd(const CustomFd&) = delete;
41 CustomFd& operator=(const CustomFd&) = delete;
42 CustomFd(CustomFd&&) = default;
43 CustomFd& operator=(CustomFd&&) = default;
44 /** @brief Saves File descriptor and uses it to do file operation
45 *
46 * @param[in] fd - File descriptor
47 */
48 CustomFd(int fd) : fd(fd)
49 {
50 }
51
52 ~CustomFd()
53 {
54 if (fd >= 0)
55 {
56 close(fd);
57 }
58 }
59
60 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 */
74struct 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 */
95 CustomMap(void* addr, size_t length) : addr(addr), length(length)
96 {
97 }
98
99 ~CustomMap()
100 {
101 munmap(addr, length);
102 }
103
104 void* operator()() const
105 {
106 return addr;
107 }
108};
109
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600110/** @class Signature
111 * @brief Contains signature verification functions.
112 * @details The software image class that contains the signature
113 * verification functions for signed image.
114 */
115class Signature
116{
117 public:
118 Signature() = delete;
119 Signature(const Signature&) = delete;
120 Signature& operator=(const Signature&) = delete;
121 Signature(Signature&&) = default;
122 Signature& operator=(Signature&&) = default;
123 ~Signature() = default;
124
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600125 /**
126 * @brief Constructs Signature.
127 * @param[in] imageDirPath - image path
128 * @param[in] signedConfPath - Path of public key
129 * hash function files
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600130 */
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600131 Signature(const fs::path& imageDirPath, const fs::path& signedConfPath);
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600132
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:
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600147 /**
148 * @brief Function used for system level file signature validation
Gunnar Millse11a2022018-03-23 12:04:48 -0500149 * of image specific publickey file and manifest file
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600150 * using the available public keys and hash functions
151 * in the system.
Gunnar Mills2bcba022018-04-08 15:02:04 -0500152 * Refer code-update documentation for more details.
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600153 */
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 fs::path& file, const fs::path& signature,
183 const fs::path& publicKey, const std::string& hashFunc);
184
Jayanth Othayothfb6e1fc2018-02-21 05:43:20 -0600185 /**
186 * @brief Create RSA object from the public key
187 * @param[in] - publickey
188 * @param[out] - RSA Object.
189 */
190 inline RSA* createPublicRSA(const fs::path& publicKey);
191
192 /**
193 * @brief Memory map the file
194 * @param[in] - file path
195 * @param[in] - file size
196 * @param[out] - Custom Mmap address
197 */
198 CustomMap mapFile(const fs::path& path, size_t size);
199
200 /** @brief Directory where software images are placed*/
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600201 fs::path imageDirPath;
Jayanth Othayoth2ab9b102018-02-21 05:27:47 -0600202
203 /** @brief Path of public key and hash function files */
204 fs::path signedConfPath;
205
206 /** @brief key type defined in mainfest file */
207 Key_t keyType;
208
209 /** @brief Hash type defined in mainfest file */
210 Hash_t hashType;
Jayanth Othayoth9d7cd832018-02-21 05:12:39 -0600211};
212
213} // namespace image
214} // namespace software
215} // namespace phosphor