/**
* @file ax_sss_scp.c
* @author NXP Semiconductors
* @version 1.0
* @par License
*
* Copyright 2016,2020 NXP
* SPDX-License-Identifier: Apache-2.0
*
* @par Description
* This file implements the setting up of the SCP03 communication channel.
* @note Execution flow and Error messages can be sent to the console by defining
* FLOW_VERBOSE and ERROR_VERBOSE respectively at the start of the source code file.
* @par History
* 1.0   26-march-2014 : Initial version
*
*/
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <nxLog_scp.h>
#include <nxEnsure.h>


#include "ax_api.h"
#include "sm_apdu.h"
#include "sm_errors.h"
#include "HostCryptoAPI.h"
#include "ax_util.h"
#include "sm_printf.h"
#include "global_platf.h"
#include "ax_sss_scp.h"

#include <fsl_sss_api.h>

#if defined(SSS_USE_FTR_FILE)
#include "fsl_sss_ftr.h"
#else
#include "fsl_sss_ftr_default.h"
#endif

#if SSS_HAVE_SCP_SCP03_SSS
static Scp_SSS_State_t scp_sss_State[2];
#endif
// #define FLOW_VERBOSE   //!< Define to enable execution flow messages
#define ERROR_VERBOSE  //!< Define to enable reporting of error messages


/**
* Performs an SCP03 authentication with the SM and - when successful - computes
* the SCP03 session keys and initializes the current Session state.
*
* @param[in] keyObj SCP03 channel encryption base key Objects (aka static key) (16 bytes)
* @param[in,out] sCounter SCP03 sequence counter (3 bytes)
* @param[in,out] sCounterLen
*/
#if SSS_HAVE_SCP_SCP03_SSS
U16 SCP_SSS_Authenticate(SM_SECURE_SCP03_KEYOBJ * scp03Params, U8 *sCounter, U16 *sCounterLen)
{
    ChannelId_t channelId;
    U8 hostChallenge[] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
    U8 keyDivData[SCP_GP_IU_KEY_DIV_DATA_LEN];
    U16 keyDivDataLen = sizeof(keyDivData);
    U8 keyInfo[SCP_GP_IU_KEY_INFO_LEN];
    U16 keyInfoLen = sizeof(keyInfo);
    U8 cardChallenge[SCP_GP_CARD_CHALLENGE_LEN];
    U16 cardChallengeLen = sizeof(cardChallenge);
    U8 cardCryptoGram[SCP_GP_IU_CARD_CRYPTOGRAM_LEN];
    U16 cardCryptoGramLen = sizeof(cardCryptoGram);
    U8 seqCounter[SCP_GP_IU_SEQ_COUNTER_LEN];
    U16 seqCounterLen = sizeof(seqCounter);
    U8 hostCryptogram[SCP_GP_IU_CARD_CRYPTOGRAM_LEN];
    sss_rng_context_t rngctx;
    scp_CommandType_t dummy;
    U16 err = 0;
    sss_status_t status = kStatus_SSS_Fail;
    channelId = DEV_GetSelectedChannel(&dummy);


    status = sss_rng_context_init(&rngctx, scp03Params->pKeyEnc.keyStore->session /* Session */);
    if (status == kStatus_SSS_Success)
    {
        status = sss_rng_get_random(&rngctx, hostChallenge,8);
    }
    sss_rng_context_free(&rngctx);
    if (status != kStatus_SSS_Success)
        return ERR_CRYPTO_ENGINE_FAILED;

    err = SCP_GP_InitializeUpdate(channelId, hostChallenge, sizeof(hostChallenge),
        keyDivData, &keyDivDataLen,
        keyInfo, &keyInfoLen,
        cardChallenge, &cardChallengeLen,
        cardCryptoGram, &cardCryptoGramLen,
        seqCounter, &seqCounterLen);
    if (err != SW_OK)
    {
        LOG_E("SCP_GP_InitializeUpdate fails with status: 0x%04X\r\n", err);
        return err;
    }
    LOG_MAU8_D("keyDivData", keyDivData, keyDivDataLen);
    LOG_MAU8_D("keyInfo", keyInfo, keyInfoLen);
    LOG_MAU8_D("cardChallenge", cardChallenge, cardChallengeLen);
    LOG_MAU8_D("cardCryptoGram", cardCryptoGram, cardCryptoGramLen);
    if (seqCounterLen == SCP_GP_IU_SEQ_COUNTER_LEN)
    {
        LOG_MAU8_D("seqCounter", seqCounter, seqCounterLen);
        if (*sCounterLen >= SCP_GP_IU_SEQ_COUNTER_LEN)
        {
            // Enough buffer space is provided by caller
            memcpy(sCounter, seqCounter, seqCounterLen);
            *sCounterLen = seqCounterLen;
        }
        else
        {
            return SCP_PARAMETER_ERROR;
        }
    }
    else
    {
        *sCounterLen = 0;
    }

    err = SCP_SSS_HostLocal_CalculateSessionKeys(channelId, scp03Params, hostChallenge, cardChallenge);
    if (err != SW_OK)
    {
        LOG_E("SCP_HostLocal_CalculateSessionKeys fails with status: 0x%04X\r\n", err);
        return err;
    }

    err = SCP_SSS_HostLocal_VerifyCardCryptogram(channelId, hostChallenge, cardChallenge, cardCryptoGram);
    if (err != SW_OK)
    {
        LOG_E("SCP_HostLocal_VerifyCardCryptogram fails with status: 0x%04X\r\n", err);
        return err;
    }

    err = SCP_SSS_HostLocal_CalculateHostCryptogram(channelId, hostChallenge, cardChallenge, hostCryptogram);
    LOG_MAU8_D("hostCryptogram", hostCryptogram, SCP_GP_IU_CARD_CRYPTOGRAM_LEN);
    if (err != SW_OK)
    {
        LOG_E("SCP_HostLocal_CalculateHostCryptogram fails with status: 0x%04X\r\n", err);
        return err;
    }

    err = SCP_SSS_GP_ExternalAuthenticate(channelId, hostCryptogram);
    if (err != SW_OK)
    {
        LOG_E("SCP_GP_ExternalAuthenticate fails with status: 0x%04X\r\n", err);
        return err;
    }

    // At this stage we have authenticated successfully.
    SCP_SSS_HostLocal_SetDefaultValueIcvCCounter(channelId);
    DEV_SetChannelCommandType(channelId, C_MAC_C_ENC_R_MAC_R_ENC);

    return err;
}

