Add support for signature verification routines

Enabled high level logic flow for the PNOR signed image
signature validation routines.

Includes reading hash type, key type from Manifest file.

Change-Id: I00280fff5a61291852c1f2d5f6fd8aec3dd62bf0
Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
diff --git a/image_verify.hpp b/image_verify.hpp
new file mode 100644
index 0000000..77fa6f4
--- /dev/null
+++ b/image_verify.hpp
@@ -0,0 +1,217 @@
+#pragma once
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <experimental/filesystem>
+#include <set>
+#include <unistd.h>
+#include <sys/mman.h>
+
+namespace openpower
+{
+namespace software
+{
+namespace image
+{
+
+namespace fs = std::experimental::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>;
+
+// 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_destroy)>;
+
+// PNOR flash image file name.
+constexpr auto squashFSImage = "pnor.xz.squashfs";
+
+/** @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
+     */
+    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
+     */
+    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.
+     */
+    inline RSA* createPublicRSA(const fs::path& publicKey);
+
+    /**
+     * @brief Memory map the  file
+     * @param[in]  - file path
+     * @param[in]  - file size
+     * @param[out] - Custom Mmap address
+     */
+    CustomMap mapFile(const fs::path& path, size_t size);
+
+    /** @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 mainfest file */
+    Key_t keyType;
+
+    /** @brief Hash type defined in mainfest file */
+    Hash_t hashType;
+};
+
+} // namespace image
+} // namespace software
+} // namespace openpower