docs: el3 token signing

Add documentation for the feature where EL3 can be used to sign realm
attestation token requests using RMM_EL3_TOKEN_SIGN command.
This patch also adds documentation for the RMM_EL3_FEATURES features
command that can be used to discover support for features such as
RMM_EL3_TOKEN_SIGN.

Change-Id: Iab5a157761ed17931210c3702f813198fc9c4b3a
Signed-off-by: Raghu Krishnamurthy <raghupathyk@nvidia.com>
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 03703bc..79e1d2c 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -52,7 +52,7 @@
   - ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
     consistency with the versioning schemes used in other parts of RMM.
 
-This document specifies the 0.3 version of Boot Interface ABI and RMM-EL3
+This document specifies the 0.4 version of Boot Interface ABI and RMM-EL3
 services specification and the 0.3 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
@@ -259,6 +259,8 @@
    0xC40001B1,``RMM_GTSI_UNDELEGATE``
    0xC40001B2,``RMM_ATTEST_GET_REALM_KEY``
    0xC40001B3,``RMM_ATTEST_GET_PLAT_TOKEN``
+   0xC40001B4,``RMM_EL3_FEATURES``
+   0xC40001B5,``RMM_EL3_TOKEN_SIGN``
 
 RMM_RMI_REQ_COMPLETE command
 ============================
@@ -505,6 +507,170 @@
    ``E_RMM_UNK``,An unknown error occurred whilst processing the command
    ``E_RMM_OK``,No errors detected
 
+RMM_EL3_FEATURES command
+========================
+
+This command provides a mechanism to discover features and ABIs supported by the
+RMM-EL3 interface, for a given version. This command is helpful when there are
+platform specific optional RMM-EL3 interfaces and features exposed by vendor
+specific EL3 firmware, and a generic RMM that can modify its behavior based on
+discovery of EL3 features.
+
+The features can be discovered by specifying the feature register index that
+has fields defined to indicate presence or absence of features and other
+relevant information. The feature register index is specified in the
+``feat_reg_idx`` parameter. Each feature register is a 64 bit register.
+
+This command is available from v0.4 of the RMM-EL3 interface.
+
+The following is the register definition for feature register index 0 for
+v0.4 of the interface:
+
+RMM-EL3 Feature Resister 0
+--------------------------
+
+.. code-block:: none
+
+    63      32      31      16       15      8       7       1       0
+    +-------+-------+-------+-------+-------+-------+-------+-------+
+    |       |       |       |       |       |       |       |       |
+    |       |       |       |       |       |       |       |       |
+    +-------+-------+-------+-------+-------+-------+-------+-------+
+                                                             ^
+                                                             |
+                                                 RMMD_EL3_TOKEN_SIGN
+
+**Bit Fields:**
+
+- **Bit 0**: `RMMD_EL3_TOKEN_SIGN`
+    - When set to 1, the `RMMD_EL3_TOKEN_SIGN` feature is enabled.
+    - When cleared (0), the feature is disabled.
+- **Bits [1:63]**: Reserved (must be zero)
+
+FID
+---
+
+``0xC40001B4``
+
+
+Input values
+------------
+
+.. csv-table:: Input values for RMM_EL3_FEATURES
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   fid,x0,[63:0],UInt64,Command FID
+   feat_reg_idx,x1,[63:0],UInt64, "Feature register index. For v0.4, a value of 0 is the only
+   acceptable value"
+
+
+Output values
+-------------
+
+.. csv-table:: Output values for RMM_EL3_FEATURES
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   Result,x0,[63:0],Error Code,Command return status
+   feat_reg,x1,[63:0],Value,Value of the register as defined above
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table:: Failure conditions for RMM_EL3_FEATURES
+   :header: "ID", "Condition"
+   :widths: 1 5
+
+   ``E_RMM_INVAL``,``feat_reg_idx`` is out of valid range
+   ``E_RMM_UNK``,"if the SMC is not present, if interface version is <0.4"
+   ``E_RMM_OK``,No errors detected
+
+RMM_EL3_TOKEN_SIGN command
+==========================
+
+This command is an optional command that can be discovered using the RMM_EL3_FEATURES command.
+This command is used to send requests related to realm attestation token signing requests to EL3.
+The command supports 3 opcodes:
+
+   - RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP
+   - RMM_EL3_TOKEN_SIGN_PULL_RESP_OP
+   - RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+
+The above opcodes can be used to send realm attestation token signing requests to EL3 and get their
+response, so that the realm attestation token can be constructed.
+
+This command is useful when the RMM may not have access to the private portion of the realm
+attestation key and needs signing services from EL3 or CCA HES, or other platform specific
+mechanisms to perform signing.
+
+The RMM-EL3 interface for this command is modeled as two separate queues, one for signing requests
+and one for retrieving the signed responses. It is possible that the queue in EL3 is full or EL3 is busy and
+unable to service the RMM requests, in which case the RMM is expected to retry the push operation
+for requests and pop operation for responses.
+
+FID
+---
+
+``0xC40001B5``
+
+Input values
+------------
+
+.. csv-table:: Input values for RMM_EL3_TOKEN_SIGN
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   fid,x0,[63:0],UInt64,Command FID
+   opcode,x1,[63:0],UInt64,"
+   Opcode that is one of:
+
+    - RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP: 0x1 -
+      Opcode to push a token signing request to EL3 using struct el3_token_sign_request as described above
+    - RMM_EL3_TOKEN_SIGN_PULL_RESP_OP: 0x2 -
+      Opcode to pull a token signing response from EL3 using struct el3_token_sign_response as described above
+    - RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP: 0x3 -
+      Opcode to get the realm attestation public key
+
+   "
+   buf_pa,x2,[63:0],Address,"PA where the request structure is stored for the opcode RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP, the response structure needs to be populated for the opcode RMM_EL3_TOKEN_SIGN_PULL_RESP_OP, or where the public key must be populated for the opcode RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP. The PA must belong to the RMM-EL3 shared buffer"
+   buf_size,x3,[63:0],Size,Size in bytes of the input buffer in ``buf_pa``. ``buf_pa + buf_size`` must lie within the shared buffer
+   ecc_curve,x4,[63:0],Enum,Type of the elliptic curve to which the requested attestation key belongs to. See :ref:`ecc_curves`. This parameter is valid on for the opcode RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+
+Output values
+-------------
+
+.. csv-table:: Output values for RMM_EL3_TOKEN_SIGN
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   Result,x0,[63:0],Error Code,Command return status. Valid for all opcodes listed in input values
+   retval1,x1,[63:0],Value, "If opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP, then returns length of
+   public key returned. Otherwise, reserved"
+
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table:: Failure conditions for RMM_EL3_TOKEN_SIGN
+   :header: "ID", "Condition"
+   :widths: 1 5
+
+   ``E_RMM_INVAL``,"if opcode is invalid or buffer address and length passed to the EL3 are not in valid range
+   corresponding to the RMM-EL3 shared buffer, or if the curve used for opcode
+   RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP is not the ECC P384 curve"
+   ``E_RMM_UNK``,"if the SMC is not present, if interface version is <0.4"
+   ``E_RMM_AGAIN``,"For opcode RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP, if the request is not queued since
+   the EL3 queue is full, or if the response is not ready yet, for other opcodes"
+   ``E_RMM_OK``,No errors detected
+
+
 RMM-EL3 world switch register save restore convention
 _____________________________________________________
 
