#pragma once

#include "rmcp.hpp"

#include <array>
#include <cstddef>
#include <vector>

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. Based on security
 * recommendations NONE will not be supported.
 */
enum class Algorithms : uint8_t
{
    NONE,            // Mandatory (implemented, not supported)
    HMAC_SHA1_96,    // Mandatory (implemented, default choice in ipmitool)
    HMAC_MD5_128,    // Optional (not implemented)
    MD5_128,         // Optional (not implemented)
    HMAC_SHA256_128, // Optional (implemented, best available)
};

/**
 * @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] integrityDataBegin - Begin iterator to the authCode in the
     *                                 packet
     * @param[in] integrityDataEnd   - End 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 integrityDataBegin,
        std::vector<uint8_t>::const_iterator integrityDataEnd) 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::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] integrityDataBegin - Begin iterator to the authCode in the
     *                                 packet
     * @param[in] integrityDataEnd   - End 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 integrityDataBegin,
        std::vector<uint8_t>::const_iterator integrityDataEnd) 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] integrityDataBegin - Begin iterator to the authCode in the
     *                                 packet
     * @param[in] integrityDataEnd   - End 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 integrityDataBegin,
        std::vector<uint8_t>::const_iterator integrityDataEnd) 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
