/*
 *
 *    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.
 */

/**
 *    @file
 *      This file defines functions for encoding and decoding CHIP messages.
 *      The encoded messages contain CHIP packet header, encrypted payload
 *      header, encrypted payload and message authentication code, as per
 *      CHIP specifications.
 *
 */

#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <transport/SecureMessageCodec.h>

namespace chip {

using System::PacketBuffer;
using System::PacketBufferHandle;

namespace SecureMessageCodec {

CHIP_ERROR Encrypt(const CryptoContext & context, CryptoContext::ConstNonceView nonce, PayloadHeader & payloadHeader,
                   PacketHeader & packetHeader, System::PacketBufferHandle & msgBuf)
{
    VerifyOrReturnError(!msgBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(!msgBuf->HasChainedBuffer(), CHIP_ERROR_INVALID_MESSAGE_LENGTH);

    ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(msgBuf));

    uint8_t * data  = msgBuf->Start();
    size_t totalLen = msgBuf->TotalLength();

    MessageAuthenticationCode mac;
    ReturnErrorOnFailure(context.Encrypt(data, totalLen, data, nonce, packetHeader, mac));

    uint16_t taglen = 0;
    ReturnErrorOnFailure(mac.Encode(packetHeader, &data[totalLen], msgBuf->AvailableDataLength(), &taglen));

    msgBuf->SetDataLength(totalLen + taglen);

    return CHIP_NO_ERROR;
}

CHIP_ERROR Decrypt(const CryptoContext & context, CryptoContext::ConstNonceView nonce, PayloadHeader & payloadHeader,
                   const PacketHeader & packetHeader, System::PacketBufferHandle & msg)
{
    ReturnErrorCodeIf(msg.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);

    uint8_t * data = msg->Start();
    size_t len     = msg->DataLength();

    PacketBufferHandle origMsg;
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    /* This is a workaround for the case where PacketBuffer payload is not
        allocated as an inline buffer to PacketBuffer structure */
    origMsg = std::move(msg);
    msg     = PacketBufferHandle::New(len);
    VerifyOrReturnError(!msg.IsNull(), CHIP_ERROR_NO_MEMORY);
    msg->SetDataLength(len);
#endif

    uint16_t footerLen = packetHeader.MICTagLength();
    VerifyOrReturnError(footerLen <= len, CHIP_ERROR_INVALID_MESSAGE_LENGTH);

    uint16_t taglen = 0;
    MessageAuthenticationCode mac;
    ReturnErrorOnFailure(mac.Decode(packetHeader, &data[len - footerLen], footerLen, &taglen));
    VerifyOrReturnError(taglen == footerLen, CHIP_ERROR_INTERNAL);

    len = len - taglen;
    msg->SetDataLength(len);

    uint8_t * plainText = msg->Start();
    ReturnErrorOnFailure(context.Decrypt(data, len, plainText, nonce, packetHeader, mac));

    ReturnErrorOnFailure(payloadHeader.DecodeAndConsume(msg));
    return CHIP_NO_ERROR;
}

} // namespace SecureMessageCodec

} // namespace chip