@@ -654,3 +820,55 @@
 | flags     |   40   |   uint64_t    | Additional flags (RES0)                |
 +-----------+--------+---------------+----------------------------------------+
 
+.. _el3_token_sign_request_struct:
+
+EL3 Token Sign Request structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This structure represents a realm attestation toekn signing request.
+
++-------------+--------+---------------+-----------------------------------------+
+|   Name      | Offset |     Type      |               Description               |
++=============+========+===============+=========================================+
+| sig_alg_id  |   0    |   uint32_t    | Algorithm idenfier for the sign request.|
+|             |        |               | - 0x0: ECC SECP384R1 (ECDSA)            |
+|             |        |               | - Other values reserved                 |
++-------------+--------+---------------+-----------------------------------------+
+| rec_granule |   8    |   uint64_t    | Identifier used by RMM to associate     |
+|             |        |               | a signing request to a realm. Must not  |
+|             |        |               | be interpreted or modified.             |
++-------------+--------+---------------+-----------------------------------------+
+| req_ticket  |   16   |   uint64_t    | Value used by RMM to associate request  |
+|             |        |               | and responses. Must not be interpreted  |
+|             |        |               | or modified.                            |
++-------------+--------+---------------+-----------------------------------------+
+| hash_alg_id |   24   |   uint32_t    | Hash algorithm for data in `hash_buf`   |
+|             |        |               | - 0x1: SHA2-384                         |
+|             |        |               | - All other values reserved.            |
++-------------+--------+---------------+-----------------------------------------+
+| hash_buf    |   32   |   uint8_t[]   | TBS (to-be-signed) Hash of length       |
+|             |        |               | defined by hash algorithm `hash_alg_id` |
++-------------+--------+---------------+-----------------------------------------+
+
+.. _el3_token_sign_response_struct:
+
+EL3 Token Sign Response structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This structure represents a realm attestation token signing response.
+
++---------------+--------+---------------+-----------------------------------------+
+|   Name        | Offset |     Type      |               Description               |
++===============+========+===============+=========================================+
+| rec_granule   |   0    |   uint64_t    | Identifier used by RMM to associate     |
+|               |        |               | a signing request to a realm. Must not  |
+|               |        |               | be interpreted or modified.             |
++---------------+--------+---------------+-----------------------------------------+
+| req_ticket    |   8    |   uint64_t    | Value used by RMM to associate request  |
+|               |        |               | and responses. Must not be interpreted  |
+|               |        |               | or modified.                            |
++---------------+--------+---------------+-----------------------------------------+
+| sig_len       |   16   |   uint16_t    | Length of the `signature_buf` field     |
++---------------+--------+---------------+-----------------------------------------+
+| signature_buf |   18   |   uint8_t[]   | Signature                               |
++---------------+--------+---------------+-----------------------------------------+
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 772447a..cd10cd6 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -1343,6 +1343,13 @@
    Management Extension. This flag can take the values 0 to 2, to align with
    the ``ENABLE_FEAT`` mechanism. Default value is 0.
 
