/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; namespace Tizen.Security.TEEC { /// /// This type denotes the Session Login Method used in OpenSession. /// /// 3 public class LoginMethod { /// No login data is provided. public const uint Public = 0x00000000; /// Login data about the user running the client application process is provided. public const uint User = 0x00000001; /// Login data about the group running the client application process is provided. public const uint Group = 0x00000002; /// Login data about the running client application itself is provided. public const uint Application = 0x00000003; } /// /// This type denotes the Value parameter. /// /// 3 public enum TEFValueType : UInt32 { /// The parameter is a ValueType tagged as the input. Input = 0x00000001, /// The parameter is a ValueType tagged as the output. Output = 0x00000002, /// The parameter is a ValueType tagged as both the input and the output. InOut = 0x00000003, } /// /// This type denotes the TempMemoryReference parameter /// describing a region of memory which needs to be temporarily registered for the duration of the operation. /// /// 3 public enum TEFTempMemoryType : UInt32 { /// The parameter is a TempMemoryType and is tagged as the input. Input = 0x00000005, /// Same as the input, but the Memory Reference is tagged as the output. Output = 0x00000006, /// A Temporary Memory Reference tagged as both the input and the output. InOut = 0x00000007, } /// /// This type denotes the SharedMemoryReference parameter. /// /// 3 public enum TEFRegisteredMemoryType : UInt32 { /// The parameter is a registered memory reference that refers to the entirety of its parent shared memory block. Whole = 0x0000000C, /// A registered memory reference structure that refers to a partial region of its parent shared mMemory block and is tagged as the input. PartialInput = 0x0000000D, /// A registered memory reference structure that refers to a partial region of its parent shared memory block and is tagged as the output. PartialOutput = 0x0000000E, /// A registered memory reference structure that refers to a partial region of its parent shared memory block and is tagged as both the input and the output. PartialInOut = 0x0000000F, } /// /// This type denotes the SharedMemory access direction. /// /// 3 [Flags] public enum SharedMemoryFlags : UInt32 { /// A flag indicates the shared memory can be read. Input = 0x00000001, /// A flag indicates the shared memory can be written. Output = 0x00000002, /// A flag indicates the shared memory can be read and written. InOut = Input | Output, } /// /// This type denotes a shared memory block which has been either registered /// with the implementation or allocated by it. /// /// 3 public sealed class SharedMemory { internal Interop.TEEC_SharedMemory shm; internal SharedMemory(Interop.TEEC_SharedMemory shm) { this.shm=shm; } /// /// This property represents the shared memory size in bytes. /// /// 3 public UInt32 Size { get { return shm.size; } } /// /// This property represents the start address of the shared memory block. /// /// 3 public IntPtr Address { get { return shm.buffer; } } /// /// This function makes a copy and is designed for convenient operations on small buffers. /// For large buffers, the direct address should be used. /// /// 3 /// The source data buffer to copy data from. /// The starting offset in the destination shared memory. /// The operation is invalid. public void SetData(byte[] data, int dstOffs) { if ((shm.flags & (uint)SharedMemoryFlags.Output) == 0) throw new InvalidOperationException("No write access"); Marshal.Copy(data, 0, shm.buffer + dstOffs, data.Length); } /// /// This function makes a copy and is designed for convenient operations on small buffers. /// For large buffers, the direct address should be used. /// /// 3 /// The destination data buffer to copy data into. /// The starting offset in the source shared memory. /// The operation is invalid. public void GetData(byte[] data, int srcOffs) { if ((shm.flags & (uint)SharedMemoryFlags.Input) == 0) throw new InvalidOperationException("No read access"); Marshal.Copy(shm.buffer + srcOffs, data, 0, data.Length); } }; /// /// This type defines the payload of either an open session operation or an invoke command operation. It is /// also used for cancelation of operations, which may be desirable even if no payload is passed. /// Parameters are used to exchange data between CA and TA. /// /// 3 public abstract class Parameter { internal Parameter(uint t) { this.NativeType = t; } internal uint NativeType { get; } }; /// /// This type defines a template for the parameter types. /// /// 3 public abstract class BaseParameter : Parameter where TEnum : struct, IComparable, IFormattable, IConvertible // as close to Enum as possible { internal BaseParameter(TEnum t) : base((uint)(object)t) { Type = t; } /// /// This property represents the access type to this parameter. /// /// 3 public TEnum Type { get; } } /// /// This type defines a temporary memory reference. /// /// 3 public sealed class TempMemoryReference : BaseParameter { /// /// Constructs a parameter object which holds information about the temporary memory copied to or from TA. /// /// 3 /// The address of the allocated memory buffer. /// The size of the buffer. /// The kind of access allowed for TA . public TempMemoryReference(IntPtr buffer, uint size, TEFTempMemoryType type) : base(type) { this.Buffer = buffer; this.Size = size; } /// /// This property represents the memory address of the buffer. /// /// 3 public IntPtr Buffer { get; } /// /// This property represents the size of the buffer. /// /// 3 public uint Size { get; } }; /// /// This type defines a memory reference that uses a pre-registered or pre-allocated shared memory block. /// /// 3 public sealed class RegisteredMemoryReference : BaseParameter { /// /// Constructs a parameter object which holds information about the registered memory shared with TA. /// /// 3 /// The shared memory - registered or allocated. /// The size of the buffer part. /// The offset of the buffer in the shared memory. /// The kind of access allowed for TA . public RegisteredMemoryReference(SharedMemory parent, uint size, uint offset, TEFRegisteredMemoryType type) : base(type) { this.Parent = parent; this.Size = size; this.Offset = offset; } /// /// This property represents the shared memory that is referred to. /// /// 3 public SharedMemory Parent { get; } /// /// This property represents the size (in bytes) of the shared memory. /// /// 3 public uint Size { get; } /// /// This property represents the offset (in bytes) from the start of the shared memory. /// /// 3 public uint Offset { get; } }; /// /// This type defines a parameter that is not referencing the shared memory, but carries instead small raw data /// passed by a value. /// /// 3 public sealed class Value : BaseParameter { /// /// Constructs a parameter object which holds information about integer values copied to or from TA. /// /// 3 /// User paramter A. /// User paramter B. /// The kind of access allowed for TA . public Value(uint a, uint b, TEFValueType type) : base(type) { this.A = a; this.B = b; } /// /// This property represents an unsigned integer A. /// /// 3 public uint A { get; } /// /// This property represents an unsigned integer B. /// /// 3 public uint B { get; } }; /// /// This type denotes a TEE Session, the logical container linking a client application with a particular trusted application. /// /// 3 public sealed class Session { private Interop.TEEC_Context context; private Interop.TEEC_Session session; internal Session(Interop.TEEC_Context context) { this.context = context; this.session = new Interop.TEEC_Session(); } ~Session() { Close(); } internal void Open(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist) { Interop.TEEC_UUID uuid = Interop.TEEC_UUID.ToTeecUuid(destination); Interop.TEEC_Operation op = new Interop.TEEC_Operation(); uint ro; int ret = Interop.Libteec.OpenSession(ref context, ref session, ref uuid, loginMethod, connectionData, ref op, out ro); //MAYBE map origin of return code to specyfic Exception Interop.CheckNThrowException(ret, string.Format("OpenSession('{0}')", destination)); } /// /// This function closes a session which has been opened with a trusted application. /// All commands within the session must be completed before this function can be called. /// /// 3 /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. public void Close() { Interop.Libteec.CloseSession(ref session); //session = null; } /// /// This function invokes a command within the specified session. /// The parameter commandID is an identifier that is used to indicate which of the exposed trusted /// application functions should be invoked. The supported command identifier values are defined by the /// trusted application's protocol. /// There can be up to four parameter objects given in the array. /// /// 3 /// The command. /// The array of parameters. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. /// The argument is wrong. public void InvokeCommand(uint commandID, Parameter[] paramlist) { Interop.TEEC_Operation op = new Interop.TEEC_Operation(); op.started=0; op.paramTypes=0; for (int i=0; i < 4; ++i) { Parameter p = paramlist[i]; //TODO fill TEEC_Operation struct } uint ro; int ret = Interop.Libteec.InvokeCommand(ref session, commandID, ref op, out ro); //MAYBE map origin of return code to specific Exception Interop.CheckNThrowException(ret, string.Format("InvokeCommand({0})", commandID)); } /// /// The asynchronous version of the InvokeCommand. /// /// 3 /// The command. /// The array of parameters. /// The token for task manipulation. /// Returns a task executing an invoke command in the background. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. /// One of the arguments is wrong. public async Task InvokeCommandAsync(uint commandID, Parameter[] paramlist, CancellationToken token = default(CancellationToken)) { await Task.Factory.StartNew(() => InvokeCommand(commandID, paramlist)); } }; /// /// This type denotes a TEE Context, the main logical container linking a Client Application with a particular TEE. /// /// 3 public sealed class Context : IDisposable { private Interop.TEEC_Context context; /// /// This function (constructor) initializes a new TEE Context, forming a connection between this client application and the /// TEE identified by the string identifier name (empty or null name denotes a default TEE). /// /// 3 /// The TEE name. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. public Context(string name) { context = new Interop.TEEC_Context(); if (name != null && name.Length == 0) name = null; int ret = Interop.Libteec.InitializeContext(name, ref context); Interop.CheckNThrowException(ret, string.Format("InititalizeContext('{0}')", name)); } ~Context() { Dispose(); } /// /// This function implements the IDisposable interface. /// /// 3 /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee public void Dispose() { Interop.Libteec.FinalizeContext(ref context); //context.imp = null; } /// /// This function opens a new session between the client application and the specified trusted application. /// The target trusted application is identified by an UUID passed in the parameter destination. /// There can be up to four parameter objects given in the array. /// /// 3 /// The UUID of the destination TA. /// The authentication algorithm . /// The data to be verified by a given login method. /// The parameters to be passed to TA open-session-callback. /// Returns opened session. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. /// One of the arguments is wrong. public Session OpenSession(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist) { Session ses = new Session(context); ses.Open(destination, loginMethod, connectionData, paramlist); return ses; } /// /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token). /// /// 3 /// The UUID of the destination TA. /// Returns opened session. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. public Session OpenSession(Guid destination) { Session ses = new Session(context); ses.Open(destination, LoginMethod.Public, null, null); return ses; } /// /// The asynchronous version of the OpenSession. /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token). /// /// 3 /// The UUID of the destination TA. /// The authentication algorithm . /// The data to be verified by a given login method. /// The parameters to be passed to the TA open-session-callback. /// The token for the task manipulation. /// Returns a Task executing the session open in the background. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. /// One of the arguments is wrong. public async Task OpenSessionAsync(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token = default(CancellationToken)) { Task task = Task.Factory.StartNew(() => { return OpenSession(destination, loginMethod, connectionData, paramlist); }); return await task; } /// /// The asynchronous version of the OpenSession. /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token). /// /// 3 /// The UUID of the destination TA. /// The token for a task manipulation. /// Returns a task executing session open in the background. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. public async Task OpenSessionAsync(Guid destination, CancellationToken token = default(CancellationToken)) { Task task = Task.Factory.StartNew(() => { return OpenSession(destination); }); return await task; } /// /// This function registers a block of the existing client application memory as a block of shared memory within /// the scope of the specified context, in accordance with the parameters. /// The input must point to the shared memory region to register. /// /// 3 /// The address of the shared memory. /// The size of the shared memory. /// The flags describing the access modes (Input and/or Output). /// Returns the SharedMemory handler. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. /// The argument is wrong. public SharedMemory RegisterSharedMemory(IntPtr memaddr, UInt32 size, SharedMemoryFlags flags) { Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory(); shm.buffer = memaddr; shm.size = size; shm.flags = (UInt32)flags; int ret = Interop.Libteec.RegisterSharedMemory(ref context, ref shm); Interop.CheckNThrowException(ret, "RegisterSharedMemory"); return new SharedMemory(shm); } /// /// This function allocates a new block of memory as a block of shared memory within the scope of the /// specified context, in accordance with the parameters. /// /// 3 /// The size of shared memory. /// The flags describing access modes (Input and/or Output). /// Returns the Shared Memory handler. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. public SharedMemory AllocateSharedMemory(UInt32 size, SharedMemoryFlags flags) { Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory(); shm.size = size; shm.flags = (UInt32)flags; int ret = Interop.Libteec.AllocateSharedMemory(ref context, ref shm); Interop.CheckNThrowException(ret, "AllocateSharedMemory"); return new SharedMemory(shm); } /// /// This function deregisters or deallocates a previously initialized block of the shared memory. /// /// /// For a memory buffer allocated using AllocateSharedMemory, the implementation must free the /// underlying memory and the client application must not access this region after this function has been /// called. In this case, the implementation must clear the buffer and size fields of the shared memory /// structure before returning. /// For memory registered using RegisterSharedMemory, the implementation must deregister the /// underlying memory from the TEE, but the memory region will stay available to the client application for /// other purposes as the memory is owned by it. /// /// 3 /// The shared memory object returned by RegisterSharedMemory or AllocateSharedMemory. /// http://tizen.org/privilege/tee.client /// partner /// http://tizen.org/feature/security.tee /// Thrown when an application does not have the privilege to access this method. /// The required feature is not supported. /// The operation is invalid. /// The argument is wrong. public void ReleaseSharedMemory(SharedMemory shm) { Interop.Libteec.ReleaseSharedMemory(ref shm.shm); } }; }