// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <arpa/inet.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include <fuchsia/hardware/tee/c/fidl.h>
#include <fuchsia/tee/c/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>

#include <tee-client-api/tee_client_api.h>

#define TEE_DEV_CLASS "/dev/class/tee/"
#define TEE_SERVICE_PATH "/svc/fuchsia.tee.Device"

#define GET_PARAM_TYPE_FOR_INDEX(param_types, index) \
    ((param_types >> (4 * index)) & 0xF)

static inline bool is_shared_mem_flag_inout(uint32_t flags) {
    const uint32_t inout_flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
    return (flags & inout_flags) == inout_flags;
}

static inline bool is_direction_input(fuchsia_tee_Direction direction) {
    return ((direction == fuchsia_tee_Direction_INPUT) ||
            (direction == fuchsia_tee_Direction_INOUT));
}

static inline bool is_direction_output(fuchsia_tee_Direction direction) {
    return ((direction == fuchsia_tee_Direction_OUTPUT) ||
            (direction == fuchsia_tee_Direction_INOUT));
}

static bool is_global_platform_compliant(zx_handle_t tee_channel) {
    fuchsia_tee_OsInfo os_info;
    zx_status_t status = fuchsia_tee_DeviceGetOsInfo(tee_channel, &os_info);

    return status == ZX_OK ? os_info.is_global_platform_compliant : false;
}

static void convert_teec_uuid_to_zx_uuid(const TEEC_UUID* teec_uuid,
                                         fuchsia_tee_Uuid* out_uuid) {
    ZX_DEBUG_ASSERT(teec_uuid);
    ZX_DEBUG_ASSERT(out_uuid);
    out_uuid->time_low = teec_uuid->timeLow;
    out_uuid->time_mid = teec_uuid->timeMid;
    out_uuid->time_hi_and_version = teec_uuid->timeHiAndVersion;
    memcpy(out_uuid->clock_seq_and_node, teec_uuid->clockSeqAndNode,
           sizeof(out_uuid->clock_seq_and_node));
}

static TEEC_Result convert_status_to_result(zx_status_t status) {
    switch (status) {
    case ZX_ERR_PEER_CLOSED:
        return TEEC_ERROR_COMMUNICATION;
    case ZX_ERR_INVALID_ARGS:
        return TEEC_ERROR_BAD_PARAMETERS;
    case ZX_ERR_NOT_SUPPORTED:
        return TEEC_ERROR_NOT_SUPPORTED;
    case ZX_ERR_NO_MEMORY:
        return TEEC_ERROR_OUT_OF_MEMORY;
    case ZX_OK:
        return TEEC_SUCCESS;
    }
    return TEEC_ERROR_GENERIC;
}

static uint32_t convert_zx_to_teec_return_origin(fuchsia_tee_ReturnOrigin return_origin) {
    switch (return_origin) {
    case fuchsia_tee_ReturnOrigin_COMMUNICATION:
        return TEEC_ORIGIN_COMMS;
    case fuchsia_tee_ReturnOrigin_TRUSTED_OS:
        return TEEC_ORIGIN_TEE;
    case fuchsia_tee_ReturnOrigin_TRUSTED_APPLICATION:
        return TEEC_ORIGIN_TRUSTED_APP;
    default:
        return TEEC_ORIGIN_API;
    }
}

static void close_all_vmos(const fuchsia_tee_ParameterSet* parameter_set) {
    ZX_DEBUG_ASSERT(parameter_set);

    for (size_t i = 0; i < parameter_set->count; i++) {
        const fuchsia_tee_Parameter* param = &parameter_set->parameters[i];
        if (param->tag == fuchsia_tee_ParameterTag_buffer) {
            zx_handle_close(param->buffer.vmo);
        }
    }
}

static void preprocess_value(uint32_t param_type, const TEEC_Value* teec_value,
                             fuchsia_tee_Parameter* out_zx_param) {
    ZX_DEBUG_ASSERT(teec_value);
    ZX_DEBUG_ASSERT(out_zx_param);

    fuchsia_tee_Direction direction = 0;
    switch (param_type) {
    case TEEC_VALUE_INPUT:
        direction = fuchsia_tee_Direction_INPUT;
        break;
    case TEEC_VALUE_OUTPUT:
        direction = fuchsia_tee_Direction_OUTPUT;
        break;
    case TEEC_VALUE_INOUT:
        direction = fuchsia_tee_Direction_INOUT;
        break;
    default:
        ZX_PANIC("Unknown param type");
    }

    out_zx_param->tag = fuchsia_tee_ParameterTag_value;
    out_zx_param->value.direction = direction;
    if (is_direction_input(direction)) {
        // The TEEC_Value type only includes two generic fields, whereas the Fuchsia TEE interface
        // supports three. The c field cannot be used by the TEE Client API.
        out_zx_param->value.a = teec_value->a;
        out_zx_param->value.b = teec_value->b;
        out_zx_param->value.c = 0;
    }
}

