blob: 59ba7122538f69b28c0dd3ccc716c1d2eaf46421 [file] [log] [blame]
Joakim Bech8e5c5b32018-10-25 08:18:32 +02001.. _trusted_applications:
2
3####################
4Trusted Applications
5####################
6There are two ways to implement Trusted Applications (TAs), Pseudo TAs and user
7mode TAs. User mode TAs are full featured Trusted Applications as specified by
8the :ref:`globalplatform_api` TEE specifications, these are simply the ones
9people are referring to when they are saying "Trusted Applications" and in most
10cases this is the preferred type of TA to write and use.
11
12.. _pta:
13
14Pseudo Trusted Applications
15***************************
Etienne Carriere5ecb86a2020-06-03 18:47:45 +020016A Pseudo Trusted Application is not a Trusted Application. A Pseudo TA is not a
17specific entity. A Pseudo TA is an interface. It is an interface exposed by the
18OP-TEE Core to its outer world: to secure client Trusted Applications and to
19non-secure client entities.
20
Joakim Bech8e5c5b32018-10-25 08:18:32 +020021These are implemented directly to the OP-TEE core tree in, e.g.,
Jerome Forissierfa993db2019-09-13 15:58:53 +020022``core/pta`` and are built along with and statically built into the
Joakim Bech8e5c5b32018-10-25 08:18:32 +020023OP-TEE core blob.
24
25The Pseudo Trusted Applications included in OP-TEE already are OP-TEE secure
26privileged level services hidden behind a "GlobalPlatform TA Client" API. These
27Pseudo TAs are used for various purposes such as specific secure services or
28embedded tests services.
29
30Pseudo TAs **do not** benefit from the GlobalPlatform Core Internal API support
31specified by the GlobalPlatform TEE specs. These APIs are provided to TAs as a
32static library each TA shall link against (the ":ref:`libutee`") and that calls
33OP-TEE core service through system calls. As OP-TEE core does not link with
34:ref:`libutee`, Pseudo TAs can **only** use the OP-TEE core internal APIs and
35routines.
36
37As Pseudo TAs runs at the same privileged execution level as the OP-TEE core
38code itself and that might or might not be desirable depending on the use case.
39
40In most cases an unprivileged (user mode) TA is the best choice instead of
41adding your code directly to the OP-TEE core. However if you decide your
42application is best handled directly in OP-TEE core like this, you can look at
Jerome Forissierfa993db2019-09-13 15:58:53 +020043``core/pta/stats.c`` as a template and just add your Pseudo TA based on
Joakim Bech8e5c5b32018-10-25 08:18:32 +020044that to the ``sub.mk`` in the same directory.
45
46.. _user_mode_ta:
47
48User Mode Trusted Applications
49******************************
50User Mode Trusted Applications are loaded (mapped into memory) by OP-TEE core in
51the Secure World when something in Rich Execution Environment (REE) wants to
52talk to that particular application UUID. They run at a lower CPU privilege
53level than OP-TEE core code. In that respect, they are quite similar to regular
54applications running in the REE, except that they execute in Secure World.
55
56Trusted Application benefit from the GlobalPlatform :ref:`tee_internal_core_api`
57as specified by the GlobalPlatform TEE specifications. There are several types
58of user mode TAs, which differ by the way they are stored.
59
Etienne Carrierec75d19d2023-11-10 14:29:28 +010060.. _ta_locations:
61
Joakim Bech8e5c5b32018-10-25 08:18:32 +020062TA locations
63************
64Plain TAs (user mode) can reside and be loaded from various places. There are
65three ways currently supported in OP-TEE.
66
67.. _early_ta:
68
69Early TA
70========
71The so-called early TAs are virtually identical to the REE FS TAs, but instead
72of being loaded from the Normal World file system, they are linked into a
73special data section in the TEE core blob. Therefore, they are available even
74before ``tee-supplicant`` and the REE's filesystems have come up. Please find
75more details in the `early TA commit`_.
76
77.. _ree_fs_ta:
78
79REE filesystem TA
80=================
Sumit Gargde0c0c72020-04-17 13:15:30 +053081They consist of a ELF_ file, signed and optionally encrypted, named from the
82UUID of the TA and the suffix ``.ta``. They are built separately from the
83OP-TEE core boot-time blob, although when they are built they use the same
84build system, and are signed with the key from the build of the original OP-TEE
85core blob.
Joakim Bech8e5c5b32018-10-25 08:18:32 +020086
Sumit Gargde0c0c72020-04-17 13:15:30 +053087Because the TAs are signed and optionally encrypted with
88``scripts/sign_encrypt.py``, they are able to be stored in the untrusted REE
Joakim Bech8e5c5b32018-10-25 08:18:32 +020089filesystem, and ``tee-supplicant`` will take care of passing them to be checked
Sumit Gargde0c0c72020-04-17 13:15:30 +053090and loaded by the Secure World OP-TEE core.
Joakim Bech8e5c5b32018-10-25 08:18:32 +020091
Sumit Gargde0c0c72020-04-17 13:15:30 +053092REE-FS TA rollback protection
93-----------------------------
94OP-TEE core maintains a ``ta_ver.db`` file in secure storage to check for
95version of REE TAs as they are loaded from REE-FS in order to prevent against
96any TA version downgrades. TA version can be configured via TA build option:
97``CFG_TA_VERSION=<unsigned integer>``.
Jens Wiklander6054d682019-11-19 11:31:14 +010098
Sumit Gargde0c0c72020-04-17 13:15:30 +053099Note: Here rollback protection is effective only when ``CFG_RPMB_FS=y``.
100
101REE-FS TA formats
102-----------------
103REE filesystem TAs come in three formats:
104
105 1. Legacy TAs signed, not encrypted, cannot be created anymore by the build
106 scripts since version 3.7.0.
107
108 2. Bootstrap TAs, signed with the key from the build of the original OP-TEE
109 core blob, not encrypted.
110
111 3. Encrypted TAs, sign-then-encrypt-then-MAC, encrypted with ``TA_ENC_KEY``
112 when ``CFG_ENCRYPT_TA=y``. During OP-TEE runtime, the symmetric key used
113 to decrypt TA has to be provided in a platform specific manner via
114 overriding API:
115
116 .. code-block:: c
117
118 TEE_Result tee_otp_get_ta_enc_key(uint32_t key_type, uint8_t *buffer,
119 size_t len);
120
121REE-FS TA header structure
122--------------------------
Jens Wiklander6054d682019-11-19 11:31:14 +0100123All REE filesystems TAs has common header, ``struct shdr``, defined as:
124
125.. code-block:: c
126
127 enum shdr_img_type {
128 SHDR_TA = 0,
129 SHDR_BOOTSTRAP_TA = 1,
Sumit Gargde0c0c72020-04-17 13:15:30 +0530130 SHDR_ENCRYPTED_TA = 2,
Jens Wiklander6054d682019-11-19 11:31:14 +0100131 };
132
133 #define SHDR_MAGIC 0x4f545348
134
135 /**
136 * struct shdr - signed header
137 * @magic: magic number must match SHDR_MAGIC
138 * @img_type: image type, values defined by enum shdr_img_type
139 * @img_size: image size in bytes
140 * @algo: algorithm, defined by public key algorithms TEE_ALG_*
141 * from TEE Internal API specification
142 * @hash_size: size of the signed hash
143 * @sig_size: size of the signature
144 * @hash: hash of an image
145 * @sig: signature of @hash
146 */
147 struct shdr {
148 uint32_t magic;
149 uint32_t img_type;
150 uint32_t img_size;
151 uint32_t algo;
152 uint16_t hash_size;
153 uint16_t sig_size;
154 /*
155 * Commented out element used to visualize the layout dynamic part
156 * of the struct.
157 *
158 * hash is accessed through the macro SHDR_GET_HASH and
159 * signature is accessed through the macro SHDR_GET_SIG
160 *
161 * uint8_t hash[hash_size];
162 * uint8_t sig[sig_size];
163 */
164 };
165
166 #define SHDR_GET_SIZE(x) (sizeof(struct shdr) + (x)->hash_size + \
167 (x)->sig_size)
168 #define SHDR_GET_HASH(x) (uint8_t *)(((struct shdr *)(x)) + 1)
169 #define SHDR_GET_SIG(x) (SHDR_GET_HASH(x) + (x)->hash_size)
170
171
Jens Wiklandera6315cd2019-11-19 14:34:30 +0100172The field ``img_type`` tells the type of TA, if it's ``SHDR_TA`` (0),
Jens Wiklander6054d682019-11-19 11:31:14 +0100173it's a legacy TA. If it's ``SHDR_BOOTSTRAP_TA`` (1) it's a bootstrap TA.
174
Jens Wiklandera6315cd2019-11-19 14:34:30 +0100175The field ``algo`` tells the algorithm used. The script used to sign TAs
176currently uses ``TEE_ALG_RSASSA_PKCS1_V1_5_SHA256`` (0x70004830). This
177means RSA with PKCS#1v1.5 padding and SHA-256 hash function. OP-TEE accepts
178any of the ``TEE_ALG_RSASSA_PKCS1_*`` algorithms.
179
Jens Wiklander6054d682019-11-19 11:31:14 +0100180For bootstrap TAs ``struct shdr`` is followed by a subheader, ``struct
181shdr_bootstrap_ta`` which is defined as:
182
183.. code-block:: c
184
185 /**
186 * struct shdr_bootstrap_ta - bootstrap TA subheader
187 * @uuid: UUID of the TA
188 * @ta_version: Version of the TA
189 */
190 struct shdr_bootstrap_ta {
191 uint8_t uuid[sizeof(TEE_UUID)];
192 uint32_t ta_version;
193 };
194
195The fields ``uuid`` and ``ta_version`` allows extra checks to be performed
196when loading the TA. Currently only the ``uuid`` field is checked.
197
Sumit Gargde0c0c72020-04-17 13:15:30 +0530198For encrypted TAs ``struct shdr`` is followed by a subheader, ``struct
199shdr_bootstrap_ta`` which is followed by another subheader, ``struct
200shdr_encrypted_ta`` defined as:
201
202.. code-block:: c
203
204 /**
205 * struct shdr_encrypted_ta - encrypted TA header
206 * @enc_algo: authenticated encyption algorithm, defined by symmetric key
207 * algorithms TEE_ALG_* from TEE Internal API
208 * specification
209 * @flags: authenticated encyption flags
210 * @iv_size: size of the initialization vector
211 * @tag_size: size of the authentication tag
212 * @iv: initialization vector
213 * @tag: authentication tag
214 */
215 struct shdr_encrypted_ta {
216 uint32_t enc_algo;
217 uint32_t flags;
218 uint16_t iv_size;
219 uint16_t tag_size;
220 /*
221 * Commented out element used to visualize the layout dynamic part
222 * of the struct.
223 *
224 * iv is accessed through the macro SHDR_ENC_GET_IV and
225 * tag is accessed through the macro SHDR_ENC_GET_TAG
226 *
227 * uint8_t iv[iv_size];
228 * uint8_t tag[tag_size];
229 */
230 };
231
232The field ``enc_algo`` tells the algorithm used. The script used to encrypt
233TAs currently uses ``TEE_ALG_AES_GCM`` (0x40000810). OP-TEE core also accepts
234``TEE_ALG_AES_CCM`` algorithm.
235
236The field ``flags`` supports a single flag to tell encryption key type which
237is defined as:
238
239.. code-block:: c
240
241 #define SHDR_ENC_KEY_TYPE_MASK 0x1
242
243 enum shdr_enc_key_type {
244 SHDR_ENC_KEY_DEV_SPECIFIC = 0,
245 SHDR_ENC_KEY_CLASS_WIDE = 1,
246 };
247
248REE-FS TA binary formats
249------------------------
250TA binary follows the ELF file which normally is stripped as additional
251symbols etc will be ignored when loading the TA.
Jens Wiklander6054d682019-11-19 11:31:14 +0100252
253Legacy TA binary is formatted as:
254
255.. code-block:: none
256
257 hash = H(<struct shdr> || <stripped ELF>)
258 signature = RSA-Sign(hash)
259 legacy_binary = <struct shdr> || <hash> || <signature> || <stripped ELF>
260
261Bootstrap TA binary is formatted as:
262
263.. code-block:: none
264
265 hash = H(<struct shdr> || <struct shdr_bootstrap_ta> || <stripped ELF>)
266 signature = RSA-Sign(<hash>)
267 bootstrap_binary = <struct shdr> || <hash> || <signature> ||
268 <struct shdr_bootstrap_ta> || <stripped ELF>
269
Sumit Gargde0c0c72020-04-17 13:15:30 +0530270Encrypted TA binary is formatted as:
271
272.. code-block:: none
273
274 nonce = <unique random value>
275 ciphertext, tag = AES_GCM(<stripped ELF>)
276 hash = H(<struct shdr> || <struct shdr_bootstrap_ta> ||
277 <struct shdr_encrypted_ta> || <nonce> || <tag> || <stripped ELF>)
278 signature = RSA-Sign(<hash>)
279 encrypted_binary = <struct shdr> || <hash> || <signature> ||
280 <struct shdr_bootstrap_ta> ||
281 <struct shdr_encrypted_ta> || <nonce> || <tag> ||
282 <ciphertext>
283
Jens Wiklandere5010392022-10-14 08:58:27 +0200284Verifying with Subkeys
285----------------------
286A TA can be verified using a subkey or a chain of subkeys. This allows
287delegation of TA signing without distributing the root key. TAs signed with
288a subkey are confined to the UUID-V5 namespace of the subkey to avoid TA
289UUID clashes with different subkeys.
290
291SHDR_SUBKEY is a type of header which enables chains of public keys. The
292public root key is used to verify the first public subkey, which then is
293used to verify the next public subkey and so on.
294
295The TA is finally verified using the last subkey. All these headers are
296added in front of the TA binary so everything needed to verify the TA is
297available when it's loaded into memory.
298
Joakim Bech0f1a4f82023-02-27 13:26:34 +0100299For details on subkeys see also :ref:`subkeys`
Jens Wiklandere5010392022-10-14 08:58:27 +0200300
Sumit Gargde0c0c72020-04-17 13:15:30 +0530301Loading REE-FS TA
302-----------------
Jens Wiklander6054d682019-11-19 11:31:14 +0100303A REE TA is loaded into shared memory using a series or RPC in
304:ref:`load_ree_ta`. The payload memory is allocated via TEE-supplicant and
305later freed when the TA has been loaded into secure memory in
306:ref:`free_appl_shm`.
307
308.. _load_ree_ta:
309
310.. figure:: ../images/trusted_applications/load_ree_ta.png
311 :figclass: align-center
312
313 Loading a REE TA into nonsecure shared memory
314
315.. _free_appl_shm:
316
317.. figure:: ../images/trusted_applications/free_appl_shm.png
318 :figclass: align-center
319
320 Freeing previously allocated nonsecure shared memory
321
322
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200323.. _secure_storage_ta:
324
325Secure Storage TA
326=================
327These are stored in secure storage. The meta data is stored in a database of all
328installed TAs and the actual binary is stored encrypted and integrity protected
329as a separate file in the untrusted REE filesystem (flash). Before these TAs can
330be loaded they have to be installed first, this is something that can be done
331during initial deployment or at a later stage.
332
333For test purposes the test program xtest can install a TA into secure storage
334with the command:
335
336.. code-block:: bash
337
338 $ xtest --install-ta
339
Jens Wiklander6b67a662019-11-25 10:58:46 +0100340TAs stored in secure storage are kept in a TA database. The TA database
341consists of a single file with the name ``dirf.db`` which is stored either
342in the REE filesystem based secure storage or in RPMB. The file is
343encrypted and integrity protected as any other object in secure storage.
344The TAs themselves are not stored in ``dirf.db``, they are instead stored
345in the REE filesystem encrypted and integrity protected. One reason for
346this is that TAs can potentially be quite large, several megabytes, while
347secure storage is designed to hold only small objects counted in kilobytes.
348
349``dirf.db`` constsist of an array of ``struct tadb_entry``, defined as:
350
351.. code-block:: C
352
353 /*
354 * struct tee_tadb_property
355 * @uuid: UUID of Trusted Application (TA) or Security Domain (SD)
356 * @version: Version of TA or SD
357 * @custom_size:Size of customized properties, prepended to the encrypted
358 * TA binary
359 * @bin_size: Size of the binary TA
360 */
361 struct tee_tadb_property {
362 TEE_UUID uuid;
363 uint32_t version;
364 uint32_t custom_size;
365 uint32_t bin_size;
366 };
367
368 #define TADB_IV_SIZE TEE_AES_BLOCK_SIZE
369 #define TADB_TAG_SIZE TEE_AES_BLOCK_SIZE
370 #define TADB_KEY_SIZE TEE_AES_MAX_KEY_SIZE
371
372 /*
373 * struct tadb_entry - TA database entry
374 * @prop: properties of TA
375 * @file_number: encrypted TA is stored in <file_number>.ta
376 * @iv: Initialization vector of the authentication crypto
377 * @tag: Tag used to validate the authentication encrypted TA
378 * @key: Key used to decrypt the TA
379 */
380 struct tadb_entry {
381 struct tee_tadb_property prop;
382 uint32_t file_number;
383 uint8_t iv[TADB_IV_SIZE];
384 uint8_t tag[TADB_TAG_SIZE];
385 uint8_t key[TADB_KEY_SIZE];
386 };
387
388Entries where the ``UUID`` consists of zeros only are not valid and are
389ignored. The ``file_number`` field represents that name of the file stored
390in the REE filesystem. The filename is made from the decimal string
391representation of ``file_number`` with ``.ta`` appended, or if it was to be
392printed: ``printf("%u.ta", file_number)``.
393
394The TA is decrypted using the authentication encryption algorithm AES-GCM
395initialized with the ``iv`` and ``key`` fields, the ``tag`` field is used
396when finalizing the decryption
397
398A TA is looked up in the TA database by opening ``dirf.db`` and scanning
399through the elements which are of type ``struct tadb_entry`` until a
400matching UUID is found.
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200401
Jens Wiklandera6315cd2019-11-19 14:34:30 +0100402Loading and preparing TA for execution
403**************************************
404
405User mode TAs are loaded into final memory in the same way using the user
406mode ELF loader ``ldelf``. The different TA locations has a common
407interface towards ``ldelf`` which makes the user mode operations identical
408regarless of how the TA is stored.
409
410The TA is loaded into secure memory in :ref:`prepare_ta`.
411
412.. _prepare_ta:
413
414.. figure:: ../images/trusted_applications/prepare_ta.png
415 :figclass: align-center
416
417 Preparing TA for execution
418
419After ``ldelf`` has returned with a TA prepared for execution it still
420remains in memory to serve the TA if dlopen() and friends are used.
421``ldelf`` is also used to dump stack trace and detailed memory mappings if
422a TA is terminated via an abort.
423
424A high level view of the entire flow from the client application in Linux
425user space where a session is opened to a TA is given in
426:ref:`open_session`.
427
428.. _open_session:
429
430.. figure:: ../images/trusted_applications/open_session.png
431 :figclass: align-center
432
433 Open session to a TA
434
435
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200436.. _ta_properties:
437
438TA Properties
439*************
440This section give a more in depth description of the TA properties (see
441:ref:`build_trusted_applications` also).
442
Etienne Carriere2f459d12019-03-11 11:58:05 +0100443GlobalPlatform Properties
444=========================
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200445Standard TA properties must be defined through property flag in macro
446``TA_FLAGS`` in ``user_ta_header_defines.h``
447
Etienne Carriere2f459d12019-03-11 11:58:05 +0100448Single Instance
449---------------
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200450``"gpd.ta.singleInstance"`` is a boolean property of the TA. This property
451defines if one instance of the TA must be created and will receive all open
452session request, or if a new specific TA instance must be created for each
453incoming open session request. OP-TEE TA flag ``TA_FLAG_SINGLE_INSTANCE`` sets
454to configuration of this property. The boolean property is set to ``true`` if
455``TA_FLAGS`` sets bit ``TA_FLAG_SINGLE_INSTANCE``, otherwise the boolean
456property is set to ``false``.
457
Etienne Carriere2f459d12019-03-11 11:58:05 +0100458Multi-session
459-------------
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200460``"gpd.ta.multiSession"`` is a boolean property of the TA. This property defines
461if the TA instance can handle several sessions. If disabled, TA instance support
462only one session. In such case, if the TA already has a opened session, any open
463session request will return with a busy error status.
464
465.. note::
466
467 This property is **meaningless** if TA is **NOT** SingleInstance TA.
468
469OP-TEE TA flag ``TA_FLAG_MULTI_SESSION`` sets to configuration of this property.
470The boolean property is set to ``true`` if ``TA_FLAGS`` sets bit
471``TA_FLAG_MULTI_SESSION``, otherwise the boolean property is set to ``false``.
472
Etienne Carriere2f459d12019-03-11 11:58:05 +0100473Keep Alive
474----------
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200475``"gpd.ta.instanceKeepAlive"`` is a boolean property of the TA. This property
476defines if the TA instance created must be destroyed or not when all sessions
477opened towards the TA are closed. If the property is enabled, TA instance, once
478created (at 1st open session request), is never removed unless the TEE itself is
479restarted (boot/reboot).
480
481.. note::
482
483 This property is **meaningless** if TA is **NOT** SingleInstance TA.
484
485OP-TEE TA flag ``TA_FLAG_INSTANCE_KEEP_ALIVE`` sets to configuration of this
486property. The boolean property is set to ``true`` if ``TA_FLAGS`` sets bit
487``TA_FLAG_INSTANCE_KEEP_ALIVE``, otherwise the boolean property is set to
488``false``.
489
Etienne Carriere2f459d12019-03-11 11:58:05 +0100490Heap Size
491---------
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200492``"gpd.ta.dataSize"`` is a 32bit integer property of the TA. This property
493defines the size in bytes of the TA allocation pool, in which ``TEE_Malloc()``
494and friends allocate memory. The value of the property must be defined by the
495macro ``TA_DATA_SIZE`` in ``user_ta_header_defines.h`` (see
496:ref:`build_ta_properties`).
497
Etienne Carriere2f459d12019-03-11 11:58:05 +0100498Stack Size
499----------
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200500``"gpd.ta.stackSize"`` is a 32bit integer property of the TA. This property
501defines the size in bytes of the stack used for TA execution. The value of the
502property must be defined by the macro ``TA_STACK_SIZE`` in
503``user_ta_header_defines.h`` (see :ref:`build_ta_properties`).
504
Etienne Carriere2f459d12019-03-11 11:58:05 +0100505Property Extensions
506===================
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200507
Etienne Carriere2f459d12019-03-11 11:58:05 +0100508Secure Data Path Flag
509---------------------
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200510``TA_FLAG_SECURE_DATA_PATH`` is a bit flag supported by ``TA_FLAGS``. This
511property flag claims the secure data support from the OP-TEE OS for the TA.
512Refer to the OP-TEE OS for secure data path support. TAs that do not set
513``TA_FLAG_SECURE_DATA_PATH`` in the value of ``TA_FLAGS`` will **not** be able
514to handle memory reference invocation parameters that relate to secure data path
515buffers.
516
Etienne Carriere5b99ccc2019-03-11 11:57:30 +0100517.. _ta_property_cache_maintenance:
Etienne Carriere2f459d12019-03-11 11:58:05 +0100518
519Cache maintenance Flag
520----------------------
Joakim Bech8e5c5b32018-10-25 08:18:32 +0200521``TA_FLAG_CACHE_MAINTENANCE`` is a bit flag supported by ``TA_FLAGS``. This
Etienne Carriere5b99ccc2019-03-11 11:57:30 +0100522property flag, when enabled, allows Trusted Applciation to use the cache
523maintenance API extension of the Internal Core API described in
524:ref:`extensions_cache_maintenance`. TAs that do not set
525``TA_FLAG_CACHE_MAINTENANCE`` in the value of their ``TA_FLAGS`` will not be
526able to call the cache maintenance API.
Etienne Carriere0ab5cc22019-03-11 10:44:13 +0100527
Etienne Carriere2f459d12019-03-11 11:58:05 +0100528Deprecated Property Flags
529-------------------------
Etienne Carriere0ab5cc22019-03-11 10:44:13 +0100530Older versions of OP-TEE used to define extended property flags that are
531deprecated and meaningless to current OP-TEE. These are ``TA_FLAG_USER_MODE``,
532``TA_FLAG_EXEC_DDR`` and ``TA_FLAG_REMAP_SUPPORT``.
Etienne Carriere2f459d12019-03-11 11:58:05 +0100533
534.. _ELF: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
535.. _early TA commit: https://github.com/OP-TEE/optee_os/commit/d0c636148b3a