1501ef24eSVolodymyr Babchuk // SPDX-License-Identifier: BSD-2-Clause 2501ef24eSVolodymyr Babchuk /* Copyright (c) 2021, EPAM Systems. All rights reserved. */ 3501ef24eSVolodymyr Babchuk 4501ef24eSVolodymyr Babchuk #include <assert.h> 5501ef24eSVolodymyr Babchuk #include <kernel/panic.h> 6501ef24eSVolodymyr Babchuk #include <kernel/spinlock.h> 7501ef24eSVolodymyr Babchuk #include <platform_config.h> 8501ef24eSVolodymyr Babchuk #include <rng_support.h> 9501ef24eSVolodymyr Babchuk #include <trace.h> 10501ef24eSVolodymyr Babchuk 11501ef24eSVolodymyr Babchuk #include "romapi.h" 12501ef24eSVolodymyr Babchuk 13501ef24eSVolodymyr Babchuk #define SCRATCH_BUF_SZ 4096 14501ef24eSVolodymyr Babchuk 15501ef24eSVolodymyr Babchuk static uint8_t scratch_buf[SCRATCH_BUF_SZ] __nex_bss 16501ef24eSVolodymyr Babchuk __aligned(RCAR_CACHE_LINE_SZ); 17501ef24eSVolodymyr Babchuk static unsigned int spin_lock __nex_data = SPINLOCK_UNLOCK; 18501ef24eSVolodymyr Babchuk 19501ef24eSVolodymyr Babchuk /* 20501ef24eSVolodymyr Babchuk * It is inefficient to call ROM_GetRndVector() every time we want 8 bits of 21501ef24eSVolodymyr Babchuk * random data, so we will cache the unused values for latter use. 22501ef24eSVolodymyr Babchuk */ 23501ef24eSVolodymyr Babchuk static uint8_t rng_cache[PLAT_RND_VECTOR_SZ] __nex_bss 24501ef24eSVolodymyr Babchuk __aligned(RCAR_CACHE_LINE_SZ); 25*e9c080a6SAndrew Davis static uint8_t rng_cache_pos __nex_data; 26501ef24eSVolodymyr Babchuk hw_get_random_bytes(void * buf,size_t len)27*e9c080a6SAndrew DavisTEE_Result hw_get_random_bytes(void *buf, size_t len) 28501ef24eSVolodymyr Babchuk { 29*e9c080a6SAndrew Davis uint32_t exceptions; 30*e9c080a6SAndrew Davis uint8_t *buffer = buf; 31*e9c080a6SAndrew Davis size_t buffer_pos = 0; 32501ef24eSVolodymyr Babchuk uint8_t ret_val = 0; 33501ef24eSVolodymyr Babchuk 34*e9c080a6SAndrew Davis assert(rng_cache_pos < PLAT_RND_VECTOR_SZ); 35501ef24eSVolodymyr Babchuk 36*e9c080a6SAndrew Davis while (buffer_pos < len) { 37*e9c080a6SAndrew Davis exceptions = cpu_spin_lock_xsave(&spin_lock); 38*e9c080a6SAndrew Davis /* Refill our FIFO */ 39*e9c080a6SAndrew Davis if (rng_cache_pos == 0) { 40*e9c080a6SAndrew Davis uint32_t ret = plat_rom_getrndvector(rng_cache, 41*e9c080a6SAndrew Davis scratch_buf, 42501ef24eSVolodymyr Babchuk sizeof(scratch_buf)); 43501ef24eSVolodymyr Babchuk if (ret != 0) 44501ef24eSVolodymyr Babchuk panic("ROM_GetRndVector() returned error!"); 45501ef24eSVolodymyr Babchuk } 46501ef24eSVolodymyr Babchuk 47*e9c080a6SAndrew Davis buffer[buffer_pos++] = rng_cache[rng_cache_pos++]; 48*e9c080a6SAndrew Davis if (rng_cache_pos == PLAT_RND_VECTOR_SZ) 49*e9c080a6SAndrew Davis rng_cache_pos = 0; 50*e9c080a6SAndrew Davis 51501ef24eSVolodymyr Babchuk cpu_spin_unlock_xrestore(&spin_lock, exceptions); 52*e9c080a6SAndrew Davis } 53501ef24eSVolodymyr Babchuk 54501ef24eSVolodymyr Babchuk return ret_val; 55501ef24eSVolodymyr Babchuk } 56