/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <crypto/DefaultSessionKeystore.h>
#include <crypto/RandUtils.h>
#include <gtest/gtest.h>
#include <lib/support/BufferWriter.h>
#include <lib/support/CHIPMem.h>
#include <protocols/Protocols.h>
#include <protocols/secure_channel/CheckinMessage.h>
#include <protocols/secure_channel/Constants.h>
#include <protocols/secure_channel/StatusReport.h>
#include <protocols/secure_channel/tests/CheckIn_Message_test_vectors.h>
#include <transport/CryptoContext.h>

using namespace chip;
using namespace chip::Protocols;
using namespace chip::Protocols::SecureChannel;
using namespace chip::Crypto;
using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore;

namespace {

/**
 * @brief Helper function that generates the Check-In message based on the test vector
 *        and verifies the generated Check-In message
 *        Helper is to avoid having the same code three times in different tests
 *
 * @return CHIP_NO_ERROR if the generation was successful
 *         error code if the generation failed - see GenerateCheckinMessagePayload
 */
CHIP_ERROR GenerateAndVerifyPayload(MutableByteSpan & output, const CheckIn_Message_test_vector & vector)
{
    TestSessionKeystoreImpl keystore;

    // Two distinct key material buffers to ensure crypto-hardware-assist with single-usage keys create two different handles.
    Symmetric128BitsKeyByteArray aesKeyMaterial;
    memcpy(aesKeyMaterial, vector.key, vector.key_len);

    Symmetric128BitsKeyByteArray hmacKeyMaterial;
    memcpy(hmacKeyMaterial, vector.key, vector.key_len);

    Aes128KeyHandle aes128KeyHandle;
    EXPECT_EQ(keystore.CreateKey(aesKeyMaterial, aes128KeyHandle), CHIP_NO_ERROR);

    Hmac128KeyHandle hmac128KeyHandle;
    EXPECT_EQ(keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle), CHIP_NO_ERROR);

    // Create application data ByteSpan
    ByteSpan applicationData(vector.application_data, vector.application_data_len);

    // Verify that the generation succeeded
    CHIP_ERROR err =
        CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output);
    if (err != CHIP_NO_ERROR)
    {
        keystore.DestroyKey(aes128KeyHandle);
        keystore.DestroyKey(hmac128KeyHandle);

        return err;
    }

    // Validate Full payload
    EXPECT_EQ(output.size(), vector.payload_len);
    EXPECT_EQ(memcmp(vector.payload, output.data(), output.size()), 0);

    size_t cursorIndex = 0;

    // Validate Nonce
    MutableByteSpan nonce = output.SubSpan(cursorIndex, vector.nonce_len);
    EXPECT_EQ(memcmp(vector.nonce, nonce.data(), nonce.size()), 0);
    cursorIndex += nonce.size();

    // Validate ciphertext
    MutableByteSpan ciphertext = output.SubSpan(cursorIndex, vector.ciphertext_len);
    EXPECT_EQ(memcmp(vector.ciphertext, ciphertext.data(), ciphertext.size()), 0);
    cursorIndex += ciphertext.size();

    // Validate MIC
    MutableByteSpan mic = output.SubSpan(cursorIndex, vector.mic_len);
    EXPECT_EQ(memcmp(vector.mic, mic.data(), mic.size()), 0);
    cursorIndex += mic.size();

    // Clean up
    keystore.DestroyKey(aes128KeyHandle);
    keystore.DestroyKey(hmac128KeyHandle);

    return err;
}

/**
 * @brief Helper function that parses the Check-In message based on the test vector
 *        and verifies parsed Check-In message
 *        Helper is to avoid having the same code in multiple tests
 *
 * @return CHIP_NO_ERROR if the parsing was successful
 *         error code if the generation failed - see ParseCheckinMessagePayload
 */
