arch/tas: Updates for REE filesystem TAs
Document support for:
- Optionally encrypted REE-FS TAs.
- Rollback protection of REE-FS TAs.
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Jerome Forissier <jerome@forissier.org>
diff --git a/architecture/trusted_applications.rst b/architecture/trusted_applications.rst
index 22a466d..51542ab 100644
--- a/architecture/trusted_applications.rst
+++ b/architecture/trusted_applications.rst
@@ -71,19 +71,48 @@
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.
+They consist of a ELF_ file, signed and optionally encrypted, 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
+Because the TAs are signed and optionally encrypted with
+``scripts/sign_encrypt.py``, 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.
+and loaded by the Secure World OP-TEE core.
-REE filesystem TAs come in two formats, the legacy TA and the bootstrap TA.
-The bootstrap TA format is used by ``scripts/sign.py`` since version 3.7.0.
+REE-FS TA rollback protection
+-----------------------------
+OP-TEE core maintains a ``ta_ver.db`` file in secure storage to check for
+version of REE TAs as they are loaded from REE-FS in order to prevent against
+any TA version downgrades. TA version can be configured via TA build option:
+``CFG_TA_VERSION=<unsigned integer>``.
+Note: Here rollback protection is effective only when ``CFG_RPMB_FS=y``.
+
+REE-FS TA formats
+-----------------
+REE filesystem TAs come in three formats:
+
+ 1. Legacy TAs signed, not encrypted, cannot be created anymore by the build
+ scripts since version 3.7.0.
+
+ 2. Bootstrap TAs, signed with the key from the build of the original OP-TEE
+ core blob, not encrypted.
+
+ 3. Encrypted TAs, sign-then-encrypt-then-MAC, encrypted with ``TA_ENC_KEY``
+ when ``CFG_ENCRYPT_TA=y``. During OP-TEE runtime, the symmetric key used
+ to decrypt TA has to be provided in a platform specific manner via
+ overriding API:
+
+ .. code-block:: c
+
+ TEE_Result tee_otp_get_ta_enc_key(uint32_t key_type, uint8_t *buffer,
+ size_t len);
+
+REE-FS TA header structure
+--------------------------
All REE filesystems TAs has common header, ``struct shdr``, defined as:
.. code-block:: c
@@ -91,6 +120,7 @@
enum shdr_img_type {
SHDR_TA = 0,
SHDR_BOOTSTRAP_TA = 1,
+ SHDR_ENCRYPTED_TA = 2,
};
#define SHDR_MAGIC 0x4f545348
@@ -158,8 +188,60 @@
The fields ``uuid`` and ``ta_version`` allows extra checks to be performed
when loading the TA. Currently only the ``uuid`` field is checked.
-Last in the TA binary follows the ELF file which normally is stripped
-as additional symbols etc will be ignored when loading the TA.
+For encrypted TAs ``struct shdr`` is followed by a subheader, ``struct
+shdr_bootstrap_ta`` which is followed by another subheader, ``struct
+shdr_encrypted_ta`` defined as:
+
+.. code-block:: c
+
+ /**
+ * struct shdr_encrypted_ta - encrypted TA header
+ * @enc_algo: authenticated encyption algorithm, defined by symmetric key
+ * algorithms TEE_ALG_* from TEE Internal API
+ * specification
+ * @flags: authenticated encyption flags
+ * @iv_size: size of the initialization vector
+ * @tag_size: size of the authentication tag
+ * @iv: initialization vector
+ * @tag: authentication tag
+ */
+ struct shdr_encrypted_ta {
+ uint32_t enc_algo;
+ uint32_t flags;
+ uint16_t iv_size;
+ uint16_t tag_size;
+ /*
+ * Commented out element used to visualize the layout dynamic part
+ * of the struct.
+ *
+ * iv is accessed through the macro SHDR_ENC_GET_IV and
+ * tag is accessed through the macro SHDR_ENC_GET_TAG
+ *
+ * uint8_t iv[iv_size];
+ * uint8_t tag[tag_size];
+ */
+ };
+
+The field ``enc_algo`` tells the algorithm used. The script used to encrypt
+TAs currently uses ``TEE_ALG_AES_GCM`` (0x40000810). OP-TEE core also accepts
+``TEE_ALG_AES_CCM`` algorithm.
+
+The field ``flags`` supports a single flag to tell encryption key type which
+is defined as:
+
+.. code-block:: c
+
+ #define SHDR_ENC_KEY_TYPE_MASK 0x1
+
+ enum shdr_enc_key_type {
+ SHDR_ENC_KEY_DEV_SPECIFIC = 0,
+ SHDR_ENC_KEY_CLASS_WIDE = 1,
+ };
+
+REE-FS TA binary formats
+------------------------
+TA binary follows the ELF file which normally is stripped as additional
+symbols etc will be ignored when loading the TA.
Legacy TA binary is formatted as:
@@ -178,6 +260,22 @@
bootstrap_binary = <struct shdr> || <hash> || <signature> ||
<struct shdr_bootstrap_ta> || <stripped ELF>
+Encrypted TA binary is formatted as:
+
+.. code-block:: none
+
+ nonce = <unique random value>
+ ciphertext, tag = AES_GCM(<stripped ELF>)
+ hash = H(<struct shdr> || <struct shdr_bootstrap_ta> ||
+ <struct shdr_encrypted_ta> || <nonce> || <tag> || <stripped ELF>)
+ signature = RSA-Sign(<hash>)
+ encrypted_binary = <struct shdr> || <hash> || <signature> ||
+ <struct shdr_bootstrap_ta> ||
+ <struct shdr_encrypted_ta> || <nonce> || <tag> ||
+ <ciphertext>
+
+Loading REE-FS TA
+-----------------
A REE TA is loaded into shared memory using a series or RPC in
:ref:`load_ree_ta`. The payload memory is allocated via TEE-supplicant and
later freed when the TA has been loaded into secure memory in