diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/std_svc/drtm/drtm_main.c | 7 | ||||
-rw-r--r-- | services/std_svc/drtm/drtm_main.h | 6 | ||||
-rw-r--r-- | services/std_svc/rmmd/trp/trp_entry.S | 34 | ||||
-rw-r--r-- | services/std_svc/rmmd/trp/trp_main.c | 94 | ||||
-rw-r--r-- | services/std_svc/rmmd/trp/trp_private.h | 4 | ||||
-rw-r--r-- | services/std_svc/spm/el3_spmc/spmc.mk | 2 | ||||
-rw-r--r-- | services/std_svc/spm/el3_spmc/spmc_shared_mem.c | 74 | ||||
-rw-r--r-- | services/std_svc/std_svc_setup.c | 6 | ||||
-rw-r--r-- | services/std_svc/trng/trng_entropy_pool.c | 29 | ||||
-rw-r--r-- | services/std_svc/trng/trng_main.c | 21 |
10 files changed, 199 insertions, 78 deletions
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c index e0f5c1784..3acf6838e 100644 --- a/services/std_svc/drtm/drtm_main.c +++ b/services/std_svc/drtm/drtm_main.c @@ -366,9 +366,10 @@ static enum drtm_retc drtm_dl_check_args(uint64_t x1, } a = &args_buf; - if (a->version != 1) { - ERROR("DRTM: parameters structure incompatible with major version %d\n", - ARM_DRTM_VERSION_MAJOR); + if (!((a->version >= ARM_DRTM_PARAMS_MIN_VERSION) && + (a->version <= ARM_DRTM_PARAMS_MAX_VERSION))) { + ERROR("DRTM: parameters structure version %u is unsupported\n", + a->version); return NOT_SUPPORTED; } diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h index baa37ae7d..60051632e 100644 --- a/services/std_svc/drtm/drtm_main.h +++ b/services/std_svc/drtm/drtm_main.h @@ -36,6 +36,12 @@ #define DL_ARGS_GET_DLME_ENTRY_POINT(a) \ (((a)->dlme_paddr + (a)->dlme_img_off + (a)->dlme_img_ep_off)) +/* + * Range(Min/Max) of DRTM parameter structure versions supported + */ +#define ARM_DRTM_PARAMS_MIN_VERSION U(1) +#define ARM_DRTM_PARAMS_MAX_VERSION U(1) + enum drtm_dlme_el { DLME_AT_EL1 = MODE_EL1, DLME_AT_EL2 = MODE_EL2 diff --git a/services/std_svc/rmmd/trp/trp_entry.S b/services/std_svc/rmmd/trp/trp_entry.S index 47c1df14d..3e1d8c9d4 100644 --- a/services/std_svc/rmmd/trp/trp_entry.S +++ b/services/std_svc/rmmd/trp/trp_entry.S @@ -83,7 +83,17 @@ trp_head: mov x3, x23 bl trp_setup bl trp_main + b 1f + warm_boot: + mov x0, x20 + mov x1, x21 + mov x2, x22 + mov x3, x23 + bl trp_validate_warmboot_args + cbnz x0, trp_panic /* Failed to validate warmboot args */ + +1: mov_imm x0, RMM_BOOT_COMPLETE mov x1, xzr /* RMM_BOOT_SUCCESS */ smc #0 @@ -115,7 +125,29 @@ endfunc trp_smc * --------------------------------------------- */ func trp_handler + /* + * Save Link Register and X4, as per SMCCC v1.2 its value + * must be preserved unless it contains result, as specified + * in the function definition. + */ + stp x4, lr, [sp, #-16]! + + /* + * Zero the space for X0-X3 in trp_smc_result structure + * and pass its address as the last argument. + */ + stp xzr, xzr, [sp, #-16]! + stp xzr, xzr, [sp, #-16]! + mov x7, sp + bl trp_rmi_handler - restore_args_call_smc + + ldp x1, x2, [sp], #16 + ldp x3, x4, [sp], #16 + ldp x5, lr, [sp], #16 + + ldr x0, =RMM_RMI_REQ_COMPLETE + smc #0 + b trp_handler endfunc trp_handler diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c index 5a56af043..196bc119e 100644 --- a/services/std_svc/rmmd/trp/trp_main.c +++ b/services/std_svc/rmmd/trp/trp_main.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ - #include <common/debug.h> #include <plat/common/platform.h> #include <services/rmm_core_manifest.h> @@ -31,11 +30,11 @@ void trp_setup(uint64_t x0, uint64_t x3) { /* - * Validate boot parameters. + * Validate boot parameters * - * According to the Boot Interface ABI v.0.1, the - * parameters recived from EL3 are: - * x0: CPUID (verified earlier so not used) + * According to the Boot Interface ABI v.0.1, + * the parameters received from EL3 are: + * x0: CPUID (verified earlier, so not used) * x1: Boot Interface version * x2: PLATFORM_CORE_COUNT * x3: Pointer to the shared memory area. @@ -66,6 +65,24 @@ void trp_setup(uint64_t x0, trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start); } +int trp_validate_warmboot_args(uint64_t x0, uint64_t x1, + uint64_t x2, uint64_t x3) +{ + /* + * Validate boot parameters for warm boot + * + * According to the Boot Interface ABI v.0.1, the parameters + * received from EL3 during warm boot are: + * + * x0: CPUID (verified earlier so not used here) + * [x1:x3]: RES0 + */ + + (void)x0; + + return ((x1 | x2 | x3) == 0UL) ? 0 : E_RMM_BOOT_UNKNOWN; +} + /* Main function for TRP */ void trp_main(void) { @@ -73,14 +90,14 @@ void trp_main(void) NOTICE("TRP: %s\n", build_message); NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n", TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR); - NOTICE("TRP: Boot Manifest Version : v.%u.%u\n", + NOTICE("TRP: Boot Manifest Version: v.%u.%u\n", RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version), RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version)); - INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE); - INFO("TRP: Base address for the shared region : 0x%lx\n", + INFO("TRP: Memory base: 0x%lx\n", (unsigned long)RMM_BASE); + INFO("TRP: Shared region base address: 0x%lx\n", (unsigned long)trp_shared_region_start); - INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END - - RMM_BASE)); + INFO("TRP: Total size: 0x%lx bytes\n", + (unsigned long)(RMM_END - RMM_BASE)); INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n", TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version), TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version)); @@ -89,62 +106,73 @@ void trp_main(void) /******************************************************************************* * Returning RMI version back to Normal World ******************************************************************************/ -static trp_args_t *trp_ret_rmi_version(void) +static void trp_ret_rmi_version(struct trp_smc_result *smc_ret) { VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR, RMI_ABI_VERSION_MINOR); - return set_smc_args(RMM_RMI_REQ_COMPLETE, RMI_ABI_VERSION, - 0, 0, 0, 0, 0, 0); + smc_ret->x[0] = RMI_ABI_VERSION; } /******************************************************************************* * Transitioning granule of NON-SECURE type to REALM type ******************************************************************************/ -static trp_args_t *trp_asc_mark_realm(unsigned long long x1) +static void trp_asc_mark_realm(unsigned long long x1, + struct trp_smc_result *smc_ret) { - unsigned long long ret; - VERBOSE("Delegating granule 0x%llx\n", x1); - ret = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0)); + smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1, + 0UL, 0UL, 0UL, 0UL, 0UL, 0UL)); - if (ret != 0ULL) { + if (smc_ret->x[0] != 0ULL) { ERROR("Granule transition from NON-SECURE type to REALM type " - "failed 0x%llx\n", ret); + "failed 0x%llx\n", smc_ret->x[0]); } - return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); } /******************************************************************************* * Transitioning granule of REALM type to NON-SECURE type ******************************************************************************/ -static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1) +static void trp_asc_mark_nonsecure(unsigned long long x1, + struct trp_smc_result *smc_ret) { - unsigned long long ret; - VERBOSE("Undelegating granule 0x%llx\n", x1); - ret = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0)); + smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1, + 0UL, 0UL, 0UL, 0UL, 0UL, 0UL)); - if (ret != 0ULL) { + if (smc_ret->x[0] != 0ULL) { ERROR("Granule transition from REALM type to NON-SECURE type " - "failed 0x%llx\n", ret); + "failed 0x%llx\n", smc_ret->x[0]); } - return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); } /******************************************************************************* * Main RMI SMC handler function ******************************************************************************/ -trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1) +void trp_rmi_handler(unsigned long fid, + unsigned long long x1, unsigned long long x2, + unsigned long long x3, unsigned long long x4, + unsigned long long x5, unsigned long long x6, + struct trp_smc_result *smc_ret) { + /* Not used in the current implementation */ + (void)x2; + (void)x3; + (void)x4; + (void)x5; + (void)x6; + switch (fid) { case RMI_RMM_REQ_VERSION: - return trp_ret_rmi_version(); + trp_ret_rmi_version(smc_ret); + break; case RMI_RMM_GRANULE_DELEGATE: - return trp_asc_mark_realm(x1); + trp_asc_mark_realm(x1, smc_ret); + break; case RMI_RMM_GRANULE_UNDELEGATE: - return trp_asc_mark_nonsecure(x1); + trp_asc_mark_nonsecure(x1, smc_ret); + break; default: - ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid); + ERROR("Invalid SMC code to %s, FID %lx\n", __func__, fid); + smc_ret->x[0] = SMC_UNK; } - return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0); } diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h index 945ae1c89..d8c69603b 100644 --- a/services/std_svc/rmmd/trp/trp_private.h +++ b/services/std_svc/rmmd/trp/trp_private.h @@ -53,5 +53,9 @@ void trp_setup(uint64_t x0, uint64_t x2, uint64_t x3); +/* Validate arguments for warm boot only */ +int trp_validate_warmboot_args(uint64_t x0, uint64_t x1, + uint64_t x2, uint64_t x3); + #endif /* __ASSEMBLER__ */ #endif /* TRP_PRIVATE_H */ diff --git a/services/std_svc/spm/el3_spmc/spmc.mk b/services/std_svc/spm/el3_spmc/spmc.mk index c674e7161..6442af049 100644 --- a/services/std_svc/spm/el3_spmc/spmc.mk +++ b/services/std_svc/spm/el3_spmc/spmc.mk @@ -20,7 +20,9 @@ SPMC_LP_SOURCES := $(addprefix ${PLAT_DIR}/, \ ${PLAT}_el3_spmc_logical_sp.c) +ifneq ($(wildcard $(SPMC_LP_SOURCES)),) SPMC_SOURCES += $(SPMC_LP_SOURCES) +endif # Let the top-level Makefile know that we intend to include a BL32 image NEED_BL32 := yes diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c index 1da2efc14..c039350a3 100644 --- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c +++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c @@ -72,13 +72,23 @@ spmc_shmem_obj_alloc(struct spmc_shmem_obj_state *state, size_t desc_size) { struct spmc_shmem_obj *obj; size_t free = state->data_size - state->allocated; + size_t obj_size; if (state->data == NULL) { ERROR("Missing shmem datastore!\n"); return NULL; } - if (spmc_shmem_obj_size(desc_size) > free) { + obj_size = spmc_shmem_obj_size(desc_size); + + /* Ensure the obj size has not overflowed. */ + if (obj_size < desc_size) { + WARN("%s(0x%zx) desc_size overflow\n", + __func__, desc_size); + return NULL; + } + + if (obj_size > free) { WARN("%s(0x%zx) failed, free 0x%zx\n", __func__, desc_size, free); return NULL; @@ -88,7 +98,7 @@ spmc_shmem_obj_alloc(struct spmc_shmem_obj_state *state, size_t desc_size) obj->desc_size = desc_size; obj->desc_filled = 0; obj->in_use = 0; - state->allocated += spmc_shmem_obj_size(desc_size); + state->allocated += obj_size; return obj; } @@ -264,13 +274,15 @@ spmc_shmem_obj_ffa_constituent_size(struct spmc_shmem_obj *obj, * spmc_shmem_obj_validate_id - Validate a partition ID is participating in * a given memory transaction. * @sp_id: Partition ID to validate. - * @desc: Descriptor of the memory transaction. - * + * @obj: The shared memory object containing the descriptor + * of the memory transaction. * Return: true if ID is valid, else false. */ -bool spmc_shmem_obj_validate_id(const struct ffa_mtd *desc, uint16_t sp_id) +bool spmc_shmem_obj_validate_id(struct spmc_shmem_obj *obj, uint16_t sp_id) { bool found = false; + struct ffa_mtd *desc = &obj->desc; + size_t desc_size = obj->desc_size; /* Validate the partition is a valid participant. */ for (unsigned int i = 0U; i < desc->emad_count; i++) { @@ -280,6 +292,15 @@ bool spmc_shmem_obj_validate_id(const struct ffa_mtd *desc, uint16_t sp_id) emad = spmc_shmem_obj_get_emad(desc, i, MAKE_FFA_VERSION(1, 1), &emad_size); + /* + * Validate the calculated emad address resides within the + * descriptor. + */ + if ((emad == NULL) || (uintptr_t) emad >= + (uintptr_t)((uint8_t *) desc + desc_size)) { + VERBOSE("Invalid emad.\n"); + break; + } if (sp_id == emad->mapd.endpoint_id) { found = true; break; @@ -330,10 +351,9 @@ overlapping_memory_regions(struct ffa_comp_mrd *region1, PAGE_SIZE_4KB; region2_end = region2_start + region2_size; - if ((region1_start >= region2_start && - region1_start < region2_end) || - (region1_end > region2_start - && region1_end < region2_end)) { + /* Check if regions are not overlapping. */ + if (!((region2_end <= region1_start) || + (region1_end <= region2_start))) { WARN("Overlapping mem regions 0x%lx-0x%lx & 0x%lx-0x%lx\n", region1_start, region1_end, region2_start, region2_end); @@ -376,7 +396,8 @@ spmc_shm_get_v1_1_descriptor_size(struct ffa_mtd_v1_0 *orig, size_t desc_size) emad_array[0].comp_mrd_offset); /* Check the calculated address is within the memory descriptor. */ - if ((uintptr_t) mrd >= (uintptr_t)((uint8_t *) orig + desc_size)) { + if (((uintptr_t) mrd + sizeof(struct ffa_comp_mrd)) > + (uintptr_t)((uint8_t *) orig + desc_size)) { return 0; } size += mrd->address_range_count * sizeof(struct ffa_cons_mrd); @@ -415,7 +436,8 @@ spmc_shm_get_v1_0_descriptor_size(struct ffa_mtd *orig, size_t desc_size) emad_array[0].comp_mrd_offset); /* Check the calculated address is within the memory descriptor. */ - if ((uintptr_t) mrd >= (uintptr_t)((uint8_t *) orig + desc_size)) { + if (((uintptr_t) mrd + sizeof(struct ffa_comp_mrd)) > + (uintptr_t)((uint8_t *) orig + desc_size)) { return 0; } size += mrd->address_range_count * sizeof(struct ffa_cons_mrd); @@ -466,6 +488,12 @@ spmc_shm_convert_shmem_obj_from_v1_0(struct spmc_shmem_obj *out_obj, /* Copy across the emad structs. */ for (unsigned int i = 0U; i < out->emad_count; i++) { + /* Bound check for emad array. */ + if (((uint8_t *)emad_array_in + sizeof(struct ffa_emad_v1_0)) > + ((uint8_t *) mtd_orig + orig->desc_size)) { + VERBOSE("%s: Invalid mtd structure.\n", __func__); + return false; + } memcpy(&emad_array_out[i], &emad_array_in[i], sizeof(struct ffa_emad_v1_0)); } @@ -533,6 +561,7 @@ spmc_shm_convert_mtd_to_v1_0(struct spmc_shmem_obj *out_obj, size_t mrd_out_offset; size_t emad_out_array_size; size_t mrd_size = 0; + size_t orig_desc_size = orig->desc_size; /* Populate the v1.0 descriptor format from the v1.1 struct. */ out->sender_id = mtd_orig->sender_id; @@ -550,6 +579,12 @@ spmc_shm_convert_mtd_to_v1_0(struct spmc_shmem_obj *out_obj, /* Copy across the emad structs. */ emad_in = emad_array_in; for (unsigned int i = 0U; i < out->emad_count; i++) { + /* Bound check for emad array. */ + if (((uint8_t *)emad_in + sizeof(struct ffa_emad_v1_0)) > + ((uint8_t *) mtd_orig + orig_desc_size)) { + VERBOSE("%s: Invalid mtd structure.\n", __func__); + return false; + } memcpy(&emad_array_out[i], emad_in, sizeof(struct ffa_emad_v1_0)); @@ -886,9 +921,6 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox, goto err_arg; } - memcpy((uint8_t *)&obj->desc + obj->desc_filled, - (uint8_t *) mbox->tx_buffer, fragment_length); - if (fragment_length > obj->desc_size - obj->desc_filled) { WARN("%s: bad fragment size %u > %zu remaining\n", __func__, fragment_length, obj->desc_size - obj->desc_filled); @@ -896,6 +928,9 @@ static long spmc_ffa_fill_desc(struct mailbox *mbox, goto err_arg; } + memcpy((uint8_t *)&obj->desc + obj->desc_filled, + (uint8_t *) mbox->tx_buffer, fragment_length); + /* Ensure that the sender ID resides in the normal world. */ if (ffa_is_secure_world_id(obj->desc.sender_id)) { WARN("%s: Invalid sender ID 0x%x.\n", @@ -1433,7 +1468,7 @@ spmc_ffa_mem_retrieve_req(uint32_t smc_fid, } /* Validate the caller is a valid participant. */ - if (!spmc_shmem_obj_validate_id(&obj->desc, sp_ctx->sp_id)) { + if (!spmc_shmem_obj_validate_id(obj, sp_ctx->sp_id)) { WARN("%s: Invalid endpoint ID (0x%x).\n", __func__, sp_ctx->sp_id); ret = FFA_ERROR_INVALID_PARAMETER; @@ -1752,7 +1787,7 @@ int spmc_ffa_mem_relinquish(uint32_t smc_fid, } /* Validate the caller is a valid participant. */ - if (!spmc_shmem_obj_validate_id(&obj->desc, sp_ctx->sp_id)) { + if (!spmc_shmem_obj_validate_id(obj, sp_ctx->sp_id)) { WARN("%s: Invalid endpoint ID (0x%x).\n", __func__, req->endpoint_array[0]); ret = FFA_ERROR_INVALID_PARAMETER; @@ -1828,6 +1863,13 @@ int spmc_ffa_mem_reclaim(uint32_t smc_fid, goto err_unlock; } + if (obj->desc_filled != obj->desc_size) { + WARN("%s: incomplete object desc filled %zu < size %zu\n", + __func__, obj->desc_filled, obj->desc_size); + ret = FFA_ERROR_INVALID_PARAMETER; + goto err_unlock; + } + /* Allow for platform specific operations to be performed. */ ret = plat_spmc_shmem_reclaim(&obj->desc); if (ret != 0) { diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c index 08d16e21a..2884a3b9e 100644 --- a/services/std_svc/std_svc_setup.c +++ b/services/std_svc/std_svc_setup.c @@ -74,7 +74,10 @@ static int32_t std_svc_setup(void) sdei_init(); #endif +#if TRNG_SUPPORT + /* TRNG initialisation */ trng_setup(); +#endif /* TRNG_SUPPORT */ #if DRTM_SUPPORT 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, flags); } -#endif +#endif /* TRNG_SUPPORT */ + #if ENABLE_RME if (is_rmmd_el3_fid(smc_fid)) { diff --git a/services/std_svc/trng/trng_entropy_pool.c b/services/std_svc/trng/trng_entropy_pool.c index ac13b1d7a..30105b3a3 100644 --- a/services/std_svc/trng/trng_entropy_pool.c +++ b/services/std_svc/trng/trng_entropy_pool.c @@ -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 */ @@ -18,7 +18,7 @@ * 192 bits of entropy, we don't have to throw out the leftover 1-63 bits of * entropy. */ -#define WORDS_IN_POOL (4) +#define WORDS_IN_POOL (4) static uint64_t entropy[WORDS_IN_POOL]; /* index in bits of the first bit of usable entropy */ static uint32_t entropy_bit_index; @@ -27,14 +27,14 @@ static uint32_t entropy_bit_size; static spinlock_t trng_pool_lock; -#define BITS_PER_WORD (sizeof(entropy[0]) * 8) -#define BITS_IN_POOL (WORDS_IN_POOL * 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_WORD (ENTROPY_FREE_BIT / BITS_PER_WORD) -#define ENTROPY_FREE_INDEX (_ENTROPY_FREE_WORD % WORDS_IN_POOL) +#define BITS_PER_WORD (sizeof(entropy[0]) * 8) +#define BITS_IN_POOL (WORDS_IN_POOL * 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_WORD (ENTROPY_FREE_BIT / BITS_PER_WORD) +#define ENTROPY_FREE_INDEX (_ENTROPY_FREE_WORD % WORDS_IN_POOL) /* 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. @@ -65,12 +65,12 @@ static bool trng_fill_entropy(uint32_t nbits) */ bool trng_pack_entropy(uint32_t nbits, uint64_t *out) { - bool success = true; + bool ret = true; spin_lock(&trng_pool_lock); if (!trng_fill_entropy(nbits)) { - success = false; + ret = false; 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++) { /* * Repack the entropy from the pool into the passed in out - * buffer. This takes the lower bits from the valid upper bits - * of word_i and the upper bits from the lower bits of - * (word_i + 1). + * buffer. This takes lesser bits from the valid upper bits + * of word_i and more bits from the lower bits of (word_i + 1). * * I found the following diagram useful. note: `e` represents * valid entropy, ` ` represents invalid bits (not entropy) and @@ -136,7 +135,7 @@ bool trng_pack_entropy(uint32_t nbits, uint64_t *out) out: spin_unlock(&trng_pool_lock); - return success; + return ret; } void trng_entropy_pool_setup(void) diff --git a/services/std_svc/trng/trng_main.c b/services/std_svc/trng/trng_main.c index 38aa64997..90098a8f2 100644 --- a/services/std_svc/trng/trng_main.c +++ b/services/std_svc/trng/trng_main.c @@ -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 */ @@ -23,9 +23,9 @@ static const uuid_t uuid_null; static uintptr_t trng_rnd32(uint32_t nbits, void *handle) { 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); } @@ -59,9 +59,9 @@ static uintptr_t trng_rnd32(uint32_t nbits, void *handle) static uintptr_t trng_rnd64(uint32_t nbits, void *handle) { 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); } @@ -117,9 +117,9 @@ uintptr_t trng_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, switch (smc_fid) { case ARM_TRNG_VERSION: SMC_RET1(handle, MAKE_SMCCC_VERSION( - TRNG_VERSION_MAJOR, TRNG_VERSION_MINOR - )); + TRNG_VERSION_MAJOR, TRNG_VERSION_MINOR)); break; /* unreachable */ + case ARM_TRNG_FEATURES: if (is_trng_fid((uint32_t)x1)) { 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); } break; /* unreachable */ + case ARM_TRNG_GET_UUID: SMC_UUID_RET(handle, plat_trng_uuid); break; /* unreachable */ + case ARM_TRNG_RND32: return trng_rnd32((uint32_t)x1, handle); + case ARM_TRNG_RND64: return trng_rnd64((uint32_t)x1, handle); + default: - WARN("Unimplemented TRNG Service Call: 0x%x\n", - smc_fid); + WARN("Unimplemented TRNG Service Call: 0x%x\n", smc_fid); SMC_RET1(handle, TRNG_E_NOT_IMPLEMENTED); break; /* unreachable */ } |