CHIP_ERROR ParseAndVerifyPayload(MutableByteSpan & applicationData, const CheckIn_Message_test_vector & vector,
                                 bool injectInvalidNonce)
{
    TestSessionKeystoreImpl keystore;

    // Copy payload to be able to modify it for invalid nonce tests
    uint8_t payloadBuffer[300] = { 0 };
    memcpy(payloadBuffer, vector.payload, vector.payload_len);

    if (injectInvalidNonce)
    {
        // Modify nonce to validate that the parsing can detect that the message was manipulated
        payloadBuffer[0] ^= 0xFF;
    }

    // Create payload byte span
    ByteSpan payload(payloadBuffer, vector.payload_len);

    CounterType decryptedCounter = 0;

    // Two distinct key material buffers to ensure crypto-hardware-assist with single-usage keys create two different handles.
    Symmetric128BitsKeyByteArray aesKeyMaterial;
    memcpy(aesKeyMaterial, vector.key, vector.key_len);

    Symmetric128BitsKeyByteArray hmacKeyMaterial;
    memcpy(hmacKeyMaterial, vector.key, vector.key_len);

    Aes128KeyHandle aes128KeyHandle;
    EXPECT_EQ(keystore.CreateKey(aesKeyMaterial, aes128KeyHandle), CHIP_NO_ERROR);

    Hmac128KeyHandle hmac128KeyHandle;
    EXPECT_EQ(keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle), CHIP_NO_ERROR);

    // Verify that the Parsing succeeded
    CHIP_ERROR err =
        CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData);
    if (err != CHIP_NO_ERROR)
    {
        keystore.DestroyKey(aes128KeyHandle);
        keystore.DestroyKey(hmac128KeyHandle);

        return err;
    }

    // Verify decrypted counter value
    EXPECT_EQ(vector.counter, decryptedCounter);

    // Verify application data
    EXPECT_EQ(vector.application_data_len, applicationData.size());
    EXPECT_EQ(memcmp(vector.application_data, applicationData.data(), applicationData.size()), 0);

    // Cleanup
    keystore.DestroyKey(aes128KeyHandle);
    keystore.DestroyKey(hmac128KeyHandle);

    return err;
}

/**
 * @brief Test verifies that the Check-In message generation is successful when using an output size equal to the payload size
 */
TEST(TestCheckInMsg, TestCheckinMessageGenerate_ValidInputsSameSizeOutputAsPayload)
{
    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
    {
        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];

        // Create output buffer
        uint8_t buffer[300] = { 0 };
        MutableByteSpan output(buffer, sizeof(buffer));

        // Force output buffer to the payload size
        output.reduce_size(vector.payload_len);

        EXPECT_EQ(GenerateAndVerifyPayload(output, vector), CHIP_NO_ERROR);
    }
}

/**
 * @brief Test verifies that the Check-In message generation is successful when using an output size greater than the payload size
 */
TEST(TestCheckInMsg, TestCheckinMessageGenerate_ValidInputsBiggerSizeOutput)
{
    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
    {
        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];

        // Create output buffer
        uint8_t buffer[300] = { 0 };
        MutableByteSpan output(buffer, sizeof(buffer));

        EXPECT_EQ(GenerateAndVerifyPayload(output, vector), CHIP_NO_ERROR);
    }
}

/**
 * @brief Test verifies that the Check-In message generation returns an error if the output buffer is too small
 */
TEST(TestCheckInMsg, TestCheckinMessageGenerate_ValidInputsTooSmallOutput)
{
    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];

    // Create output buffer with 0 size
    MutableByteSpan output;
    EXPECT_EQ(GenerateAndVerifyPayload(output, vector), CHIP_ERROR_BUFFER_TOO_SMALL);
}

/**
 * @brief Test verifies that the Check-In Message generations returns an error if the AesKeyHandle is empty
 */
