/*
@file app_main.c
@brief App main entry point.
*/

#include <string.h>
#include "authhat_protocol.h"
#include "sec_common.h"
#include "sec_main.h"
#include "qsee_message.h"
#include "qsee_cfg_prop.h"

#define MAX_PREFIX_LEN  128
#define MAX_TA_NAME_LEN 32

#define ALT_ROT_DOMAIN  "alt_rot_domain_name_dot"
#define DL_ROT_DOMAIN   "dl_rot_domain_name_dot"

#undef USE_ION_MEMORY

#if defined (CHIPSET_SM8150)
#define ENCAP_DEST_PREFIX "alt.9361A53CBE05BDDEEEF7DDCD9E0D2AD472FF0A1AEE5F3EE4C7E416162273D237."
#elif defined (CHIPSET_SM8150_FUSION)
#define ENCAP_DEST_PREFIX "alt.984426BE79B6C60F9265EDF6ECDD4CFF1827E9CB0B439D1CBFDCE378B76001DC."
#elif defined (CHIPSET_SM6150_7150)
#define ENCAP_DEST_PREFIX "alt.FEF4EFBC5D6689C2939E7C410088053F102F5FB4D7B7319C3144BD79E5464654."
#elif defined (CHIPSET_SDM710)
#define ENCAP_DEST_PREFIX "alt.C6A1B1F001AA41325C471DEFBB767B962D381CF0FE7224E73EC4305C0C848736."
#elif defined (CHIPSET_SM8250)
#define ENCAP_DEST_PREFIX "alt.288717EFA81760C347CDB3A0CA23723C92AC2EE97AD36A7BB9EE3EEE76678BEA."
#elif defined (CHIPSET_SM7250)
#define ENCAP_DEST_PREFIX "alt.5F9C8380E961E155915D29DE377BBED27FDA4E89F64C7BBB403CF3B8070C3BB0."
#elif defined (CHIPSET_SM7125)
#define ENCAP_DEST_PREFIX "alt.CFB65A86E7474BFBC56E4073CD90B00894FA7658A5DD3F09C6C9802EBF4B2BF5."
#elif defined (CHIPSET_SM7225)
#define ENCAP_DEST_PREFIX "alt.1719D77DE33667DC1D31FE8C99668CB2CCE585C44C6EDADBA57573052430BEE4."
#else
#define ENCAP_DEST_PREFIX ""
#endif

#ifndef QSEE_MESSAGE_SUCCESS
#define QSEE_MESSAGE_SUCCESS QSEE_MESSAGE_SUCESS
#endif

#if defined(USE_ION_MEMORY)
#define BFP_ION_BUF_NUM     2
#define BFP_ION_BUF_SIZE    (1 * 1024 * 1024)	// for cmd 1MB, rsp 1MB


typedef struct tl_bfp_ion_req_s
{
    authhat_tz_cmd_type cmd_id;         /* command id */
    UINT8 *			req_buf;
    UINT8 *			rsp_buf;
} __attribute__ ((packed)) tl_bfp_ion_req_t;

typedef struct tl_bfp_ion_rsp_s
{
    authhat_tz_cmd_type cmd_id;         /* command id */
} __attribute__ ((packed)) tl_bfp_ion_rsp_t;

/**
  @brief 
    Prepare buffer for secure read
*/
int vfm_prepare_buffer_for_secure(void *ptr, UINT32 size)
{
    int retval = AUTHHAT_RESULT_SUCCESS;
    UINT32 bSbRegistered = 0;

    /* IMPORTANT : Buffer should be 64 bytes aligned.(64 is cache line length) And 64 bytes align is accomplished by Normal world ION allocater */

    retval = qsee_register_shared_buffer(ptr, size);
    if (retval) {
        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "FAIL_REGISTER_SB(%d)", retval);
        retval = AUTHHAT_RESULT_FAIL_GENERAL;
        goto cleanup;
    }
    bSbRegistered = TRUE;

    retval = qsee_prepare_shared_buf_for_secure_read(ptr, size);
    if (retval) {
        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "FAIL_PREP_SB_SECURE_READ(%d)", retval);
        retval = AUTHHAT_RESULT_FAIL_GENERAL;
        goto cleanup;
    }

  return retval;

