/**
 * @file ex_hlse_cert.c
 * @author NXP Semiconductors
 * @version 1.0
 * @par License
 *
 * Copyright 2018 NXP
 * SPDX-License-Identifier: Apache-2.0
 *
 * @par Description
 * Example using Certificate objects
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sm_printf.h"
#include "HLSEAPI.h"
#include "sm_types.h"
#include "sm_apdu.h"
#include "tst_sm_util.h"
#include "a71ch_util.h"

#include "HLSEAPI.h"
#include "tst_a71ch_util.h"
#include "tst_hlse_a71ch_util.h"

static U8 exDataObjUsage(U8 initMode);
static U8 exMixedCertsAndDataObj(U8 initMode, U16 nBaseSize, U16 nObj);

static U8 exCertUsageBasic(U8 initMode);
static U8 exCertUsageEnlarge(U8 initMode);
static U8 exCertUsageGpTableLengthUnknown(U8 initMode);

static U8 exCertUsageReadOnly(U8 initMode);
static U8 exCertEnumerate(void);
static U8 exCertGetAttr(void);
static U8 exCertSetAttr(void);

// internal utilities
static HLSE_RET_CODE patchCertificateInitialTL(U8 *clientCertDer, U16 clientCertDerLen);
static HLSE_RET_CODE getObject(HLSE_OBJECT_HANDLE handle, U8 *data, U16 *len);
static HLSE_RET_CODE setObject(HLSE_OBJECT_HANDLE handle, U8 *data, U16 len);

/**
 * Demonstrate usage of certificate objects
 */