TEST(TestCheckInMsg, TestCheckInMessageGenerate_EmptyAesKeyHandle)
{
    TestSessionKeystoreImpl keystore;
    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];

    // Create output buffer
    uint8_t buffer[300] = { 0 };
    MutableByteSpan output(buffer, sizeof(buffer));

    // Force output buffer to the payload size
    output.reduce_size(vector.payload_len);

    // Empty AES Key handle
    Aes128KeyHandle aes128KeyHandle;

    Symmetric128BitsKeyByteArray hmacKeyMaterial;
    memcpy(hmacKeyMaterial, vector.key, vector.key_len);

    Hmac128KeyHandle hmac128KeyHandle;
    EXPECT_EQ(keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle), CHIP_NO_ERROR);

    // Create application data ByteSpan
    ByteSpan applicationData(vector.application_data, vector.application_data_len);

/*
    TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure.
                  When using OpenSSL this same test result in a success.
*/
#if 0
    // Verify that the generation fails with an empty key handle
    EXPECT_NE(
        CHIP_NO_ERROR,
        CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output));
#endif

    // Clean up
    keystore.DestroyKey(hmac128KeyHandle);
}

/**
 * @brief Test verifies that the Check-In Message generations returns an error if the HmacKeyHandle is empty
 */
TEST(TestCheckInMsg, TestCheckInMessageGenerate_EmptyHmacKeyHandle)
{
    TestSessionKeystoreImpl keystore;
    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];

    // Create output buffer
    uint8_t buffer[300] = { 0 };
    MutableByteSpan output(buffer, sizeof(buffer));

    // Force output buffer to the payload size
    output.reduce_size(vector.payload_len);

    Symmetric128BitsKeyByteArray aesKeyMaterial;
    memcpy(aesKeyMaterial, vector.key, vector.key_len);

    Aes128KeyHandle aes128KeyHandle;
    EXPECT_EQ(keystore.CreateKey(aesKeyMaterial, aes128KeyHandle), CHIP_NO_ERROR);

    Hmac128KeyHandle hmac128KeyHandle;

    // Create application data ByteSpan
    ByteSpan applicationData(vector.application_data, vector.application_data_len);

/*
    TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure.
                  When using OpenSSL this same test result in a success.
*/
#if 0
    // Verify that the generation fails with an empty key handle
    EXPECT_NE(
        CHIP_NO_ERROR,
        CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output));
#endif

    // Clean up
    keystore.DestroyKey(aes128KeyHandle);
}

/**
 * @brief Test verifies that the Check-In message parsing succeeds with the Application buffer set to the minimum required size
 */
TEST(TestCheckInMsg, TestCheckinMessageParse_ValidInputsSameSizeMinAppData)
{
    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
    {
        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];

        uint8_t applicationDataBuffer[128] = { 0 };
        MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
        applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));

        EXPECT_EQ(ParseAndVerifyPayload(applicationData, vector, false), CHIP_NO_ERROR);
    }
}

/**
 * @brief Test verifies that the Check-In message parsing succeeds with the Application buffer set to a larger than necessary size
 */
TEST(TestCheckInMsg, TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData)
{
    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
    {
        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];

        uint8_t applicationDataBuffer[128] = { 0 };
        MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));

        EXPECT_EQ(ParseAndVerifyPayload(applicationData, vector, false), CHIP_NO_ERROR);
    }
}

/**
 * @brief Test verifies that the Check-In message throws an error if the application data buffer is too small
 */
TEST(TestCheckInMsg, TestCheckinMessageParse_ValidInputsTooSmallAppData)
{
    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];

    // Create applicationData buffer with 0 size
    MutableByteSpan applicationData;

    EXPECT_EQ(ParseAndVerifyPayload(applicationData, vector, false), CHIP_ERROR_BUFFER_TOO_SMALL);
}

/**
 * @brief Test verifies that the Check-In Message parsing returns an error if the AesKeyHandle is empty
 */
