#pragma once

#include "crypt_algo.hpp"
#include "integrity_algo.hpp"

#include <array>
#include <vector>

namespace cipher
{
namespace rakp_auth
{
constexpr size_t USER_KEY_MAX_LENGTH = 20;
constexpr size_t BMC_RANDOM_NUMBER_LEN = 16;
constexpr size_t REMOTE_CONSOLE_RANDOM_NUMBER_LEN = 16;
extern const std::string userName;

/**
 * @enum RAKP Authentication Algorithms
 *
 * RMCP+ Authenticated Key-Exchange Protocol (RAKP)
 *
 * RAKP-None is not supported as per the following recommendation
 * (https://www.us-cert.gov/ncas/alerts/TA13-207A)
 * ("cipher 0" is an option enabled by default on many IPMI enabled devices that
 * allows authentication to be bypassed.  Disable "cipher 0" to prevent
 * attackers from bypassing authentication and sending arbitrary IPMI commands.)
 */
enum class Algorithms : uint8_t
{
    RAKP_NONE = 0,    // Mandatory (implemented, not supported)
    RAKP_HMAC_SHA1,   // Mandatory (implemented, default choice in ipmitool)
    RAKP_HMAC_MD5,    // Optional (not implemented)
    RAKP_HMAC_SHA256, // Optional (implemented, best available)
    // Reserved used to indicate an invalid authentication algorithm
    RAKP_HMAC_INVALID = 0xB0
};

/**
 * @class Interface
 *
 * Interface is the base class for the Authentication Algorithms.
 * The Authentication Algorithm specifies the type of authentication “handshake”
 * process that is used and identifies any particular variations of hashing or
 * signature algorithm that is used as part of the process.
 *
 */
class Interface
{
  public:
    explicit Interface(integrity::Algorithms intAlgo,
                       crypt::Algorithms cryptAlgo) :
        intAlgo(intAlgo),
        cryptAlgo(cryptAlgo)
    {
    }

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

    /**
     * @brief Generate the Hash Message Authentication Code
     *
     * This API is invoked to generate the Key Exchange Authentication Code
     * in the RAKP2 and RAKP4 sequence and for generating the Session
     * Integrity Key.
     *
     * @param input message
     *
     * @return hash output
     *
     * @note The user key which is the secret key for the hash operation
     *        needs to be set before this operation.
     */
    std::vector<uint8_t> virtual generateHMAC(
        const std::vector<uint8_t>& input) const = 0;

    /**
     * @brief Generate the Integrity Check Value
     *
     * This API is invoked in the RAKP4 sequence for generating the
     * Integrity Check Value.
     *
     * @param input message
     *
     * @return hash output
     *
     * @note The session integrity key which is the secret key for the
     *        hash operation needs to be set before this operation.
     */
    std::vector<uint8_t> virtual generateICV(
        const std::vector<uint8_t>& input) const = 0;

    /**
     * @brief Check if the Authentication algorithm is supported
     *
     * @param[in] algo - authentication algorithm
     *
     * @return true if algorithm is supported else false
     *
     */
    static bool isAlgorithmSupported(Algorithms algo)
    {
        if (algo == Algorithms::RAKP_HMAC_SHA256)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    // User Key is hardcoded to PASSW0RD till the IPMI User account
    // management is in place.
    std::array<uint8_t, USER_KEY_MAX_LENGTH> userKey = {"0penBmc"};

    // Managed System Random Number
    std::array<uint8_t, BMC_RANDOM_NUMBER_LEN> bmcRandomNum;

    // Remote Console Random Number
    std::array<uint8_t, REMOTE_CONSOLE_RANDOM_NUMBER_LEN> rcRandomNum;

    // Session Integrity Key
    std::vector<uint8_t> sessionIntegrityKey;

    /**
     * Integrity Algorithm is activated and set in the session data only
     * once the session setup is succeeded in the RAKP34 command. But the
     * integrity algorithm is negotiated in the Open Session Request command
     * . So the integrity algorithm successfully negotiated is stored
     * in the authentication algorithm's instance.
     */
    integrity::Algorithms intAlgo;

    /**
     * Confidentiality Algorithm is activated and set in the session data
     * only once the session setup is succeeded in the RAKP34 command. But
     * the confidentiality algorithm is negotiated in the Open Session
     * Request command. So the confidentiality algorithm successfully
     * negotiated is stored in the authentication algorithm's instance.
     */
    crypt::Algorithms cryptAlgo;
};

/**
 * @class AlgoSHA1
 *
 * RAKP-HMAC-SHA1 specifies the use of RAKP messages for the key exchange
 * portion of establishing the session, and that HMAC-SHA1 (per [RFC2104]) is
 * used to create 20-byte Key Exchange Authentication Code fields in RAKP
 * Message 2 and RAKP Message 3. HMAC-SHA1-96(per [RFC2404]) is used for
 * generating a 12-byte Integrity Check Value field for RAKP Message 4.
 */

class AlgoSHA1 : public Interface
{
  public:
    static constexpr size_t integrityCheckValueLength = 12;

    explicit AlgoSHA1(integrity::Algorithms intAlgo,
                      crypt::Algorithms cryptAlgo) :
        Interface(intAlgo, cryptAlgo)
    {
    }

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

    std::vector<uint8_t>
        generateHMAC(const std::vector<uint8_t>& input) const override;

    std::vector<uint8_t>
        generateICV(const std::vector<uint8_t>& input) const override;
};

/**
 * @class AlgoSHA256
 *
 * RAKP-HMAC-SHA256 specifies the use of RAKP messages for the key exchange
 * portion of establishing the session, and that HMAC-SHA256 (per [FIPS 180-2]
 * and [RFC4634] and is used to create a 32-byte Key Exchange Authentication
 * Code fields in RAKP Message 2 and RAKP Message 3. HMAC-SHA256-128 (per
 * [RFC4868]) is used for generating a 16-byte Integrity Check Value field for
 * RAKP Message 4.
 */

class AlgoSHA256 : public Interface
{
  public:
    static constexpr size_t integrityCheckValueLength = 16;

    explicit AlgoSHA256(integrity::Algorithms intAlgo,
                        crypt::Algorithms cryptAlgo) :
        Interface(intAlgo, cryptAlgo)
    {
    }

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

    std::vector<uint8_t>
        generateHMAC(const std::vector<uint8_t>& input) const override;

    std::vector<uint8_t>
        generateICV(const std::vector<uint8_t>& input) const override;
};

} // namespace rakp_auth

} // namespace cipher
