/*
* @author NXP Semiconductors
* @version 1.0
* @par License
*
* Copyright 2016,2020 NXP
* SPDX-License-Identifier: Apache-2.0
*
* @par History
* 1.0   2016-aug-29 : Initial version
*
*/
/**
* @file a71ch_module.c
* @par Description
* Wrap module centric APDU functionality of the A71CH
*/
#include <stdio.h>
#include <string.h>

#include "scp.h"
#include "a71ch_api.h"
#include "sm_apdu.h"
#include "sm_errors.h"
#include "ax_common_private.h"

#if defined(SSS_USE_FTR_FILE)
#include "fsl_sss_ftr.h"
#else
#include "fsl_sss_ftr_default.h"
#endif

/// @cond

#define NX_LOG_ENABLE_HOSTLIB_DEBUG 1
#include <nxLog_hostLib.h>

static U16 A71_GetChallengeGeneric(U8 challengeType, U8 *challenge, U16 *challengeLen)
{
    U16 rv = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U8 isOk;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((challenge == NULL) || (challengeLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_GET_MODULE;
    pApdu->p1    = challengeType;
    pApdu->p2    = P2_CHALLENGE;

    if (*challengeLen < A71CH_MODULE_UNLOCK_CHALLENGE_LEN)
    {
        return ERR_BUF_TOO_SMALL;
    }

    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, challenge, challengeLen);
            if (*challengeLen != A71CH_MODULE_UNLOCK_CHALLENGE_LEN)
            {
                rv = ERR_WRONG_RESPONSE;
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

static U16 A71_GetRandomGeneric(U8 *random, U8 randomLen, U8 mode)
{
    U8 isOk = 0;
    U16 rv;
    U16 randomBufLen = randomLen;

    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;

#ifndef A71_IGNORE_PARAM_CHECK
    if (random == NULL) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71CH_INS_MODULE_GET_RANDOM;
    pApdu->p1    = mode;
    pApdu->p2    = (mode == P1_RANDOM_PLAIN) ? randomLen : 0x00;

    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, random, &randomBufLen);
            if (rv == SW_OK)
            {
                if (randomBufLen != randomLen)
                {
                    rv = ERR_WRONG_RESPONSE;
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

/// @endcond

/**
* Get credential info from Module (in raw format)
* @param[in,out] map
* @param[in,out] mapLen
* @retval ::SW_OK Upon successful execution
*/
U16 A71_GetCredentialInfo(U8 *map, U16 *mapLen)
{
    U16 rv = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U8 isOk;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((map == NULL) || (mapLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_GET_MODULE;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_CREDENTIAL_MAP;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, 0);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        rv = smGetSw(pApdu, &isOk);
        if (isOk)
        {
            rv = smApduGetResponseBody(pApdu, map, mapLen);
        }
        else
        {
            *mapLen = 0;
        }
    }
    else
    {
        *mapLen = 0;
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* Get info on Module
* @param[out] selectResponse     Encodes applet revision and whether Debug Mode is available
* @param[out] debugOn            Equals 0x01 when the Debug Mode is available
* @param[out] restrictedKpIdx    Either the index of the restricted keypair or ::A71CH_NO_RESTRICTED_KP
* @param[out] transportLockState The value retieved is one of ::A71CH_TRANSPORT_LOCK_STATE_LOCKED,
*   A71CH_TRANSPORT_LOCK_STATE_UNLOCKED or A71CH_TRANSPORT_LOCK_STATE_ALLOW_LOCK
* @param[out] scpState           The value retrieved is on of ::A71CH_SCP_MANDATORY, ::A71CH_SCP_NOT_SET_UP
*   or ::A71CH_SCP_KEYS_SET
* @param[out] injectLockState The value retrieved is one of ::A71CH_INJECT_LOCK_STATE_LOCKED or ::A71CH_INJECT_LOCK_STATE_UNLOCKED
* @param[out] gpStorageSize   Total storage size (in byte) of the General Purpose data store
* @retval ::SW_OK Upon successful execution
*/
U16 A71_GetModuleInfo(U16 *selectResponse, U8 *debugOn, U8 *restrictedKpIdx, U8 *transportLockState, U8 *scpState, U8 *injectLockState, U16 *gpStorageSize)
{
    U16 rv = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U8 isOk;
    U8 data[64];
    U16 dataLen = sizeof(data);

#ifndef A71_IGNORE_PARAM_CHECK
    if ((selectResponse == NULL) || (debugOn == NULL) || (restrictedKpIdx == NULL) || (transportLockState == NULL) ||
        (scpState == NULL) || (injectLockState == NULL) || (gpStorageSize == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_GET_MODULE;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_APPLET_INFO;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    *selectResponse = 0;
    *debugOn = 0;
    *restrictedKpIdx = 0;
    *transportLockState = 0;
    *injectLockState = 0;
    *gpStorageSize = 0;

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        rv = smGetSw(pApdu, &isOk);
        if (isOk)
        {
            rv = smApduGetResponseBody(pApdu, data, &dataLen);
            if (dataLen == AX_MODULE_INFO_RESPONSE_LEN)
            {
                *selectResponse = (data[0] << 8) + data[1];
                *debugOn = *selectResponse & 0x01;
                *restrictedKpIdx = (data[2] & 0xF0) >> 4;
                *transportLockState = data[2] & 0x0F;
                *scpState = (data[3] & 0xF0) >> 4;
                *injectLockState = data[3] & 0x0F;
                *gpStorageSize = (data[4] << 8) + data[5];
            }
            else
            {
                rv = ERR_WRONG_RESPONSE;
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}


/**
* Get Unique Identifier from the Secure Module
* @param[in,out] uid IN: buffer to contain uid; OUT: uid retrieved from Secure Module
* @param[in,out] uidLen IN: Size of buffer provided (at least ::A71CH_MODULE_UNIQUE_ID_LEN byte);
    OUT: length of retrieved unique identifier (expected to be ::A71CH_MODULE_UNIQUE_ID_LEN byte)
* @retval ::SW_OK Upon successful execution
* @retval ::ERR_WRONG_RESPONSE In case an identifier with a length different from ::A71CH_MODULE_UNIQUE_ID_LEN was retrieved
*/
U16 A71_GetUniqueID(U8 *uid, U16 *uidLen)
{
    U16 rv = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U8 isOk;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((uid == NULL) || (uidLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_GET_MODULE;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_UNIQUE_ID;

    if (*uidLen < A71CH_MODULE_UNIQUE_ID_LEN)
    {
        return ERR_BUF_TOO_SMALL;
    }

    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, uid, uidLen);
            if (*uidLen != A71CH_MODULE_UNIQUE_ID_LEN)
            {
                rv = ERR_WRONG_RESPONSE;
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
 * Get cert uid from the Secure Module. The cert uid is a subset of the Secure Module Unique Identifier
 * @param[in,out] certUid IN: buffer to contain cert uid; OUT: cert uid retrieved from Secure Module
 * @param[in,out] certUidLen IN: Size of buffer provided (at least ::A71CH_MODULE_CERT_UID_LEN byte);
 * OUT: length of retrieved unique identifier (expected to be ::A71CH_MODULE_CERT_UID_LEN byte)
 *
 * @retval ::SW_OK Upon successful execution
 * @retval ::ERR_WRONG_RESPONSE In case the Secure Module Unique Identifier (i.e. the base uid) did not have the expected length
 */
U16 A71_GetCertUid(U8 *certUid, U16 *certUidLen)
{
    U16 rv = 0;
    U8 uid[A71CH_MODULE_UNIQUE_ID_LEN] = {0};
    U16 uidLen = A71CH_MODULE_UNIQUE_ID_LEN;
    int idx = 0;

    if (*certUidLen < A71CH_MODULE_CERT_UID_LEN)
    {
        return ERR_BUF_TOO_SMALL;
    }

    rv = A71_GetUniqueID(uid, &uidLen);
    if (rv == SMCOM_OK)
    {
        idx = 0;
        certUid[idx++] = uid[A71CH_UID_IC_TYPE_OFFSET];
        certUid[idx++] = uid[A71CH_UID_IC_TYPE_OFFSET + 1];
        certUid[idx++] = uid[A71CH_UID_IC_FABRICATION_DATA_OFFSET];
        certUid[idx++] = uid[A71CH_UID_IC_FABRICATION_DATA_OFFSET + 1];
        certUid[idx++] = uid[A71CH_UID_IC_SERIAL_NR_OFFSET];
        certUid[idx++] = uid[A71CH_UID_IC_SERIAL_NR_OFFSET + 1];
        certUid[idx++] = uid[A71CH_UID_IC_SERIAL_NR_OFFSET + 2];
        certUid[idx++] = uid[A71CH_UID_IC_BATCH_ID_OFFSET];
        certUid[idx++] = uid[A71CH_UID_IC_BATCH_ID_OFFSET + 1];
        certUid[idx++] = uid[A71CH_UID_IC_BATCH_ID_OFFSET + 2];
        *certUidLen = A71CH_MODULE_CERT_UID_LEN;
    }
    else
    {
        *certUidLen = 0;
    }

    return rv;
}

/**
* Get Unlock challenge from the Secure Module
* @param[in,out] challenge IN: buffer to contain challenge; OUT: challenge retrieved from Secure Module
* @param[in,out] challengeLen IN: Size of buffer provided (at least ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN byte);
    OUT: length of retrieved unique identifier (must be ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN byte)
* @retval ::SW_OK Upon successful execution
* @retval ::ERR_WRONG_RESPONSE In case an identifier with a length different from ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN was retrieved
*/
U16 A71_GetUnlockChallenge(U8 *challenge, U16 *challengeLen)
{
    return A71_GetChallengeGeneric(P1_MODULE_UNLOCK_CHALLENGE, challenge, challengeLen);
}

/**
* Get Unlock challenge for a Keypair
* @param[in,out] challenge IN: buffer to contain challenge; OUT: challenge retrieved from Secure Module
* @param[in,out] challengeLen IN: Size of buffer provided (at least ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN byte);
    OUT: length of retrieved unique identifier (must be ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN byte)
* @retval ::SW_OK Upon successful execution
* @retval ::ERR_WRONG_RESPONSE In case an identifier with a length different from ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN was retrieved
*/
U16 A71_GetKeyPairChallenge(U8 *challenge, U16 *challengeLen)
{
    return A71_GetChallengeGeneric(P1_KEYPAIR_CHALLENGE, challenge, challengeLen);
}
/**
* Get Unlock challenge for a Public Key
* @param[in,out] challenge IN: buffer to contain challenge; OUT: challenge retrieved from Secure Module
* @param[in,out] challengeLen IN: Size of buffer provided (at least ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN byte);
    OUT: length of retrieved unique identifier (must be ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN byte)
* @retval ::SW_OK Upon successful execution
* @retval ::ERR_WRONG_RESPONSE In case an identifier with a length different from ::A71CH_MODULE_UNLOCK_CHALLENGE_LEN was retrieved
*/
U16 A71_GetPublicKeyChallenge(U8 *challenge, U16 *challengeLen)
{
    return A71_GetChallengeGeneric(P1_PUBLIC_KEY_CHALLENGE, challenge, challengeLen);
}

/**
* Retrieves a random byte array of size randomLen from the Secure Module.
* The maximum amount of data that can be retrieved depends on
* whether an authenticated channel (SCP03) has been set up.
* In case SCP03 has been set up, this (worst-case) maximum is ::A71CH_SCP03_MAX_PAYLOAD_SIZE
* @param[in,out] random  IN: buffer to contain random value (at least of size randomLen);
                         OUT: retrieved random data
* @param[in] randomLen Amount of byte to retrieve
* @retval ::SW_OK Upon successful execution
*/
U16 A71_GetRandom(U8 *random, U8 randomLen)
{
    return A71_GetRandomGeneric(random, randomLen, P1_RANDOM_PLAIN);
}

/**
* Updates a 32 byte random value inside the A71CH and returns this value to the caller.
* \post A71CH is in a state it will accept ::A71_PskDeriveMasterSecret or ::A71_EcdhPskDeriveMasterSecret as an API call.
*
* @param[in,out] clientHello  IN: buffer to contain random value (at least of size randomLen);
                              OUT: retrieved random data
* @param[in] clientHelloLen Amount of byte to retrieve (must be equal to ::AX_TLS_PSK_HELLO_RANDOM_LEN)
* @retval ::SW_OK Upon successful execution
*/
U16 A71_CreateClientHelloRandom(U8 *clientHello, U8 clientHelloLen)
{
    if (clientHelloLen != AX_TLS_PSK_HELLO_RANDOM_LEN)
    {
        return ERR_API_ERROR;
    }
    return A71_GetRandomGeneric(clientHello, clientHelloLen, P1_RANDOM_CLIENT_HELLO);
}

/**
 * Get the index of the restricted key pair (\p idx) together with the number of modifiable blocks
 * (\p nBlocks) in the locked GP storage area that is associated with the restricted key pair.
 * Detailed info on block offset and block length is contained in the \p blockInfo byte array.
 * Per block 2 bytes indicate the offset into GP storage and two bytes indicate the length of
 * the modifiable block.
 *
 * @param[out] idx Index of restricted key pair. ::A71CH_NO_RESTRICTED_KP in case there is no restricted key pair
 * @param[out] nBlocks Number of modifiable blocks
 * @param[in,out] blockInfo IN: Storage to contain blockInfo; OUT: Raw info on block offset and block lenght per block.
 * @param[in,out] blockInfoLen IN: Size of blockInfo (in byte); OUT: effective size of blockInfo
 * @retval ::SW_OK Upon successful execution
 */
U16 A71_GetRestrictedKeyPairInfo(U8 *idx, U16 *nBlocks, U8 *blockInfo, U16 *blockInfoLen)
{
    U16 rv = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U8 isOk;
    U8 localBuf[255];
    U16 localBufLen = sizeof(localBuf);

#ifndef A71_IGNORE_PARAM_CHECK
    if ((idx == NULL) || (nBlocks == NULL) || (blockInfo == NULL) || (blockInfoLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    *idx = A71CH_NO_RESTRICTED_KP;
    *nBlocks = 0;

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_GET_MODULE;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_RESTRICTED_INFO;

    // Ensure there's at least space to contain Offset|Lenght description of one block.
    if (*blockInfoLen < 4)
    {
        return ERR_BUF_TOO_SMALL;
    }

    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, localBuf, &localBufLen);
            if (rv == SW_OK)
            {
                if (localBufLen == 0)
                {
                    // There is no restricted keypair and associated modifiable block(s)
                    *blockInfoLen = 0;
                }
                else if (localBufLen == 2)
                {
                    // Workaround for Applet 1.3 Issue
                    if ( (localBuf[0] == 0xFF) && (localBuf[1] == 0x00) )
                    {
                        // There is no restricted keypair and associated modifiable block(s)
                        *blockInfoLen = 0;
                    }
                    else
                    {
                        *blockInfoLen = 0;
                        rv = ERR_WRONG_RESPONSE;
                    }
                }
                else if (localBufLen > 2)
                {
                    if (*blockInfoLen < (localBufLen-2) )
                    {
                        *blockInfoLen = 0;
                        rv = ERR_BUF_TOO_SMALL;
                    }
                    else
                    {
                        *idx = localBuf[0];
                        *nBlocks = localBuf[1];
                        *blockInfoLen = localBufLen - 2;
                        memcpy(blockInfo, &localBuf[2], *blockInfoLen);
                    }
                }
                else
                {
                    *blockInfoLen = 0;
                    rv = ERR_WRONG_RESPONSE;
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* Calculates the SHA256 value of the data provided as input.
* @param[in] data    Data buffer for which the SHA256 must be calculated
* @param[in] dataLen The length of data passed as argument
* @param[in,out] sha    IN: caller passes a buffer of at least 32 byte;
                        OUT: contains the calculated SHA256
* @param[in,out] shaLen IN: length of the sha buffer passed;
                        OUT: because SHA256 is used this is 32 byte exact
* @retval ::SW_OK Upon successful execution
*/
U16 A71_GetSha256(U8 *data, U16 dataLen, U8 *sha, U16 *shaLen)
{
    U8 isOk = 0;
    U16 rv;
    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) || (sha == NULL) || (shaLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71CH_INS_MODULE_GET_SHA256;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_SHA256_ONE_SHOT;

    AllocateAPDUBuffer(pApdu);

    maxChunk = A71CH_SHA256_MAX_DATA_CHUNK;

    // Depending on dataLen we can do a one-shot SHA256 or need to split up across multiple APDU's
    if (dataLen <= maxChunk)
    {
        SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

        if (dataLen != 0){
            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, sha, shaLen);
                if (rv == SW_OK)
                {
                    if (32 != *shaLen)
                    {
                        rv = ERR_WRONG_RESPONSE;
                    }
                }
            }
        }
    }
    else
    {
        // Split up in multiple transactions ...
        // Send out first chunk (SHA256_Init)
        pApdu->p2    = P2_SHA256_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_GetSha256; }
            }
        }

        while (remainingData > maxChunk)
        {
            // Send out 'middle' chunks (SHA256_Update)
            pApdu->p2    = P2_SHA256_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_GetSha256; }
                }
            }
        }

        // Always close with SHA256_Final
        pApdu->p2    = P2_SHA256_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, sha, shaLen);
                if (rv == SW_OK)
                {
                    if (32 != *shaLen)
                    {
                        rv = ERR_WRONG_RESPONSE;
                    }
                }
            }
        }
    }

LBL_LEAVE_A71_GetSha256:
    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* Initialise multistep SHA256.
* @retval ::SW_OK Upon successful execution
*/
U16 A71_Sha256Init(void)
{
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U16 rv;

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71CH_INS_MODULE_GET_SHA256;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_SHA256_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 SHA256 value (in multistep).
* @param[in] data    Data buffer for which the SHA256 must be calculated
* @param[in] dataLen The length of data passed as argument
* @retval ::SW_OK Upon successful execution
*/
U16 A71_Sha256Update(U8 *data, U16 dataLen)
{
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *)&apdu;
    U16 rv = 0;
    U16 maxChunk = A71CH_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_MODULE_GET_SHA256;
    pApdu->p1 = 0x00;
    pApdu->p2 = P2_SHA256_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 SHA256 value (in multistep).
* @param[in,out] sha    IN: caller passes a buffer of at least 32 byte;
OUT: contains the calculated SHA256
* @param[in,out] shaLen IN: length of the sha buffer passed;
OUT: because SHA256 is used this is 32 byte exact
* @retval ::SW_OK Upon successful execution
*/
U16 A71_Sha256Final(U8 *sha, U16 *shaLen)
{
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *)&apdu;
    U16 rv;
    U8 isOk = 0;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((sha == NULL) || (shaLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla = AX_CLA;
    pApdu->ins = A71CH_INS_MODULE_GET_SHA256;
    pApdu->p1 = 0x00;
    pApdu->p2 = P2_SHA256_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, sha, shaLen);
            if (rv == SW_OK)
            {
                if (32 != *shaLen)
                {
                    rv = ERR_WRONG_RESPONSE;
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}


/**
* This function disables - at device level - the ability to
  - Set symmetric keys without prior wrapping
  - Erase symmetric keys
  - Set ECC key pairs (private key part) without prior wrapping
  - Set ECC public key without prior wrapping

* @retval ::SW_OK Upon successful execution
*/
U16 A71_InjectLock()
{
    U16 rv;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71CH_INS_SET_MODULE;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_SMF_LOCK_PLAIN_INJECTION;

    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;
}

/**
* This function locks the module (typically to protect the module during transport to production
 facilities). When the A71CH is locked the functionality is reduced to the following subset:
    - ::A71_GetUniqueID
    - ::A71_GetUnlockChallenge
    - ::A71_UnlockModule
    - ::A71_GetModuleInfo

* @retval ::SW_OK Upon successful execution
*/
U16 A71_LockModule()
{
    U16 rv;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71CH_INS_SET_MODULE;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_SMF_LOCK_MODULE;

    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;
}

/**
* This function unlocks the module provided the correct code is provided as input argument.
The A71CH can only be unlocked once: if the device is already unlocked, the device cannot be locked
or unlocked again (it will remain unlocked).

The unlock code is calculated as follows:
    - Request a challenge from A71CH using ::A71_GetUnlockChallenge.
    - Decrypt the challenge in ECB mode using the appropriate configuration key value (the same as stored at index ::A71CH_CFG_KEY_IDX_MODULE_LOCK).
    - The decrypted value is the unlock \p code
* @param[in] code Value of unlock code
* @param[in] codeLen Length of unlock code (must be 16)
* @retval ::SW_OK Upon successful execution
*/
U16 A71_UnlockModule(U8 *code, U16 codeLen)
{
    U16 rv;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;

#ifndef A71_IGNORE_PARAM_CHECK
    if (code == NULL) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71CH_INS_SET_MODULE;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_SMF_UNLOCK_MODULE;

    if (codeLen != 16)
    {
        return ERR_API_ERROR;
    }

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    smApduAppendCmdData(pApdu, code, codeLen);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        // No response data expected
        rv = CheckNoResponseData(pApdu);
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
 * Sets the label that is used when calling ::A71_EcdhPskDeriveMasterSecret or
 * ::A71_PskDeriveMasterSecret. Calling this function is optional. By default the label
 * used by the A71CH is \p 'master secret' (no quotes) as applicable for TLS 1.2.
 * The maximum size of the label that can be set is 24 byte.
 * @param[in] label Value to be stored and used as 'label' in TLS 1.2 protocol
 * @param[in] labelLen Length of label (less than or equal to ::A71CH_TLS_MAX_LABEL)
 * @retval ::SW_OK Upon successful execution
 */
U16 A71_SetTlsLabel(const U8* label, U16 labelLen)
{
    U16 rv;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;

#ifndef A71_IGNORE_PARAM_CHECK
    if (label == NULL) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71CH_INS_SET_MODULE;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_SMF_LABEL;

    if (labelLen > A71CH_TLS_MAX_LABEL)
    {
        return ERR_API_ERROR;
    }

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    smApduAppendCmdData(pApdu, label, labelLen);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        // No response data expected
        rv = CheckNoResponseData(pApdu);
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* Verifies whether \p pSignature is the signature of \p pHash
* using \p pKeyData as the verifying public key.
*
* As opposed to function ::A71_EccVerify the public key value is passed as
* an argument to the A71CH.
*
* @param[in] pKeyData Public key passed as byte array in ANSI X9.62 uncompressed format
* @param[in] keyDataLen Length of public key passed as argument
* @param[in] pHash Pointer to the provided hash (or any other bytestring).
* @param[in] hashLen Length of the provided hash.
* @param[in] pSignature Pointer to the provided signature.
* @param[in] signatureLen Length of the provided signature.
* @param[out] pResult Pointer to the computed result of the verification.
  Points to a value of 0x01 in case of successful verification
* @retval ::SW_OK Upon successful execution
*/
U16 A71_EccVerifyWithKey(const U8 *pKeyData, U16 keyDataLen, const U8 *pHash, U16 hashLen, const U8 *pSignature, U16 signatureLen, U8 *pResult)
{
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U16 rv;
    U8 isOk = 0;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((pKeyData == NULL) || (pHash == NULL) || (pSignature == NULL) || (pResult == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    if (keyDataLen != A71CH_PUB_KEY_LEN) { return ERR_API_ERROR; }
    if (hashLen != AX_SHA256_LEN) { return ERR_API_ERROR; }

    *pResult = 0;

    pApdu->cla   = A71CH_CLA;
    pApdu->ins   = A71CH_INS_VERIFY_SIG_ECC_PUBLIC_KEY;
    pApdu->p1    = 0x00;
    pApdu->p2    = P2_PUBKEY_PRESENT;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    smApduAppendCmdData(pApdu, pHash, hashLen);
    smApduAppendCmdData(pApdu, pSignature, signatureLen);
    smApduAppendCmdData(pApdu, pKeyData, keyDataLen);

    rv = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (rv == SMCOM_OK)
    {
        U8 result = AX_VERIFY_FAILURE;
        U16 resultLen = 1;
        rv = smGetSw(pApdu, &isOk);
        if (isOk)
        {
            rv = smApduGetResponseBody(pApdu, &result, &resultLen);
            if ((rv != SW_OK) || (resultLen != 1) || ((result != AX_VERIFY_SUCCESS) && (result != AX_VERIFY_FAILURE)))
            {
                rv = ERR_WRONG_RESPONSE;
            }
            else
            {
                if (result == AX_VERIFY_SUCCESS)
                {
                    *pResult = 1;
                }
                else
                {
                    *pResult = 0;
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}
