/*
 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Created in Samsung Ukraine R&D Center (SRK) under a contract between
 * LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
 * and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea)
 */

/**
 * @file TigerSskds.c
 * @brief TigerTa
 * @author Viktor Kopp (v.kopp@samsung.com)
 * @author Andrey Orlenko (a.orlenko@samsung.com)
 * @date Created Aug 23, 2016
 */

#include "TigerSskds.h"

#include <stdio.h>
#include <inttypes.h>
#include <mbedtls/pk.h>

#include "TigerLogging.h"
#include "TigerKeyDataStore.h"
#include "TigerAttk.h"
#include "TigerMacroses.h"
#include "TigerMbedTlsExt.h"
#include "TigerStorageUtils.h"
#include "TigerCounterDataStore.h"
#include "TzwSerialNumber.h"
#include "TzwHash.h"
#include "TzwString.h"
#include "TigerFingerprintIdTable.h"

#if defined(TIGER_BUILD_TESTS)
    #include "TigerTests.h"
#endif


#define TIGER_SHA256_HASH_LENGTH        32  /*bytes*/
#define TIGER_RSA_SIGNATURE_PSS_LENGTH  256 /*bytes*/
#define SILICON_PROVIDER_ID             15; // Use 00 for Common QC implement.
                                            // But as Samsung develops by itself, you should use 15.

static TEE_Result signDataWeChatServer(mbedtls_pk_context* devkey, const uint8_t* data, size_t len,
        uint8_t* signature, size_t* siglen);
static TciDeviceStatus_t getDeviceRegistrationStatus();
static TEE_Result checkCertificate(const char* alias);
// this function can be static but we don't do that to avoid compilation errors (unused function if TIGER_BUILD_TESTS)
TEE_Result fillDeviceId(uint8_t* deviceId, const size_t devIdSize, const uint32_t chipId);

TEE_Result getRegistrationStatus(TciDeviceStatus_t* deviceStatus) {
    LOG_FUNC_BEGIN;

    *deviceStatus = getDeviceRegistrationStatus();
    TEE_Result status = TEE_SUCCESS;
    do {
        if (TCI_DEVICE_REGISTERED == *deviceStatus) {
            // check ATTK exist in RPMB and is not corrupted
            TigerKeyPair_t* attk = tigerAllocateKeyPair();
            TIGER_CHECK_BUFFER_ALLOCATED_BREAK(attk);

            status = loadAttestationKey(attk, false);
            tigerFreeKeyPair(attk);
            if (TEE_SUCCESS != status) {
                LOG_E("Broken ATTK at RPMB, although device is registered.");
                *deviceStatus = TCI_DEVICE_ATTK_NOT_FOUND;
                status = TEE_SUCCESS;
                break;
            }
            // we do not need certificates anymore
            {
                TEE_Result status = TEE_SUCCESS;
                status = deletePersistentObject((const uint8_t*)TIGER_ATTK_CERT_ALIAS, strlen(TIGER_ATTK_CERT_ALIAS));
                logTeeError(status, "Deleting "TIGER_ATTK_CERT_ALIAS);
                status = deletePersistentObject((const uint8_t*)TIGER_DRK_CERT_ALIAS, strlen(TIGER_DRK_CERT_ALIAS));
                logTeeError(status, "Deleting "TIGER_DRK_CERT_ALIAS);
            }
        }

        if (TCI_DEVICE_NOT_REGISTERED == *deviceStatus) {
            // check if certificates needed for registration have been received already
            status = checkCertificate(TIGER_DRK_CERT_ALIAS);
            if ((TEE_ERROR_ITEM_NOT_FOUND == status) || (TEE_ERROR_CORRUPT_OBJECT == status)) {
                LOG_I("No DRK certificate.");
                *deviceStatus = TCI_DEVICE_ATTK_NOT_FOUND;
                status = TEE_SUCCESS;
                break;
            }
            TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Check DRK certificate");

            status = checkCertificate(TIGER_ATTK_CERT_ALIAS);
            if ((TEE_ERROR_ITEM_NOT_FOUND == status) || (TEE_ERROR_CORRUPT_OBJECT == status)) {
                LOG_I("No ATTK certificate.");
                *deviceStatus = TCI_DEVICE_ATTK_NOT_FOUND;
                status = TEE_SUCCESS;
                break;
            }
            TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Check ATTK certificate");
        }
    } while(0);

    LOG_FUNC_END;
    return status;
}