U16 SCP_SSS_HostLocal_CalculateSessionKeys(ChannelId_t channelId,SM_SECURE_SCP03_KEYOBJ *scp03Params, U8 *hostChallenge, U8 *cardChallenge)
{
    int stateIdx = 0;
    U8 ddA[128];
    U16 ddALen = sizeof(ddA);
    U8 context[128];
    U16 contextLen = 0;
    U8 sessionEncKey[AES_KEY_LEN_nBYTE];
    U8 sessionMacKey[AES_KEY_LEN_nBYTE];
    U8 sessionRmacKey[AES_KEY_LEN_nBYTE];
    U32 signatureLen = sizeof(sessionMacKey);
    S32 ret;
    sss_status_t status;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    LOG_I("HOST: Calculate session keys\r\n");

    // Calculate the Derviation data
    memcpy(context, hostChallenge, SCP_GP_HOST_CHALLENGE_LEN);
    memcpy(&context[SCP_GP_HOST_CHALLENGE_LEN], cardChallenge, SCP_GP_CARD_CHALLENGE_LEN);
    contextLen = SCP_GP_HOST_CHALLENGE_LEN + SCP_GP_CARD_CHALLENGE_LEN;

    // Calculate the Session-ENC key
    DEV_setDataDerivationArray(ddA, &ddALen,
        DATA_DERIVATION_SENC, DATA_DERIVATION_L_128BIT, DATA_DERIVATION_KDF_CTR, context, contextLen);
    ret = SCP_SSS_CalculateCMAC(scp03Params->pKeyEnc, ddA, ddALen, sessionEncKey, &signatureLen);
    if (ret != HOST_CRYPTO_OK) { return ERR_CRYPTO_ENGINE_FAILED; }
    LOG_MAU8_D("sessionEncKey", sessionEncKey, AES_KEY_LEN_nBYTE);
    /* Init ENC  session key object */
    status = sss_key_object_init(&scp_sss_State[stateIdx].session.sEnckeyObj, scp03Params->pKeyEnc.keyStore);
    if (status != kStatus_SSS_Success)
    {
        return SCP_FAIL;
    }
    ret = SCP_SSS_Save_SessionKeyObj(&scp_sss_State[stateIdx].session.sEnckeyObj, sessionEncKey);
    if (ret == HOST_CRYPTO_ERROR)
    {
        return SCP_FAIL;
    }

    // Calculate the Session-MAC key
    DEV_setDataDerivationArray(ddA, &ddALen,
        DATA_DERIVATION_SMAC, DATA_DERIVATION_L_128BIT, DATA_DERIVATION_KDF_CTR, context, contextLen);
    ret = SCP_SSS_CalculateCMAC(scp03Params->pKeyMac, ddA, ddALen, sessionMacKey, &signatureLen);
    if (ret != HOST_CRYPTO_OK) { return ERR_CRYPTO_ENGINE_FAILED; }
    LOG_MAU8_D("sessionMacKey", sessionMacKey, AES_KEY_LEN_nBYTE);
    /* Init MAC  session key object */
    status = sss_key_object_init(&scp_sss_State[stateIdx].session.sMackeyObj, scp03Params->pKeyMac.keyStore);
    if (status != kStatus_SSS_Success)
    {
        return SCP_FAIL;
    }
    ret = SCP_SSS_Save_SessionKeyObj(&scp_sss_State[stateIdx].session.sMackeyObj, sessionMacKey);
    if (ret == HOST_CRYPTO_ERROR)
    {
        return SCP_FAIL;
    }

    // Calculate the Session-RMAC key
    DEV_setDataDerivationArray(ddA, &ddALen,
        DATA_DERIVATION_SRMAC, DATA_DERIVATION_L_128BIT, DATA_DERIVATION_KDF_CTR, context, contextLen);
    ret = SCP_SSS_CalculateCMAC(scp03Params->pKeyMac, ddA, ddALen, sessionRmacKey, &signatureLen);
    if (ret != HOST_CRYPTO_OK) { return ERR_CRYPTO_ENGINE_FAILED; }
    LOG_MAU8_D("sessionRmacKey", sessionRmacKey, AES_KEY_LEN_nBYTE);
    /* Init RMAC  session key object */
    status = sss_key_object_init(&scp_sss_State[stateIdx].session.sRMackeyObj, scp03Params->pKeyDek.keyStore);
    if (status != kStatus_SSS_Success)
    {
        return SCP_FAIL;
    }
    ret = SCP_SSS_Save_SessionKeyObj(&scp_sss_State[stateIdx].session.sRMackeyObj, sessionRmacKey);
    if (ret == HOST_CRYPTO_ERROR)
    {
        return SCP_FAIL;
    }

    return SCP_OK;
}

