Trusted Applications

There are two ways to implement Trusted Applications (TAs), Pseudo TAs and user mode TAs. User mode TAs are full featured Trusted Applications as specified by the GlobalPlatform API TEE specifications, these are simply the ones people are referring to when they are saying “Trusted Applications” and in most cases this is the preferred type of TA to write and use.

Pseudo Trusted Applications

These are implemented directly to the OP-TEE core tree in, e.g., core/arch/arm/pta and are built along with and statically built into the OP-TEE core blob.

The Pseudo Trusted Applications included in OP-TEE already are OP-TEE secure privileged level services hidden behind a “GlobalPlatform TA Client” API. These Pseudo TAs are used for various purposes such as specific secure services or embedded tests services.

Pseudo TAs do not benefit from the GlobalPlatform Core Internal API support specified by the GlobalPlatform TEE specs. These APIs are provided to TAs as a static library each TA shall link against (the “libutee”) and that calls OP-TEE core service through system calls. As OP-TEE core does not link with libutee, Pseudo TAs can only use the OP-TEE core internal APIs and routines.

As Pseudo TAs runs at the same privileged execution level as the OP-TEE core code itself and that might or might not be desirable depending on the use case.

In most cases an unprivileged (user mode) TA is the best choice instead of adding your code directly to the OP-TEE core. However if you decide your application is best handled directly in OP-TEE core like this, you can look at core/arch/arm/pta/stats.c as a template and just add your Pseudo TA based on that to the sub.mk in the same directory.

User Mode Trusted Applications

User Mode Trusted Applications are loaded (mapped into memory) by OP-TEE core in the Secure World when something in Rich Execution Environment (REE) wants to talk to that particular application UUID. They run at a lower CPU privilege level than OP-TEE core code. In that respect, they are quite similar to regular applications running in the REE, except that they execute in Secure World.

Trusted Application benefit from the GlobalPlatform TEE Internal Core API as specified by the GlobalPlatform TEE specifications. There are several types of user mode TAs, which differ by the way they are stored.

TA locations

Plain TAs (user mode) can reside and be loaded from various places. There are three ways currently supported in OP-TEE.

Early TA

The so-called early TAs are virtually identical to the REE FS TAs, but instead of being loaded from the Normal World file system, they are linked into a special data section in the TEE core blob. Therefore, they are available even before tee-supplicant and the REE’s filesystems have come up. Please find more details in the early TA commit.

REE filesystem TA

They consist of a cleartext signed ELF file, named from the UUID of the TA and the suffix .ta. They are built separately from the OP-TEE core boot-time blob, although when they are built they use the same build system, and are signed with the key from the build of the original OP-TEE core blob.

Because the TAs are signed, they are able to be stored in the untrusted REE filesystem, and tee-supplicant will take care of passing them to be checked and loaded by the Secure World OP-TEE core. Note that this type of TA isn’t encrypted.

Secure Storage TA

These are stored in secure storage. The meta data is stored in a database of all installed TAs and the actual binary is stored encrypted and integrity protected as a separate file in the untrusted REE filesystem (flash). Before these TAs can be loaded they have to be installed first, this is something that can be done during initial deployment or at a later stage.

For test purposes the test program xtest can install a TA into secure storage with the command:

$ xtest --install-ta

TA Properties

This section give a more in depth description of the TA properties (see Trusted Applications also).

GlobalPlatform Properties

Standard TA properties must be defined through property flag in macro TA_FLAGS in user_ta_header_defines.h

Single Instance

"gpd.ta.singleInstance" is a boolean property of the TA. This property defines if one instance of the TA must be created and will receive all open session request, or if a new specific TA instance must be created for each incoming open session request. OP-TEE TA flag TA_FLAG_SINGLE_INSTANCE sets to configuration of this property. The boolean property is set to true if TA_FLAGS sets bit TA_FLAG_SINGLE_INSTANCE, otherwise the boolean property is set to false.

Multi-session

"gpd.ta.multiSession" is a boolean property of the TA. This property defines if the TA instance can handle several sessions. If disabled, TA instance support only one session. In such case, if the TA already has a opened session, any open session request will return with a busy error status.

Note

This property is meaningless if TA is NOT SingleInstance TA.

OP-TEE TA flag TA_FLAG_MULTI_SESSION sets to configuration of this property. The boolean property is set to true if TA_FLAGS sets bit TA_FLAG_MULTI_SESSION, otherwise the boolean property is set to false.

Keep Alive

"gpd.ta.instanceKeepAlive" is a boolean property of the TA. This property defines if the TA instance created must be destroyed or not when all sessions opened towards the TA are closed. If the property is enabled, TA instance, once created (at 1st open session request), is never removed unless the TEE itself is restarted (boot/reboot).

Note

This property is meaningless if TA is NOT SingleInstance TA.

OP-TEE TA flag TA_FLAG_INSTANCE_KEEP_ALIVE sets to configuration of this property. The boolean property is set to true if TA_FLAGS sets bit TA_FLAG_INSTANCE_KEEP_ALIVE, otherwise the boolean property is set to false.

Heap Size

"gpd.ta.dataSize" is a 32bit integer property of the TA. This property defines the size in bytes of the TA allocation pool, in which TEE_Malloc() and friends allocate memory. The value of the property must be defined by the macro TA_DATA_SIZE in user_ta_header_defines.h (see TA Properties).

Stack Size

"gpd.ta.stackSize" is a 32bit integer property of the TA. This property defines the size in bytes of the stack used for TA execution. The value of the property must be defined by the macro TA_STACK_SIZE in user_ta_header_defines.h (see TA Properties).

Property Extensions

Secure Data Path Flag

TA_FLAG_SECURE_DATA_PATH is a bit flag supported by TA_FLAGS. This property flag claims the secure data support from the OP-TEE OS for the TA. Refer to the OP-TEE OS for secure data path support. TAs that do not set TA_FLAG_SECURE_DATA_PATH in the value of TA_FLAGS will not be able to handle memory reference invocation parameters that relate to secure data path buffers.

Cache maintenance Flag

TA_FLAG_CACHE_MAINTENANCE is a bit flag supported by TA_FLAGS. This property flag, when enabled, allows Trusted Applciation to use the cache maintenance API extension of the Internal Core API described in Cache Maintenance Support. TAs that do not set TA_FLAG_CACHE_MAINTENANCE in the value of their TA_FLAGS will not be able to call the cache maintenance API.

Deprecated Property Flags

Older versions of OP-TEE used to define extended property flags that are deprecated and meaningless to current OP-TEE. These are TA_FLAG_USER_MODE, TA_FLAG_EXEC_DDR and TA_FLAG_REMAP_SUPPORT.