1 #pragma once 2 #include "utils.hpp" 3 4 #include <openssl/evp.h> 5 #include <openssl/pem.h> 6 #include <openssl/rsa.h> 7 #include <sys/mman.h> 8 #include <unistd.h> 9 10 #include <filesystem> 11 #include <set> 12 #include <string> 13 14 namespace openpower 15 { 16 namespace software 17 { 18 namespace image 19 { 20 21 using Key_t = std::string; 22 using Hash_t = std::string; 23 using PublicKeyPath = std::filesystem::path; 24 using HashFilePath = std::filesystem::path; 25 using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>; 26 using AvailableKeyTypes = std::set<Key_t>; 27 28 // RAII support for openSSL functions. 29 using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>; 30 using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>; 31 using EVP_MD_CTX_Ptr = 32 std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>; 33 34 /** @struct CustomFd 35 * 36 * RAII wrapper for file descriptor. 37 */ 38 struct CustomFd 39 { 40 public: 41 CustomFd() = delete; 42 CustomFd(const CustomFd&) = delete; 43 CustomFd& operator=(const CustomFd&) = delete; 44 CustomFd(CustomFd&&) = default; 45 CustomFd& operator=(CustomFd&&) = default; 46 /** @brief Saves File descriptor and uses it to do file operation 47 * 48 * @param[in] fd - File descriptor 49 */ 50 explicit CustomFd(int fd) : fd(fd) 51 {} 52 53 ~CustomFd() 54 { 55 if (fd >= 0) 56 { 57 close(fd); 58 } 59 } 60 61 int operator()() const 62 { 63 return fd; 64 } 65 66 private: 67 /** @brief File descriptor */ 68 int fd = -1; 69 }; 70 71 /** @struct CustomMap 72 * 73 * RAII wrapper for mmap. 74 */ 75 struct CustomMap 76 { 77 private: 78 /** @brief starting address of the map */ 79 void* addr; 80 81 /** @brief length of the mapping */ 82 size_t length; 83 84 public: 85 CustomMap() = delete; 86 CustomMap(const CustomMap&) = delete; 87 CustomMap& operator=(const CustomMap&) = delete; 88 CustomMap(CustomMap&&) = default; 89 CustomMap& operator=(CustomMap&&) = default; 90 91 /** @brief Saves starting address of the map and 92 * and length of the file. 93 * @param[in] addr - Starting address of the map 94 * @param[in] length - length of the map 95 */ 96 CustomMap(void* addr, size_t length) : addr(addr), length(length) 97 {} 98 99 ~CustomMap() 100 { 101 munmap(addr, length); 102 } 103 104 void* operator()() const 105 { 106 return addr; 107 } 108 }; 109 110 /** @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 */ 115 class 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 125 /** 126 * @brief Constructs Signature. 127 * @param[in] imageDirPath - image path 128 * @param[in] signedConfPath - Path of public key 129 * hash function files 130 */ 131 explicit Signature(const std::filesystem::path& imageDirPath, 132 const std::string& pnorFileName, 133 const std::filesystem::path& signedConfPath); 134 135 /** 136 * @brief Image signature verification function. 137 * Verify the Manifest and public key file signature using the 138 * public keys available in the system first. After successful 139 * validation, continue the whole image files signature 140 * validation using the image specific public key and the 141 * hash function. 142 * 143 * @return true if signature verification was successful, 144 * false if not 145 */ 146 bool verify(); 147 148 private: 149 /** 150 * @brief Function used for system level file signature validation 151 * of image specific publickey file and manifest file 152 * using the available public keys and hash functions 153 * in the system. 154 * Refer code-update documentation for more details. 155 */ 156 bool systemLevelVerify(); 157 158 /** 159 * @brief Return all key types stored in the BMC based on the 160 * public key and hashfunc files stored in the BMC. 161 * 162 * @return list 163 */ 164 AvailableKeyTypes getAvailableKeyTypesFromSystem() const; 165 166 /** 167 * @brief Return public key and hash function file names for the 168 * corresponding key type 169 * 170 * @param[in] key - key type 171 * @return Pair of hash and public key file names 172 */ 173 inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const; 174 175 /** 176 * @brief Verify the file signature using public key and hash function 177 * 178 * @param[in] - Image file path 179 * @param[in] - Signature file path 180 * @param[in] - Public key 181 * @param[in] - Hash function name 182 * @return true if signature verification was successful, false if not 183 */ 184 bool verifyFile(const std::filesystem::path& file, 185 const std::filesystem::path& signature, 186 const std::filesystem::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 inline EVP_PKEY_Ptr createPublicRSA(const std::filesystem::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 CustomMap mapFile(const std::filesystem::path& path, size_t size); 203 204 /** @brief Directory where software images are placed*/ 205 std::filesystem::path imageDirPath; 206 207 /** @brief The PNOR file name in imageDirPath */ 208 std::string pnorFileName; 209 210 /** @brief Path of public key and hash function files */ 211 std::filesystem::path signedConfPath; 212 213 /** @brief key type defined in mainfest file */ 214 Key_t keyType; 215 216 /** @brief Hash type defined in mainfest file */ 217 Hash_t hashType; 218 }; 219 220 } // namespace image 221 } // namespace software 222 } // namespace openpower 223