cleanup:
    (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "clean up shared buffer");
    if (bSbRegistered) {
        if (AUTHHAT_RESULT_SUCCESS != qsee_prepare_shared_buf_for_nosecure_read(ptr, size))
        {
            (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "FAIL_PREP_SB_NON_SECURE_READ");
        }

        if (AUTHHAT_RESULT_SUCCESS != qsee_deregister_shared_buffer(ptr))
        {
            (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "FAIL_DEREGISTER_SB");
        }
    }

    return retval;
}

/**
  @brief 
    Prepare buffer for nonsecure read
*/
int vfm_prepare_buffer_for_nonsecure(void *ptr, UINT32 size)
{
    int retval = AUTHHAT_RESULT_SUCCESS;

    retval = qsee_prepare_shared_buf_for_nosecure_read(ptr, size);
    if (AUTHHAT_RESULT_SUCCESS != retval)
    {
        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "FAIL_PREP_SB_NON_SECURE_READ(%d)", retval);
        retval = AUTHHAT_RESULT_FAIL_GENERAL;
    }

    retval = qsee_deregister_shared_buffer(ptr);
    if (AUTHHAT_RESULT_SUCCESS != retval)
    {
        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "FAIL_DEREGISTER_SB(%d)", retval);
        retval = AUTHHAT_RESULT_FAIL_GENERAL;
    }

    return retval;
}


#define PREPARE_BUFFER_FOR_SECURE(ptr, size) {                                \
    ret = vfm_prepare_buffer_for_secure(ptr, size);                          \
    if (ret) {                                                               \
        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "vfm_prepare_buffer_for_secure failed");     \
        return;                                                            \
    }                                                                           \
}                                                                             \

#define PREPARE_BUFFER_FOR_NONSECURE(ptr, size) {                             \
    ret = vfm_prepare_buffer_for_nonsecure(ptr, size);                       \
    if (ret) {                                                               \
        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "vfm_prepare_buffer_for_nonsecure failed");  \
        return;                                                            \
    }                                                                           \
}                                                                             \

#endif

#define LENGTH_INTEGRITY_CHECK(in_length, max_length, rsp_t)    {                                           \
    if(in_length > max_length)                                                                                                  \
    {                                                                                                                                   \
        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG,"input data length error in_len= ", in_length);                   \
        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG,"input data length error max_len = ", max_length);            \
        rsp_t *err_ret = (rsp_t *) rsp;                                                                                             \
        err_ret->ret = AUTHHAT_RESULT_FAIL_MEMORY_ALLOC;                                                    \
        if(cmd_ptr)                                                                                                                     \
            PAL_MemoryFree(cmd_ptr);                                                                                           \
        if(rsp_ptr)                                                                                                                     \
            PAL_MemoryFree(rsp_ptr);                                                                                           \
        break;                                                                                                                          \
    }                                                                                                                                       \
}                                                                                                                                           \

