xref: /optee_os/core/drivers/versal_trng.c (revision 9194d279f018f1905a562d026cb2a7d7cd79b9a6)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright (C) 2022 Xilinx, Inc.  All rights reserved.
4  * Copyright (C) 2022 Foundries Ltd.
5  *
6  * Driver port from Xilinx's FSBL implementation, jorge@foundries.io
7  *
8  * The Xilinx True Random Number Generator(TRNG) module in Versal - PMC TRNG
9  * consists of an entropy source, a deterministic random bit generator (DRBG)
10  * and health test logic, which tests the randomness of the generated data.
11  * The entropy source for the unit is an array of Ring Oscillators.
12  *
13  * The Versal PMC TRNG is envisaged to operate in three basic modes: DRNG, PTRNG
14  * and HRNG . Each of these can be operated with or without Derivative Function
15  * (DF), resulting in a total of 6 different modes of operation.
16  *
17  * NIST SP-800-90A practically requires the true random generators based on
18  * CTR_DRBG to include a derivation function (DF). This is expected to be
19  * implemented inside the Silicon (TRNG IP). However, the version of the IP used
20  * in Versal PMC does not have this capability. Hence, a software
21  * implementation of the DF is done in this driver.
22  *
23  * DRNG mode: Deterministic Random Number Generator mode.
24  *            In this mode, the DRBG portion of the TRNG is used. User provides
25  *            the (external) seed.
26  * PTRNG mode: Physical True Random Number Generator mode (aka Entropy mode).
27  *            In this mode digitized Entropy source is output as random number.
28  * HRNG mode: Hybrid Random Number Generator mode.
29  *            This is combination of above two modes in which the Entropy source
30  *            is used to provide the seed, which is fed to the DRBG, which in
31  *            turn generates the random number.
32  *
33  * DRNG mode with DF: It may not be common usecase to use the DF with DRNG as
34  * the general expectation would be that the seed would have sufficient entropy.
35  * However, the below guideline from section 10.2.1 of NIST SP-800-90A implies
36  * that need for DF for DRNG mode too: "..the DRBG mechanism is specified to
37  * allow an implementation tradeoff with respect to the use of this derivation
38  * function. The use of the derivation function is optional if either an
39  * approved RBG or an entropy source provides full entropy output when entropy
40  * input is requested by the DRBG mechanism. Otherwise, the derivation function
41  * shall be used". Sufficient large entropy data from user is fed to DF to
42  * generate the seed which will be loaded into the external seed registers.
43  * From here, it is similar to regular DRNG mode.
44  *
45  * PTRNG mode with DF: This mode is similar to PTRNG mode, however, the entropy
46  * data from the core output registers are accumulated and fed to the DF
47  * (instead of directly consuming it). The output of the DF would be final
48  * random data. In this mode, the output of DF is not seed but the random data.
49  *
50  * HRNG mode with DF: This mode is the combination of the above two modes.
51  * The entropy data is fed to the DF to produce seed. This seed is loaded to the
52  * external seed registers which provide seed to the DRBG.
53  */
54 
55 #include <config.h>
56 #include <drivers/versal_pmc.h>
57 #include <drivers/versal_trng.h>
58 #include <initcall.h>
59 #include <io.h>
60 #include <kernel/delay.h>
61 #include <kernel/panic.h>
62 #include <mm/core_mmu.h>
63 #include <mm/core_memprot.h>
64 #include <rng_support.h>
65 #include <stdint.h>
66 #include <string.h>
67 #include <tee/tee_cryp_utl.h>
68 #include <util.h>
69 
70 #ifdef CFG_VERSAL_RNG_IO
71 #define TRNG_STATUS			0x04
72 #define TRNG_STATUS_QCNT_SHIFT		9
73 #define TRNG_STATUS_QCNT_MASK		(BIT(9) | BIT(10) | BIT(11))
74 #define TRNG_STATUS_CERTF_MASK		BIT(3)
75 #define TRNG_STATUS_DTF_MASK		BIT(1)
76 #define TRNG_STATUS_DONE_MASK		BIT(0)
77 #define TRNG_CTRL			0x08
78 #define TRNG_CTRL_EUMODE_MASK		BIT(8)
79 #define TRNG_CTRL_PRNGMODE_MASK		BIT(7)
80 #define TRNG_CTRL_TSTMODE_MASK		BIT(6)
81 #define TRNG_CTRL_PRNGSTART_MASK	BIT(5)
82 #define TRNG_CTRL_PRNGXS_MASK		BIT(3)
83 #define TRNG_CTRL_TRSSEN_MASK		BIT(2)
84 #define TRNG_CTRL_PRNGSRST_MASK		BIT(0)
85 
86 #define TRNG_CTRL_PERSODISABLE_MASK	BIT(10)
87 #define TRNG_CTRL_SINGLEGENMODE_MASK	BIT(9)
88 
89 #ifdef CFG_VERSAL_RNG_V2
90 /* register CTRL_2 is also called CONF_0 */
91 #define TRNG_CTRL_2			0x0C
92 #define TRNG_CTRL_2_RCTCUTOFF_SHIFT	8
93 #define TRNG_CTRL_2_RCTCUTOFF_MASK	GENMASK_32(16, 8)
94 #define TRNG_CTRL_2_RCTCUTOFF_DEFVAL	0x21
95 #define TRNG_CTRL_2_DIT_SHIFT		0
96 #define TRNG_CTRL_2_DIT_MASK		GENMASK_32(4, 0)
97 #define TRNG_CTRL_2_DIT_DEFVAL		0xC
98 /* register CTRL_3 is also called CONF_1 */
99 #define TRNG_CTRL_3			0x10
100 #define TRNG_CTRL_3_APTCUTOFF_SHIFT	8
101 #define TRNG_CTRL_3_APTCUTOFF_MASK	GENMASK_32(17, 8)
102 #define TRNG_CTRL_3_APTCUTOFF_DEFVAL	0x264
103 #define TRNG_CTRL_3_DLEN_SHIFT		0
104 #define TRNG_CTRL_3_DLEN_MASK		GENMASK_32(7, 0)
105 #define TRNG_CTRL_3_DLEN_DEFVAL		0x9
106 /* register CTRL_4 is also called TEST */
107 #define TRNG_CTRL_4			0x14
108 #define TRNG_CTRL_4_SINGLEBITRAW_MASK	BIT(0)
109 #endif
110 
111 #define TRNG_EXT_SEED_0			0x40
112 /*
113  * Below registers are not directly referenced in driver but are accessed
114  * with offset from TRNG_EXT_SEED_0
115  * Register: TRNG_EXT_SEED_1		0x00000044
116  * Register: TRNG_EXT_SEED_2		0x00000048
117  * Register: TRNG_EXT_SEED_3		0x0000004C
118  * Register: TRNG_EXT_SEED_4		0x00000050
119  * Register: TRNG_EXT_SEED_5		0x00000054
120  * Register: TRNG_EXT_SEED_6		0x00000058
121  * Register: TRNG_EXT_SEED_7		0x0000005C
122  * Register: TRNG_EXT_SEED_8		0x00000060
123  * Register: TRNG_EXT_SEED_9		0x00000064
124  * Register: TRNG_EXT_SEED_10		0x00000068
125  * Register: TRNG_EXT_SEED_11		0x0000006C
126  */
127 #define TRNG_PER_STRING_0		0x80
128 /*
129  * Below registers are not directly referenced in driver but are accessed
130  * with offset from TRNG_PER_STRING_0
131  * Register: TRNG_PER_STRING_1		0x00000084
132  * Register: TRNG_PER_STRING_2		0x00000088
133  * Register: TRNG_PER_STRING_3		0x0000008C
134  * Register: TRNG_PER_STRING_4		0x00000090
135  * Register: TRNG_PER_STRING_5		0x00000094
136  * Register: TRNG_PER_STRING_6		0x00000098
137  * Register: TRNG_PER_STRING_7		0x0000009C
138  * Register: TRNG_PER_STRING_8		0x000000A0
139  * Register: TRNG_PER_STRING_9		0x000000A4
140  * Register: TRNG_PER_STRING_10		0x000000A8
141  * Register: TRNG_PER_STRING_11		0x000000AC
142  */
143 #define TRNG_CORE_OUTPUT		0xC0
144 #define TRNG_RESET			0xD0
145 #define TRNG_RESET_VAL_MASK		BIT(0)
146 #define TRNG_OSC_EN			0xD4
147 #define TRNG_OSC_EN_VAL_MASK		BIT(0)
148 
149 /* TRNG configuration  */
150 #define TRNG_BURST_SIZE		16
151 #define TRNG_BURST_SIZE_BITS	128
152 #define TRNG_NUM_INIT_REGS	12
153 #define TRNG_REG_SIZE		32
154 #define TRNG_BYTES_PER_REG	4
155 #define TRNG_MAX_QCNT		4
156 #define TRNG_RESEED_TIMEOUT	15000
157 #define TRNG_GENERATE_TIMEOUT	8000
158 #define TRNG_V2_RESEED_TIMEOUT	1500000
159 #define TRNG_V2_GENERATE_TIMEOUT 1500000
160 #define TRNG_V2_MIN_SEEDLIFE	1
161 #define TRNG_V2_MAX_SEEDLIFE	0x80000
162 #define TRNG_MIN_DFLENMULT	2
163 #define TRNG_MAX_DFLENMULT	9
164 #define TRNG_V2_MIN_DFLENMULT	TRNG_MIN_DFLENMULT
165 #define TRNG_V2_MAX_DFLENMULT	31
166 #define PRNGMODE_RESEED		0
167 #define PRNGMODE_GEN		TRNG_CTRL_PRNGMODE_MASK
168 #define RESET_DELAY		10
169 #define TRNG_ENTROPY_SEED_LEN	64
170 #define TRNG_SEC_STRENGTH_LEN	32
171 #define TRNG_SEED_REGS		12
172 #define TRNG_GEN_LEN		32
173 #define BYTES_PER_BLOCK		16
174 #define ALL_A_PATTERN_32	0xAAAAAAAA
175 #define ALL_5_PATTERN_32	0x55555555
176 
177 #ifdef CFG_VERSAL_RNG_V2
178 #define TRNG_DF_2CLKS_WAIT	2
179 #define TRNG_DF_700CLKS_WAIT	10
180 #define TRNG_DF_NUM_OF_BYTES_BEFORE_MIN_700CLKS_WAIT 8
181 #endif
182 
183 /* Derivative function helper macros */
184 #define DF_SEED			0
185 #define DF_RAND			1
186 
187 #ifdef CFG_VERSAL_RNG_V1
188 #define DF_PAD_VAL		0x80
189 #define DF_KEY_LEN		32
190 #define BLK_SIZE		16
191 #define MAX_ROUNDS		14
192 
193 /* Derivative function variables */
194 static unsigned char sbx1[256];
195 static unsigned char sbx2[256];
196 static unsigned char sbx3[256];
197 static unsigned char schedule[BLK_SIZE * (MAX_ROUNDS + 1)];
198 static unsigned int rounds;
199 
rota4(uint8_t * a,uint8_t * b,uint8_t * c,uint8_t * d)200 static void rota4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d)
201 {
202 	uint8_t t = *a;
203 
204 	*a = sbx1[*b];
205 	*b = sbx1[*c];
206 	*c = sbx1[*d];
207 	*d = sbx1[t];
208 }
209 
rota2(uint8_t * a,uint8_t * b)210 static void rota2(uint8_t *a, uint8_t *b)
211 {
212 	uint8_t t = *a;
213 
214 	*a = sbx1[*b];
215 	*b = sbx1[t];
216 }
217 
sbox4(uint8_t * a,uint8_t * b,uint8_t * c,uint8_t * d)218 static void sbox4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d)
219 {
220 	*a = sbx1[*a];
221 	*b = sbx1[*b];
222 	*c = sbx1[*c];
223 	*d = sbx1[*d];
224 }
225 
xorb(uint8_t * res,const uint8_t * in)226 static void xorb(uint8_t *res,  const uint8_t *in)
227 {
228 	size_t i = 0;
229 
230 	for (i = 0; i < BLK_SIZE; ++i)
231 		res[i] ^= in[i];
232 }
233 
set_key(uint8_t * res,const uint8_t * src,unsigned int roundval)234 static void set_key(uint8_t *res, const uint8_t *src, unsigned int roundval)
235 {
236 	memcpy(res, src, BLK_SIZE);
237 	xorb(res, schedule + roundval * BLK_SIZE);
238 }
239 
mix_column_sbox(uint8_t * dst,const uint8_t * f)240 static void mix_column_sbox(uint8_t *dst, const uint8_t *f)
241 {
242 	size_t i = 0;
243 	size_t a = 0;
244 	size_t b = 0;
245 	size_t c = 0;
246 	size_t d = 0;
247 
248 	for (i = 0; i < 4; i++) {
249 		a = 4 * i;
250 		b = (0x5 + a) % 16;
251 		c = (0xa + a) % 16;
252 		d = (0xf + a) % 16;
253 		dst[0 + a] = sbx2[f[a]] ^ sbx3[f[b]] ^ sbx1[f[c]] ^ sbx1[f[d]];
254 		dst[1 + a] = sbx1[f[a]] ^ sbx2[f[b]] ^ sbx3[f[c]] ^ sbx1[f[d]];
255 		dst[2 + a] = sbx1[f[a]] ^ sbx1[f[b]] ^ sbx2[f[c]] ^ sbx3[f[d]];
256 		dst[3 + a] = sbx3[f[a]] ^ sbx1[f[b]] ^ sbx1[f[c]] ^ sbx2[f[d]];
257 	}
258 }
259 
shift_row_sbox(uint8_t * f)260 static void shift_row_sbox(uint8_t *f)
261 {
262 	sbox4(&f[0], &f[4], &f[8], &f[12]);
263 	rota4(&f[1], &f[5], &f[9], &f[13]);
264 	rota2(&f[2], &f[10]);
265 	rota2(&f[6], &f[14]);
266 	rota4(&f[15], &f[11], &f[7], &f[3]);
267 }
268 
encrypt(uint8_t * in,uint8_t * out)269 static void encrypt(uint8_t *in, uint8_t *out)
270 {
271 	uint8_t fa[BLK_SIZE] = { 0 };
272 	uint8_t fb[BLK_SIZE] = { 0 };
273 	size_t roundval = 0;
274 
275 	set_key(fa, in, 0);
276 	for (roundval = 1; roundval < rounds; ++roundval) {
277 		mix_column_sbox(fb, fa);
278 		set_key(fa, fb, roundval);
279 	}
280 
281 	shift_row_sbox(fa);
282 	set_key(out, fa, roundval);
283 }
284 
checksum(unsigned char * in,uint8_t * iv,int max_blk)285 static void checksum(unsigned char *in, uint8_t *iv, int max_blk)
286 {
287 	while (max_blk > 0) {
288 		xorb(iv, in);
289 		encrypt(iv, iv);
290 		in += BLK_SIZE;
291 		max_blk -= 1;
292 	}
293 }
294 
setup_key(const unsigned char * k,size_t klen)295 static void setup_key(const unsigned char *k, size_t klen)
296 {
297 	unsigned char rcon = 1;
298 	size_t sch_size = 240;
299 	size_t i = 0;
300 
301 	rounds = MAX_ROUNDS;
302 	memcpy(schedule, k, klen);
303 	for (i = klen; i < sch_size; i += 4) {
304 		unsigned char t0 = 0;
305 		unsigned char t1 = 0;
306 		unsigned char t2 = 0;
307 		unsigned char t3 = 0;
308 		int ik = 0;
309 
310 		t0 = schedule[i - 4];
311 		t1 = schedule[i - 3];
312 		t2 = schedule[i - 2];
313 		t3 = schedule[i - 1];
314 		if (i % klen == 0) {
315 			rota4(&t0, &t1, &t2, &t3);
316 			t0 ^= rcon;
317 			rcon = (rcon << 1) ^ (((rcon >> 7) & 1) * 0x1B);
318 		} else if (i % klen == 16) {
319 			sbox4(&t0, &t1, &t2, &t3);
320 		}
321 		ik = i - klen;
322 		schedule[i + 0] = schedule[ik + 0] ^ t0;
323 		schedule[i + 1] = schedule[ik + 1] ^ t1;
324 		schedule[i + 2] = schedule[ik + 2] ^ t2;
325 		schedule[i + 3] = schedule[ik + 3] ^ t3;
326 	}
327 }
328 
trng_df_init(void)329 static void trng_df_init(void)
330 {
331 	const uint8_t sb[] = {
332 		0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01,
333 		0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d,
334 		0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4,
335 		0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
336 		0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7,
337 		0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
338 		0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e,
339 		0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
340 		0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb,
341 		0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb,
342 		0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c,
343 		0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
344 		0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c,
345 		0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d,
346 		0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a,
347 		0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
348 		0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3,
349 		0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
350 		0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a,
351 		0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
352 		0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e,
353 		0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9,
354 		0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9,
355 		0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
356 		0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99,
357 		0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
358 	};
359 	size_t i = 0;
360 
361 	memcpy(sbx1, sb, sizeof(sb));
362 	for (i = 0; i < sizeof(sb); i++) {
363 		sbx2[i] = (sb[i] << 1) ^ (((sb[i] >> 7) & 1) * 0x1B);
364 		sbx3[i] = sbx2[i] ^ sb[i];
365 	}
366 }
367 
368 /*
369  * This function implements the Derivative Function by distilling the entropy
370  * available in its input into a smaller number of bits on the output.
371  * - per NIST SP80090A.
372  *
373  * The Block Cipher algorithm follows sections 10.3.2 and 10.3.3 of the
374  * NIST.SP.800-90Ar1 document
375  */
trng_df_algorithm(struct versal_trng * trng,uint8_t * dfout,uint32_t flag,const uint8_t * pstr)376 static void trng_df_algorithm(struct versal_trng *trng, uint8_t *dfout,
377 			      uint32_t flag, const uint8_t *pstr)
378 {
379 	static bool df_init;
380 	const uint8_t df_key[DF_KEY_LEN] = {
381 		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
382 		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
383 	};
384 	size_t dfin_len = sizeof(struct trng_dfin) + trng->len;
385 	uint8_t *inp_blk = NULL;
386 	uint8_t *out_blk = NULL;
387 	uintptr_t reminder = 0;
388 	size_t xfer_len = 0;
389 	uint32_t index = 0;
390 	uintptr_t src = 0;
391 	uintptr_t dst = 0;
392 	size_t offset = 0;
393 
394 	if (!df_init) {
395 		trng_df_init();
396 		df_init = true;
397 	}
398 
399 	if (flag == DF_SEED)
400 		trng->dfin.val2 = TEE_U32_TO_BIG_ENDIAN(TRNG_PERS_STR_LEN);
401 	else
402 		trng->dfin.val2 = TEE_U32_TO_BIG_ENDIAN(TRNG_GEN_LEN);
403 
404 	trng->dfin.pad_data[0] = DF_PAD_VAL;
405 
406 	if (!pstr) {
407 		if (trng->len > (MAX_PRE_DF_LEN + TRNG_PERS_STR_LEN))
408 			panic();
409 
410 		dfin_len = dfin_len - TRNG_PERS_STR_LEN - MAX_PRE_DF_LEN;
411 		trng->dfin.val1 = TEE_U32_TO_BIG_ENDIAN(trng->len);
412 
413 		xfer_len = DF_PAD_DATA_LEN;
414 		src = (uintptr_t)trng->dfin.pad_data;
415 		offset = MAX_PRE_DF_LEN + TRNG_PERS_STR_LEN - trng->len;
416 	} else {
417 		if (trng->len > MAX_PRE_DF_LEN)
418 			panic();
419 
420 		memcpy(trng->dfin.pstr, pstr, TRNG_PERS_STR_LEN);
421 		dfin_len = dfin_len - MAX_PRE_DF_LEN;
422 		trng->dfin.val1 = TEE_U32_TO_BIG_ENDIAN(trng->len +
423 							TRNG_PERS_STR_LEN);
424 		xfer_len = DF_PAD_DATA_LEN + TRNG_PERS_STR_LEN;
425 		src = (uintptr_t)trng->dfin.pstr;
426 		offset = MAX_PRE_DF_LEN - trng->len;
427 	}
428 
429 	/* Move back into the dfin structure */
430 	dst = src - offset;
431 	reminder = (uintptr_t)&trng->dfin + sizeof(trng->dfin) - offset;
432 	if (offset) {
433 		if (xfer_len > offset)
434 			panic("Overlapping data");
435 
436 		memcpy((void *)dst, (void *)src, xfer_len);
437 		memset((void *)reminder, 0, offset);
438 	}
439 
440 	/* DF algorithm - step 1 */
441 	setup_key(df_key, DF_KEY_LEN);
442 	for (index = 0; index < TRNG_SEED_LEN; index += BLK_SIZE) {
443 		memset((void *)(trng->dfout + index), 0, BLK_SIZE);
444 		trng->dfin.ivc[0] = TEE_U32_TO_BIG_ENDIAN(index / BLK_SIZE);
445 		checksum((unsigned char *)&trng->dfin,
446 			 trng->dfout + index, dfin_len / BLK_SIZE);
447 	}
448 
449 	/* DF algorithm - step 2 */
450 	setup_key(trng->dfout, DF_KEY_LEN);
451 	for (index = 0; index < TRNG_SEED_LEN; index += BLK_SIZE) {
452 		if (!index)
453 			inp_blk = &dfout[TRNG_SEC_STRENGTH_LEN];
454 		else
455 			inp_blk = &dfout[index - BLK_SIZE];
456 
457 		out_blk = &dfout[index];
458 		encrypt(inp_blk, out_blk);
459 	}
460 }
461 #endif
462 
trng_read32(vaddr_t addr,size_t off)463 static uint32_t trng_read32(vaddr_t addr, size_t off)
464 {
465 	return io_read32(addr + off);
466 }
467 
trng_write32(vaddr_t addr,size_t off,uint32_t val)468 static void trng_write32(vaddr_t addr, size_t off, uint32_t val)
469 {
470 	io_write32(addr + off, val);
471 }
472 
trng_clrset32(vaddr_t addr,size_t off,uint32_t mask,uint32_t val)473 static void trng_clrset32(vaddr_t addr, size_t off, uint32_t mask, uint32_t val)
474 {
475 	io_clrsetbits32(addr + off, mask, mask & val);
476 }
477 
trng_write32_range(const struct versal_trng * trng,uint32_t start,uint32_t num_regs,const uint8_t * buf)478 static void trng_write32_range(const struct versal_trng *trng, uint32_t start,
479 			       uint32_t num_regs, const uint8_t *buf)
480 {
481 	size_t off = 0;
482 	uint32_t val = 0;
483 	size_t cnt = 0;
484 	size_t i = 0;
485 
486 	for (i = 0; i < num_regs; ++i) {
487 		if (!buf) {
488 			off = start + i * TRNG_BYTES_PER_REG;
489 			trng_write32(trng->cfg.addr, off, 0);
490 			continue;
491 		}
492 
493 		val = 0;
494 		for (cnt = 0; cnt < TRNG_BYTES_PER_REG; ++cnt)
495 			val = (val << 8) | buf[i * TRNG_BYTES_PER_REG + cnt];
496 
497 		off = start + (TRNG_NUM_INIT_REGS - 1 - i) * TRNG_BYTES_PER_REG;
498 		trng_write32(trng->cfg.addr, off, val);
499 	}
500 }
501 
trng_wait_for_event(vaddr_t addr,size_t off,uint32_t mask,uint32_t event,uint32_t time_out)502 static TEE_Result trng_wait_for_event(vaddr_t addr, size_t off, uint32_t mask,
503 				      uint32_t event, uint32_t time_out)
504 {
505 	uint64_t tref = timeout_init_us(time_out);
506 
507 	do {
508 		if (timeout_elapsed(tref))
509 			break;
510 	} while ((io_read32(addr + off) & mask) != event);
511 
512 	/* Normal world might have suspended the OP-TEE thread, check again  */
513 	if ((io_read32(addr + off) & mask) != event)
514 		return TEE_ERROR_GENERIC;
515 
516 	return TEE_SUCCESS;
517 }
518 
trng_soft_reset(const struct versal_trng * trng)519 static void trng_soft_reset(const struct versal_trng *trng)
520 {
521 	trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSRST_MASK,
522 		      TRNG_CTRL_PRNGSRST_MASK);
523 	udelay(RESET_DELAY);
524 	trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSRST_MASK, 0);
525 }
526 
trng_reset(const struct versal_trng * trng)527 static void trng_reset(const struct versal_trng *trng)
528 {
529 	trng_write32(trng->cfg.addr, TRNG_RESET, TRNG_RESET_VAL_MASK);
530 	udelay(RESET_DELAY);
531 	trng_write32(trng->cfg.addr, TRNG_RESET, 0);
532 	trng_soft_reset(trng);
533 }
534 
trng_hold_reset(const struct versal_trng * trng)535 static void trng_hold_reset(const struct versal_trng *trng)
536 {
537 	trng_clrset32(trng->cfg.addr, TRNG_CTRL,
538 		      TRNG_CTRL_PRNGSRST_MASK, TRNG_CTRL_PRNGSRST_MASK);
539 	trng_write32(trng->cfg.addr, TRNG_RESET, TRNG_RESET_VAL_MASK);
540 	udelay(RESET_DELAY);
541 }
542 
543 #ifdef CFG_VERSAL_RNG_V2
trng_v2_write_seed(const struct versal_trng * trng,const uint8_t * seed,uint8_t dlen)544 static int trng_v2_write_seed(const struct versal_trng *trng,
545 			      const uint8_t *seed, uint8_t dlen)
546 {
547 	int status = TEE_ERROR_GENERIC;
548 	uint32_t seed_len = (dlen + 1) * BYTES_PER_BLOCK;
549 	uint32_t idx = 0;
550 	uint8_t cnt = 0;
551 
552 	while (idx < seed_len) {
553 		uint8_t seed_construct = 0;
554 
555 		for (cnt = 0; cnt < 8; cnt++) {
556 			uint32_t bit = (seed[idx] >> (8 - 1 - cnt)) & 0x01;
557 
558 			trng_write32(trng->cfg.addr, TRNG_CTRL_4, bit);
559 			seed_construct = (seed_construct << 1) | bit;
560 		}
561 
562 		if (seed_construct != seed[idx])
563 			goto END;
564 
565 		udelay(TRNG_DF_2CLKS_WAIT);
566 		if (!(idx % TRNG_DF_NUM_OF_BYTES_BEFORE_MIN_700CLKS_WAIT))
567 			udelay(TRNG_DF_700CLKS_WAIT);
568 
569 		idx++;
570 	}
571 	if (idx == seed_len)
572 		status = TEE_SUCCESS;
573 
574 END:
575 	return status;
576 }
577 #endif
578 
579 #ifdef CFG_VERSAL_RNG_V1
trng_check_seed(uint8_t * entropy,uint32_t len)580 static TEE_Result trng_check_seed(uint8_t *entropy, uint32_t len)
581 {
582 	uint32_t *p = (void *)entropy;
583 	size_t i = 0;
584 
585 	for (i = 0; i < len / sizeof(*p); i++) {
586 		if (p[i] == ALL_A_PATTERN_32)
587 			return TEE_ERROR_GENERIC;
588 
589 		if (p[i] == ALL_5_PATTERN_32)
590 			return TEE_ERROR_GENERIC;
591 	}
592 
593 	return TEE_SUCCESS;
594 }
595 #endif
596 
trng_collect_random(struct versal_trng * trng,uint8_t * dst,size_t len)597 static TEE_Result trng_collect_random(struct versal_trng *trng, uint8_t *dst,
598 				      size_t len)
599 {
600 	const size_t bursts = len / TRNG_BURST_SIZE;
601 	const size_t words = TRNG_BURST_SIZE_BITS / TRNG_REG_SIZE;
602 	uint32_t *p = (void *)dst;
603 	size_t bcnt = 0;
604 	size_t wcnt = 0;
605 	size_t index = 0;
606 	uint32_t val = 0;
607 	bool match = false;
608 	uint32_t timeout = TRNG_GENERATE_TIMEOUT;
609 	bool do_start = true;
610 
611 	if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2) {
612 		if (trng->usr_cfg.predict_en ||
613 		    !trng->stats.elapsed_seed_life) {
614 			uint32_t singlegen = 0;
615 
616 			if (trng->usr_cfg.predict_en)
617 				singlegen = TRNG_CTRL_SINGLEGENMODE_MASK;
618 
619 			trng_clrset32(trng->cfg.addr, TRNG_CTRL,
620 				      TRNG_CTRL_PRNGMODE_MASK |
621 				      TRNG_CTRL_SINGLEGENMODE_MASK |
622 				      TRNG_CTRL_PRNGSTART_MASK,
623 				      PRNGMODE_GEN | singlegen);
624 		} else {
625 			do_start = false;
626 		}
627 
628 		timeout = TRNG_V2_GENERATE_TIMEOUT;
629 	}
630 
631 	if (do_start)
632 		trng_clrset32(trng->cfg.addr, TRNG_CTRL,
633 			      TRNG_CTRL_PRNGSTART_MASK,
634 			      TRNG_CTRL_PRNGSTART_MASK);
635 
636 	/*
637 	 * Loop as many times based on len requested. In each burst 128 bits
638 	 * are generated, which is reflected in QCNT value of 4 by hardware.
639 	 */
640 	for (bcnt = 0; bcnt < bursts; bcnt++) {
641 		if (trng_wait_for_event(trng->cfg.addr,
642 					TRNG_STATUS, TRNG_STATUS_QCNT_MASK,
643 					TRNG_MAX_QCNT << TRNG_STATUS_QCNT_SHIFT,
644 					timeout)) {
645 			EMSG("Timeout waiting for randomness");
646 			return TEE_ERROR_GENERIC;
647 		}
648 
649 		/*
650 		 * DTF flag set during generate indicates catastrophic
651 		 * condition, which needs to be checked for every time unless we
652 		 * are in PTRNG mode
653 		 */
654 		if (trng->usr_cfg.mode != TRNG_PTRNG) {
655 			val = trng_read32(trng->cfg.addr, TRNG_STATUS);
656 			if (val & TRNG_STATUS_DTF_MASK) {
657 				EMSG("Catastrophic DFT error");
658 				trng->status = TRNG_CATASTROPHIC;
659 
660 				return TEE_ERROR_GENERIC;
661 			}
662 		}
663 		/*
664 		 * Read the core output register 4 times to consume the random
665 		 * data generated for every burst.
666 		 */
667 		match = true;
668 		for (wcnt = 0; wcnt < words; wcnt++) {
669 			val = trng_read32(trng->cfg.addr, TRNG_CORE_OUTPUT);
670 
671 			if (bcnt > 0 && trng->buf[wcnt] != val)
672 				match = false;
673 
674 			trng->buf[wcnt] = val;
675 
676 			if (dst) {
677 				p[index] = TEE_U32_TO_BIG_ENDIAN(val);
678 				index++;
679 			}
680 		}
681 
682 		if (bursts > 1 && bcnt > 0 && match) {
683 			EMSG("Catastrophic software error");
684 			trng->status = TRNG_CATASTROPHIC;
685 			return TEE_ERROR_GENERIC;
686 		}
687 	}
688 
689 	return TEE_SUCCESS;
690 }
691 
692 #ifdef CFG_VERSAL_RNG_V2
trng_v2_reseed_internal(struct versal_trng * trng,uint8_t * eseed,uint8_t * str,uint32_t mul)693 static TEE_Result trng_v2_reseed_internal(struct versal_trng *trng,
694 					  uint8_t *eseed, uint8_t *str,
695 					  uint32_t mul)
696 {
697 	uint32_t ret = TEE_ERROR_GENERIC;
698 	uint32_t persmask = TRNG_CTRL_PERSODISABLE_MASK;
699 	uint32_t val = 0;
700 
701 	trng->stats.bytes_reseed = 0;
702 	trng->stats.elapsed_seed_life = 0;
703 
704 	/* Configure DF Len */
705 	trng_clrset32(trng->cfg.addr, TRNG_CTRL_3, TRNG_CTRL_3_DLEN_MASK,
706 		      (mul << TRNG_CTRL_3_DLEN_SHIFT));
707 
708 	if (str) {
709 		trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS,
710 				   str);
711 		persmask = 0;
712 	}
713 
714 	trng_clrset32(trng->cfg.addr, TRNG_CTRL,
715 		      TRNG_CTRL_PERSODISABLE_MASK | TRNG_CTRL_PRNGSTART_MASK,
716 		      persmask);
717 
718 	switch (trng->usr_cfg.mode) {
719 	case TRNG_HRNG:
720 		/* Enable ring oscillators for random seed source */
721 		trng_clrset32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK,
722 			      TRNG_OSC_EN_VAL_MASK);
723 
724 		/* Enable TRSSEN and set PRNG mode for reseed operation */
725 		trng_clrset32(trng->cfg.addr, TRNG_CTRL,
726 			      TRNG_CTRL_PRNGMODE_MASK |
727 			      TRNG_CTRL_TRSSEN_MASK | TRNG_CTRL_PRNGXS_MASK,
728 			      PRNGMODE_RESEED |
729 			      TRNG_CTRL_TRSSEN_MASK);
730 
731 		/* Start reseed operation */
732 		trng_clrset32(trng->cfg.addr, TRNG_CTRL,
733 			      TRNG_CTRL_PRNGSTART_MASK,
734 			      TRNG_CTRL_PRNGSTART_MASK);
735 		break;
736 	case TRNG_DRNG:
737 		/* Enable TST mode and set PRNG mode for reseed operation */
738 		trng_clrset32(trng->cfg.addr, TRNG_CTRL,
739 			      TRNG_CTRL_PRNGMODE_MASK |
740 			      TRNG_CTRL_TSTMODE_MASK | TRNG_CTRL_TRSSEN_MASK,
741 			      PRNGMODE_RESEED |
742 			      TRNG_CTRL_TSTMODE_MASK | TRNG_CTRL_TRSSEN_MASK);
743 
744 		/* Start reseed operation */
745 		trng_clrset32(trng->cfg.addr, TRNG_CTRL,
746 			      TRNG_CTRL_PRNGSTART_MASK,
747 			      TRNG_CTRL_PRNGSTART_MASK);
748 
749 		ret = trng_v2_write_seed(trng, eseed, mul);
750 		if (ret)
751 			return ret;
752 		break;
753 	default:
754 		/* shall not be reached */
755 		panic();
756 	}
757 
758 	/* Wait for reseed operation */
759 	if (trng_wait_for_event(trng->cfg.addr, TRNG_STATUS,
760 				TRNG_STATUS_DONE_MASK,
761 				TRNG_STATUS_DONE_MASK,
762 				TRNG_V2_RESEED_TIMEOUT))
763 		goto error;
764 
765 	/* Check SP800 - 90B (entropy health test error) */
766 	val = trng_read32(trng->cfg.addr, TRNG_STATUS) & TRNG_STATUS_CERTF_MASK;
767 	if (val == TRNG_STATUS_CERTF_MASK)
768 		goto error;
769 
770 	/* Stop reseed operation */
771 	trng_clrset32(trng->cfg.addr, TRNG_CTRL,
772 		      TRNG_CTRL_PRNGSTART_MASK | TRNG_CTRL_TRSSEN_MASK, 0);
773 	return TEE_SUCCESS;
774 
775 error:
776 	trng->status = TRNG_ERROR;
777 	return TEE_ERROR_GENERIC;
778 }
779 #else
trng_v2_reseed_internal(struct versal_trng * trng __unused,uint8_t * eseed __unused,uint8_t * str __unused,uint32_t mul __unused)780 static TEE_Result trng_v2_reseed_internal(struct versal_trng *trng __unused,
781 					  uint8_t *eseed __unused,
782 					  uint8_t *str __unused,
783 					  uint32_t mul __unused)
784 {
785 	return TEE_ERROR_NOT_SUPPORTED;
786 }
787 #endif
788 
789 #ifdef CFG_VERSAL_RNG_V1
trng_reseed_internal_nodf(struct versal_trng * trng,uint8_t * eseed,uint8_t * str)790 static TEE_Result trng_reseed_internal_nodf(struct versal_trng *trng,
791 					    uint8_t *eseed, uint8_t *str)
792 {
793 	uint8_t entropy[TRNG_ENTROPY_SEED_LEN] = { 0 };
794 	uint8_t *seed = NULL;
795 
796 	switch (trng->usr_cfg.mode) {
797 	case TRNG_HRNG:
798 		/*
799 		 * Versal TRNG IP doesn't recognize alternate 1 and 0 pattern,
800 		 * hence the entropy output need to be monitored before using it
801 		 * as seed. This means, TRNG couldn't be configured for entropy
802 		 * source as seed source. Instead, entropy data is collected as
803 		 * random data, and after inspecting for pattern, is fed again
804 		 * to the external seed registers. This is essentially similar
805 		 * to HRNG + DF case except that there is no DF involved. This
806 		 * actually is configuration for PTRNG mode (not for reseed) to
807 		 * collect random output data from entropy source.
808 		 */
809 		trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK);
810 		trng_soft_reset(trng);
811 		trng_write32(trng->cfg.addr, TRNG_CTRL,
812 			     TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK);
813 
814 		if (trng_collect_random(trng, entropy, TRNG_ENTROPY_SEED_LEN))
815 			return TEE_ERROR_GENERIC;
816 
817 		if (trng_check_seed(entropy, TRNG_ENTROPY_SEED_LEN))
818 			return TEE_ERROR_GENERIC;
819 
820 		seed = entropy;
821 		break;
822 	case TRNG_DRNG:
823 		seed = eseed;
824 		break;
825 	default:
826 		seed = NULL;
827 		break;
828 	}
829 
830 	trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, seed);
831 	if (str)
832 		trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS,
833 				   str);
834 
835 	return TEE_SUCCESS;
836 }
837 
trng_reseed_internal_df(struct versal_trng * trng,uint8_t * eseed,uint8_t * str)838 static TEE_Result trng_reseed_internal_df(struct versal_trng *trng,
839 					  uint8_t *eseed, uint8_t *str)
840 {
841 	memset(&trng->dfin, 0, sizeof(trng->dfin));
842 
843 	switch (trng->usr_cfg.mode) {
844 	case TRNG_HRNG:
845 		/* see comment in _nodf() */
846 		trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK);
847 		trng_soft_reset(trng);
848 		trng_write32(trng->cfg.addr, TRNG_CTRL,
849 			     TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK);
850 
851 		if (trng_collect_random(trng, trng->dfin.entropy, trng->len))
852 			return TEE_ERROR_GENERIC;
853 
854 		if (trng_check_seed(trng->dfin.entropy, trng->len))
855 			return TEE_ERROR_GENERIC;
856 		break;
857 	case TRNG_DRNG:
858 		memcpy(trng->dfin.entropy, eseed, trng->len);
859 		break;
860 	default:
861 		break;
862 	}
863 
864 	trng_df_algorithm(trng, trng->dfout, DF_SEED, str);
865 	trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, trng->dfout);
866 
867 	return TEE_SUCCESS;
868 }
869 
trng_v1_reseed_internal(struct versal_trng * trng,uint8_t * eseed,uint8_t * str,uint32_t mul)870 static TEE_Result trng_v1_reseed_internal(struct versal_trng *trng,
871 					  uint8_t *eseed, uint8_t *str,
872 					  uint32_t mul)
873 {
874 	uint32_t val = 0;
875 
876 	trng->stats.bytes_reseed = 0;
877 	trng->stats.elapsed_seed_life = 0;
878 
879 	if (trng->usr_cfg.df_disable)
880 		trng->len = TRNG_SEED_LEN;
881 	else
882 		trng->len = (mul + 1) * BYTES_PER_BLOCK;
883 
884 	if (trng->usr_cfg.df_disable) {
885 		if (trng_reseed_internal_nodf(trng, eseed, str))
886 			goto error;
887 	} else {
888 		if (trng_reseed_internal_df(trng, eseed, str))
889 			goto error;
890 	}
891 
892 	/*
893 	 * Set PRNGMODE to reseed and seed source (PRNGXS) to
894 	 * TRNG_EXT_SEED_*; the latter especially also for HRNG due to
895 	 * not being able to selected entropy source as seed source.
896 	 */
897 	trng_write32(trng->cfg.addr, TRNG_CTRL,
898 		     PRNGMODE_RESEED | TRNG_CTRL_PRNGXS_MASK);
899 
900 	/* Start the reseed operation */
901 	trng_clrset32(trng->cfg.addr, TRNG_CTRL,
902 		      TRNG_CTRL_PRNGSTART_MASK,
903 		      TRNG_CTRL_PRNGSTART_MASK);
904 
905 	/* Wait for reseed operation */
906 	if (trng_wait_for_event(trng->cfg.addr, TRNG_STATUS,
907 				TRNG_STATUS_DONE_MASK,
908 				TRNG_STATUS_DONE_MASK,
909 				TRNG_RESEED_TIMEOUT))
910 		goto error;
911 
912 	/* Check SP800 - 90B (entropy health test error) */
913 	val = trng_read32(trng->cfg.addr, TRNG_STATUS) & TRNG_STATUS_CERTF_MASK;
914 	if (val == TRNG_STATUS_CERTF_MASK)
915 		goto error;
916 
917 	/* Stop reseed operation */
918 	trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSTART_MASK, 0);
919 	return TEE_SUCCESS;
920 error:
921 	trng->status = TRNG_ERROR;
922 	return TEE_ERROR_GENERIC;
923 }
924 #else
trng_df_algorithm(struct versal_trng * trng __unused,uint8_t * dfout __unused,uint32_t flag __unused,const uint8_t * pstr __unused)925 static void trng_df_algorithm(struct versal_trng *trng __unused,
926 			      uint8_t *dfout __unused,
927 			      uint32_t flag __unused,
928 			      const uint8_t *pstr __unused)
929 
930 {
931 	panic();
932 }
933 
trng_v1_reseed_internal(struct versal_trng * trng __unused,uint8_t * eseed __unused,uint8_t * str __unused,uint32_t mul __unused)934 static TEE_Result trng_v1_reseed_internal(struct versal_trng *trng __unused,
935 					  uint8_t *eseed __unused,
936 					  uint8_t *str __unused,
937 					  uint32_t mul __unused)
938 {
939 	return TEE_ERROR_NOT_SUPPORTED;
940 }
941 #endif
942 
trng_reseed_internal(struct versal_trng * trng,uint8_t * eseed,uint8_t * str,uint32_t mul)943 static TEE_Result trng_reseed_internal(struct versal_trng *trng,
944 				       uint8_t *eseed, uint8_t *str,
945 				       uint32_t mul)
946 {
947 	if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1)
948 		return trng_v1_reseed_internal(trng, eseed, str, mul);
949 	if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2)
950 		return trng_v2_reseed_internal(trng, eseed, str, mul);
951 
952 	return TEE_ERROR_GENERIC;
953 }
954 
trng_instantiate(struct versal_trng * trng,const struct trng_usr_cfg * usr_cfg)955 static TEE_Result trng_instantiate(struct versal_trng *trng,
956 				   const struct trng_usr_cfg *usr_cfg)
957 {
958 	uint8_t *seed = NULL;
959 	uint8_t *pers = NULL;
960 
961 	if (!trng)
962 		return TEE_ERROR_GENERIC;
963 
964 	if (!usr_cfg)
965 		goto error;
966 
967 	if (trng->status != TRNG_UNINITIALIZED)
968 		goto error;
969 
970 	if (usr_cfg->mode != TRNG_HRNG && usr_cfg->mode != TRNG_DRNG &&
971 	    usr_cfg->mode != TRNG_PTRNG)
972 		goto error;
973 
974 	if (usr_cfg->mode != TRNG_PTRNG && !usr_cfg->seed_life)
975 		goto error;
976 
977 	if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2 &&
978 	    usr_cfg->mode != TRNG_PTRNG)
979 		if (usr_cfg->seed_life < TRNG_V2_MIN_SEEDLIFE ||
980 		    usr_cfg->seed_life > TRNG_V2_MAX_SEEDLIFE)
981 			goto error;
982 
983 	if (!usr_cfg->iseed_en && usr_cfg->mode == TRNG_DRNG)
984 		goto error;
985 
986 	if (usr_cfg->iseed_en && usr_cfg->mode == TRNG_HRNG)
987 		goto error;
988 
989 	if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1 &&
990 	    !usr_cfg->df_disable &&
991 	    (usr_cfg->dfmul < TRNG_MIN_DFLENMULT ||
992 	     usr_cfg->dfmul > TRNG_MAX_DFLENMULT))
993 		goto error;
994 	if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2 &&
995 	    (usr_cfg->df_disable ||
996 	     (usr_cfg->dfmul < TRNG_V2_MIN_DFLENMULT ||
997 	      usr_cfg->dfmul > TRNG_V2_MAX_DFLENMULT)))
998 		goto error;
999 
1000 	if (usr_cfg->df_disable && usr_cfg->dfmul)
1001 		goto error;
1002 
1003 	if (usr_cfg->mode == TRNG_PTRNG &&
1004 	    (usr_cfg->iseed_en || usr_cfg->pstr_en ||
1005 	     usr_cfg->predict_en || usr_cfg->seed_life))
1006 		goto error;
1007 
1008 	memcpy(&trng->usr_cfg, usr_cfg, sizeof(struct trng_usr_cfg));
1009 	trng_reset(trng);
1010 
1011 	if (trng->usr_cfg.iseed_en)
1012 		seed = (void *)trng->usr_cfg.init_seed;
1013 
1014 	if (trng->usr_cfg.pstr_en)
1015 		pers = (void *)trng->usr_cfg.pstr;
1016 
1017 	if (trng->usr_cfg.mode != TRNG_PTRNG) {
1018 		if (trng_reseed_internal(trng, seed, pers, trng->usr_cfg.dfmul))
1019 			goto error;
1020 	}
1021 
1022 	trng->status = TRNG_HEALTHY;
1023 	return TEE_SUCCESS;
1024 error:
1025 	trng->status = TRNG_ERROR;
1026 	return TEE_ERROR_GENERIC;
1027 }
1028 
trng_reseed(struct versal_trng * trng,uint8_t * eseed,uint32_t mul)1029 static TEE_Result trng_reseed(struct versal_trng *trng, uint8_t *eseed,
1030 			      uint32_t mul)
1031 {
1032 	if (!trng)
1033 		return TEE_ERROR_GENERIC;
1034 
1035 	if (trng->status != TRNG_HEALTHY)
1036 		goto error;
1037 
1038 	if (trng->usr_cfg.mode != TRNG_DRNG && trng->usr_cfg.mode != TRNG_HRNG)
1039 		goto error;
1040 
1041 	if (trng->usr_cfg.mode == TRNG_DRNG && !eseed)
1042 		goto error;
1043 
1044 	if (trng->usr_cfg.mode != TRNG_DRNG && eseed)
1045 		goto error;
1046 
1047 	if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1 &&
1048 	    !trng->usr_cfg.df_disable) {
1049 		if (mul < TRNG_MIN_DFLENMULT || mul > TRNG_MAX_DFLENMULT)
1050 			goto error;
1051 	}
1052 	if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2 &&
1053 	    (trng->usr_cfg.df_disable ||
1054 	     (mul < TRNG_V2_MIN_DFLENMULT || mul > TRNG_V2_MAX_DFLENMULT)))
1055 		goto error;
1056 
1057 	if (trng->usr_cfg.df_disable && mul)
1058 		goto error;
1059 
1060 	if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1 &&
1061 	    eseed && (trng->len > TRNG_SEED_LEN ||
1062 		      !memcmp(eseed, trng->usr_cfg.init_seed, trng->len)))
1063 		goto error;
1064 
1065 	if (trng_reseed_internal(trng, eseed, NULL, mul))
1066 		goto error;
1067 
1068 	return TEE_SUCCESS;
1069 error:
1070 	trng->status = TRNG_ERROR;
1071 	return TEE_ERROR_GENERIC;
1072 }
1073 
trng_generate(struct versal_trng * trng,uint8_t * buf,size_t blen,bool predict)1074 static TEE_Result trng_generate(struct versal_trng *trng, uint8_t *buf,
1075 				size_t blen, bool predict)
1076 {
1077 	uint32_t len = TRNG_SEC_STRENGTH_LEN;
1078 	uint8_t *p = buf;
1079 	uint32_t mul = 0;
1080 
1081 	if (!trng)
1082 		return TEE_ERROR_GENERIC;
1083 
1084 	if (!p)
1085 		goto error;
1086 
1087 	if (blen < TRNG_SEC_STRENGTH_LEN)
1088 		goto error;
1089 
1090 	if (trng->status != TRNG_HEALTHY)
1091 		goto error;
1092 
1093 	if (trng->usr_cfg.mode == TRNG_PTRNG && predict)
1094 		goto error;
1095 
1096 	if (!trng->usr_cfg.predict_en && predict)
1097 		goto error;
1098 
1099 	switch (trng->usr_cfg.mode) {
1100 	case TRNG_HRNG:
1101 		if (IS_ENABLED(CFG_VERSAL_RNG_V2) &&
1102 		    trng->cfg.version == TRNG_V2)
1103 			mul = trng->usr_cfg.dfmul;
1104 
1105 		if (trng->stats.elapsed_seed_life >= trng->usr_cfg.seed_life) {
1106 			if (trng_reseed_internal(trng, NULL, NULL, mul))
1107 				goto error;
1108 		}
1109 
1110 		if (predict && trng->stats.elapsed_seed_life > 0) {
1111 			if (trng_reseed_internal(trng, NULL, NULL, mul))
1112 				goto error;
1113 		}
1114 
1115 		if (IS_ENABLED(CFG_VERSAL_RNG_V1) &&
1116 		    trng->cfg.version == TRNG_V1)
1117 			trng_write32(trng->cfg.addr, TRNG_CTRL,
1118 				     PRNGMODE_GEN | TRNG_CTRL_PRNGXS_MASK);
1119 		break;
1120 	case TRNG_DRNG:
1121 		if (trng->stats.elapsed_seed_life >= trng->usr_cfg.seed_life) {
1122 			EMSG("Reseeding required");
1123 			goto error;
1124 		}
1125 
1126 		if (predict && trng->stats.elapsed_seed_life > 0) {
1127 			EMSG("Reseeding required");
1128 			goto error;
1129 		}
1130 
1131 		if (IS_ENABLED(CFG_VERSAL_RNG_V1) &&
1132 		    trng->cfg.version == TRNG_V1)
1133 			trng_write32(trng->cfg.addr, TRNG_CTRL,
1134 				     PRNGMODE_GEN | TRNG_CTRL_PRNGXS_MASK);
1135 		break;
1136 	default:
1137 		if (IS_ENABLED(CFG_VERSAL_RNG_V1) &&
1138 		    trng->cfg.version == TRNG_V1 &&
1139 		    !trng->usr_cfg.df_disable) {
1140 			memset(&trng->dfin, 0, sizeof(trng->dfin));
1141 			len = (trng->usr_cfg.dfmul + 1) * BYTES_PER_BLOCK;
1142 			trng->len = len;
1143 			p = trng->dfin.entropy;
1144 		}
1145 		/* Enable the 8 ring oscillators used for entropy source */
1146 		trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK);
1147 		if (IS_ENABLED(CFG_VERSAL_RNG_V1) &&
1148 		    trng->cfg.version == TRNG_V1) {
1149 			trng_soft_reset(trng);
1150 			trng_write32(trng->cfg.addr, TRNG_CTRL,
1151 				     TRNG_CTRL_EUMODE_MASK |
1152 				     TRNG_CTRL_TRSSEN_MASK);
1153 		}
1154 
1155 		if (IS_ENABLED(CFG_VERSAL_RNG_V2) &&
1156 		    trng->cfg.version == TRNG_V2)
1157 			trng_clrset32(trng->cfg.addr, TRNG_CTRL,
1158 				      TRNG_CTRL_TRSSEN_MASK |
1159 				      TRNG_CTRL_EUMODE_MASK |
1160 				      TRNG_CTRL_PRNGXS_MASK,
1161 				      TRNG_CTRL_TRSSEN_MASK |
1162 				      TRNG_CTRL_EUMODE_MASK);
1163 		break;
1164 	}
1165 
1166 	if (trng_collect_random(trng, p, len))
1167 		goto error;
1168 
1169 	trng->stats.bytes_reseed += len;
1170 	trng->stats.bytes += len;
1171 	trng->stats.elapsed_seed_life++;
1172 
1173 	if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1 &&
1174 	    !trng->usr_cfg.df_disable && trng->usr_cfg.mode == TRNG_PTRNG)
1175 		trng_df_algorithm(trng, buf, DF_RAND, NULL);
1176 
1177 	return TEE_SUCCESS;
1178 error:
1179 	if (trng->status != TRNG_CATASTROPHIC)
1180 		trng->status = TRNG_ERROR;
1181 
1182 	return TEE_ERROR_GENERIC;
1183 }
1184 
trng_release(struct versal_trng * trng)1185 static TEE_Result trng_release(struct versal_trng *trng)
1186 {
1187 	if (!trng)
1188 		return TEE_ERROR_GENERIC;
1189 
1190 	if (trng->status == TRNG_UNINITIALIZED)
1191 		goto error;
1192 
1193 	trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, NULL);
1194 	trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS, NULL);
1195 	trng_hold_reset(trng);
1196 
1197 	/* Clear the instance */
1198 	memset(&trng->usr_cfg, 0, sizeof(trng->usr_cfg));
1199 	memset(trng->buf, 0, sizeof(trng->buf));
1200 	memset(trng->dfout, 0, sizeof(trng->dfout));
1201 	trng->status = TRNG_UNINITIALIZED;
1202 
1203 	return TEE_SUCCESS;
1204 error:
1205 	trng->status = TRNG_ERROR;
1206 
1207 	return TEE_ERROR_GENERIC;
1208 }
1209 
1210 /* Health tests should be run when the configured mode is of PTRNG or HRNG */
trng_health_test(struct versal_trng * trng)1211 static TEE_Result trng_health_test(struct versal_trng *trng)
1212 {
1213 	struct trng_usr_cfg tests = {
1214 		.mode = TRNG_HRNG,
1215 		.seed_life = 10,
1216 		.dfmul = 7,
1217 		.predict_en = false,
1218 		.iseed_en = false,
1219 		.pstr_en = false,
1220 		.df_disable = false,
1221 	};
1222 
1223 	if (trng_instantiate(trng, &tests))
1224 		goto error;
1225 
1226 	if (trng_release(trng))
1227 		goto error;
1228 
1229 	return TEE_SUCCESS;
1230 error:
1231 	trng->status = TRNG_ERROR;
1232 
1233 	return TEE_ERROR_GENERIC;
1234 }
1235 
1236 const uint8_t trng_pers_str[TRNG_PERS_STR_LEN] = {
1237 	0xB2U, 0x80U, 0x7EU, 0x4CU, 0xD0U, 0xE4U, 0xE2U, 0xA9U,
1238 	0x2FU, 0x1FU, 0x5DU, 0xC1U, 0xA2U, 0x1FU, 0x40U, 0xFCU,
1239 	0x1FU, 0x24U, 0x5DU, 0x42U, 0x61U, 0x80U, 0xE6U, 0xE9U,
1240 	0x71U, 0x05U, 0x17U, 0x5BU, 0xAFU, 0x70U, 0x30U, 0x18U,
1241 	0xBCU, 0x23U, 0x18U, 0x15U, 0xCBU, 0xB8U, 0xA6U, 0x3EU,
1242 	0x83U, 0xB8U, 0x4AU, 0xFEU, 0x38U, 0xFCU, 0x25U, 0x87U,
1243 };
1244 
1245 #ifdef CFG_VERSAL_RNG_V1
1246 static const uint8_t trng_ext_seed[TRNG_SEED_LEN] = {
1247 	0x3BU, 0xC3U, 0xEDU, 0x64U, 0xF4U, 0x80U, 0x1CU, 0xC7U,
1248 	0x14U, 0xCCU, 0x35U, 0xEDU, 0x57U, 0x01U, 0x2AU, 0xE4U,
1249 	0xBCU, 0xEFU, 0xDEU, 0xF6U, 0x7CU, 0x46U, 0xA6U, 0x34U,
1250 	0xC6U, 0x79U, 0xE8U, 0x91U, 0x5DU, 0xB1U, 0xDBU, 0xA7U,
1251 	0x49U, 0xA5U, 0xBBU, 0x4FU, 0xEDU, 0x30U, 0xB3U, 0x7BU,
1252 	0xA9U, 0x8BU, 0xF5U, 0x56U, 0x4DU, 0x40U, 0x18U, 0x9FU,
1253 };
1254 
1255 static const uint8_t trng_ext_reseed[TRNG_SEED_LEN] = {
1256 	0xFDU, 0x85U, 0xA8U, 0x36U, 0xBBU, 0xA8U, 0x50U, 0x19U,
1257 	0x88U, 0x1EU, 0x8CU, 0x6BU, 0xADU, 0x23U, 0xC9U, 0x06U,
1258 	0x1AU, 0xDCU, 0x75U, 0x47U, 0x76U, 0x59U, 0xACU, 0xAEU,
1259 	0xA8U, 0xE4U, 0xA0U, 0x1DU, 0xFEU, 0x07U, 0xA1U, 0x83U,
1260 	0x2DU, 0xADU, 0x1CU, 0x13U, 0x6FU, 0x59U, 0xD7U, 0x0FU,
1261 	0x86U, 0x53U, 0xA5U, 0xDCU, 0x11U, 0x86U, 0x63U, 0xD6U,
1262 };
1263 
1264 static const uint8_t trng_expected_out[TRNG_GEN_LEN] = {
1265 	0xEBU, 0xF6U, 0x97U, 0x6EU, 0x7EU, 0xF0U, 0x4AU, 0x34U,
1266 	0xEEU, 0xF6U, 0xA8U, 0x1AU, 0x67U, 0x33U, 0xF2U, 0x3CU,
1267 	0x27U, 0x24U, 0x7AU, 0x6DU, 0x0EU, 0x12U, 0xD7U, 0x42U,
1268 	0x73U, 0xEDU, 0xDDU, 0x3FU, 0x07U, 0x23U, 0xD8U, 0x52U,
1269 };
1270 #endif
1271 
1272 #ifdef CFG_VERSAL_RNG_V2
1273 #define TRNG_V2_KAT_SEED_LIFE 2
1274 #define TRNG_V2_KAT_DF_LEN 7
1275 #define TRNG_V2_KAT_SEED_LEN ((TRNG_V2_KAT_DF_LEN + 1) * BYTES_PER_BLOCK)
1276 
1277 static const uint8_t trng_v2_ext_seed[TRNG_V2_KAT_SEED_LEN] = {
1278 	0x3BU, 0xC3U, 0xEDU, 0x64U, 0xF4U, 0x80U, 0x1CU, 0xC7U,
1279 	0x14U, 0xCCU, 0x35U, 0xEDU, 0x57U, 0x01U, 0x2AU, 0xE4U,
1280 	0xBCU, 0xEFU, 0xDEU, 0xF6U, 0x7CU, 0x46U, 0xA6U, 0x34U,
1281 	0xC6U, 0x79U, 0xE8U, 0x91U, 0x5DU, 0xB1U, 0xDBU, 0xA7U,
1282 	0x49U, 0xA5U, 0xBBU, 0x4FU, 0xEDU, 0x30U, 0xB3U, 0x7BU,
1283 	0xA9U, 0x8BU, 0xF5U, 0x56U, 0x4DU, 0x40U, 0x18U, 0x9FU,
1284 	0x66U, 0x4EU, 0x39U, 0xC0U, 0x60U, 0xC8U, 0x8EU, 0xF4U,
1285 	0x1CU, 0xB9U, 0x9DU, 0x7BU, 0x97U, 0x8BU, 0x69U, 0x62U,
1286 	0x45U, 0x0CU, 0xD4U, 0x85U, 0xFCU, 0xDCU, 0x5AU, 0x2BU,
1287 	0xFDU, 0xABU, 0x92U, 0x4AU, 0x12U, 0x52U, 0x7DU, 0x45U,
1288 	0xD2U, 0x61U, 0x0AU, 0x06U, 0x74U, 0xA7U, 0x88U, 0x36U,
1289 	0x4BU, 0xA2U, 0x65U, 0xEEU, 0x71U, 0x0BU, 0x5AU, 0x4EU,
1290 	0x33U, 0xB2U, 0x7AU, 0x2EU, 0xC0U, 0xA6U, 0xF2U, 0x7DU,
1291 	0xBDU, 0x7DU, 0xDFU, 0x07U, 0xBBU, 0xE2U, 0x86U, 0xFFU,
1292 	0xF0U, 0x8EU, 0xA4U, 0xB1U, 0x46U, 0xDBU, 0xF7U, 0x8CU,
1293 	0x3CU, 0x62U, 0x4DU, 0xF0U, 0x51U, 0x50U, 0xE7U, 0x85U
1294 };
1295 
1296 static const uint8_t trng_v2_ext_reseed[TRNG_V2_KAT_SEED_LEN] = {
1297 	0xDFU, 0x5EU, 0x4DU, 0x4FU, 0x38U, 0x9EU, 0x2AU, 0x3EU,
1298 	0xF2U, 0xABU, 0x46U, 0xE3U, 0xA0U, 0x26U, 0x77U, 0x84U,
1299 	0x0BU, 0x9DU, 0x29U, 0xB0U, 0x5DU, 0xCEU, 0xC8U, 0xC3U,
1300 	0xF9U, 0x4DU, 0x32U, 0xF7U, 0xBAU, 0x6FU, 0xA3U, 0xB5U,
1301 	0x35U, 0xCBU, 0xC7U, 0x5CU, 0x62U, 0x48U, 0x01U, 0x65U,
1302 	0x3AU, 0xAAU, 0x34U, 0x2DU, 0x89U, 0x6EU, 0xEFU, 0x6FU,
1303 	0x69U, 0x96U, 0xE7U, 0x84U, 0xDAU, 0xEFU, 0x4EU, 0xBEU,
1304 	0x27U, 0x4EU, 0x9FU, 0x88U, 0xB1U, 0xA0U, 0x7FU, 0x83U,
1305 	0xDBU, 0x4AU, 0xA9U, 0x42U, 0x01U, 0xF1U, 0x84U, 0x71U,
1306 	0xA9U, 0xEFU, 0xB9U, 0xE8U, 0x7FU, 0x81U, 0xC7U, 0xC1U,
1307 	0x6CU, 0x5EU, 0xACU, 0x00U, 0x47U, 0x34U, 0xA1U, 0x75U,
1308 	0xC0U, 0xE8U, 0x7FU, 0x48U, 0x00U, 0x45U, 0xC9U, 0xE9U,
1309 	0x41U, 0xE3U, 0x8DU, 0xD8U, 0x4AU, 0x63U, 0xC4U, 0x94U,
1310 	0x77U, 0x59U, 0xD9U, 0x50U, 0x2AU, 0x1DU, 0x4CU, 0x47U,
1311 	0x64U, 0xA6U, 0x66U, 0x60U, 0x16U, 0xE7U, 0x29U, 0xC0U,
1312 	0xB1U, 0xCFU, 0x3BU, 0x3FU, 0x54U, 0x49U, 0x31U, 0xD4U
1313 };
1314 
1315 static const uint8_t trng_v2_expected_out[TRNG_SEC_STRENGTH_LEN] = {
1316 	0xEEU, 0xA7U, 0x5BU, 0xB6U, 0x2BU, 0x97U, 0xF0U, 0xC0U,
1317 	0x0FU, 0xD6U, 0xABU, 0x13U, 0x00U, 0x87U, 0x7EU, 0xF4U,
1318 	0x00U, 0x7FU, 0xD7U, 0x56U, 0xFEU, 0xE5U, 0xDFU, 0xA6U,
1319 	0x55U, 0x5BU, 0xB2U, 0x86U, 0xDDU, 0x81U, 0x73U, 0xB2U
1320 };
1321 #endif
1322 
trng_kat_test(struct versal_trng * trng)1323 static TEE_Result trng_kat_test(struct versal_trng *trng)
1324 {
1325 	struct trng_usr_cfg tests = {
1326 		.mode = TRNG_DRNG,
1327 		.seed_life = 5,
1328 		.dfmul = 2,
1329 		.predict_en = false,
1330 		.iseed_en = true,
1331 		.pstr_en = true,
1332 		.df_disable = false,
1333 	};
1334 	uint32_t seed_len = TRNG_SEED_LEN;
1335 	const uint8_t *ext_seed = NULL;
1336 	const uint8_t *ext_reseed = NULL;
1337 	const uint8_t *expected_out = NULL;
1338 	uint8_t out[TRNG_GEN_LEN] = { 0 };
1339 
1340 	if (!trng)
1341 		return TEE_ERROR_GENERIC;
1342 
1343 #ifdef CFG_VERSAL_RNG_V1
1344 	if (trng->cfg.version == TRNG_V1) {
1345 		ext_seed = trng_ext_seed;
1346 		ext_reseed = trng_ext_reseed;
1347 		expected_out = trng_expected_out;
1348 	}
1349 #endif
1350 
1351 #ifdef CFG_VERSAL_RNG_V2
1352 	if (trng->cfg.version == TRNG_V2) {
1353 		tests.seed_life = TRNG_V2_KAT_SEED_LIFE;
1354 		tests.dfmul = TRNG_V2_KAT_DF_LEN;
1355 
1356 		seed_len = TRNG_V2_KAT_SEED_LEN;
1357 		ext_seed = trng_v2_ext_seed;
1358 		ext_reseed = trng_v2_ext_reseed;
1359 		expected_out = trng_v2_expected_out;
1360 	}
1361 #endif
1362 
1363 	memcpy(&tests.init_seed, ext_seed, seed_len);
1364 	memcpy(tests.pstr, trng_pers_str, sizeof(trng_pers_str));
1365 
1366 	if (trng_instantiate(trng, &tests))
1367 		goto error;
1368 
1369 	if (trng_reseed(trng, (uint8_t *)ext_reseed, tests.dfmul))
1370 		goto error;
1371 
1372 	if (trng_generate(trng, out, sizeof(out), false))
1373 		goto error;
1374 
1375 	if (memcmp(out, expected_out, TRNG_GEN_LEN)) {
1376 		EMSG("K.A.T mismatch");
1377 		goto error;
1378 	}
1379 
1380 	if (trng_release(trng))
1381 		goto error;
1382 
1383 	return TEE_SUCCESS;
1384 error:
1385 	trng->status = TRNG_ERROR;
1386 	return TEE_ERROR_GENERIC;
1387 }
1388 
versal_trng_get_random_bytes(struct versal_trng * trng,void * buf,size_t len)1389 TEE_Result versal_trng_get_random_bytes(struct versal_trng *trng,
1390 					void *buf, size_t len)
1391 {
1392 	uint8_t random[TRNG_SEC_STRENGTH_LEN] = { 0 };
1393 	uint8_t *p = buf;
1394 	size_t i = 0;
1395 
1396 	for (i = 0; i < len / TRNG_SEC_STRENGTH_LEN; i++) {
1397 		if (trng_generate(trng, p + i * TRNG_SEC_STRENGTH_LEN,
1398 				  TRNG_SEC_STRENGTH_LEN, false))
1399 			panic();
1400 	}
1401 
1402 	if (len % TRNG_SEC_STRENGTH_LEN) {
1403 		if (trng_generate(trng, random, TRNG_SEC_STRENGTH_LEN,
1404 				  false))
1405 			panic();
1406 		memcpy(p + i * TRNG_SEC_STRENGTH_LEN, random,
1407 		       len % TRNG_SEC_STRENGTH_LEN);
1408 	}
1409 
1410 	return TEE_SUCCESS;
1411 }
1412 
versal_trng_hw_init(struct versal_trng * trng,struct trng_usr_cfg * usr_cfg)1413 TEE_Result versal_trng_hw_init(struct versal_trng *trng,
1414 			       struct trng_usr_cfg *usr_cfg)
1415 {
1416 	trng->cfg.addr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC,
1417 						       trng->cfg.base,
1418 						       trng->cfg.len);
1419 	if (!trng->cfg.addr) {
1420 		EMSG("Failed to map TRNG");
1421 		panic();
1422 	}
1423 
1424 	if (trng_kat_test(trng)) {
1425 		EMSG("KAT Failed");
1426 		panic();
1427 	}
1428 
1429 	if (trng_health_test(trng)) {
1430 		EMSG("RunHealthTest Failed");
1431 		panic();
1432 	}
1433 
1434 	if (trng_instantiate(trng, usr_cfg)) {
1435 		EMSG("Driver instantiation Failed");
1436 		panic();
1437 	}
1438 
1439 	if (trng->usr_cfg.mode == TRNG_HRNG &&
1440 	    trng_reseed(trng, NULL, trng->usr_cfg.dfmul)) {
1441 		EMSG("Reseed Failed");
1442 		panic();
1443 	}
1444 
1445 	return TEE_SUCCESS;
1446 }
1447 #endif
1448 
1449 #ifdef CFG_VERSAL_RNG_PLM
1450 #define SEC_MODULE_SHIFT 8
1451 #define SEC_MODULE_ID 5
1452 
1453 #define CRYPTO_API_ID(__x) ((SEC_MODULE_ID << SEC_MODULE_SHIFT) | (__x))
1454 
1455 #define VERSAL_TRNG_GENERATE 22
1456 
1457 #define TRNG_SEC_STRENGTH_LEN 32
1458 
versal_plm_get_random_bytes(void * buf,size_t len)1459 static TEE_Result versal_plm_get_random_bytes(void *buf, size_t len)
1460 {
1461 	uint32_t low = 0;
1462 	uint32_t hi = 0;
1463 	struct versal_ipi_cmd cmd = { };
1464 	struct versal_mbox_mem p = { };
1465 	TEE_Result ret = TEE_SUCCESS;
1466 	uint32_t status = 0;
1467 	uint32_t offset = 0;
1468 
1469 	ret = versal_mbox_alloc(TRNG_SEC_STRENGTH_LEN, NULL, &p);
1470 	if (ret)
1471 		return ret;
1472 
1473 	cmd.data[0] = CRYPTO_API_ID(VERSAL_TRNG_GENERATE);
1474 	cmd.ibuf[0].mem = p;
1475 
1476 	reg_pair_from_64(virt_to_phys(p.buf), &hi, &low);
1477 	cmd.data[1] = low;
1478 	cmd.data[2] = hi;
1479 
1480 	while (len) {
1481 		uint32_t _len = (uint32_t)TRNG_SEC_STRENGTH_LEN;
1482 
1483 		if (len < TRNG_SEC_STRENGTH_LEN)
1484 			_len = (uint32_t)len;
1485 
1486 		cmd.data[3] = _len;
1487 
1488 		ret = versal_pmc_notify(&cmd, NULL, &status);
1489 		if (ret)
1490 			panic();
1491 
1492 		memcpy((uint8_t *)buf + offset, p.buf, _len);
1493 
1494 		offset += TRNG_SEC_STRENGTH_LEN;
1495 		len -= _len;
1496 	}
1497 
1498 	versal_mbox_free(&p);
1499 	return ret;
1500 }
1501 #endif
1502 
1503 #if !defined(PLATFORM_FLAVOR_net)
1504 
1505 #define TRNG_BASE            0xF1230000
1506 #define TRNG_SIZE            0x10000
1507 
1508 static struct versal_trng versal_trng = {
1509 	.cfg.base = TRNG_BASE,
1510 	.cfg.len = TRNG_SIZE,
1511 	.cfg.version = TRNG_V1,
1512 };
1513 
hw_get_random_bytes(void * buf,size_t len)1514 TEE_Result hw_get_random_bytes(void *buf, size_t len)
1515 {
1516 	return versal_trng_get_random_bytes(&versal_trng, buf, len);
1517 }
1518 
trng_hrng_mode_init(void)1519 static TEE_Result trng_hrng_mode_init(void)
1520 {
1521 	/* configure in hybrid mode with derivative function enabled */
1522 	struct trng_usr_cfg usr_cfg = {
1523 		.mode = TRNG_HRNG,
1524 		.seed_life = CFG_VERSAL_TRNG_SEED_LIFE,
1525 		.predict_en = false,
1526 		.df_disable = false,
1527 		.dfmul = CFG_VERSAL_TRNG_DF_MUL,
1528 		.iseed_en =  false,
1529 		.pstr_en = true,
1530 	};
1531 
1532 	memcpy(usr_cfg.pstr, trng_pers_str, sizeof(trng_pers_str));
1533 	return versal_trng_hw_init(&versal_trng, &usr_cfg);
1534 }
1535 
1536 early_init(trng_hrng_mode_init);
1537 
1538 #else
1539 
hw_get_random_bytes(void * buf,size_t len)1540 TEE_Result hw_get_random_bytes(void *buf, size_t len)
1541 {
1542 	return versal_plm_get_random_bytes(buf, len);
1543 }
1544 
1545 #endif
1546