#pragma once

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

#include <array>
#include <cstddef>
#include <string>
#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;

/**
 * @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
