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]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~