#pragma once

#include <array>
#include <vector>
#include "crypt_algo.hpp"
#include "integrity_algo.hpp"

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
    RAKP_HMAC_SHA1,             // Mandatory
    RAKP_HMAC_MD5,              // Optional
    RAKP_HMAC_SHA256,           // Optional
    // 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(
            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(
            std::vector<uint8_t>& input) const = 0;

        // 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:
        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(std::vector<uint8_t>& input) const
        override;

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

}// namespace auth

}// namespace cipher

