/*
 *
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *    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.
 */

/**
 *    @file
 *      This file implements a unit test for the Weave message encoding
 *      and decoding functions of the WeaveMessageLayer class.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include <stdio.h>
#include <nlunit-test.h>
#include <string.h>

#include "ToolCommon.h"
#include <Weave/Core/WeaveConfig.h>
#include <Weave/Support/crypto/CTRMode.h>
#include <Weave/Support/crypto/WeaveCrypto.h>

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#include "lwip/tcpip.h"
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

using namespace nl::Inet;
using namespace nl::Weave::Encoding;
using namespace nl::Weave::Crypto;
using namespace nl::Weave::Profiles::Security;

#define DEBUG_PRINT_ENABLE 0

namespace nl {
namespace Weave {

class NL_DLL_EXPORT WeaveMessageLayerTestObject
{
public:
    WeaveMessageLayer *msgLayer;

    WEAVE_ERROR DecodeMessage(PacketBuffer *msgBuf, uint64_t sourceNodeId, WeaveConnection *con,
            WeaveMessageInfo *msgInfo, uint8_t **rPayload, uint16_t *rPayloadLen)
    {
        return msgLayer->DecodeMessage(msgBuf, sourceNodeId, con, msgInfo, rPayload, rPayloadLen);
    }
};

} // namespace nl
} // namespace Weave


static const uint8_t sMsgPayload[] =
{
    0x05, 0x26, 0xAD, 0xB7, 0xBB, 0xD7, 0x82, 0x52, 0x78, 0x2D, 0x60, 0xD6, 0x40, 0xFD, 0xE6, 0xF9,
    0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
    0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
    0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x6A
};

static const uint8_t sMsgEncKey_DataKey[] =
{
    0xF7, 0xE7, 0xD7, 0xC7, 0xB7, 0xA7, 0x97, 0x87, 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77
};

static const uint8_t sMsgEncKey_IntegrityKey[] =
{
    0xFD, 0xED, 0xDD, 0xCD, 0xBD, 0xAD, 0x9D, 0x8D, 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
    0x82, 0x52, 0x78, 0x2D
};

static const uint8_t sEncodedMsg_V1[] =
{
    0x10, 0x1B, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0xB4, 0x18, 0x78, 0x56,
    0x34, 0x12, 0x00, 0x30, 0xB4, 0x18, 0x2A, 0x20, 0xAC, 0xBD, 0x69, 0x5C, 0x20, 0x44, 0x51, 0x71,
    0x16, 0x1C, 0x29, 0x48, 0xC6, 0x3D, 0xBD, 0x91, 0x33, 0x77, 0x7B, 0x58, 0xFA, 0x9C, 0x08, 0x6B,
    0x2B, 0xAF, 0x1D, 0x25, 0x04, 0x01, 0x4E, 0xE2, 0x1E, 0xB7, 0x2F, 0x41, 0x19, 0x2B, 0x81, 0x60,
    0x6B, 0xE8, 0xB9, 0x00, 0x08, 0xA1, 0x1C, 0x9C, 0x62, 0x3B, 0x23, 0x1D, 0x99, 0xBC, 0xA4, 0x7B,
    0x54, 0x00, 0xA2, 0x0B, 0x20, 0x3B, 0xA7, 0x80, 0x01, 0xAC, 0xF4, 0xF4, 0xF5, 0x50, 0x24, 0x63,
    0xF1, 0xBA, 0x50
};

static const uint8_t sEncodedMsg_V2[] =
{
    0x10, 0x2B, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0xB4, 0x18, 0x78, 0x56,
    0x34, 0x12, 0x00, 0x30, 0xB4, 0x18, 0x2A, 0x20, 0xAC, 0xBD, 0x69, 0x5C, 0x20, 0x44, 0x51, 0x71,
    0x16, 0x1C, 0x29, 0x48, 0xC6, 0x3D, 0xBD, 0x91, 0x33, 0x77, 0x7B, 0x58, 0xFA, 0x9C, 0x08, 0x6B,
    0x2B, 0xAF, 0x1D, 0x25, 0x04, 0x01, 0x4E, 0xE2, 0x1E, 0xB7, 0x2F, 0x41, 0x19, 0x2B, 0x81, 0x60,
    0x6B, 0xE8, 0xB9, 0x00, 0x08, 0xA1, 0x1C, 0x9C, 0x62, 0x3B, 0x23, 0x1D, 0x99, 0xBC, 0xA4, 0x96,
    0xD0, 0xAE, 0x61, 0xFD, 0x55, 0x05, 0x43, 0xEA, 0x6C, 0x49, 0x1D, 0xA5, 0x8D, 0x57, 0x3C, 0xF6,
    0xD9, 0x27, 0x9D
};

// Test input vector format.
struct TestContext {
    uint8_t        MsgVersion;
    const uint8_t *MsgPayload;
    uint16_t       MsgPayloadLen;
    const uint8_t *EncodedMsg;
    uint16_t       EncodedMsgLen;
    WEAVE_ERROR    EncodeError;
    WEAVE_ERROR    DecodeError;
};

// Test input data.
static struct TestContext sContext[] = {
    { kWeaveMessageVersion_V1, sMsgPayload, sizeof(sMsgPayload), sEncodedMsg_V1, sizeof(sEncodedMsg_V1), WEAVE_NO_ERROR, WEAVE_NO_ERROR },
    { kWeaveMessageVersion_V2, sMsgPayload, sizeof(sMsgPayload), sEncodedMsg_V2, sizeof(sEncodedMsg_V2), WEAVE_NO_ERROR, WEAVE_NO_ERROR },
    { kWeaveMessageVersion_V2, sMsgPayload, sizeof(sMsgPayload), sEncodedMsg_V2, sizeof(sEncodedMsg_V2), WEAVE_NO_ERROR, WEAVE_ERROR_WRONG_ENCRYPTION_TYPE },
    { kWeaveMessageVersion_V2, sMsgPayload, sizeof(sMsgPayload), sEncodedMsg_V2, sizeof(sEncodedMsg_V2), WEAVE_ERROR_WRONG_ENCRYPTION_TYPE, WEAVE_NO_ERROR },
};

// Number of test context examples.
static const size_t kTestElements = sizeof(sContext) / sizeof(struct TestContext);

void WeaveMessageEncryption_Test1(nlTestSuite *inSuite, void *inContext)
{
    static WeaveFabricState fabricState;
    static WeaveMessageLayer messageLayer;
    static WeaveMessageInfo msgInfo;

    WEAVE_ERROR err;
    PacketBuffer *msgBuf;
    WeaveSessionKey *sessionKey;
    uint64_t srcNodeId;
    uint64_t destNodeId = 0x18B4300012345678;
    uint32_t msgId = 3;
    uint8_t encType = kWeaveEncryptionType_AES128CTRSHA1;
    uint16_t sessionKeyId = sTestDefaultSessionKeyId;
    uint8_t *p;

    const char localAddrStr[] = "fd00:0:1:1:18B4:3000::2";
    IPAddress localIPv6Addr;
    NL_TEST_ASSERT(inSuite, ParseIPAddress(localAddrStr, localIPv6Addr));

    // Initialize the FabricState object.
    err = fabricState.Init();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    srcNodeId = localIPv6Addr.InterfaceId();
    fabricState.LocalNodeId = srcNodeId;
    fabricState.FabricId = localIPv6Addr.GlobalId();
    fabricState.DefaultSubnet = localIPv6Addr.Subnet();

    // Initialize message encryption session key.
    WeaveEncryptionKey msgEncSessionKey;
    WeaveAuthMode authMode = kWeaveAuthMode_CASE_Device;

    memcpy(msgEncSessionKey.AES128CTRSHA1.DataKey, sMsgEncKey_DataKey, sizeof(sMsgEncKey_DataKey));
    memcpy(msgEncSessionKey.AES128CTRSHA1.IntegrityKey, sMsgEncKey_IntegrityKey, sizeof(sMsgEncKey_IntegrityKey));

    // Initialize session key with destination node id.
    err = fabricState.AllocSessionKey(destNodeId, sessionKeyId, NULL, sessionKey);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    fabricState.SetSessionKey(sessionKey, encType, authMode, &msgEncSessionKey);

    // Initialize the same session key with LocalNodeId as a destination node id.
    err = fabricState.AllocSessionKey(srcNodeId, sessionKeyId, NULL, sessionKey);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    fabricState.SetSessionKey(sessionKey, encType, authMode, &msgEncSessionKey);

    // Initialize the MessageLayer object.
    messageLayer.FabricState = &fabricState;

    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++, theContext++)
    {
        uint8_t msgVersion = theContext->MsgVersion;
        const uint8_t *msgPayload = theContext->MsgPayload;
        uint16_t msgPayloadLen = theContext->MsgPayloadLen;
        const uint8_t *encodedMsg = theContext->EncodedMsg;
        uint16_t encodedMsgLen = theContext->EncodedMsgLen;
        WEAVE_ERROR encodeError = theContext->EncodeError;
        WEAVE_ERROR decodeError = theContext->DecodeError;
        uint8_t localMsgBuf[theContext->EncodedMsgLen];

        // Allocate buffer.
        msgBuf = PacketBuffer::New();
        NL_TEST_ASSERT(inSuite, msgBuf != NULL);
        if (msgBuf == NULL)
            continue;

        // Copy payload data.
        memcpy(msgBuf->Start(), msgPayload, msgPayloadLen);
        msgBuf->SetDataLength(msgPayloadLen);

        // Initialize the Message info object.
        msgInfo.Clear();
        msgInfo.SourceNodeId = srcNodeId;
        msgInfo.DestNodeId = destNodeId;
        msgInfo.MessageId = msgId;
        if (encodeError == WEAVE_ERROR_WRONG_ENCRYPTION_TYPE)
            msgInfo.KeyId = WeaveKeyId::kNone;
        else
            msgInfo.KeyId = sessionKeyId;
        msgInfo.Flags = kWeaveMessageFlag_DestNodeId |
                          kWeaveMessageFlag_SourceNodeId |
                          kWeaveMessageFlag_MsgCounterSyncReq |
                          kWeaveMessageFlag_ReuseMessageId;
        msgInfo.MessageVersion = msgVersion;
        msgInfo.EncryptionType = encType;

        // =====================================================================================================
        // Encode message using EncodeMessage() function.
        // =====================================================================================================
        err = messageLayer.EncodeMessage(&msgInfo, msgBuf, NULL, UINT16_MAX, 0);
        NL_TEST_ASSERT(inSuite, err == encodeError);

        if (err != WEAVE_NO_ERROR)
        {
            PacketBuffer::Free(msgBuf);
            msgBuf = NULL;

            continue;
        }

#if DEBUG_PRINT_ENABLE
        printf("Encoded message generated by EncodeMessage():\n");
        DumpMemoryCStyle(msgBuf->Start(), msgBuf->DataLength(), "    ", 16);
#endif

        // =====================================================================================================
        // Manually encode message and compare against the result generated by EncodeMessage() function.
        // =====================================================================================================
        p = localMsgBuf;

        // Write the header field.
        uint16_t headerVal = ((uint16_t) (msgInfo.Flags & 0xF0F) << 0) |
                             ((uint16_t) (msgInfo.EncryptionType & 0xF) << 4) |
                             ((uint16_t) (msgInfo.MessageVersion & 0xF) << 12);
        LittleEndian::Write16(p, headerVal);
        LittleEndian::Write32(p, msgId);
        LittleEndian::Write64(p, srcNodeId);
        LittleEndian::Write64(p, destNodeId);
        LittleEndian::Write16(p, sessionKeyId);

        // Message data to encrypt.
        uint8_t aesDataIn[msgPayloadLen + HMACSHA1::kDigestLength];
        memcpy(aesDataIn, msgPayload, msgPayloadLen);

        // Message data to authenticate.
        uint16_t sha1DataLen;
        uint8_t sha1DataIn[2 * sizeof(uint64_t) + sizeof(uint16_t) + sizeof(uint32_t) + msgPayloadLen];
        uint8_t *p2 = sha1DataIn;
        Encoding::LittleEndian::Write64(p2, srcNodeId);
        Encoding::LittleEndian::Write64(p2, destNodeId);
        sha1DataLen = 2 * sizeof(uint64_t);
        if (msgVersion == kWeaveMessageVersion_V2)
        {
            // Mask destination and source node Id flags.
            headerVal &= kMsgHeaderField_MessageHMACMask;

            // Encode the message header field and the message Id in a little-endian format.
            Encoding::LittleEndian::Write16(p2, headerVal);
            Encoding::LittleEndian::Write32(p2, msgId);

            sha1DataLen += sizeof(uint16_t) + sizeof(uint32_t);
        }
        memcpy(p2, msgPayload, msgPayloadLen);
        sha1DataLen += msgPayloadLen;

        // Compute integrity check.
        HMACSHA1 sha1;
        sha1.Begin(sMsgEncKey_IntegrityKey, sizeof(sMsgEncKey_IntegrityKey));
        sha1.AddData(sha1DataIn, sha1DataLen);
        sha1.Finish(aesDataIn + msgPayloadLen);

        // Encrypt the message payload and the integrity value.
        AES128CTRMode aes128CTR;
        aes128CTR.SetKey(sMsgEncKey_DataKey);
        aes128CTR.SetWeaveMessageCounter(srcNodeId, msgId);
        aes128CTR.EncryptData(aesDataIn, sizeof(aesDataIn), p);

#if DEBUG_PRINT_ENABLE
        printf("Manually generated encoded message:\n");
        DumpMemoryCStyle(localMsgBuf, sizeof(localMsgBuf), "    ", 16);
#endif

        // Compare the result.
        NL_TEST_ASSERT(inSuite, memcmp(msgBuf->Start(), localMsgBuf, sizeof(localMsgBuf)) == 0);

        // Compare the result against the static value saved in this test.
        NL_TEST_ASSERT(inSuite, msgBuf->DataLength() == encodedMsgLen);
        NL_TEST_ASSERT(inSuite, memcmp(msgBuf->Start(), encodedMsg, encodedMsgLen) == 0);

        // =====================================================================================================
        // Verify that DecodeMessage() generates original payload context.
        // =====================================================================================================
        WeaveMessageLayerTestObject msgLayerTestObject;
        uint8_t *payload;
        uint16_t payloadLen;

        // Inject wrong KeyId.
        if (decodeError == WEAVE_ERROR_WRONG_ENCRYPTION_TYPE)
        {
            uint8_t *injectKeyId = msgBuf->Start() + sizeof(headerVal) + sizeof(msgId) + sizeof(srcNodeId) + sizeof(destNodeId);

            LittleEndian::Write16(injectKeyId, WeaveKeyId::kNone);
        }

        msgLayerTestObject.msgLayer = &messageLayer;
        err = msgLayerTestObject.DecodeMessage(msgBuf, srcNodeId, NULL, &msgInfo, &payload, &payloadLen);
        NL_TEST_ASSERT(inSuite, err == decodeError);

        if (err == WEAVE_NO_ERROR)
        {
#if DEBUG_PRINT_ENABLE
            printf("Decoded Payload generated by DecodeMessage():\n");
            DumpMemoryCStyle(payload, payloadLen, "    ", 16);
#endif

            // Compare the result of DecodeMessage() to the original Payload message data.
            NL_TEST_ASSERT(inSuite, payloadLen == msgPayloadLen);
            NL_TEST_ASSERT(inSuite, memcmp(payload, msgPayload, msgPayloadLen) == 0);
        }

        // Release buffer.
        PacketBuffer::Free(msgBuf);
        msgBuf = NULL;
    }
}


int main(int argc, char *argv[])
{
    static const nlTest tests[] = {
        NL_TEST_DEF("WeaveMessageEncryption",           WeaveMessageEncryption_Test1),
        NL_TEST_SENTINEL()
    };

    static nlTestSuite testSuite = {
        "provisioning-hash",
        &tests[0]
    };

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    tcpip_init(NULL, NULL);
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

    nl_test_set_output_style(OUTPUT_CSV);

    nlTestRunner(&testSuite, &sContext);

    return nlTestRunnerStats(&testSuite);
}
