|  | #pragma once | 
|  | #include "openssl_alloc.hpp" | 
|  | #include "version.hpp" | 
|  |  | 
|  | #include <openssl/evp.h> | 
|  | #include <openssl/pem.h> | 
|  | #include <openssl/rsa.h> | 
|  | #include <sys/mman.h> | 
|  | #include <unistd.h> | 
|  |  | 
|  | #include <filesystem> | 
|  | #include <set> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | namespace phosphor | 
|  | { | 
|  | namespace software | 
|  | { | 
|  | namespace image | 
|  | { | 
|  |  | 
|  | namespace fs = std::filesystem; | 
|  | using Key_t = std::string; | 
|  | using Hash_t = std::string; | 
|  | using PublicKeyPath = fs::path; | 
|  | using HashFilePath = fs::path; | 
|  | using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>; | 
|  | using AvailableKeyTypes = std::set<Key_t>; | 
|  | using VersionPurpose = | 
|  | sdbusplus::server::xyz::openbmc_project::software::Version::VersionPurpose; | 
|  |  | 
|  | // RAII support for openSSL functions. | 
|  | using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>; | 
|  | using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>; | 
|  | using EVP_MD_CTX_Ptr = | 
|  | std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>; | 
|  |  | 
|  | /** @struct CustomFd | 
|  | * | 
|  | *  RAII wrapper for file descriptor. | 
|  | */ | 
|  | struct CustomFd | 
|  | { | 
|  | public: | 
|  | CustomFd() = delete; | 
|  | CustomFd(const CustomFd&) = delete; | 
|  | CustomFd& operator=(const CustomFd&) = delete; | 
|  | CustomFd(CustomFd&&) = default; | 
|  | CustomFd& operator=(CustomFd&&) = default; | 
|  | /** @brief Saves File descriptor and uses it to do file operation | 
|  | * | 
|  | *  @param[in] fd - File descriptor | 
|  | */ | 
|  | explicit CustomFd(int fd) : fd(fd) {} | 
|  |  | 
|  | ~CustomFd() | 
|  | { | 
|  | if (fd >= 0) | 
|  | { | 
|  | close(fd); | 
|  | } | 
|  | } | 
|  |  | 
|  | int operator()() const | 
|  | { | 
|  | return fd; | 
|  | } | 
|  |  | 
|  | private: | 
|  | /** @brief File descriptor */ | 
|  | int fd = -1; | 
|  | }; | 
|  |  | 
|  | /** @struct CustomMap | 
|  | * | 
|  | *  RAII wrapper for mmap. | 
|  | */ | 
|  | struct CustomMap | 
|  | { | 
|  | private: | 
|  | /** @brief starting address of the map   */ | 
|  | void* addr; | 
|  |  | 
|  | /** @brief length of the mapping   */ | 
|  | size_t length; | 
|  |  | 
|  | public: | 
|  | CustomMap() = delete; | 
|  | CustomMap(const CustomMap&) = delete; | 
|  | CustomMap& operator=(const CustomMap&) = delete; | 
|  | CustomMap(CustomMap&&) = default; | 
|  | CustomMap& operator=(CustomMap&&) = default; | 
|  |  | 
|  | /** @brief Saves starting address of the map and | 
|  | *         and length of the file. | 
|  | *  @param[in]  addr - Starting address of the map | 
|  | *  @param[in]  length - length of the map | 
|  | */ | 
|  | CustomMap(void* addr, size_t length) : addr(addr), length(length) {} | 
|  |  | 
|  | ~CustomMap() | 
|  | { | 
|  | munmap(addr, length); | 
|  | } | 
|  |  | 
|  | void* operator()() const | 
|  | { | 
|  | return addr; | 
|  | } | 
|  | }; | 
|  |  | 
|  | /** @class Signature | 
|  | *  @brief Contains signature verification functions. | 
|  | *  @details The software image class that contains the signature | 
|  | *           verification functions for signed image. | 
|  | */ | 
|  | class Signature | 
|  | { | 
|  | public: | 
|  | Signature() = delete; | 
|  | Signature(const Signature&) = delete; | 
|  | Signature& operator=(const Signature&) = delete; | 
|  | Signature(Signature&&) = default; | 
|  | Signature& operator=(Signature&&) = default; | 
|  | ~Signature() = default; | 
|  |  | 
|  | /** | 
|  | * @brief Constructs Signature. | 
|  | * @param[in]  imageDirPath - image path | 
|  | * @param[in]  signedConfPath - Path of public key | 
|  | *                              hash function files | 
|  | */ | 
|  | Signature(const fs::path& imageDirPath, const fs::path& signedConfPath); | 
|  |  | 
|  | /** | 
|  | * @brief Image signature verification function. | 
|  | *        Verify the Manifest and public key file signature using the | 
|  | *        public keys available in the system first. After successful | 
|  | *        validation, continue the whole image files signature | 
|  | *        validation using the image specific public key and the | 
|  | *        hash function. | 
|  | * | 
|  | *        @return true if signature verification was successful, | 
|  | *                     false if not | 
|  | */ | 
|  | bool verify(); | 
|  |  | 
|  | private: | 
|  | /** | 
|  | * @brief Function used for system level file signature validation | 
|  | *        of image specific publickey file and manifest file | 
|  | *        using the available public keys and hash functions | 
|  | *        in the system. | 
|  | *        Refer code-update documentation for more details. | 
|  | */ | 
|  | bool systemLevelVerify(); | 
|  |  | 
|  | /** | 
|  | *  @brief Return all key types stored in the BMC based on the | 
|  | *         public key and hashfunc files stored in the BMC. | 
|  | * | 
|  | *  @return list | 
|  | */ | 
|  | AvailableKeyTypes getAvailableKeyTypesFromSystem() const; | 
|  |  | 
|  | /** | 
|  | *  @brief Return public key and hash function file names for the | 
|  | *  corresponding key type | 
|  | * | 
|  | *  @param[in]  key - key type | 
|  | *  @return Pair of hash and public key file names | 
|  | */ | 
|  | inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const; | 
|  |  | 
|  | /** | 
|  | * @brief Verify the file signature using public key and hash function | 
|  | * | 
|  | * @param[in]  - Image file path | 
|  | * @param[in]  - Signature file path | 
|  | * @param[in]  - Public key | 
|  | * @param[in]  - Hash function name | 
|  | * @return true if signature verification was successful, false if not | 
|  | */ | 
|  | static bool verifyFile(const fs::path& file, const fs::path& signature, | 
|  | const fs::path& publicKey, | 
|  | const std::string& hashFunc); | 
|  |  | 
|  | /** | 
|  | * @brief Create RSA object from the public key | 
|  | * @param[in]  - publickey | 
|  | * @param[out] - RSA Object. | 
|  | */ | 
|  | static inline EVP_PKEY_Ptr createPublicRSA(const fs::path& publicKey); | 
|  |  | 
|  | /** | 
|  | * @brief Memory map the  file | 
|  | * @param[in]  - file path | 
|  | * @param[in]  - file size | 
|  | * @param[out] - Custom Mmap address | 
|  | */ | 
|  | static CustomMap mapFile(const fs::path& path, size_t size); | 
|  |  | 
|  | /** | 
|  | * @brief Verify the full file signature using public key and hash function | 
|  | * | 
|  | * @return true if signature verification was successful, false if not | 
|  | */ | 
|  | bool verifyFullImage(); | 
|  |  | 
|  | /** @brief Directory where software images are placed*/ | 
|  | fs::path imageDirPath; | 
|  |  | 
|  | /** @brief Path of public key and hash function files */ | 
|  | fs::path signedConfPath; | 
|  |  | 
|  | /** @brief key type defined in manifest file */ | 
|  | Key_t keyType; | 
|  |  | 
|  | /** @brief Hash type defined in manifest file */ | 
|  | Hash_t hashType; | 
|  |  | 
|  | /** @brief The image purpose */ | 
|  | VersionPurpose purpose; | 
|  |  | 
|  | /** @brief Check and Verify the required image files | 
|  | * | 
|  | * @param[in] filePath - BMC tarball file path | 
|  | * @param[in] publicKeyPath - publicKey file Path | 
|  | * @param[in] imageList - Image filenames included in the BMC tarball | 
|  | * @param[out] fileFound - Indicate if the file to verify is found or not | 
|  | * | 
|  | * @return true if all image files are found in BMC tarball and | 
|  | * Verify Success false if one of image files is missing | 
|  | */ | 
|  | bool checkAndVerifyImage(const std::string& filePath, | 
|  | const std::string& publicKeyPath, | 
|  | const std::vector<std::string>& imageList, | 
|  | bool& fileFound); | 
|  | }; | 
|  |  | 
|  | } // namespace image | 
|  | } // namespace software | 
|  | } // namespace phosphor |