#pragma once

#include <array>
#include <vector>
#include "rmcp.hpp"

namespace cipher
{

namespace integrity
{

/**
 * @enum Integrity Algorithms
 *
 * The Integrity Algorithm Number specifies the algorithm used to generate the
 * contents for the AuthCode “signature” field that accompanies authenticated
 * IPMI v2.0/RMCP+ messages once the session has been established. If the
 * Integrity Algorithm is none the AuthCode value is not calculated and the
 * AuthCode field in the message is not present.
 */
enum class Algorithms : uint8_t
{
    NONE,                  // Mandatory
    HMAC_SHA1_96,          // Mandatory
    HMAC_MD5_128,          // Optional
    MD5_128,               // Optional
    HMAC_SHA256_128,       // Optional
};

/**
 * @class Interface
 *
 * Interface is the base class for the Integrity Algorithms.
 * Unless otherwise specified, the integrity algorithm is applied to the packet
 * data starting with the AuthType/Format field up to and including the field
 * that immediately precedes the AuthCode field itself.
 */
class Interface
{
    public:
        /**
         * @brief Constructor for Interface
         *
         * @param[in] - AuthCode length
         */
        explicit Interface(size_t authLength)
            : authCodeLength(authLength) {}

        Interface() = delete;
        virtual ~Interface() = default;
        Interface(const Interface&) = default;
        Interface& operator=(const Interface&) = default;
        Interface(Interface&&) = default;
        Interface& operator=(Interface&&) = default;

        /**
         * @brief Verify the integrity data of the packet
         *
         * @param[in] packet - Incoming IPMI packet
         * @param[in] packetLen - Packet length excluding authCode
         * @param[in] integrityData - Iterator to the authCode in the packet
         *
         * @return true if authcode in the packet is equal to one generated
         *         using integrity algorithm on the packet data, false otherwise
         */
        bool virtual verifyIntegrityData(
                const std::vector<uint8_t>& packet,
                const size_t packetLen,
                std::vector<uint8_t>::const_iterator integrityData) const = 0;

        /**
         * @brief Generate integrity data for the outgoing IPMI packet
         *
         * @param[in] input - Outgoing IPMI packet
         *
         * @return authcode for the outgoing IPMI packet
         *
         */
        std::vector<uint8_t> virtual generateIntegrityData(
                const std::vector<uint8_t>& input) const = 0;

        /**
         * @brief Check if the Integrity algorithm is supported
         *
         * @param[in] algo - integrity algorithm
         *
         * @return true if algorithm is supported else false
         *
         */
        static bool isAlgorithmSupported(Algorithms algo)
        {
            if (algo == Algorithms::NONE ||
                algo == Algorithms::HMAC_SHA1_96 ||
                algo == Algorithms::HMAC_SHA256_128)
            {
               return true;
            }
            else
            {
                return false;
            }
        }

        /**
         * @brief Generate additional keying material based on SIK
         *
         * @note
         * The IPMI 2.0 spec only states that the additional keying material is
         * generated by running HMAC(constN) using SIK as the key. It does not
         * state whether this is the integrity algorithm or the authentication
         * algorithm. Other implementations of the RMCP+ algorithm (ipmitool
         * and ipmiutil) are not consistent on this matter. But it does not
         * really matter because based on any of the defined cipher suites, the
         * integrity and authentication algorithms are both based on the same
         * digest method (integrity::Algorithms::HMAC_SHA1_96 uses SHA1 and
         * rakp_auth::Algorithms::RAKP_HMAC_SHA1 uses SHA1). None of the
         * defined cipher suites mix and match digests for integrity and
         * authentication. Generating Kn belongs in either the integrity or
         * authentication classes, so in this implementation, integrity has
         * been chosen.
         *
         * @param[in] sik - session integrity key
         * @param[in] data - 20-byte Const_n
         *
         * @return on success returns the Kn based on this integrity class
         *
         */
        std::vector<uint8_t> virtual generateKn(
                const std::vector<uint8_t>& sik,
                const rmcp::Const_n& data) const = 0;

        /** @brief Authcode field
         *
         *  AuthCode field length varies based on the integrity algorithm, for
         *  HMAC-SHA1-96 the authcode field is 12 bytes. For HMAC-SHA256-128 and
         *  HMAC-MD5-128 the authcode field is 16 bytes.
         */
        size_t authCodeLength;

    protected:

        /** @brief K1 key used to generated the integrity data. */
        std::vector<uint8_t> k1;
};

/**
 * @class AlgoSHA1
 *
 * @brief Implementation of the HMAC-SHA1-96 Integrity algorithm
 *
 * HMAC-SHA1-96 take the Session Integrity Key and use it to generate K1. K1 is
 * then used as the key for use in HMAC to produce the AuthCode field.
 * For “one-key” logins, the user’s key (password) is used in the creation of
 * the Session Integrity Key. When the HMAC-SHA1-96 Integrity Algorithm is used
 * the resulting AuthCode field is 12 bytes (96 bits).
 */
class AlgoSHA1 final : public Interface
{
    public:
        static constexpr size_t SHA1_96_AUTHCODE_LENGTH = 12;

