feat(rmmd): add RMM_MECID_KEY_UPDATE call

With this addition, TF-A now has an SMC call to handle the
update of MEC keys associated to MECIDs.

The behavior of this newly added call is empty for now until an
implementation for the MPE (Memory Protection Engine) driver is
available. Only parameter sanitization has been implemented.

Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Juan Pablo Conde <juanpablo.conde@arm.com>
Change-Id: I2a969310b47e8c6da1817a79be0cd56158c6efc3
This commit is contained in:
Tushar Khandelwal 2024-04-22 15:35:40 +01:00 committed by Juan Pablo Conde
parent 7e84f3cf90
commit f801fdc22e
9 changed files with 150 additions and 6 deletions

View file

@ -52,8 +52,8 @@ are explained below:
- ``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.4 version of Boot Interface ABI and RMM-EL3
services specification and the 0.4 version of the Boot Manifest.
This document specifies the 0.5 version of Boot Interface ABI and RMM-EL3
services specification and the 0.5 version of the Boot Manifest.
.. _rmm_el3_boot_interface:
@ -671,6 +671,54 @@ a failure. The errors are ordered by condition check.
``E_RMM_OK``,No errors detected
RMM_MECID_KEY_UPDATE command
============================
This command updates the tweak for the encryption key/programs a new encryption key
associated with a given MECID. After the execution of this command, all memory
accesses associated with the MECID are encrypted/decrypted using the new key.
This command is available from v0.5 of the RMM-EL3 interface.
FID
---
``0xC40001B6``
Input values
------------
.. csv-table:: Input values for RMM_MECID_KEY_UPDATE
:header: "Name", "Register", "Field", "Type", "Description"
:widths: 1 1 1 1 5
fid,x0,[63:0],UInt64,Command FID
mecid,x1,[15:0],UInt64,"mecid is a 16-bit value between 0 and 65,535 that identifies the MECID for which the encryption key is to be updated. Value has to be a valid MECID as per field MECIDWidthm1 read from MECIDR_EL2. Bits [63:16] must be 0."
Output values
-------------
.. csv-table:: Output values for RMM_MECID_KEY_UPDATE
: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
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_MECID_KEY_UPDATE
:header: "ID", "Condition"
:widths: 1 5
``E_RMM_INVAL``,"if mecid is invalid (larger than 65,535 or than the maximum MECID width, determined by MECIDR_EL2.MECIDWidthm1)"
``E_RMM_UNK``,"An unknown error occurred whilst processing the command or the SMC is not present if interface version is <0.5"
``E_RMM_OK``,No errors detected
RMM-EL3 world switch register save restore convention
_____________________________________________________

View file

@ -2350,6 +2350,24 @@ RMM image and stores it in the area specified by manifest.
When ENABLE_RME is disabled, this function is not used.
Function : plat_rmm_mecid_key_update() [when ENABLE_RME == 1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
Argument : uint16_t
Return : int
This function is invoked by BL31's RMMD when there is a request from the RMM
monitor to update the tweak for the encryption key associated to a MECID.
The first parameter (``uint16_t mecid``) contains the MECID for which the
encryption key is to be updated.
Return value is 0 upon success and -EFAULT otherwise.
This function needs to be implemented by a platform if it enables RME.
Function : plat_rmmd_el3_token_sign_push_req() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -1585,4 +1585,11 @@
#define CLUSTERPMCR_N_SHIFT U(11)
#define CLUSTERPMCR_N_MASK U(0x1f)
/*******************************************************************************
* FEAT_MEC - Memory Encryption Contexts
******************************************************************************/
#define MECIDR_EL2 S3_4_C10_C8_7
#define MECIDR_EL2_MECIDWidthm1_MASK U(0xf)
#define MECIDR_EL2_MECIDWidthm1_SHIFT U(0)
#endif /* ARCH_H */

View file

@ -746,6 +746,9 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(fpmr, FPMR)
/* FEAT_MEC Registers */
DEFINE_RENAME_SYSREG_READ_FUNC(mecidr_el2, MECIDR_EL2)
#define IS_IN_EL(x) \
(GET_EL(read_CurrentEl()) == MODE_EL##x)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -398,6 +398,7 @@ int plat_rmmd_el3_token_sign_push_req(
int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp);
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
int plat_rmmd_mecid_key_update(uint16_t mecid);
#endif
/*******************************************************************************

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -161,6 +161,18 @@
#define RMM_EL3_TOKEN_SIGN_PULL_RESP_OP U(2)
#define RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP U(3)
/* Starting RMM-EL3 interface version 0.5 */
/*
* Function code to support update of MEC keys.
* The arguments of this SMC are:
* arg0 - Function ID.
* arg1 - MECID
* The return arguments are:
* ret0 - Status/Error
*/
#define RMM_MECID_KEY_UPDATE SMC64_RMMD_EL3_FID(U(6))
/* ECC Curve types for attest key generation */
#define ATTEST_KEY_CURVE_ECC_SECP384R1 U(0)
@ -188,7 +200,7 @@
* Increase this when a bug is fixed, or a feature is added without
* breaking compatibility.
*/
#define RMM_EL3_IFC_VERSION_MINOR (U(4))
#define RMM_EL3_IFC_VERSION_MINOR (U(5))
#define RMM_EL3_INTERFACE_VERSION \
(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \

View file

@ -7,6 +7,8 @@
#include <assert.h>
#include <string.h>
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/cci.h>
#include <drivers/arm/ccn.h>
@ -775,4 +777,16 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
return 0;
}
/*
* Update encryption key associated with @mecid.
*/
int plat_rmmd_mecid_key_update(uint16_t mecid)
{
/*
* FVP does not provide an interface to change the encryption key associated
* with MECID. Hence always return success.
*/
return 0;
}
#endif /* ENABLE_RME */

View file

@ -187,6 +187,17 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
return 0;
}
/*
* Update encryption key associated with @mecid.
*/
int plat_rmmd_mecid_key_update(uint16_t mecid)
{
/*
* TODO
*/
return 0;
}
int plat_rse_comms_init(void)
{
struct mhu_addr mhu_addresses;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -470,6 +470,33 @@ static int rmm_el3_ifc_get_feat_register(uint64_t feat_reg_idx,
return E_RMM_OK;
}
/*
* Update encryption key associated with @mecid.
*/
static int rmmd_mecid_key_update(uint64_t mecid)
{
uint64_t mecid_width, mecid_width_mask;
int ret;
/*
* Check whether the mecid parameter is at most MECIDR_EL2.MECIDWidthm1 + 1
* in length.
*/
mecid_width = ((read_mecidr_el2() >> MECIDR_EL2_MECIDWidthm1_SHIFT) &
MECIDR_EL2_MECIDWidthm1_MASK) + 1;
mecid_width_mask = ((1 << mecid_width) - 1);
if ((mecid & ~mecid_width_mask) != 0U) {
return E_RMM_INVAL;
}
ret = plat_rmmd_mecid_key_update(mecid);
if (ret != 0) {
return E_RMM_UNK;
}
return E_RMM_OK;
}
/*******************************************************************************
* This function handles RMM-EL3 interface SMCs
******************************************************************************/
@ -519,6 +546,9 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
rmmd_rmm_sync_exit(x1);
case RMM_MECID_KEY_UPDATE:
ret = rmmd_mecid_key_update(x1);
SMC_RET1(handle, ret);
default:
WARN("RMMD: Unsupported RMM-EL3 call 0x%08x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);