TEST(TestCheckInMsg, TestCheckInMessageParse_EmptyAesKeyHandle)
{
    TestSessionKeystoreImpl keystore;
    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];

    // Create application data ByteSpan
    uint8_t applicationDataBuffer[128] = { 0 };
    MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
    applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));

    // Create payload byte span
    ByteSpan payload(vector.payload, vector.payload_len);

    CounterType decryptedCounter = 0;
    //
    (void) decryptedCounter;

    // Empty AES Key handle
    Aes128KeyHandle aes128KeyHandle;

    Symmetric128BitsKeyByteArray hmacKeyMaterial;
    memcpy(hmacKeyMaterial, vector.key, vector.key_len);

    Hmac128KeyHandle hmac128KeyHandle;
    EXPECT_EQ(keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle), CHIP_NO_ERROR);

/*
    TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure.
                  When using OpenSSL this same test result in a success.
*/
#if 0
    // Verify that the generation fails with an empty key handle
    EXPECT_NE(
        CHIP_NO_ERROR,
        CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData));
#endif

    // Clean up
    keystore.DestroyKey(hmac128KeyHandle);
}

/**
 * @brief Test verifies that the Check-In Message parsing returns an error if the HmacKeyHandle is empty
 */
TEST(TestCheckInMsg, TestCheckInMessageParse_EmptyHmacKeyHandle)
{
    TestSessionKeystoreImpl keystore;
    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];

    // Create application data ByteSpan
    uint8_t applicationDataBuffer[128] = { 0 };
    MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
    applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));

    // Create payload byte span
    ByteSpan payload(vector.payload, vector.payload_len);

    CounterType decryptedCounter = 0;
    //
    (void) decryptedCounter;

    // Empty Hmac Key handle
    Hmac128KeyHandle hmac128KeyHandle;

    Symmetric128BitsKeyByteArray aesKeyMaterial;
    memcpy(aesKeyMaterial, vector.key, vector.key_len);

    Aes128KeyHandle aes128KeyHandle;
    EXPECT_EQ(keystore.CreateKey(aesKeyMaterial, aes128KeyHandle), CHIP_NO_ERROR);

/*
    TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure.
                  When using OpenSSL this same test result in a success.
*/
#if 0
    // Verify that the generation fails with an empty key handle
    EXPECT_NE(
        CHIP_NO_ERROR,
        CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData));
#endif

    // Clean up
    keystore.DestroyKey(aes128KeyHandle);
}

/**
 * @brief Test verifies that the Check-In message processing throws an error if the nonce is corrupted
 */
TEST(TestCheckInMsg, TestCheckinMessageParse_CorruptedNonce)
{
    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
    {
        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];

        uint8_t applicationDataBuffer[128] = { 0 };
        MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
        applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));

        EXPECT_EQ(ParseAndVerifyPayload(applicationData, vector, true), CHIP_ERROR_INTERNAL);
    }
}

/**
 * @brief Test verifies that the Check-In message processing throws an error if the nonce was not calculated with the counter in the
 * payload
 */
TEST(TestCheckInMsg, TestCheckinMessageParse_InvalidNonce)
{
    CheckIn_Message_test_vector vector = invalidNonceVector;

    uint8_t applicationDataBuffer[128] = { 0 };
    MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
    applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));

    EXPECT_EQ(ParseAndVerifyPayload(applicationData, vector, true), CHIP_ERROR_INTERNAL);
}

/**
 * @brief test verifies that GetAppDataSize returns the correct application data size
 */
TEST(TestCheckInMsg, TestCheckInMessagePayloadSize)
{
    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
    {
        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];

        ByteSpan payload(vector.payload, vector.payload_len);
        size_t calculated_size = CheckinMessage::GetAppDataSize(payload);

        // Verify the AppData size matches the expected application data size
        EXPECT_EQ(vector.application_data_len, calculated_size);
    }
}

/**
 * @brief test verifies that GetAppDataSize returns 0 if the payload is smaller that the minimum size
 */
TEST(TestCheckInMsg, TestCheckInMessagePayloadSizeNullBuffer)
{
    ByteSpan payload;
    size_t calculated_size = CheckinMessage::GetAppDataSize(payload);
    size_t expected_size   = 0;

    // Verify that the size is 0
    EXPECT_EQ(calculated_size, expected_size);
}

} // namespace
