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 */ CustomFdopenpower::software::image::CustomFd50 explicit CustomFd(int fd) : fd(fd) {} 51 ~CustomFdopenpower::software::image::CustomFd52 ~CustomFd() 53 { 54 if (fd >= 0) 55 { 56 close(fd); 57 } 58 } 59 operator ()openpower::software::image::CustomFd60 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 */ 74 struct 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 */ CustomMapopenpower::software::image::CustomMap95 CustomMap(void* addr, size_t length) : addr(addr), length(length) {} 96 ~CustomMapopenpower::software::image::CustomMap97 ~CustomMap() 98 { 99 munmap(addr, length); 100 } 101 operator ()openpower::software::image::CustomMap102 void* operator()() const 103 { 104 return addr; 105 } 106 }; 107 108 /** @class Signature 109 * @brief Contains signature verification functions. 110 * @details The software image class that contains the signature 111 * verification functions for signed image. 112 */ 113 class Signature 114 { 115 public: 116 Signature() = delete; 117 Signature(const Signature&) = delete; 118 Signature& operator=(const Signature&) = delete; 119 Signature(Signature&&) = default; 120 Signature& operator=(Signature&&) = default; 121 ~Signature() = default; 122 123 /** 124 * @brief Constructs Signature. 125 * @param[in] imageDirPath - image path 126 * @param[in] signedConfPath - Path of public key 127 * hash function files 128 */ 129 explicit Signature(const std::filesystem::path& imageDirPath, 130 const std::string& pnorFileName, 131 const std::filesystem::path& signedConfPath); 132 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: 147 /** 148 * @brief Function used for system level file signature validation 149 * of image specific publickey file and manifest file 150 * using the available public keys and hash functions 151 * in the system. 152 * Refer code-update documentation for more details. 153 */ 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 std::filesystem::path& file, 183 const std::filesystem::path& signature, 184 const std::filesystem::path& publicKey, 185 const std::string& hashFunc); 186 187 /** 188 * @brief Create RSA object from the public key 189 * @param[in] - publickey 190 * @param[out] - RSA Object. 191 */ 192 inline EVP_PKEY_Ptr createPublicRSA(const std::filesystem::path& publicKey); 193 194 /** 195 * @brief Memory map the file 196 * @param[in] - file path 197 * @param[in] - file size 198 * @param[out] - Custom Mmap address 199 */ 200 CustomMap mapFile(const std::filesystem::path& path, size_t size); 201 202 /** @brief Directory where software images are placed*/ 203 std::filesystem::path imageDirPath; 204 205 /** @brief The PNOR file name in imageDirPath */ 206 std::string pnorFileName; 207 208 /** @brief Path of public key and hash function files */ 209 std::filesystem::path signedConfPath; 210 211 /** @brief key type defined in manifest file */ 212 Key_t keyType; 213 214 /** @brief Hash type defined in manifest file */ 215 Hash_t hashType; 216 }; 217 218 } // namespace image 219 } // namespace software 220 } // namespace openpower 221