/**
 * @file ex_config.c
 * @author NXP Semiconductors
 * @version 1.0
 * @par License
 *
 * Copyright 2017 NXP
 * SPDX-License-Identifier: Apache-2.0
 *
 * @par Description
 * Example invocation of configure key specific functionality of the A71CH
 */

#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 "axHostCrypto.h"
#include "tstHostCrypto.h"
#include "HostCryptoAPI.h"
#include "nxLog_hostLib.h"
static U8 exSetConfigKey(U8 initMode);
static U8 exSstPubEnc(U8 initMode);
static U8 exSstPubEraseAfterInjectLock(void);
static U8 exSstKeyPairEnc(U8 initMode);

static U8 configKeyModuleLock[16];  //!< Configuration Key for Module, acting as transport key (index ::A71CH_CFG_KEY_IDX_MODULE_LOCK)
static U8 configKeyPrivateKey[16];  //!< Configuration Key for Private Key encryption (index ::A71CH_CFG_KEY_IDX_PRIVATE_KEYS)
static U8 configKeyPublicKey[16];   //!< Configuration Key for Public Key encryption (index ::A71CH_CFG_KEY_IDX_PUBLIC_KEYS)

#define EX_CONFIG_DEMO_LOCK_UNLOCK
#define EX_CONFIG_ALSO_USE_SCP03

/**
 * Demonstrate storage and usage of config keys:
 * - ::exSetConfigKey
 * - ::exSstPubEnc
 * - ::exSstKeyPairEnc
 * - ::exSstPubEraseAfterInjectLock
 *
 */
U8 exConfig()
{
    U8 result = 1;
    int i = 0;
    LOG_I( "-----------Start exConfig()------------");

    DEV_ClearChannelState();

    // Choose a (unique) pattern for each config key
    for (i=0; i<16; i++) {
        configKeyModuleLock[i] = (U8)(i ^ A71CH_CFG_KEY_IDX_MODULE_LOCK);
        configKeyPrivateKey[i] = (U8)(i ^ A71CH_CFG_KEY_IDX_PRIVATE_KEYS);
        configKeyPublicKey[i] = (U8)(i ^ A71CH_CFG_KEY_IDX_PUBLIC_KEYS);
    }

    // No channel encryption
    // ---------------------
    // - First set the config keys
    result &= exSetConfigKey(INIT_MODE_RESET);

    // - Set wrapped Public keys
    result &= exSstPubEnc(INIT_MODE_NO_RESET);
    // - Set wrapped key pairs (only private key is wrapped)
    result &= exSstKeyPairEnc(INIT_MODE_NO_RESET);
    // - Check on erasing Public keys after Module Inject Lock has been set
    result &= exSstPubEraseAfterInjectLock();

#ifdef EX_CONFIG_ALSO_USE_SCP03
    // Using channel encryption
    // ------------------------
    // - First set the config keysSym keys
    result &= exSetConfigKey(INIT_MODE_RESET_DO_SCP03);

    // - Set wrapped Public keys
    result &= exSstPubEnc(INIT_MODE_NO_RESET);

    // - Set wrapped key pairs (only private key is wrapped)
    result &= exSstKeyPairEnc(INIT_MODE_NO_RESET);

    // - Check on erasing Public keys after Module Inject Lock has been set
    result &= exSstPubEraseAfterInjectLock();
#endif

    // overall result
    LOG_I( "-----------End exConfig(), result = %s------------", ((result == 1)? "OK": "FAILED"));

    return result;
}

/**
 * Demonstrate
 * - setting config keys
 * - use of transport key (config key at index ::A71CH_CFG_KEY_IDX_MODULE_LOCK) to lock/unlock A71CH
 *
 * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
 */
