From f801fdc22ef4fce3cc24fd1cbccde5772c15b633 Mon Sep 17 00:00:00 2001 From: Tushar Khandelwal Date: Mon, 22 Apr 2024 15:35:40 +0100 Subject: [PATCH 1/2] 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 Signed-off-by: Jean-Philippe Brucker Signed-off-by: Juan Pablo Conde Change-Id: I2a969310b47e8c6da1817a79be0cd56158c6efc3 --- docs/components/rmm-el3-comms-spec.rst | 52 ++++++++++++++++++- docs/porting-guide.rst | 18 +++++++ include/arch/aarch64/arch.h | 7 +++ include/arch/aarch64/arch_helpers.h | 3 ++ include/plat/common/platform.h | 3 +- include/services/rmmd_svc.h | 16 +++++- plat/arm/board/fvp/fvp_common.c | 14 +++++ .../neoverse_rd/platform/rdv3/rdv3_common.c | 11 ++++ services/std_svc/rmmd/rmmd_main.c | 32 +++++++++++- 9 files changed, 150 insertions(+), 6 deletions(-) diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst index f1ca031f7..dfdabc68c 100644 --- a/docs/components/rmm-el3-comms-spec.rst +++ b/docs/components/rmm-el3-comms-spec.rst @@ -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 _____________________________________________________ diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst index 0f0deddca..327c67b1a 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -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] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 627416feb..67fdead99 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -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 */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index f85da972b..55b61993f 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -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) diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index b43f131bc..708cbcd3f 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -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 /******************************************************************************* diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h index 0cc8628a6..8bf93194e 100644 --- a/include/services/rmmd_svc.h +++ b/include/services/rmmd_svc.h @@ -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) | \ diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 7d7681473..98d4bbcd6 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include #include @@ -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 */ diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c index 364bce1ad..b1ee5e605 100644 --- a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c +++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c @@ -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; diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c index 10a2c429a..3ebae1302 100644 --- a/services/std_svc/rmmd/rmmd_main.c +++ b/services/std_svc/rmmd/rmmd_main.c @@ -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); From 9c9a31eb9ae36cab9db58ddc5d49f82ca3cf976d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Tue, 18 Mar 2025 14:35:11 +0000 Subject: [PATCH 2/2] feat(qemu): add plat_rmmd_mecid_key_update() Add an implementation of the plat_rmmd_mecid_key_update() callback, that updates the MEC keys associated with a MECID. Leave it empty for now, since QEMU doesn't yet implement an MPE (Memory Protection Engine). Change-Id: I2746f6024f28e4fd487726de9e43e14d8cad57a0 Signed-off-by: Jean-Philippe Brucker --- plat/qemu/common/qemu_common.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c index a88297da8..4a79a908c 100644 --- a/plat/qemu/common/qemu_common.c +++ b/plat/qemu/common/qemu_common.c @@ -400,6 +400,18 @@ 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) +{ + /* + * QEMU does not provide an interface to change the encryption key + * associated with MECID. Hence always return success. + */ + return 0; +} #endif /* ENABLE_RME */ /**