#include "knoxai_io_datatypes.h"
#include "knoxai_logger.h"

#include "mcSo.h"                 // MC_SO_*
#include "TlApi/TlApiError.h"     // TLAPI_OK, tlApiResult_t; 
#include "TlApi/TlApiSecurity.h"  // tlApiWrapObject, tlApiUnwrapObject

uint32_t knoxai_unwrap(TEE_UUID target_uuid, uint8_t *blob_ptr, uint32_t blob_len, uint8_t *dest_ptr, uint32_t* dest_len){
    tz_knoxai_return_type   ret = KNOXAI_FAILURE;
    unsigned int           unwrap_ret;

    if ( blob_ptr == NULL || dest_ptr == NULL || dest_len == NULL || *dest_len < SO_LOCAL_HEADERSIZE ) {
        KNOXAI_DEBUG_LOG("unwrap ptr must be NOT NULL");
        ret = KNOXAI_FAILURE;
        goto exit;
    }
    unwrap_ret = tlApiUnwrapObject(blob_ptr, blob_len, dest_ptr, dest_len, 
            TLAPI_UNWRAP_PERMIT_DELEGATED | TLAPI_UNWRAP_DEFAULT);
    if (unwrap_ret != TEE_SUCCESS) {
        KNOXAI_DEBUG_LOG("knoxai_unwrap unwrap failed with ret=0x%08X, exit", unwrap_ret);
        ret = KNOXAI_FAILURE;
        goto exit;
    }/*
    if (*dest_len < KNOXAI_FAC_KEY_LEN || *dest_len > MAX_WRAPPED_KEY_LEN) {
        KNOXAI_DEBUG_LOG("knoxai_unwrap: Key Bigger than space");
        ret = KNOXAI_FAILURE;
        goto exit;
    }*/
    ret = KNOXAI_SUCCESS;
exit:
    return ret;
}

uint32_t knoxai_wrap(TEE_UUID target_uuid, uint8_t *blob_ptr, uint32_t blob_len, uint8_t *dest_ptr, uint32_t* dest_len){
    tz_knoxai_return_type  ret = KNOXAI_FAILURE;
    unsigned int          wrap_ret;

    if ( blob_ptr == NULL || dest_ptr == NULL || blob_len == 0 || *dest_len < MC_SO_SIZE(0, blob_len) ) {
        KNOXAI_DEBUG_LOG("wrap ptr must be NOT NULL");
        ret = KNOXAI_FAILURE;
        goto exit;
    }
    wrap_ret = tlApiWrapObject(blob_ptr, 0, blob_len, dest_ptr, dest_len,
            MC_SO_CONTEXT_TLT, MC_SO_LIFETIME_PERMANENT, NULL, TLAPI_WRAP_DEFAULT);
    if (wrap_ret != TEE_SUCCESS) {
        KNOXAI_DEBUG_LOG("knoxai_wrap wrap failed with ret=0x%08X, exit", wrap_ret);
        ret = KNOXAI_FAILURE;
        goto exit;
    }
    /*if (*dest_len < KNOXAI_FAC_KEY_LEN || *dest_len > MAX_WRAPPED_KEY_LEN) {
        KNOXAI_DEBUG_LOG("knoxai_wrap: Key Bigger than space");
        ret = KNOXAI_FAILURE;
        goto exit;
    }*/
    ret = KNOXAI_SUCCESS;
exit:
    return ret;
}

size_t kinibi_strnlen(const char *s, size_t count) {
    const char *sc;
    for (sc = s; count-- && *sc != '\0'; ++sc) 
        ; /* nothing */
    return sc - s;
}

// GP API impl
#include "TlApi/TlApiHeap.h"
void* TEE_Malloc(uint32_t size, uint32_t hint){
    return tlApiMalloc(size, hint);
}
void TEE_Free(void *buffer) {
    tlApiFree(buffer);
}

void TEE_MemMove(void* dest, void* src, uint32_t size) {
    memcpy(dest, src, size);
}
int32_t TEE_MemCompare(void* buffer1, void* buffer2, uint32_t size) {
    return memcmp(buffer1, buffer2, size);
}
void TEE_MemFill(void* buffer, uint32_t x, uint32_t size ) {
    memset(buffer, x, size);
}

