2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using System.Threading;
21 using System.Threading.Tasks;
22 using System.Runtime.CompilerServices;
25 namespace Tizen.Security.TEEC
28 /// This type denotes the Session Login Method used in OpenSession.
30 /// <since_tizen> 3 </since_tizen>
31 public class LoginMethod
33 /// <summary>No login data is provided.</summary>
34 /// <since_tizen> 3 </since_tizen>
35 public const uint Public = 0x00000000;
36 /// <summary>Login data about the user running the client application process is provided.</summary>
37 /// <since_tizen> 3 </since_tizen>
38 public const uint User = 0x00000001;
39 /// <summary>Login data about the group running the client application process is provided.</summary>
40 /// <since_tizen> 3 </since_tizen>
41 public const uint Group = 0x00000002;
42 /// <summary>Login data about the running client application itself is provided.</summary>
43 /// <since_tizen> 3 </since_tizen>
44 public const uint Application = 0x00000003;
48 /// This type denotes the Value parameter.
50 /// <since_tizen> 3 </since_tizen>
51 public enum TEFValueType : UInt32
53 /// <summary>The parameter is a ValueType tagged as the input.</summary>
55 /// <summary>The parameter is a ValueType tagged as the output.</summary>
57 /// <summary>The parameter is a ValueType tagged as both the input and the output.</summary>
62 /// This type denotes the TempMemoryReference parameter
63 /// describing a region of memory which needs to be temporarily registered for the duration of the operation.
65 /// <since_tizen> 3 </since_tizen>
66 public enum TEFTempMemoryType : UInt32
68 /// <summary>The parameter is a TempMemoryType and is tagged as the input.</summary>
70 /// <summary>Same as the input, but the Memory Reference is tagged as the output.</summary>
72 /// <summary>A Temporary Memory Reference tagged as both the input and the output.</summary>
77 /// This type denotes the SharedMemoryReference parameter.
79 /// <since_tizen> 3 </since_tizen>
80 public enum TEFRegisteredMemoryType : UInt32
82 /// <summary>The parameter is a registered memory reference that refers to the entirety of its parent shared memory block.</summary>
84 /// <summary>A registered memory reference structure that refers to a partial region of its parent shared mMemory block and is tagged as the input.</summary>
85 PartialInput = 0x0000000D,
86 /// <summary>A registered memory reference structure that refers to a partial region of its parent shared memory block and is tagged as the output.</summary>
87 PartialOutput = 0x0000000E,
88 /// <summary>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.</summary>
89 PartialInOut = 0x0000000F,
93 /// This type denotes the SharedMemory access direction.
95 /// <since_tizen> 3 </since_tizen>
97 public enum SharedMemoryFlags : UInt32
99 /// <summary>A flag indicates the shared memory can be read.</summary>
101 /// <summary>A flag indicates the shared memory can be written.</summary>
103 /// <summary>A flag indicates the shared memory can be read and written.</summary>
104 InOut = Input | Output,
108 /// This type denotes a shared memory block which has been either registered
109 /// with the implementation or allocated by it.
111 /// <since_tizen> 3 </since_tizen>
112 public sealed class SharedMemory
114 internal Interop.TEEC_SharedMemory shm;
115 internal IntPtr shmptr;
116 internal SharedMemory(ref Interop.TEEC_SharedMemory shm)
119 shmptr = Marshal.AllocHGlobal(Marshal.SizeOf(shm));
120 Marshal.StructureToPtr(shm, shmptr, false);
124 Marshal.FreeHGlobal(shmptr);
127 /// This property represents the shared memory size in bytes.
129 /// <since_tizen> 3 </since_tizen>
130 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
131 /// <privlevel>partner</privlevel>
134 get { return shm.size.ToUInt32(); }
137 /// This property represents the start address of the shared memory block.
139 /// <since_tizen> 3 </since_tizen>
140 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
141 /// <privlevel>partner</privlevel>
142 public IntPtr Address
144 get { return shm.buffer; }
148 /// This function makes a copy and is designed for convenient operations on small buffers.
149 /// For large buffers, the direct address should be used.
151 /// <since_tizen> 3 </since_tizen>
152 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
153 /// <privlevel>partner</privlevel>
154 /// <param name="data">The source data buffer to copy data from.</param>
155 /// <param name="dstOffs">The starting offset in the destination shared memory.</param>
156 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
157 public void SetData(byte[] data, int dstOffs)
159 Marshal.Copy(data, 0, shm.buffer + dstOffs, data.Length);
162 /// This function makes a copy and is designed for convenient operations on small buffers.
163 /// For large buffers, the direct address should be used.
165 /// <since_tizen> 3 </since_tizen>
166 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
167 /// <privlevel>partner</privlevel>
168 /// <param name="data">The destination data buffer to copy data into.</param>
169 /// <param name="srcOffs">The starting offset in the source shared memory.</param>
170 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
171 public void GetData(byte[] data, int srcOffs)
173 Marshal.Copy(shm.buffer + srcOffs, data, 0, data.Length);
178 /// This type defines the payload of either an open session operation or an invoke command operation. It is
179 /// also used for cancelation of operations, which may be desirable even if no payload is passed.
180 /// Parameters are used to exchange data between CA and TA.
182 /// <since_tizen> 3 </since_tizen>
183 public abstract class Parameter
185 internal Parameter(uint t)
189 internal uint NativeType { get; }
193 /// This type defines a template for the parameter types.
195 /// <since_tizen> 3 </since_tizen>
196 public abstract class BaseParameter<TEnum> : Parameter where TEnum : struct, IComparable, IFormattable, IConvertible // as close to Enum as possible
198 internal BaseParameter(TEnum t) : base((uint)(object)t)
204 /// This property represents the access type to this parameter.
206 /// <since_tizen> 3 </since_tizen>
207 public TEnum Type { get; }
211 /// This type defines a temporary memory reference.
213 /// <since_tizen> 3 </since_tizen>
214 public sealed class TempMemoryReference : BaseParameter<TEFTempMemoryType>
217 /// Constructs a parameter object which holds information about the temporary memory copied to or from TA.
219 /// <since_tizen> 3 </since_tizen>
220 /// <param name="buffer">The address of the allocated memory buffer.</param>
221 /// <param name="size">The size of the buffer.</param>
222 /// <param name="type">The kind of access allowed for TA <see cref="TEFTempMemoryType"/>.</param>
223 public TempMemoryReference(IntPtr buffer, uint size, TEFTempMemoryType type) :
226 this.Buffer = buffer;
230 /// This property represents the memory address of the buffer.
232 /// <since_tizen> 3 </since_tizen>
233 public IntPtr Buffer { get; }
235 /// This property represents the size of the buffer.
237 /// <since_tizen> 3 </since_tizen>
238 public uint Size { get; internal set; }
242 /// This type defines a memory reference that uses a pre-registered or pre-allocated shared memory block.
244 /// <since_tizen> 3 </since_tizen>
245 public sealed class RegisteredMemoryReference : BaseParameter<TEFRegisteredMemoryType>
248 /// Constructs a parameter object which holds information about the registered memory shared with TA.
250 /// <since_tizen> 3 </since_tizen>
251 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
252 /// <privlevel>partner</privlevel>
253 /// <param name="parent">The shared memory - registered or allocated.</param>
254 /// <param name="size">The size of the buffer part.</param>
255 /// <param name="offset">The offset of the buffer in the shared memory.</param>
256 /// <param name="type">The kind of access allowed for TA <see cref="TEFRegisteredMemoryType"/>.</param>
257 public RegisteredMemoryReference(SharedMemory parent, uint size, uint offset, TEFRegisteredMemoryType type) :
260 this.Parent = parent;
261 if (type == TEFRegisteredMemoryType.Whole) {
262 this.Size = parent.Size;
267 this.Offset = offset;
272 /// This property represents the shared memory that is referred to.
274 /// <since_tizen> 3 </since_tizen>
275 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
276 /// <privlevel>partner</privlevel>
277 public SharedMemory Parent { get; }
279 /// This property represents the size (in bytes) of the shared memory.
281 /// <since_tizen> 3 </since_tizen>
282 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
283 /// <privlevel>partner</privlevel>
284 public uint Size { get; internal set; }
286 /// This property represents the offset (in bytes) from the start of the shared memory.
288 /// <since_tizen> 3 </since_tizen>
289 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
290 /// <privlevel>partner</privlevel>
291 public uint Offset { get; }
295 /// This type defines a parameter that is not referencing the shared memory, but carries instead small raw data
296 /// passed by a value.
298 /// <since_tizen> 3 </since_tizen>
299 public sealed class Value : BaseParameter<TEFValueType>
302 /// Constructs a parameter object which holds information about integer values copied to or from TA.
304 /// <since_tizen> 3 </since_tizen>
305 /// <param name="a">User paramter A.</param>
306 /// <param name="b">User paramter B.</param>
307 /// <param name="type">The kind of access allowed for TA <see cref="TEFValueType"/>.</param>
308 public Value(uint a, uint b, TEFValueType type) :
315 /// This property represents an unsigned integer A.
317 /// <since_tizen> 3 </since_tizen>
318 public uint A { get; internal set; }
320 /// This property represents an unsigned integer B.
322 /// <since_tizen> 3 </since_tizen>
323 public uint B { get; internal set; }
328 /// This type denotes a TEE Session, the logical container linking a client application with a particular trusted application.
330 /// <since_tizen> 3 </since_tizen>
331 public sealed class Session : IDisposable
333 private bool disposed = false;
334 private bool opened = false;
335 private Context context;
336 private IntPtr session_imp;
337 private IntPtr opptr;
338 private SharedMemory[] shm = new SharedMemory[4];
340 internal Session(Context context) {
341 this.context = context;
342 this.session_imp = Marshal.AllocHGlobal(Marshal.SizeOf<Interop.TEEC_Session>());
343 this.opptr = Marshal.AllocHGlobal(Marshal.SizeOf<Interop.TEEC_Operation64>());
344 for (int i=0; i < 4; ++i) shm[i] = null;
347 // internal since class is sealed
348 internal void Dispose(bool disposing)
354 Interop.Libteec.CloseSession(session_imp);
357 Marshal.FreeHGlobal(this.opptr);
358 Marshal.FreeHGlobal(this.session_imp);
359 this.opptr = IntPtr.Zero;
360 this.session_imp = IntPtr.Zero;
365 /// Destructor of the class.
373 /// Disposable interface implememtation.
375 public void Dispose()
380 internal UInt32 InitParam(ref Interop.TEEC_Parameter32[] dst, int i, Parameter src)
382 if (IntPtr.Size != 4) throw new Exception("wrong arch - not 32bit");
383 UInt32 rType = src.NativeType;
384 switch (src.NativeType) {
385 case (int)TEFValueType.Input:
386 case (int)TEFValueType.Output:
387 case (int)TEFValueType.InOut:
388 dst[i].value.a = ((Value)src).A;
389 dst[i].value.b = ((Value)src).B;
392 case (int)TEFTempMemoryType.Input:
393 case (int)TEFTempMemoryType.Output:
394 case (int)TEFTempMemoryType.InOut:
395 byte[] mem = new byte[(uint)((TempMemoryReference)src).Size];
396 Marshal.Copy(((TempMemoryReference)src).Buffer, mem, 0, mem.Length);
397 shm[i] = context.AllocateSharedMemory((uint)mem.Length, SharedMemoryFlags.InOut);
398 Marshal.Copy(mem, 0, shm[i].shm.buffer, mem.Length);
399 dst[i].tmpref.size = (uint)mem.Length;
400 dst[i].tmpref.buffer = shm[i].shm.buffer.ToInt32();
403 case (int)TEFRegisteredMemoryType.Whole:
404 RegisteredMemoryReference rmrw = (RegisteredMemoryReference)src;
405 rType = ((int)TEFRegisteredMemoryType.PartialInput & (int)TEFRegisteredMemoryType.PartialOutput) | rmrw.Parent.shm.flags;
406 dst[i].memref.parent = rmrw.Parent.shmptr.ToInt32();
407 dst[i].memref.size = rmrw.Size;
408 dst[i].memref.offset = rmrw.Offset;
411 case (int)TEFRegisteredMemoryType.PartialInput:
412 case (int)TEFRegisteredMemoryType.PartialOutput:
413 case (int)TEFRegisteredMemoryType.PartialInOut:
414 RegisteredMemoryReference rmr = (RegisteredMemoryReference)src;
415 dst[i].memref.parent = rmr.Parent.shmptr.ToInt32();
416 dst[i].memref.size = rmr.Size;
417 dst[i].memref.offset = rmr.Offset;
425 internal void UpdateParam(Interop.TEEC_Parameter32 src, ref Parameter[] dst, int i)
427 if (IntPtr.Size != 4) throw new Exception("wrong arch - not 32bit");
428 switch (dst[i].NativeType) {
429 case (int)TEFValueType.Input:
430 case (int)TEFValueType.Output:
431 case (int)TEFValueType.InOut:
432 ((Value)dst[i]).A = src.value.a;
433 ((Value)dst[i]).B = src.value.b;
436 case (int)TEFTempMemoryType.Input:
437 case (int)TEFTempMemoryType.Output:
438 case (int)TEFTempMemoryType.InOut:
439 byte[] mem = new byte[src.tmpref.size];
440 Marshal.Copy(shm[i].shm.buffer, mem, 0, mem.Length);
441 Marshal.Copy(mem, 0, ((TempMemoryReference)dst[i]).Buffer, mem.Length);
442 ((TempMemoryReference)dst[i]).Size = src.tmpref.size;
445 case (int)TEFRegisteredMemoryType.Whole:
446 case (int)TEFRegisteredMemoryType.PartialInput:
447 case (int)TEFRegisteredMemoryType.PartialOutput:
448 case (int)TEFRegisteredMemoryType.PartialInOut:
449 ((RegisteredMemoryReference)dst[i]).Size = src.memref.size;
456 static internal Interop.TEEC_Operation32 Create_TEEC_Operation32() {
457 Interop.TEEC_Operation32 op = new Interop.TEEC_Operation32();
460 op.paramlist = new Interop.TEEC_Parameter32[4];
464 internal UInt32 InitParam(ref Interop.TEEC_Parameter64[] dst, int i, Parameter src)
466 if (IntPtr.Size != 8) throw new Exception("wrong arch - not 64bit");
467 UInt32 rType = src.NativeType;
468 switch (src.NativeType) {
469 case (int)TEFValueType.Input:
470 case (int)TEFValueType.Output:
471 case (int)TEFValueType.InOut:
472 dst[i].value.a = ((Value)src).A;
473 dst[i].value.b = ((Value)src).B;
476 case (int)TEFTempMemoryType.Input:
477 case (int)TEFTempMemoryType.Output:
478 case (int)TEFTempMemoryType.InOut:
479 byte[] mem = new byte[(uint)((TempMemoryReference)src).Size];
480 Marshal.Copy(((TempMemoryReference)src).Buffer, mem, 0, mem.Length);
481 shm[i] = context.AllocateSharedMemory((uint)mem.Length, SharedMemoryFlags.InOut);
482 Marshal.Copy(mem, 0, shm[i].shm.buffer, mem.Length);
483 dst[i].tmpref.size = (UInt64)mem.Length;
484 dst[i].tmpref.buffer = shm[i].shm.buffer.ToInt64();
487 case (int)TEFRegisteredMemoryType.Whole:
488 RegisteredMemoryReference rmrw = (RegisteredMemoryReference)src;
489 rType = ((int)TEFRegisteredMemoryType.PartialInput & (int)TEFRegisteredMemoryType.PartialOutput) | rmrw.Parent.shm.flags;
490 dst[i].memref.parent = rmrw.Parent.shmptr.ToInt64();
491 dst[i].memref.size = rmrw.Size;
492 dst[i].memref.offset = rmrw.Offset;
495 case (int)TEFRegisteredMemoryType.PartialInput:
496 case (int)TEFRegisteredMemoryType.PartialOutput:
497 case (int)TEFRegisteredMemoryType.PartialInOut:
498 RegisteredMemoryReference rmr = (RegisteredMemoryReference)src;
499 dst[i].memref.parent = rmr.Parent.shmptr.ToInt64();
500 dst[i].memref.size = rmr.Size;
501 dst[i].memref.offset = rmr.Offset;
510 internal void UpdateParam(Interop.TEEC_Parameter64 src, ref Parameter[] dst, int i)
512 if (IntPtr.Size != 8) throw new Exception("wrong arch - not 64bit");
513 switch (dst[i].NativeType) {
514 case (int)TEFValueType.Input:
515 case (int)TEFValueType.Output:
516 case (int)TEFValueType.InOut:
517 ((Value)dst[i]).A = src.value.a;
518 ((Value)dst[i]).B = src.value.b;
521 case (int)TEFTempMemoryType.Input:
522 case (int)TEFTempMemoryType.Output:
523 case (int)TEFTempMemoryType.InOut:
524 byte[] mem = new byte[src.tmpref.size];
525 Marshal.Copy(shm[i].shm.buffer, mem, 0, mem.Length);
526 Marshal.Copy(mem, 0, ((TempMemoryReference)dst[i]).Buffer, mem.Length);
527 ((TempMemoryReference)dst[i]).Size = (uint)src.tmpref.size;
530 case (int)TEFRegisteredMemoryType.Whole:
531 case (int)TEFRegisteredMemoryType.PartialInput:
532 case (int)TEFRegisteredMemoryType.PartialOutput:
533 case (int)TEFRegisteredMemoryType.PartialInOut:
534 ((RegisteredMemoryReference)dst[i]).Size = (uint)src.memref.size;
541 static internal Interop.TEEC_Operation64 Create_TEEC_Operation64() {
542 Interop.TEEC_Operation64 op = new Interop.TEEC_Operation64();
545 op.paramlist = new Interop.TEEC_Parameter64[4];
549 internal void Open32(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist)
551 Interop.TEEC_UUID uuid = Interop.TEEC_UUID.ToTeecUuid(destination);
555 if (paramlist != null) {
556 Interop.TEEC_Operation32 op = Create_TEEC_Operation32();
557 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
558 op.paramTypes |= InitParam(ref op.paramlist, i, paramlist[i]) << (8*i);
560 Marshal.StructureToPtr(op, opptr, false);
561 ret = Interop.Libteec.OpenSession(context.context_imp, session_imp, ref uuid, loginMethod, connectionData, opptr, out ro);
562 op = Marshal.PtrToStructure<Interop.TEEC_Operation32>(opptr);
563 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
564 UpdateParam(op.paramlist[i], ref paramlist, i);
568 ret = Interop.Libteec.OpenSession(context.context_imp, session_imp, ref uuid, loginMethod, connectionData, IntPtr.Zero, out ro);
571 for (int i=0; i < 4; ++i) {
572 if (shm[i] != null) {
573 context.ReleaseSharedMemory(shm[i]);
578 //MAYBE map origin of return code to specyfic Exception
579 Interop.CheckNThrowException(ret, string.Format("OpenSession('{0}')", destination));
582 internal void Open64(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist)
584 Interop.TEEC_UUID uuid = Interop.TEEC_UUID.ToTeecUuid(destination);
588 if (paramlist != null) {
589 Interop.TEEC_Operation64 op = Create_TEEC_Operation64();
590 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
591 op.paramTypes |= InitParam(ref op.paramlist, i, paramlist[i]) << (8*i);
593 Marshal.StructureToPtr(op, opptr, false);
594 ret = Interop.Libteec.OpenSession(context.context_imp, session_imp, ref uuid, loginMethod, connectionData, opptr, out ro);
595 op = Marshal.PtrToStructure<Interop.TEEC_Operation64>(opptr);
596 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
597 UpdateParam(op.paramlist[i], ref paramlist, i);
601 ret = Interop.Libteec.OpenSession(context.context_imp, session_imp, ref uuid, loginMethod, connectionData, IntPtr.Zero, out ro);
604 for (int i=0; i < 4; ++i) {
605 if (shm[i] != null) {
606 context.ReleaseSharedMemory(shm[i]);
611 //MAYBE map origin of return code to specyfic Exception
612 Interop.CheckNThrowException(ret, string.Format("OpenSession('{0}')", destination));
617 /// This function closes a session which has been opened with a trusted application.
618 /// All commands within the session must be completed before this function can be called.
620 /// <since_tizen> 3 </since_tizen>
621 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
622 /// <privlevel>partner</privlevel>
623 /// <feature>http://tizen.org/feature/security.tee</feature>
624 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
625 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
626 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
627 public void Close() {
629 GC.SuppressFinalize(this);
633 /// This function invokes a command within the specified session.
634 /// The parameter commandID is an identifier that is used to indicate which of the exposed trusted
635 /// application functions should be invoked. The supported command identifier values are defined by the
636 /// trusted application's protocol.
637 /// There can be up to four parameter objects given in the <paramref name="paramlist"/> array.
639 /// <since_tizen> 3 </since_tizen>
640 /// <param name="commandID">The command.</param>
641 /// <param name="paramlist">The array of parameters.</param>
642 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
643 /// <privlevel>partner</privlevel>
644 /// <feature>http://tizen.org/feature/security.tee</feature>
645 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
646 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
647 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
648 /// <exception cref="ArgumentException">The argument <paramref name="paramlist"/> is wrong.</exception>
649 public void InvokeCommand(uint commandID, Parameter[] paramlist)
653 if (paramlist != null) {
654 if (IntPtr.Size == 4) {
655 Interop.TEEC_Operation32 op = Create_TEEC_Operation32();
656 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
657 op.paramTypes |= InitParam(ref op.paramlist, i, paramlist[i]) << (8*i);
659 Marshal.StructureToPtr(op, opptr, false);
660 ret = Interop.Libteec.InvokeCommand(session_imp, commandID, opptr, out ro);
661 op = Marshal.PtrToStructure<Interop.TEEC_Operation32>(opptr);
662 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
663 UpdateParam(op.paramlist[i], ref paramlist, i);
667 Interop.TEEC_Operation64 op = Create_TEEC_Operation64();
668 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
669 op.paramTypes |= InitParam(ref op.paramlist, i, paramlist[i]) << (8*i);
671 Marshal.StructureToPtr(op, opptr, false);
672 ret = Interop.Libteec.InvokeCommand(session_imp, commandID, opptr, out ro);
673 op = Marshal.PtrToStructure<Interop.TEEC_Operation64>(opptr);
674 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
675 UpdateParam(op.paramlist[i], ref paramlist, i);
680 ret = Interop.Libteec.InvokeCommand(session_imp, commandID, IntPtr.Zero, out ro);
683 for (int i=0; i < 4; ++i) {
684 if (shm[i] != null) {
685 context.ReleaseSharedMemory(shm[i]);
690 //MAYBE map origin of return code to specific Exception
691 Interop.CheckNThrowException(ret, string.Format("InvokeCommand({0})", commandID));
695 /// The asynchronous version of the InvokeCommand.
697 /// <since_tizen> 3 </since_tizen>
698 /// <param name="commandID">The command.</param>
699 /// <param name="paramlist">The array of parameters.</param>
700 /// <param name="token">The token for task manipulation.</param>
701 /// <returns>Returns a task executing an invoke command in the background.</returns>
702 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
703 /// <privlevel>partner</privlevel>
704 /// <feature>http://tizen.org/feature/security.tee</feature>
705 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
706 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
707 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
708 /// <exception cref="ArgumentException">One of the arguments is wrong.</exception>
709 public async Task InvokeCommandAsync(uint commandID, Parameter[] paramlist, CancellationToken token = default(CancellationToken))
711 await Task.Factory.StartNew(() => InvokeCommand(commandID, paramlist));
717 /// This type denotes a TEE Context, the main logical container linking a Client Application with a particular TEE.
719 /// <since_tizen> 3 </since_tizen>
720 public sealed class Context : IDisposable
722 private bool disposed = false;
723 private bool initialized = false;
724 internal IntPtr context_imp;
727 /// This function (constructor) initializes a new TEE Context, forming a connection between this client application and the
728 /// TEE identified by the string identifier name (empty or null name denotes a default TEE).
730 /// <since_tizen> 3 </since_tizen>
731 /// <param name="name">The TEE name.</param>
732 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
733 /// <privlevel>partner</privlevel>
734 /// <feature>http://tizen.org/feature/security.tee</feature>
735 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
736 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
737 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
738 public Context(string name)
740 context_imp = Marshal.AllocHGlobal(Marshal.SizeOf<Interop.TEEC_Context>());
741 if (name != null && name.Length == 0)
744 int ret = Interop.Libteec.InitializeContext(name, context_imp);
745 Interop.CheckNThrowException(ret, string.Format("InititalizeContext('{0}')", name));
748 catch (global::System.DllNotFoundException e)
751 Interop.CheckNThrowException((int)Interop.LibteecError.NotImplemented, "Not found: " + e.Message);
756 // internal since class is sealed
757 internal void Dispose(bool disposing)
763 Interop.Libteec.FinalizeContext(context_imp);
765 Marshal.FreeHGlobal(context_imp);
766 context_imp = IntPtr.Zero;
771 /// Destructor of the class.
779 /// This function implements the IDisposable interface.
781 /// <since_tizen> 3 </since_tizen>
782 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
783 /// <privlevel>partner</privlevel>
784 /// <feature>http://tizen.org/feature/security.tee</feature>
785 public void Dispose() {
787 GC.SuppressFinalize(this);
791 /// This function opens a new session between the client application and the specified trusted application.
792 /// The target trusted application is identified by an UUID passed in the parameter destination.
793 /// There can be up to four parameter objects given in the <paramref name="paramlist"/> array.
795 /// <since_tizen> 3 </since_tizen>
796 /// <param name="destination">The UUID of the destination TA.</param>
797 /// <param name="loginMethod">The authentication algorithm <see cref="LoginMethod" />.</param>
798 /// <param name="connectionData">The data to be verified by a given login method.</param>
799 /// <param name="paramlist">The parameters to be passed to TA open-session-callback.</param>
800 /// <returns>Returns opened session.</returns>
801 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
802 /// <privlevel>partner</privlevel>
803 /// <feature>http://tizen.org/feature/security.tee</feature>
804 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
805 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
806 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
807 /// <exception cref="ArgumentException">One of the arguments is wrong.</exception>
808 public Session OpenSession(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist)
810 Session ses = new Session(this);
811 if (IntPtr.Size == 4)
812 ses.Open32(destination, loginMethod, connectionData, paramlist);
813 else if (IntPtr.Size == 8)
814 ses.Open64(destination, loginMethod, connectionData, paramlist);
815 else throw new NotSupportedException("unsupported arch");
819 /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token).
821 /// <since_tizen> 3 </since_tizen>
822 /// <param name="destination">The UUID of the destination TA.</param>
823 /// <returns>Returns opened session.</returns>
824 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
825 /// <privlevel>partner</privlevel>
826 /// <feature>http://tizen.org/feature/security.tee</feature>
827 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
828 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
829 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
830 public Session OpenSession(Guid destination)
832 Session ses = new Session(this);
833 if (IntPtr.Size == 4)
834 ses.Open32(destination, LoginMethod.Public, null, null);
835 else if (IntPtr.Size == 8)
836 ses.Open64(destination, LoginMethod.Public, null, null);
837 else throw new NotSupportedException("unsupported arch");
842 /// The asynchronous version of the OpenSession.
843 /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token).
845 /// <since_tizen> 3 </since_tizen>
846 /// <param name="destination">The UUID of the destination TA.</param>
847 /// <param name="loginMethod">The authentication algorithm <see cref="LoginMethod" />.</param>
848 /// <param name="connectionData">The data to be verified by a given login method.</param>
849 /// <param name="paramlist">The parameters to be passed to the TA open-session-callback.</param>
850 /// <param name="token">The token for the task manipulation.</param>
851 /// <returns>Returns a Task executing the session open in the background.</returns>
852 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
853 /// <privlevel>partner</privlevel>
854 /// <feature>http://tizen.org/feature/security.tee</feature>
855 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
856 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
857 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
858 /// <exception cref="ArgumentException">One of the arguments is wrong.</exception>
859 public async Task<Session> OpenSessionAsync(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token = default(CancellationToken))
861 Task<Session> task = Task<Session>.Factory.StartNew(() =>
863 return OpenSession(destination, loginMethod, connectionData, paramlist);
868 /// The asynchronous version of the OpenSession.
869 /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token).
871 /// <since_tizen> 3 </since_tizen>
872 /// <param name="destination">The UUID of the destination TA.</param>
873 /// <param name="token">The token for a task manipulation.</param>
874 /// <returns>Returns a task executing session open in the background.</returns>
875 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
876 /// <privlevel>partner</privlevel>
877 /// <feature>http://tizen.org/feature/security.tee</feature>
878 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
879 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
880 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
881 public async Task<Session> OpenSessionAsync(Guid destination, CancellationToken token = default(CancellationToken))
883 Task<Session> task = Task<Session>.Factory.StartNew(() =>
885 return OpenSession(destination);
891 /// This function registers a block of the existing client application memory as a block of shared memory within
892 /// the scope of the specified context, in accordance with the parameters.
893 /// The input <paramref name="memaddr"/> must point to the shared memory region to register.
895 /// <since_tizen> 3 </since_tizen>
896 /// <param name="memaddr">The address of the shared memory.</param>
897 /// <param name="size">The size of the shared memory.</param>
898 /// <param name="flags">The flags describing the access modes (Input and/or Output).</param>
899 /// <returns>Returns the SharedMemory handler.</returns>
900 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
901 /// <privlevel>partner</privlevel>
902 /// <feature>http://tizen.org/feature/security.tee</feature>
903 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
904 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
905 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
906 /// <exception cref="ArgumentException">The argument <paramref name="memaddr"/> is wrong.</exception>
907 public SharedMemory RegisterSharedMemory(IntPtr memaddr, UInt32 size, SharedMemoryFlags flags)
909 Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory();
910 shm.buffer = memaddr;
911 shm.size = new UIntPtr(size);
912 shm.flags = (UInt32)flags;
913 int ret = Interop.Libteec.RegisterSharedMemory(context_imp, ref shm);
914 Interop.CheckNThrowException(ret, "RegisterSharedMemory");
915 return new SharedMemory(ref shm);
919 /// This function allocates a new block of memory as a block of shared memory within the scope of the
920 /// specified context, in accordance with the parameters.
922 /// <since_tizen> 3 </since_tizen>
923 /// <param name="size">The size of shared memory.</param>
924 /// <param name="flags">The flags describing access modes (Input and/or Output).</param>
925 /// <returns>Returns the Shared Memory handler.</returns>
926 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
927 /// <privlevel>partner</privlevel>
928 /// <feature>http://tizen.org/feature/security.tee</feature>
929 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
930 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
931 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
932 public SharedMemory AllocateSharedMemory(UInt32 size, SharedMemoryFlags flags)
934 Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory();
935 shm.size = new UIntPtr(size);
936 shm.flags = (UInt32)flags;
937 int ret = Interop.Libteec.AllocateSharedMemory(context_imp, ref shm);
938 Interop.CheckNThrowException(ret, "AllocateSharedMemory");
939 return new SharedMemory(ref shm);
943 /// This function deregisters or deallocates a previously initialized block of the shared memory.
946 /// For a memory buffer allocated using AllocateSharedMemory, the implementation must free the
947 /// underlying memory and the client application must not access this region after this function has been
948 /// called. In this case, the implementation must clear the buffer and size fields of the shared memory
949 /// structure before returning.
950 /// For memory registered using RegisterSharedMemory, the implementation must deregister the
951 /// underlying memory from the TEE, but the memory region will stay available to the client application for
952 /// other purposes as the memory is owned by it.
954 /// <since_tizen> 3 </since_tizen>
955 /// <param name="shm">The shared memory object returned by RegisterSharedMemory or AllocateSharedMemory.</param>
956 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
957 /// <privlevel>partner</privlevel>
958 /// <feature>http://tizen.org/feature/security.tee</feature>
959 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
960 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
961 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
962 /// <exception cref="ArgumentException">The argument is wrong.</exception>
963 public void ReleaseSharedMemory(SharedMemory shm)
965 Interop.Libteec.ReleaseSharedMemory(ref shm.shm);