mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 09:34:18 +00:00

When a platform decides to use FEAT_RNG_TRAP, every RNDR or RNDRSS read will trap into EL3. The platform can then emulate those instructions, by either executing the real CPU instructions, potentially conditioning the results, or use rate-limiting or filtering to protect the hardware entropy pool. Another possiblitiy would be to use some platform specific TRNG device to get entropy and returning this. To demonstrate platform specific usage, add a demo implementation for the FVP: It will execute the actual CPU instruction and just return the result. This should serve as reference code to implement platform specific policies. We change the definition of read_rndr() and read_rndrrs() to use the alternative sysreg encoding, so that all assemblers can handle that. Add documentation about the new platform specific RNG handler function. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Change-Id: Ibce817b3b06ad20129d15531b81402e3cc3e9a9e
62 lines
1.4 KiB
C
62 lines
1.4 KiB
C
/*
|
|
* Copyright (c) 2022, ARM Limited. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
* This file just contains demonstration code, to "handle" RNG traps.
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <arch.h>
|
|
#include <arch_helpers.h>
|
|
#include <bl31/sync_handle.h>
|
|
#include <context.h>
|
|
|
|
/*
|
|
* SCR_EL3.SCR_TRNDR_BIT also affects execution in EL3, so allow to disable
|
|
* the trap temporarily.
|
|
*/
|
|
static void enable_rng_trap(bool enable)
|
|
{
|
|
uint64_t scr_el3 = read_scr_el3();
|
|
|
|
if (enable) {
|
|
scr_el3 |= SCR_TRNDR_BIT;
|
|
} else {
|
|
scr_el3 &= ~SCR_TRNDR_BIT;
|
|
}
|
|
|
|
write_scr_el3(scr_el3);
|
|
isb();
|
|
}
|
|
|
|
/*
|
|
* This emulation code here is not very meaningful: enabling the RNG
|
|
* trap typically happens for a reason, so just calling the actual
|
|
* hardware instructions might not be useful or even possible.
|
|
*/
|
|
int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx)
|
|
{
|
|
/* 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 */
|
|
if (rt == 31 || is_sysreg_iss_write(esr_el3)) {
|
|
return TRAP_RET_CONTINUE;
|
|
}
|
|
|
|
enable_rng_trap(false);
|
|
if ((esr_el3 & ISS_SYSREG_OPCODE_MASK) == ISS_SYSREG_OPCODE_RNDR) {
|
|
ctx->gpregs_ctx.ctx_regs[rt] = read_rndr();
|
|
} else {
|
|
ctx->gpregs_ctx.ctx_regs[rt] = read_rndrrs();
|
|
}
|
|
enable_rng_trap(true);
|
|
|
|
/*
|
|
* We successfully handled the trap, continue with the next
|
|
* instruction.
|
|
*/
|
|
return TRAP_RET_CONTINUE;
|
|
}
|