/*
* @author NXP Semiconductors
* @version 1.0
* @par License
*
* Copyright 2016,2020 NXP
* SPDX-License-Identifier: Apache-2.0
*
* @par History
* 1.0   2016-Sep-22 : Initial version
*
*****************************************************************************/
/**
* @file a71ch_crypto_derive.c
* @par Description
* Wrap the key derivation functionality of the A71CH.
*/
#include <stddef.h>
#include <string.h>
#include <stdio.h> // DEBUG

#include "scp.h"
#include "a71ch_api.h"
#include "sm_apdu.h"
#include "sm_errors.h"
#include <nxLog_App.h>
#include "nxEnsure.h"

/// @cond
static U16 DERIVE_KdfGeneric(SST_Index_t index, U8 nBlock, const U8 *salt, U16 saltLen, const U8 *info, U16 infoLen, U8 *derivedData, U16 derivedDataLen)
{
    U8 isOk;
    U16 rv;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U16 minBufLen = derivedDataLen;
    U8 data = 0x00;

#ifndef A71_IGNORE_PARAM_CHECK
    ENSURE_OR_EXIT_WITH_STATUS_ON_ERROR(((info != NULL) && (derivedData != NULL)), rv, ERR_API_ERROR)
#endif


    ENSURE_OR_EXIT_WITH_STATUS_ON_ERROR(infoLen <= DERIVE_KEYDATA_FROM_SHARED_SECRET_MAX_INFO, rv, ERR_API_ERROR);

    ENSURE_OR_EXIT_WITH_STATUS_ON_ERROR(derivedDataLen <= DERIVE_KEYDATA_FROM_SHARED_SECRET_MAX_DERIVED_DATA, rv, ERR_API_ERROR);

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_KDF_SYM_KEY;
    pApdu->p1    = (nBlock << 4) + index;
    pApdu->p2    = (U8)derivedDataLen;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    if (saltLen != 0)
    {
        if (salt == NULL) {
            FreeAPDUBuffer(pApdu);
            return ERR_API_ERROR;
        }
        data = (U8)saltLen;
        smApduAppendCmdData(pApdu, &data, 1);
        smApduAppendCmdData(pApdu, salt, saltLen);
    }
    data = (U8)infoLen;
    smApduAppendCmdData(pApdu, &data, 1);
    smApduAppendCmdData(pApdu, info, infoLen);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        rv = smGetSw(pApdu, &isOk);
        if (isOk)
        {
            rv = smApduGetResponseBody(pApdu, derivedData, &minBufLen);
            if (rv == SW_OK)
            {
                if (minBufLen != derivedDataLen)
                {
                    rv = ERR_WRONG_RESPONSE;
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
exit:
    return rv;
}
/// @endcond

/**
* The HMAC Key Derivation function derives a key from a stored secret using SHA256 as hash function according to [RFC5869].
  Only the expand step will be executed.

  The secret is stored in the SYM key store. It can be either 16, 32, 48 or 64 byte long.
  The Most Significant part of the secret resides in the storage location with the lowest index.
  The subsequent parts reside in the next storage locations. The nBlock parameter is equal to the length
  of the secret divided by 16.
  A secret with length 64 can only start at Index 0 of the SYM key store: a secret can not be stored wrapped around in the
  SYM key store.

  \note infoLen must be smaller than 254 byte.

* \param[in] index Index of the SYM key store containing the MSB part of the pre-shared secret
* \param[in] nBlock Amount of blocks, equivalent to the pre-shared secret length when multiplied by 16
* \param[in] info Context and application specific information used in expand step
* \param[in] infoLen The length of the info data passed as argument
* \param[in,out] derivedData IN: caller passes a buffer of at least derivedDataLen;
     OUT: contains the calculated derived data
* \param[in] derivedDataLen IN: length of the requested derivedData. Must be smaller than 256 byte.
*
* \retval ::SW_OK Successfull execution
*/
U16 A71_HkdfExpandSymKey(SST_Index_t index, U8 nBlock, const U8 *info, U16 infoLen, U8 *derivedData, U16 derivedDataLen)
{
    U8 *salt = NULL;
    U16 saltLen = 0;
    return DERIVE_KdfGeneric(index, nBlock, salt, saltLen, info, infoLen, derivedData, derivedDataLen);
}

/**
* The HMAC Key Derivation function derives a key from a stored secret using SHA256 as hash function according to [RFC5869].
  Both the extract and expand steps will be executed.

  In case a zero length salt value is passed as argument, this function is equivalent to A71_HkdfExpandSymKey:
  i.e. the extract step is skipped. To enforce the usage of the default salt value (a Bytestring of 32 zeroes)
  the caller must explicitly pass this default salt value as argument to this function.

  The secret is stored in the SYM key store. It can be either 16, 32, 48 or 64 byte long.
  The Most Significant part of the secret resides in the storage location with the lowest index.
  The subsequent parts reside in the next storage locations. The nBlock parameter is equal to the length
  of the secret divided by 16.
  A secret with length 64 can only start at Index 0 of the SYM key store: a secret can not be stored wrapped around in the
  SYM key store.

  \note The sum of saltLen and infoLen must be smaller than 254 byte.

* \param[in] index Index of the SYM key store containing the MSB part of the pre-shared secret
* \param[in] nBlock Amount of blocks, equivalent to the pre-shared secret length when multiplied by 16
* \param[in] salt Salt data used in extract step
* \param[in] saltLen The length of the salt data passed as argument
* \param[in] info Context and application specific information used in expand step
* \param[in] infoLen The length of the info data passed as argument
* \param[in,out] derivedData IN: caller passes a buffer of at least derivedDataLen;
     OUT: contains the calculated derived data
* \param[in] derivedDataLen IN: length of the requested derivedData. Must be smaller than 256 byte.
*
* \retval ::SW_OK Successfull execution
*/
U16 A71_HkdfSymKey(SST_Index_t index, U8 nBlock, const U8 *salt, U16 saltLen, const U8 *info, U16 infoLen, U8 *derivedData, U16 derivedDataLen)
{
    return DERIVE_KdfGeneric(index, nBlock, salt, saltLen, info, infoLen, derivedData, derivedDataLen);
}

/**
* This function calculates the PRF according to TLS1.2 [RFC5246]. The pre-master secret is formed - based upon
  a pre-shared secret (PSK) stored in the secure module - according to [RFC4279].

  The pre-shared secret is stored in the SYM key store. It can be either 16, 32, 48 or 64 byte long.
  The Most Significant part of the pre-shared secret resides in the storage location with the lowest index.
  The subsequent parts reside in the next storage locations. The nBlock parameter is equal to the length
  of the PSK divided by 16.

  A PSK cannot be stored wrapped around in the SYM key store.

  The PRF creating the masterSecret also takes as parameter the concatentation of label ("master_secret"), ClientHello.random and ServerHello.random.
  This function only takes ServerHello.random as parameter: ClientHello.random has already been set by a call to ::A71_CreateClientHelloRandom,
  the value of the label (default is "master_secret") can be overruled by a call to ::A71_SetTlsLabel.

  \pre This call must be preceded by a call to ::A71_CreateClientHelloRandom, no other A71CH API call (implying
  an APDU exchange between Host and A71CH) may be executed in between the invocation of ::A71_CreateClientHelloRandom
  and ::A71_PskDeriveMasterSecret

* \param[in] index Index of the SYM key store containing the MSB part of the pre-shared secret
* \param[in] nBlock Amount of blocks, equivalent to the pre-shared secret length when multiplied by 16
* \param[in] serverHelloRnd ServerHello.random (concatenated with values already contained in A71CH)
* \param[in] serverHelloRndLen The length of serverHelloRnd passed as an argument
* \param[in,out] masterSecret IN: caller passes a buffer of at least 48 byte; OUT: contains the calculated master Secret, TLS 1.2 mandates this to be 48 byte exact
*
* \retval ::SW_OK Successfull execution
*/
U16 A71_PskDeriveMasterSecret(SST_Index_t index, U8 nBlock, const U8 *serverHelloRnd, U16 serverHelloRndLen, U8 *masterSecret)
{
    U8 isOk;
    U16 rv;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U16 minBufLen = AX_TLS_PSK_MASTER_SECRET_LEN;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((serverHelloRnd == NULL) || (masterSecret == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    if ( nBlock > A71CH_SYM_KEY_COMBINED_MAX)
    {
        return ERR_API_ERROR;
    }

    if (serverHelloRndLen > A71CH_MAX_CMD_PAYLOAD_SIZE)
    {
        return ERR_API_ERROR;
    }

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_MS_PSK_SYM_KEY;
    pApdu->p1    = (nBlock << 4) + index;
    pApdu->p2    = 0x00;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    smApduAppendCmdData(pApdu, serverHelloRnd, serverHelloRndLen);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        rv = smGetSw(pApdu, &isOk);
        if (isOk)
        {
            rv = smApduGetResponseBody(pApdu, masterSecret, &minBufLen);
            if (rv == SW_OK)
            {
                if (minBufLen != AX_TLS_PSK_MASTER_SECRET_LEN)
                {
                    rv = ERR_WRONG_RESPONSE;
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}


/**
* This function calculates the PRF according to TLS1.2 [RFC5246]. The pre-master secret is formed - based upon
  a pre-shared secret (PSK) stored in the secure module and on an ECDH calculation - according to [RFC5489].

  The pre-shared secret is stored in the SYM key store. It can be either 16, 32, 48 or 64 byte long.
  The Most Significant part of the pre-shared secret resides in the storage location with the lowest index.
  The subsequent parts reside in the next storage locations. The nBlock parameter is equal to the length
  of the PSK divided by 16.

  A PSK cannot be stored wrapped around in the SYM key store.

  The PRF creating the masterSecret also takes as parameter the concatentation of label ("master_secret"), ClientHello.random and ServerHello.random.
  This function only takes ServerHello.random as parameter: ClientHello.random has already been set by a call to ::A71_CreateClientHelloRandom,
  the value of the label (default is "master_secret") can be overruled by a call to ::A71_SetTlsLabel.

  \pre This call must be preceded by a call to ::A71_CreateClientHelloRandom, no other A71CH API call (implying
  an APDU exchange between Host and A71CH) may be executed in between the invocation of ::A71_CreateClientHelloRandom
  and ::A71_EcdhPskDeriveMasterSecret


* \param[in] indexKp Index of the ECC keypair whose private key is used in the ECDH operation
* \param[in] publicKey Value of the public key to be used in ECDH operation
* \param[in] publicKeyLen Length of publicKey in byte
* \param[in] index Index of the SYM key store containing the MSB part of the pre-shared secret
* \param[in] nBlock Amount of blocks, equivalent to the pre-shared secret length when multiplied by 16
* \param[in] serverHelloRnd ServerHello.random (concatenated with values already contained in A71CH)
* \param[in] serverHelloRndLen The length of serverHelloRnd passed as an argument
* \param[in,out] masterSecret IN: caller passes a buffer of at least 48 byte; OUT: contains the calculated master Secret, TLS 1.2 mandates this to be 48 byte exact
*
* \retval ::SW_OK Successfull execution
*/
U16 A71_EcdhPskDeriveMasterSecret(SST_Index_t indexKp, const U8 *publicKey, U16 publicKeyLen,
    SST_Index_t index, U8 nBlock, const U8 *serverHelloRnd, U16 serverHelloRndLen, U8 *masterSecret)
{
    U8 isOk;
    U16 rv;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U16 minBufLen = AX_TLS_PSK_MASTER_SECRET_LEN;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((publicKey == NULL) || (serverHelloRnd == NULL) || (masterSecret == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    if ( nBlock > A71CH_SYM_KEY_COMBINED_MAX)
    {
        return ERR_API_ERROR;
    }

    if ( (serverHelloRndLen + publicKeyLen) > A71CH_MAX_CMD_PAYLOAD_SIZE)
    {
        return ERR_API_ERROR;
    }

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_MS_ECDH_PSK_ECC_KEYPAIR;
    pApdu->p1    = indexKp;
    pApdu->p2    = (nBlock << 4) + index;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    smApduAppendCmdData(pApdu, publicKey, publicKeyLen);
    smApduAppendCmdData(pApdu, serverHelloRnd, serverHelloRndLen);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        rv = smGetSw(pApdu, &isOk);
        if (isOk)
        {
            rv = smApduGetResponseBody(pApdu, masterSecret, &minBufLen);
            if (rv == SW_OK)
            {
                if (minBufLen != AX_TLS_PSK_MASTER_SECRET_LEN)
                {
                    rv = ERR_WRONG_RESPONSE;
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* Calculates the HMAC on \p data using SHA256 as Hash Function according to [RFC2104].
  The secret is stored in the SYM key store. It can be either 16, 32, 48 or 64 byte long.
  The Most Significant part of the secret resides in the storage location with the lowest index.
  The subsequent parts reside in the next storage locations. The nBlock parameter is equal to the length
  of the secret divided by 16.
  A secret with length 64 can only start at Index 0 of the SYM key store: a secret can not be stored wrapped around in the
  SYM key store.
* \param[in] index Index of the SYM key store containing the MSB part of the pre-shared secret
* \param[in] nBlock Amount of blocks, equivalent to the pre-shared secret length when multiplied by 16
* \param[in] data Data buffer for which the HMAC-SHA256 must be calculated
* \param[in] dataLen The length of data passed as argument
* \param[in,out] hmac IN: caller passes a buffer of at least 32 byte;
     OUT: contains the calculated hmac
* \param[in,out] hmacLen IN: length of the hmac buffer passed;
     OUT: because SHA256 is used this is 32 byte exact
*
* \retval ::SW_OK Successfull execution
*/
U16 A71_GetHmacSha256(SST_Index_t index, U8 nBlock, const U8 *data, U16 dataLen, U8 *hmac, U16 *hmacLen)
{
    U8 isOk = 0;
    U16 rv;
    // U8 payload = 0x00;
    U16 maxChunk = 0;
    U16 remainingData = dataLen;
    U16 toSend = 0;
    U16 dataOffset = 0;

    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((data == NULL) || (hmac == NULL) || (hmacLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71CH_INS_HMAC_SHA256_SYM_KEY;
    pApdu->p1    = (nBlock << 4) + index;
    pApdu->p2    = P2_HMAC_ONE_SHOT;

    AllocateAPDUBuffer(pApdu);

    // Assumes SCP03 is used
    maxChunk = A71CH_HMAC_SHA256_MAX_DATA_CHUNK;

    // Depending on dataLen we can do a one-shot HMAC or need to split up across multiple APDU's
    if (dataLen <= maxChunk)
    {
        SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);
        smApduAppendCmdData(pApdu, data, dataLen);

        rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
        if (rv == SMCOM_OK)
        {
            rv = smGetSw(pApdu, &isOk);
            if (isOk)
            {
                rv = smApduGetResponseBody(pApdu, hmac, hmacLen);
                if (rv == SW_OK)
                {
                    if (32 != *hmacLen)
                    {
                        rv = ERR_WRONG_RESPONSE;
                    }
                }
            }
        }
    }
    else
    {
        // Split up in multiple transactions ...
        // rv = ERR_NOT_IMPLEMENTED;
        // goto LBL_LEAVE_A71_GetHmacSha256;

        // Send out first chunk (HMAC_SHA256_Init)
        pApdu->p2    = P2_HMAC_INIT;
        SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);
        toSend = maxChunk;
        remainingData -= toSend;
        smApduAppendCmdData(pApdu, data, toSend);
        dataOffset += toSend;

        rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
        if (rv == SMCOM_OK)
        {
            if (rv == SMCOM_OK)
            {
                // No response data expected
                rv = CheckNoResponseData(pApdu);
                if (rv != SW_OK) { goto LBL_LEAVE_A71_GetHmacSha256; }
            }
        }

        while (remainingData > maxChunk)
        {
            // Send out 'middle' chunks (HMAC_SHA256_Update)
            pApdu->p2    = P2_HMAC_UPDATE;
            SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);
            toSend = maxChunk;
            remainingData -= toSend;
            smApduAppendCmdData(pApdu, &data[dataOffset], toSend);
            dataOffset += toSend;

            rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
            if (rv == SMCOM_OK)
            {
                if (rv == SMCOM_OK)
                {
                    // No response data expected
                    rv = CheckNoResponseData(pApdu);
                    if (rv != SW_OK) { goto LBL_LEAVE_A71_GetHmacSha256; }
                }
            }
        }

        // Always close with HMAC_SHA256_Final
        pApdu->p2    = P2_HMAC_FINAL;
        SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);
        toSend = remainingData;
        // remainingData -= toSend;
        // dataOffset += toSend;
        smApduAppendCmdData(pApdu, &data[dataOffset], toSend);

        rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
        {
            rv = smGetSw(pApdu, &isOk);
            if (isOk)
            {
                rv = smApduGetResponseBody(pApdu, hmac, hmacLen);
                if (rv == SW_OK)
                {
                    if (32 != *hmacLen)
                    {
                        rv = ERR_WRONG_RESPONSE;
                    }
                }
            }
        }
    }

LBL_LEAVE_A71_GetHmacSha256:
    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* Initialise multistep HMACSHA256.
* @param[in] index Index of the SYM key store containing the MSB part of the pre-shared secret
* @param[in] nBlock Amount of blocks, equivalent to the pre-shared secret length when multiplied by 16
* @retval ::SW_OK Upon successful execution
*/
U16 A71_HmacSha256Init(SST_Index_t index, U8 nBlock)
{
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *)&apdu;
    U16 rv;

    pApdu->cla = AX_CLA;
    pApdu->ins = A71CH_INS_HMAC_SHA256_SYM_KEY;
    pApdu->p1 = (nBlock << 4) + index;
    pApdu->p2 = P2_HMAC_INIT;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        // No response data expected
        rv = CheckNoResponseData(pApdu);
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* Update the data for calulating HMACSHA256 value (in multistep).
* @param[in] index Index of the SYM key store containing the MSB part of the pre-shared secret
* @param[in] nBlock Amount of blocks, equivalent to the pre-shared secret length when multiplied by 16
* @param[in] data    Data buffer for which the HMACSHA256 must be calculated
* @param[in] dataLen The length of data passed as argument
* @retval ::SW_OK Upon successful execution
*/
U16 A71_HmacSha256Update(SST_Index_t index, U8 nBlock, U8 *data, U16 dataLen)
{
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *)&apdu;
    U16 rv = 0;
    U16 maxChunk = A71CH_HMAC_SHA256_MAX_DATA_CHUNK;
    U16 remainingData = dataLen;
    U16 toSend = 0;
    U16 dataSent = 0;

#ifndef A71_IGNORE_PARAM_CHECK
    if (data == NULL) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla = AX_CLA;
    pApdu->ins = A71CH_INS_HMAC_SHA256_SYM_KEY;
    pApdu->p1 = (nBlock << 4) + index;
    pApdu->p2 = P2_HMAC_UPDATE;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    if (dataLen == 0) {
        rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
        if (rv == SMCOM_OK)
        {
            // No response data expected
            rv = CheckNoResponseData(pApdu);
            if (rv != SW_OK) { goto LBL_LEAVE_A71_Sha256Update; }
        }
    }
    else {
        while (remainingData != 0)
        {
            toSend = (remainingData > maxChunk) ? maxChunk : remainingData;
            smApduAppendCmdData(pApdu, (data + dataSent), toSend);

            rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
            if (rv == SMCOM_OK)
            {
                // No response data expected
                rv = CheckNoResponseData(pApdu);
                if (rv != SW_OK) { goto LBL_LEAVE_A71_Sha256Update; }
            }

            dataSent += toSend;
            remainingData -= toSend;
        }
    }


LBL_LEAVE_A71_Sha256Update:
    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* calulating HMACSHA256 value (in multistep).
* @param[in] index Index of the SYM key store containing the MSB part of the pre-shared secret
* @param[in] nBlock Amount of blocks, equivalent to the pre-shared secret length when multiplied by 16
* @param[in,out] hmac    IN: caller passes a buffer of at least 32 byte;
OUT: contains the calculated HMACSHA256
* @param[in,out] hmacLen IN: length of the sha buffer passed;
OUT: because HMACSHA256 is used this is 32 byte exact
* @retval ::SW_OK Upon successful execution
*/
U16 A71_HmacSha256Final(SST_Index_t index, U8 nBlock, U8 *hmac, U16 *hmacLen)
{
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *)&apdu;
    U16 rv;
    U8 isOk = 0;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((hmac == NULL) || (hmacLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla = AX_CLA;
    pApdu->ins = A71CH_INS_HMAC_SHA256_SYM_KEY;
    pApdu->p1 = (nBlock << 4) + index;
    pApdu->p2 = P2_HMAC_FINAL;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        rv = smGetSw(pApdu, &isOk);
        if (isOk)
        {
            rv = smApduGetResponseBody(pApdu, hmac, hmacLen);
            if (rv == SW_OK)
            {
                if (32 != *hmacLen)
                {
                    rv = ERR_WRONG_RESPONSE;
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}