HLSE_RET_CODE   SCP_SSS_CalculateCMAC(sss_object_t keyObj,
    U8* inData, U32 inDataLen,
    U8* outSignature, U32* outSignatureLen)
{
    sss_mac_t macCtx;
    sss_status_t status;
    sss_algorithm_t algorithm;
    sss_mode_t mode;
    algorithm = kAlgorithm_SSS_CMAC_AES;
    mode = kMode_SSS_Mac;
    HLSE_RET_CODE ret = HOST_CRYPTO_ERROR;

    // Init Context
    status = sss_mac_context_init(
        &macCtx, keyObj.keyStore->session, &keyObj, algorithm, mode);

    if (status == kStatus_SSS_Success)
    {
        // Calculate CMAC
        status = sss_mac_one_go(
            &macCtx, inData, (size_t)inDataLen,
            (uint8_t*)outSignature, (size_t*)outSignatureLen);
    }
    if (status == kStatus_SSS_Success)
    {
        ret = HOST_CRYPTO_OK;
    }
    return ret;
}

U16 SCP_SSS_Save_SessionKeyObj(sss_object_t *keyObj, U8 *Sessionkey)
{
    sss_status_t status;
    static int i = 0;
    U16 ret = HOST_CRYPTO_ERROR;
    /* Allocate handle for SSS object */
    status = sss_key_object_allocate_handle(keyObj,
        0xAA58 + i,
        kSSS_KeyPart_Default,
        kSSS_CipherType_AES,
        16,
        kKeyObject_Mode_Transient);
    if (status == kStatus_SSS_Success) {
        /* Set the key */
        status = sss_key_store_set_key(
            keyObj->keyStore, keyObj, Sessionkey, 16, (16) * 8, NULL, 0);
    }
    if (status == kStatus_SSS_Success) {
        /* Save the key store */
        status = sss_key_store_save(keyObj->keyStore);
    }

    if (status == kStatus_SSS_Success) {
        i++;
        ret = HOST_CRYPTO_OK;
    }
    return ret;
}