static TEEC_Result preprocess_temporary_memref(uint32_t param_type,
                                               const TEEC_TempMemoryReference* temp_memory_ref,
                                               fuchsia_tee_Parameter* out_zx_param) {
    ZX_DEBUG_ASSERT(temp_memory_ref);
    ZX_DEBUG_ASSERT(out_zx_param);

    fuchsia_tee_Direction direction;
    switch (param_type) {
    case TEEC_MEMREF_TEMP_INPUT:
        direction = fuchsia_tee_Direction_INPUT;
        break;
    case TEEC_MEMREF_TEMP_OUTPUT:
        direction = fuchsia_tee_Direction_OUTPUT;
        break;
    case TEEC_MEMREF_TEMP_INOUT:
        direction = fuchsia_tee_Direction_INOUT;
        break;
    default:
        ZX_PANIC("TEE Client API Unknown parameter type\n");
    }

    zx_handle_t vmo;

    if (!temp_memory_ref->buffer) {
        // A null buffer marked as output is a valid request to determine the necessary size of the
        // output buffer. It is an error for any sort of input.
        if (is_direction_input(direction)) {
            return TEEC_ERROR_BAD_PARAMETERS;
        }
        vmo = ZX_HANDLE_INVALID;
    } else {
        // We either have data to input or have a buffer to output data to, so create a VMO for it.
        zx_status_t status = zx_vmo_create(temp_memory_ref->size, 0, &vmo);
        if (status != ZX_OK) {
            return convert_status_to_result(status);
        }

        // If the memory reference is used as an input, then we must copy the data from the user
        // provided buffer into the VMO. There is no need to do this for parameters that are output
        // only.
        if (is_direction_input(direction)) {
            status = zx_vmo_write(vmo, temp_memory_ref->buffer, 0, temp_memory_ref->size);
            if (status != ZX_OK) {
                zx_handle_close(vmo);
                return convert_status_to_result(status);
            }
        }
    }

    out_zx_param->tag = fuchsia_tee_ParameterTag_buffer;
    out_zx_param->buffer.direction = direction;
    out_zx_param->buffer.vmo = vmo;
    out_zx_param->buffer.offset = 0;
    out_zx_param->buffer.size = temp_memory_ref->size;
    return TEEC_SUCCESS;
}

