// 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.

library fuchsia.tee;

using zx;

// Trusted Execution Environment (TEE) Interface

/// UUID identifiers are used to identify the TEE Operating System and individual Trusted
/// Applications. This structure matches the UUID type as defined by RFC4122.
struct Uuid {
    uint32 time_low;
    uint16 time_mid;
    uint16 time_hi_and_version;
    array<uint8>:8 clock_seq_and_node;
};

table OsRevision {
    1: uint32 major;
    2: uint32 minor;
};

table OsInfo {
    1: Uuid uuid;
    2: OsRevision revision;
    3: bool is_global_platform_compliant;
};

/// Communication with the TEE OS and Trusted Applications is performed using opaque parameters.
/// These parameters can be a mix of small values (Value type) or a buffer reference (Buffer type).
/// A parameter will be tagged as either an input, output or both (inout).
enum Direction : uint32 {
    INPUT = 0;
    OUTPUT = 1;
    INOUT = 2;
};

/// An empty parameter type is used as a placeholder for elements in the parameter set that are not
/// used.
// TODO(fxbug.dev/8031): Consider making this a table once empty tables do not cause binding issues.
struct None {
};

/// Represents a buffer parameter.
resource table Buffer {
    1: Direction direction;

    /// The VMO is allowed to be not present for situations where the TEE allows for buffer size
    /// checks.
    ///
    /// For example, if the operation to be performed needs an output buffer, but the user cannot
    /// calculate how large that output buffer should be, they can attempt the operation without
    /// a vmo and the Trusted Application will populate the size field so that the operation can
    /// be performed again with an appropriately sized buffer.
    2: zx.handle:VMO vmo;
    3: uint64 offset;
    4: uint64 size;
};

/// Represents a direct value parameter.
table Value {
    1: Direction direction;

    /// This value is optional. If not set, a zero value is sent in its place if it is required by
    /// the calling convention.
    2: uint64 a;

    /// This value is optional. If not set, a zero value is sent in its place if it is required by
    /// the calling convention.
    3: uint64 b;

    /// This value is optional. If not set, a zero value is sent in its place if it is required by
    /// the calling convention.
    4: uint64 c;
};

flexible resource union Parameter {
    1: None none;
    2: Buffer buffer;
    3: Value value;
};

const uint32 MAX_PARAMETERSET_COUNT = 4;
alias ParameterSet = vector<Parameter>:MAX_PARAMETERSET_COUNT;

/// Each operation must flow through the device driver and the trusted operating system before
/// reaching the trusted application (and back). The ReturnOrigin indicates which layer provided the
/// return code.
enum ReturnOrigin : uint32 {
    COMMUNICATION = 0;
    TRUSTED_OS = 1;
    TRUSTED_APPLICATION = 2;
};

/// The result of an operation will include a return code, the origin of the result, and the return
/// of the parameter set. The returned parameter set will be a copy of the input parameter set, but
/// with the INOUT and OUTPUT parameters updated. If the parameter is a Buffer, it will update the
/// Buffer.size to the number of bytes written.
resource table OpResult {
    1: uint64 return_code;
    2: ReturnOrigin return_origin;
    3: ParameterSet parameter_set;
};

// TODO(fxbug.dev/44664): Remove this protocol once transition is complete.
[Discoverable]
protocol Device {
    /// Obtains information about the TEE OS
    GetOsInfo() -> (OsInfo info);

    /// Initiates a communication session with the specified trusted application.
    OpenSession(Uuid trusted_app, ParameterSet parameter_set)
        -> (uint32 session_id, OpResult op_result);

    /// Requests the trusted application perform the provided command. The command is unique to the
    /// trusted application.
    InvokeCommand(uint32 session_id, uint32 command_id, ParameterSet parameter_set)
        -> (OpResult op_result);

    /// Closes an established session.
    CloseSession(uint32 session_id) -> ();
};

/// Provides information about the TEE device.
[Discoverable]
protocol DeviceInfo {
    /// Obtains information about the TEE OS.
    GetOsInfo() -> (OsInfo info);
};

/// Represents a connection to an application running in the TEE.
protocol Application {
    // TODO(fxbug.dev/44664): Remove this function once transition is complete. Used for source-compatibility.
    [Transitional, Deprecated]
    GetOsInfo() -> (OsInfo info);

    // TODO(fxbug.dev/44664): Remove this function once transition is complete. Used for source-compatibility.
    [Transitional, Deprecated]
    OpenSession(Uuid trusted_app, ParameterSet parameter_set)
        -> (uint32 session_id, OpResult op_result);

    /// Initiates a communication session with the trusted application.
    OpenSession2(ParameterSet parameter_set)
        -> (uint32 session_id, OpResult op_result);

    /// Requests the trusted application perform the provided command. The command is unique to the
    /// trusted application.
    InvokeCommand(uint32 session_id, uint32 command_id, ParameterSet parameter_set)
        -> (OpResult op_result);

    /// Closes an established session.
    CloseSession(uint32 session_id) -> ();
};