#define CMD_RSP_PTR_INIT(req_t, rsp_t)  {               \
    cmd_ptr = (req_t *)PAL_MemoryAlloc(sizeof(req_t));          \
    if(cmd_ptr == NULL)                                         \
    {                                                                   \
        (*LOG_MSG)(TZ_LOG_LEVEL_ERROR, "CMD_RSP_PTR_INIT cmd_ptr memory fail");      \
            rsp_t *err_ret = (rsp_t *) rsp;                 \
            err_ret->ret = AUTHHAT_RESULT_FAIL_MEMORY_ALLOC;  \
            break;                                                  \
    }                                                                   \
    else                                                                \
    {                                                                   \
        memset(cmd_ptr, 0, sizeof(req_t));                  \
    }                                                                  \
    rsp_ptr = (rsp_t *)PAL_MemoryAlloc(sizeof(rsp_t));          \
    if(rsp_ptr == NULL)                                         \
    {                                                                   \
        (*LOG_MSG)(TZ_LOG_LEVEL_ERROR, "CMD_RSP_PTR_INIT rsp_ptr memory fail");      \
        if(cmd_ptr)                                                 \
            PAL_MemoryFree(cmd_ptr);                       \
        rsp_t *err_ret = (rsp_t *) rsp;                         \
        err_ret->ret = AUTHHAT_RESULT_FAIL_MEMORY_ALLOC;  \
        break;                                                      \
    }                                                                   \
    else                                                                \
    {                                                                   \
        memset(rsp_ptr, 0, sizeof(rsp_t));                  \
    }                                                                  \
    memcpy(cmd_ptr, cmd, sizeof(req_t));    \
}   \

#define CMD_RSP_PTR_INIT_ION(req_t, rsp_t)  {               \
    cmd_ptr = (req_t *)PAL_MemoryAlloc(sizeof(req_t));          \
    if(cmd_ptr == NULL)                                         \
    {                                                                   \
        (*LOG_MSG)(TZ_LOG_LEVEL_ERROR, "CMD_RSP_PTR_INIT cmd_ptr memory fail");      \
        rsp_t *err_ret = (rsp_t *) rsp;                     \
        err_ret->ret = AUTHHAT_RESULT_FAIL_MEMORY_ALLOC;  \
        break;      \
    }                                                                   \
    rsp_ptr = (rsp_t *)PAL_MemoryAlloc(sizeof(rsp_t));          \
    if(rsp_ptr == NULL)                                         \
    {                                                                   \
        (*LOG_MSG)(TZ_LOG_LEVEL_ERROR, "CMD_RSP_PTR_INIT rsp_ptr memory fail");      \
        if(cmd_ptr)                                                 \
            PAL_MemoryFree(cmd_ptr);                       \
        rsp_t *err_ret = (rsp_t *) rsp;                         \
        err_ret->ret = AUTHHAT_RESULT_FAIL_MEMORY_ALLOC;  \
        break;                      \
    }                                                                   \
    memcpy(cmd_ptr, mod_cmd->req_buf, sizeof(req_t));    \
}   \

#define CMD_RSP_PTR_SET(rsp_t)   {               \
    memcpy(rsp, rsp_ptr, sizeof(rsp_t));    \
    if(cmd_ptr)                                         \
        PAL_MemoryFree(cmd_ptr);               \
    if(rsp_ptr)                                         \
        PAL_MemoryFree(rsp_ptr);               \
}                                                           \

#define CMD_RSP_PTR_SET_ION(rsp_t)   {               \
        memcpy(mod_cmd->rsp_buf, rsp_ptr, sizeof(rsp_t));    \
        if(cmd_ptr)                                         \
            PAL_MemoryFree(cmd_ptr);               \
        if(rsp_ptr)                                         \
            PAL_MemoryFree(rsp_ptr);               \
    }                                                           \


#define CHECK_INVALID_CMDRSP_BUFFER(cmd_t, rsp_t, cmd_len, rsp_len) {               \
    if ((sizeof(cmd_t) > (cmd_len)) || (sizeof(rsp_t) > (rsp_len))) {               \
        (*LOG_MSG)(TZ_LOG_LEVEL_ERROR, "tl_cmd_handler :: invalid buffer length");  \
        if (rsp_len >= sizeof(rsp_t)) {                                             \
            rsp_ptr->ret = AUTHHAT_RESULT_INVALID_PARAMETER;                        \
        }                                                                           \
        return;                                                                     \
    }                                                                               \
}                                                                                   \

