#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