TEE_Result setRegistrationStatus(uint8_t type) {
    LOG_FUNC_BEGIN;

    LOG_D("type: 0x%02x", type);

    TzwSfsObject_t objHandle = TEE_HANDLE_NULL;
    TEE_Result status = TEE_SUCCESS;
    do {
        status = tzwOpenSfsObject((void*) TIGER_REGISTRATION_INFO_ALIAS, strlen(TIGER_REGISTRATION_INFO_ALIAS),
                                         TEE_DATA_FLAG_ACCESS_WRITE | TEE_DATA_FLAG_ACCESS_WRITE_META, &objHandle);
        LOG_D("status: %08x", status);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Open device id object");

        // if type == 0 remove stored device Id because update count exceed limitation
        // and we need to generate new device Id;
        if (0 == type) {
            LOG_I("Registration object will be removed by request from outside");
            tzwCloseAndDeleteSfsObject(objHandle);
            return TEE_SUCCESS;
        }

        // seek to registration status in device info file
        int32_t regCountOffset = getOffsetTo(REG_COUNT);
        TIGER_ASSERT(regCountOffset != -1);

        status = tzwSeekIntoSfsObject(objHandle, regCountOffset, TEE_DATA_SEEK_SET);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Seek to device registration count");

        status = tzwWriteToSfsObject(objHandle, &type, sizeof(type));
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Write to device id object");

        tzwCloseSfsObject(objHandle);
        objHandle = TEE_HANDLE_NULL;

        status = tigerSetCounter(1); // set initial counter value
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tigerSetCounter");

        //after registaration success, remove ATTK and DRK cert files.(don't need it any more)
        {
            TEE_Result status = TEE_SUCCESS;
            status = deletePersistentObject((const uint8_t*)TIGER_ATTK_CERT_ALIAS, strlen(TIGER_ATTK_CERT_ALIAS));
            logTeeError(status, "Deleting "TIGER_ATTK_CERT_ALIAS);
            status = deletePersistentObject((const uint8_t*)TIGER_DRK_CERT_ALIAS, strlen(TIGER_DRK_CERT_ALIAS));
            logTeeError(status, "Deleting "TIGER_DRK_CERT_ALIAS);
        }
    } while(0);
    tzwCloseSfsObject(objHandle);

    LOG_FUNC_END;
    return status;
}

TEE_Result loadDeviceId(uint8_t* deviceId, const uint32_t deviceIdLen) {
    LOG_FUNC_BEGIN;

    TIGER_ASSERT(deviceId != NULL);
    TIGER_ASSERT(deviceIdLen == DEVICE_ID_SIZE);

    TEE_Result status = TEE_SUCCESS;
#if defined(TIGER_BUILD_TESTS)
        status = fillTestDeviceId(deviceId, deviceIdLen);
#else
    TzwSfsObject_t objHandle = TEE_HANDLE_NULL;
    do {
        status = tzwOpenSfsObject((void*) TIGER_REGISTRATION_INFO_ALIAS, strlen(TIGER_REGISTRATION_INFO_ALIAS),
                                             TEE_DATA_FLAG_ACCESS_READ,
                                             &objHandle);
        TIGER_CHECK_TEE_STATUS_SUCCESS_RETURN("tzwOpenSfsObject");

        // seek to device id in registration info file
        // this is not required because device Id is at the beginning of the file: offset is 0
        int32_t deviceIdOffset = getOffsetTo(DEVICE_ID);
        TIGER_ASSERT(deviceIdOffset != -1);

        status = tzwSeekIntoSfsObject(objHandle, deviceIdOffset, TEE_DATA_SEEK_SET);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Seek to device id");

        uint32_t count = 0;
        status = tzwReadFromSfsObject(objHandle, deviceId, DEVICE_ID_SIZE, &count);
        if (count != DEVICE_ID_SIZE) {
            status = TEE_ERROR_CORRUPT_OBJECT;
            TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwReadFromSfsObject");
        }

    } while (0);
    tzwCloseSfsObject(objHandle);
#endif
    logByteArrayString(deviceId, deviceIdLen, "DeviceID");

    LOG_FUNC_END;
    return status;
}

