#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] 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::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
