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 <experimental/filesystem> 11 #include <set> 12 #include <string> 13 14 namespace openpower 15 { 16 namespace software 17 { 18 namespace image 19 { 20 21 namespace fs = std::experimental::filesystem; 22 using Key_t = std::string; 23 using Hash_t = std::string; 24 using PublicKeyPath = fs::path; 25 using HashFilePath = fs::path; 26 using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>; 27 using AvailableKeyTypes = std::set<Key_t>; 28 29 // RAII support for openSSL functions. 30 using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>; 31 using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>; 32 using EVP_MD_CTX_Ptr = 33 std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>; 34 35 /** @struct CustomFd 36 * 37 * RAII wrapper for file descriptor. 38 */ 39 struct CustomFd 40 { 41 public: 42 CustomFd() = delete; 43 CustomFd(const CustomFd&) = delete; 44 CustomFd& operator=(const CustomFd&) = delete; 45 CustomFd(CustomFd&&) = default; 46 CustomFd& operator=(CustomFd&&) = default; 47 /** @brief Saves File descriptor and uses it to do file operation 48 * 49 * @param[in] fd - File descriptor 50 */ 51 explicit CustomFd(int fd) : fd(fd) 52 {} 53 54 ~CustomFd() 55 { 56 if (fd >= 0) 57 { 58 close(fd); 59 } 60 } 61 62 int operator()() const 63 { 64 return fd; 65 } 66 67 private: 68 /** @brief File descriptor */ 69 int fd = -1; 70 }; 71 72 /** @struct CustomMap 73 * 74 * RAII wrapper for mmap. 75 */ 76 struct CustomMap 77 { 78 private: 79 /** @brief starting address of the map */ 80 void* addr; 81 82 /** @brief length of the mapping */ 83 size_t length; 84 85 public: 86 CustomMap() = delete; 87 CustomMap(const CustomMap&) = delete; 88 CustomMap& operator=(const CustomMap&) = delete; 89 CustomMap(CustomMap&&) = default; 90 CustomMap& operator=(CustomMap&&) = default; 91 92 /** @brief Saves starting address of the map and 93 * and length of the file. 94 * @param[in] addr - Starting address of the map 95 * @param[in] length - length of the map 96 */ 97 CustomMap(void* addr, size_t length) : addr(addr), length(length) 98 {} 99 100 ~CustomMap() 101 { 102 munmap(addr, length); 103 } 104 105 void* operator()() const 106 { 107 return addr; 108 } 109 }; 110 111 /** @class Signature 112 * @brief Contains signature verification functions. 113 * @details The software image class that contains the signature 114 * verification functions for signed image. 115 */ 116 class Signature 117 { 118 public: 119 Signature() = delete; 120 Signature(const Signature&) = delete; 121 Signature& operator=(const Signature&) = delete; 122 Signature(Signature&&) = default; 123 Signature& operator=(Signature&&) = default; 124 ~Signature() = default; 125 126 /** 127 * @brief Constructs Signature. 128 * @param[in] imageDirPath - image path 129 * @param[in] signedConfPath - Path of public key 130 * hash function files 131 */ 132 explicit Signature(const fs::path& imageDirPath, 133 const std::string& pnorFileName, 134 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 bool verifyFile(const fs::path& file, const fs::path& signature, 186 const fs::path& publicKey, const std::string& hashFunc); 187 188 /** 189 * @brief Create RSA object from the public key 190 * @param[in] - publickey 191 * @param[out] - RSA Object. 192 */ 193 inline RSA* createPublicRSA(const fs::path& publicKey); 194 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 203 /** @brief Directory where software images are placed*/ 204 fs::path imageDirPath; 205 206 /** @brief The PNOR file name in imageDirPath */ 207 std::string pnorFileName; 208 209 /** @brief Path of public key and hash function files */ 210 fs::path signedConfPath; 211 212 /** @brief key type defined in mainfest file */ 213 Key_t keyType; 214 215 /** @brief Hash type defined in mainfest file */ 216 Hash_t hashType; 217 }; 218 219 } // namespace image 220 } // namespace software 221 } // namespace openpower 222