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 : IDisposable
114 private bool disposed = false;
115 private bool initialized = false;
116 private Context context; // keep reference for correct finalizers order
117 internal Interop.TEEC_SharedMemory shm;
118 internal IntPtr shmptr;
119 internal SharedMemory(Context context)
121 this.context = context;
122 shmptr = Marshal.AllocHGlobal(Marshal.SizeOf<Interop.TEEC_SharedMemory>());
124 internal void setShm(ref Interop.TEEC_SharedMemory shm)
127 Marshal.StructureToPtr(shm, shmptr, false);
131 private void Dispose(bool disposing)
136 if (context == null) {
137 throw new Exception("internal error: context is null");
140 Interop.Libteec.ReleaseSharedMemory(ref shm);
144 Marshal.FreeHGlobal(shmptr);
145 shmptr = IntPtr.Zero;
151 /// Destructor of the class.
159 /// Disposable interface implememtation.
161 public void Dispose()
164 GC.SuppressFinalize(this);
168 /// This property represents the shared memory size in bytes.
170 /// <since_tizen> 3 </since_tizen>
171 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
172 /// <privlevel>partner</privlevel>
175 get { return shm.size.ToUInt32(); }
178 /// This property represents the start address of the shared memory block.
180 /// <since_tizen> 3 </since_tizen>
181 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
182 /// <privlevel>partner</privlevel>
183 public IntPtr Address
185 get { return shm.buffer; }
189 /// This function makes a copy and is designed for convenient operations on small buffers.
190 /// For large buffers, the direct address should be used.
192 /// <since_tizen> 3 </since_tizen>
193 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
194 /// <privlevel>partner</privlevel>
195 /// <param name="data">The source data buffer to copy data from.</param>
196 /// <param name="dstOffs">The starting offset in the destination shared memory.</param>
197 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
198 public void SetData(byte[] data, int dstOffs)
200 Marshal.Copy(data, 0, shm.buffer + dstOffs, data.Length);
203 /// This function makes a copy and is designed for convenient operations on small buffers.
204 /// For large buffers, the direct address should be used.
206 /// <since_tizen> 3 </since_tizen>
207 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
208 /// <privlevel>partner</privlevel>
209 /// <param name="data">The destination data buffer to copy data into.</param>
210 /// <param name="srcOffs">The starting offset in the source shared memory.</param>
211 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
212 public void GetData(byte[] data, int srcOffs)
214 Marshal.Copy(shm.buffer + srcOffs, data, 0, data.Length);
219 /// This type defines the payload of either an open session operation or an invoke command operation. It is
220 /// also used for cancelation of operations, which may be desirable even if no payload is passed.
221 /// Parameters are used to exchange data between CA and TA.
223 /// <since_tizen> 3 </since_tizen>
224 public abstract class Parameter
226 internal Parameter(uint t)
230 internal uint NativeType { get; }
234 /// This type defines a template for the parameter types.
236 /// <since_tizen> 3 </since_tizen>
237 public abstract class BaseParameter<TEnum> : Parameter where TEnum : struct, IComparable, IFormattable, IConvertible // as close to Enum as possible
239 internal BaseParameter(TEnum t) : base((uint)(object)t)
245 /// This property represents the access type to this parameter.
247 /// <since_tizen> 3 </since_tizen>
248 public TEnum Type { get; }
252 /// This type defines a temporary memory reference.
254 /// <since_tizen> 3 </since_tizen>
255 public sealed class TempMemoryReference : BaseParameter<TEFTempMemoryType>
258 /// Constructs a parameter object which holds information about the temporary memory copied to or from TA.
260 /// <since_tizen> 3 </since_tizen>
261 /// <param name="buffer">The address of the allocated memory buffer.</param>
262 /// <param name="size">The size of the buffer.</param>
263 /// <param name="type">The kind of access allowed for TA <see cref="TEFTempMemoryType"/>.</param>
264 public TempMemoryReference(IntPtr buffer, uint size, TEFTempMemoryType type) :
267 this.Buffer = buffer;
271 /// This property represents the memory address of the buffer.
273 /// <since_tizen> 3 </since_tizen>
274 public IntPtr Buffer { get; }
276 /// This property represents the size of the buffer.
278 /// <since_tizen> 3 </since_tizen>
279 public uint Size { get; internal set; }
283 /// This type defines a memory reference that uses a pre-registered or pre-allocated shared memory block.
285 /// <since_tizen> 3 </since_tizen>
286 public sealed class RegisteredMemoryReference : BaseParameter<TEFRegisteredMemoryType>
289 /// Constructs a parameter object which holds information about the registered memory shared with TA.
291 /// <since_tizen> 3 </since_tizen>
292 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
293 /// <privlevel>partner</privlevel>
294 /// <param name="parent">The shared memory - registered or allocated.</param>
295 /// <param name="size">The size of the buffer part.</param>
296 /// <param name="offset">The offset of the buffer in the shared memory.</param>
297 /// <param name="type">The kind of access allowed for TA <see cref="TEFRegisteredMemoryType"/>.</param>
298 public RegisteredMemoryReference(SharedMemory parent, uint size, uint offset, TEFRegisteredMemoryType type) :
301 this.Parent = parent;
302 if (type == TEFRegisteredMemoryType.Whole) {
303 this.Size = parent.Size;
308 this.Offset = offset;
313 /// This property represents the shared memory that is referred to.
315 /// <since_tizen> 3 </since_tizen>
316 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
317 /// <privlevel>partner</privlevel>
318 public SharedMemory Parent { get; }
320 /// This property represents the size (in bytes) of the shared memory.
322 /// <since_tizen> 3 </since_tizen>
323 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
324 /// <privlevel>partner</privlevel>
325 public uint Size { get; internal set; }
327 /// This property represents the offset (in bytes) from the start of the shared memory.
329 /// <since_tizen> 3 </since_tizen>
330 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
331 /// <privlevel>partner</privlevel>
332 public uint Offset { get; }
336 /// This type defines a parameter that is not referencing the shared memory, but carries instead small raw data
337 /// passed by a value.
339 /// <since_tizen> 3 </since_tizen>
340 public sealed class Value : BaseParameter<TEFValueType>
343 /// Constructs a parameter object which holds information about integer values copied to or from TA.
345 /// <since_tizen> 3 </since_tizen>
346 /// <param name="a">User paramter A.</param>
347 /// <param name="b">User paramter B.</param>
348 /// <param name="type">The kind of access allowed for TA <see cref="TEFValueType"/>.</param>
349 public Value(uint a, uint b, TEFValueType type) :
356 /// This property represents an unsigned integer A.
358 /// <since_tizen> 3 </since_tizen>
359 public uint A { get; internal set; }
361 /// This property represents an unsigned integer B.
363 /// <since_tizen> 3 </since_tizen>
364 public uint B { get; internal set; }
369 /// This type denotes a TEE Session, the logical container linking a client application with a particular trusted application.
371 /// <since_tizen> 3 </since_tizen>
372 public sealed class Session : IDisposable
374 private bool disposed = false;
375 private bool opened = false;
376 private Context context;
377 private IntPtr session_imp;
378 private IntPtr opptr;
379 private SharedMemory[] shm = new SharedMemory[4];
381 internal Session(Context context) {
382 this.context = context;
383 this.session_imp = Marshal.AllocHGlobal(Marshal.SizeOf<Interop.TEEC_Session>());
384 this.opptr = Marshal.AllocHGlobal(Marshal.SizeOf<Interop.TEEC_Operation64>());
385 for (int i=0; i < 4; ++i) shm[i] = null;
388 private void Dispose(bool disposing)
394 Interop.Libteec.CloseSession(session_imp);
397 Marshal.FreeHGlobal(this.opptr);
398 Marshal.FreeHGlobal(this.session_imp);
399 this.opptr = IntPtr.Zero;
400 this.session_imp = IntPtr.Zero;
405 /// Destructor of the class.
413 /// Disposable interface implememtation.
415 public void Dispose()
418 GC.SuppressFinalize(this);
421 internal UInt32 InitParam(ref Interop.TEEC_Parameter32[] dst, int i, Parameter src)
423 if (IntPtr.Size != 4) throw new Exception("wrong arch - not 32bit");
424 UInt32 rType = src.NativeType;
425 switch (src.NativeType) {
426 case (int)TEFValueType.Input:
427 case (int)TEFValueType.Output:
428 case (int)TEFValueType.InOut:
429 dst[i].value.a = ((Value)src).A;
430 dst[i].value.b = ((Value)src).B;
433 case (int)TEFTempMemoryType.Input:
434 case (int)TEFTempMemoryType.Output:
435 case (int)TEFTempMemoryType.InOut:
436 byte[] mem = new byte[(uint)((TempMemoryReference)src).Size];
437 Marshal.Copy(((TempMemoryReference)src).Buffer, mem, 0, mem.Length);
438 shm[i] = context.AllocateSharedMemory((uint)mem.Length, SharedMemoryFlags.InOut);
439 Marshal.Copy(mem, 0, shm[i].shm.buffer, mem.Length);
440 dst[i].tmpref.size = (uint)mem.Length;
441 dst[i].tmpref.buffer = shm[i].shm.buffer.ToInt32();
444 case (int)TEFRegisteredMemoryType.Whole:
445 RegisteredMemoryReference rmrw = (RegisteredMemoryReference)src;
446 rType = ((int)TEFRegisteredMemoryType.PartialInput & (int)TEFRegisteredMemoryType.PartialOutput) | rmrw.Parent.shm.flags;
447 dst[i].memref.parent = rmrw.Parent.shmptr.ToInt32();
448 dst[i].memref.size = rmrw.Size;
449 dst[i].memref.offset = rmrw.Offset;
452 case (int)TEFRegisteredMemoryType.PartialInput:
453 case (int)TEFRegisteredMemoryType.PartialOutput:
454 case (int)TEFRegisteredMemoryType.PartialInOut:
455 RegisteredMemoryReference rmr = (RegisteredMemoryReference)src;
456 dst[i].memref.parent = rmr.Parent.shmptr.ToInt32();
457 dst[i].memref.size = rmr.Size;
458 dst[i].memref.offset = rmr.Offset;
466 internal void UpdateParam(Interop.TEEC_Parameter32 src, ref Parameter[] dst, int i)
468 if (IntPtr.Size != 4) throw new Exception("wrong arch - not 32bit");
469 switch (dst[i].NativeType) {
470 case (int)TEFValueType.Input:
471 case (int)TEFValueType.Output:
472 case (int)TEFValueType.InOut:
473 ((Value)dst[i]).A = src.value.a;
474 ((Value)dst[i]).B = src.value.b;
477 case (int)TEFTempMemoryType.Input:
478 case (int)TEFTempMemoryType.Output:
479 case (int)TEFTempMemoryType.InOut:
480 byte[] mem = new byte[src.tmpref.size];
481 Marshal.Copy(shm[i].shm.buffer, mem, 0, mem.Length);
482 Marshal.Copy(mem, 0, ((TempMemoryReference)dst[i]).Buffer, mem.Length);
483 ((TempMemoryReference)dst[i]).Size = src.tmpref.size;
486 case (int)TEFRegisteredMemoryType.Whole:
487 case (int)TEFRegisteredMemoryType.PartialInput:
488 case (int)TEFRegisteredMemoryType.PartialOutput:
489 case (int)TEFRegisteredMemoryType.PartialInOut:
490 ((RegisteredMemoryReference)dst[i]).Size = src.memref.size;
497 static internal Interop.TEEC_Operation32 Create_TEEC_Operation32() {
498 Interop.TEEC_Operation32 op = new Interop.TEEC_Operation32();
501 op.paramlist = new Interop.TEEC_Parameter32[4];
505 internal UInt32 InitParam(ref Interop.TEEC_Parameter64[] dst, int i, Parameter src)
507 if (IntPtr.Size != 8) throw new Exception("wrong arch - not 64bit");
508 UInt32 rType = src.NativeType;
509 switch (src.NativeType) {
510 case (int)TEFValueType.Input:
511 case (int)TEFValueType.Output:
512 case (int)TEFValueType.InOut:
513 dst[i].value.a = ((Value)src).A;
514 dst[i].value.b = ((Value)src).B;
517 case (int)TEFTempMemoryType.Input:
518 case (int)TEFTempMemoryType.Output:
519 case (int)TEFTempMemoryType.InOut:
520 byte[] mem = new byte[(uint)((TempMemoryReference)src).Size];
521 Marshal.Copy(((TempMemoryReference)src).Buffer, mem, 0, mem.Length);
522 shm[i] = context.AllocateSharedMemory((uint)mem.Length, SharedMemoryFlags.InOut);
523 Marshal.Copy(mem, 0, shm[i].shm.buffer, mem.Length);
524 dst[i].tmpref.size = (UInt64)mem.Length;
525 dst[i].tmpref.buffer = shm[i].shm.buffer.ToInt64();
528 case (int)TEFRegisteredMemoryType.Whole:
529 RegisteredMemoryReference rmrw = (RegisteredMemoryReference)src;
530 rType = ((int)TEFRegisteredMemoryType.PartialInput & (int)TEFRegisteredMemoryType.PartialOutput) | rmrw.Parent.shm.flags;
531 dst[i].memref.parent = rmrw.Parent.shmptr.ToInt64();
532 dst[i].memref.size = rmrw.Size;
533 dst[i].memref.offset = rmrw.Offset;
536 case (int)TEFRegisteredMemoryType.PartialInput:
537 case (int)TEFRegisteredMemoryType.PartialOutput:
538 case (int)TEFRegisteredMemoryType.PartialInOut:
539 RegisteredMemoryReference rmr = (RegisteredMemoryReference)src;
540 dst[i].memref.parent = rmr.Parent.shmptr.ToInt64();
541 dst[i].memref.size = rmr.Size;
542 dst[i].memref.offset = rmr.Offset;
551 internal void UpdateParam(Interop.TEEC_Parameter64 src, ref Parameter[] dst, int i)
553 if (IntPtr.Size != 8) throw new Exception("wrong arch - not 64bit");
554 switch (dst[i].NativeType) {
555 case (int)TEFValueType.Input:
556 case (int)TEFValueType.Output:
557 case (int)TEFValueType.InOut:
558 ((Value)dst[i]).A = src.value.a;
559 ((Value)dst[i]).B = src.value.b;
562 case (int)TEFTempMemoryType.Input:
563 case (int)TEFTempMemoryType.Output:
564 case (int)TEFTempMemoryType.InOut:
565 byte[] mem = new byte[src.tmpref.size];
566 Marshal.Copy(shm[i].shm.buffer, mem, 0, mem.Length);
567 Marshal.Copy(mem, 0, ((TempMemoryReference)dst[i]).Buffer, mem.Length);
568 ((TempMemoryReference)dst[i]).Size = (uint)src.tmpref.size;
571 case (int)TEFRegisteredMemoryType.Whole:
572 case (int)TEFRegisteredMemoryType.PartialInput:
573 case (int)TEFRegisteredMemoryType.PartialOutput:
574 case (int)TEFRegisteredMemoryType.PartialInOut:
575 ((RegisteredMemoryReference)dst[i]).Size = (uint)src.memref.size;
582 static internal Interop.TEEC_Operation64 Create_TEEC_Operation64() {
583 Interop.TEEC_Operation64 op = new Interop.TEEC_Operation64();
586 op.paramlist = new Interop.TEEC_Parameter64[4];
590 internal void Open32(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist)
592 Interop.TEEC_UUID uuid = Interop.TEEC_UUID.ToTeecUuid(destination);
596 if (paramlist != null) {
597 Interop.TEEC_Operation32 op = Create_TEEC_Operation32();
598 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
599 op.paramTypes |= InitParam(ref op.paramlist, i, paramlist[i]) << (8*i);
601 Marshal.StructureToPtr(op, opptr, false);
602 ret = Interop.Libteec.OpenSession(context.context_imp, session_imp, ref uuid, loginMethod, connectionData, opptr, out ro);
603 op = Marshal.PtrToStructure<Interop.TEEC_Operation32>(opptr);
604 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
605 UpdateParam(op.paramlist[i], ref paramlist, i);
609 ret = Interop.Libteec.OpenSession(context.context_imp, session_imp, ref uuid, loginMethod, connectionData, IntPtr.Zero, out ro);
612 for (int i=0; i < 4; ++i) {
613 if (shm[i] != null) {
619 //MAYBE map origin of return code to specyfic Exception
620 Interop.CheckNThrowException(ret, string.Format("OpenSession('{0}')", destination));
623 internal void Open64(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist)
625 Interop.TEEC_UUID uuid = Interop.TEEC_UUID.ToTeecUuid(destination);
629 if (paramlist != null) {
630 Interop.TEEC_Operation64 op = Create_TEEC_Operation64();
631 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
632 op.paramTypes |= InitParam(ref op.paramlist, i, paramlist[i]) << (8*i);
634 Marshal.StructureToPtr(op, opptr, false);
635 ret = Interop.Libteec.OpenSession(context.context_imp, session_imp, ref uuid, loginMethod, connectionData, opptr, out ro);
636 op = Marshal.PtrToStructure<Interop.TEEC_Operation64>(opptr);
637 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
638 UpdateParam(op.paramlist[i], ref paramlist, i);
642 ret = Interop.Libteec.OpenSession(context.context_imp, session_imp, ref uuid, loginMethod, connectionData, IntPtr.Zero, out ro);
645 for (int i=0; i < 4; ++i) {
646 if (shm[i] != null) {
652 //MAYBE map origin of return code to specyfic Exception
653 Interop.CheckNThrowException(ret, string.Format("OpenSession('{0}')", destination));
658 /// This function closes a session which has been opened with a trusted application.
659 /// All commands within the session must be completed before this function can be called.
661 /// <since_tizen> 3 </since_tizen>
662 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
663 /// <privlevel>partner</privlevel>
664 /// <feature>http://tizen.org/feature/security.tee</feature>
665 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
666 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
667 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
668 public void Close() {
673 /// This function invokes a command within the specified session.
674 /// The parameter commandID is an identifier that is used to indicate which of the exposed trusted
675 /// application functions should be invoked. The supported command identifier values are defined by the
676 /// trusted application's protocol.
677 /// There can be up to four parameter objects given in the <paramref name="paramlist"/> array.
679 /// <since_tizen> 3 </since_tizen>
680 /// <param name="commandID">The command.</param>
681 /// <param name="paramlist">The array of parameters.</param>
682 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
683 /// <privlevel>partner</privlevel>
684 /// <feature>http://tizen.org/feature/security.tee</feature>
685 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
686 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
687 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
688 /// <exception cref="ArgumentException">The argument <paramref name="paramlist"/> is wrong.</exception>
689 public void InvokeCommand(uint commandID, Parameter[] paramlist)
693 if (paramlist != null) {
694 if (IntPtr.Size == 4) {
695 Interop.TEEC_Operation32 op = Create_TEEC_Operation32();
696 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
697 op.paramTypes |= InitParam(ref op.paramlist, i, paramlist[i]) << (8*i);
699 Marshal.StructureToPtr(op, opptr, false);
700 ret = Interop.Libteec.InvokeCommand(session_imp, commandID, opptr, out ro);
701 op = Marshal.PtrToStructure<Interop.TEEC_Operation32>(opptr);
702 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
703 UpdateParam(op.paramlist[i], ref paramlist, i);
707 Interop.TEEC_Operation64 op = Create_TEEC_Operation64();
708 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
709 op.paramTypes |= InitParam(ref op.paramlist, i, paramlist[i]) << (8*i);
711 Marshal.StructureToPtr(op, opptr, false);
712 ret = Interop.Libteec.InvokeCommand(session_imp, commandID, opptr, out ro);
713 op = Marshal.PtrToStructure<Interop.TEEC_Operation64>(opptr);
714 for (int i=0; i < 4 && i < paramlist.Length; ++i) {
715 UpdateParam(op.paramlist[i], ref paramlist, i);
720 ret = Interop.Libteec.InvokeCommand(session_imp, commandID, IntPtr.Zero, out ro);
723 for (int i=0; i < 4; ++i) {
724 if (shm[i] != null) {
730 //MAYBE map origin of return code to specific Exception
731 Interop.CheckNThrowException(ret, string.Format("InvokeCommand({0})", commandID));
735 /// The asynchronous version of the InvokeCommand.
737 /// <since_tizen> 3 </since_tizen>
738 /// <param name="commandID">The command.</param>
739 /// <param name="paramlist">The array of parameters.</param>
740 /// <param name="token">The token for task manipulation.</param>
741 /// <returns>Returns a task executing an invoke command in the background.</returns>
742 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
743 /// <privlevel>partner</privlevel>
744 /// <feature>http://tizen.org/feature/security.tee</feature>
745 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
746 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
747 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
748 /// <exception cref="ArgumentException">One of the arguments is wrong.</exception>
749 public async Task InvokeCommandAsync(uint commandID, Parameter[] paramlist, CancellationToken token = default(CancellationToken))
751 await Task.Factory.StartNew(() => InvokeCommand(commandID, paramlist));
757 /// This type denotes a TEE Context, the main logical container linking a Client Application with a particular TEE.
759 /// <since_tizen> 3 </since_tizen>
760 public sealed class Context : IDisposable
762 private bool disposed = false;
763 private bool initialized = false;
764 internal IntPtr context_imp;
765 internal uint shmcnt = 0;
768 /// This function (constructor) initializes a new TEE Context, forming a connection between this client application and the
769 /// TEE identified by the string identifier name (empty or null name denotes a default TEE).
771 /// <since_tizen> 3 </since_tizen>
772 /// <param name="name">The TEE name.</param>
773 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
774 /// <privlevel>partner</privlevel>
775 /// <feature>http://tizen.org/feature/security.tee</feature>
776 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
777 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
778 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
779 public Context(string name)
781 context_imp = Marshal.AllocHGlobal(Marshal.SizeOf<Interop.TEEC_Context>());
782 if (name != null && name.Length == 0)
785 int ret = Interop.Libteec.InitializeContext(name, context_imp);
786 Interop.CheckNThrowException(ret, string.Format("InititalizeContext('{0}')", name));
789 catch (global::System.DllNotFoundException e)
792 Interop.CheckNThrowException((int)Interop.LibteecError.NotImplemented, "Not found: " + e.Message);
797 private void Dispose(bool disposing)
803 Interop.Libteec.FinalizeContext(context_imp);
806 Marshal.FreeHGlobal(context_imp);
807 context_imp = IntPtr.Zero;
812 /// Destructor of the class.
820 /// This function implements the IDisposable interface.
822 /// <since_tizen> 3 </since_tizen>
823 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
824 /// <privlevel>partner</privlevel>
825 /// <feature>http://tizen.org/feature/security.tee</feature>
826 public void Dispose() {
828 Tizen.Log.Error("TZ_CLIENTAPI", "Context.Dispose not all shm released yet!");
832 GC.SuppressFinalize(this);
836 /// This function opens a new session between the client application and the specified trusted application.
837 /// The target trusted application is identified by an UUID passed in the parameter destination.
838 /// There can be up to four parameter objects given in the <paramref name="paramlist"/> array.
840 /// <since_tizen> 3 </since_tizen>
841 /// <param name="destination">The UUID of the destination TA.</param>
842 /// <param name="loginMethod">The authentication algorithm <see cref="LoginMethod" />.</param>
843 /// <param name="connectionData">The data to be verified by a given login method.</param>
844 /// <param name="paramlist">The parameters to be passed to TA open-session-callback.</param>
845 /// <returns>Returns opened session.</returns>
846 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
847 /// <privlevel>partner</privlevel>
848 /// <feature>http://tizen.org/feature/security.tee</feature>
849 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
850 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
851 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
852 /// <exception cref="ArgumentException">One of the arguments is wrong.</exception>
853 public Session OpenSession(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist)
855 Session ses = new Session(this);
856 if (IntPtr.Size == 4)
857 ses.Open32(destination, loginMethod, connectionData, paramlist);
858 else if (IntPtr.Size == 8)
859 ses.Open64(destination, loginMethod, connectionData, paramlist);
860 else throw new NotSupportedException("unsupported arch");
864 /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token).
866 /// <since_tizen> 3 </since_tizen>
867 /// <param name="destination">The UUID of the destination TA.</param>
868 /// <returns>Returns opened session.</returns>
869 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
870 /// <privlevel>partner</privlevel>
871 /// <feature>http://tizen.org/feature/security.tee</feature>
872 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
873 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
874 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
875 public Session OpenSession(Guid destination)
877 Session ses = new Session(this);
878 if (IntPtr.Size == 4)
879 ses.Open32(destination, LoginMethod.Public, null, null);
880 else if (IntPtr.Size == 8)
881 ses.Open64(destination, LoginMethod.Public, null, null);
882 else throw new NotSupportedException("unsupported arch");
887 /// The asynchronous version of the OpenSession.
888 /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token).
890 /// <since_tizen> 3 </since_tizen>
891 /// <param name="destination">The UUID of the destination TA.</param>
892 /// <param name="loginMethod">The authentication algorithm <see cref="LoginMethod" />.</param>
893 /// <param name="connectionData">The data to be verified by a given login method.</param>
894 /// <param name="paramlist">The parameters to be passed to the TA open-session-callback.</param>
895 /// <param name="token">The token for the task manipulation.</param>
896 /// <returns>Returns a Task executing the session open in the background.</returns>
897 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
898 /// <privlevel>partner</privlevel>
899 /// <feature>http://tizen.org/feature/security.tee</feature>
900 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
901 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
902 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
903 /// <exception cref="ArgumentException">One of the arguments is wrong.</exception>
904 public async Task<Session> OpenSessionAsync(Guid destination, uint loginMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token = default(CancellationToken))
906 Task<Session> task = Task<Session>.Factory.StartNew(() =>
908 return OpenSession(destination, loginMethod, connectionData, paramlist);
913 /// The asynchronous version of the OpenSession.
914 /// @see OpenSession (Guid destination, uint connectionMethod, byte[] connectionData, Parameter[] paramlist, CancellationToken token).
916 /// <since_tizen> 3 </since_tizen>
917 /// <param name="destination">The UUID of the destination TA.</param>
918 /// <param name="token">The token for a task manipulation.</param>
919 /// <returns>Returns a task executing session open in the background.</returns>
920 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
921 /// <privlevel>partner</privlevel>
922 /// <feature>http://tizen.org/feature/security.tee</feature>
923 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
924 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
925 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
926 public async Task<Session> OpenSessionAsync(Guid destination, CancellationToken token = default(CancellationToken))
928 Task<Session> task = Task<Session>.Factory.StartNew(() =>
930 return OpenSession(destination);
936 /// This function registers a block of the existing client application memory as a block of shared memory within
937 /// the scope of the specified context, in accordance with the parameters.
938 /// The input <paramref name="memaddr"/> must point to the shared memory region to register.
940 /// <since_tizen> 3 </since_tizen>
941 /// <param name="memaddr">The address of the shared memory.</param>
942 /// <param name="size">The size of the shared memory.</param>
943 /// <param name="flags">The flags describing the access modes (Input and/or Output).</param>
944 /// <returns>Returns the SharedMemory handler.</returns>
945 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
946 /// <privlevel>partner</privlevel>
947 /// <feature>http://tizen.org/feature/security.tee</feature>
948 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
949 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
950 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
951 /// <exception cref="ArgumentException">The argument <paramref name="memaddr"/> is wrong.</exception>
952 public SharedMemory RegisterSharedMemory(IntPtr memaddr, UInt32 size, SharedMemoryFlags flags)
954 SharedMemory sharedmem = new SharedMemory(this);
955 Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory();
956 shm.buffer = memaddr;
957 shm.size = (UIntPtr)size;
958 shm.flags = (UInt32)flags;
959 int ret = Interop.Libteec.RegisterSharedMemory(context_imp, ref shm);
960 Interop.CheckNThrowException(ret, "RegisterSharedMemory");
961 sharedmem.setShm(ref shm);
966 /// This function allocates a new block of memory as a block of shared memory within the scope of the
967 /// specified context, in accordance with the parameters.
969 /// <since_tizen> 3 </since_tizen>
970 /// <param name="size">The size of shared memory.</param>
971 /// <param name="flags">The flags describing access modes (Input and/or Output).</param>
972 /// <returns>Returns the Shared Memory handler.</returns>
973 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
974 /// <privlevel>partner</privlevel>
975 /// <feature>http://tizen.org/feature/security.tee</feature>
976 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
977 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
978 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
979 public SharedMemory AllocateSharedMemory(UInt32 size, SharedMemoryFlags flags)
981 SharedMemory sharedmem = new SharedMemory(this);
982 Interop.TEEC_SharedMemory shm = new Interop.TEEC_SharedMemory();
983 shm.size = (UIntPtr)size;
984 shm.flags = (UInt32)flags;
985 int ret = Interop.Libteec.AllocateSharedMemory(context_imp, ref shm);
986 Interop.CheckNThrowException(ret, "AllocateSharedMemory");
987 sharedmem.setShm(ref shm);
992 /// This function deregisters or deallocates a previously initialized block of the shared memory.
995 /// For a memory buffer allocated using AllocateSharedMemory, the implementation must free the
996 /// underlying memory and the client application must not access this region after this function has been
997 /// called. In this case, the implementation must clear the buffer and size fields of the shared memory
998 /// structure before returning.
999 /// For memory registered using RegisterSharedMemory, the implementation must deregister the
1000 /// underlying memory from the TEE, but the memory region will stay available to the client application for
1001 /// other purposes as the memory is owned by it.
1003 /// <since_tizen> 3 </since_tizen>
1004 /// <param name="shm">The shared memory object returned by RegisterSharedMemory or AllocateSharedMemory.</param>
1005 /// <privilege>http://tizen.org/privilege/tee.client</privilege>
1006 /// <privlevel>partner</privlevel>
1007 /// <feature>http://tizen.org/feature/security.tee</feature>
1008 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1009 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
1010 /// <exception cref="InvalidOperationException">The operation is invalid.</exception>
1011 /// <exception cref="ArgumentException">The argument is wrong.</exception>
1012 public void ReleaseSharedMemory(SharedMemory shm)