/**
 * @file ex_psk.c
 * @author NXP Semiconductors
 * @version 1.0
 * @par License
 *
 * Copyright 2016 NXP
 * SPDX-License-Identifier: Apache-2.0
 *
 * @par Description
 * Demonstrate the pre-shared-key
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "a71ch_ex.h"
#include "a71_debug.h"
#include "sm_types.h"
#include "sm_apdu.h"
#include "ax_util.h"
#include "tst_sm_util.h"
#include "tst_a71ch_util.h"
#include "tstHostCrypto.h"

/*******************************************************************
* global variables and struct definitions
*******************************************************************/
#define AX_TLS_LABEL_LEN       13 //!< Should this not move to project header file?
#define AX_TLS_SECRET_LEN      32 //!< Should this not move to project header file?



/**
 * Demonstrate plain or ECDH enhanced pre-shared key based master key creation:
 * - ::exPskTls1_2
 *
 * @param[in]  appletVersion  The applet version
 *
 * @return     1 if successful. Else 0.
 */
U8 exPsk()
{
    U8 result = 1;
    PRINTF( "\r\n-----------\r\nStart exPsk()\r\n------------\r\n");

    // Without channel encryption
    result &= exPskTls1_2(INIT_MODE_RESET, PLAIN_PSK);

    result &= exPskTls1_2(INIT_MODE_RESET, ECDH_PSK);

    // With channel encryption
    result &= exPskTls1_2(INIT_MODE_RESET_DO_SCP03, PLAIN_PSK);

    result &= exPskTls1_2(INIT_MODE_RESET_DO_SCP03, ECDH_PSK);

    // overall result
    PRINTF( "\r\n-----------\r\nEnd exPsk(), result = %s\r\n------------\r\n", ((result == 1)? "OK": "FAILED"));

    return result;
}

/**
 * This example function creates a master secret based upon
 * - all supported PSK sizes (16, 32, 48 and 64 byte)
 * - all supported offsets in the SYM keystore (from 0 upto ::A71CH_SYM_KEY_MAX-1)
 *
 * The master secret is created according to RFC5246 (TLS1.2)
 *
 * Two test modes are supported:
 * - The pre-master secret is created according to RFC4279 section 2 ( if @p pskMode == ::PLAIN_PSK)
 * - The pre-master secret is created according to RFC5489 (if @p pskMode == ::ECDH_PSK)
 *
 * @param[in]  initMode       Visit the documentation of ::a71chInitModule for
 *                            more information on this parameter
 * @param[in]  pskMode        Either ::PLAIN_PSK or ::ECDH_PSK
 * @param[in]  appletVersion  The applet version
 *
 * @return     1 if successful, 0 if failed.
 */

#ifdef __ICCARM__
#pragma optimize=none
#endif

