// 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 <fcntl.h>
#include <fuchsia/hardware/tee/llcpp/fidl.h>
#include <fuchsia/tee/llcpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/service/llcpp/service.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <unistd.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include <cstring>
#include <optional>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>

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

namespace {

struct UuidEqualityComparator {
  bool operator()(const fuchsia_tee::wire::Uuid& lhs, const fuchsia_tee::wire::Uuid& rhs) const {
    if (lhs.time_low != rhs.time_low) {
      return false;
    }
    if (lhs.time_mid != rhs.time_mid) {
      return false;
    }
    if (lhs.time_hi_and_version != rhs.time_hi_and_version) {
      return false;
    }

    if (!std::equal(lhs.clock_seq_and_node.begin(), lhs.clock_seq_and_node.end(),
                    rhs.clock_seq_and_node.begin(), rhs.clock_seq_and_node.end())) {
      return false;
    }

    return true;
  }
};

using UuidToAppContainer =
    std::vector<std::pair<fuchsia_tee::wire::Uuid, fidl::ClientEnd<fuchsia_tee::Application>>>;

constexpr std::string_view kServiceDirectoryPath("/svc/");

// Presently only used by clients that need to connect before the service is available / don't need
// the TEE to be able to use file services.
constexpr std::string_view kTeeDevClass("/dev/class/tee/");

std::string GetApplicationServicePath(const fuchsia_tee::wire::Uuid& app_uuid) {
  constexpr std::string_view kApplicationServicePathPrefix = "/svc/fuchsia.tee.Application.";
  constexpr size_t kUuidNameLength = 36;
  constexpr const char* kPathFormat = "%s%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
  constexpr size_t kPathLength = kApplicationServicePathPrefix.size() + kUuidNameLength;

  // Reserve an extra spot for the null-terminating character.
  char path_buf[kPathLength + 1];
  snprintf(path_buf, kPathLength + 1, kPathFormat, kApplicationServicePathPrefix.data(),
           app_uuid.time_low, app_uuid.time_mid, app_uuid.time_hi_and_version,
           app_uuid.clock_seq_and_node[0], app_uuid.clock_seq_and_node[1],
           app_uuid.clock_seq_and_node[2], app_uuid.clock_seq_and_node[3],
           app_uuid.clock_seq_and_node[4], app_uuid.clock_seq_and_node[5],
           app_uuid.clock_seq_and_node[6], app_uuid.clock_seq_and_node[7]);

  return std::string(path_buf, kPathLength);
}

constexpr uint32_t GetParamTypeForIndex(uint32_t param_types, size_t index) {
  constexpr uint32_t kBitsPerParamType = 4;
  return ((param_types >> (index * kBitsPerParamType)) & 0xF);
}

constexpr bool IsSharedMemFlagInOut(uint32_t flags) {
  constexpr uint32_t kInOutFlags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
  return (flags & kInOutFlags) == kInOutFlags;
}

constexpr bool IsDirectionInput(fuchsia_tee::wire::Direction direction) {
  return ((direction == fuchsia_tee::wire::Direction::INPUT) ||
          (direction == fuchsia_tee::wire::Direction::INOUT));
}

constexpr bool IsDirectionOutput(fuchsia_tee::wire::Direction direction) {
  return ((direction == fuchsia_tee::wire::Direction::OUTPUT) ||
          (direction == fuchsia_tee::wire::Direction::INOUT));
}

TEEC_Result CheckGlobalPlatformCompliance(
    fidl::UnownedClientEnd<fuchsia_hardware_tee::DeviceConnector> maybe_device_connector) {
  fidl::ClientEnd<fuchsia_tee::DeviceInfo> device_info;

  if (maybe_device_connector.is_valid()) {
    auto server_end = fidl::CreateEndpoints(&device_info);
    if (!server_end.is_ok()) {
      return TEEC_ERROR_COMMUNICATION;
    }
    auto result = fidl::WireCall(std::move(maybe_device_connector))
                      .ConnectToDeviceInfo(std::move(server_end.value()));
    if (!result.ok()) {
      return TEEC_ERROR_NOT_SUPPORTED;
    }
  } else {
    auto result = service::Connect<fuchsia_tee::DeviceInfo>();
    if (!result.is_ok()) {
      return TEEC_ERROR_NOT_SUPPORTED;
    }
    device_info = std::move(result.value());
  }

  auto result = fidl::WireCall(device_info).GetOsInfo();
  if (!result.ok() || !result->info.has_is_global_platform_compliant() ||
      !result->info.is_global_platform_compliant()) {
    return TEEC_ERROR_NOT_SUPPORTED;
  }

  return TEEC_SUCCESS;
}

void ConvertTeecUuidToZxUuid(const TEEC_UUID& teec_uuid, fuchsia_tee::wire::Uuid* out_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;

  std::memcpy(out_uuid->clock_seq_and_node.data(), teec_uuid.clockSeqAndNode,
              sizeof(out_uuid->clock_seq_and_node));
}

constexpr TEEC_Result ConvertStatusToResult(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;
}

constexpr uint32_t ConvertZxToTeecReturnOrigin(fuchsia_tee::wire::ReturnOrigin return_origin) {
  switch (return_origin) {
    case fuchsia_tee::wire::ReturnOrigin::COMMUNICATION:
      return TEEC_ORIGIN_COMMS;
    case fuchsia_tee::wire::ReturnOrigin::TRUSTED_OS:
      return TEEC_ORIGIN_TEE;
    case fuchsia_tee::wire::ReturnOrigin::TRUSTED_APPLICATION:
      return TEEC_ORIGIN_TRUSTED_APP;
    default:
      return TEEC_ORIGIN_API;
  }
}

constexpr size_t CountOperationParameters(const TEEC_Operation& operation) {
  // Find the highest-indexed non-none parameter.
  for (size_t param_num = static_cast<size_t>(TEEC_NUM_PARAMS_MAX); param_num != 0; param_num--) {
    uint32_t param_type = GetParamTypeForIndex(operation.paramTypes, param_num - 1);
    if (param_type != TEEC_NONE) {
      return param_num;
    }
  }

  return 0;
}

zx_status_t CreateVmoWithName(uint64_t size, uint32_t options, std::string_view name,
                              zx::vmo* result) {
  ZX_DEBUG_ASSERT(result);

  zx::vmo vmo;
  zx_status_t s = zx::vmo::create(size, options, &vmo);
  if (s != ZX_OK) {
    return s;
  }

  s = vmo.set_property(ZX_PROP_NAME, name.data(), name.size());
  if (s != ZX_OK) {
    return s;
  }
  *result = std::move(vmo);
  return s;
}

void PreprocessValue(fidl::AnyAllocator& allocator, uint32_t param_type,
                     const TEEC_Value& teec_value, fuchsia_tee::wire::Parameter* out_parameter) {
  ZX_DEBUG_ASSERT(out_parameter);

  fuchsia_tee::wire::Direction direction;
  switch (param_type) {
    case TEEC_VALUE_INPUT:
      direction = fuchsia_tee::wire::Direction::INPUT;
      break;
    case TEEC_VALUE_OUTPUT:
      direction = fuchsia_tee::wire::Direction::OUTPUT;
      break;
    case TEEC_VALUE_INOUT:
      direction = fuchsia_tee::wire::Direction::INOUT;
      break;
    default:
      ZX_PANIC("Unknown param type");
  }

  fuchsia_tee::wire::Value value(allocator);
  value.set_direction(allocator, direction);
  if (IsDirectionInput(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.
    value.set_a(allocator, teec_value.a);
    value.set_b(allocator, teec_value.b);
  }

  out_parameter->set_value(allocator, std::move(value));
}

TEEC_Result PreprocessTemporaryMemref(fidl::AnyAllocator& allocator, uint32_t param_type,
                                      const TEEC_TempMemoryReference& temp_memory_ref,
                                      fuchsia_tee::wire::Parameter* out_parameter) {
  ZX_DEBUG_ASSERT(out_parameter);

  fuchsia_tee::wire::Direction direction;
  switch (param_type) {
    case TEEC_MEMREF_TEMP_INPUT:
      direction = fuchsia_tee::wire::Direction::INPUT;
      break;
    case TEEC_MEMREF_TEMP_OUTPUT:
      direction = fuchsia_tee::wire::Direction::OUTPUT;
      break;
    case TEEC_MEMREF_TEMP_INOUT:
      direction = fuchsia_tee::wire::Direction::INOUT;
      break;
    default:
      ZX_PANIC("TEE Client API Unknown parameter type\n");
  }

  zx::vmo vmo;

  if (temp_memory_ref.buffer) {
    // We either have data to input or have a buffer to output data to, so create a VMO for it.
    zx_status_t status = CreateVmoWithName(temp_memory_ref.size, 0, "teec_temp_memory", &vmo);
    if (status != ZX_OK) {
      return ConvertStatusToResult(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 (IsDirectionInput(direction)) {
      status = vmo.write(temp_memory_ref.buffer, 0, temp_memory_ref.size);
      if (status != ZX_OK) {
        return ConvertStatusToResult(status);
      }
    }
  }

  fuchsia_tee::wire::Buffer buffer(allocator);
  buffer.set_direction(allocator, direction);
  if (vmo.is_valid()) {
    buffer.set_vmo(allocator, std::move(vmo));
  }
  buffer.set_offset(allocator, 0);
  buffer.set_size(allocator, temp_memory_ref.size);

  out_parameter->set_buffer(allocator, std::move(buffer));
  return TEEC_SUCCESS;
}

TEEC_Result PreprocessWholeMemref(fidl::AnyAllocator& allocator,
                                  const TEEC_RegisteredMemoryReference& memory_ref,
                                  fuchsia_tee::wire::Parameter* out_parameter) {
  ZX_DEBUG_ASSERT(out_parameter);

  if (!memory_ref.parent) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  TEEC_SharedMemory* shared_mem = memory_ref.parent;
  fuchsia_tee::wire::Direction direction;
  if (IsSharedMemFlagInOut(shared_mem->flags)) {
    direction = fuchsia_tee::wire::Direction::INOUT;
  } else if (shared_mem->flags & TEEC_MEM_INPUT) {
    direction = fuchsia_tee::wire::Direction::INPUT;
  } else if (shared_mem->flags & TEEC_MEM_OUTPUT) {
    direction = fuchsia_tee::wire::Direction::OUTPUT;
  } else {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  zx::vmo vmo;
  zx_status_t status = zx::unowned_vmo(shared_mem->imp.vmo)->duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo);
  if (status != ZX_OK) {
    return ConvertStatusToResult(status);
  }

  fuchsia_tee::wire::Buffer buffer(allocator);
  buffer.set_direction(allocator, direction);
  buffer.set_vmo(allocator, std::move(vmo));
  buffer.set_offset(allocator, 0);
  buffer.set_size(allocator, shared_mem->size);

  out_parameter->set_buffer(allocator, std::move(buffer));
  return TEEC_SUCCESS;
}

TEEC_Result PreprocessPartialMemref(fidl::AnyAllocator& allocator, uint32_t param_type,
                                    const TEEC_RegisteredMemoryReference& memory_ref,
                                    fuchsia_tee::wire::Parameter* out_parameter) {
  ZX_DEBUG_ASSERT(out_parameter);

  if (!memory_ref.parent) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  uint32_t expected_shm_flags = 0;
  fuchsia_tee::wire::Direction direction;
  switch (param_type) {
    case TEEC_MEMREF_PARTIAL_INPUT:
      expected_shm_flags = TEEC_MEM_INPUT;
      direction = fuchsia_tee::wire::Direction::INPUT;
      break;
    case TEEC_MEMREF_PARTIAL_OUTPUT:
      expected_shm_flags = TEEC_MEM_OUTPUT;
      direction = fuchsia_tee::wire::Direction::OUTPUT;
      break;
    case TEEC_MEMREF_PARTIAL_INOUT:
      expected_shm_flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
      direction = fuchsia_tee::wire::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::vmo vmo;
  zx_status_t status = zx::unowned_vmo(shared_mem->imp.vmo)->duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo);
  if (status != ZX_OK) {
    return ConvertStatusToResult(status);
  }

  fuchsia_tee::wire::Buffer buffer(allocator);
  buffer.set_direction(allocator, direction);
  buffer.set_vmo(allocator, std::move(vmo));
  buffer.set_offset(allocator, memory_ref.offset);
  buffer.set_size(allocator, memory_ref.size);

  out_parameter->set_buffer(allocator, std::move(buffer));
  return TEEC_SUCCESS;
}

TEEC_Result PreprocessOperation(fidl::AnyAllocator& allocator, const TEEC_Operation* operation,
                                fidl::VectorView<fuchsia_tee::wire::Parameter>* out_parameter_set) {
  ZX_DEBUG_ASSERT(out_parameter_set);

  if (!operation) {
    out_parameter_set->Allocate(allocator, 0);
    return TEEC_SUCCESS;
  }

  size_t num_params = CountOperationParameters(*operation);
  out_parameter_set->Allocate(allocator, num_params);

  TEEC_Result rc = TEEC_SUCCESS;
  for (size_t i = 0; i < num_params; i++) {
    uint32_t param_type = GetParamTypeForIndex(operation->paramTypes, i);
    fuchsia_tee::wire::Parameter& parameter = (*out_parameter_set)[i];

    switch (param_type) {
      case TEEC_NONE:
        parameter.set_none(allocator);
        break;
      case TEEC_VALUE_INPUT:
      case TEEC_VALUE_OUTPUT:
      case TEEC_VALUE_INOUT:
        PreprocessValue(allocator, param_type, operation->params[i].value, &parameter);
        break;
      case TEEC_MEMREF_TEMP_INPUT:
      case TEEC_MEMREF_TEMP_OUTPUT:
      case TEEC_MEMREF_TEMP_INOUT:
        rc = PreprocessTemporaryMemref(allocator, param_type, operation->params[i].tmpref,
                                       &parameter);
        break;
      case TEEC_MEMREF_WHOLE:
        rc = PreprocessWholeMemref(allocator, operation->params[i].memref, &parameter);
        break;
      case TEEC_MEMREF_PARTIAL_INPUT:
      case TEEC_MEMREF_PARTIAL_OUTPUT:
      case TEEC_MEMREF_PARTIAL_INOUT:
        rc =
            PreprocessPartialMemref(allocator, param_type, operation->params[i].memref, &parameter);
        break;
      default:
        rc = TEEC_ERROR_BAD_PARAMETERS;
        break;
    }

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

  return rc;
}

TEEC_Result PostprocessValue(uint32_t param_type, const fuchsia_tee::wire::Parameter& zx_param,
                             TEEC_Value* out_teec_value) {
  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.which() != fuchsia_tee::wire::Parameter::Tag::kValue) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  const fuchsia_tee::wire::Value& zx_value = zx_param.value();
  if (!zx_value.has_direction()) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  // Validate that the direction of the returned parameter matches the expected.
  if ((param_type == TEEC_VALUE_INPUT) &&
      (zx_value.direction() != fuchsia_tee::wire::Direction::INPUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }
  if ((param_type == TEEC_VALUE_OUTPUT) &&
      (zx_value.direction() != fuchsia_tee::wire::Direction::OUTPUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }
  if ((param_type == TEEC_VALUE_INOUT) &&
      (zx_value.direction() != fuchsia_tee::wire::Direction::INOUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  if (IsDirectionOutput(zx_value.direction())) {
    if (!zx_value.has_a() || !zx_value.has_b()) {
      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 = static_cast<uint32_t>(zx_value.a());
    out_teec_value->b = static_cast<uint32_t>(zx_value.b());
  }
  return TEEC_SUCCESS;
}

TEEC_Result PostprocessTemporaryMemref(uint32_t param_type,
                                       const fuchsia_tee::wire::Parameter& zx_param,
                                       TEEC_TempMemoryReference* out_temp_memory_ref) {
  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.which() != fuchsia_tee::wire::Parameter::Tag::kBuffer) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  const fuchsia_tee::wire::Buffer& zx_buffer = zx_param.buffer();
  if (!zx_buffer.has_direction()) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  if ((param_type == TEEC_MEMREF_TEMP_INPUT) &&
      (zx_buffer.direction() != fuchsia_tee::wire::Direction::INPUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }
  if ((param_type == TEEC_MEMREF_TEMP_OUTPUT) &&
      (zx_buffer.direction() != fuchsia_tee::wire::Direction::OUTPUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }
  if ((param_type == TEEC_MEMREF_TEMP_INOUT) &&
      (zx_buffer.direction() != fuchsia_tee::wire::Direction::INOUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  TEEC_Result rc = TEEC_SUCCESS;
  if (IsDirectionOutput(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 (!zx_buffer.has_size()) {
      return TEEC_ERROR_BAD_PARAMETERS;
    }

    if (out_temp_memory_ref->buffer && out_temp_memory_ref->size >= zx_buffer.size()) {
      if (!zx_buffer.has_offset() || !zx_buffer.has_vmo()) {
        return TEEC_ERROR_BAD_PARAMETERS;
      }

      zx_status_t status =
          zx_buffer.vmo().read(out_temp_memory_ref->buffer, zx_buffer.offset(), zx_buffer.size());
      rc = ConvertStatusToResult(status);
    }
    out_temp_memory_ref->size = zx_buffer.size();
  }

  return rc;
}

TEEC_Result PostprocessWholeMemref(const fuchsia_tee::wire::Parameter& zx_param,
                                   TEEC_RegisteredMemoryReference* out_memory_ref) {
  ZX_DEBUG_ASSERT(out_memory_ref);
  ZX_DEBUG_ASSERT(out_memory_ref->parent);

  if (zx_param.which() != fuchsia_tee::wire::Parameter::Tag::kBuffer) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  const fuchsia_tee::wire::Buffer& zx_buffer = zx_param.buffer();
  if (!zx_buffer.has_direction()) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  if (IsDirectionOutput(zx_buffer.direction())) {
    if (!zx_buffer.has_size()) {
      return TEEC_ERROR_BAD_PARAMETERS;
    }
    out_memory_ref->size = zx_buffer.size();
  }

  return TEEC_SUCCESS;
}

TEEC_Result PostprocessPartialMemref(uint32_t param_type,
                                     const fuchsia_tee::wire::Parameter& zx_param,
                                     TEEC_RegisteredMemoryReference* out_memory_ref) {
  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.which() != fuchsia_tee::wire::Parameter::Tag::kBuffer) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  const fuchsia_tee::wire::Buffer& zx_buffer = zx_param.buffer();
  if (!zx_buffer.has_direction()) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  if ((param_type == TEEC_MEMREF_PARTIAL_INPUT) &&
      (zx_buffer.direction() != fuchsia_tee::wire::Direction::INPUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }
  if ((param_type == TEEC_MEMREF_PARTIAL_OUTPUT) &&
      (zx_buffer.direction() != fuchsia_tee::wire::Direction::OUTPUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }
  if ((param_type == TEEC_MEMREF_PARTIAL_INOUT) &&
      (zx_buffer.direction() != fuchsia_tee::wire::Direction::INOUT)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  if (IsDirectionOutput(zx_buffer.direction())) {
    if (!zx_buffer.has_size()) {
      return TEEC_ERROR_BAD_PARAMETERS;
    }
    out_memory_ref->size = zx_buffer.size();
  }

  return TEEC_SUCCESS;
}

TEEC_Result PostprocessOperation(
    const fidl::VectorView<fuchsia_tee::wire::Parameter>& parameter_set,
    TEEC_Operation* out_operation) {
  if (!out_operation) {
    return TEEC_SUCCESS;
  }

  size_t num_params = CountOperationParameters(*out_operation);

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

    // This check catches the case where we did not receive all the parameters we expected.
    if (i >= parameter_set.count() && param_type != TEEC_NONE) {
      rc = TEEC_ERROR_BAD_PARAMETERS;
      break;
    }

    switch (param_type) {
      case TEEC_NONE:
        if (parameter_set[i].which() != fuchsia_tee::wire::Parameter::Tag::kNone) {
          rc = TEEC_ERROR_BAD_PARAMETERS;
        }
        break;
      case TEEC_VALUE_INPUT:
      case TEEC_VALUE_OUTPUT:
      case TEEC_VALUE_INOUT:
        rc = PostprocessValue(param_type, parameter_set[i], &out_operation->params[i].value);
        break;
      case TEEC_MEMREF_TEMP_INPUT:
      case TEEC_MEMREF_TEMP_OUTPUT:
      case TEEC_MEMREF_TEMP_INOUT:
        rc = PostprocessTemporaryMemref(param_type, parameter_set[i],
                                        &out_operation->params[i].tmpref);
        break;
      case TEEC_MEMREF_WHOLE:
        rc = PostprocessWholeMemref(parameter_set[i], &out_operation->params[i].memref);
        break;
      case TEEC_MEMREF_PARTIAL_INPUT:
      case TEEC_MEMREF_PARTIAL_OUTPUT:
      case TEEC_MEMREF_PARTIAL_INOUT:
        rc = PostprocessPartialMemref(param_type, parameter_set[i],
                                      &out_operation->params[i].memref);
        break;
      default:
        rc = TEEC_ERROR_BAD_PARAMETERS;
    }

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

  // This check catches the case where we received more parameters than we expected.
  for (size_t i = num_params; i < parameter_set.count(); i++) {
    if (parameter_set[i].which() != fuchsia_tee::wire::Parameter::Tag::kNone) {
      return TEEC_ERROR_BAD_PARAMETERS;
    }
  }

  return rc;
}

fidl::UnownedClientEnd<fuchsia_hardware_tee::DeviceConnector> GetDeviceConnectorFromContext(
    TEEC_Context* context) {
  ZX_DEBUG_ASSERT(context);
  return fidl::UnownedClientEnd<fuchsia_hardware_tee::DeviceConnector>(
      context->imp.device_connector_channel);
}

fidl::UnownedClientEnd<fuchsia_tee::Application> GetApplicationFromSession(TEEC_Session* session) {
  ZX_DEBUG_ASSERT(session);
  return fidl::UnownedClientEnd<fuchsia_tee::Application>(session->imp.application_channel);
}

UuidToAppContainer* GetUuidToAppContainerFromContext(TEEC_Context* context) {
  ZX_DEBUG_ASSERT(context);
  return reinterpret_cast<UuidToAppContainer*>(context->imp.uuid_to_channel);
}

UuidToAppContainer::iterator FindInUuidToAppContainer(UuidToAppContainer* container,
                                                      const fuchsia_tee::wire::Uuid& uuid) {
  ZX_DEBUG_ASSERT(container);

  return std::find_if(container->begin(), container->end(), [&](const auto& uuid_app_pair) {
    return UuidEqualityComparator{}(uuid_app_pair.first, uuid);
  });
}

constexpr bool ShouldUseDeviceConnector(const TEEC_Context* context) {
  return context->imp.device_connector_channel != ZX_HANDLE_INVALID;
}

// Connects the client directly to the TEE Driver's DeviceConnector interface.
//
// 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 opens a
// session and sends a command to a trusted application that then needs persistent storage to
// complete, the persistent storage request will be rejected by the driver.
zx_status_t ConnectToDeviceConnector(
    const char* tee_device,
    fidl::ClientEnd<fuchsia_hardware_tee::DeviceConnector>* device_connector) {
  ZX_DEBUG_ASSERT(tee_device);
  ZX_DEBUG_ASSERT(device_connector);

  auto device_connector_result =
      service::Connect<fuchsia_hardware_tee::DeviceConnector>(tee_device);
  if (!device_connector_result.is_ok()) {
    return device_connector_result.status_value();
  }

  *device_connector = std::move(device_connector_result.value());
  return ZX_OK;
}

// Opens a connection to a `fuchsia.tee.Application` via a device connector.
TEEC_Result ConnectApplicationViaDeviceConnector(
    const fuchsia_tee::wire::Uuid& app_uuid,
    fidl::UnownedClientEnd<fuchsia_hardware_tee::DeviceConnector> device_connector,
    fidl::ClientEnd<fuchsia_tee::Application>* out_app) {
  ZX_DEBUG_ASSERT(device_connector.is_valid());
  ZX_DEBUG_ASSERT(out_app);

  auto app_ends = fidl::CreateEndpoints<fuchsia_tee::Application>();
  if (!app_ends.is_ok()) {
    return TEEC_ERROR_COMMUNICATION;
  }

  auto result =
      fidl::WireCall(std::move(device_connector))
          .ConnectToApplication(
              app_uuid, fidl::ClientEnd<::fuchsia_tee_manager::Provider>() /* service_provider */,
              std::move(app_ends->server));
  if (!result.ok()) {
    return TEEC_ERROR_COMMUNICATION;
  }

  *out_app = std::move(app_ends->client);
  return TEEC_SUCCESS;
}

// Opens a connection to a `fuchsia.tee.Application` via the service.
TEEC_Result ConnectApplicationViaService(const fuchsia_tee::wire::Uuid& app_uuid,
                                         fidl::ClientEnd<fuchsia_tee::Application>* out_app) {
  ZX_DEBUG_ASSERT(out_app);

  std::string service_path = GetApplicationServicePath(app_uuid);

  auto application = service::Connect<fuchsia_tee::Application>(service_path.c_str());
  if (!application.is_ok()) {
    return TEEC_ERROR_COMMUNICATION;
  }

  *out_app = std::move(application.value());
  return TEEC_SUCCESS;
}

TEEC_Result ConnectApplication(const fuchsia_tee::wire::Uuid& app_uuid, TEEC_Context* context,
                               fidl::UnownedClientEnd<fuchsia_tee::Application>* out_app) {
  ZX_DEBUG_ASSERT(context);
  ZX_DEBUG_ASSERT(out_app);

  UuidToAppContainer* uuid_to_app = GetUuidToAppContainerFromContext(context);
  if (uuid_to_app == nullptr) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  if (auto iter = FindInUuidToAppContainer(uuid_to_app, app_uuid); iter != uuid_to_app->end()) {
    // A connection to this application already exists, so just reuse the channel.
    *out_app = iter->second.borrow();
    return TEEC_SUCCESS;
  }

  // This is a new connection to this application, so a new connection must be made.
  fidl::ClientEnd<fuchsia_tee::Application> app_owned;
  TEEC_Result result = ShouldUseDeviceConnector(context)
                           ? ConnectApplicationViaDeviceConnector(
                                 app_uuid, GetDeviceConnectorFromContext(context), &app_owned)
                           : ConnectApplicationViaService(app_uuid, &app_owned);
  if (result != TEEC_SUCCESS) {
    return result;
  }

  *out_app = app_owned.borrow();

  // Stash the client end into the `uuid_to_app` for ownership and future use.
  uuid_to_app->emplace_back(app_uuid, std::move(app_owned));

  return TEEC_SUCCESS;
}

}  // namespace

__EXPORT
TEEC_Result TEEC_InitializeContext(const char* name, TEEC_Context* context) {
  if (!context) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  // TODO: use `std::string_view::starts_with()` when C++20 is available.
  auto starts_with = [](std::string_view str, std::string_view prefix) -> bool {
    // if prefix.size() is larger than str, compare clamps the comparison to the end of str
    return str.compare(0, prefix.size(), prefix) == 0;
  };

  auto name_view = std::string_view(name != nullptr ? name : "");
  fidl::ClientEnd<fuchsia_hardware_tee::DeviceConnector> maybe_device_connector;

  if (starts_with(name_view, kTeeDevClass)) {
    if (zx_status_t status = ConnectToDeviceConnector(name, &maybe_device_connector);
        status != ZX_OK) {
      return TEEC_ERROR_COMMUNICATION;
    }
  } else if (name != nullptr && !starts_with(name_view, kServiceDirectoryPath)) {
    return TEEC_ERROR_BAD_PARAMETERS;
  }

  // The device connector is allowed to be invalid in this usage.
  if (TEEC_Result result = CheckGlobalPlatformCompliance(maybe_device_connector.borrow());
      result != TEEC_SUCCESS) {
    return result;
  }

  context->imp.device_connector_channel = maybe_device_connector.TakeChannel().release();
  context->imp.uuid_to_channel = new UuidToAppContainer();

  return TEEC_SUCCESS;
}

__EXPORT
void TEEC_FinalizeContext(TEEC_Context* context) {
  if (context) {
    zx_handle_close(context->imp.device_connector_channel);
    context->imp.device_connector_channel = ZX_HANDLE_INVALID;

    delete GetUuidToAppContainerFromContext(context);
    context->imp.uuid_to_channel = nullptr;
  }
}

__EXPORT
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;
}

__EXPORT
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;
  }

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

  size_t size = sharedMem->size;

  zx::vmo vmo;
  zx_status_t status = CreateVmoWithName(size, 0, "teec_shared_memory", &vmo);
  if (status != ZX_OK) {
    return ConvertStatusToResult(status);
  }

  uintptr_t mapped_addr;
  status =
      zx::vmar::root_self()->map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0, size, &mapped_addr);
  if (status != ZX_OK) {
    return ConvertStatusToResult(status);
  }

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

  return TEEC_SUCCESS;
}

__EXPORT
void TEEC_ReleaseSharedMemory(TEEC_SharedMemory* sharedMem) {
  if (!sharedMem) {
    return;
  }
  zx::vmar::root_self()->unmap(sharedMem->imp.mapped_addr, sharedMem->imp.mapped_size);
  zx_handle_close(sharedMem->imp.vmo);
  sharedMem->imp.vmo = ZX_HANDLE_INVALID;
}

__EXPORT
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::wire::Uuid app_uuid_fidl;
  ConvertTeecUuidToZxUuid(*destination, &app_uuid_fidl);

  fidl::FidlAllocator allocator;
  fidl::VectorView<fuchsia_tee::wire::Parameter> parameter_set;
  TEEC_Result processing_rc = PreprocessOperation(allocator, operation, &parameter_set);
  if (processing_rc != TEEC_SUCCESS) {
    if (returnOrigin) {
      *returnOrigin = TEEC_ORIGIN_COMMS;
    }
    return processing_rc;
  }

  fidl::UnownedClientEnd<fuchsia_tee::Application> app_client_end(ZX_HANDLE_INVALID);
  if (TEEC_Result result = ConnectApplication(app_uuid_fidl, context, &app_client_end);
      result != TEEC_SUCCESS) {
    return result;
  }

  auto result = fidl::WireCall(app_client_end).OpenSession2(std::move(parameter_set));
  zx_status_t status = result.status();

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

    if (status == ZX_ERR_PEER_CLOSED) {
      // If the channel has closed, drop the entry from the map, closing the client end.
      UuidToAppContainer* uuid_to_app = GetUuidToAppContainerFromContext(context);
      if (auto iter = FindInUuidToAppContainer(uuid_to_app, app_uuid_fidl);
          iter != uuid_to_app->end()) {
        uuid_to_app->erase(iter);
      }
    }

    return ConvertStatusToResult(status);
  }

  uint32_t out_session_id = result->session_id;
  fuchsia_tee::wire::OpResult& out_result = result->op_result;

  if (!out_result.has_return_code() || !out_result.has_return_origin()) {
    if (returnOrigin) {
      *returnOrigin = TEEC_ORIGIN_COMMS;
    }
    return TEEC_ERROR_COMMUNICATION;
  }

  // Try and run post-processing regardless of TEE operation status. Even if an error occurred,
  // the parameter set may have been updated.
  processing_rc = out_result.has_parameter_set()
                      ? PostprocessOperation(out_result.parameter_set(), operation)
                      : TEEC_ERROR_COMMUNICATION;

  if (out_result.return_code() != TEEC_SUCCESS) {
    // If the TEE operation failed, use that return code above any processing failure codes.
    if (returnOrigin) {
      *returnOrigin = ConvertZxToTeecReturnOrigin(out_result.return_origin());
    }
    return static_cast<uint32_t>(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.application_channel = app_client_end.handle();

  return static_cast<uint32_t>(out_result.return_code());
}

__EXPORT
void TEEC_CloseSession(TEEC_Session* session) {
  if (!session || session->imp.application_channel == ZX_HANDLE_INVALID) {
    return;
  }

  // TEEC_CloseSession simply swallows errors, so no need to check here.
  fidl::WireCall(GetApplicationFromSession(session)).CloseSession(session->imp.session_id);
  session->imp.application_channel = ZX_HANDLE_INVALID;
}

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

  fidl::FidlAllocator allocator;
  fidl::VectorView<fuchsia_tee::wire::Parameter> parameter_set;
  TEEC_Result processing_rc = PreprocessOperation(allocator, operation, &parameter_set);
  if (processing_rc != TEEC_SUCCESS) {
    if (returnOrigin) {
      *returnOrigin = TEEC_ORIGIN_COMMS;
    }
    return processing_rc;
  }

  auto result = fidl::WireCall(GetApplicationFromSession(session))
                    .InvokeCommand(session->imp.session_id, commandID, std::move(parameter_set));
  zx_status_t status = result.status();
  if (status != ZX_OK) {
    if (returnOrigin) {
      *returnOrigin = TEEC_ORIGIN_COMMS;
    }
    return ConvertStatusToResult(status);
  }

  fuchsia_tee::wire::OpResult& out_result = result->op_result;

  if (!out_result.has_return_code() || !out_result.has_return_origin()) {
    if (returnOrigin) {
      *returnOrigin = TEEC_ORIGIN_COMMS;
    }
    return TEEC_ERROR_COMMUNICATION;
  }

  // Try and run post-processing regardless of TEE operation status. Even if an error occurred,
  // the parameter set may have been updated.
  processing_rc = out_result.has_parameter_set()
                      ? PostprocessOperation(out_result.parameter_set(), operation)
                      : TEEC_ERROR_COMMUNICATION;

  if (out_result.return_code() != TEEC_SUCCESS) {
    // If the TEE operation failed, use that return code above any processing failure codes.
    if (returnOrigin) {
      *returnOrigin = ConvertZxToTeecReturnOrigin(out_result.return_origin());
    }
    return static_cast<uint32_t>(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 static_cast<uint32_t>(out_result.return_code());
}

__EXPORT
void TEEC_RequestCancellation(TEEC_Operation* operation) {}