#if defined(USE_ALT_ROT_NAME)
void get_rot_ta_name(char* domain_type, char* tz_name, char *rot_ta_name) {

    (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "get_rot_ta_name");
    
    UINT32 rv = AUTHHAT_RESULT_SUCCESS;
    uint32_t prop[2 + (MAX_PREFIX_LEN / sizeof(uint32_t))] = {0};
    uint32_t prop_len = 0;
    char prefix[MAX_PREFIX_LEN] = {0};

    if((domain_type == NULL)||(tz_name == NULL)||(rot_ta_name == NULL)) {
        PAL_DbgLog("get_rot_ta_name - invalid param");
        return;
    }

    memset(rot_ta_name, 0, MAX_PREFIX_LEN + MAX_TA_NAME_LEN);

    rv = qsee_cfg_getpropval(domain_type, strlen(domain_type) + 1, 0, (qsee_cfg_propvar_t *)&prop, sizeof(prop), &prop_len);
    if(rv != QSEE_CFG_SUCCESS) {
        PAL_DbgLog("get_rot_ta_name - '%s' read failed, using legacy appname", domain_type);
        prop_len = strlcpy(rot_ta_name, tz_name, MAX_TA_NAME_LEN);
        return;
    }

    qsee_cfg_propvar_t* ptr = (qsee_cfg_propvar_t *)prop;
    
    /* len = ret_size - sizeof(qsee_cfg_propvar_t) + padding */
    size_t len = prop_len - sizeof(*ptr) + 2 * sizeof(ptr->val) + 1;

    if (len > sizeof(prefix)) {
        PAL_DbgLog("get_rot_ta_name - '%s' len invalid, using legacy appname", domain_type);
        strlcpy(rot_ta_name, tz_name, MAX_TA_NAME_LEN);
        return;
    }

    /* remove the quotes only when read from devcfg */
    memcpy(prefix, &ptr->val[1], len - 1);
    prefix[len] = '\0';

    /* finalize fully qualified distname */
    strlcpy(rot_ta_name, prefix, MAX_PREFIX_LEN);
    strlcat(rot_ta_name, tz_name, MAX_TA_NAME_LEN + MAX_PREFIX_LEN);

}
#endif


/**
  @brief 
    Handles fp_asm Commands

  @param[in]      cmd         Requested command structure
  @param[in]      cmdlen      length of request commad struct
  @param[in/out]  rsp         Resposnse structure
  @param[in/out]  rsplen      length of response commad struct
*/


UINT8 key_from_keymaster[AUTHHAT_MAX_KEY_LEN]={0,};
UINT32 key_from_keymaster_len = 0;
UINT8 key_to_fingerprint[AUTHHAT_MAX_KEY_LEN + AUTHHAT_MAX_ADDITIONAL_ENCAP_OUT_LEN]={0,};
UINT32 key_to_fingerprint_len = 0;

