#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_SHA1 ||
            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
