1 #pragma once 2 #include "openssl_alloc.hpp" 3 #include "version.hpp" 4 5 #include <openssl/evp.h> 6 #include <openssl/pem.h> 7 #include <openssl/rsa.h> 8 #include <sys/mman.h> 9 #include <unistd.h> 10 11 #include <filesystem> 12 #include <set> 13 #include <string> 14 #include <vector> 15 16 namespace phosphor 17 { 18 namespace software 19 { 20 namespace image 21 { 22 23 namespace fs = std::filesystem; 24 using Key_t = std::string; 25 using Hash_t = std::string; 26 using PublicKeyPath = fs::path; 27 using HashFilePath = fs::path; 28 using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>; 29 using AvailableKeyTypes = std::set<Key_t>; 30 using VersionPurpose = 31 sdbusplus::server::xyz::openbmc_project::software::Version::VersionPurpose; 32 33 // RAII support for openSSL functions. 34 using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>; 35 using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>; 36 using EVP_MD_CTX_Ptr = 37 std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>; 38 39 /** @struct CustomFd 40 * 41 * RAII wrapper for file descriptor. 42 */ 43 struct 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 */ 55 explicit CustomFd(int fd) : fd(fd) {} 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 */ 79 struct 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 ~CustomMap() 103 { 104 munmap(addr, length); 105 } 106 107 void* operator()() const 108 { 109 return addr; 110 } 111 }; 112 113 /** @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 */ 118 class 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 128 /** 129 * @brief Constructs Signature. 130 * @param[in] imageDirPath - image path 131 * @param[in] signedConfPath - Path of public key 132 * hash function files 133 */ 134 Signature(const fs::path& imageDirPath, const fs::path& signedConfPath); 135 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: 150 /** 151 * @brief Function used for system level file signature validation 152 * of image specific publickey file and manifest file 153 * using the available public keys and hash functions 154 * in the system. 155 * Refer code-update documentation for more details. 156 */ 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 static bool verifyFile(const fs::path& file, const fs::path& signature, 186 const fs::path& publicKey, 187 const std::string& hashFunc); 188 189 /** 190 * @brief Create RSA object from the public key 191 * @param[in] - publickey 192 * @param[out] - RSA Object. 193 */ 194 static inline EVP_PKEY_Ptr createPublicRSA(const fs::path& publicKey); 195 196 /** 197 * @brief Memory map the file 198 * @param[in] - file path 199 * @param[in] - file size 200 * @param[out] - Custom Mmap address 201 */ 202 static CustomMap mapFile(const fs::path& path, size_t size); 203 204 /** 205 * @brief Verify the full file signature using public key and hash function 206 * 207 * @return true if signature verification was successful, false if not 208 */ 209 bool verifyFullImage(); 210 211 /** @brief Directory where software images are placed*/ 212 fs::path imageDirPath; 213 214 /** @brief Path of public key and hash function files */ 215 fs::path signedConfPath; 216 217 /** @brief key type defined in manifest file */ 218 Key_t keyType; 219 220 /** @brief Hash type defined in manifest file */ 221 Hash_t hashType; 222 223 /** @brief The image purpose */ 224 VersionPurpose purpose; 225 226 /** @brief Check and Verify the required image files 227 * 228 * @param[in] filePath - BMC tarball file path 229 * @param[in] publicKeyPath - publicKey file Path 230 * @param[in] imageList - Image filenames included in the BMC tarball 231 * @param[out] fileFound - Indicate if the file to verify is found or not 232 * 233 * @return true if all image files are found in BMC tarball and 234 * Verify Success false if one of image files is missing 235 */ 236 bool checkAndVerifyImage(const std::string& filePath, 237 const std::string& publicKeyPath, 238 const std::vector<std::string>& imageList, 239 bool& fileFound); 240 }; 241 242 } // namespace image 243 } // namespace software 244 } // namespace phosphor 245