refactor(trng): cleanup the existing TRNG support

This patch adds the following changes to complete the existing
TRNG implementation:

1. Adds a feature specific scope for buildlog generation.
2. Updates the docs on the build flag "TRNG_SUPPORT" and its values.
3. Makefile update and improves the existing comments at few sections
for better understanding of the underlying logic.

Change-Id: I3f72f0ccd5c94005a2df87158cf23199d2160d37
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
This commit is contained in:
Jayanth Dodderi Chidanand 2022-10-11 17:16:07 +01:00
parent 6325f661c2
commit 0b22e59103
10 changed files with 54 additions and 43 deletions

View file

@ -1079,6 +1079,7 @@ $(eval $(call assert_booleans,\
ENABLE_MPMM_FCONF \ ENABLE_MPMM_FCONF \
SIMICS_BUILD \ SIMICS_BUILD \
FEATURE_DETECTION \ FEATURE_DETECTION \
TRNG_SUPPORT \
))) )))
$(eval $(call assert_numerics,\ $(eval $(call assert_numerics,\

View file

@ -595,6 +595,9 @@ subsections:
- title: DRTM - title: DRTM
scope: drtm scope: drtm
- title: TRNG
scope: trng
- title: Libraries - title: Libraries
subsections: subsections:

View file

@ -851,6 +851,9 @@ Common build options
hardware will limit the effective VL to the maximum physically supported hardware will limit the effective VL to the maximum physically supported
VL. VL.
- ``TRNG_SUPPORT``: Setting this to ``1`` enables support for True
Random Number Generator Interface to BL31 image. This defaults to ``0``.
- ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board - ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board
Boot feature. When set to '1', BL1 and BL2 images include support to load Boot feature. When set to '1', BL1 and BL2 images include support to load
and verify the certificates and images in a FIP, and BL1 includes support and verify the certificates and images in a FIP, and BL1 includes support

View file

@ -2468,7 +2468,7 @@ value: uuid_t plat_trng_uuid [mandatory]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This value must be defined to the UUID of the TRNG backend that is specific to This value must be defined to the UUID of the TRNG backend that is specific to
the hardware after ``plat_trng_setup`` function is called. This value must the hardware after ``plat_entropy_setup`` function is called. This value must
conform to the SMCCC calling convention; The most significant 32 bits of the conform to the SMCCC calling convention; The most significant 32 bits of the
UUID must not equal ``0xffffffff`` or the signed integer ``-1`` as this value in UUID must not equal ``0xffffffff`` or the signed integer ``-1`` as this value in
w0 indicates failure to get a TRNG source. w0 indicates failure to get a TRNG source.

View file

@ -16,10 +16,10 @@
#if ENABLE_RME #if ENABLE_RME
#include <services/rmm_core_manifest.h> #include <services/rmm_core_manifest.h>
#endif #endif
#include <drivers/fwu/fwu_metadata.h>
#if TRNG_SUPPORT #if TRNG_SUPPORT
#include "plat_trng.h" #include "plat_trng.h"
#endif #endif /* TRNG_SUPPORT */
#include <drivers/fwu/fwu_metadata.h>
#if DRTM_SUPPORT #if DRTM_SUPPORT
#include "plat_drtm.h" #include "plat_drtm.h"
#endif /* DRTM_SUPPORT */ #endif /* DRTM_SUPPORT */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, ARM Limited. All rights reserved. * Copyright (c) 2021-2022, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -17,7 +17,7 @@
#define ARM_TRNG_FEATURES U(0x84000051) #define ARM_TRNG_FEATURES U(0x84000051)
#define ARM_TRNG_GET_UUID U(0x84000052) #define ARM_TRNG_GET_UUID U(0x84000052)
#define ARM_TRNG_RND32 U(0x84000053) #define ARM_TRNG_RND32 U(0x84000053)
#define ARM_TRNG_RND64 U(0xc4000053) #define ARM_TRNG_RND64 U(0xC4000053)
/* TRNG version numbers */ /* TRNG version numbers */
#define TRNG_VERSION_MAJOR (0x1) #define TRNG_VERSION_MAJOR (0x1)
@ -30,19 +30,17 @@
#define TRNG_E_NO_ENTROPY (-3) #define TRNG_E_NO_ENTROPY (-3)
#define TRNG_E_NOT_IMPLEMENTED (-4) #define TRNG_E_NOT_IMPLEMENTED (-4)
#if TRNG_SUPPORT /* TRNG Entropy Bit Numbers */
void trng_setup(void); #define TRNG_RND32_ENTROPY_MAXBITS (96U)
bool is_trng_fid(uint32_t smc_fid); #define TRNG_RND64_ENTROPY_MAXBITS (192U)
#else
static inline void trng_setup(void)
{
}
static inline bool is_trng_fid(uint32_t smc_fid) /* Public API to perform the initial TRNG entropy setup */
{ void trng_setup(void);
return false;
} /* Public API to verify function id is part of TRNG */
#endif bool is_trng_fid(uint32_t smc_fid);
/* Handler to be called to handle TRNG smc calls */
uintptr_t trng_smc_handler( uintptr_t trng_smc_handler(
uint32_t smc_fid, uint32_t smc_fid,
u_register_t x1, u_register_t x1,

View file

@ -270,7 +270,7 @@ SAVE_KEYS := 0
# Software Delegated Exception support # Software Delegated Exception support
SDEI_SUPPORT := 0 SDEI_SUPPORT := 0
# True Random Number firmware Interface # True Random Number firmware Interface support
TRNG_SUPPORT := 0 TRNG_SUPPORT := 0
# SMCCC PCI support # SMCCC PCI support

View file

@ -74,7 +74,10 @@ static int32_t std_svc_setup(void)
sdei_init(); sdei_init();
#endif #endif
#if TRNG_SUPPORT
/* TRNG initialisation */
trng_setup(); trng_setup();
#endif /* TRNG_SUPPORT */
#if DRTM_SUPPORT #if DRTM_SUPPORT
if (drtm_setup() != 0) { if (drtm_setup() != 0) {
@ -172,7 +175,8 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
flags); flags);
} }
#endif #endif /* TRNG_SUPPORT */
#if ENABLE_RME #if ENABLE_RME
if (is_rmmd_el3_fid(smc_fid)) { if (is_rmmd_el3_fid(smc_fid)) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, ARM Limited. All rights reserved. * Copyright (c) 2021-2022, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -18,7 +18,7 @@
* 192 bits of entropy, we don't have to throw out the leftover 1-63 bits of * 192 bits of entropy, we don't have to throw out the leftover 1-63 bits of
* entropy. * entropy.
*/ */
#define WORDS_IN_POOL (4) #define WORDS_IN_POOL (4)
static uint64_t entropy[WORDS_IN_POOL]; static uint64_t entropy[WORDS_IN_POOL];
/* index in bits of the first bit of usable entropy */ /* index in bits of the first bit of usable entropy */
static uint32_t entropy_bit_index; static uint32_t entropy_bit_index;
@ -27,14 +27,14 @@ static uint32_t entropy_bit_size;
static spinlock_t trng_pool_lock; static spinlock_t trng_pool_lock;
#define BITS_PER_WORD (sizeof(entropy[0]) * 8) #define BITS_PER_WORD (sizeof(entropy[0]) * 8)
#define BITS_IN_POOL (WORDS_IN_POOL * BITS_PER_WORD) #define BITS_IN_POOL (WORDS_IN_POOL * BITS_PER_WORD)
#define ENTROPY_MIN_WORD (entropy_bit_index / BITS_PER_WORD) #define ENTROPY_MIN_WORD (entropy_bit_index / BITS_PER_WORD)
#define ENTROPY_FREE_BIT (entropy_bit_size + entropy_bit_index) #define ENTROPY_FREE_BIT (entropy_bit_size + entropy_bit_index)
#define _ENTROPY_FREE_WORD (ENTROPY_FREE_BIT / BITS_PER_WORD) #define _ENTROPY_FREE_WORD (ENTROPY_FREE_BIT / BITS_PER_WORD)
#define ENTROPY_FREE_INDEX (_ENTROPY_FREE_WORD % WORDS_IN_POOL) #define ENTROPY_FREE_INDEX (_ENTROPY_FREE_WORD % WORDS_IN_POOL)
/* ENTROPY_WORD_INDEX(0) includes leftover bits in the lower bits */ /* ENTROPY_WORD_INDEX(0) includes leftover bits in the lower bits */
#define ENTROPY_WORD_INDEX(i) ((ENTROPY_MIN_WORD + i) % WORDS_IN_POOL) #define ENTROPY_WORD_INDEX(i) ((ENTROPY_MIN_WORD + i) % WORDS_IN_POOL)
/* /*
* Fill the entropy pool until we have at least as many bits as requested. * Fill the entropy pool until we have at least as many bits as requested.
@ -65,12 +65,12 @@ static bool trng_fill_entropy(uint32_t nbits)
*/ */
bool trng_pack_entropy(uint32_t nbits, uint64_t *out) bool trng_pack_entropy(uint32_t nbits, uint64_t *out)
{ {
bool success = true; bool ret = true;
spin_lock(&trng_pool_lock); spin_lock(&trng_pool_lock);
if (!trng_fill_entropy(nbits)) { if (!trng_fill_entropy(nbits)) {
success = false; ret = false;
goto out; goto out;
} }
@ -82,9 +82,8 @@ bool trng_pack_entropy(uint32_t nbits, uint64_t *out)
for (word_i = 0; word_i < to_fill; word_i++) { for (word_i = 0; word_i < to_fill; word_i++) {
/* /*
* Repack the entropy from the pool into the passed in out * Repack the entropy from the pool into the passed in out
* buffer. This takes the lower bits from the valid upper bits * buffer. This takes lesser bits from the valid upper bits
* of word_i and the upper bits from the lower bits of * of word_i and more bits from the lower bits of (word_i + 1).
* (word_i + 1).
* *
* I found the following diagram useful. note: `e` represents * I found the following diagram useful. note: `e` represents
* valid entropy, ` ` represents invalid bits (not entropy) and * valid entropy, ` ` represents invalid bits (not entropy) and
@ -136,7 +135,7 @@ bool trng_pack_entropy(uint32_t nbits, uint64_t *out)
out: out:
spin_unlock(&trng_pool_lock); spin_unlock(&trng_pool_lock);
return success; return ret;
} }
void trng_entropy_pool_setup(void) void trng_entropy_pool_setup(void)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -23,9 +23,9 @@ static const uuid_t uuid_null;
static uintptr_t trng_rnd32(uint32_t nbits, void *handle) static uintptr_t trng_rnd32(uint32_t nbits, void *handle)
{ {
uint32_t mask = ~0U; uint32_t mask = ~0U;
uint64_t ent[2]; uint64_t ent[2] = {0};
if (nbits == 0U || nbits > 96U) { if (nbits == 0U || nbits > TRNG_RND32_ENTROPY_MAXBITS) {
SMC_RET1(handle, TRNG_E_INVALID_PARAMS); SMC_RET1(handle, TRNG_E_INVALID_PARAMS);
} }
@ -59,9 +59,9 @@ static uintptr_t trng_rnd32(uint32_t nbits, void *handle)
static uintptr_t trng_rnd64(uint32_t nbits, void *handle) static uintptr_t trng_rnd64(uint32_t nbits, void *handle)
{ {
uint64_t mask = ~0ULL; uint64_t mask = ~0ULL;
uint64_t ent[3]; uint64_t ent[3] = {0};
if (nbits == 0U || nbits > 192U) { if (nbits == 0U || nbits > TRNG_RND64_ENTROPY_MAXBITS) {
SMC_RET1(handle, TRNG_E_INVALID_PARAMS); SMC_RET1(handle, TRNG_E_INVALID_PARAMS);
} }
@ -117,9 +117,9 @@ uintptr_t trng_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
switch (smc_fid) { switch (smc_fid) {
case ARM_TRNG_VERSION: case ARM_TRNG_VERSION:
SMC_RET1(handle, MAKE_SMCCC_VERSION( SMC_RET1(handle, MAKE_SMCCC_VERSION(
TRNG_VERSION_MAJOR, TRNG_VERSION_MINOR TRNG_VERSION_MAJOR, TRNG_VERSION_MINOR));
));
break; /* unreachable */ break; /* unreachable */
case ARM_TRNG_FEATURES: case ARM_TRNG_FEATURES:
if (is_trng_fid((uint32_t)x1)) { if (is_trng_fid((uint32_t)x1)) {
SMC_RET1(handle, TRNG_E_SUCCESS); SMC_RET1(handle, TRNG_E_SUCCESS);
@ -127,16 +127,19 @@ uintptr_t trng_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
SMC_RET1(handle, TRNG_E_NOT_SUPPORTED); SMC_RET1(handle, TRNG_E_NOT_SUPPORTED);
} }
break; /* unreachable */ break; /* unreachable */
case ARM_TRNG_GET_UUID: case ARM_TRNG_GET_UUID:
SMC_UUID_RET(handle, plat_trng_uuid); SMC_UUID_RET(handle, plat_trng_uuid);
break; /* unreachable */ break; /* unreachable */
case ARM_TRNG_RND32: case ARM_TRNG_RND32:
return trng_rnd32((uint32_t)x1, handle); return trng_rnd32((uint32_t)x1, handle);
case ARM_TRNG_RND64: case ARM_TRNG_RND64:
return trng_rnd64((uint32_t)x1, handle); return trng_rnd64((uint32_t)x1, handle);
default: default:
WARN("Unimplemented TRNG Service Call: 0x%x\n", WARN("Unimplemented TRNG Service Call: 0x%x\n", smc_fid);
smc_fid);
SMC_RET1(handle, TRNG_E_NOT_IMPLEMENTED); SMC_RET1(handle, TRNG_E_NOT_IMPLEMENTED);
break; /* unreachable */ break; /* unreachable */
} }