TEE_Result signSskdsData(const uint8_t* data, size_t datalen, uint8_t* sig, uint32_t* siglen) {
    TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(data != NULL);
    TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(datalen != 0);
    TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(sig != NULL);
    TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(*siglen >= TIGER_RSA_SIGNATURE_PSS_LENGTH);

    logByteArrayString(data, datalen, "DATA2SIGN:");

    TEE_Result status = TEE_SUCCESS;
    TigerKeyPair_t* attk = NULL;
    do {
        attk = tigerAllocateKeyPair();
        TIGER_CHECK_BUFFER_ALLOCATED_BREAK(attk);

        status = loadAttestationKey(tigerGetKeyPairContext(attk), false);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("loadAttk");

        size_t signatureLength = 0;
        status = signDataWeChatServer(tigerGetKeyPairContext(attk), data, datalen, sig, &signatureLength);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("signDataWeChatServer");

        TIGER_CHECK_CONDITION_BREAK(signatureLength < UINT_MAX);

        *siglen = (uint32_t) signatureLength;
    } while (0);
    tigerFreeKeyPair(attk);

    return status;
}

TEE_Result getSskdsData(const TciSskdsGetData_t* const apRequest, TciExportedData_t* apResponse) {
    LOG_FUNC_BEGIN;
    TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(apRequest != NULL);
    TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(apResponse != NULL);

    TEE_Result status = TEE_ERROR_BAD_PARAMETERS;
    LOG_D("Exporting SSKDS Data Type: %d", apRequest->type);

    uint32_t szRead = MAX_EXPORT_SIZE_BYTES;

    switch (apRequest->type) {
    case SSKDS_GET_DATA_CERTIFICATE_DRK: {
        status = readFromPersistentObject(TIGER_DRK_CERT_ALIAS, apResponse->bytes, &szRead);
        break;
    }
    case SSKDS_GET_DATA_CERTIFICATE_ATTK: {
        status = readFromPersistentObject(TIGER_ATTK_CERT_ALIAS, apResponse->bytes, &szRead);
        break;
    }
    case SSKDS_GET_DATA_PUBLIC_KEY_ATTK: {
        /// TODO(o.kachkan): remove it by getting attk public from it's certificate in SskdsConnector.cpp
        // Check Attk exist.
        TigerKeyPair_t* attk = tigerAllocateKeyPair();
        TIGER_CHECK_BUFFER_ALLOCATED_BREAK(attk);

        status = loadAttestationKey(attk, false);
        if (TEE_SUCCESS != status) {
            LOG_I("No Attk at rpmb.");
            tigerFreeKeyPair(attk);
            break;
        }

        int ret = mbedtls_pk_write_pubkey_pem(tigerGetKeyPairContext(attk),
                                              (unsigned char*) apResponse->bytes, szRead);
        if (0 != ret) {
            logMbedtlsError(ret, "Could not write attk pem.");
            status = TEE_ERROR_CORRUPT_OBJECT;
        } else {
            logByteArrayString(apResponse->bytes, strlen((const char*) apResponse->bytes), "ATTK PUB");
            size_t currSzRead = strlen((const char*) apResponse->bytes);
            TIGER_CHECK_CONDITION_RETURN(currSzRead < UINT_MAX);

            szRead = (uint32_t) currSzRead;
        }
        tigerFreeKeyPair(attk);
        break;
    }
    default:
        LOG_E("Unknown sskds export request.");
        szRead = 0;
        break;
    }

#ifdef __DEV_DEBUG__
    logByteArrayBase64(apResponse->bytes, szRead, "CERTIFICATE");
#endif

    // set  correct export bufer len
    apResponse->size = szRead;
    LOG_FUNC_END;
    return status;
}
TEE_Result convertBytesToHex(const uint8_t* bytesIn, const uint32_t sizeIn, uint8_t* bytesOut, const uint32_t sizeOut) {
    TIGER_ASSERT(bytesIn != NULL);
    TIGER_ASSERT(bytesOut != NULL);
    TIGER_ASSERT(sizeOut == (sizeIn * 2));

    S_VAR_NOT_USED(sizeOut);

    char hexByte[BYTE_IN_HEX_LEN + 1];//make it C-string for snprintf
    for (size_t i = 0; i < sizeIn; ++i) {
        int ret = snprintf(hexByte, sizeof(hexByte), "%02x", bytesIn[i]);
        TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(ret == BYTE_IN_HEX_LEN);
        // copy to device id
        tzwMemMove(bytesOut + (BYTE_IN_HEX_LEN * i), hexByte, BYTE_IN_HEX_LEN);
    }
    return TEE_SUCCESS;
}