U16 SCP_SSS_HostLocal_VerifyCardCryptogram(ChannelId_t channelId, U8 *hostChallenge, U8 *cardChallenge ,U8 *cardCryptogram)
{
    int stateIdx = 0;
    U8 ddA[128];
    U16 ddALen = sizeof(ddA);
    U8 context[128];
    U16 contextLen = 0;
    U8 cardCryptogramFullLength[AES_KEY_LEN_nBYTE];
    U16 rv = SCP_OK;
    U32 signatureLen = sizeof(cardCryptogramFullLength);
    S32 ret;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    LOG_I("HOST: Verify Card Cryptogram\r\n");

    memcpy(context, hostChallenge, SCP_GP_HOST_CHALLENGE_LEN);
    memcpy(&context[SCP_GP_HOST_CHALLENGE_LEN], cardChallenge, SCP_GP_CARD_CHALLENGE_LEN);
    contextLen = SCP_GP_HOST_CHALLENGE_LEN + SCP_GP_CARD_CHALLENGE_LEN;

    DEV_setDataDerivationArray(ddA, &ddALen,
        DATA_CARD_CRYPTOGRAM, DATA_DERIVATION_L_64BIT, DATA_DERIVATION_KDF_CTR, context, contextLen);

     ret = SCP_SSS_CalculateCMAC(scp_sss_State[stateIdx].session.sMackeyObj, ddA, ddALen, cardCryptogramFullLength, &signatureLen);
    if (ret != HOST_CRYPTO_OK) { return ERR_CRYPTO_ENGINE_FAILED; }

    LOG_MAU8_D("cardCryptogramFullLength - Verify", cardCryptogramFullLength, AES_KEY_LEN_nBYTE);

    // Verify whether the 8 left most byte of cardCryptogramFullLength match cardCryptogram
    if (memcmp(cardCryptogramFullLength, cardCryptogram, SCP_GP_IU_CARD_CRYPTOGRAM_LEN) != 0)
    {
        rv = SCP_CARD_CRYPTOGRAM_FAILS_TO_VERIFY;
    }

    return rv;
}

U16 SCP_SSS_HostLocal_CalculateHostCryptogram(ChannelId_t channelId, U8 *hostChallenge, U8 *cardChallenge, U8 *hostCryptogram)
{
    int stateIdx = 0;
    U8 ddA[128];
    U16 ddALen = sizeof(ddA);
    U8 context[128];
    U16 contextLen = 0;
    U8 hostCryptogramFullLength[AES_KEY_LEN_nBYTE];
    U32 signatureLen = sizeof(hostCryptogramFullLength);
    S32 ret;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    LOG_I("HOST: Calculate Host Cryptogram\r\n");

    memcpy(context, hostChallenge, SCP_GP_HOST_CHALLENGE_LEN);
    memcpy(&context[SCP_GP_HOST_CHALLENGE_LEN], cardChallenge, SCP_GP_CARD_CHALLENGE_LEN);
    contextLen = SCP_GP_HOST_CHALLENGE_LEN + SCP_GP_CARD_CHALLENGE_LEN;

    DEV_setDataDerivationArray(ddA, &ddALen,
        DATA_HOST_CRYPTOGRAM, DATA_DERIVATION_L_64BIT, DATA_DERIVATION_KDF_CTR, context, contextLen);

    ret = SCP_SSS_CalculateCMAC(scp_sss_State[stateIdx].session.sMackeyObj, ddA, ddALen, hostCryptogramFullLength, &signatureLen);

    if (ret != HOST_CRYPTO_OK) { return ERR_CRYPTO_ENGINE_FAILED; }

    // Chop of the tail of the hostCryptogramFullLength
    memcpy(hostCryptogram, hostCryptogramFullLength, SCP_GP_IU_CARD_CRYPTOGRAM_LEN);

    return SCP_OK;
}

