19d7cd834SJayanth Othayoth #pragma once 2a013560fSJayashankar Padath #include "openssl_alloc.hpp" 3b0ce996aSGunnar Mills 4fb6e1fc2SJayanth Othayoth #include <openssl/evp.h> 5fb6e1fc2SJayanth Othayoth #include <openssl/pem.h> 6b0ce996aSGunnar Mills #include <openssl/rsa.h> 7b0ce996aSGunnar Mills #include <sys/mman.h> 8b0ce996aSGunnar Mills #include <unistd.h> 9b0ce996aSGunnar Mills 10c98d912eSAdriana Kobylak #include <filesystem> 112ab9b109SJayanth Othayoth #include <set> 129155b713SAndrew Geissler #include <string> 13574f94bcSHenry Tian #include <vector> 149d7cd834SJayanth Othayoth 159d7cd834SJayanth Othayoth namespace phosphor 169d7cd834SJayanth Othayoth { 179d7cd834SJayanth Othayoth namespace software 189d7cd834SJayanth Othayoth { 199d7cd834SJayanth Othayoth namespace image 209d7cd834SJayanth Othayoth { 219d7cd834SJayanth Othayoth 22c98d912eSAdriana Kobylak namespace fs = std::filesystem; 232ab9b109SJayanth Othayoth using Key_t = std::string; 242ab9b109SJayanth Othayoth using Hash_t = std::string; 252ab9b109SJayanth Othayoth using PublicKeyPath = fs::path; 262ab9b109SJayanth Othayoth using HashFilePath = fs::path; 272ab9b109SJayanth Othayoth using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>; 282ab9b109SJayanth Othayoth using AvailableKeyTypes = std::set<Key_t>; 299d7cd834SJayanth Othayoth 30fb6e1fc2SJayanth Othayoth // RAII support for openSSL functions. 31fb6e1fc2SJayanth Othayoth using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>; 32fb6e1fc2SJayanth Othayoth using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>; 33fb6e1fc2SJayanth Othayoth using EVP_MD_CTX_Ptr = 345ed9b2d7SAdriana Kobylak std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>; 35fb6e1fc2SJayanth Othayoth 36fb6e1fc2SJayanth Othayoth /** @struct CustomFd 37fb6e1fc2SJayanth Othayoth * 38fb6e1fc2SJayanth Othayoth * RAII wrapper for file descriptor. 39fb6e1fc2SJayanth Othayoth */ 40fb6e1fc2SJayanth Othayoth struct CustomFd 41fb6e1fc2SJayanth Othayoth { 42fb6e1fc2SJayanth Othayoth public: 43fb6e1fc2SJayanth Othayoth CustomFd() = delete; 44fb6e1fc2SJayanth Othayoth CustomFd(const CustomFd&) = delete; 45fb6e1fc2SJayanth Othayoth CustomFd& operator=(const CustomFd&) = delete; 46fb6e1fc2SJayanth Othayoth CustomFd(CustomFd&&) = default; 47fb6e1fc2SJayanth Othayoth CustomFd& operator=(CustomFd&&) = default; 48fb6e1fc2SJayanth Othayoth /** @brief Saves File descriptor and uses it to do file operation 49fb6e1fc2SJayanth Othayoth * 50fb6e1fc2SJayanth Othayoth * @param[in] fd - File descriptor 51fb6e1fc2SJayanth Othayoth */ 52fb6e1fc2SJayanth Othayoth CustomFd(int fd) : fd(fd) 5358aa7508SAdriana Kobylak {} 54fb6e1fc2SJayanth Othayoth 55fb6e1fc2SJayanth Othayoth ~CustomFd() 56fb6e1fc2SJayanth Othayoth { 57fb6e1fc2SJayanth Othayoth if (fd >= 0) 58fb6e1fc2SJayanth Othayoth { 59fb6e1fc2SJayanth Othayoth close(fd); 60fb6e1fc2SJayanth Othayoth } 61fb6e1fc2SJayanth Othayoth } 62fb6e1fc2SJayanth Othayoth 63fb6e1fc2SJayanth Othayoth int operator()() const 64fb6e1fc2SJayanth Othayoth { 65fb6e1fc2SJayanth Othayoth return fd; 66fb6e1fc2SJayanth Othayoth } 67fb6e1fc2SJayanth Othayoth 68fb6e1fc2SJayanth Othayoth private: 69fb6e1fc2SJayanth Othayoth /** @brief File descriptor */ 70fb6e1fc2SJayanth Othayoth int fd = -1; 71fb6e1fc2SJayanth Othayoth }; 72fb6e1fc2SJayanth Othayoth 73fb6e1fc2SJayanth Othayoth /** @struct CustomMap 74fb6e1fc2SJayanth Othayoth * 75fb6e1fc2SJayanth Othayoth * RAII wrapper for mmap. 76fb6e1fc2SJayanth Othayoth */ 77fb6e1fc2SJayanth Othayoth struct CustomMap 78fb6e1fc2SJayanth Othayoth { 79fb6e1fc2SJayanth Othayoth private: 80fb6e1fc2SJayanth Othayoth /** @brief starting address of the map */ 81fb6e1fc2SJayanth Othayoth void* addr; 82fb6e1fc2SJayanth Othayoth 83fb6e1fc2SJayanth Othayoth /** @brief length of the mapping */ 84fb6e1fc2SJayanth Othayoth size_t length; 85fb6e1fc2SJayanth Othayoth 86fb6e1fc2SJayanth Othayoth public: 87fb6e1fc2SJayanth Othayoth CustomMap() = delete; 88fb6e1fc2SJayanth Othayoth CustomMap(const CustomMap&) = delete; 89fb6e1fc2SJayanth Othayoth CustomMap& operator=(const CustomMap&) = delete; 90fb6e1fc2SJayanth Othayoth CustomMap(CustomMap&&) = default; 91fb6e1fc2SJayanth Othayoth CustomMap& operator=(CustomMap&&) = default; 92fb6e1fc2SJayanth Othayoth 93fb6e1fc2SJayanth Othayoth /** @brief Saves starting address of the map and 94fb6e1fc2SJayanth Othayoth * and length of the file. 95fb6e1fc2SJayanth Othayoth * @param[in] addr - Starting address of the map 96fb6e1fc2SJayanth Othayoth * @param[in] length - length of the map 97fb6e1fc2SJayanth Othayoth */ 98fb6e1fc2SJayanth Othayoth CustomMap(void* addr, size_t length) : addr(addr), length(length) 9958aa7508SAdriana Kobylak {} 100fb6e1fc2SJayanth Othayoth 101fb6e1fc2SJayanth Othayoth ~CustomMap() 102fb6e1fc2SJayanth Othayoth { 103fb6e1fc2SJayanth Othayoth munmap(addr, length); 104fb6e1fc2SJayanth Othayoth } 105fb6e1fc2SJayanth Othayoth 106fb6e1fc2SJayanth Othayoth void* operator()() const 107fb6e1fc2SJayanth Othayoth { 108fb6e1fc2SJayanth Othayoth return addr; 109fb6e1fc2SJayanth Othayoth } 110fb6e1fc2SJayanth Othayoth }; 111fb6e1fc2SJayanth Othayoth 1129d7cd834SJayanth Othayoth /** @class Signature 1139d7cd834SJayanth Othayoth * @brief Contains signature verification functions. 1149d7cd834SJayanth Othayoth * @details The software image class that contains the signature 1159d7cd834SJayanth Othayoth * verification functions for signed image. 1169d7cd834SJayanth Othayoth */ 1179d7cd834SJayanth Othayoth class Signature 1189d7cd834SJayanth Othayoth { 1199d7cd834SJayanth Othayoth public: 1209d7cd834SJayanth Othayoth Signature() = delete; 1219d7cd834SJayanth Othayoth Signature(const Signature&) = delete; 1229d7cd834SJayanth Othayoth Signature& operator=(const Signature&) = delete; 1239d7cd834SJayanth Othayoth Signature(Signature&&) = default; 1249d7cd834SJayanth Othayoth Signature& operator=(Signature&&) = default; 1259d7cd834SJayanth Othayoth ~Signature() = default; 1269d7cd834SJayanth Othayoth 1272ab9b109SJayanth Othayoth /** 1282ab9b109SJayanth Othayoth * @brief Constructs Signature. 1292ab9b109SJayanth Othayoth * @param[in] imageDirPath - image path 1302ab9b109SJayanth Othayoth * @param[in] signedConfPath - Path of public key 1312ab9b109SJayanth Othayoth * hash function files 1329d7cd834SJayanth Othayoth */ 1332ab9b109SJayanth Othayoth Signature(const fs::path& imageDirPath, const fs::path& signedConfPath); 1349d7cd834SJayanth Othayoth 1359d7cd834SJayanth Othayoth /** 1369d7cd834SJayanth Othayoth * @brief Image signature verification function. 1379d7cd834SJayanth Othayoth * Verify the Manifest and public key file signature using the 1389d7cd834SJayanth Othayoth * public keys available in the system first. After successful 1399d7cd834SJayanth Othayoth * validation, continue the whole image files signature 1409d7cd834SJayanth Othayoth * validation using the image specific public key and the 1419d7cd834SJayanth Othayoth * hash function. 1429d7cd834SJayanth Othayoth * 1439d7cd834SJayanth Othayoth * @return true if signature verification was successful, 1449d7cd834SJayanth Othayoth * false if not 1459d7cd834SJayanth Othayoth */ 1469d7cd834SJayanth Othayoth bool verify(); 1479d7cd834SJayanth Othayoth 1489d7cd834SJayanth Othayoth private: 1492ab9b109SJayanth Othayoth /** 1502ab9b109SJayanth Othayoth * @brief Function used for system level file signature validation 151e11a2028SGunnar Mills * of image specific publickey file and manifest file 1522ab9b109SJayanth Othayoth * using the available public keys and hash functions 1532ab9b109SJayanth Othayoth * in the system. 1542bcba02aSGunnar Mills * Refer code-update documentation for more details. 1552ab9b109SJayanth Othayoth */ 1562ab9b109SJayanth Othayoth bool systemLevelVerify(); 1572ab9b109SJayanth Othayoth 1582ab9b109SJayanth Othayoth /** 1592ab9b109SJayanth Othayoth * @brief Return all key types stored in the BMC based on the 1602ab9b109SJayanth Othayoth * public key and hashfunc files stored in the BMC. 1612ab9b109SJayanth Othayoth * 1622ab9b109SJayanth Othayoth * @return list 1632ab9b109SJayanth Othayoth */ 1642ab9b109SJayanth Othayoth AvailableKeyTypes getAvailableKeyTypesFromSystem() const; 1652ab9b109SJayanth Othayoth 1662ab9b109SJayanth Othayoth /** 1672ab9b109SJayanth Othayoth * @brief Return public key and hash function file names for the 1682ab9b109SJayanth Othayoth * corresponding key type 1692ab9b109SJayanth Othayoth * 1702ab9b109SJayanth Othayoth * @param[in] key - key type 1712ab9b109SJayanth Othayoth * @return Pair of hash and public key file names 1722ab9b109SJayanth Othayoth */ 1732ab9b109SJayanth Othayoth inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const; 1742ab9b109SJayanth Othayoth 1752ab9b109SJayanth Othayoth /** 1762ab9b109SJayanth Othayoth * @brief Verify the file signature using public key and hash function 1772ab9b109SJayanth Othayoth * 1782ab9b109SJayanth Othayoth * @param[in] - Image file path 1792ab9b109SJayanth Othayoth * @param[in] - Signature file path 1802ab9b109SJayanth Othayoth * @param[in] - Public key 1812ab9b109SJayanth Othayoth * @param[in] - Hash function name 1822ab9b109SJayanth Othayoth * @return true if signature verification was successful, false if not 1832ab9b109SJayanth Othayoth */ 1842ab9b109SJayanth Othayoth bool verifyFile(const fs::path& file, const fs::path& signature, 1852ab9b109SJayanth Othayoth const fs::path& publicKey, const std::string& hashFunc); 1862ab9b109SJayanth Othayoth 187fb6e1fc2SJayanth Othayoth /** 188fb6e1fc2SJayanth Othayoth * @brief Create RSA object from the public key 189fb6e1fc2SJayanth Othayoth * @param[in] - publickey 190fb6e1fc2SJayanth Othayoth * @param[out] - RSA Object. 191fb6e1fc2SJayanth Othayoth */ 192fb6e1fc2SJayanth Othayoth inline RSA* createPublicRSA(const fs::path& publicKey); 193fb6e1fc2SJayanth Othayoth 194fb6e1fc2SJayanth Othayoth /** 195fb6e1fc2SJayanth Othayoth * @brief Memory map the file 196fb6e1fc2SJayanth Othayoth * @param[in] - file path 197fb6e1fc2SJayanth Othayoth * @param[in] - file size 198fb6e1fc2SJayanth Othayoth * @param[out] - Custom Mmap address 199fb6e1fc2SJayanth Othayoth */ 200fb6e1fc2SJayanth Othayoth CustomMap mapFile(const fs::path& path, size_t size); 201fb6e1fc2SJayanth Othayoth 202*0a06e97fSGeorge Liu /** 203*0a06e97fSGeorge Liu * @brief Verify the full file signature using public key and hash function 204*0a06e97fSGeorge Liu * 205*0a06e97fSGeorge Liu * @return true if signature verification was successful, false if not 206*0a06e97fSGeorge Liu */ 207*0a06e97fSGeorge Liu bool verifyFullImage(); 208*0a06e97fSGeorge Liu 2099d7cd834SJayanth Othayoth /** @brief Directory where software images are placed*/ 2109d7cd834SJayanth Othayoth fs::path imageDirPath; 2112ab9b109SJayanth Othayoth 2122ab9b109SJayanth Othayoth /** @brief Path of public key and hash function files */ 2132ab9b109SJayanth Othayoth fs::path signedConfPath; 2142ab9b109SJayanth Othayoth 2152ab9b109SJayanth Othayoth /** @brief key type defined in mainfest file */ 2162ab9b109SJayanth Othayoth Key_t keyType; 2172ab9b109SJayanth Othayoth 2182ab9b109SJayanth Othayoth /** @brief Hash type defined in mainfest file */ 2192ab9b109SJayanth Othayoth Hash_t hashType; 220574f94bcSHenry Tian 221574f94bcSHenry Tian /** @brief Check and Verify the required image files 222574f94bcSHenry Tian * 223574f94bcSHenry Tian * @param[in] filePath - BMC tarball file path 224574f94bcSHenry Tian * @param[in] publicKeyPath - publicKey file Path 225574f94bcSHenry Tian * @param[in] imageList - Image filenames included in the BMC tarball 226574f94bcSHenry Tian * @param[out] result - Boolean 227574f94bcSHenry Tian * true if all image files are found in BMC tarball and 228574f94bcSHenry Tian * Verify Sucess false if one of image files is missing 229574f94bcSHenry Tian */ 230574f94bcSHenry Tian bool checkAndVerifyImage(const std::string& filePath, 231574f94bcSHenry Tian const std::string& publicKeyPath, 232574f94bcSHenry Tian const std::vector<std::string>& imageList); 2339d7cd834SJayanth Othayoth }; 2349d7cd834SJayanth Othayoth 2359d7cd834SJayanth Othayoth } // namespace image 2369d7cd834SJayanth Othayoth } // namespace software 2379d7cd834SJayanth Othayoth } // namespace phosphor 238