/*
 *
 * Copyright 2018, 2019, 2020 NXP
 * SPDX-License-Identifier: Apache-2.0
 */

/* ************************************************************************** */
/* Includes                                                                   */
/* ************************************************************************** */

#include <ex_sss.h>
#include <ex_sss_boot.h>
#include <fsl_sss_se05x_apis.h>
#include <nxEnsure.h>
#include <nxLog_App.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* ************************************************************************** */
/* Local Defines                                                              */
/* ************************************************************************** */
#define KEY_BIT_LEN 128
/* ************************************************************************** */
/* Structures and Typedefs                                                    */
/* ************************************************************************** */

/* ************************************************************************** */
/* Global Variables                                                           */
/* ************************************************************************** */

uint32_t gAuthid = 0;
uint32_t gKeyid = 0;
uint8_t gAlgo = 0;
char *gportName = NULL;
uint32_t gLoopCount = 0;
static ex_sss_boot_ctx_t gex_sym_cc_boot_ctx;

/* ************************************************************************** */
/* Static function declarations                                               */
/* ************************************************************************** */
static sss_status_t parse_command_line_args(int argc, const char **argv);
/* ************************************************************************** */
/* Private Functions                                                          */
/* ************************************************************************** */

/* ************************************************************************** */
/* Public Functions                                                           */
/* ************************************************************************** */

#define EX_SSS_BOOT_PCONTEXT (&gex_sym_cc_boot_ctx)
#define EX_SSS_BOOT_DO_ERASE 0
#define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 1

#include <ex_sss_main_cc_inc.h>

void usage()
{
    LOG_W(
        "\n\
    usage:\n\
    se05x_ConcurrentSymm.exe \n\
        -authid <auth object id to open Session >\n\
        -keyid <Key id to store Key>\n\
        -algo <block cipher mode, choose 1 for ebc or 2 for cbc>\n\
        -cnt <no of times to loop the operation >\n \
        -port <port to connect to>\n");
    return;
}


#define CIPHER_BLOCK_SIZE_TEST 55



sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx)
{

    sss_status_t status = kStatus_SSS_Success;
    int argc = gex_sss_argc;
    const char **argv = gex_sss_argv;
    size_t i = 0;
    size_t blocksize = CIPHER_BLOCK_SIZE_TEST;
    sss_algorithm_t algorithm = kAlgorithm_None;
    sss_mode_t mode;
    /* clang-format off */
    uint8_t srcData[1024] = { 0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x31, 0 };
    uint8_t encData[1100] = { 0, };
    size_t encDataLen = 0;
    uint8_t keystring[KEY_BIT_LEN / 8] = { 0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x48 ,0x45 ,0x4c ,0x4c ,0x4f ,0x31 }; /*HELLOHELLOHELLO1*/
    uint8_t destData[1024] = {0,};
    uint8_t iv[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    size_t ivlen = sizeof(iv);
    sss_key_part_t keyPart;
    sss_cipher_type_t cipherType;
    size_t keyByteLenMax = KEY_BIT_LEN/8;
    sss_object_t key;
    sss_symmetric_t ctx_symm_encrypt = { 0 };
    sss_symmetric_t ctx_symm_decrypt = { 0 };
    size_t tempOutbufLen = 0;
    size_t tempdataLen = 0;
    size_t output_offset = 0;
    uint32_t uLoopCnt = 0;
    uint32_t uLooplimit = 200;

    /* clang-format on */

    keyPart    = kSSS_KeyPart_Default;
    cipherType = kSSS_CipherType_AES;
    mode       = kMode_SSS_Encrypt;


    LOG_I("\n\n");
    LOG_I("Running AES symmetric Example se05x_ConcurrentSymm.c");
    LOG_I("\n\n");

    /* Parse commandline arguments */
    status = parse_command_line_args(argc, argv);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
    const char *portName = gportName;
    algorithm = gAlgo;

    if (gLoopCount != 0)
    {
        /*Accept the loopcount from user*/
        uLooplimit = gLoopCount;
    }


    /*Open session at given Auth ID*/
    status = ex_sss_boot_open_on_id(pCtx, portName, gAuthid);

    status = ex_sss_key_store_and_object_init((pCtx));
    if (kStatus_SSS_Success != status) {
        LOG_E("ex_sss_key_store_and_object_init Failed");
        goto cleanup;
    }


    /* Pre-requisite for encryption Part*/
    //keep the crypto operations in loop
    for (uLoopCnt = 0;uLoopCnt < uLooplimit; uLoopCnt++)
    {
        LOG_I("LoopCount (loop = %d)\n", uLoopCnt);
        status = sss_key_object_init(&key, &pCtx->ks);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

        status =
            sss_key_object_allocate_handle(&key, gKeyid, keyPart, cipherType, keyByteLenMax, kKeyObject_Mode_Persistent);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

        status = sss_key_store_set_key(&pCtx->ks, &key, keystring, sizeof(keystring), sizeof(keystring) * 8, NULL, 0);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
        /* doc:end ex_sss_symmetric-allocate-key */

        mode = kMode_SSS_Encrypt;
        /* doc:start ex_sss_symmetric-encrypt */
        status = sss_symmetric_context_init(&ctx_symm_encrypt, &pCtx->session, &key, algorithm, mode);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

        memset(iv, 0x00, 16);
        LOG_I("Do Encryption");
        LOG_MAU8_D("iv", iv, ivlen);
        LOG_MAU8_D("srcData", srcData, sizeof(srcData));
        /*Do Encryption*/

        status = sss_cipher_init(&ctx_symm_encrypt, iv, ivlen);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

        for (i = 0; i < sizeof(srcData); i = i + blocksize) {
            tempdataLen = (i + blocksize > sizeof(srcData)) ? (sizeof(srcData) - i) : blocksize;
            tempOutbufLen = tempdataLen + 16; /* To handle any unprocessed data in cache */

            status = sss_cipher_update(&ctx_symm_encrypt, (srcData + i), tempdataLen, (encData + output_offset), &tempOutbufLen);
            ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

            output_offset = output_offset + tempOutbufLen;
        }

        tempOutbufLen = blocksize + 16; /* To handle any unprocessed data in cache */
        status = sss_cipher_finish(&ctx_symm_encrypt, NULL, 0, (encData + output_offset), &tempOutbufLen);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
        encDataLen = output_offset + tempOutbufLen;

        sss_symmetric_context_free(&ctx_symm_encrypt);

        LOG_I("Encryption successful !!!");
        LOG_MAU8_I("encrypted data", encData, encDataLen);


        mode = kMode_SSS_Decrypt;

        /* doc:start ex_sss_symmetric-decrypt */
        status = sss_symmetric_context_init(&ctx_symm_decrypt, &pCtx->session, &key, algorithm, mode);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

        status = sss_cipher_init(&ctx_symm_decrypt, iv, ivlen);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

        LOG_I("Do Decryption");
        LOG_MAU8_D("iv", iv, ivlen);

        output_offset = 0;
        for (i = 0; i < encDataLen; i = i + blocksize) {
            tempdataLen = (i + blocksize > encDataLen) ? (encDataLen - i) : blocksize;
            tempOutbufLen = tempdataLen + 16; /* To handle any unprocessed data in cache */

            if (output_offset >= sizeof(destData)) {
                status = kStatus_SSS_Fail;
                goto cleanup;
            }
            status = sss_cipher_update(&ctx_symm_decrypt, (encData + i), tempdataLen, (destData + output_offset), &tempOutbufLen);
            ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

            output_offset = output_offset + tempOutbufLen;
        }

        tempOutbufLen = blocksize + 16; /* To handle any unprocessed data in cache */
        if (output_offset > sizeof(destData)) {
            LOG_E("Failure BufferOverflow");
            status = kStatus_SSS_Fail;
            goto cleanup;
        }
        status = sss_cipher_finish(&ctx_symm_decrypt, NULL, 0, (destData + output_offset), &tempOutbufLen);
        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

        LOG_I("Encryption successful !!!");
        LOG_MAU8_I("decrypted data", destData,sizeof(destData));

        if (memcmp(srcData, destData, sizeof(srcData)) == 0) {
            status = kStatus_SSS_Success;
        }
        else {
            status = kStatus_SSS_Fail;
        }

        ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

        LOG_I("Decryption successful !!!");
        output_offset = 0;
        tempOutbufLen = 0;
        tempdataLen = 0;
        sss_symmetric_context_free(&ctx_symm_encrypt);
        sss_symmetric_context_free(&ctx_symm_decrypt);

    }


cleanup:
    if (kStatus_SSS_Success == status) {
        LOG_I("se05x_ConcurrentSymm Example Success !!!...");
    }
    else {
        LOG_E("se05x_ConcurrentSymm Example Failed !!!...");
    }
    if (ctx_symm_encrypt.session != NULL)
        sss_symmetric_context_free(&ctx_symm_encrypt);
    if (ctx_symm_decrypt.session != NULL)
        sss_symmetric_context_free(&ctx_symm_decrypt);
    return status;
}

static sss_status_t parse_command_line_args(int argc, const char **argv)
{
    bool authid_passed = false;
    bool keyid_passed = false;
    bool port_passed = false;
    bool algo_passed = false;

    for (int j = 1; j < argc; j++) {
        if (strcmp(argv[j], "-authid") == 0) {
            if (++j < argc) {
                gAuthid = (uint32_t)strtoul(argv[j], NULL, 16);
                authid_passed = true;
            }
        }
        else if (strcmp(argv[j], "-keyid") == 0) {
            if (++j < argc) {
                gKeyid = (uint32_t)strtoul(argv[j], NULL, 16);
                keyid_passed = true;
            }
        }
        else if (strcmp(argv[j], "-algo") == 0) {
            if (++j < argc) {
                gAlgo = (uint8_t)strtoul(argv[j], NULL, 10);
                if (gAlgo == 1 || gAlgo == 2) {
                    algo_passed = true;
                }
            }
        }
        else if (strcmp(argv[j], "-cnt") == 0) {
            if (++j < argc) {
                gLoopCount = (uint32_t)strtoul(argv[j], NULL, 10);
            }
        }
        else if (strcmp(argv[j], "-port") == 0) {
            if (++j < argc) {
                gportName = (char *)argv[j];
                port_passed = true;
            }
        }
    }
    if (!authid_passed) {
        LOG_E("Auth key Id not passed");
        usage();
        return kStatus_SSS_Fail;
    }
    if (!algo_passed) {
        LOG_E("Symm algorithm(ecb/cbc) not passed");
        usage();
        return kStatus_SSS_Fail;
    }
    if (!keyid_passed) {
        LOG_E("Object key Id not passed");
        usage();
        return kStatus_SSS_Fail;
    }
    if (!port_passed) {
        LOG_E("Port  not passed");
        usage();
        return kStatus_SSS_Fail;
    }

    return kStatus_SSS_Success;
}
