#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>
#include "integrity_algo.hpp"
#include "message_parsers.hpp"

namespace cipher
{

namespace integrity
{

AlgoSHA1::AlgoSHA1(const std::vector<uint8_t>& sik)
    : Interface(SHA1_96_AUTHCODE_LENGTH)
{
    k1 = generateKn(sik, rmcp::const_1);
}

std::vector<uint8_t> AlgoSHA1::generateHMAC(const uint8_t* input,
        const size_t len) const
{
    std::vector<uint8_t> output(SHA_DIGEST_LENGTH);
    unsigned int mdLen = 0;

    if (HMAC(EVP_sha1(), k1.data(), k1.size(), input, len,
             output.data(), &mdLen) == NULL)
    {
        throw std::runtime_error("Generating integrity data failed");
    }

    // HMAC generates Message Digest to the size of SHA_DIGEST_LENGTH, the
    // AuthCode field length is based on the integrity algorithm. So we are
    // interested only in the AuthCode field length of the generated Message
    // digest.
    output.resize(authCodeLength);

    return output;
}

bool AlgoSHA1::verifyIntegrityData(
        const std::vector<uint8_t>& packet,
        const size_t length,
        std::vector<uint8_t>::const_iterator integrityData) const
{

    auto output = generateHMAC(
            packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
            length);

    // Verify if the generated integrity data for the packet and the received
    // integrity data matches.
    return (std::equal(output.begin(), output.end(), integrityData));
}

std::vector<uint8_t> AlgoSHA1::generateIntegrityData(
        const std::vector<uint8_t>& packet) const
{
    return generateHMAC(
            packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
            packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE);
}

std::vector<uint8_t> AlgoSHA1::generateKn(const std::vector<uint8_t>& sik,
        const rmcp::Const_n& const_n) const
{
    unsigned int mdLen = 0;
    std::vector<uint8_t> Kn(sik.size());

    // Generated Kn for the integrity algorithm with the additional key keyed
    // with SIK.
    if (HMAC(EVP_sha1(), sik.data(), sik.size(), const_n.data(),
             const_n.size(), Kn.data(), &mdLen) == NULL)
    {
        throw std::runtime_error("Generating KeyN for integrity "
                                 "algorithm failed");
    }
    return Kn;
}

AlgoSHA256::AlgoSHA256(const std::vector<uint8_t>& sik)
    : Interface(SHA256_128_AUTHCODE_LENGTH)
{
    k1 = generateKn(sik, rmcp::const_1);
}

std::vector<uint8_t> AlgoSHA256::generateHMAC(const uint8_t* input,
        const size_t len) const
{
    std::vector<uint8_t> output(SHA256_DIGEST_LENGTH);
    unsigned int mdLen = 0;

    if (HMAC(EVP_sha256(), k1.data(), k1.size(), input, len,
             output.data(), &mdLen) == NULL)
    {
        throw std::runtime_error("Generating HMAC_SHA256_128 failed");
    }

    // HMAC generates Message Digest to the size of SHA256_DIGEST_LENGTH, the
    // AuthCode field length is based on the integrity algorithm. So we are
    // interested only in the AuthCode field length of the generated Message
    // digest.
    output.resize(authCodeLength);

    return output;
}

bool AlgoSHA256::verifyIntegrityData(
        const std::vector<uint8_t>& packet,
        const size_t length,
        std::vector<uint8_t>::const_iterator integrityData) const
{

    auto output = generateHMAC(
            packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
            length);

    // Verify if the generated integrity data for the packet and the received
    // integrity data matches.
    return (std::equal(output.begin(), output.end(), integrityData));
}

std::vector<uint8_t> AlgoSHA256::generateIntegrityData(
        const std::vector<uint8_t>& packet) const
{
    return generateHMAC(
            packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
            packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE);
}

std::vector<uint8_t> AlgoSHA256::generateKn(const std::vector<uint8_t>& sik,
        const rmcp::Const_n& const_n) const
{
    unsigned int mdLen = 0;
    std::vector<uint8_t> Kn(sik.size());

    // Generated Kn for the integrity algorithm with the additional key keyed
    // with SIK.
    if (HMAC(EVP_sha256(), sik.data(), sik.size(), const_n.data(),
             const_n.size(), Kn.data(), &mdLen) == NULL)
    {
        throw std::runtime_error("Generating KeyN for integrity "
                                 "algorithm HMAC_SHA256 failed");
    }
    return Kn;
}

}// namespace integrity

}// namespace cipher
