From a3f9617964ee30070855f9ba5e42ccb28dcc6a05 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Fri, 31 May 2024 13:57:36 +0100 Subject: [PATCH 1/5] feat(tc): initialize the RSE communication in earlier phase Move the RSE MHU channel initialization to the platform setup phase, this allows the services (e.g. TRNG service) to talk to RSE during the service init function. Change-Id: Id0ff6e49117008463f11b2dc3c585daca00f609c Signed-off-by: Leo Yan Signed-off-by: Icen Zeyada --- plat/arm/board/tc/tc_bl31_setup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c index bc8f5ec7f..4e346ab17 100644 --- a/plat/arm/board/tc/tc_bl31_setup.c +++ b/plat/arm/board/tc/tc_bl31_setup.c @@ -114,6 +114,8 @@ static void set_mcn_slc_alloc_mode(void) void bl31_platform_setup(void) { + psa_status_t status; + tc_bl31_common_platform_setup(); #if (TARGET_PLATFORM == 3) || (TARGET_PLATFORM == 4) enable_ns_mcn_pmu(); @@ -122,6 +124,12 @@ void bl31_platform_setup(void) set_mcn_slc_alloc_mode(); plat_arm_ni_setup(NCI_BASE_ADDR); #endif + + /* Initialise RSE communication channel */ + status = rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE); + if (status != PSA_SUCCESS) { + ERROR("Failed to initialize RSE communication channel - psa_status = %d\n", status); + } } scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id __unused) @@ -194,18 +202,10 @@ void __init bl31_plat_arch_setup(void) #if defined(SPD_spmd) && (SPMC_AT_EL3 == 0) void tc_bl31_plat_runtime_setup(void) { - psa_status_t status; - /* Start secure watchdog timer. */ plat_arm_secure_wdt_start(); arm_bl31_plat_runtime_setup(); - - /* Initialise RSE communication channel */ - status = rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE); - if (status != PSA_SUCCESS) { - ERROR("Failed to initialize RSE communication channel - psa_status = %d\n", status); - } } void bl31_plat_runtime_setup(void) From 2ae197acd6a91a96619090e503521d44bee494b2 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Thu, 16 May 2024 15:59:41 +0100 Subject: [PATCH 2/5] feat(tc): enable trng Enable the trng on the platform, which can be used by other features. `rng-seed` has been removed and enabled `FEAT_RNG_TRAP` to trap to EL3 when accessing system registers RNDR and RNDRRS Change-Id: Ibde39115f285e67d31b14863c75beaf37493deca Signed-off-by: Leo Yan Signed-off-by: Icen Zeyada --- fdts/tc-base.dtsi | 15 ------------ plat/arm/board/tc/platform.mk | 14 +++++++++-- plat/arm/board/tc/tc_rng_trap.c | 41 +++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 plat/arm/board/tc/tc_rng_trap.c diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi index 691a3b8c0..33e165720 100644 --- a/fdts/tc-base.dtsi +++ b/fdts/tc-base.dtsi @@ -46,21 +46,6 @@ serial0 = &os_uart; }; - chosen { - /* - * Add some dummy entropy for Linux so it - * doesn't delay the boot waiting for it. - */ - rng-seed = <0x01 0x02 0x04 0x05 0x06 0x07 0x08 \ - 0x01 0x02 0x04 0x05 0x06 0x07 0x08 \ - 0x01 0x02 0x04 0x05 0x06 0x07 0x08 \ - 0x01 0x02 0x04 0x05 0x06 0x07 0x08 \ - 0x01 0x02 0x04 0x05 0x06 0x07 0x08 \ - 0x01 0x02 0x04 0x05 0x06 0x07 0x08 \ - 0x01 0x02 0x04 0x05 0x06 0x07 0x08 \ - 0x01 0x02 0x04 0x05 0x06 0x07 0x08 >; - }; - cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index b2b32531c..8b15a6f23 100644 --- a/plat/arm/board/tc/platform.mk +++ b/plat/arm/board/tc/platform.mk @@ -40,6 +40,12 @@ ENABLE_FEAT_MTE2 := 2 ENABLE_SPE_FOR_NS := 3 ENABLE_FEAT_TCR2 := 3 +ifneq ($(filter ${TARGET_PLATFORM}, 3),) +ENABLE_FEAT_RNG_TRAP := 0 +else +ENABLE_FEAT_RNG_TRAP := 1 +endif + CTX_INCLUDE_AARCH32_REGS := 0 ifeq (${SPD},spmd) @@ -47,6 +53,8 @@ ifeq (${SPD},spmd) CTX_INCLUDE_PAUTH_REGS := 1 endif +TRNG_SUPPORT := 1 + # TC RESOLUTION - LIST OF VALID OPTIONS (this impacts only FVP) TC_RESOLUTION_OPTIONS := 640x480p60 \ 1920x1080p60 @@ -285,8 +293,10 @@ ifeq (${MEASURED_BOOT},1) endif endif -ifeq (${TRNG_SUPPORT},1) - BL31_SOURCES += plat/arm/board/tc/tc_trng.c +BL31_SOURCES += plat/arm/board/tc/tc_trng.c + +ifneq (${ENABLE_FEAT_RNG_TRAP},0) + BL31_SOURCES += plat/arm/board/tc/tc_rng_trap.c endif ifneq (${PLATFORM_TEST},) diff --git a/plat/arm/board/tc/tc_rng_trap.c b/plat/arm/board/tc/tc_rng_trap.c new file mode 100644 index 000000000..b055fe406 --- /dev/null +++ b/plat/arm/board/tc/tc_rng_trap.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#define XZR_REG_NUM 31 + + +int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx) +{ + uint64_t entropy; + + /* extract the target register number from the exception syndrome */ + unsigned int rt = get_sysreg_iss_rt(esr_el3); + + /* ignore XZR accesses and writes to the register */ + assert(rt != XZR_REG_NUM && !is_sysreg_iss_write(esr_el3)); + + if (!plat_get_entropy(&entropy)) { + ERROR("Failed to get entropy\n"); + panic(); + } + + /* Emulate RNDR and RNDRRS */ + gp_regs_t *gpregs = get_gpregs_ctx(ctx); + + write_ctx_reg(gpregs, rt, entropy); + + /* + * We successfully handled the trap, continue with the next + * instruction. + */ + return TRAP_RET_CONTINUE; +} From 8a41106c83961029c2d251f390c091d398c100a6 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Fri, 31 Jan 2025 17:16:34 +0000 Subject: [PATCH 3/5] fix(psa): guard Crypto APIs with CRYPTO_SUPPORT When building Crypto APIs, it requires dependency on external headers, e.g., Mbedtls headers. Without the CRYPTO_SUPPORT configuration, external dependencies are not set up, building Crypto APIs will fail. Guard Crypto APIs with the CRYPTO_SUPPORT configuration, to make sure the code is built only for Crypto enabled case. Change-Id: Iffe1220b0e6272586c46432b4f8d0512cb39b0b5 Signed-off-by: Leo Yan --- include/lib/psa/rse_platform_api.h | 4 ++++ lib/psa/rse_platform.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/include/lib/psa/rse_platform_api.h b/include/lib/psa/rse_platform_api.h index 535001bd6..c9fdb55b1 100644 --- a/include/lib/psa/rse_platform_api.h +++ b/include/lib/psa/rse_platform_api.h @@ -11,7 +11,9 @@ #include #include "psa/error.h" +#if CRYPTO_SUPPORT #include +#endif #define RSE_PLATFORM_API_ID_NV_READ (1010) #define RSE_PLATFORM_API_ID_NV_INCREMENT (1011) @@ -42,6 +44,7 @@ psa_status_t rse_platform_nv_counter_read(uint32_t counter_id, uint32_t size, uint8_t *val); +#if CRYPTO_SUPPORT /* * Reads the public key or the public part of a key pair in binary format. * @@ -56,5 +59,6 @@ rse_platform_nv_counter_read(uint32_t counter_id, psa_status_t rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data, size_t data_size, size_t *data_length); +#endif #endif /* RSE_PLATFORM_API_H */ diff --git a/lib/psa/rse_platform.c b/lib/psa/rse_platform.c index 7fc238206..9ede8b4d5 100644 --- a/lib/psa/rse_platform.c +++ b/lib/psa/rse_platform.c @@ -7,7 +7,9 @@ #include #include +#if CRYPTO_SUPPORT #include +#endif #include psa_status_t @@ -41,6 +43,7 @@ rse_platform_nv_counter_read(uint32_t counter_id, in_vec, 1, out_vec, 1); } +#if CRYPTO_SUPPORT psa_status_t rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data, size_t data_size, size_t *data_length) @@ -67,3 +70,4 @@ rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data, return status; } +#endif From 1147a470c257403466cdbd55a13823ca1652063e Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Fri, 31 Jan 2025 10:07:51 +0000 Subject: [PATCH 4/5] feat(psa): add interface with RSE for retrieving entropy Add the AP/RSS interface for reading the entropy. And update the document for the API. Change-Id: I61492d6b5d824a01ffeadc92f9d41ca841ba3367 Signed-off-by: Leo Yan Signed-off-by: Icen Zeyada --- docs/design_documents/rse.rst | 15 +++++++++++++++ include/lib/psa/rse_crypto_defs.h | 3 +++ include/lib/psa/rse_platform_api.h | 12 ++++++++++++ lib/psa/rse_platform.c | 23 +++++++++++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/docs/design_documents/rse.rst b/docs/design_documents/rse.rst index dd110ca82..21e5fd46e 100644 --- a/docs/design_documents/rse.rst +++ b/docs/design_documents/rse.rst @@ -781,6 +781,21 @@ Arm CCA platform: - ``ROTPK for secure firmware.`` - ``ROTPK for non-secure firmware.`` +Get entropy API +^^^^^^^^^^^^^^^ + +AP/RSE interface for reading the entropy is as follows. + +Defined here: + +- ``include/lib/psa/rse_platform_api.h`` + +.. code-block:: c + + psa_status_t rse_platform_get_entropy(uint8_t *data, size_t data_size) + +Through this service, we can read an entropy generated from RSE. + References ---------- diff --git a/include/lib/psa/rse_crypto_defs.h b/include/lib/psa/rse_crypto_defs.h index b94664fb6..ea1342fd5 100644 --- a/include/lib/psa/rse_crypto_defs.h +++ b/include/lib/psa/rse_crypto_defs.h @@ -11,6 +11,9 @@ /* Declares types that encode errors, algorithms, key types, policies, etc. */ #include "psa/crypto_types.h" +/* Value identifying random number generating API */ +#define RSE_CRYPTO_GENERATE_RANDOM_SID (uint16_t)(0x100) + /* * Value identifying export public key function API, used to dispatch the request * to the corresponding API implementation in the Crypto service backend. diff --git a/include/lib/psa/rse_platform_api.h b/include/lib/psa/rse_platform_api.h index c9fdb55b1..fcfeb5050 100644 --- a/include/lib/psa/rse_platform_api.h +++ b/include/lib/psa/rse_platform_api.h @@ -59,6 +59,18 @@ rse_platform_nv_counter_read(uint32_t counter_id, psa_status_t rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data, size_t data_size, size_t *data_length); + +/* + * Gets the entropy. + * + * data Buffer where the entropy data is to be written. + * data_size Size of the data buffer in bytes. + * + * PSA_SUCCESS if the entropy is generated successfully. Otherwise, + * it returns a PSA_ERROR. + */ +psa_status_t +rse_platform_get_entropy(uint8_t *data, size_t data_size); #endif #endif /* RSE_PLATFORM_API_H */ diff --git a/lib/psa/rse_platform.c b/lib/psa/rse_platform.c index 9ede8b4d5..ffa2f480a 100644 --- a/lib/psa/rse_platform.c +++ b/lib/psa/rse_platform.c @@ -70,4 +70,27 @@ rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data, return status; } + +psa_status_t +rse_platform_get_entropy(uint8_t *data, size_t data_size) +{ + psa_status_t status; + + struct rse_crypto_pack_iovec iov = { + .function_id = RSE_CRYPTO_GENERATE_RANDOM_SID, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct rse_crypto_pack_iovec)}, + }; + psa_outvec out_vec[] = { + {.base = data, .len = data_size} + }; + + status = psa_call(RSE_CRYPTO_HANDLE, PSA_IPC_CALL, + in_vec, IOVEC_LEN(in_vec), + out_vec, IOVEC_LEN(out_vec)); + + return status; +} #endif From 8f0235fb8f2d46ee6ca6309f8c365ad57e3a1565 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Fri, 31 Jan 2025 10:20:28 +0000 Subject: [PATCH 5/5] feat(tc): get entropy with PSA Crypto API The PSA Crypto API is available with sending messages to RSE. Change to invoke PSA Crypto API for getting entropy. Change-Id: I4b2dc4eb99606c2425b64949d9c3f5c576883758 Signed-off-by: Leo Yan Signed-off-by: Icen Zeyada --- plat/arm/board/tc/platform.mk | 3 ++- plat/arm/board/tc/tc_trng.c | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index 8b15a6f23..21d712221 100644 --- a/plat/arm/board/tc/platform.mk +++ b/plat/arm/board/tc/platform.mk @@ -248,7 +248,8 @@ include drivers/arm/rse/rse_comms.mk BL1_SOURCES += ${RSE_COMMS_SOURCES} BL2_SOURCES += ${RSE_COMMS_SOURCES} -BL31_SOURCES += ${RSE_COMMS_SOURCES} +BL31_SOURCES += ${RSE_COMMS_SOURCES} \ + lib/psa/rse_platform.c # Include Measured Boot makefile before any Crypto library makefile. # Crypto library makefile may need default definitions of Measured Boot build diff --git a/plat/arm/board/tc/tc_trng.c b/plat/arm/board/tc/tc_trng.c index e5ec48a1a..793a90fbc 100644 --- a/plat/arm/board/tc/tc_trng.c +++ b/plat/arm/board/tc/tc_trng.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -24,20 +25,33 @@ DEFINE_SVC_UUID2(_plat_trng_uuid, ); uuid_t plat_trng_uuid; -/* Dummy implementation */ bool plat_get_entropy(uint64_t *out) { +#if CRYPTO_SUPPORT + psa_status_t status; + + status = rse_platform_get_entropy((uint8_t *)out, sizeof(*out)); + if (status != PSA_SUCCESS) { + printf("Failed for entropy read, psa_status=%d\n", status); + return false; + } +#else + /* Dummy value */ *out = 0xABBAEDDAACDCDEAD; +#endif return true; } void plat_entropy_setup(void) { - uint64_t dummy; + uint64_t entropy; plat_trng_uuid = _plat_trng_uuid; /* Initialise the entropy source and trigger RNG generation */ - plat_get_entropy(&dummy); + if (!plat_get_entropy(&entropy)) { + ERROR("Failed to setup entropy\n"); + panic(); + } }