19d7cd834SJayanth Othayoth #pragma once 2a013560fSJayashankar Padath #include "openssl_alloc.hpp" 36173a079SLei YU #include "version.hpp" 4b0ce996aSGunnar Mills 5fb6e1fc2SJayanth Othayoth #include <openssl/evp.h> 6fb6e1fc2SJayanth Othayoth #include <openssl/pem.h> 7b0ce996aSGunnar Mills #include <openssl/rsa.h> 8b0ce996aSGunnar Mills #include <sys/mman.h> 9b0ce996aSGunnar Mills #include <unistd.h> 10b0ce996aSGunnar Mills 11c98d912eSAdriana Kobylak #include <filesystem> 122ab9b109SJayanth Othayoth #include <set> 139155b713SAndrew Geissler #include <string> 14574f94bcSHenry Tian #include <vector> 159d7cd834SJayanth Othayoth 169d7cd834SJayanth Othayoth namespace phosphor 179d7cd834SJayanth Othayoth { 189d7cd834SJayanth Othayoth namespace software 199d7cd834SJayanth Othayoth { 209d7cd834SJayanth Othayoth namespace image 219d7cd834SJayanth Othayoth { 229d7cd834SJayanth Othayoth 23c98d912eSAdriana Kobylak namespace fs = std::filesystem; 242ab9b109SJayanth Othayoth using Key_t = std::string; 252ab9b109SJayanth Othayoth using Hash_t = std::string; 262ab9b109SJayanth Othayoth using PublicKeyPath = fs::path; 272ab9b109SJayanth Othayoth using HashFilePath = fs::path; 282ab9b109SJayanth Othayoth using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>; 292ab9b109SJayanth Othayoth using AvailableKeyTypes = std::set<Key_t>; 306173a079SLei YU using VersionPurpose = 316173a079SLei YU sdbusplus::xyz::openbmc_project::Software::server::Version::VersionPurpose; 329d7cd834SJayanth Othayoth 33fb6e1fc2SJayanth Othayoth // RAII support for openSSL functions. 34fb6e1fc2SJayanth Othayoth using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>; 35fb6e1fc2SJayanth Othayoth using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>; 36fb6e1fc2SJayanth Othayoth using EVP_MD_CTX_Ptr = 375ed9b2d7SAdriana Kobylak std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>; 38fb6e1fc2SJayanth Othayoth 39fb6e1fc2SJayanth Othayoth /** @struct CustomFd 40fb6e1fc2SJayanth Othayoth * 41fb6e1fc2SJayanth Othayoth * RAII wrapper for file descriptor. 42fb6e1fc2SJayanth Othayoth */ 43fb6e1fc2SJayanth Othayoth struct CustomFd 44fb6e1fc2SJayanth Othayoth { 45fb6e1fc2SJayanth Othayoth public: 46fb6e1fc2SJayanth Othayoth CustomFd() = delete; 47fb6e1fc2SJayanth Othayoth CustomFd(const CustomFd&) = delete; 48fb6e1fc2SJayanth Othayoth CustomFd& operator=(const CustomFd&) = delete; 49fb6e1fc2SJayanth Othayoth CustomFd(CustomFd&&) = default; 50fb6e1fc2SJayanth Othayoth CustomFd& operator=(CustomFd&&) = default; 51fb6e1fc2SJayanth Othayoth /** @brief Saves File descriptor and uses it to do file operation 52fb6e1fc2SJayanth Othayoth * 53fb6e1fc2SJayanth Othayoth * @param[in] fd - File descriptor 54fb6e1fc2SJayanth Othayoth */ 55*d5e8e73bSPatrick Williams explicit CustomFd(int fd) : fd(fd) {} 56fb6e1fc2SJayanth Othayoth 57fb6e1fc2SJayanth Othayoth ~CustomFd() 58fb6e1fc2SJayanth Othayoth { 59fb6e1fc2SJayanth Othayoth if (fd >= 0) 60fb6e1fc2SJayanth Othayoth { 61fb6e1fc2SJayanth Othayoth close(fd); 62fb6e1fc2SJayanth Othayoth } 63fb6e1fc2SJayanth Othayoth } 64fb6e1fc2SJayanth Othayoth 65fb6e1fc2SJayanth Othayoth int operator()() const 66fb6e1fc2SJayanth Othayoth { 67fb6e1fc2SJayanth Othayoth return fd; 68fb6e1fc2SJayanth Othayoth } 69fb6e1fc2SJayanth Othayoth 70fb6e1fc2SJayanth Othayoth private: 71fb6e1fc2SJayanth Othayoth /** @brief File descriptor */ 72fb6e1fc2SJayanth Othayoth int fd = -1; 73fb6e1fc2SJayanth Othayoth }; 74fb6e1fc2SJayanth Othayoth 75fb6e1fc2SJayanth Othayoth /** @struct CustomMap 76fb6e1fc2SJayanth Othayoth * 77fb6e1fc2SJayanth Othayoth * RAII wrapper for mmap. 78fb6e1fc2SJayanth Othayoth */ 79fb6e1fc2SJayanth Othayoth struct CustomMap 80fb6e1fc2SJayanth Othayoth { 81fb6e1fc2SJayanth Othayoth private: 82fb6e1fc2SJayanth Othayoth /** @brief starting address of the map */ 83fb6e1fc2SJayanth Othayoth void* addr; 84fb6e1fc2SJayanth Othayoth 85fb6e1fc2SJayanth Othayoth /** @brief length of the mapping */ 86fb6e1fc2SJayanth Othayoth size_t length; 87fb6e1fc2SJayanth Othayoth 88fb6e1fc2SJayanth Othayoth public: 89fb6e1fc2SJayanth Othayoth CustomMap() = delete; 90fb6e1fc2SJayanth Othayoth CustomMap(const CustomMap&) = delete; 91fb6e1fc2SJayanth Othayoth CustomMap& operator=(const CustomMap&) = delete; 92fb6e1fc2SJayanth Othayoth CustomMap(CustomMap&&) = default; 93fb6e1fc2SJayanth Othayoth CustomMap& operator=(CustomMap&&) = default; 94fb6e1fc2SJayanth Othayoth 95fb6e1fc2SJayanth Othayoth /** @brief Saves starting address of the map and 96fb6e1fc2SJayanth Othayoth * and length of the file. 97fb6e1fc2SJayanth Othayoth * @param[in] addr - Starting address of the map 98fb6e1fc2SJayanth Othayoth * @param[in] length - length of the map 99fb6e1fc2SJayanth Othayoth */ 100*d5e8e73bSPatrick Williams CustomMap(void* addr, size_t length) : addr(addr), length(length) {} 101fb6e1fc2SJayanth Othayoth 102fb6e1fc2SJayanth Othayoth ~CustomMap() 103fb6e1fc2SJayanth Othayoth { 104fb6e1fc2SJayanth Othayoth munmap(addr, length); 105fb6e1fc2SJayanth Othayoth } 106fb6e1fc2SJayanth Othayoth 107fb6e1fc2SJayanth Othayoth void* operator()() const 108fb6e1fc2SJayanth Othayoth { 109fb6e1fc2SJayanth Othayoth return addr; 110fb6e1fc2SJayanth Othayoth } 111fb6e1fc2SJayanth Othayoth }; 112fb6e1fc2SJayanth Othayoth 1139d7cd834SJayanth Othayoth /** @class Signature 1149d7cd834SJayanth Othayoth * @brief Contains signature verification functions. 1159d7cd834SJayanth Othayoth * @details The software image class that contains the signature 1169d7cd834SJayanth Othayoth * verification functions for signed image. 1179d7cd834SJayanth Othayoth */ 1189d7cd834SJayanth Othayoth class Signature 1199d7cd834SJayanth Othayoth { 1209d7cd834SJayanth Othayoth public: 1219d7cd834SJayanth Othayoth Signature() = delete; 1229d7cd834SJayanth Othayoth Signature(const Signature&) = delete; 1239d7cd834SJayanth Othayoth Signature& operator=(const Signature&) = delete; 1249d7cd834SJayanth Othayoth Signature(Signature&&) = default; 1259d7cd834SJayanth Othayoth Signature& operator=(Signature&&) = default; 1269d7cd834SJayanth Othayoth ~Signature() = default; 1279d7cd834SJayanth Othayoth 1282ab9b109SJayanth Othayoth /** 1292ab9b109SJayanth Othayoth * @brief Constructs Signature. 1302ab9b109SJayanth Othayoth * @param[in] imageDirPath - image path 1312ab9b109SJayanth Othayoth * @param[in] signedConfPath - Path of public key 1322ab9b109SJayanth Othayoth * hash function files 1339d7cd834SJayanth Othayoth */ 1342ab9b109SJayanth Othayoth Signature(const fs::path& imageDirPath, const fs::path& signedConfPath); 1359d7cd834SJayanth Othayoth 1369d7cd834SJayanth Othayoth /** 1379d7cd834SJayanth Othayoth * @brief Image signature verification function. 1389d7cd834SJayanth Othayoth * Verify the Manifest and public key file signature using the 1399d7cd834SJayanth Othayoth * public keys available in the system first. After successful 1409d7cd834SJayanth Othayoth * validation, continue the whole image files signature 1419d7cd834SJayanth Othayoth * validation using the image specific public key and the 1429d7cd834SJayanth Othayoth * hash function. 1439d7cd834SJayanth Othayoth * 1449d7cd834SJayanth Othayoth * @return true if signature verification was successful, 1459d7cd834SJayanth Othayoth * false if not 1469d7cd834SJayanth Othayoth */ 1479d7cd834SJayanth Othayoth bool verify(); 1489d7cd834SJayanth Othayoth 1499d7cd834SJayanth Othayoth private: 1502ab9b109SJayanth Othayoth /** 1512ab9b109SJayanth Othayoth * @brief Function used for system level file signature validation 152e11a2028SGunnar Mills * of image specific publickey file and manifest file 1532ab9b109SJayanth Othayoth * using the available public keys and hash functions 1542ab9b109SJayanth Othayoth * in the system. 1552bcba02aSGunnar Mills * Refer code-update documentation for more details. 1562ab9b109SJayanth Othayoth */ 1572ab9b109SJayanth Othayoth bool systemLevelVerify(); 1582ab9b109SJayanth Othayoth 1592ab9b109SJayanth Othayoth /** 1602ab9b109SJayanth Othayoth * @brief Return all key types stored in the BMC based on the 1612ab9b109SJayanth Othayoth * public key and hashfunc files stored in the BMC. 1622ab9b109SJayanth Othayoth * 1632ab9b109SJayanth Othayoth * @return list 1642ab9b109SJayanth Othayoth */ 1652ab9b109SJayanth Othayoth AvailableKeyTypes getAvailableKeyTypesFromSystem() const; 1662ab9b109SJayanth Othayoth 1672ab9b109SJayanth Othayoth /** 1682ab9b109SJayanth Othayoth * @brief Return public key and hash function file names for the 1692ab9b109SJayanth Othayoth * corresponding key type 1702ab9b109SJayanth Othayoth * 1712ab9b109SJayanth Othayoth * @param[in] key - key type 1722ab9b109SJayanth Othayoth * @return Pair of hash and public key file names 1732ab9b109SJayanth Othayoth */ 1742ab9b109SJayanth Othayoth inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const; 1752ab9b109SJayanth Othayoth 1762ab9b109SJayanth Othayoth /** 1772ab9b109SJayanth Othayoth * @brief Verify the file signature using public key and hash function 1782ab9b109SJayanth Othayoth * 1792ab9b109SJayanth Othayoth * @param[in] - Image file path 1802ab9b109SJayanth Othayoth * @param[in] - Signature file path 1812ab9b109SJayanth Othayoth * @param[in] - Public key 1822ab9b109SJayanth Othayoth * @param[in] - Hash function name 1832ab9b109SJayanth Othayoth * @return true if signature verification was successful, false if not 1842ab9b109SJayanth Othayoth */ 1852ab9b109SJayanth Othayoth bool verifyFile(const fs::path& file, const fs::path& signature, 1862ab9b109SJayanth Othayoth const fs::path& publicKey, const std::string& hashFunc); 1872ab9b109SJayanth Othayoth 188fb6e1fc2SJayanth Othayoth /** 189fb6e1fc2SJayanth Othayoth * @brief Create RSA object from the public key 190fb6e1fc2SJayanth Othayoth * @param[in] - publickey 191fb6e1fc2SJayanth Othayoth * @param[out] - RSA Object. 192fb6e1fc2SJayanth Othayoth */ 193d75c869dSPatrick Williams inline EVP_PKEY_Ptr createPublicRSA(const fs::path& publicKey); 194fb6e1fc2SJayanth Othayoth 195fb6e1fc2SJayanth Othayoth /** 196fb6e1fc2SJayanth Othayoth * @brief Memory map the file 197fb6e1fc2SJayanth Othayoth * @param[in] - file path 198fb6e1fc2SJayanth Othayoth * @param[in] - file size 199fb6e1fc2SJayanth Othayoth * @param[out] - Custom Mmap address 200fb6e1fc2SJayanth Othayoth */ 201fb6e1fc2SJayanth Othayoth CustomMap mapFile(const fs::path& path, size_t size); 202fb6e1fc2SJayanth Othayoth 2030a06e97fSGeorge Liu /** 2040a06e97fSGeorge Liu * @brief Verify the full file signature using public key and hash function 2050a06e97fSGeorge Liu * 2060a06e97fSGeorge Liu * @return true if signature verification was successful, false if not 2070a06e97fSGeorge Liu */ 2080a06e97fSGeorge Liu bool verifyFullImage(); 2090a06e97fSGeorge Liu 2109d7cd834SJayanth Othayoth /** @brief Directory where software images are placed*/ 2119d7cd834SJayanth Othayoth fs::path imageDirPath; 2122ab9b109SJayanth Othayoth 2132ab9b109SJayanth Othayoth /** @brief Path of public key and hash function files */ 2142ab9b109SJayanth Othayoth fs::path signedConfPath; 2152ab9b109SJayanth Othayoth 2162ab9b109SJayanth Othayoth /** @brief key type defined in mainfest file */ 2172ab9b109SJayanth Othayoth Key_t keyType; 2182ab9b109SJayanth Othayoth 2192ab9b109SJayanth Othayoth /** @brief Hash type defined in mainfest file */ 2202ab9b109SJayanth Othayoth Hash_t hashType; 221574f94bcSHenry Tian 2226173a079SLei YU /** @brief The image purpose */ 2236173a079SLei YU VersionPurpose purpose; 2246173a079SLei YU 225574f94bcSHenry Tian /** @brief Check and Verify the required image files 226574f94bcSHenry Tian * 227574f94bcSHenry Tian * @param[in] filePath - BMC tarball file path 228574f94bcSHenry Tian * @param[in] publicKeyPath - publicKey file Path 229574f94bcSHenry Tian * @param[in] imageList - Image filenames included in the BMC tarball 2307ab55e20SLei YU * @param[out] fileFound - Indicate if the file to verify is found or not 2317ab55e20SLei YU * 2327ab55e20SLei YU * @return true if all image files are found in BMC tarball and 233574f94bcSHenry Tian * Verify Sucess false if one of image files is missing 234574f94bcSHenry Tian */ 235574f94bcSHenry Tian bool checkAndVerifyImage(const std::string& filePath, 236574f94bcSHenry Tian const std::string& publicKeyPath, 2377ab55e20SLei YU const std::vector<std::string>& imageList, 2387ab55e20SLei YU bool& fileFound); 2399d7cd834SJayanth Othayoth }; 2409d7cd834SJayanth Othayoth 2419d7cd834SJayanth Othayoth } // namespace image 2429d7cd834SJayanth Othayoth } // namespace software 2439d7cd834SJayanth Othayoth } // namespace phosphor 244