U8 exPskTls1_2(U8 initMode, U8 pskMode)
{
    U8 result = 1;
    U16 err = SW_OK;

    const U8 aesRef[A71CH_SYM_KEY_MAX_B][16] = {
        {0x01, 0xFE, 0xE9, 0xE3, 0xB2, 0x76, 0x15, 0x4D, 0x67, 0xF9, 0xD8, 0x4C, 0xB9, 0x35, 0x54, 0x56},
        {0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
        {0x03, 0x79, 0xEF, 0x82, 0xCD, 0xF7, 0x12, 0xF2, 0x87, 0x28, 0xFD, 0x18, 0xED, 0xD7, 0xF2, 0xE4},
        {0x04, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x06, 0x07, 0x08, 0x09, 0xA0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4},
        {0x05, 0xFE, 0xE9, 0xE3, 0xB2, 0x76, 0x15, 0x4D, 0x67, 0xF9, 0xD8, 0x4C, 0xB9, 0x35, 0x54, 0x56},
        {0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
        {0x07, 0x79, 0xEF, 0x82, 0xCD, 0xF7, 0x12, 0xF2, 0x87, 0x28, 0xFD, 0x18, 0xED, 0xD7, 0xF2, 0xE4},
        {0x08, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x06, 0x07, 0x08, 0x09, 0xA0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4},
    };

    U8 indexAesKey = 0;

    char labelString[] = "master secret";
    U8 label[AX_TLS_LABEL_LEN] = {0};

    U8 clientHelloRandom[AX_TLS_SECRET_LEN] = {0};
    U16 clientHelloRandomLen = sizeof(clientHelloRandom);
    U8 serverHelloRandom[AX_TLS_SECRET_LEN] = {0};

    U8 labelAndSeed[AX_TLS_LABEL_LEN+2*AX_TLS_SECRET_LEN] = {0};
    U16 labelAndSeedLen = sizeof(labelAndSeed);

    U8 serverSeed[AX_TLS_SECRET_LEN] = {0};
    U16 serverSeedLen = sizeof(serverSeed);

    U8 hostPsk[A71CH_SYM_KEY_MAX*16];
    U16 hostPskLen;

    U8 premasterSecret[256];
    U16 premasterSecretLen = 0;

    U8 masterSecret[AX_TLS_PSK_MASTER_SECRET_LEN] = {0};
    U8 masterSecretHost[AX_TLS_PSK_MASTER_SECRET_LEN] = {0};
    U16 masterSecretHostLen = sizeof(masterSecretHost);

    SST_Index_t indexKp = 0;
    eccKeyComponents_t eccKcTls_0 = { 0 };
	eccKeyComponents_t eccKcTls_Host = { 0 };
    U8 ecdhSS[32];
    U16 ecdhSSLen = sizeof(ecdhSS);

    U8 indexOffset = 0x00;

    U8 nBlock = 1;

    int i;

    PRINTF( "\r\n-----------\r\nStart exPskTls1_2(%s, %s)\r\n------------\r\n", getInitModeAsString(initMode),
        (pskMode == 0x00) ? "PLAIN_PSK" : "ECDH_PSK");

    if ( (pskMode != PLAIN_PSK) && (pskMode != ECDH_PSK) )
    {
        PRINTF("pskMode (0x%02X) does not have a legal value.\r\n", pskMode);
        result = 0;
        return result;
    }

    DEV_ClearChannelState();
    // PRINTF("\r\nDBG_Reset()\r\n");
    // err = DBG_Reset();
    // result &= AX_CHECK_SW(err, SW_OK, "err");

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= a71chInitModule(initMode);

    // Conditionaly create and inject an ECC keypair (pskMode == ECDH_PSK)
    if (pskMode == ECDH_PSK)
    {
        ECCCurve_t eccCurve = ECCCurve_NIST_P256;
        EC_KEY *eccKeyTls_0 = NULL;
        EC_KEY *eccKeyTls_Host = NULL;

        // const U16 expectedPubKeyLen = 65;
        const U16 expectedPrivKeyLen = 32;

        err = HOSTCRYPTO_GenerateEccKey(eccCurve, &eccKeyTls_0);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        err = HOSTCRYPTO_GenerateEccKey(eccCurve, &eccKeyTls_Host);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        // Break down the ECC keys generated in OpenSSL into eccKeyComponents
        err = HOSTCRYPTO_GetPublicKey(eccKeyTls_0, eccKcTls_0.pub, &(eccKcTls_0.pubLen), (64 << 1)+1);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        err = HOSTCRYPTO_GetPrivateKey(eccKeyTls_0, eccKcTls_0.priv, &(eccKcTls_0.privLen), 64);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        eccKcTls_0.bits = expectedPrivKeyLen << 3;
        eccKcTls_0.curve = eccCurve;
        HOSTCRYPTO_FreeEccKey(&eccKeyTls_0);

        err = HOSTCRYPTO_GetPublicKey(eccKeyTls_Host, eccKcTls_Host.pub, &(eccKcTls_Host.pubLen), (64 << 1)+1);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        err = HOSTCRYPTO_GetPrivateKey(eccKeyTls_Host, eccKcTls_Host.priv, &(eccKcTls_Host.privLen), 64);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        eccKcTls_Host.bits = expectedPrivKeyLen << 3;
        eccKcTls_Host.curve = eccCurve;

        // Set first ECC keyPair with eccKcTls_0 (Key pair created on Host)
        indexKp = A71CH_KEY_PAIR_0;
        PRINTF("\r\nA71_SetEccKeyPair(0x%02x)\r\n", indexKp);
        err = A71_SetEccKeyPair(indexKp, eccKcTls_0.pub, eccKcTls_0.pubLen, eccKcTls_0.priv, eccKcTls_0.privLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        // Create and compare a shared secret on A71CH and Host
        //   The Second ECC key pair was already set, now use it in combination with
        // eccKeyTls_0 to create a shared secret
        // index = A71CH_KEY_PAIR_1;
        // PRINTF("\r\nA71_EcdhGetSharedSecret(0x%02x) on A71CH\r\n", index);
        // sharedSecretOnA71CHLen = sizeof(sharedSecretOnA71CH);
        // err = A71_EcdhGetSharedSecret(index, eccKcTls_0.pub, eccKcTls_0.pubLen, sharedSecretOnA71CH, &sharedSecretOnA71CHLen);
        // result &= AX_CHECK_SW(err, SW_OK, "err");
        // axPrintByteArray("sharedSecretOnA71CH", sharedSecretOnA71CH, sharedSecretOnA71CHLen, AX_COLON_32);

        PRINTF("\r\nA71_EcdhGetSharedSecret() on Host\r\n");
        ecdhSSLen = sizeof(ecdhSS);
        err = HOSTCRYPTO_ECC_ComputeSharedSecret(eccKeyTls_Host, eccKcTls_0.pub, eccKcTls_0.pubLen, ecdhSS, &ecdhSSLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        axPrintByteArray("sharedSecretOnHost", ecdhSS, ecdhSSLen, AX_COLON_32);
        HOSTCRYPTO_FreeEccKey(&eccKeyTls_Host);
    }

    // The premaster secret is stored in the SYM key store
    for (indexAesKey=0; indexAesKey<A71CH_SYM_KEY_MAX; indexAesKey++)
    {
        // Write the key (unwrapped)
        PRINTF( "\r\nA71_SetSymKey(0x%02x)\r\n", indexAesKey);
        err = A71_SetSymKey((SST_Index_t)indexAesKey, aesRef[indexAesKey], sizeof(aesRef[indexAesKey]));
        result &= AX_CHECK_SW(err, SW_OK, "err");
        axPrintByteArray("aesRef[indexAesKey]", aesRef[indexAesKey], sizeof(aesRef[indexAesKey]), AX_COLON_32);
    }

    // Convert ascii string to equivalent byte array - don't convert closing 0x00
    for (i=0; i<sizeof(labelString)-1; i++)
    {
        if (i >= AX_TLS_LABEL_LEN)
        {
            PRINTF("Insufficient storage for label (i=%d) totalsize=%d\r\n", i, sizeof(labelString));
            result = 0;
            break;
        }
        label[i] = (U8) labelString[i];
        PRINTF("0x%02X - %c\r\n", label[i], labelString[i]);
    }

    for (i=0; i<AX_TLS_SECRET_LEN; i++)
    {
        clientHelloRandom[i] = (U8)(0xC0 + i);
        serverHelloRandom[i] = (U8)(0x30 + i);
    }

    // REMARK: Backwards compatibility with 1.2 applet is not implemented (some elements to prepare for this are present)
    for (indexOffset = 0x00; indexOffset < A71CH_SYM_KEY_MAX; indexOffset++)
    {
        U8 nBlockMax = ( (A71CH_SYM_KEY_MAX-indexOffset) > A71CH_SYM_KEY_COMBINED_MAX ) ? A71CH_SYM_KEY_COMBINED_MAX : (A71CH_SYM_KEY_MAX-indexOffset);
        for (nBlock=1; nBlock<=nBlockMax; nBlock++)
        {
            int j;

            {
                clientHelloRandomLen = sizeof(clientHelloRandom);
                err = A71_CreateClientHelloRandom(clientHelloRandom, (U8)clientHelloRandomLen);
                result &= AX_CHECK_SW(err, SW_OK, "A71_CreateClientHelloRandom failed.");

                // Please ensure the label - as set in the A71CH - matches the value of 'label'

                memcpy(serverSeed, serverHelloRandom, AX_TLS_SECRET_LEN);
                serverSeedLen = AX_TLS_SECRET_LEN;
            }

            memcpy(labelAndSeed, label, AX_TLS_LABEL_LEN);
            memcpy(&labelAndSeed[AX_TLS_LABEL_LEN], clientHelloRandom, AX_TLS_SECRET_LEN);
            memcpy(&labelAndSeed[AX_TLS_LABEL_LEN+AX_TLS_SECRET_LEN], serverHelloRandom, AX_TLS_SECRET_LEN);
            labelAndSeedLen = sizeof(labelAndSeed);

            // Call A71_PskDeriveMasterSecret on Secure Element and compare created master secret with value returned by KDF on Host
            // ** Shared secret is nBlock * 16 byte long and located in (starts at) AES-STORE @ [A71CH_SYM_KEY_0 + indexOffset]
            indexAesKey = A71CH_SYM_KEY_0 + indexOffset;
            if (pskMode == PLAIN_PSK)
            {
                PRINTF("\r\nA71_PskDeriveMasterSecret(0x%02x, nBlock=%d, labelAndSeedLen=%d)\r\n", indexAesKey, nBlock, serverSeedLen);
                err = A71_PskDeriveMasterSecret(indexAesKey, nBlock, serverSeed, serverSeedLen, masterSecret);
                result &= AX_CHECK_SW(err, SW_OK, "A71_PskDeriveMasterSecret failed.");
            }
            else if (pskMode == ECDH_PSK)
            {
                PRINTF("\r\nA71_EcdhPskDeriveMasterSecret(0x%02x, 0x%02x, nBlock=%d, labelAndSeedLen=%d)\r\n", indexKp, indexAesKey, nBlock, serverSeedLen);
                err = A71_EcdhPskDeriveMasterSecret(indexKp, eccKcTls_Host.pub, eccKcTls_Host.pubLen, indexAesKey, nBlock,
                    serverSeed, serverSeedLen, masterSecret);
                result &= AX_CHECK_SW(err, SW_OK, "A71_PskDeriveMasterSecret failed.");
            }
            if (err == SW_OK)
            {
                axPrintByteArray("masterSecret", masterSecret, AX_TLS_PSK_MASTER_SECRET_LEN, AX_COLON_32);
            }

            // ** Calculate master secret on Host
            // *** First create pre-master secret based upon PSK
            for (j=0; j<nBlock; j++)
            {
                memcpy(&hostPsk[j*16], &aesRef[indexAesKey+j], sizeof(aesRef[indexAesKey+j]));
            }
            hostPskLen = nBlock*sizeof(aesRef[indexAesKey]);
            axPrintByteArray("hostPsk", hostPsk, nBlock*sizeof(aesRef[indexAesKey]), AX_COLON_32);
            premasterSecretLen = sizeof(premasterSecret);
            if (pskMode == PLAIN_PSK)
            {
                err = HOSTCRYPTO_TlsPskCreatePremasterSecret(hostPsk, hostPskLen, premasterSecret, &premasterSecretLen);
                result &= AX_CHECK_SW(err, SW_OK, "Failed to create premasterSecret");
            }
            else if (pskMode == ECDH_PSK)
            {
                err = HOSTCRYPTO_TlsEcdhPskCreatePremasterSecret(ecdhSS, ecdhSSLen, hostPsk, hostPskLen, premasterSecret, &premasterSecretLen);
                result &= AX_CHECK_SW(err, SW_OK, "Failed to create premasterSecret");
            }
            if (err == SW_OK) { axPrintByteArray("premasterSecret", premasterSecret, premasterSecretLen, AX_COLON_32); }
            // *** Now invoke P_SHA256
            PRINTF("\r\nHOSTCRYPTO_Tls1_2_P_Sha256(secret,secretLen=%d, ...)\r\n", premasterSecretLen);
            err = HOSTCRYPTO_Tls1_2_P_Sha256(premasterSecret, premasterSecretLen,
                labelAndSeed, labelAndSeedLen, masterSecretHost, masterSecretHostLen);
            result &= AX_CHECK_SW(err, SW_OK, "HOSTCRYPTO_Tls1_2_P_Sha256 failed");
            if (err == SW_OK)
            {
                axPrintByteArray("masterSecretHost", masterSecretHost, AX_TLS_PSK_MASTER_SECRET_LEN, AX_COLON_32);
            }

            // ** Compare both master secrets
            if (memcmp(masterSecret, masterSecretHost, AX_TLS_PSK_MASTER_SECRET_LEN) != 0 )
            {
                result = 0;

                PRINTF("\r\n***** ERROR Master secrets differ for PSKLen = %d:\r\n", nBlock*16);
                axPrintByteArray("masterSecret", masterSecret, AX_TLS_PSK_MASTER_SECRET_LEN, AX_COLON_32);
                axPrintByteArray("masterSecretHost", masterSecretHost, AX_TLS_PSK_MASTER_SECRET_LEN, AX_COLON_32);
            }
            if (result == 0)
                break;
        }
        if (result == 0)
            break;
    }

    PRINTF("\r\n-----------\r\nEnd exPskTls1_2(%s, %s), result = %s\r\n------------\r\n", getInitModeAsString(initMode),
        (pskMode == 0x00) ? "PLAIN_PSK" : "ECDH_PSK",
        ((result == 1)? "OK": "FAILED") );

    return result;
}
