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/fdts/tc-base.dtsi b/fdts/tc-base.dtsi index 462379006..fc0b3b642 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/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 535001bd6..fcfeb5050 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. * @@ -57,4 +60,17 @@ 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 7fc238206..ffa2f480a 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,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 diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index b2b32531c..21d712221 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 @@ -240,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 @@ -285,8 +294,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_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) 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; +} 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(); + } }