// internal helper-functions.
static TEE_Result signDataWeChatServer(mbedtls_pk_context* devkey, const uint8_t* data, size_t len, uint8_t* signature,
        size_t* siglen) {
    LOG_FUNC_BEGIN;

    TEE_Result status = TEE_SUCCESS;
    TzwHashOperation_t digestOperation = TEE_HANDLE_NULL;
    do {
        status = tzwAllocateHashOperation(&digestOperation, TEE_ALG_SHA256);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwAllocateHashOperation");

        uint8_t hash[TIGER_SHA256_HASH_LENGTH] = { 0 };
        size_t hashLen = sizeof(hash);
        uint8_t deviceId[DEVICE_ID_SIZE];
        status = loadDeviceId(deviceId, DEVICE_ID_SIZE);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("loadDeviceId");
        logByteArrayHex(deviceId, DEVICE_ID_SIZE, "DEVICE_ID");
        logByteArrayHex(data, len, "ATTK_PUB");

        status = tzwHashUpdate(digestOperation, deviceId, DEVICE_ID_SIZE);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwHashUpdate");

        status = tzwHashFinalize(digestOperation, (void*) data, len, hash, &hashLen);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwHashFinalize");

        mbedtls_rsa_context* ctx = mbedtls_pk_rsa(*devkey);
        mbedtls_rsa_set_padding(ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
        //[a.orlenko] CURRENT: default salt length for registration
        int ret = mbedtls_rsa_rsassa_pss_sign(ctx, tigerMbedtlsRng, NULL,
                MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256, hashLen, hash, signature);
        TIGER_CHECK_MBEDTLS_RET_ZERO_BREAK("mbedtls_rsa_rsassa_pss_sign")
        *siglen = TIGER_RSA_SIGNATURE_PSS_LENGTH;

        logByteArrayBase64(signature, *siglen, "Signature");
        status = TEE_SUCCESS;
    } while (0);

    tzwFreeHashOperation(digestOperation);

    LOG_FUNC_END;
    return status;
}

TEE_Result generateDeviceId(const uint32_t chipId, uint8_t* deviceId, const uint32_t deviceIdLen) {
    LOG_FUNC_BEGIN;

    TEE_Result status = TEE_SUCCESS;
#ifdef TIGER_BUILD_TESTS
    status = fillTestDeviceId(deviceId, deviceIdLen);
    S_VAR_NOT_USED(chipId);
#else
    status = fillDeviceId(deviceId, deviceIdLen, chipId);
#endif

    LOG_FUNC_END;
    return status;
}

TEE_Result storeDeviceId(uint8_t* deviceId, const size_t devIdSize) {
    LOG_FUNC_BEGIN;

    TEE_Result status = TEE_SUCCESS;
    TzwSfsObject_t objHandle = TEE_HANDLE_NULL;

    do {
        status = tzwCreateSfsObject((void*) TIGER_REGISTRATION_INFO_ALIAS, strlen(TIGER_REGISTRATION_INFO_ALIAS),
                TEE_DATA_FLAG_ACCESS_WRITE | TEE_DATA_FLAG_ACCESS_WRITE_META,
                &objHandle);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwCreateSfsObject");

        logByteArrayString(deviceId, devIdSize, "GENERATED DEV ID");

        // store new device id
        status = tzwWriteToSfsObject(objHandle, deviceId, devIdSize);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwWriteToSfsObject");

        // set this device id to 'unregistered', i.e. number of registrations == 0
        uint8_t registrationNumber = 0;
        status = tzwWriteToSfsObject(objHandle, &registrationNumber, sizeof(registrationNumber));
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwWriteToSfsObject");
    } while (0);

    tzwCloseSfsObject(objHandle);

    LOG_FUNC_END;
    return status;
}

TEE_Result fillDeviceId(uint8_t* deviceId, const size_t devIdSize, const uint32_t chipId) {
    LOG_FUNC_BEGIN;

    TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(deviceId != NULL);
    TIGER_CHECK_FUNCTION_ARGUMENT_RETURN(devIdSize == DEVICE_ID_SIZE);

    uint8_t uniqueId [UNIQUE_ID_SIZE] = {0};
    uint8_t* pUuniq = uniqueId;

    // 1.bytes 0-3: Identify each silicon provider id, defined by WeChat
    const uint32_t siliconProviderCode = SILICON_PROVIDER_ID;
    tzwMemMove(pUuniq, &siliconProviderCode, sizeof(siliconProviderCode));
    pUuniq += sizeof(siliconProviderCode);

    // 2.bytes 4-7: SoC model ID, defined by each silicon provider（like Qualcomm and Trustonic）. Example: MSM8996
    tzwMemMove(pUuniq, &chipId, sizeof(chipId));
    pUuniq += sizeof(chipId);

    // 3.bytes 8-15: Public Chip Serial *Number of SoC, defined by each silicon provider（like Qualcomm and Trustonic）
    TzwSerialNumber_t realSerial = {0,};
    TEE_Result status = tzwReadSerialNumber(&realSerial);
    TIGER_CHECK_TEE_STATUS_SUCCESS_RETURN("tzwReadSerialNumber");

    size_t realSerialSize = realSerial.size;
    tzwMemMove(pUuniq, &realSerial, realSerialSize);
    pUuniq += realSerialSize;
    /*LOG_D("Real serial number %"PRId32", size: %u", realSerial->uuid, realSerialSize);*/

    // -
    // - Type 'int' is 32 bits is 4 bytes length, just add random data to fill up to 8 bytes,
    // - Code below guarantee that serial number is 8 bytes.
    // -
    LOG_D("realSerialSize = %zd", realSerialSize);

    /*size_t bytesLeft = sizeof(uint64_t) - realSerialSize;*/
    size_t bytesLeft = UNIQUE_ID_SIZE - (pUuniq - uniqueId);
    LOG_D("bytesLeft: 0x%08zx", bytesLeft);
    if (bytesLeft > 0) {
        LOG_D("Filling %zu bytes", bytesLeft);
        tzwGenerateRandom(pUuniq, bytesLeft);
        pUuniq += bytesLeft;
    }

    // Convert to HEX make it human-readable.
    convertBytesToHex(uniqueId, UNIQUE_ID_SIZE, deviceId, DEVICE_ID_SIZE);
    TIGER_CHECK_TEE_STATUS_SUCCESS_RETURN("convertBytesToHex");

    logByteArrayString(deviceId, devIdSize, "DeviceID");

    LOG_FUNC_END;

    return TEE_SUCCESS;
}

/**
 * @brief clearSFSfiles: clear all sfs files for failing registration.
 * @return
 */
TEE_Result clearSFSfiles() {
    LOG_FUNC_BEGIN;
    TEE_Result status = TEE_SUCCESS;
    TzwSfsObjectList_t objectEnumerator = TEE_HANDLE_NULL;
    do {
        status = tzwAllocateSfsObjectList(&objectEnumerator);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwAllocateSfsObjectList failure.")

        status = tzwStartSfsObjectList(objectEnumerator);
        if (TEE_ERROR_ITEM_NOT_FOUND == status) {
            LOG_D("No object in the storage");
            break;
        }
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("tzwStartSfsObjectList failure.")

        uint8_t objectId[MAX_OBJ_ID_SIZE_BYTES] = {0};
        uint32_t objectIdLen = 0;
        while (TEE_ERROR_ITEM_NOT_FOUND != tzwGetNextSfsObject(objectEnumerator, objectId, &objectIdLen)) {
            LOG_D("Delete object: %.*s", objectIdLen, objectId);
            status = deletePersistentObject(objectId, objectIdLen);
            TIGER_CHECK_TEE_STATUS_SUCCESS_CONTINUE("deletePersistentObject");
        }
    } while(0);

    tzwFreeSfsObjectList(objectEnumerator);

    LOG_FUNC_END;
    return status;
}

TciDeviceStatus_t getDeviceRegistrationStatus() {
    TciDeviceStatus_t regStatus = TCI_DEVICE_NOT_REGISTERED;
    TzwSfsObject_t objHandle = TEE_HANDLE_NULL;
    TEE_Result status = TEE_ERROR_GENERIC;
    do {
        status = tzwOpenSfsObject((void*) TIGER_REGISTRATION_INFO_ALIAS, strlen(TIGER_REGISTRATION_INFO_ALIAS),
                                    TEE_DATA_FLAG_ACCESS_READ, &objHandle);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Open device id object");

        // seek to device id in registration info file
        // this is not required because device Id is at the beginning of the file: offset is 0
        int32_t regCountOffset = getOffsetTo(REG_COUNT);
        TIGER_ASSERT(regCountOffset != -1);

        status = tzwSeekIntoSfsObject(objHandle, regCountOffset, TEE_DATA_SEEK_SET);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Seek to device id");

        uint8_t loadedRegStatus = 0;
        uint32_t count = 0;
        status = tzwReadFromSfsObject(objHandle, &loadedRegStatus, sizeof(loadedRegStatus), &count);
        TIGER_CHECK_TEE_STATUS_SUCCESS_BREAK("Read from device id object");
        if (count != sizeof(loadedRegStatus)) {
            // this may happen for devices with old version of TA
            LOG_I("Could not read nb of registrations.");
        }

        LOG_I("Loaded registration status: %d", loadedRegStatus);
        if (loadedRegStatus > 0) {// 0 - not registered, >0 registered.
            regStatus = TCI_DEVICE_REGISTERED;
        }
    } while(0);

    tzwCloseSfsObject(objHandle);
    initFPTable();

    return regStatus;
}

TEE_Result checkCertificate(const char *alias) {
    TIGER_ASSERT(0 != strlen(alias));

    LOG_D("Checking %s file", alias);

    TzwSfsObject_t objHandle = TEE_HANDLE_NULL;
    TEE_Result status = tzwOpenSfsObject((void*) alias, strlen(alias), TEE_DATA_FLAG_ACCESS_READ, &objHandle);
    tzwCloseSfsObject(objHandle);

    return status;
}