U8 exHlseCert()
{
    U8 result = 1;
    PRINTF("\r\n-----------\r\nStart exHlseCert()\r\n------------\r\n");

    DEV_ClearChannelState();

    // Example of Data object usage
    result &= exDataObjUsage(INIT_MODE_RESET);

#if AX_EMBEDDED
    result &= exMixedCertsAndDataObj(INIT_MODE_RESET, 40 /* size */, 8 /* num of objects */);
#else
    result &= exMixedCertsAndDataObj(INIT_MODE_RESET, 300 /* size */, 8 /* num of objects */);
#endif

    // Example certificate usage with enhanced validations
    result &= exCertUsageBasic(INIT_MODE_RESET);

    // Example certificate usage enlarging and updating a certificate
    result &= exCertUsageEnlarge(INIT_MODE_RESET);

    // Example of Certificate creation / enumeration / Get / Set / Delete - when Read Only attribute used
    result &= exCertUsageReadOnly(INIT_MODE_RESET);

    // Example certificate usage when map contains indirect length (to be obtained from TLV of actual object)
    result &= exCertUsageGpTableLengthUnknown(INIT_MODE_RESET);

    // overall result
    PRINTF("\r\n-----------\r\nEnd exHlseCert(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}


/**
 * Demonstrate usage of certificate object:
 *
 * Simulate the following scenario and aim to verify it works correctly:
 *
 * - Create Certificate
 * - Read certificate data and verify correctness
 *      - Index ok
 *      - Value was correctly set
 * - Update Certificate contents
 * - Verify Certificate updated correctly
 * - Delete certificate
 * - Verify deletion
 *
 * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
 */
static U8 exCertUsageBasic(U8 initMode)
{
    U8 result = 1;
    HLSE_RET_CODE hlseRc;

    HLSE_OBJECT_HANDLE certHandles[5];
    U16 certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);

    HLSE_OBJECT_INDEX index = 0;
    HLSE_OBJECT_TYPE objType = HLSE_CERTIFICATE;

    // Cert for this test is 50 bytes which occupies 2 chunks of 32 bytes on the GP Storage
    U8 certData[50];

    HLSE_ATTRIBUTE attr[3];
    unsigned short templateSize = 3;

    U8 data[50];        // to hold data to update certificate

    memset(certHandles, 0x00, sizeof(certHandles));
    memset(certData, 0xAA, sizeof(certData));

    PRINTF("\r\n-----------\r\nStart exCertUsageBasic(%s)\r\n------------\r\n", getInitModeAsString(initMode));

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= hlse_a71chInitModule(initMode);
    assert(result);

    // start with clean GP table to avoid cached data from previous test
    hlseRc = Debug_ForceReadGPDataTable();
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    attr[0].type = HLSE_ATTR_OBJECT_TYPE;
    attr[0].value = &objType;
    attr[0].valueLen = sizeof(objType);
    attr[1].type = HLSE_ATTR_OBJECT_INDEX;
    attr[1].value = &index;
    attr[1].valueLen = sizeof(index);
    attr[2].type = HLSE_ATTR_OBJECT_VALUE;
    attr[2].value = certData;
    attr[2].valueLen = sizeof(certData);

    // Create certificate object index = 0
    PRINTF("\r\nHLSE_CreateObject() - Create certificate object...\r\n------------\r\n");
    hlseRc = HLSE_CreateObject(attr, templateSize, &certHandles[0]);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // assumption : correct slot in GP Table data was occupied
    // TODO: consider additional low level test for it

    // Now read certificate data and verify correctness
    // Find certificate where index=0

    // enumerate objects - we should have one certificate by now with index 0
    PRINTF("\r\nHLSE_EnumerateObjects()...\r\n");
    certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, certHandles, &certHandlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(certHandlesNum, 1, "err");

    // Get the attributes of the single certificate we have created
    // - Object Index
    // - Certificate data
    PRINTF("\r\nHLSE_GetObjectAttribute()...\r\n");
    {
        U32 certIndex = 0xFFFFFFFF;
        HLSE_ATTRIBUTE attrL;
        attrL.type = HLSE_ATTR_OBJECT_INDEX;
        attrL.value = &certIndex;
        attrL.valueLen = sizeof(certIndex);

        hlseRc = HLSE_GetObjectAttribute(certHandles[certHandlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        PRINTF("\tcert index = 0x%lx\r\n", certIndex);
        result &= AX_CHECK_U16((U16)certIndex, 0x00, "err");
    }

    PRINTF("Verify Certificate contents...\r\n");
    {
        U8 readCertData[50];

        HLSE_ATTRIBUTE attrL;
        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(certHandles[certHandlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("certOnA71CH", readCertData, sizeof(certData),
            "expected cert data", certData, sizeof(certData), AX_COLON_32);
    }

    PRINTF("Update Certificate contents...\r\n");
    {
        HLSE_ATTRIBUTE attrL;
        memset(data, 0xAB, sizeof(data));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = data;
        attrL.valueLen = sizeof(data);

        hlseRc = HLSE_SetObjectAttribute(certHandles[certHandlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }


    PRINTF("Verify Certificate Updated correctly...\r\n");
    {
        U8 readCertData[50];
        HLSE_ATTRIBUTE attrL;

        memset(readCertData, 0x00, sizeof(readCertData));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(certHandles[certHandlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("read data", readCertData, sizeof(certData),
            "expected cert data", data, sizeof(data), AX_COLON_32);
    }

    // Delete the certificate
    PRINTF("\r\nHLSE_EraseObject()...\r\n");
    hlseRc = HLSE_EraseObject(certHandles[certHandlesNum - 1]);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // Verify it was actually deleted
    // enumerate objects - we should have no certificates by now
    PRINTF("\r\nVerify object was erased...\r\n");
    certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, certHandles, &certHandlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(certHandlesNum, 0, "err");


    PRINTF("\r\n-----------\r\nEnd exCertUsageBasic(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}


/**
* Demonstrate usage of a data object:
*
* Simulate the following scenario and aim to verify it works correctly:
*
* - Create Data Object
* - Shows how to obtain the object GP offset
* - Read Data object and verify correctness
*      - Index ok
*      - Value was correctly set
* - Update Data Object contents
* - Verify Data Object updated correctly
*
* - Show direct update of partial block in Data Object
* - Show direct read of partial block in Data Object
* - Show direct Read / Write with offset that exceeds object boundaries is not allowed
* - Show direct Read / Write with length that exceeds object boundaries is not allowed
*
* - Delete Data Object
* - Verify deletion
*
* @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
*/
static U8 exDataObjUsage(U8 initMode)
{
    U8 result = 1;
    HLSE_RET_CODE hlseRc;

    HLSE_OBJECT_HANDLE handles[5];
    U16 handlesNum = sizeof(handles) / sizeof(HLSE_OBJECT_HANDLE);

    HLSE_OBJECT_INDEX index = 0;
    HLSE_OBJECT_TYPE objType = HLSE_DATA;

    // data for this test is 100 bytes which occupies 2 chunks of 32 bytes on the GP Storage
    U8 data[50];

    HLSE_ATTRIBUTE attr[3];
    unsigned short templateSize = 3;

    //U8 updateData[50];        // to hold data to update data object

    memset(handles, 0x00, sizeof(handles));
    memset(data, 0xAA, sizeof(data));

    PRINTF("\r\n-----------\r\nStart exDataObjUsage(%s)\r\n------------\r\n", getInitModeAsString(initMode));

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= hlse_a71chInitModule(initMode);
    assert(result);

    // start with clean GP table to avoid cached data from previous test
    hlseRc = Debug_ForceReadGPDataTable();
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    attr[0].type = HLSE_ATTR_OBJECT_TYPE;
    attr[0].value = &objType;
    attr[0].valueLen = sizeof(objType);
    attr[1].type = HLSE_ATTR_OBJECT_INDEX;
    attr[1].value = &index;
    attr[1].valueLen = sizeof(index);
    attr[2].type = HLSE_ATTR_OBJECT_VALUE;
    attr[2].value = data;
    attr[2].valueLen = sizeof(data);

    // Create data object index = 0
    PRINTF("\r\nHLSE_CreateObject() - Create Data object...\r\n------------\r\n");
    hlseRc = HLSE_CreateObject(attr, templateSize, &handles[0]);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // assumption : correct slot in GP Table data was occupied
    // TODO: consider additional low level test for it

    // Now read data object and verify correctness
    // Find data object where index=0

    // enumerate objects - we should have one certificate by now with index 0
    PRINTF("\r\nHLSE_EnumerateObjects()...\r\n");
    handlesNum = sizeof(handles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_DATA, handles, &handlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(handlesNum, 1, "err");

    // show how to get the object's GP offset
    PRINTF("\r\nGet object GP offset...\r\n");
    {
        U16 offset;
        HLSE_ATTRIBUTE attrL;
        attrL.type = HLSE_ATTR_OBJECT_OFFSET;
        attrL.value = &offset;
        attrL.valueLen = sizeof(offset);

        hlseRc = HLSE_GetObjectAttribute(handles[handlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        PRINTF("\tdata object offset = 0x%u\r\n", offset);
    }

    // make sure our data object is the one we previously created
    // Get the attributes of the single data object we have
    PRINTF("\r\nHLSE_GetObjectAttribute()...\r\n");
    {
        U32 dataIndex = 0xFFFFFFFF;
        HLSE_ATTRIBUTE attrL;
        attrL.type = HLSE_ATTR_OBJECT_INDEX;
        attrL.value = &dataIndex;
        attrL.valueLen = sizeof(dataIndex);

        hlseRc = HLSE_GetObjectAttribute(handles[handlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        PRINTF("\tdata object index = 0x%lx\r\n", dataIndex);
        result &= AX_CHECK_U16((U16)dataIndex, 0x00, "err");
    }

    PRINTF("Verify Data object contents...\r\n");
    {
        U8 readData[50];

        HLSE_ATTRIBUTE attrL;
        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readData;
        attrL.valueLen = sizeof(readData);

        hlseRc = HLSE_GetObjectAttribute(handles[handlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("dataOnA71CH", readData, sizeof(data),
            "expected data", data, sizeof(data), AX_COLON_32);
    }

    PRINTF("Update Data object contents...\r\n");
    {
        HLSE_ATTRIBUTE attrL;
        memset(data, 0xAB, sizeof(data));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = data;
        attrL.valueLen = sizeof(data);

        hlseRc = HLSE_SetObjectAttribute(handles[handlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }

    PRINTF("Verify Data object Updated correctly...\r\n");
    {
        U8 readData[50];
        HLSE_ATTRIBUTE attrL;

        memset(readData, 0x00, sizeof(readData));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readData;
        attrL.valueLen = sizeof(readData);

        hlseRc = HLSE_GetObjectAttribute(handles[handlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("read data", readData, sizeof(readData),
            "expected data", data, sizeof(data), AX_COLON_32);
    }

    PRINTF("Show usage of direct read / Update access to Data Object...\r\n");
    {
        HLSE_ATTRIBUTE attrL;
        HLSE_DIRECT_ACCESS_ATTRIBUTE_VALUE theValue;
        U8 buffer[50]; // a buffer to hold the read data
        U8 refBuffer2[50];
        memset(buffer, 0x00, sizeof(buffer));

        attrL.type = HLSE_ATTR_DIRECT_ACCESS_OBJECT_VALUE;

        PRINTF("    Verify Direct Read of Data Object...\r\n");
        theValue.offset = 0;
        theValue.bytes = 32;
        theValue.buffer = buffer;
        theValue.bufferLen = sizeof(buffer);

        attrL.value = &theValue;
        attrL.valueLen = sizeof(theValue);

        hlseRc = HLSE_GetObjectAttribute(handles[handlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("dataOnA71CH", buffer, theValue.bytes,
            "expected data", data, theValue.bytes, AX_COLON_32);

        // Now show usage of direct update to data object - update 10 bytes at offset 0 to 0x11
        memset(buffer, 0x11, 10);
        theValue.bytes = 10;
        theValue.buffer = buffer;

        hlseRc = HLSE_SetObjectAttribute(handles[handlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        PRINTF("    Verify Direct Update of Data Object...\r\n");
        memcpy(refBuffer2, buffer, 50);
        memset(buffer, 0x00, sizeof(buffer));

        theValue.bytes = 32;
        theValue.buffer = buffer;
        theValue.bufferLen = sizeof(buffer);

        hlseRc = HLSE_GetObjectAttribute(handles[handlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("dataOnA71CH", buffer, theValue.bytes,
            "expected data", refBuffer2, theValue.bytes, AX_COLON_32);

        PRINTF("    Test Direct Read / Write with offset that exceeds object boundaries...\r\n");
        {
            // Note : data object 0 is at offset 0 , size 50 bytes

            memset(buffer, 0x00, sizeof(buffer));

            theValue.offset = 100;
            theValue.bytes = 50;
            theValue.buffer = buffer;
            theValue.bufferLen = sizeof(buffer);

            // Read with offset exceeding object boundary - not allowed
            hlseRc = HLSE_GetObjectAttribute(handles[handlesNum - 1], &attrL);
            result &= AX_CHECK_SW(hlseRc, HLSE_ERR_MEMORY, "err");

            // Write with offset exceeding object boundary - not allowed
            hlseRc = HLSE_SetObjectAttribute(handles[handlesNum - 1], &attrL);
            result &= AX_CHECK_SW(hlseRc, HLSE_ERR_MEMORY, "err");
        }

        PRINTF("    Test Direct Read / Write with length that exceeds object boundaries...\r\n");
        {
            // Note : data object 0 is at offset 0 , size 50 bytes

            memset(buffer, 0x00, sizeof(buffer));

            theValue.offset = 30;
            theValue.bytes = 50;
            theValue.buffer = buffer;
            theValue.bufferLen = sizeof(buffer);

            // Read exceeding object boundary - not allowed
            hlseRc = HLSE_GetObjectAttribute(handles[handlesNum - 1], &attrL);
            result &= AX_CHECK_SW(hlseRc, HLSE_ERR_MEMORY, "err");

            // Write exceeding object boundary - not allowed
            hlseRc = HLSE_SetObjectAttribute(handles[handlesNum - 1], &attrL);
            result &= AX_CHECK_SW(hlseRc, HLSE_ERR_MEMORY, "err");
        }
    }


    // Delete the Data object
    PRINTF("\r\nHLSE_EraseObject()...\r\n");
    hlseRc = HLSE_EraseObject(handles[handlesNum - 1]);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // Verify it was actually deleted
    // enumerate objects - we should have no certificates by now
    PRINTF("\r\nVerify object was erased...\r\n");
    handlesNum = sizeof(handles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_DATA, handles, &handlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(handlesNum, 0, "err");

    PRINTF("\r\n-----------\r\nEnd exDataObjUsage(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}


#define N_ADV_CERT         255
#define MAX_ADV_CERT_SIZE  (4096 - 32)

#define LEN_SHORT_FORM_MAX 127
#define LEN_LONG_FORM_ONE_BYTE_MAX 255
#define LEN_LONG_FORM_TWO_BYTE_MAX 65536
#define ERR_GP_NO_CERT 0x2000

/**
* An Example to show usage of mixed certificates and data objects
*
* Scenario:
*   - Create certificates and data objects
*   - Read back the certificate and data objects
*       - verify objects exists
*       - verify object's length matches
*       - verify objects's data matches
*   - Delete a random number of objects
*   - Read back the remaining certificate and data objects
*       - verify objects exists
*       - verify object's length matches
*       - verify objects's data matches
*   - Update an objects with new data
*   - Read back the remaining certificate and data objects
*       - verify objects exists
*       - verify object's length matches
*       - verify objects's data matches
*   - Delete all objects
*
* @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
* @param[in] nBaseSize base size of Cert/Data object to create
* @param[in] nObj number of total objects to create
*/
static U8 exMixedCertsAndDataObj(U8 initMode, U16 nBaseSize, U16 nObj)
{
    U8 result = 1;
    HLSE_RET_CODE hlseRc;

    HLSE_OBJECT_HANDLE mixedHandles[N_ADV_CERT];        // to hold handles of objects created

    HLSE_OBJECT_INDEX index = 0;
    HLSE_OBJECT_TYPE objType = HLSE_CERTIFICATE;

    U8 *refData[N_ADV_CERT];
    U16 effectiveSize[N_ADV_CERT];

    U8 *refDataU[N_ADV_CERT];
    U16 effectiveSizeU[N_ADV_CERT];

    HLSE_ATTRIBUTE attr[3];
    unsigned short templateSize = 3;

    U8 data[MAX_ADV_CERT_SIZE];        // to hold data to read certificate

    U8 nObjCreated = 0;  // certs and data objects
    U8 nObjToDelete = 0;
    U8 handleIndDeleted[N_ADV_CERT];   // to hold array ind of handle deleted
    U8 handleAlreadySelected = 0;

    int i, j;

    PRINTF("\r\n-----------\r\nStart exMixedCertsAndDataObjUsage(%s)\r\n------------\r\n", getInitModeAsString(initMode));

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= hlse_a71chInitModule(initMode);
    assert(result);

    // start with clean GP table to avoid cached data from previous test
    hlseRc = Debug_ForceReadGPDataTable();
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    memset(mixedHandles, 0x00, sizeof(mixedHandles));
    memset(handleIndDeleted, 0x00, sizeof(handleIndDeleted));

    // Create reference arrays containing random values which could serve as certificates or data objects
    srand(0);
    for (i = 0; i < nObj; i++)
    {
        effectiveSize[i] = (U16)(nBaseSize - (i % 24));
        refData[i] = (U8 *)malloc(effectiveSize[i]);
        for (j = 0; j < effectiveSize[i]; j++)
        {
            refData[i][j] = (U8)rand();
        }
    }

    // Create reference arrays containing random values which could serve as certificates or data objects, for updating the objects later
    for (i = 0; i < nObj; i++)
    {
        effectiveSizeU[i] = (U16)(nBaseSize - (i % 24));
        refDataU[i] = (U8 *)malloc(effectiveSizeU[i]);
        for (j = 0; j < effectiveSizeU[i]; j++)
        {
            refDataU[i][j] = (U8)rand();
        }
    }

    // Since the reference data arrays can be used as certificate we have to patch it to make sure it begins with a TLV of the certificate size,
    // as this determines the certificate value returned when we retrieve it
    for (i = 0; i < nObj; i++)
    {
        hlseRc = patchCertificateInitialTL(refData[i], effectiveSize[i]);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "Failed to patch initial TL of certificate");

        hlseRc = patchCertificateInitialTL(refDataU[i], effectiveSizeU[i]);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "Failed to patch initial TL of certificate");
    }

    PRINTF("\r\n-----------\r\nStart intMixedCertsAndDataObjUsage()\r\n------------\r\n");

    for (i = 0; i < nObj; i++)
    {
        index = (HLSE_OBJECT_INDEX)i;

        // create mixed data objects and certficiates objects
        objType = (i % 2 == 0) ? HLSE_CERTIFICATE : HLSE_DATA;

        attr[0].type = HLSE_ATTR_OBJECT_TYPE;
        attr[0].value = &objType;
        attr[0].valueLen = sizeof(objType);
        attr[1].type = HLSE_ATTR_OBJECT_INDEX;
        attr[1].value = &index;
        attr[1].valueLen = sizeof(index);
        attr[2].type = HLSE_ATTR_OBJECT_VALUE;
        attr[2].value = refData[i];
        attr[2].valueLen = effectiveSize[i];

        // Create certificate object @ index
        PRINTF("\r\nHLSE_CreateObject(index=%lu, size=%d) - Create %s object...\r\n------------\r\n",
            index, attr[2].valueLen, (objType == HLSE_CERTIFICATE ? "Certificate" : "Data"));
        hlseRc = HLSE_CreateObject(attr, templateSize, &mixedHandles[i]);

        if ((hlseRc == HLSE_ERR_MEMORY) && (index > 4)) {
            // this is acceptable since we managed to create at least 5 certificates
            PRINTF("\r\nGp Memory filled up");
            break;
        }
        else if (hlseRc == HLSE_SW_OK)
        {
            nObjCreated++;
        }

        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }
    PRINTF("\r\nCreated %02d total objects ( mixed data and certificates objects )...", nObjCreated);

    PRINTF("\r\nNow read back certificates and data objects...");
    for (i = 0; i < nObjCreated; i++)
    {
        U16 dataLen = MAX_ADV_CERT_SIZE;
        U8 localScore = 1;

        hlseRc = getObject(mixedHandles[i], data, &dataLen);
        localScore &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // Does the length match?
        localScore &= AX_CHECK_U16(dataLen, effectiveSize[i], "dataLen");

        // Does the data match?
        localScore &= AX_COMPARE_BYTE_ARRAY("data", data, dataLen, "refData", refData[i], effectiveSize[i], AX_COLON_16);

        if (localScore != 1) { PRINTF("\r\nFailed to retrieve certificate at index %d (expected size=%d)\r\n", i, effectiveSize[i]); }

        result &= localScore;
    }

    // Delete a random number of objects
    do {
        nObjToDelete = (U8)(rand() % (nObjCreated / 2));
    } while (nObjToDelete == 0);

    PRINTF("\r\nAbout to delete %d objects...", nObjToDelete);
    for (i = 0; i < nObjToDelete; i++)
    {
        handleAlreadySelected = 0;
        // find an index to delete
        do {
            // index in mixedHandles array of handle to delete
            index = (U8)(rand() % nObjCreated);
            // verify this index was not already deleted
            if (handleIndDeleted[index] == 1) {
                // need to select another handle
                handleAlreadySelected = 1;
            }
            else {
                handleAlreadySelected = 0;
            }
        } while (handleAlreadySelected == 1);

        // set this index as a handle which was deleted
        handleIndDeleted[index] = 1;

        // Delete the object
        PRINTF("\r\nHLSE_EraseObject(),  handle=0x%lX...\r\n", mixedHandles[index]);
        hlseRc = HLSE_EraseObject(mixedHandles[index]);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }


    // Verify the remaining objects are still ok
    PRINTF("\r\nNow read back remaining certificates and data objects...\r\n");
    for (i = 0; i < nObjCreated; i++)
    {
        U16 dataLen = MAX_ADV_CERT_SIZE;
        U8 localScore = 1;

        // ignore this handle if was deleted
        if (handleIndDeleted[i] != 0)
        {
            // skip this deleted object;
            continue;
        }

        hlseRc = getObject(mixedHandles[i], data, &dataLen);
        localScore &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // Does the length match?
        localScore &= AX_CHECK_U16(dataLen, effectiveSize[i], "dataLen");

        // Does the certificate match?
        localScore &= AX_COMPARE_BYTE_ARRAY("data", data, dataLen, "refData", refData[i], effectiveSize[i], AX_COLON_16);

        if (localScore != 1) { PRINTF("\r\nFailed to retrieve certificate at index %d (expected size=%d)\r\n", i, effectiveSize[i]); }

        result &= localScore;
    }

    // Update remaining objects with the alternate reference data, and verify updated data succesfull
    PRINTF("\r\nNow update remaining certificates and data objects...\r\n");
    for (i = 0; i < nObjCreated; i++)
    {
        U16 dataLen;
        U8 localScore = 1;
        // ignore this handle if was deleted
        if (handleIndDeleted[i] != 0)
        {
            // skip this deleted object;
            continue;
        }


        // Set object with new data
        memcpy(data, refDataU[i], effectiveSizeU[i]);
        dataLen = effectiveSizeU[i];
        hlseRc = setObject(mixedHandles[i], data, dataLen);
        localScore &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // Get updated data
        memset(data, 0, sizeof(data));
        dataLen = MAX_ADV_CERT_SIZE;
        hlseRc = getObject(mixedHandles[i], data, &dataLen);
        localScore &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // Does the length match?
        localScore &= AX_CHECK_U16(dataLen, effectiveSizeU[i], "dataLen");

        // Does the data match?
        localScore &= AX_COMPARE_BYTE_ARRAY("data", data, dataLen, "refData", refDataU[i], effectiveSizeU[i], AX_COLON_16);


        if (localScore != 1) { PRINTF("\r\nFailed to retrieve certificate at index %d (expected size=%d)\r\n", i, effectiveSize[i]); }

        result &= localScore;
    }


    /*
    * Delete all objects
    */
    PRINTF("\r\nNow Delete all objects...\r\n");
    for (i = 0; i < nObjCreated; i++)
    {
        // ignore this handle if was deleted
        if (handleIndDeleted[i] != 0)
        {
            // skip this deleted object;
            continue;
        }

        // set this index as a handle which was deleted
        handleIndDeleted[i] = 1;

        // Delete the object
        PRINTF("\r\nHLSE_EraseObject(), handle=0x%lX...\r\n", mixedHandles[i]);
        hlseRc = HLSE_EraseObject(mixedHandles[i]);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }


    for (i = 0; i < nObjCreated; i++)
    {
        free(refData[i]);
        free(refDataU[i]);
    }

    PRINTF("\r\n-----------\r\nEnd exMixedCertsAndDataObjUsage(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}



/**
 * Demonstrate usage of certificate objects:
 *
 * Simulate the following scenario and aim to verify it works correctly:
 *
 * - Create certificates
 * - Verify cannot create additional certificate
 * - Verify allows to enlarge a certificate with size within allocated boundary
 * - Verify cannot enlarge beyond the allocated boundary
 * - Delete the certificate
 * - Recreate it with bigger size
 * - Verify last certificate created still exists
 *
 * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
 */
static U8 exCertUsageEnlarge(U8 initMode)
{
    U8 result = 1;
    HLSE_RET_CODE hlseRc;

    // num of certificates to try to create ( actually created depends on GP memory availability )
    U8 nCertsToCreate = 50;

    // Note at max of 254 objects could be stored in the Gp table
    // we allocate here space for one more in case we want to check that more that that is not possible
    HLSE_OBJECT_HANDLE certHandles[255 + 1];

    U8 nCertsCreated = 0;

    // to hold actual handles created
    //HLSE_OBJECT_HANDLE certHandle0;
    //HLSE_OBJECT_HANDLE certHandle1;
    HLSE_OBJECT_HANDLE certHandle2;
    HLSE_OBJECT_HANDLE certHandle3;
    //HLSE_OBJECT_HANDLE certHandle4;
    HLSE_OBJECT_HANDLE lastCertHandle;

    HLSE_OBJECT_INDEX index = 0;
    HLSE_OBJECT_TYPE objType = HLSE_CERTIFICATE;
    U8 indexCert;
    U16 certHandlesNum;

    // Cert for this test is 32 bytes which occupies 2 chunks of 32 bytes on the GP Storage
    U8 certData[50];

    HLSE_ATTRIBUTE attr[3];
    unsigned short templateSize = 3;

    U8 dataIn2Chunks[60];       // to hold data to update certificate - within 2 chunks boundary

    U8 dataIn3Chunks[90];       // to hold data to update certificate - within 3 chunks boundary

    memset(certHandles, 0x00, sizeof(certHandles));
    memset(certData, 0xAA, sizeof(certData));

    PRINTF("\r\n-----------\r\nStart exCertUsageEnlarge(%s)\r\n------------\r\n", getInitModeAsString(initMode));

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= hlse_a71chInitModule(initMode);
    assert(result);

    // start with clean GP table to avoid cached data from previous test
    hlseRc = Debug_ForceReadGPDataTable();
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    attr[0].type = HLSE_ATTR_OBJECT_TYPE;
    attr[0].value = &objType;
    attr[0].valueLen = sizeof(objType);
    attr[1].type = HLSE_ATTR_OBJECT_INDEX;
    attr[1].value = &index;
    attr[1].valueLen = sizeof(index);
    attr[2].type = HLSE_ATTR_OBJECT_VALUE;
    attr[2].value = certData;
    attr[2].valueLen = sizeof(certData);

    PRINTF("\r\nAbout to create up to  %02d certificates...", nCertsToCreate);
    for (indexCert = 0; indexCert < nCertsToCreate; indexCert++)
    {
        index = indexCert;
        memset(certData, (0xAA+index), sizeof(certData));

        PRINTF("\r\nHLSE_CreateObject() - Create certificate object(0x%02lx)", index);
        hlseRc = HLSE_CreateObject(attr, templateSize, &certHandles[indexCert]);

        if ((hlseRc != HLSE_SW_OK) && (indexCert > 4)) {
            // this is acceptable since we managed to create 5 certificates
            break;
        }
        else if (hlseRc == HLSE_SW_OK )
        {
            nCertsCreated++;
        }
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }
    PRINTF("\r\nCreated %02d certificates...", nCertsCreated);

    // save the handles as the values in the array might be changed . not reflecting the actual handles , after deletion
    //certHandle0 = certHandles[0];
    //certHandle1 = certHandles[1];
    certHandle2 = certHandles[2];
    certHandle3 = certHandles[3];
    //certHandle4 = certHandles[4];
    lastCertHandle = certHandles[nCertsCreated - 1];

    // Enlarge certificate at index=2 within boundary
    PRINTF("Try to Enlarge Certificate contents within 2 chunks...\r\n");
    {
        HLSE_ATTRIBUTE attrL;
        memset(dataIn2Chunks, 0xBB, sizeof(dataIn2Chunks));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = dataIn2Chunks;
        attrL.valueLen = sizeof(dataIn2Chunks);

        hlseRc = HLSE_SetObjectAttribute(certHandle2, &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }

    PRINTF("Verify Certificate Updated correctly...\r\n");
    {
        U8 readCertData[60];
        HLSE_ATTRIBUTE attrL;

        memset(readCertData, 0x00, sizeof(readCertData));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(certHandle2, &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("read data", readCertData, sizeof(readCertData),
            "expected cert data", dataIn2Chunks, sizeof(dataIn2Chunks), AX_COLON_32);
    }

    // Enlarge certificate at index=2, over the boundary - not allowed - need to delete it and recreate it
    PRINTF("Try to Enlarge Certificate with 3 chunks data over the allocated size - not allowed...\r\n");
    {
        HLSE_ATTRIBUTE attrL;
        memset(dataIn3Chunks, 0xCC, sizeof(dataIn3Chunks));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = dataIn3Chunks;
        attrL.valueLen = sizeof(dataIn3Chunks);

        hlseRc = HLSE_SetObjectAttribute(certHandle2, &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_ERR_MEMORY, "err");
    }

    PRINTF("Verify Certificate contents has not changed...\r\n");
    {
        U8 readCertData[60];
        HLSE_ATTRIBUTE attrL;

        memset(readCertData, 0x00, sizeof(readCertData));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(certHandle2, &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("read data", readCertData, sizeof(readCertData),
            "expected cert data", dataIn2Chunks, sizeof(dataIn2Chunks), AX_COLON_32);
    }

    // enumerate objects - we should have nCertsCreated objects
    memset(certHandles, 0, sizeof(certHandles));
    PRINTF("\r\nHLSE_EnumerateObjects()...\r\n");
    certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, certHandles, &certHandlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(certHandlesNum, nCertsCreated, "err");

    // Need to delete the object and recreate it
    PRINTF("\r\nHLSE_EraseObject()...\r\n");
    hlseRc = HLSE_EraseObject(certHandle2);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    nCertsCreated--;

    // enumerate objects - we should have nCertsCreated objects
    memset(certHandles, 0, sizeof(certHandles));
    PRINTF("\r\nHLSE_EnumerateObjects()...\r\n");
    certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, certHandles, &certHandlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(certHandlesNum, nCertsCreated, "err");
    //

    // recreate it - should now succeed
    index = 2;
    // set the reference data that in cert 3 that is expected not to change
    memset(dataIn2Chunks, (0xBB + index), sizeof(certData));
    {
        attr[0].type = HLSE_ATTR_OBJECT_TYPE;
        attr[0].value = &objType;
        attr[0].valueLen = sizeof(objType);
        attr[1].type = HLSE_ATTR_OBJECT_INDEX;
        attr[1].value = &index;
        attr[1].valueLen = sizeof(index);
        attr[2].type = HLSE_ATTR_OBJECT_VALUE;
        attr[2].value = dataIn2Chunks;
        attr[2].valueLen = sizeof(dataIn2Chunks);

        PRINTF("\r\nHLSE_CreateObject() - Create certificate object(0x%02lx)\r\n", index);
        hlseRc = HLSE_CreateObject(attr, templateSize, &certHandle2);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
        nCertsCreated++;
    }

    PRINTF("Verify Certificate Updated correctly...\r\n");
    {
        U8 readCertData[60];
        HLSE_ATTRIBUTE attrL;

        memset(readCertData, 0x00, sizeof(readCertData));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(certHandle2, &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("read data", readCertData, sizeof(readCertData),
            "expected cert data", dataIn2Chunks, sizeof(dataIn2Chunks), AX_COLON_32);
    }


    PRINTF("Verify Cert 4 still exists\r\n");
    {
        U8 readCertData[90];
        HLSE_ATTRIBUTE attrL;
        index = 3;

        memset(readCertData, 0x00, sizeof(readCertData));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(certHandle3 /*certHandles[index]*/, &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // set the reference data that in cert 3 that is expected not to change
        memset(certData, (0xAA + index), sizeof(certData));

        result &= AX_COMPARE_BYTE_ARRAY("read data", readCertData, sizeof(certData),
            "expected cert data", certData, sizeof(certData), AX_COLON_32);
    }
    //

    // note : last certificate depends on max certifcate which are allowed at Gp table
    PRINTF("Verify last Certificate created in table still exists\r\n");
    {
        U8 readCertData[90];
        HLSE_ATTRIBUTE attrL;
        index = nCertsCreated - 1;

        memset(readCertData, 0x00, sizeof(readCertData));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(lastCertHandle , &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // set the reference data that in lasr cert that is expected not to change
        memset(certData, (0xAA + index), sizeof(certData));

        result &= AX_COMPARE_BYTE_ARRAY("read data", readCertData, sizeof(certData),
            "expected cert data", certData, sizeof(certData), AX_COLON_32);
    }

    // enumerate objects - we should have certHandlesNum objects
    memset(certHandles, 0, sizeof(certHandles));
    PRINTF("\r\nHLSE_EnumerateObjects()...\r\n");
    certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, certHandles, &certHandlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(certHandlesNum, nCertsCreated, "err");

    // delete all certs
    for (indexCert = 0; indexCert < certHandlesNum; indexCert++)
    {
        index = indexCert;

        PRINTF("\r\nHLSE_EraseObject() - index 0x%02lx", index);
        hlseRc = HLSE_EraseObject(certHandles[index]);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }

    PRINTF("\r\n-----------\r\nEnd exCertUsageEnlarge(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}


/**
 * Demonstrate usage of certificate objects:
 *
 * this example Verifies correct operation in case when length of certificate object was Unknown at the
 * time the mapping table was created
 *
 * Detailed explanation :
 *
 * - The abstraction for various objects that reside in the GP Storage area is achieved by maintaining a
 *   lookup table (mapping) at the end of the GP Storage area to holds information about the logical objects that exist
 *   in the GP Storage
 *
 * - The gp table is rewritten(whole) each time an object is inserted or deleted
 * - Each object is aligned to occupy at least the amount of memory on the boundary of the GP storage, that is 32 bytes.
 *   E.g. an object of 17 bytes will occupy 32 bytes
 *
 * In cases where the length of an object is not known at the time the table entry is set, the MSBit (0x8000) will be set
 * in the length as an indicator for the host library to know that the data is in TLV format and that the actual length
 * can be obtained by reading the first bytes of the object's data.
 *
 * Example pre setup required:
 *
 * - We want to have a single certificate at offset 0 in the GP storage
 * - we want to have a mapping table with one entry in which the length of the certificate object is unknown.
 *
 * Simulate the following scenario to verify it works correctly:
 *
 * - Create A Mapping table with one entry with length unknown as follows:
 *
 * \verbatim
 *
 *      Notes:
 *          X+1 is the address of the last byte of the GP Storage.
 *          N is the object number from 1 to N
 *
 *      Address     Value
 *      -------     ----------------------
 *      X-1*6+0     First Object Class      - 1 byte    value : 0
 *      X-1*6+1     First Object Index      - 1 byte    value : 0
 *      X-1*6+2     First Object Length MSB - 1 byte    value : 0x80    ( 0x8000 the MSBit Indicates Indirect length)
 *      X-1*6+3     First Object Length LSB - 1 byte    value : 0x00
 *      X-1*6+4     First Object Offset MSB - 1 byte    value : 0
 *      X-1*6+5     First Object Offset LSB - 1 byte    value : 0
 *      X           Update Counter          - 1 byte    value : 1
 *      X+1         Number of table entries - 1 byte    value : 1
 *      End of GP Storage
 *
 * \endverbatim
 *
 * - Write simulated certificate object at offset 0 of gp storage
 *      use TLV length encoded length:
 *          - 2 bytes 0x81, 0x..
 *          - 3 bytes 0x82, 0x00, 0x..
 *
 * - Read certificate data and verify correctness
 *      - index ok
 *      - value was correctly set
 * - Update Certificate contents
 * - Verify Certificate Updated correctly
 * - Delete certificate
 * - Verify deletion
 *
 * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
 */
static U8 exCertUsageGpTableLengthUnknown(U8 initMode)
{
    U8 result = 1;
    HLSE_RET_CODE hlseRc;

    HLSE_OBJECT_HANDLE certHandles[5];

    U16 certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);

    HLSE_OBJECT_INDEX index = 0;
    HLSE_OBJECT_TYPE objType = HLSE_CERTIFICATE;

    // Cert for this test is 50 bytes which occupies 2 chunks of 32 bytes on the GP Storage
    U8 certData[50];

    HLSE_ATTRIBUTE attr[3];
    unsigned short templateSize = 3;

    U8 data[50];        // to hold data to update certificate

    memset(certHandles, 0x00, sizeof(certHandles));
    memset(certData, 0xAA, sizeof(certData));

    // Set header data - to be able to simulate length is unknown in the GP table at time Gp table was created -
    // so it will be retrieved from this header
    certData[0] = 0x30;     // tag
    certData[1] = 0x81;     // length in next byte
    certData[2] = 0x2F;     // length is 47 bytes

    PRINTF("\r\n-----------\r\nStart exCertUsageGpTableLengthUnknown(%s)\r\n------------\r\n", getInitModeAsString(initMode));

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= hlse_a71chInitModule(initMode);
    assert(result);

    // start with clean GP table to avoid cached data from previous test
    hlseRc = Debug_ForceReadGPDataTable();
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    attr[0].type = HLSE_ATTR_OBJECT_TYPE;
    attr[0].value = &objType;
    attr[0].valueLen = sizeof(objType);
    attr[1].type = HLSE_ATTR_OBJECT_INDEX;
    attr[1].value = &index;
    attr[1].valueLen = sizeof(index);
    attr[2].type = HLSE_ATTR_OBJECT_VALUE;
    attr[2].value = certData;
    attr[2].valueLen = sizeof(certData);

    // Create certificate object index = 0
    PRINTF("\r\nHLSE_CreateObject() - Create certificate object, use 2 bytes encoded length in header...\r\n------------\r\n");
    hlseRc = HLSE_CreateObject(attr, templateSize, &certHandles[0]);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // We now have a mapping table, starting at the beginning of the last chunk of the GP storage (order is backward) which consists of 32 bytes composed of:
    //
    // Start of last chunk of GP storage :
    // Address Offset                 Value
    // -------  ------------------    ----------------------
    // ...  (note invalid entries are filled with 0xff)
    // ...      ...                   ...
    // 4088 [0x00000018]          0x09 class               certificate 1
    // 4089 [0x00000019]          0x00 index
    // 4090 [0x0000001a]          0x00 Length MSB Byte
    // 4091 [0x0000001b]          0x32 Length LSB Byte     means size is 50 bytes = sizeof(certData)
    // 4092 [0x0000001c]          0x00 Offset MSB Byte     offset 0
    // 4093 [0x0000001d]          0x00 Offset LSB Byte
    // 4094 [0x0000001e]          0x01 update counter
    // 4095 [0x0000001f]          0x01 number of entries    (Note it is in the last byte of the GP storage)
    // End of Gp Storage

    // We'll now overrun this map to contain 0x8000 in the length to indicate indirect length
    PRINTF("\r\noverwrite gp table map to have indirect length indication...\r\n");
    {
        U16 gpSize;
        //HLSE_RET_CODE lReturn = HLSE_SW_OK;
        U8 dataL[32];
        U8 dataSize = sizeof(dataL);

        hlseRc = hlse_GetGPDataSize(&gpSize);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // Read the entire table - consists of one chunk 5 entries
        hlseRc = A71_GetGpData(gpSize - 32, dataL, 32);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // Now overwrite Gp Table with indirect length
        dataL[dataSize - 2 - 1*6 + 2] = 0x80;
        dataL[dataSize - 2 - 1*6 + 3] = 0x00;

//      dataL[2] = 0x80;
//      dataL[3] = 0x00;

#if 0   // just for debug !!
        //  data format to check
        U8 altData[32] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,            // invalid entry
            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,            // invalid entry
            0x09, 0x02, 0x80, 0x00, 0x06, 0x00,         // third certificate
            0x09, 0x01, 0x80, 0x00, 0x02, 0x00,         // second certificate
            0x09, 0x00, 0x80, 0x00, 0x00, 0x00,         // first certificate
            0x00, 0x03                                                       // update counter + num of entries
        };
        memcpy(dataL, altData, 32);
#endif

        hlseRc = A71_SetGpData(gpSize - 32, dataL, 32);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        hlseRc = Debug_ForceReadGPDataTable();
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }


    // enumerate objects - we should have one certificate by now with index 0
    PRINTF("\r\nHLSE_EnumerateObjects()...\r\n");
    certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, certHandles, &certHandlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(certHandlesNum, 1, "err");

    // make sure our certificate is the one we previously created
    // Get the attributes of the single certificate we have
    PRINTF("\r\nHLSE_GetObjectAttribute()...\r\n");
    {
        U32 certIndex = 0xFFFFFFFF;
        HLSE_ATTRIBUTE attrL;
        attrL.type = HLSE_ATTR_OBJECT_INDEX;
        attrL.value = &certIndex;
        attrL.valueLen = sizeof(certIndex);

        hlseRc = HLSE_GetObjectAttribute(certHandles[certHandlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        PRINTF("\tcert index = 0x%lx\r\n", certIndex);
        result &= AX_CHECK_U16((U16)certIndex, 0x00, "err");
    }

    PRINTF("Verify Certificate contents...\r\n");
    {
        U8 readCertData[50];

        HLSE_ATTRIBUTE attrL;
        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(certHandles[certHandlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("certOnA71CH", readCertData, sizeof(certData),
            "expected cert data", certData, sizeof(certData), AX_COLON_32);
    }

    PRINTF("Update Certificate contents , use 3 bytes encoded length in header...\r\n");
    {
        HLSE_ATTRIBUTE attrL;
        memset(data, 0xAB, sizeof(data));

        // Now use 3 bytes indirect length

        // Set header data - to be able to simulate length is unknown in the GP table at time Gp table was created -
        // so it will be retrieved from this header
        data[0] = 0x06;     // tag
        data[1] = 0x82;     // length in next 2 bytes
        data[2] = 0x00;     // MSB 0
        data[3] = 0x2E;     // length is 46 bytes

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = data;
        attrL.valueLen = sizeof(data);

        hlseRc = HLSE_SetObjectAttribute(certHandles[certHandlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }

    // We'll now overrun this map to contain 0x8000 in the length to indicate indirect length
    {
        U16 gpSize;
        //HLSE_RET_CODE lReturn = HLSE_SW_OK;
        U8 dataL[32];

        hlseRc = hlse_GetGPDataSize(&gpSize);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // Read the entire table - consists of one chunk 5 entries
        hlseRc = A71_GetGpData(gpSize - 32, dataL, 32);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        // Now overrite with indirect length
        dataL[2] = 0x80;
        dataL[3] = 0x00;

        hlseRc = A71_SetGpData(gpSize - 32, dataL, 32);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        hlseRc = Debug_ForceReadGPDataTable();
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }

    PRINTF("Verify Certificate Updated correctly...\r\n");
    {
        U8 readCertData[50];
        HLSE_ATTRIBUTE attrL;

        memset(readCertData, 0x00, sizeof(readCertData));

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = readCertData;
        attrL.valueLen = sizeof(readCertData);

        hlseRc = HLSE_GetObjectAttribute(certHandles[certHandlesNum - 1], &attrL);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        result &= AX_COMPARE_BYTE_ARRAY("read data", readCertData, sizeof(certData),
            "expected cert data", data, sizeof(data), AX_COLON_32);
    }


    // Delete the certificate
    PRINTF("\r\nHLSE_EraseObject()...\r\n");
    hlseRc = HLSE_EraseObject(certHandles[certHandlesNum - 1]);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // Verify it was actually deleted
    // enumerate objects - we should have no certificates by now
    PRINTF("\r\nVerify object was erased...\r\n");
    certHandlesNum = sizeof(certHandles) / sizeof(HLSE_OBJECT_HANDLE);
    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, certHandles, &certHandlesNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    result &= AX_CHECK_U16(certHandlesNum, 0, "err");


    PRINTF("\r\n-----------\r\nEnd exCertUsageGpTableLengthUnknown(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}


/**
 * Demonstrate
 *
 *  - Creating 3 read only certificates
 *  - Verify erasure of existing cert is disallowed since it's Read Only
 *  - Verify recreation of existing cert is disallowed since it's Read Only
 *  - Certificate Enumeration
 *  - Get Certificate value
 *  - Verify unable to update certificate value since it's Read Only
 *
 * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter
 */
static U8 exCertUsageReadOnly(U8 initMode)
{
    U8 result = 1;
    HLSE_RET_CODE hlseRc;

    HLSE_OBJECT_HANDLE objHandle, objHandle2, objHandle3, objHandle4;

    HLSE_OBJECT_INDEX index = 1;
    HLSE_OBJECT_TYPE objType = HLSE_CERTIFICATE;

    U8 readOnly = 1;

    U8 certData[50];
    HLSE_ATTRIBUTE attr[4];
    unsigned short templateSize = 4;

    U8 largeCertData[300];

    memset(certData, 0xAA, sizeof(certData));
    memset(largeCertData, 0xAC, sizeof(largeCertData));

    PRINTF("\r\n-----------\r\nStart exCertUsageReadOnly(%s)\r\n------------\r\n", getInitModeAsString(initMode));

    // Initialize the A71CH (Debug mode restrictions may apply)
    result &= hlse_a71chInitModule(initMode);
    assert(result);

    // start with clean GP table to avoid cached data from previous test
    hlseRc = Debug_ForceReadGPDataTable();
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    attr[0].type = HLSE_ATTR_OBJECT_TYPE;
    attr[0].value = &objType;
    attr[0].valueLen = sizeof(objType);
    attr[1].type = HLSE_ATTR_OBJECT_INDEX;
    attr[1].value = &index;
    attr[1].valueLen = sizeof(index);
    attr[2].type = HLSE_ATTR_OBJECT_VALUE;
    attr[2].value = certData;
    attr[2].valueLen = sizeof(certData);
    attr[3].type = HLSE_ATTR_READ_ONLY;     // meaning further modification of the GP storage area is disallowed
    attr[3].value = &readOnly;
    attr[3].valueLen = sizeof(readOnly);


    // Create certificate objects index 1 to 3 - with HLSE_ATTR_READ_ONLY

    hlseRc = HLSE_CreateObject(attr, templateSize, &objHandle);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    index = 2;
    hlseRc = HLSE_CreateObject(attr, templateSize, &objHandle2);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // Create large certificate - READ ONLY
    index = 3;
    attr[2].value = largeCertData;
    attr[2].valueLen = sizeof(largeCertData);
    hlseRc = HLSE_CreateObject(attr, templateSize, &objHandle3);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // Create large certificate
    index = 4;
    hlseRc = HLSE_CreateObject(attr, 3 /* without READ ONLY */, &objHandle4);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    // Try to erase certificate object at index 2 - should be disallowed as we created it with HLSE_ATTR_READ_ONLY attribute
    hlseRc = HLSE_EraseObject(objHandle2);
    result &= AX_CHECK_SW(hlseRc, HLSE_ERR_API_ERROR, "err");

    // Certificate Enumeration
    result &= exCertEnumerate();

    // Get certificate Attributes
    result &= exCertGetAttr();

    // Set Certificate Attributes
    result &= exCertSetAttr();

    // Certificate Enumeration
    result &= exCertEnumerate();

    PRINTF("\r\n-----------\r\nEnd exCertUsageReadOnly(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}

/**
 * Internal function , called from exCertUsageReadOnly()
 *
 * Demonstrate
 * - using HLSE_EnumerateObjects() for certificate enumeration
 * - using HLSE_GetObjectAttribute() to get certificate tag
 *
 */
static U8 exCertEnumerate()
{
    HLSE_OBJECT_HANDLE handles[10] = { 0 };
    U16 handleNum = 10;
    HLSE_RET_CODE hlseRc;
    U16 i;

    U8 result = 1;
    PRINTF("\r\n-----------\r\nStart exCertEnumerate()\r\n------------\r\n");

    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, handles, &handleNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    for (i = 0 ; i < handleNum ; ++i)  {
        U32 tag = 0;
        HLSE_ATTRIBUTE attr;
        attr.type = HLSE_ATTR_OBJECT_INDEX;
        attr.value = &tag;
        attr.valueLen = sizeof(tag);

        hlseRc = HLSE_GetObjectAttribute(handles[i], &attr);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

        PRINTF("exCertEnumerate - tag = 0x%lx\r\n", tag);
    }

    PRINTF("\r\n-----------\r\nEnd exCertEnumerate(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}

/**
 * Internal function , called from exCertUsageReadOnly()
 *
 * Demonstrate
 * - using HLSE_EnumerateObjects() for certificate enumeration
 * - using HLSE_GetObjectAttribute() with HLSE_ATTR_OBJECT_VALUE to get object's value
 *
 */
static U8 exCertGetAttr()
{
    U8 result = 1;
    HLSE_RET_CODE hlseRc;

    HLSE_OBJECT_HANDLE handles[10] = { 0 };
    U16 handleNum = 10;
    U16 i;

    PRINTF("\r\n-----------\r\nStart exCertGetAttr()\r\n------------\r\n");

    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, handles, &handleNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    for (i = 0; i < handleNum; ++i)  {
        U8 data[300];

        HLSE_ATTRIBUTE attr;
        attr.type = HLSE_ATTR_OBJECT_VALUE;
        attr.value = data;
        attr.valueLen = sizeof(data);

        hlseRc = HLSE_GetObjectAttribute(handles[i], &attr);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }

    PRINTF("\r\n-----------\r\nEnd exCertGetAttr(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}

/**
 * Demonstrate
 * - using HLSE_EnumerateObjects() for certificate enumeration
 * - shows using HLSE_SetObjectAttribute() to change an object's value fails when credential is frozen
 *
 */
static U8 exCertSetAttr()
{
    U8 result = 1;
    HLSE_RET_CODE hlseRc;

    HLSE_OBJECT_HANDLE handles[10];
    U16 handleNum = 10;

    U8 certData[40];

    U8 largeCertData[300];

    U16 i ;
    memset(certData, 0xBB, sizeof(certData));
    memset(largeCertData, 0xBD, sizeof(largeCertData));

    PRINTF("\r\n-----------\r\nStart exCertSetAttr()\r\n------------\r\n");

    hlseRc = HLSE_EnumerateObjects(HLSE_CERTIFICATE, handles, &handleNum);
    result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");

    for (i = 0; i < handleNum-2; ++i)  {
        HLSE_ATTRIBUTE attr;
        attr.type = HLSE_ATTR_OBJECT_VALUE;
        attr.value = certData;
        attr.valueLen = sizeof(certData);

        hlseRc = HLSE_SetObjectAttribute(handles[i], &attr);
        result &= AX_CHECK_SW(hlseRc, SW_COMMAND_NOT_ALLOWED, "Expected to fail, frozen credential cannot be changed");
    }

    // Try to update large cert data which is locked in GP storage
    i = handleNum - 2;
    {
        HLSE_ATTRIBUTE attr;
        attr.type = HLSE_ATTR_OBJECT_VALUE;
        attr.value = largeCertData;
        attr.valueLen = sizeof(largeCertData);

        hlseRc = HLSE_SetObjectAttribute(handles[i], &attr);
        result &= AX_CHECK_SW(hlseRc, SW_COMMAND_NOT_ALLOWED, "Expected to fail, frozen credential cannot be changed");
        // Last one is not frozen and should allow update
        i = handleNum - 1;
        hlseRc = HLSE_SetObjectAttribute(handles[i], &attr);
        result &= AX_CHECK_SW(hlseRc, HLSE_SW_OK, "err");
    }

    PRINTF("\r\n-----------\r\nEnd exCertSetAttr(), result = %s\r\n------------\r\n", ((result == 1) ? "OK" : "FAILED"));

    return result;
}


/**
* Internal utility to patch the TLV header of a data buffer so it contains the
* certificate header TLV correct
*
* A certificate header consists of the 0x30 tag followes by a length which could be encoded as
* 1) one byte: the length byte in case of length <= 127
* 2) 2 bytes : 0x81 followed byte the length byte in case 127 < length <= 255
* 3) 3 bytes : 0x82 followed by 2 bytes length otherwise
*/
static HLSE_RET_CODE patchCertificateInitialTL(U8 *clientCertDer, U16 clientCertDerLen)
{
    if (clientCertDerLen < 3)
    {
        // This is too short for a certificate
        return ERR_GP_NO_CERT;
    }
    else if (clientCertDerLen <= LEN_SHORT_FORM_MAX)
    {
        clientCertDer[0] = 0x30;
        clientCertDer[1] = (clientCertDerLen-2) & 0x00FF;
    }
    else if (clientCertDerLen <= LEN_LONG_FORM_ONE_BYTE_MAX)
    {
        clientCertDer[0] = 0x30;
        clientCertDer[1] = 0x81;
        clientCertDer[2] = (clientCertDerLen-3) & 0x00FF;
    }
    else
    {
        clientCertDer[0] = 0x30;
        clientCertDer[1] = 0x82;
        clientCertDer[2] = ((clientCertDerLen-4) >> 8) & 0x00FF;
        clientCertDer[3] = (clientCertDerLen-4) & 0x00FF;
    }
    return HLSE_SW_OK;
}


/**
* Internal - called from exMixedCertsAndDataObjUsage
*  Get an object's value and length based on based on object handle provided
*
* @param[in]     handle     object handle
* @param[out]    data       buffer to store object's value retrieved
* @param[in,out] len        in - length of data buffer, out - actual object's length
*/
static HLSE_RET_CODE getObject(HLSE_OBJECT_HANDLE handle, U8 *data, U16 *len)
{
    HLSE_RET_CODE hlseRc;
    HLSE_ATTRIBUTE attr;
    HLSE_OBJECT_TYPE type;
    U16 offset;

    // We are looking for the object on index i in handles array
    type = HLSE_GET_OBJECT_TYPE(handle);
    if (type == HLSE_CERTIFICATE) {
        PRINTF("get Certificate Object, handle=0x%lX\n", handle);
    }
    else {
        PRINTF("get Data Object, handle=0x%lX\n", handle);
    }

    // Read
    attr.type = HLSE_ATTR_OBJECT_VALUE;
    attr.value = data;
    attr.valueLen = *len;
    hlseRc = HLSE_GetObjectAttribute(handle, &attr);
    if (hlseRc != HLSE_SW_OK) {
        return hlseRc;
    }

    *len = attr.valueLen;

    // obtain object's GP offset
    {
        HLSE_ATTRIBUTE attrL;
        attrL.type = HLSE_ATTR_OBJECT_OFFSET;
        attrL.value = &offset;
        attrL.valueLen = sizeof(offset);

        hlseRc = HLSE_GetObjectAttribute(handle, &attrL);
        if (hlseRc != HLSE_SW_OK) {
            return hlseRc;
        }
    }

    PRINTF("Object retrieved: Offset=%d, Size=%d\n", offset, *len);

    return HLSE_SW_OK;
}


/**
* Internal - called from exMixedCertsAndDataObjUsage
*  Set a Certificate or Data object's value based on on object handle provided
*
* @param[in] handle     object handle
* @param[in] data       buffer of data to set obj value
* @param[in] len        in - length of data buffer
*/
static HLSE_RET_CODE setObject(HLSE_OBJECT_HANDLE handle, U8 *data, U16 len)
{
    HLSE_RET_CODE hlseRc;
    HLSE_OBJECT_TYPE type;

    // We are looking for the object on index i in handles array
    type = HLSE_GET_OBJECT_TYPE(handle);
    if (type == HLSE_CERTIFICATE) {
        PRINTF("Set Certificate Object, handle=0x%lX\n", handle);
    }
    else {
        PRINTF("Set Data Object, handle=0x%lX\n", handle);
    }

    // Update
    {
        HLSE_ATTRIBUTE attrL;

        attrL.type = HLSE_ATTR_OBJECT_VALUE;
        attrL.value = data;
        attrL.valueLen = len;

        hlseRc = HLSE_SetObjectAttribute(handle, &attrL);
        if (hlseRc != HLSE_SW_OK) {
            return hlseRc;
        }
    }

    return HLSE_SW_OK;
}