        /**
         * @brief Constructor for AlgoSHA1
         *
         * @param[in] - Session Integrity Key
         */
        explicit AlgoSHA1(const std::vector<uint8_t>& sik);

        AlgoSHA1() = delete;
        ~AlgoSHA1() = default;
        AlgoSHA1(const AlgoSHA1&) = default;
        AlgoSHA1& operator=(const AlgoSHA1&) = default;
        AlgoSHA1(AlgoSHA1&&) = default;
        AlgoSHA1& operator=(AlgoSHA1&&) = default;

        /**
         * @brief Verify the integrity data of the packet
         *
         * @param[in] packet - Incoming IPMI packet
         * @param[in] length - Length of the data in the packet to calculate
         *                     the integrity data
         * @param[in] integrityData - Iterator to the authCode in the packet
         *
         * @return true if authcode in the packet is equal to one generated
         *         using integrity algorithm on the packet data, false otherwise
         */
        bool verifyIntegrityData(
                const std::vector<uint8_t>& packet,
                const size_t length,
                std::vector<uint8_t>::const_iterator integrityData)
            const override;

        /**
         * @brief Generate integrity data for the outgoing IPMI packet
         *
         * @param[in] input - Outgoing IPMI packet
         *
         * @return on success return the integrity data for the outgoing IPMI
         *         packet
         */
        std::vector<uint8_t> generateIntegrityData(
                const std::vector<uint8_t>& packet) const override;

        /**
         * @brief Generate additional keying material based on SIK
         *
         * @param[in] sik - session integrity key
         * @param[in] data - 20-byte Const_n
         *
         * @return on success returns the Kn based on HMAC-SHA1
         *
         */
        std::vector<uint8_t> generateKn(
                const std::vector<uint8_t>& sik,
                const rmcp::Const_n& const_n) const;

    private:
        /**
         * @brief Generate HMAC based on HMAC-SHA1-96 algorithm
         *
         * @param[in] input - pointer to the message
         * @param[in] length - length of the message
         *
         * @return on success returns the message authentication code
         *
         */
        std::vector<uint8_t> generateHMAC(const uint8_t* input,
                const size_t len) const;
};

/**
 * @class AlgoSHA256
 *
 * @brief Implementation of the HMAC-SHA256-128 Integrity algorithm
 *
 * HMAC-SHA256-128 take the Session Integrity Key and use it to generate K1. K1
 * is then used as the key for use in HMAC to produce the AuthCode field.  For
 * “one-key” logins, the user’s key (password) is used in the creation of the
 * Session Integrity Key. When the HMAC-SHA256-128 Integrity Algorithm is used
 * the resulting AuthCode field is 16 bytes (128 bits).
 */
class AlgoSHA256 final : public Interface
{
    public:
        static constexpr size_t SHA256_128_AUTHCODE_LENGTH = 16;

        /**
         * @brief Constructor for AlgoSHA256
         *
         * @param[in] - Session Integrity Key
         */
        explicit AlgoSHA256(const std::vector<uint8_t>& sik);

        AlgoSHA256() = delete;
        ~AlgoSHA256() = default;
        AlgoSHA256(const AlgoSHA256&) = default;
        AlgoSHA256& operator=(const AlgoSHA256&) = default;
        AlgoSHA256(AlgoSHA256&&) = default;
        AlgoSHA256& operator=(AlgoSHA256&&) = default;

        /**
         * @brief Verify the integrity data of the packet
         *
         * @param[in] packet - Incoming IPMI packet
         * @param[in] length - Length of the data in the packet to calculate
         *                     the integrity data
         * @param[in] integrityData - Iterator to the authCode in the packet
         *
         * @return true if authcode in the packet is equal to one generated
         *         using integrity algorithm on the packet data, false otherwise
         */
        bool verifyIntegrityData(
                const std::vector<uint8_t>& packet,
                const size_t length,
                std::vector<uint8_t>::const_iterator integrityData)
            const override;

        /**
         * @brief Generate integrity data for the outgoing IPMI packet
         *
         * @param[in] packet - Outgoing IPMI packet
         *
         * @return on success return the integrity data for the outgoing IPMI
         *         packet
         */
        std::vector<uint8_t> generateIntegrityData(
                const std::vector<uint8_t>& packet) const override;

        /**
         * @brief Generate additional keying material based on SIK
         *
         * @param[in] sik - session integrity key
         * @param[in] data - 20-byte Const_n
         *
         * @return on success returns the Kn based on HMAC-SHA256
         *
         */
        std::vector<uint8_t> generateKn(
                const std::vector<uint8_t>& sik,
                const rmcp::Const_n& const_n) const;

    private:
        /**
         * @brief Generate HMAC based on HMAC-SHA256-128 algorithm
         *
         * @param[in] input - pointer to the message
         * @param[in] len - length of the message
         *
         * @return on success returns the message authentication code
         *
         */
        std::vector<uint8_t> generateHMAC(const uint8_t* input,
                const size_t len) const;
};

}// namespace integrity

}// namespace cipher

