#pragma once

#include <array>
#include <cstddef>
#include <cstdint>
#include <vector>

namespace cipher
{

namespace crypt
{

/**
 * @enum Confidentiality Algorithms
 *
 * The Confidentiality Algorithm Number specifies the encryption/decryption
 * algorithm field that is used for encrypted payload data under the session.
 * The ‘encrypted’ bit in the payload type field being set identifies packets
 * with payloads that include data that is encrypted per this specification.
 * When payload data is encrypted, there may be additional “Confidentiality
 * Header” and/or “Confidentiality Trailer” fields that are included within the
 * payload. The size and definition of those fields is specific to the
 * particular confidentiality algorithm. Based on security recommendations
 * encrypting IPMI traffic is preferred, so NONE is not supported.
 */
enum class Algorithms : uint8_t
{
    NONE,        /**< No encryption (mandatory , not supported) */
    AES_CBC_128, /**< AES-CBC-128 Algorithm (mandatory option) */
    xRC4_128,    /**< xRC4-128 Algorithm (optional option) */
    xRC4_40,     /**< xRC4-40 Algorithm (optional option) */
};

/**
 * @class Interface
 *
 * Interface is the base class for the Confidentiality Algorithms.
 */
class Interface
{
  public:
    /**
     * @brief Constructor for Interface
     */
    explicit Interface(const std::vector<uint8_t>& k2) : k2(k2) {}

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

    /**
     * @brief Decrypt the incoming payload
     *
     * @param[in] packet - Incoming IPMI packet
     * @param[in] sessHeaderLen - Length of the IPMI Session Header
     * @param[in] payloadLen - Length of the encrypted IPMI payload
     *
     * @return decrypted payload if the operation is successful
     */
    virtual std::vector<uint8_t> decryptPayload(
        const std::vector<uint8_t>& packet, const size_t sessHeaderLen,
        const size_t payloadLen) const = 0;

    /**
     * @brief Encrypt the outgoing payload
     *
     * @param[in] payload - plain payload for the outgoing IPMI packet
     *
     * @return encrypted payload if the operation is successful
     *
     */
    virtual std::vector<uint8_t> encryptPayload(
        std::vector<uint8_t>& payload) const = 0;

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

  protected:
    /**
     * @brief The Cipher Key is the first 128-bits of key “K2”, K2 is
     * generated by processing a pre-defined constant keyed by Session
     * Integrity Key (SIK) that was created during session activation.
     */
    std::vector<uint8_t> k2;
};

/**
 * @class AlgoAES128
 *
 * @brief Implementation of the AES-CBC-128 Confidentiality algorithm
 *
 * AES-128 uses a 128-bit Cipher Key. The Cipher Key is the first 128-bits of
 * key “K2”.Once the Cipher Key has been generated it is used to encrypt
 * the payload data. The payload data is padded to make it an integral numbers
 * of blocks in length (a block is 16 bytes for AES). The payload is then
 * encrypted one block at a time from the lowest data offset to the highest
 * using Cipher_Key as specified in AES.
 */
class AlgoAES128 final : public Interface
{
  public:
    static constexpr size_t AESCBC128ConfHeader = 16;
    static constexpr size_t AESCBC128BlockSize = 16;

    /**
     * If confidentiality bytes are present, the value of the first byte is
     * one (01h). and all subsequent bytes shall have a monotonically
     * increasing value (e.g., 02h, 03h, 04h, etc). The receiver, as an
     * additional check for proper decryption, shall check the value of each
     * byte of Confidentiality Pad. For AES algorithm, the pad bytes will
     * range from 0 to 15 bytes. This predefined array would help in
     * doing the additional check.
     */
    static constexpr std::array<uint8_t, AESCBC128BlockSize - 1> confPadBytes =
        {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
         0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};

    /**
     * @brief Constructor for AlgoAES128
     *
     * @param[in] - Session Integrity key
     */
    explicit AlgoAES128(const std::vector<uint8_t>& k2) : Interface(k2) {}

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

    /**
     * @brief Decrypt the incoming payload
     *
     * @param[in] packet - Incoming IPMI packet
     * @param[in] sessHeaderLen - Length of the IPMI Session Header
     * @param[in] payloadLen - Length of the encrypted IPMI payload
     *
     * @return decrypted payload if the operation is successful
     */
    std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet,
                                        const size_t sessHeaderLen,
                                        const size_t payloadLen) const override;

    /**
     * @brief Encrypt the outgoing payload
     *
     * @param[in] payload - plain payload for the outgoing IPMI packet
     *
     * @return encrypted payload if the operation is successful
     *
     */
    std::vector<uint8_t> encryptPayload(
        std::vector<uint8_t>& payload) const override;

  private:
    /**
     * @brief Decrypt the passed data
     *
     * @param[in] iv - Initialization vector
     * @param[in] input - Pointer to input data
     * @param[in] inputLen - Length of input data
     *
     * @return decrypted data if the operation is successful
     */
    std::vector<uint8_t> decryptData(const uint8_t* iv, const uint8_t* input,
                                     const int inputLen) const;

    /**
     * @brief Encrypt the passed data
     *
     * @param[in] input - Pointer to input data
     * @param[in] inputLen - Length of input data
     *
     * @return encrypted data if the operation is successful
     */
    std::vector<uint8_t> encryptData(const uint8_t* input,
                                     const int inputLen) const;
};

} // namespace crypt

} // namespace cipher