static U8 exSetConfigKey(U8 initMode)
{
    U8 result = 1;
    U16 err;

    U8 uid[A71CH_MODULE_UNIQUE_ID_LEN] = {0};
    U16 uidLen = sizeof(uid);

    U8 challenge[A71CH_MODULE_UNLOCK_CHALLENGE_LEN] = {0};
    U16 challengeLen = sizeof(challenge);

    U8 unlockCode[A71CH_MODULE_UNLOCK_CHALLENGE_LEN] = {0};
    S32 hcRet = 0;

    U8 indexCfgKey = A71CH_CFG_KEY_IDX_MODULE_LOCK;

    LOG_I("-----------Start exSetConfigKey(%s)------------", getInitModeAsString(initMode));
    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= a71chInitModule(initMode);

    // Store all configure keys (value is stored in variables with module scope)
    indexCfgKey = A71CH_CFG_KEY_IDX_MODULE_LOCK;
    LOG_I("A71_SetConfigKey(0x%02x)", indexCfgKey);
    err = A71_SetConfigKey((SST_Index_t)indexCfgKey, configKeyModuleLock, sizeof(configKeyModuleLock));
    result &= AX_CHECK_SW(err, SW_OK, "err");
    axPrintByteArray("configKeyModuleLock", configKeyModuleLock, sizeof(configKeyModuleLock), AX_COLON_32);

    indexCfgKey = A71CH_CFG_KEY_IDX_PRIVATE_KEYS;
    LOG_I("A71_SetConfigKey(0x%02x)", indexCfgKey);
    err = A71_SetConfigKey((SST_Index_t)indexCfgKey, configKeyPrivateKey, sizeof(configKeyPrivateKey));
    result &= AX_CHECK_SW(err, SW_OK, "err");
    axPrintByteArray("configKeyPrivateKey", configKeyPrivateKey, sizeof(configKeyPrivateKey), AX_COLON_32);

    indexCfgKey = A71CH_CFG_KEY_IDX_PUBLIC_KEYS;
    LOG_I("A71_SetConfigKey(0x%02x)", indexCfgKey);
    err = A71_SetConfigKey((SST_Index_t)indexCfgKey, configKeyPublicKey, sizeof(configKeyPublicKey));
    result &= AX_CHECK_SW(err, SW_OK, "err");
    axPrintByteArray("configKeyPublicKey", configKeyPublicKey, sizeof(configKeyPublicKey), AX_COLON_32);

#ifdef EX_CONFIG_DEMO_LOCK_UNLOCK
    // Lock device for transport
    LOG_I("A71_LockModule()");
    err = A71_LockModule();
    result &= AX_CHECK_SW(err, SW_OK, "err");

    LOG_I("A71_GetUniqueID().");
    err = A71_GetUniqueID(uid, &uidLen);
    result &= AX_CHECK_SW(err, SW_OK, "err");
    axPrintByteArray("uid", uid, uidLen, AX_COLON_32);

    LOG_I("A71_GetUnlockChallenge().");
    err = A71_GetUnlockChallenge(challenge, &challengeLen);
    result &= AX_CHECK_SW(err, SW_OK, "err");
    axPrintByteArray("challenge", challenge, challengeLen, AX_COLON_32);

    // Decrypt challenge
    hcRet = HOST_AES_ECB_DECRYPT(unlockCode, challenge, configKeyModuleLock, sizeof(configKeyModuleLock));
    if (hcRet != HOST_CRYPTO_OK)
    {
    	LOG_E("HOST_AES_ECB_DECRYPT: failed.");
        result = 0;
    }

    LOG_I("A71_UnlockModule()");
    err = A71_UnlockModule(unlockCode, 16);
    result &= AX_CHECK_SW(err, SW_OK, "err");
#endif

    LOG_I( "-----------End exSetConfigKey(%s), result = %s------------", getInitModeAsString(initMode), ((result == 1)? "OK": "FAILED"));

    return result;
}

/**
 * Demonstrate
 * - setting a wrapped public key
 * - demonstrate key can be used through verify operation
 *
 * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
 */