U16 SCP_SSS_GP_ExternalAuthenticate(ChannelId_t channelId, U8* hostCryptogram)
{
    U32 st = 0;
    U8 txBuf[128];
    U8 cla = 0;
    U8 response[128];
    U32 responseLen = 128;
    U16 rv = 0;
    U8 mcv[AES_KEY_LEN_nBYTE];
    U8 macToAdd[AES_KEY_LEN_nBYTE];
    int stateIdx = 0;// ADMIN_CHANNEL_STATE_IDX;
    sss_mac_t macCtx;
    sss_algorithm_t algorithm;
    sss_mode_t mode;
    algorithm = kAlgorithm_SSS_CMAC_AES;
    mode = kMode_SSS_Mac;
    size_t signatureLen = sizeof(macToAdd);
    sss_status_t status;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    LOG_I(">> %s: Enter\r\n", "SCP_GP_ExternalAuthenticate");

    cla = 0x84;

    txBuf[0] = cla;
    txBuf[1] = INS_GP_EXTERNAL_AUTHENTICATE;
    txBuf[2] = SECLVL_CDEC_RENC_CMAC_RMAC;
    txBuf[3] = 0x00;
    txBuf[4] = 0x10; // The Lc valus is set as-if the MAC has already been appended (SCP03 spec p16. Fig.6-1)
    memcpy(&txBuf[5], hostCryptogram, SCP_GP_IU_CARD_CRYPTOGRAM_LEN);

    // Calculate the MAC value
    status = sss_mac_context_init(
        &macCtx, scp_sss_State[stateIdx].session.sMackeyObj.keyStore->session,
        &scp_sss_State[stateIdx].session.sMackeyObj, algorithm, mode);

    if (status != kStatus_SSS_Success)
    {
        return ERR_CRYPTO_ENGINE_FAILED;
    }
    status = sss_mac_init(&macCtx);
    if (status != kStatus_SSS_Success)
    {
        return ERR_CRYPTO_ENGINE_FAILED;
    }

    /*
    * For the EXTERNAL AUTHENTICATE command MAC verification, the "MAC chaining value" is set to 16
    * bytes '00'. (SCP03 spec p16)
    */
    SCP_SSS_HostLocal_ResetMacChainingValue(channelId);
    memcpy(mcv, scp_sss_State[stateIdx].session.mcv, AES_KEY_LEN_nBYTE);

    status = sss_mac_update( &macCtx, mcv, AES_KEY_LEN_nBYTE);
    if (status != kStatus_SSS_Success)
    {
        return ERR_CRYPTO_ENGINE_FAILED;
    }
    status = sss_mac_update(&macCtx, txBuf, 13);
    if (status != kStatus_SSS_Success)
    {
        return ERR_CRYPTO_ENGINE_FAILED;
    }
    status = sss_mac_finish(&macCtx, macToAdd, &signatureLen);
    if (status != kStatus_SSS_Success)
    {
        return ERR_CRYPTO_ENGINE_FAILED;
    }
    memcpy(scp_sss_State[stateIdx].session.mcv, macToAdd, AES_KEY_LEN_nBYTE);

    memcpy(&txBuf[5 + SCP_GP_IU_CARD_CRYPTOGRAM_LEN], macToAdd, SCP_GP_IU_CARD_CRYPTOGRAM_LEN);

    LOG_MAU8_D("mcv", mcv, 16);
    LOG_MAU8_D("txBuf", txBuf, 13);
    LOG_MAU8_D("macToAdd", macToAdd, 16);

#ifdef TGT_EDEV
    if (channelId == AX_HOST_CHANNEL)
    {
        // Modify the CLA byte to tag this channel as a Host Channel
        cla = 0xE4;
    }
    txBuf[0] = cla;
#endif

    st = smCom_TransceiveRaw(NULL, (U8*)txBuf, 5 + AES_KEY_LEN_nBYTE, response, &responseLen);

    if (st != SMCOM_OK)
    {
        LOG_E("SCP_GP_ExternalAuthenticate %lX\r\n", st);
        rv = ERR_GENERAL_ERROR;
    }
    else
    {
        rv = CheckNoResponseDataRaw(response, (U16)responseLen);
    }
    return rv;
}