static TEEC_Result preprocess_whole_memref(const TEEC_RegisteredMemoryReference* memory_ref,
                                           fuchsia_tee_Parameter* out_zx_param) {
    ZX_DEBUG_ASSERT(memory_ref);
    ZX_DEBUG_ASSERT(out_zx_param);

    if (!memory_ref->parent) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    TEEC_SharedMemory* shared_mem = memory_ref->parent;
    fuchsia_tee_Direction direction;
    if (is_shared_mem_flag_inout(shared_mem->flags)) {
        direction = fuchsia_tee_Direction_INOUT;
    } else if (shared_mem->flags & TEEC_MEM_INPUT) {
        direction = fuchsia_tee_Direction_INPUT;
    } else if (shared_mem->flags & TEEC_MEM_OUTPUT) {
        direction = fuchsia_tee_Direction_OUTPUT;
    } else {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    zx_handle_t vmo;
    zx_status_t status = zx_handle_duplicate(shared_mem->imp.vmo, ZX_RIGHT_SAME_RIGHTS, &vmo);
    if (status != ZX_OK) {
        return convert_status_to_result(status);
    }

    out_zx_param->tag = fuchsia_tee_ParameterTag_buffer;
    out_zx_param->buffer.direction = direction;
    out_zx_param->buffer.vmo = vmo;
    out_zx_param->buffer.offset = 0;
    out_zx_param->buffer.size = shared_mem->size;

    return TEEC_SUCCESS;
}

static TEEC_Result preprocess_partial_memref(uint32_t param_type,
                                             const TEEC_RegisteredMemoryReference* memory_ref,
                                             fuchsia_tee_Parameter* out_zx_param) {
    ZX_DEBUG_ASSERT(memory_ref);
    ZX_DEBUG_ASSERT(out_zx_param);

    if (!memory_ref->parent) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    uint32_t expected_shm_flags = 0;
    fuchsia_tee_Direction direction = 0;
    switch (param_type) {
    case TEEC_MEMREF_PARTIAL_INPUT:
        expected_shm_flags = TEEC_MEM_INPUT;
        direction = fuchsia_tee_Direction_INPUT;
        break;
    case TEEC_MEMREF_PARTIAL_OUTPUT:
        expected_shm_flags = TEEC_MEM_OUTPUT;
        direction = fuchsia_tee_Direction_OUTPUT;
        break;
    case TEEC_MEMREF_PARTIAL_INOUT:
        expected_shm_flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
        direction = fuchsia_tee_Direction_INOUT;
        break;
    default:
        ZX_DEBUG_ASSERT(param_type == TEEC_MEMREF_PARTIAL_INPUT ||
                        param_type == TEEC_MEMREF_PARTIAL_OUTPUT ||
                        param_type == TEEC_MEMREF_PARTIAL_INOUT);
    }

    TEEC_SharedMemory* shared_mem = memory_ref->parent;

    if ((shared_mem->flags & expected_shm_flags) != expected_shm_flags) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    zx_handle_t vmo;
    zx_status_t status = zx_handle_duplicate(shared_mem->imp.vmo, ZX_RIGHT_SAME_RIGHTS, &vmo);
    if (status != ZX_OK) {
        return convert_status_to_result(status);
    }

    out_zx_param->tag = fuchsia_tee_ParameterTag_buffer;
    out_zx_param->buffer.direction = direction;
    out_zx_param->buffer.vmo = vmo;
    out_zx_param->buffer.offset = memory_ref->offset;
    out_zx_param->buffer.size = memory_ref->size;

    return TEEC_SUCCESS;
}

static TEEC_Result preprocess_operation(const TEEC_Operation* operation,
                                        fuchsia_tee_ParameterSet* out_parameter_set) {
    if (!operation) {
        return TEEC_SUCCESS;
    }

    TEEC_Result rc = TEEC_SUCCESS;
    for (size_t i = 0; i < TEEC_NUM_PARAMS_MAX; i++) {
        uint32_t param_type = GET_PARAM_TYPE_FOR_INDEX(operation->paramTypes, i);

        switch (param_type) {
        case TEEC_NONE:
            out_parameter_set->parameters[i].tag = fuchsia_tee_ParameterTag_empty;
            break;
        case TEEC_VALUE_INPUT:
        case TEEC_VALUE_OUTPUT:
        case TEEC_VALUE_INOUT:
            preprocess_value(param_type, &operation->params[i].value,
                             &out_parameter_set->parameters[i]);
            break;
        case TEEC_MEMREF_TEMP_INPUT:
        case TEEC_MEMREF_TEMP_OUTPUT:
        case TEEC_MEMREF_TEMP_INOUT:
            rc = preprocess_temporary_memref(param_type, &operation->params[i].tmpref,
                                             &out_parameter_set->parameters[i]);
            break;
        case TEEC_MEMREF_WHOLE:
            rc = preprocess_whole_memref(&operation->params[i].memref,
                                         &out_parameter_set->parameters[i]);
            break;
        case TEEC_MEMREF_PARTIAL_INPUT:
        case TEEC_MEMREF_PARTIAL_OUTPUT:
        case TEEC_MEMREF_PARTIAL_INOUT:
            rc = preprocess_partial_memref(param_type, &operation->params[i].memref,
                                           &out_parameter_set->parameters[i]);
            break;
        default:
            rc = TEEC_ERROR_BAD_PARAMETERS;
            break;
        }

        if (rc != TEEC_SUCCESS) {
            // Close out any VMOs we already opened for the parameters we did parse
            close_all_vmos(out_parameter_set);
            return rc;
        }
    }

    out_parameter_set->count = TEEC_NUM_PARAMS_MAX;

    return rc;
}

static TEEC_Result postprocess_value(uint32_t param_type,
                                     const fuchsia_tee_Parameter* zx_param,
                                     TEEC_Value* out_teec_value) {
    ZX_DEBUG_ASSERT(zx_param);
    ZX_DEBUG_ASSERT(out_teec_value);
    ZX_DEBUG_ASSERT(param_type == TEEC_VALUE_INPUT ||
                    param_type == TEEC_VALUE_OUTPUT ||
                    param_type == TEEC_VALUE_INOUT);

    if (zx_param->tag != fuchsia_tee_ParameterTag_value) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    const fuchsia_tee_Value* zx_value = &zx_param->value;

    // Validate that the direction of the returned parameter matches the expected.
    if ((param_type == TEEC_VALUE_INPUT) &&
        (zx_value->direction != fuchsia_tee_Direction_INPUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }
    if ((param_type == TEEC_VALUE_OUTPUT) &&
        (zx_value->direction != fuchsia_tee_Direction_OUTPUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }
    if ((param_type == TEEC_VALUE_INOUT) &&
        (zx_value->direction != fuchsia_tee_Direction_INOUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    // The TEEC_Value type only includes two generic fields, whereas the Fuchsia TEE interface
    // supports three. The c field cannot be used by the TEE Client API.
    out_teec_value->a = zx_value->a;
    out_teec_value->b = zx_value->b;
    return TEEC_SUCCESS;
}

static TEEC_Result postprocess_temporary_memref(uint32_t param_type,
                                                const fuchsia_tee_Parameter* zx_param,
                                                TEEC_TempMemoryReference* out_temp_memory_ref) {
    ZX_DEBUG_ASSERT(zx_param);
    ZX_DEBUG_ASSERT(out_temp_memory_ref);
    ZX_DEBUG_ASSERT(param_type == TEEC_MEMREF_TEMP_INPUT ||
                    param_type == TEEC_MEMREF_TEMP_OUTPUT ||
                    param_type == TEEC_MEMREF_TEMP_INOUT);

    if (zx_param->tag != fuchsia_tee_ParameterTag_buffer) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    const fuchsia_tee_Buffer* zx_buffer = &zx_param->buffer;

    if ((param_type == TEEC_MEMREF_TEMP_INPUT) &&
        (zx_buffer->direction != fuchsia_tee_Direction_INPUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }
    if ((param_type == TEEC_MEMREF_TEMP_OUTPUT) &&
        (zx_buffer->direction != fuchsia_tee_Direction_OUTPUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }
    if ((param_type == TEEC_MEMREF_TEMP_INOUT) &&
        (zx_buffer->direction != fuchsia_tee_Direction_INOUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    TEEC_Result rc = TEEC_SUCCESS;
    if (is_direction_output(zx_buffer->direction)) {
        // For output buffers, if we don't have enough space in the temporary memory reference to
        // copy the data out, we still need to update the size to indicate to the user how large of
        // a buffer they need to perform the requested operation.
        if (out_temp_memory_ref->buffer && out_temp_memory_ref->size >= zx_buffer->size) {
            zx_status_t status = zx_vmo_read(zx_buffer->vmo,
                                             out_temp_memory_ref->buffer,
                                             zx_buffer->offset,
                                             zx_buffer->size);
            rc = convert_status_to_result(status);
        }
        out_temp_memory_ref->size = zx_buffer->size;
    }

    return rc;
}

static TEEC_Result postprocess_whole_memref(const fuchsia_tee_Parameter* zx_param,
                                            TEEC_RegisteredMemoryReference* out_memory_ref) {
    ZX_DEBUG_ASSERT(zx_param);
    ZX_DEBUG_ASSERT(out_memory_ref);
    ZX_DEBUG_ASSERT(out_memory_ref->parent);

    if (zx_param->tag != fuchsia_tee_ParameterTag_buffer) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    const fuchsia_tee_Buffer* zx_buffer = &zx_param->buffer;

    if (is_direction_output(zx_buffer->direction)) {
        out_memory_ref->size = zx_buffer->size;
    }

    return TEEC_SUCCESS;
}

static TEEC_Result postprocess_partial_memref(uint32_t param_type,
                                              const fuchsia_tee_Parameter* zx_param,
                                              TEEC_RegisteredMemoryReference* out_memory_ref) {
    ZX_DEBUG_ASSERT(zx_param);
    ZX_DEBUG_ASSERT(out_memory_ref);
    ZX_DEBUG_ASSERT(param_type == TEEC_MEMREF_PARTIAL_INPUT ||
                    param_type == TEEC_MEMREF_PARTIAL_OUTPUT ||
                    param_type == TEEC_MEMREF_PARTIAL_INOUT);

    if (zx_param->tag != fuchsia_tee_ParameterTag_buffer) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    const fuchsia_tee_Buffer* zx_buffer = &zx_param->buffer;

    if ((param_type == TEEC_MEMREF_PARTIAL_INPUT) &&
        (zx_buffer->direction != fuchsia_tee_Direction_INPUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }
    if ((param_type == TEEC_MEMREF_PARTIAL_OUTPUT) &&
        (zx_buffer->direction != fuchsia_tee_Direction_OUTPUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }
    if ((param_type == TEEC_MEMREF_PARTIAL_INOUT) &&
        (zx_buffer->direction != fuchsia_tee_Direction_INOUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    if (is_direction_output(zx_buffer->direction)) {
        out_memory_ref->size = zx_buffer->size;
    }

    return TEEC_SUCCESS;
}

static TEEC_Result postprocess_operation(const fuchsia_tee_ParameterSet* parameter_set,
                                         TEEC_Operation* out_operation) {

    if (!out_operation) {
        return TEEC_SUCCESS;
    }

    TEEC_Result rc = TEEC_SUCCESS;
    for (size_t i = 0; i < TEEC_NUM_PARAMS_MAX; i++) {
        uint32_t param_type = GET_PARAM_TYPE_FOR_INDEX(out_operation->paramTypes, i);

        // This check catches the case where we did not receive all the parameters back that we
        // expected. Once in_param_index hits the parameter_set count, we've parsed all the
        // parameters that came back.
        if (i >= parameter_set->count) {
            rc = TEEC_ERROR_BAD_PARAMETERS;
            break;
        }

        switch (param_type) {
        case TEEC_NONE:
            if (parameter_set->parameters[i].tag != fuchsia_tee_ParameterTag_empty) {
                rc = TEEC_ERROR_BAD_PARAMETERS;
            }
            break;
        case TEEC_VALUE_INPUT:
        case TEEC_VALUE_OUTPUT:
        case TEEC_VALUE_INOUT:
            rc = postprocess_value(param_type, &parameter_set->parameters[i],
                                   &out_operation->params[i].value);
            break;
        case TEEC_MEMREF_TEMP_INPUT:
        case TEEC_MEMREF_TEMP_OUTPUT:
        case TEEC_MEMREF_TEMP_INOUT:
            rc = postprocess_temporary_memref(param_type, &parameter_set->parameters[i],
                                              &out_operation->params[i].tmpref);
            break;
        case TEEC_MEMREF_WHOLE:
            rc = postprocess_whole_memref(&parameter_set->parameters[i],
                                          &out_operation->params[i].memref);
            break;
        case TEEC_MEMREF_PARTIAL_INPUT:
        case TEEC_MEMREF_PARTIAL_OUTPUT:
        case TEEC_MEMREF_PARTIAL_INOUT:
            rc = postprocess_partial_memref(param_type, &parameter_set->parameters[i],
                                            &out_operation->params[i].memref);
            break;
        default:
            rc = TEEC_ERROR_BAD_PARAMETERS;
        }

        if (rc != TEEC_SUCCESS) {
            break;
        }
    }

    close_all_vmos(parameter_set);

    return rc;
}

static zx_status_t connect_service(zx_handle_t* tee_channel) {
    ZX_DEBUG_ASSERT(tee_channel);

    zx_handle_t client_channel;
    zx_handle_t server_channel;
    zx_status_t status = zx_channel_create(0, &client_channel, &server_channel);
    if (status != ZX_OK) {
        return status;
    }

    status = fdio_service_connect(TEE_SERVICE_PATH, server_channel);
    if (status != ZX_OK) {
        zx_handle_close(client_channel);
        return status;
    }

    *tee_channel = client_channel;
    return ZX_OK;
}

// Connects the client directly to the TEE Driver.
//
// This is a temporary measure to allow clients that come up before component services to still
// access the TEE. This requires that the client has access to the TEE device class. Additionally,
// the client's entire context will not have any filesystem support, so if the client sends a
// command to a trusted application that then needs persistent storage to complete, the persistent
// storage request will be rejected by the driver.
static zx_status_t connect_driver(const char* tee_device, zx_handle_t* tee_channel) {
    ZX_DEBUG_ASSERT(tee_device);
    ZX_DEBUG_ASSERT(tee_channel);

    int fd = open(tee_device, O_RDWR);
    if (fd < 0) {
        return ZX_ERR_NOT_FOUND;
    }

    zx_handle_t connector_channel;
    zx_status_t status = fdio_get_service_handle(fd, &connector_channel);
    if (status != ZX_OK) {
        return status;
    }

    zx_handle_t client_channel;
    zx_handle_t server_channel;
    status = zx_channel_create(0, &client_channel, &server_channel);
    if (status != ZX_OK) {
        zx_handle_close(connector_channel);
        return status;
    }

    // Connect to the device interface with no supporting service provider
    status = fuchsia_hardware_tee_DeviceConnectorConnectTee(connector_channel,
                                                            ZX_HANDLE_INVALID,
                                                            server_channel);

    // Close the connector channel regardless of FIDL call success. It has served its purpose.
    zx_handle_close(connector_channel);

    if (status != ZX_OK) {
        zx_handle_close(client_channel);
        return status;
    }

    *tee_channel = client_channel;
    return ZX_OK;
}

TEEC_Result TEEC_InitializeContext(const char* name, TEEC_Context* context) {

    if (!context) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    zx_status_t status;
    zx_handle_t tee_channel;
    if (!name || strcmp(TEE_SERVICE_PATH, name) == 0) {
        status = connect_service(&tee_channel);
        if (status != ZX_OK) {
            return TEEC_ERROR_COMMUNICATION;
        }
    } else if (strncmp(TEE_DEV_CLASS, name, strlen(TEE_DEV_CLASS)) == 0) {
        // The client has specified a direct connection to some TEE device
        // See comments on `connect_driver()` for details.
        status = connect_driver(name, &tee_channel);
        if (status != ZX_OK) {
            if (status == ZX_ERR_NOT_FOUND) {
                return TEEC_ERROR_ITEM_NOT_FOUND;
            } else {
                return TEEC_ERROR_COMMUNICATION;
            }
        }
    } else {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    if (!is_global_platform_compliant(tee_channel)) {
        // This API is only designed to support TEEs that are Global Platform compliant.
        zx_handle_close(tee_channel);
        return TEEC_ERROR_NOT_SUPPORTED;
    }
    context->imp.tee_channel = tee_channel;

    return TEEC_SUCCESS;
}

void TEEC_FinalizeContext(TEEC_Context* context) {
    if (context) {
        zx_handle_close(context->imp.tee_channel);
    }
}

TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context* context, TEEC_SharedMemory* sharedMem) {
    /* This function is supposed to register an existing buffer for use as shared memory. We don't
     * have a way of discovering the VMO handle for an arbitrary address, so implementing this would
     * require an extra VMO that would be copied into at invocation. Since we currently don't have
     * any use cases for this function and TEEC_AllocateSharedMemory should be the preferred method
     * of acquiring shared memory, we're going to leave this unimplemented for now. */
    return TEEC_ERROR_NOT_IMPLEMENTED;
}

TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context* context, TEEC_SharedMemory* sharedMem) {
    if (!context || !sharedMem) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    if (sharedMem->flags & ~(TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) {
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    memset(&sharedMem->imp, 0, sizeof(sharedMem->imp));

    size_t size = sharedMem->size;

    zx_handle_t vmo = ZX_HANDLE_INVALID;
    zx_status_t status = zx_vmo_create(size, ZX_VMO_NON_RESIZABLE, &vmo);
    if (status != ZX_OK) {
        return convert_status_to_result(status);
    }

    zx_vaddr_t mapped_addr;
    status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0, size,
                         &mapped_addr);
    if (status != ZX_OK) {
        zx_handle_close(vmo);
        return convert_status_to_result(status);
    }

    sharedMem->buffer = (void*)mapped_addr;
    sharedMem->imp.vmo = vmo;
    sharedMem->imp.mapped_addr = mapped_addr;
    sharedMem->imp.mapped_size = size;

    return TEEC_SUCCESS;
}

void TEEC_ReleaseSharedMemory(TEEC_SharedMemory* sharedMem) {
    if (!sharedMem) {
        return;
    }
    zx_vmar_unmap(zx_vmar_root_self(), sharedMem->imp.mapped_addr, sharedMem->imp.mapped_size);
    zx_handle_close(sharedMem->imp.vmo);
}

TEEC_Result TEEC_OpenSession(TEEC_Context* context,
                             TEEC_Session* session,
                             const TEEC_UUID* destination,
                             uint32_t connectionMethod,
                             const void* connectionData,
                             TEEC_Operation* operation,
                             uint32_t* returnOrigin) {
    if (!context || !session || !destination) {
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_API;
        }
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    if (connectionMethod != TEEC_LOGIN_PUBLIC) {
        // TODO(rjascani): Investigate whether non public login is needed.
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_API;
        }
        return TEEC_ERROR_NOT_IMPLEMENTED;
    }

    fuchsia_tee_Uuid trusted_app;
    convert_teec_uuid_to_zx_uuid(destination, &trusted_app);

    fuchsia_tee_ParameterSet parameter_set;
    memset(&parameter_set, 0, sizeof(parameter_set));

    uint32_t processing_rc = preprocess_operation(operation, &parameter_set);
    if (processing_rc != TEEC_SUCCESS) {
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_COMMS;
        }
        return processing_rc;
    }

    // Outputs
    uint32_t out_session_id;
    fuchsia_tee_OpResult out_result;
    memset(&out_result, 0, sizeof(out_result));

    zx_status_t status = fuchsia_tee_DeviceOpenSession(
        context->imp.tee_channel, &trusted_app, &parameter_set, &out_session_id, &out_result);

    if (status != ZX_OK) {
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_COMMS;
        }
        return convert_status_to_result(status);
    }

    // Run post-processing regardless of TEE operation status. The operation was invoked
    // successfully, so the parameter set should be okay to post-process.
    processing_rc = postprocess_operation(&out_result.parameter_set, operation);

    if (out_result.return_code != TEEC_SUCCESS) {
        // If the TEE operation failed, use that return code above any processing failure codes.
        if (returnOrigin) {
            *returnOrigin = convert_zx_to_teec_return_origin(out_result.return_origin);
        }
        return out_result.return_code;
    }
    if (processing_rc != TEEC_SUCCESS) {
        // The TEE operation succeeded but the processing operation failed.
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_COMMS;
        }
        return processing_rc;
    }

    session->imp.session_id = out_session_id;
    session->imp.context_imp = &context->imp;

    return out_result.return_code;
}

void TEEC_CloseSession(TEEC_Session* session) {
    if (!session || !session->imp.context_imp) {
        return;
    }

    // TEEC_CloseSession simply swallows errors, so no need to check here.
    fuchsia_tee_DeviceCloseSession(session->imp.context_imp->tee_channel,
                                   session->imp.session_id);
    session->imp.context_imp = NULL;
}

TEEC_Result TEEC_InvokeCommand(TEEC_Session* session,
                               uint32_t commandID,
                               TEEC_Operation* operation,
                               uint32_t* returnOrigin) {
    if (!session || !session->imp.context_imp) {
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_API;
        }
        return TEEC_ERROR_BAD_PARAMETERS;
    }

    fuchsia_tee_ParameterSet parameter_set;
    memset(&parameter_set, 0, sizeof(parameter_set));

    fuchsia_tee_OpResult out_result;
    memset(&out_result, 0, sizeof(out_result));

    uint32_t processing_rc = preprocess_operation(operation, &parameter_set);
    if (processing_rc != TEEC_SUCCESS) {
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_COMMS;
        }
        return processing_rc;
    }

    zx_status_t status = fuchsia_tee_DeviceInvokeCommand(
        session->imp.context_imp->tee_channel, session->imp.session_id, commandID, &parameter_set,
        &out_result);

    if (status != ZX_OK) {
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_COMMS;
        }
        return convert_status_to_result(status);
    }

    // Run post-processing regardless of TEE operation status. The operation was invoked
    // successfully, so the parameter set should be okay to post-process.
    processing_rc = postprocess_operation(&out_result.parameter_set, operation);

    if (out_result.return_code != TEEC_SUCCESS) {
        // If the TEE operation failed, use that return code above any processing failure codes.
        if (returnOrigin) {
            *returnOrigin = convert_zx_to_teec_return_origin(out_result.return_origin);
        }
        return out_result.return_code;
    }
    if (processing_rc != TEEC_SUCCESS) {
        // The TEE operation succeeded but the processing operation failed.
        if (returnOrigin) {
            *returnOrigin = TEEC_ORIGIN_COMMS;
        }
        return processing_rc;
    }

    return out_result.return_code;
}

void TEEC_RequestCancellation(TEEC_Operation* operation) {}
