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 13 namespace openpower 14 { 15 namespace software 16 { 17 namespace image 18 { 19 20 namespace fs = std::experimental::filesystem; 21 using Key_t = std::string; 22 using Hash_t = std::string; 23 using PublicKeyPath = fs::path; 24 using HashFilePath = fs::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 // PNOR flash image file name. 35 constexpr auto squashFSImage = "pnor.xz.squashfs"; 36 37 /** @struct CustomFd 38 * 39 * RAII wrapper for file descriptor. 40 */ 41 struct CustomFd 42 { 43 public: 44 CustomFd() = delete; 45 CustomFd(const CustomFd&) = delete; 46 CustomFd& operator=(const CustomFd&) = delete; 47 CustomFd(CustomFd&&) = default; 48 CustomFd& operator=(CustomFd&&) = default; 49 /** @brief Saves File descriptor and uses it to do file operation 50 * 51 * @param[in] fd - File descriptor 52 */ 53 CustomFd(int fd) : fd(fd) 54 { 55 } 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 } 103 104 ~CustomMap() 105 { 106 munmap(addr, length); 107 } 108 109 void* operator()() const 110 { 111 return addr; 112 } 113 }; 114 115 /** @class Signature 116 * @brief Contains signature verification functions. 117 * @details The software image class that contains the signature 118 * verification functions for signed image. 119 */ 120 class Signature 121 { 122 public: 123 Signature() = delete; 124 Signature(const Signature&) = delete; 125 Signature& operator=(const Signature&) = delete; 126 Signature(Signature&&) = default; 127 Signature& operator=(Signature&&) = default; 128 ~Signature() = default; 129 130 /** 131 * @brief Constructs Signature. 132 * @param[in] imageDirPath - image path 133 * @param[in] signedConfPath - Path of public key 134 * hash function files 135 */ 136 Signature(const fs::path& imageDirPath, const fs::path& signedConfPath); 137 138 /** 139 * @brief Image signature verification function. 140 * Verify the Manifest and public key file signature using the 141 * public keys available in the system first. After successful 142 * validation, continue the whole image files signature 143 * validation using the image specific public key and the 144 * hash function. 145 * 146 * @return true if signature verification was successful, 147 * false if not 148 */ 149 bool verify(); 150 151 private: 152 /** 153 * @brief Function used for system level file signature validation 154 * of image specific publickey file and manifest file 155 * using the available public keys and hash functions 156 * in the system. 157 * Refer code-update documentation for more details. 158 */ 159 bool systemLevelVerify(); 160 161 /** 162 * @brief Return all key types stored in the BMC based on the 163 * public key and hashfunc files stored in the BMC. 164 * 165 * @return list 166 */ 167 AvailableKeyTypes getAvailableKeyTypesFromSystem() const; 168 169 /** 170 * @brief Return public key and hash function file names for the 171 * corresponding key type 172 * 173 * @param[in] key - key type 174 * @return Pair of hash and public key file names 175 */ 176 inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const; 177 178 /** 179 * @brief Verify the file signature using public key and hash function 180 * 181 * @param[in] - Image file path 182 * @param[in] - Signature file path 183 * @param[in] - Public key 184 * @param[in] - Hash function name 185 * @return true if signature verification was successful, false if not 186 */ 187 bool verifyFile(const fs::path& file, const fs::path& signature, 188 const fs::path& publicKey, const std::string& hashFunc); 189 190 /** 191 * @brief Create RSA object from the public key 192 * @param[in] - publickey 193 * @param[out] - RSA Object. 194 */ 195 inline RSA* createPublicRSA(const fs::path& publicKey); 196 197 /** 198 * @brief Memory map the file 199 * @param[in] - file path 200 * @param[in] - file size 201 * @param[out] - Custom Mmap address 202 */ 203 CustomMap mapFile(const fs::path& path, size_t size); 204 205 /** @brief Directory where software images are placed*/ 206 fs::path imageDirPath; 207 208 /** @brief Path of public key and hash function files */ 209 fs::path signedConfPath; 210 211 /** @brief key type defined in mainfest file */ 212 Key_t keyType; 213 214 /** @brief Hash type defined in mainfest file */ 215 Hash_t hashType; 216 }; 217 218 } // namespace image 219 } // namespace software 220 } // namespace openpower 221