xref: /rk3399_ARM-atf/drivers/arm/sfcp/sfcp_core/sfcp_random.c (revision 2801427972c4b0d4c0165edb509f21186103f21f)
1 /*
2  * Copyright (c) 2026, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdbool.h>
9 #include <string.h>
10 
11 #include "sfcp_random.h"
12 
13 struct xorshift_plus_128_state_t {
14 	uint64_t state[2];
15 };
16 
lfsr_seed(struct xorshift_plus_128_state_t * lfsr,uint8_t * seed,size_t seed_len)17 static inline void lfsr_seed(struct xorshift_plus_128_state_t *lfsr,
18 			     uint8_t *seed, size_t seed_len)
19 {
20 	if (seed_len < sizeof(lfsr->state)) {
21 		memcpy(lfsr->state, seed, seed_len);
22 	} else {
23 		memcpy(lfsr->state, seed, sizeof(lfsr->state));
24 	}
25 }
26 
27 /* See https://en.wikipedia.org/wiki/Xorshift#xorshift+ */
xorshift_plus_128_lfsr(struct xorshift_plus_128_state_t * lfsr,uint8_t * seed,size_t seed_len)28 static uint64_t xorshift_plus_128_lfsr(struct xorshift_plus_128_state_t *lfsr,
29 				       uint8_t *seed, size_t seed_len)
30 {
31 	uint64_t temp0, temp1;
32 
33 	lfsr_seed(lfsr, seed, seed_len);
34 
35 	temp0 = lfsr->state[0];
36 	temp1 = lfsr->state[1];
37 	lfsr->state[0] = lfsr->state[1];
38 
39 	temp0 ^= temp0 << 23;
40 	temp0 ^= temp0 >> 18;
41 	temp0 ^= temp1 ^ (temp1 >> 5);
42 
43 	lfsr->state[1] = temp0;
44 
45 	return temp0 + temp1;
46 }
47 
sfcp_random_generate_random_lfsr(uint8_t * seed,size_t seed_len)48 uint64_t sfcp_random_generate_random_lfsr(uint8_t *seed, size_t seed_len)
49 {
50 	struct xorshift_plus_128_state_t lfsr = { 0 };
51 
52 	return xorshift_plus_128_lfsr(&lfsr, seed, seed_len);
53 }
54