void tl_cmd_handler(void* cmd, UINT32 cmdlen, void* rsp, UINT32 rsplen)
{
    /* Request-response buffers are allocated by non-secure side*/
    /* Add code to process requests and set response (if any)*/

    UINT32 ret = AUTHHAT_RESULT_SUCCESS;

#ifdef PERFORM_CHECK
    unsigned long long start = 0;
    unsigned long long end = 0;
#endif

#if defined(USE_ION_MEMORY)
    tl_bfp_ion_req_t *mod_cmd = (tl_bfp_ion_req_t *)cmd;
    //	tl_bfp_ion_rsp_t *mod_rsp = (tl_bfp_ion_rsp_t *)rsp;

    PREPARE_BUFFER_FOR_SECURE(mod_cmd->req_buf, BFP_ION_BUF_SIZE);
    PREPARE_BUFFER_FOR_SECURE(mod_cmd->rsp_buf, BFP_ION_BUF_SIZE);
#endif


    cmd_req_t *cmd_req = (cmd_req_t *)cmd;
    switch (cmd_req->cmd_id)
    {
        case AUTHHAT_CMD_DECAP_KEY:
        {
            get_decapped_key_req_t *cmd_ptr = NULL;
            get_decapped_key_rsp_t *rsp_ptr = NULL;
            char TZ_NAME[MAX_PREFIX_LEN + MAX_TA_NAME_LEN] = "keymaster";
            int ret = AUTHHAT_RESULT_SUCCESS;

#if defined(USE_ION_MEMORY)
            CMD_RSP_PTR_INIT_ION(get_decapped_key_req_t, get_decapped_key_rsp_t);
#else
            CMD_RSP_PTR_INIT(get_decapped_key_req_t, get_decapped_key_rsp_t);
#endif

            CHECK_INVALID_CMDRSP_BUFFER(get_decapped_key_req_t, get_decapped_key_rsp_t, cmdlen, rsplen);

            LENGTH_INTEGRITY_CHECK(cmd_ptr->in_param_len, AUTHHAT_MAX_KEY_LEN, get_decapped_key_rsp_t);

            key_from_keymaster_len = cmd_ptr->in_param_len;

            ret = qsee_decapsulate_inter_app_message (TZ_NAME, (uint8_t*)cmd_ptr->in_param, (uint32_t)cmd_ptr->in_param_len, (uint8_t*)key_from_keymaster, (uint32_t*)&key_from_keymaster_len);

#if defined(USE_ALT_ROT_NAME)
            char tz_app[MAX_PREFIX_LEN + MAX_TA_NAME_LEN + 1] = {0};
            get_rot_ta_name(ALT_ROT_DOMAIN, "skeymast", tz_app);
            if((strncmp(TZ_NAME, tz_app, strlen(tz_app)) != 0))
#else
            if((strncmp(TZ_NAME, "skeymast", 8) != 0)
                && (strncmp(TZ_NAME, "keymaste", 8) != 0)
                && (strncmp(TZ_NAME, "keymaster", 9) != 0))
#endif
            {
                (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT Error received app name : %s", TZ_NAME);
                memset(key_from_keymaster, 0, sizeof(key_from_keymaster));
                key_from_keymaster_len = 0;
                ret = QSEE_MESSAGE_ERROR;
            }

            rsp_ptr->ret = ret;

#if defined(USE_ION_MEMORY)
            CMD_RSP_PTR_SET_ION(get_decapped_key_rsp_t);
#else
            CMD_RSP_PTR_SET(get_decapped_key_rsp_t);
#endif
            (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT TZ App cmd handler, cmd_id = %d ret : %d END ", cmd_req->cmd_id, ((get_decapped_key_rsp_t *)rsp)->ret);

            break;
        }
        
        case AUTHHAT_CMD_ENCAP_KEY:
        {
            encap_key_req_t *cmd_ptr = NULL;
            encap_key_rsp_t *rsp_ptr = NULL;
            char TZ_NAME[MAX_TA_NAME_LEN] = {0};
           // (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT tz type : %d", cmd_ptr->tz_type);

            int ret = AUTHHAT_RESULT_SUCCESS;

#if defined(USE_ION_MEMORY)
            CMD_RSP_PTR_INIT_ION(encap_key_req_t, encap_key_rsp_t);
#else
            CMD_RSP_PTR_INIT(encap_key_req_t, encap_key_rsp_t);
#endif

            CHECK_INVALID_CMDRSP_BUFFER(encap_key_req_t, encap_key_rsp_t, cmdlen, rsplen);

            switch(cmd_ptr->tz_type)
            {
                case TZ_NAME_SECUREFP:
                {
                    char temp[MAX_TA_NAME_LEN] = "securefp";
                    memcpy(TZ_NAME, temp, sizeof(temp));
                    break;
                }
                case TZ_NAME_DUALFP:
                {
                    char temp[MAX_TA_NAME_LEN] = "dualfp";
                    memcpy(TZ_NAME, temp, sizeof(temp));
                    break;
                }
                case TZ_NAME_FIDO:
                {
                    break;
                }
                case TZ_NAME_SEC_IRIS:
                {
                    char temp[MAX_TA_NAME_LEN] = "sec_iris";
                    memcpy(TZ_NAME, temp, sizeof(temp));
                    break;
                }
                case TZ_NAME_TIGERFP:
                {
                    char temp[MAX_TA_NAME_LEN] = "tigerfp";
                    memcpy(TZ_NAME, temp, sizeof(temp));
                    break;
                }
                case TZ_NAME_SEC_FR:
                {
                    char temp[MAX_TA_NAME_LEN] = "sec_fr";
                    memcpy(TZ_NAME, temp, sizeof(temp));
                    break;
                }
                default:
                {
                    (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT AUTHHAT_CMD_ENCAP_KEY default");
                    rsp_ptr->out_param_len = 0;
                    rsp_ptr->ret = AUTHHAT_RESULT_INVALID_PARAMETER;
#if defined(USE_ION_MEMORY)
                    CMD_RSP_PTR_SET_ION(encap_key_rsp_t);
                    PREPARE_BUFFER_FOR_NONSECURE(mod_cmd->req_buf, BFP_ION_BUF_SIZE);
                    PREPARE_BUFFER_FOR_NONSECURE(mod_cmd->rsp_buf, BFP_ION_BUF_SIZE);
#else
                    CMD_RSP_PTR_SET(encap_key_rsp_t);
#endif
                    return;
                }
            }

            if((key_from_keymaster_len <= AUTHHAT_MAX_KEY_LEN) && (key_from_keymaster_len > 0))
            {
                key_to_fingerprint_len = AUTHHAT_MAX_KEY_LEN + AUTHHAT_MAX_ADDITIONAL_ENCAP_OUT_LEN;
                ret = qsee_encapsulate_inter_app_message (TZ_NAME, (uint8_t*)key_from_keymaster, (uint32_t)key_from_keymaster_len, (uint8_t*)key_to_fingerprint, (uint32_t*)&key_to_fingerprint_len);
                if (ret != QSEE_MESSAGE_SUCCESS) {
                    (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "retry");
                    char TZ_NAME_WITH_PREFIX[MAX_PREFIX_LEN + MAX_TA_NAME_LEN + 1] = {0};
#if defined(USE_ALT_ROT_NAME)
                    get_rot_ta_name(DL_ROT_DOMAIN, TZ_NAME, TZ_NAME_WITH_PREFIX);
#else
                    int prefix_len = strlen(ENCAP_DEST_PREFIX);
                    memcpy(TZ_NAME_WITH_PREFIX, ENCAP_DEST_PREFIX, prefix_len);
                    memcpy(TZ_NAME_WITH_PREFIX + prefix_len, TZ_NAME, strlen(TZ_NAME));
#endif
                    if(key_from_keymaster_len <= AUTHHAT_MAX_KEY_LEN)
                    {
                        ret = qsee_encapsulate_inter_app_message (TZ_NAME_WITH_PREFIX, (uint8_t*)key_from_keymaster, (uint32_t)key_from_keymaster_len, (uint8_t*)key_to_fingerprint, (uint32_t*)&key_to_fingerprint_len);
                    }
                    else
                    {
                        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT second boundary check fail : %d", key_from_keymaster_len);
                        key_to_fingerprint_len = 0;
                        ret = QSEE_MESSAGE_ERROR;
                    }
                }

                if(ret == QSEE_MESSAGE_SUCCESS)
                {
                    if(key_to_fingerprint_len > key_from_keymaster_len + AUTHHAT_MAX_ADDITIONAL_ENCAP_OUT_LEN)
                    {
                        (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT org out_len boundary check fail : %d %d", key_from_keymaster_len, key_to_fingerprint_len);
                        key_to_fingerprint_len = 0;
                        ret = QSEE_MESSAGE_ERROR;
                    }
                }

                memcpy(rsp_ptr->out_param, key_to_fingerprint, key_to_fingerprint_len);
                rsp_ptr->out_param_len = key_to_fingerprint_len;
                rsp_ptr->ret = ret;
            }
            else
            {
                (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT first boundary check fail : %d", key_from_keymaster_len);
                rsp_ptr->out_param_len = 0;
                rsp_ptr->ret = QSEE_MESSAGE_ERROR;
            }

#if defined(USE_ION_MEMORY)
            CMD_RSP_PTR_SET_ION(encap_key_rsp_t);
#else
            CMD_RSP_PTR_SET(encap_key_rsp_t);
#endif
            (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT TZ App cmd handler, cmd_id = %d ret : %d END ", cmd_req->cmd_id, ((encap_key_rsp_t *)rsp)->ret);

            break;

        }

        case AUTHHAT_CMD_ENCAP_KEY_WITH_PREFIX:
        {
            encap_key_req_t *cmd_ptr = NULL;
            encap_key_rsp_t *rsp_ptr = NULL;
            char TZ_NAME[200] = {0, };
           // (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT tz type : %d", cmd_ptr->tz_type);

            int ret = AUTHHAT_RESULT_SUCCESS;

#if defined(USE_ION_MEMORY)
            CMD_RSP_PTR_INIT_ION(encap_key_req_t, encap_key_rsp_t);
#else
            CMD_RSP_PTR_INIT(encap_key_req_t, encap_key_rsp_t);
#endif

            CHECK_INVALID_CMDRSP_BUFFER(encap_key_req_t, encap_key_rsp_t, cmdlen, rsplen);

            int prefix_len = strlen(ENCAP_DEST_PREFIX);
            memcpy(TZ_NAME, ENCAP_DEST_PREFIX, prefix_len);

            switch(cmd_ptr->tz_type)
            {
                case TZ_NAME_SECUREFP:
                {
                    char temp[32] = "securefp";
                    memcpy(TZ_NAME + prefix_len, temp, strlen(temp));
                    break;
                }
                case TZ_NAME_DUALFP:
                {
                    char temp[32] = "dualfp";
                    memcpy(TZ_NAME + prefix_len, temp, strlen(temp));
                    break;
                }
                case TZ_NAME_SEC_FR:
                {
                    char temp[32] = "sec_fr";
                    memcpy(TZ_NAME + prefix_len, temp, strlen(temp));
                    break;
                }
                default:
                {
                    (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT AUTHHAT_CMD_ENCAP_KEY default");
                    rsp_ptr->out_param_len = 0;
                    rsp_ptr->ret = AUTHHAT_RESULT_INVALID_PARAMETER;
#if defined(USE_ION_MEMORY)
                    CMD_RSP_PTR_SET_ION(encap_key_rsp_t);
                    PREPARE_BUFFER_FOR_NONSECURE(mod_cmd->req_buf, BFP_ION_BUF_SIZE);
                    PREPARE_BUFFER_FOR_NONSECURE(mod_cmd->rsp_buf, BFP_ION_BUF_SIZE);
#else
                    CMD_RSP_PTR_SET(encap_key_rsp_t);
#endif
                    return;
                }
            }

            if((key_from_keymaster_len <= AUTHHAT_MAX_KEY_LEN) && (key_from_keymaster_len > 0))
            {
                key_to_fingerprint_len = AUTHHAT_MAX_KEY_LEN + AUTHHAT_MAX_ADDITIONAL_ENCAP_OUT_LEN;
                ret = qsee_encapsulate_inter_app_message (TZ_NAME, (uint8_t*)key_from_keymaster, (uint32_t)key_from_keymaster_len, (uint8_t*)key_to_fingerprint, (uint32_t*)&key_to_fingerprint_len);
            }
            else
            {
                (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT prefix boundary check fail : %d", key_from_keymaster_len);
                key_to_fingerprint_len = 0;
                ret = QSEE_MESSAGE_ERROR;
            }

            if(ret == QSEE_MESSAGE_SUCCESS)
            {
                if(key_to_fingerprint_len > key_from_keymaster_len + AUTHHAT_MAX_ADDITIONAL_ENCAP_OUT_LEN)
                {
                    (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT prefix out_len boundary check fail : %d %d", key_from_keymaster_len, key_to_fingerprint_len);
                    key_to_fingerprint_len = 0;
                    ret = QSEE_MESSAGE_ERROR;
                }
            }

            memcpy(rsp_ptr->out_param, key_to_fingerprint, key_to_fingerprint_len);
            rsp_ptr->out_param_len = key_to_fingerprint_len;
            rsp_ptr->ret = ret;

#if defined(USE_ION_MEMORY)
            CMD_RSP_PTR_SET_ION(encap_key_rsp_t);
#else
            CMD_RSP_PTR_SET(encap_key_rsp_t);
#endif
            (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT TZ App cmd handler, cmd_id = %d ret : %d END ", cmd_req->cmd_id, ((encap_key_rsp_t *)rsp)->ret);

            break;

        }
        case AUTHHAT_CMD_PRE_ENROLL: 
		{
            pre_enroll_req_t *cmd_ptr = NULL;
            pre_enroll_rsp_t *rsp_ptr = NULL;
			
            int ret = AUTHHAT_RESULT_SUCCESS;
            UINT32 tz_type = 0;
            uint64_t challenge; 												 
            UINT8 encryptedChallenge[AUTHHAT_SUBMODULE_MAX_META_DATA_LEN] = {0, };		 
            UINT32 encryptedChallengeLen;

#if defined(USE_ION_MEMORY)
            CMD_RSP_PTR_INIT_ION(pre_enroll_req_t, pre_enroll_rsp_t);
#else
            CMD_RSP_PTR_INIT(pre_enroll_req_t, pre_enroll_rsp_t);
#endif

            CHECK_INVALID_CMDRSP_BUFFER(pre_enroll_req_t, pre_enroll_rsp_t, cmdlen, rsplen);

            switch (cmd_ptr->tz_type) {
            case TZ_NAME_SEC_IRIS: {
                tz_type = BIO_SUBMODULE_SEC_IRIS;
                break;
            }
            case TZ_NAME_SEC_FR: {
                tz_type = BIO_SUBMODULE_SEC_FR;
                break;
            }
            default: {
                (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT AUTHHAT_CMD_PRE_ENROLL default");
                break;
            }
            }

			ret = authhat_pre_enroll(tz_type, &challenge, encryptedChallenge, &encryptedChallengeLen);
            if (ret != AUTHHAT_RESULT_SUCCESS) {
                (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT AUTHHAT_CMD_PRE_ENROLL failed");
            }

            rsp_ptr->challenge = challenge;
            rsp_ptr->encryptedChallengeLen = encryptedChallengeLen;
            if ((encryptedChallengeLen > 0) && (encryptedChallengeLen < AUTHHAT_SUBMODULE_MAX_META_DATA_LEN)) {
                memcpy(rsp_ptr->encryptedChallenge, encryptedChallenge, encryptedChallengeLen);
            }

			rsp_ptr->ret = ret;

			memset(encryptedChallenge, 0, encryptedChallengeLen);

#if defined(USE_ION_MEMORY)
            CMD_RSP_PTR_SET_ION(pre_enroll_req_t);
#else
            CMD_RSP_PTR_SET(pre_enroll_rsp_t);
#endif
            (*LOG_MSG)(TZ_LOG_LEVEL_DEBUG, "AUTHHAT TZ App cmd handler, cmd_id = %d ret : %d END ", cmd_req->cmd_id, ((pre_enroll_rsp_t *)rsp)->ret);

            break;			
		}
        default:
        {
            cmd_rsp_t *rsp_ptr = (cmd_rsp_t *)rsp;
            rsp_ptr->ret = (UINT32) AUTHHAT_RESULT_FAIL_GENERAL;
            break;
        }
    }


#if defined(USE_ION_MEMORY)
    PREPARE_BUFFER_FOR_NONSECURE(mod_cmd->req_buf, BFP_ION_BUF_SIZE);
    PREPARE_BUFFER_FOR_NONSECURE(mod_cmd->rsp_buf, BFP_ION_BUF_SIZE);
#endif
}