static U8 exSstPubEnc(U8 initMode)
{
    U8 result = 1;
    U16 err;
    int i;

    ECCCurve_t eccCurve = ECCCurve_NIST_P256;

    EC_KEY *eccKeyCA[A71CH_PUBLIC_KEY_MAX] = {0};
    eccKeyComponents_t eccKcCA[A71CH_PUBLIC_KEY_MAX] = {0};

    U8 fetchedPubKey[65];
    U16 fetchedPubKeyLen = sizeof(fetchedPubKey);

    // const U16 expectedPubKeyLen = 65;
    const U16 expectedPrivKeyLen = 32;

    LOG_I("-----------Start exSstPubEnc(%s)------------", getInitModeAsString(initMode));

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= a71chInitModule(initMode);

    // Start by creating, inserting and checking keys
    for (i=0; i<A71CH_PUBLIC_KEY_MAX; i++)
    {
        U8 wrappedKey[64+8];
        U16 wrappedKeyLen = sizeof(wrappedKey);
        eccKeyCA[i] = NULL;
        err = HOSTCRYPTO_GenerateEccKey(eccCurve, &eccKeyCA[i]);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        err = HOSTCRYPTO_GetPublicKey(eccKeyCA[i], eccKcCA[i].pub, &(eccKcCA[i].pubLen), (64 << 1)+1);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        err = HOSTCRYPTO_GetPrivateKey(eccKeyCA[i], eccKcCA[i].priv, &(eccKcCA[i].privLen), 64);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        eccKcCA[i].bits = expectedPrivKeyLen << 3;
        eccKcCA[i].curve = eccCurve;

        // Wrap public key (strip first character before wrapping) on host
        LOG_I("HOSTCRYPTO_AesWrapKeyRFC3394(0x%02X)", (SST_Index_t)i);
        err = HOSTCRYPTO_AesWrapKeyRFC3394(configKeyPublicKey, sizeof(configKeyPublicKey),
            wrappedKey, &wrappedKeyLen, &(eccKcCA[i].pub[1]), eccKcCA[i].pubLen - 1);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        axPrintByteArray("wrappedKey", wrappedKey, wrappedKeyLen, AX_COLON_32);

        LOG_I( "A71_SetEccPublicKey(0x%02X)", (SST_Index_t)i);
        err = A71_SetEccPublicKey ((SST_Index_t) i, wrappedKey, wrappedKeyLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");
    }

    // Read out and verify public key
    for (i=0; i<A71CH_PUBLIC_KEY_MAX; i++)
    {
    	LOG_I( "A71_GetEccPublicKey(0x%02X)", (SST_Index_t)i);
        fetchedPubKeyLen = sizeof(fetchedPubKey);
        err = A71_GetEccPublicKey ((SST_Index_t) i, fetchedPubKey, &fetchedPubKeyLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        // Compare with reference value
        result &= AX_COMPARE_BYTE_ARRAY("eccKcCA[i].pub", eccKcCA[i].pub, eccKcCA[i].pubLen,
            "fetchedPubKey", fetchedPubKey, fetchedPubKeyLen, AX_COLON_32);
    }

    for (i=0; i<A71CH_PUBLIC_KEY_MAX; i++)
    {
        HOSTCRYPTO_FreeEccKey(&eccKeyCA[i]);
    }

    LOG_I( "-----------End exSstPubEnc(%s), result = %s------------", getInitModeAsString(initMode),
        ((result == 1)? "OK": "FAILED"));

    return result;
}

/**
 * Demonstrate
 * - Once the module Inject Lock has been set, its only possible to erase a public key
 *   through a challenge response protocol
 *
 */
static U8 exSstPubEraseAfterInjectLock()
{
    U8 result = 1;
    U16 err;
    int i;

    // ECCCurve_t eccCurve = ECCCurve_NIST_P256;

    // EC_KEY *eccKeyCA[A71CH_PUBLIC_KEY_MAX] = {0};
    // eccKeyComponents_t eccKcCA[A71CH_PUBLIC_KEY_MAX] = {0};

    U8 fetchedPubKey[65];
    U16 fetchedPubKeyLen = sizeof(fetchedPubKey);

    // const U16 expectedPubKeyLen = 65;
    // const U16 expectedPrivKeyLen = 32;

    LOG_I("-----------Start exSstPubEraseAfterInjectLock()------------");

    // Check whether ErasePublicKey - without challenge/response - fails
    for (i=0; i<A71CH_PUBLIC_KEY_MAX; i++)
    {
    	LOG_I( "A71_EraseEccPublicKey(0x%02X)", (SST_Index_t)i);
        err = A71_EraseEccPublicKey((SST_Index_t) i);
        result &= AX_CHECK_SW(err, SW_WRONG_DATA, "err");
    }

    // Confirm reading out public key is still possible
    for (i=0; i<A71CH_PUBLIC_KEY_MAX; i++)
    {
    	LOG_I("A71_GetEccPublicKey (index=0x%02X)", i);
        fetchedPubKeyLen = sizeof(fetchedPubKey);
        err = A71_GetEccPublicKey ((SST_Index_t)i, fetchedPubKey, &fetchedPubKeyLen);
        result &= AX_CHECK_SW(err, SW_OK, "Failed to retrieve Public Ecc Key");
    }

    // Do a ErasePublicKey with challenge response
    for (i=0; i<A71CH_PUBLIC_KEY_MAX; i++)
    {
    	LOG_I( "A71_EraseEccPublicKeyWithChallenge(0x%02X)", (SST_Index_t)i);
        err = A71_EraseEccPublicKeyWithChallenge((SST_Index_t) i, configKeyPublicKey, sizeof(configKeyPublicKey));
        result &= AX_CHECK_SW(err, SW_OK, "err");
    }

    // Check whether reading out (erased) public key now fails.
    for (i=0; i<A71CH_PUBLIC_KEY_MAX; i++)
    {
    	LOG_I("A71_GetEccPublicKey (index=0x%02X)", i);
        fetchedPubKeyLen = sizeof(fetchedPubKey);
        err = A71_GetEccPublicKey ((SST_Index_t)i, fetchedPubKey, &fetchedPubKeyLen);
        result &= AX_CHECK_SW(err, SW_CONDITIONS_NOT_SATISFIED, "Get Public Ecc Key was supposed to fail");
    }

    LOG_I( "-----------End exSstPubEraseAfterInjectLock(), result = %s------------",
        ((result == 1)? "OK": "FAILED"));

    return result;
}

/**
 * Demonstrate
 * - setting (encrypted)/getting/erasing of key pairs
 * - demonstrate key can be used through sign operations
 * - demonstrate a plain key pair can not be inserted once 'inject lock' has been enabled
 * - demonstrate a keywrapped key pair can still be inserted
 * - demonstrate generating a key pair is conditional on a correct challenge/response
 *
 * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
 * @param[in] appletVersion See #SmCommState_t::appletVersion
 */
static U8 exSstKeyPairEnc(U8 initMode)
{
    U8 result = 1;
    U16 err;
    int i;
    HLSE_RET_CODE retcode;

    ECCCurve_t eccCurve = ECCCurve_NIST_P256;

    EC_KEY *eccKeyTls[A71CH_KEY_PAIR_MAX] = {0};
    eccKeyComponents_t eccKcTls[A71CH_KEY_PAIR_MAX] = {0};

    EC_KEY *eccKeyAlt = NULL;
    eccKeyComponents_t eccKcAlt;

    U8 fetchedPubKey[65];
    U16 fetchedPubKeyLen = sizeof(fetchedPubKey);

    U8 hashSha256[32];
    U16 hashSha256Len = sizeof(hashSha256);

    U8 signature[128];
    U16 signatureLen = sizeof(signature);
    HLSE_MECHANISM_INFO mechInfo;

    // const U16 expectedPubKeyLen = 65;
    const U16 expectedPrivKeyLen = 32;

    U8 wrappedPrivKey[32+8];
    U16 wrappedPrivKeyLen = sizeof(wrappedPrivKey);

    SST_Index_t kpIndex;

    LOG_I("-----------Start exSstKeyPairEnc(%s)------------", getInitModeAsString(initMode));

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= a71chInitModule(initMode);

    // Start by creating, inserting and checking keys
    for (i=0; i<A71CH_KEY_PAIR_MAX; i++)
    {
        eccKeyTls[i] = NULL;
        err = HOSTCRYPTO_GenerateEccKey(eccCurve, &eccKeyTls[i]);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        err = HOSTCRYPTO_GetPublicKey(eccKeyTls[i], eccKcTls[i].pub, &(eccKcTls[i].pubLen), (64 << 1)+1);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        err = HOSTCRYPTO_GetPrivateKey(eccKeyTls[i], eccKcTls[i].priv, &(eccKcTls[i].privLen), 64);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        eccKcTls[i].bits = expectedPrivKeyLen << 3;
        eccKcTls[i].curve = eccCurve;

        // Wrap private key on host
        wrappedPrivKeyLen = sizeof(wrappedPrivKey);
        LOG_I("HOSTCRYPTO_AesWrapKeyRFC3394(0x%02X)", (SST_Index_t)i);
        err = HOSTCRYPTO_AesWrapKeyRFC3394(configKeyPrivateKey, sizeof(configKeyPrivateKey),
            wrappedPrivKey, &wrappedPrivKeyLen, eccKcTls[i].priv, eccKcTls[i].privLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");
        axPrintByteArray("wrappedPrivKey", wrappedPrivKey, wrappedPrivKeyLen, AX_COLON_32);

        LOG_I( "A71_SetEccKeyPair(0x%02X)", (SST_Index_t)i);
        err = A71_SetEccKeyPair((SST_Index_t) i, eccKcTls[i].pub, eccKcTls[i].pubLen,
            wrappedPrivKey, wrappedPrivKeyLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");
    }

    // Read out and verify public key
    for (i=0; i<A71CH_KEY_PAIR_MAX; i++)
    {
    	LOG_I( "A71_GetPublicKeyEccKeyPair (0x%02X)", (SST_Index_t)i);
        fetchedPubKeyLen = sizeof(fetchedPubKey);
        err = A71_GetPublicKeyEccKeyPair  ((SST_Index_t) i, fetchedPubKey, &fetchedPubKeyLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        // Compare with reference value
        result &= AX_COMPARE_BYTE_ARRAY("eccKcTls[i].pub", eccKcTls[i].pub, eccKcTls[i].pubLen,
            "fetchedPubKey", fetchedPubKey, fetchedPubKeyLen, AX_COLON_32);
    }

    // Create alternative key
    err = HOSTCRYPTO_GenerateEccKey(eccCurve, &eccKeyAlt);
    result &= AX_CHECK_SW(err, SW_OK, "err");

    err = HOSTCRYPTO_GetPublicKey(eccKeyAlt, eccKcAlt.pub, &(eccKcAlt.pubLen), (64 << 1)+1);
    result &= AX_CHECK_SW(err, SW_OK, "err");

    err = HOSTCRYPTO_GetPrivateKey(eccKeyAlt, eccKcAlt.priv, &(eccKcAlt.privLen), 64);
    result &= AX_CHECK_SW(err, SW_OK, "err");
    eccKcAlt.bits = expectedPrivKeyLen << 3;
    eccKcAlt.curve = eccCurve;
    HOSTCRYPTO_FreeEccKey(&eccKeyAlt);

    // Fill up the hash with some reference data
    hashSha256Len = sizeof(hashSha256);
    for (i=0; i<hashSha256Len; i++) { hashSha256[i] = (U8)i; }

    // Sign a hash of correct length on the A71CH and do the verification on the Host
    for (i=0; i<A71CH_KEY_PAIR_MAX; i++)
    {
        signatureLen = sizeof(signature);
        LOG_I("A71_EccSign(0x%02X)", (SST_Index_t)i);
        err = A71_EccSign((SST_Index_t)i, hashSha256, hashSha256Len, signature, &signatureLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        // Verify ... on opposite platform
        LOG_I("(Host)ECDSA_verify API with eccKeyTls[i] (verify signature created on A71CH).");
        memset(&mechInfo, 0, sizeof(mechInfo));
        mechInfo.mechanism = HLSE_ECDSA_VERIFY;
        retcode = HLCRYPT_Verify(&mechInfo,(U8 *)eccKeyTls[i],0,hashSha256,hashSha256Len,signature,signatureLen);
        if (retcode == HLSE_SW_OK)
        {
        	LOG_I("Verification OK for eccKeyTls[i].");
        }
        else
        {
        	LOG_E("Return value: %d, Verification Not OK for eccKeyTls[i]. Test Failed!", retcode);
            result &= 0;
            break;
        }
    }

    // Erase the keypair at index 0 & verify the value is no longer readable
    // ** Erase **
    kpIndex = A71CH_KEY_PAIR_0;
    LOG_I("A71_EraseEccKeyPair(index=0x%02X)", kpIndex);
    err = A71_EraseEccKeyPair(kpIndex);
    result &= AX_CHECK_SW(err, SW_OK, "err");
    // ** Check whether erase was effective **
    LOG_I("A71_GetPublicKeyEccKeyPair (index=0x%02X)", kpIndex);
    fetchedPubKeyLen = sizeof(fetchedPubKey);
    err = A71_GetPublicKeyEccKeyPair ((SST_Index_t)kpIndex, fetchedPubKey, &fetchedPubKeyLen);
    result &= AX_CHECK_SW(err, SW_CONDITIONS_NOT_SATISFIED, "Get Public Ecc Key was supposed to fail");

    // Now disable the plain insertion/reading out of Symmetric keys & Keypairs
    LOG_I("A71_InjectLock()");
    err = A71_InjectLock();
    result &= AX_CHECK_SW(err, SW_OK, "err");
    assert(result);

    // Check whether the plain inject has been disabled (check only first key pair)
    LOG_I( "A71_SetEccKeyPair(0x%02x)", kpIndex);
    err = A71_SetEccKeyPair((SST_Index_t)kpIndex, eccKcAlt.pub, eccKcAlt.pubLen, eccKcAlt.priv, eccKcAlt.privLen);
    result &= AX_CHECK_SW(err, SW_COMMAND_NOT_ALLOWED, "Expected to fail, frozen credential cannot be overwritten");

    // Put back the original (reference) value in the first slot, now first wrap private key on host
    wrappedPrivKeyLen = sizeof(wrappedPrivKey);
    LOG_I("HOSTCRYPTO_AesWrapKeyRFC3394(0x%02X)", (SST_Index_t)kpIndex);
    err = HOSTCRYPTO_AesWrapKeyRFC3394(configKeyPrivateKey, sizeof(configKeyPrivateKey),
        wrappedPrivKey, &wrappedPrivKeyLen, eccKcTls[kpIndex].priv, eccKcTls[kpIndex].privLen);
    result &= AX_CHECK_SW(err, SW_OK, "err");
    axPrintByteArray("wrappedPrivKey", wrappedPrivKey, wrappedPrivKeyLen, AX_COLON_32);

    LOG_I( "A71_SetEccKeyPair(0x%02X)", (SST_Index_t)kpIndex);
    err = A71_SetEccKeyPair((SST_Index_t) kpIndex, eccKcTls[kpIndex].pub, eccKcTls[kpIndex].pubLen,
        wrappedPrivKey, wrappedPrivKeyLen);
    result &= AX_CHECK_SW(err, SW_OK, "err");

    // Check all keys are still fine by doing a sign/verify operation
    for (i=0; i<A71CH_KEY_PAIR_MAX; i++)
    {
        signatureLen = sizeof(signature);
        LOG_I("A71_EccSign(0x%02X)", (SST_Index_t)i);
        err = A71_EccSign((SST_Index_t)i, hashSha256, hashSha256Len, signature, &signatureLen);
        result &= AX_CHECK_SW(err, SW_OK, "err");

        // Verify ... on opposite platform
        LOG_I("(Host)ECDSA_verify API with eccKeyTls[i] (verify signature created on A71CH).");
        memset(&mechInfo, 0, sizeof(mechInfo));
        mechInfo.mechanism = HLSE_ECDSA_VERIFY;
        retcode = HLCRYPT_Verify(&mechInfo,(U8 *)eccKeyTls[i],0,hashSha256,hashSha256Len,signature,signatureLen);
        if (retcode == HLSE_SW_OK)
        {
            LOG_I("Verification OK for eccKeyTls[i].");
        }
        else
        {
            LOG_E("Return value: %d, Verification Not OK for eccKeyTls[i]. Test Failed!", retcode);
            result &= 0;
            break;
        }
    }

    // Check whether the plain inject has been disabled (for all key pair)
    for (kpIndex=0; kpIndex<A71CH_KEY_PAIR_MAX; kpIndex++)
    {
        LOG_I( "A71_SetEccKeyPair(0x%02X)", (SST_Index_t)kpIndex);
        err = A71_SetEccKeyPair((SST_Index_t) kpIndex, eccKcTls[kpIndex].pub, eccKcTls[kpIndex].pubLen,
            eccKcTls[kpIndex].priv, eccKcTls[kpIndex].privLen);
        result &= AX_CHECK_SW(err, SW_COMMAND_NOT_ALLOWED, "err");
    }

    // Check whether GenerateKeyPair - without challenge/response - fails
    for (kpIndex=0; kpIndex<A71CH_KEY_PAIR_MAX; kpIndex++)
    {
        LOG_I( "A71_GenerateEccKeyPair(0x%02X)", (SST_Index_t)kpIndex);
        err = A71_GenerateEccKeyPair((SST_Index_t) kpIndex);
        result &= AX_CHECK_SW(err, SW_COMMAND_NOT_ALLOWED, "err");
    }

    // Do a GenerateKeyPair with challenge response
    for (kpIndex=0; kpIndex<A71CH_KEY_PAIR_MAX; kpIndex++)
    {
        LOG_I( "A71_GenerateEccKeyPairWithChallenge(0x%02X)", (SST_Index_t)kpIndex);
        err = A71_GenerateEccKeyPairWithChallenge((SST_Index_t) kpIndex, configKeyPrivateKey, sizeof(configKeyPrivateKey));
        result &= AX_CHECK_SW(err, SW_OK, "err");
    }

    //!< \todo Extend example program to check whether there's a new keypair inside A71CH

    // Check whether EraseKeyPair - without challenge/response - fails
    for (kpIndex=0; kpIndex<A71CH_KEY_PAIR_MAX; kpIndex++)
    {
        LOG_I( "A71_EraseEccKeyPair(0x%02X)", (SST_Index_t)kpIndex);
        err = A71_EraseEccKeyPair((SST_Index_t) kpIndex);
        result &= AX_CHECK_SW(err, SW_WRONG_DATA, "err");
    }

    // Do a EraseKeyPair with challenge response
    for (kpIndex=0; kpIndex<A71CH_KEY_PAIR_MAX; kpIndex++)
    {
        LOG_I( "A71_EraseEccKeyPairWithChallenge(0x%02X)", (SST_Index_t)kpIndex);
        err = A71_EraseEccKeyPairWithChallenge((SST_Index_t) kpIndex, configKeyPrivateKey, sizeof(configKeyPrivateKey));
        result &= AX_CHECK_SW(err, SW_OK, "err");
    }

    // Check whether reading out public key from erased keypairs now fails.
    for (kpIndex=0; kpIndex<A71CH_KEY_PAIR_MAX; kpIndex++)
    {
        LOG_I("A71_GetPublicKeyEccKeyPair (index=0x%02X)", kpIndex);
        fetchedPubKeyLen = sizeof(fetchedPubKey);
        err = A71_GetPublicKeyEccKeyPair ((SST_Index_t)kpIndex, fetchedPubKey, &fetchedPubKeyLen);
        result &= AX_CHECK_SW(err, SW_CONDITIONS_NOT_SATISFIED, "Get Public Ecc Key was supposed to fail");
    }

    for (i=0; i<A71CH_KEY_PAIR_MAX; i++)
    {
        HOSTCRYPTO_FreeEccKey(&eccKeyTls[i]);
    }

    LOG_I( "-----------End exSstKeyPairEnc(%s), result = %s------------", getInitModeAsString(initMode),
        ((result == 1)? "OK": "FAILED"));

    return result;
}
