From 073cb6654639a33f83e2033c4a26d7a0f8a1454d Mon Sep 17 00:00:00 2001 From: Editor Lionbridge Date: Wed, 14 Jun 2017 14:03:37 +0300 Subject: [PATCH] Add .NET Libteec Guide Note that since the general structure of the .NET content is still open, the new topic has not been added to any index files, and there is no parent topic introducing the .NET guides. Also, since there is no .NET AR content in git, all AR links lead directly to TD. PS2: Prerequisites updated based on comments PS3: Copy-paste fix PS4: Updated with AR links, since the AR content became available PS5: Changed the order of the prerequisites section to be consistent with other .NET content. PS6: Removed "building dependency" prerequisite as per comments. Change-Id: Idce756fd83c1da853c76202dabb5df1552c7159c --- org.tizen.guides/html/dotnet/libteec.htm | 269 +++++++++++++++++++++ .../html/images/libteec_architecture.png | Bin 0 -> 11910 bytes 2 files changed, 269 insertions(+) create mode 100644 org.tizen.guides/html/dotnet/libteec.htm create mode 100644 org.tizen.guides/html/images/libteec_architecture.png diff --git a/org.tizen.guides/html/dotnet/libteec.htm b/org.tizen.guides/html/dotnet/libteec.htm new file mode 100644 index 0000000..5966c05 --- /dev/null +++ b/org.tizen.guides/html/dotnet/libteec.htm @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + TEE Communication + + + + +
+
+

Mobile C# TV C#

+
+ +
+

Dependencies

+
    +
  • Tizen 4.0 and Higher for Mobile and TV
  • +
+

Content

+ +

Related Info

+ +
+
+ +
+ +

TEE Communication

+

You can create secure communications by executing your application in a trusted execution environment (TEE), and communicating with other applications within that environment. To implement TEE communication, you can use the libteec API, which is based on the GlobalPlatform® TEE Client API.

+ +

You can run applications in 2 environments: a rich world (like Linux) with client applications (CA) and a secure world with trusted applications (TA).

+ +

Figure: TEE communication architecture

+

TEE communication architecture

+ +

The main features of the Tizen.Security.TEEC namespace include:

+ + +

Prerequisites

+

To enable your application to use the TEE communication functionality:

+
    +
  1. To make your application visible in the Tizen Store only for devices that support TEE communication, the application must specify the following feature in the tizen-manifest.xml file: + +
    +<feature name="http://tizen.org/feature/security.tee"/>
    +
    + +

    You can also check whether a device supports the Tizen.Security.TEEC namespace by using the TryGetValue() method of the Tizen.System.SystemInfo class and accordingly enabling or disabling the code requiring the namespace:

    + +
    +const string TEEC_FEATURE_KEY = "http://tizen.org/feature/security.tee";
    +bool ret;
    +
    +if (SystemInfo.TryGetValue<bool>(TEEC_FEATURE_KEY, out ret) == false)
    +{
    +    /// Error handling
    +}
    +
    + +
    +Note +In TV applications, you can test the TEE communication functionality on an emulator only. Most target devices do not currently support this feature. +
    +
  2. +
  3. To use the methods and properties of the Tizen.Security.TEEC namespace, include it in your application: +
    +using Tizen.Security.TEEC;
    +
    +
  4. +
  5. Initialize a new TEEC context by creating an instance of the Tizen.Security.TEEC.Context class: +
    +Context ctx = new Context(null);
    +
    +

    When it is no longer needed, destroy the TEEC context:

    +
    +ctx.Dispose();
    +
    +
  6. + +
+ +

Connecting Applications

+

To communicate between applications, you must connect a client application to a trusted application by creating a session:

+
    +
  1. Open a session with the OpenSession() method of the Tizen.Security.TEEC.Context class, which returns the session as a new instance of the Tizen.Security.TEEC.Session class. +
    +Guid ta_uuid = new Guid("  "); /// Trusted application GUID
    +try
    +{
    +    Session ses = ctx.OpenSession(ta_uuid);
    +
  2. +
  3. When it is no longer needed, close the session with the Close() method of the Tizen.Security.TEEC.Session class: +
    +    ses.Close();
    +}
    +catch (Exception e)
    +{
    +    /// Error handling
    +}
    +
  4. +
+ +

Sending Secure Commands

+

After opening a session with a trusted application, a client application can execute functions in the trusted application by sending secure commands to the trusted application.

+

To send function call commands:

+
    +
  • To send a command for invoking a function without parameters, use the InvokeCommand() method of the Tizen.Security.TEEC.Session class, with the first parameter identifying the function to be executed by the trusted application: +
    +try
    +{
    +    ses.InvokeCommand(1, null);
    +}
    +catch (Exception e)
    +{
    +    /// Error handling
    +}
    +
  • +
  • To send a command for invoking a function with simple integer parameters: +
      +
    1. Create the parameters as new instances of the Tizen.Security.TEEC.Value class: +
      +try
      +{
      +    Value p1 = new Value(1, 2, TEFValueType.InOut);
      +    Value p2 = new Value(10, 200, TEFValueType.InOut);
      +
      +
    2. +
    3. Send the command to the trusted application with the InvokeCommand() method of the Tizen.Security.TEEC.Session class. The second parameter is a new instance of the Tizen.Security.TEEC.Parameter class containing the 2 integer parameter values. +
      +    ses.InvokeCommand(1, new Parameter[] {p1, p2});
      +}
      +catch (Exception e)
      +{
      +    /// Error handling
      +}
      +
      +
    4. +
    +
  • +
  • To send a command for invoking a function with a local memory reference as a parameter: +
      +
    1. Create a temporary memory reference as a new instance of the Tizen.Security.TEEC.TempMemoryReference class: +
      +try
      +{
      +    long val=10;
      +    TempMemoryReference p1 = new TempMemoryReference((IntPtr)(&val), 1024, TEFTempMemoryType.InOut);
      +
      +
    2. +
    3. Send the command to the trusted application with the InvokeCommand() method of the Tizen.Security.TEEC.Session class. The second parameter is a new instance of the Tizen.Security.TEEC.Parameter class containing the memory reference. +
      +    ses.InvokeCommand(1, new Parameter[] {p1});
      +}
      +catch (Exception e)
      +{
      +    /// Error handling
      +}
      +
      +
    4. +
    +
  • + +
+ +

Using Shared Memory

+

To share a memory block between a client application and a trusted application:

+
    +
  • To send a function call command to the trusted application, including an allocated shared memory reference: +
      +
    1. Allocate a new memory block as shared memory with the AllocateSharedMemory() method of the Tizen.Security.TEEC.Context class, which returns the block as a new instance of the Tizen.Security.TEEC.SharedMemory class: +
      +try
      +{
      +    SharedMemory shm = ctx.AllocateSharedMemory(1024, SharedMemoryFlags.InOut);
      +
      +
    2. +
    3. Register a memory reference based on the shared memory block by creating a new instance of the Tizen.Security.TEEC.RegisteredMemoryReference class, and send the function call command to the trusted application with the InvokeCommand() method of the Tizen.Security.TEEC.Session class. The registered memory reference is passed in a new instance of the Tizen.Security.TEEC.Parameter class. +
      +    RegisteredMemoryReference p1 = new RegisteredMemoryReference(shm, 1024, 0, RegisteredMemoryReference.InOut);
      +    ses.InvokeCommand(1, new Parameter[] {p1});
      +
      +
    4. +
    5. Release the shared memory: +
      +    ctx.ReleaseSharedMemory(shm);
      +}
      +catch (Exception e)
      +{
      +    /// Error handling
      +}
      +
      +
    6. +
  • +
  • Send a function call command to the trusted application, including an external shared memory reference: +
      +
    1. Register a block of existing client application memory as shared memory with the RegisterSharedMemory() method of the Tizen.Security.TEEC.Context class, which returns the block as a new instance of the Tizen.Security.TEEC.SharedMemory class: +
      +try
      +{
      +    IntPtr memaddr = <Some memory address>;
      +    SharedMemory shm = ctx.RegisterSharedMemory(memaddr, 1024, SharedMemoryFlags.InOut);
      +
      +
    2. +
    3. Register a memory reference based on the shared memory block by creating a new instance of the Tizen.Security.TEEC.RegisteredMemoryReference class, and send the function call command to the trusted application with the InvokeCommand() method of the Tizen.Security.TEEC.Session class. The registered memory reference is passed in a new instance of the Tizen.Security.TEEC.Parameter class. +
      +    RegisteredMemoryReference p1 = new RegisteredMemoryReference(shm, 1024, 0, RegisteredMemoryReference.InOut);
      +    ses.InvokeCommand(1, new Parameter[] {p1});
      +
      +
    4. +
    5. Release the shared memory: +
      +    ctx.ReleaseSharedMemory(shm);
      +}
      +catch (Exception e)
      +{
      +    /// Error handling
      +}
      +
      +
    6. +
    +
  • +
+ + + + +
+ +Go to top + + + + + + + diff --git a/org.tizen.guides/html/images/libteec_architecture.png b/org.tizen.guides/html/images/libteec_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..e60c0d8a6a0bb3ec6ba3b3f9daa65a85bcb7db68 GIT binary patch literal 11910 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 IDYMZ32mjzci2wiq literal 0 HcmV?d00001 -- 2.7.4