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