+-  ``RMMD_ENABLE_EL3_TOKEN_SIGN``: Numeric value to enable support for singing
+   realm attestation token signing requests in EL3. This flag can take the
+   values 0 and 1. The default value is ``0``. When set to ``1``, this option
+   enables additional RMMD SMCs to push and pop requests for signing to
+   EL3 along with platform hooks that must be implemented to service those
+   requests and responses.
+
 -  ``ENABLE_SME_FOR_NS``: Numeric value to enable Scalable Matrix Extension
    (SME), SVE, and FPU/SIMD for the non-secure world only. These features share
    registers so are enabled together. Using this option without
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index e672ad7..5cb20fd 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2329,6 +2329,98 @@
 
 When ENABLE_RME is disabled, this function is not used.
 
+Function : plat_rmmd_el3_token_sign_push_req() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Arguments : const struct el3_token_sign_request *req
+    Return    : int
+
+Queue realm attestation token signing request from the RMM in EL3. The interface between
+the RMM and EL3 is modeled as a queue but the underlying implementation may be different,
+so long as the semantics of queuing and the error codes are used as defined below.
+
+See :ref:`el3_token_sign_request_struct` for definition of the request structure.
+
+Optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the functions are:
+      arg0: Pointer to the token sign request to be pushed to EL3.
+      The structure must be located in the RMM-EL3 shared
+      memory buffer and must be locked before use.
+
+Return codes:
+        - E_RMM_OK	On Success.
+        - E_RMM_INVAL   If the arguments are invalid.
+        - E_RMM_AGAIN   Indicates that the request was not queued since the
+	  queue in EL3 is full. This may also be returned for any reason
+	  or situation in the system, that prevents accepting the request
+	  from the RMM.
+        - E_RMM_UNK     If the SMC is not implemented or if interface
+	  version is < 0.4.
+
+Function : plat_rmmd_el3_token_sign_pull_resp() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Arguments : struct el3_token_sign_response *resp
+    Return    : int
+
+Populate the attestation signing response in the ``resp`` parameter. The interface between
+the RMM and EL3 is modeled as a queue for responses but the underlying implementation may
+be different, so long as the semantics of queuing and the error codes are used as defined
+below.
+
+See :ref:`el3_token_sign_response_struct` for definition of the response structure.
+
+Optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the functions are:
+          resp: Pointer to the token sign response to get from EL3.
+	  The structure must be located in the RMM-EL3 shared
+	  memory buffer and must be locked before use.
+
+Return:
+        - E_RMM_OK      On Success.
+        - E_RMM_INVAL   If the arguments are invalid.
+        - E_RMM_AGAIN   Indicates that a response is not ready yet.
+        - E_RMM_UNK     If the SMC is not implemented or if interface
+	  version is < 0.4.
+
+Function : plat_rmmd_el3_token_sign_get_rak_pub() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uintptr_t, size_t *, unsigned int
+    Return   : int
+
+This function returns the public portion of the realm attestation key which will be used to
+sign Realm attestation token. Typically, with delegated attestation, the private key is
+returned, however, there may be platforms where the private key bits are better protected
+in a platform specific manner such that the private key is not exposed. In such cases,
+the RMM will only cache the public key and forward any requests such as signing, that
+uses the private key to EL3. The API currently only supports P-384 ECC curve key.
+
+This is an optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the function are:
+
+    arg0 - A pointer to the buffer where the public key should be copied
+    by this function. The buffer must be big enough to hold the
+    attestation key.
+
+    arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
+    function returns the attestation key length in this parameter.
+
+    arg2 - The type of the elliptic curve to which the requested attestation key
+    belongs.
+
+The function returns E_RMM_OK on success, RMM_E_INVAL if arguments are invalid and
+E_RMM_UNK if the SMC is not implemented or if interface version is < 0.4.
+
 Function : bl31_plat_enable_mmu [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~