//State maintain functions (scp_sss_State)

U16 SCP_SSS_HostLocal_SetDefaultValueIcvCCounter(ChannelId_t channelId)
{
    U8 commandCounter[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 };
    int stateIdx = 0;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    memcpy(scp_sss_State[stateIdx].session.cCounter, commandCounter, 16);

    return SCP_OK;
}


U16 SCP_SSS_HostLocal_IncIcvCCounter(ChannelId_t channelId)
{
    int stateIdx = 0;
    int i = 15;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    i = 15;
    while (i > 0)
    {
        if (scp_sss_State[stateIdx].session.cCounter[i] < 255)
        {
            scp_sss_State[stateIdx].session.cCounter[i] += 1;
            break;
        }
        else
        {
            scp_sss_State[stateIdx].session.cCounter[i] = 0;
            i--;
        }
    }

    return SCP_OK;
}

U16 SCP_SSS_HostLocal_ResetMacChainingValue(ChannelId_t channelId)
{
    int stateIdx = 0;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    memset(scp_sss_State[stateIdx].session.mcv, 0, SCP_MCV_LEN);

    return SCP_OK;
}

U16 SCP_SSS_HostLocal_SetMacChainingValue(ChannelId_t channelId, U8 *mcv)
{
    int stateIdx = 0;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    memcpy(scp_sss_State[stateIdx].session.mcv, mcv, SCP_MCV_LEN);

    return SCP_OK;
}

/**
* Copy the session state into \p pSession. Caller must allocate memory of \p pSession.
* @param[in] channelId Either ::AX_HOST_CHANNEL or ::AX_ADMIN_CHANNEL. Must be ::AX_HOST_CHANNEL in case of A71CH.
* @param[in,out] pSession IN: pointer to allocated ::Scp03SessionState_t structure; OUT: retrieved state
* @retval ::SW_OK Upon successful execution
* @retval ::SCP_UNDEFINED_CHANNEL_ID In case an undefined ::ChannelId_t type was passed as parameter
*/
U16 SCP_SSS_HostLocal_GetSessionState(ChannelId_t channelId, Scp03_SSS_SessionState_t *pSession)
{
    int stateIdx = 0;

    switch (channelId)
    {
    case AX_HOST_CHANNEL:
        stateIdx = HOST_CHANNEL_STATE_IDX;
        break;
    case AX_ADMIN_CHANNEL:
        stateIdx = ADMIN_CHANNEL_STATE_IDX;
        break;
    default:
        return SCP_UNDEFINED_CHANNEL_ID;
    }

    memcpy(pSession, &(scp_sss_State[stateIdx].session), sizeof(Scp03_SSS_SessionState_t));

    return SCP_OK;
}
U16 SM_ChannelAuthenticate(SM_SECURE_SCP03_KEYOBJ *scp03Params, U8 *cCounter)
{
    U16 counterLen = 16;
    U16 lReturn = SCP_FAIL;

    lReturn = SCP_SSS_Authenticate(scp03Params, cCounter, &counterLen);

    if (lReturn != SW_OK)
        return lReturn;


    return lReturn;
}

#endif

#ifdef TGT_EDEV
#ifndef AX_SF
/**
* Performs a soft-reset of the Security Module, effectively resetting the SCP channels.
*               This function is only available for the administrator
* @return status.
*/
U16 SM_SoftReset(void)
{
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U16 rv;

    pApdu->cla   = AX_CLA;
    pApdu->ins   = INS_AX_SM;
    pApdu->p1    = P1_SOFT_RESET;
    pApdu->p2    = 0x00;

    AllocateAPDUBuffer(pApdu);

    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);
    scp_Transceive(pApdu, SCP_MODE);

    // no response data expected
    rv = CheckNoResponseData(pApdu);

    FreeAPDUBuffer(pApdu);
    return rv;
}
#endif // AX_SF
#endif // TGT_EDEV
