xref: /optee_os/core/arch/arm/plat-rcar/hw_rng.c (revision ad0ae8003583f7270d62568c85a32a5f25a601c6)
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 = PLAT_RND_VECTOR_SZ;
26 
27 uint8_t hw_get_random_byte(void)
28 {
29 	uint32_t exceptions = cpu_spin_lock_xsave(&spin_lock);
30 	uint8_t ret_val = 0;
31 
32 	assert(rng_cache_pos <= PLAT_RND_VECTOR_SZ);
33 
34 	if (rng_cache_pos == PLAT_RND_VECTOR_SZ) {
35 		uint32_t ret = plat_rom_getrndvector(rng_cache, scratch_buf,
36 						     sizeof(scratch_buf));
37 
38 		if (ret != 0)
39 			panic("ROM_GetRndVector() returned error!");
40 
41 		rng_cache_pos = 0;
42 	}
43 
44 	ret_val = rng_cache[rng_cache_pos++];
45 	cpu_spin_unlock_xrestore(&spin_lock, exceptions);
46 
47 	return ret_val;
48 }
49