1 // SPDX-License-Identifier: BSD-2-Clause 2 /* Copyright (c) 2021, EPAM Systems. All rights reserved. */ 3 4 #include <assert.h> 5 #include <kernel/panic.h> 6 #include <kernel/spinlock.h> 7 #include <platform_config.h> 8 #include <rng_support.h> 9 #include <trace.h> 10 11 #include "romapi.h" 12 13 #define SCRATCH_BUF_SZ 4096 14 15 static uint8_t scratch_buf[SCRATCH_BUF_SZ] __nex_bss 16 __aligned(RCAR_CACHE_LINE_SZ); 17 static unsigned int spin_lock __nex_data = SPINLOCK_UNLOCK; 18 19 /* 20 * It is inefficient to call ROM_GetRndVector() every time we want 8 bits of 21 * random data, so we will cache the unused values for latter use. 22 */ 23 static uint8_t rng_cache[PLAT_RND_VECTOR_SZ] __nex_bss 24 __aligned(RCAR_CACHE_LINE_SZ); 25 static uint8_t rng_cache_pos __nex_data; 26 hw_get_random_bytes(void * buf,size_t len)27TEE_Result hw_get_random_bytes(void *buf, size_t len) 28 { 29 uint32_t exceptions; 30 uint8_t *buffer = buf; 31 size_t buffer_pos = 0; 32 uint8_t ret_val = 0; 33 34 assert(rng_cache_pos < PLAT_RND_VECTOR_SZ); 35 36 while (buffer_pos < len) { 37 exceptions = cpu_spin_lock_xsave(&spin_lock); 38 /* Refill our FIFO */ 39 if (rng_cache_pos == 0) { 40 uint32_t ret = plat_rom_getrndvector(rng_cache, 41 scratch_buf, 42 sizeof(scratch_buf)); 43 if (ret != 0) 44 panic("ROM_GetRndVector() returned error!"); 45 } 46 47 buffer[buffer_pos++] = rng_cache[rng_cache_pos++]; 48 if (rng_cache_pos == PLAT_RND_VECTOR_SZ) 49 rng_cache_pos = 0; 50 51 cpu_spin_unlock_xrestore(&spin_lock, exceptions); 52 } 53 54 return ret_val; 55 } 56