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 #include <arm.h>
55 #include <crypto/crypto.h>
56 #include <initcall.h>
57 #include <io.h>
58 #include <kernel/delay.h>
59 #include <kernel/panic.h>
60 #include <mm/core_mmu.h>
61 #include <platform_config.h>
62 #include <rng_support.h>
63 #include <stdlib.h>
64 #include <string.h>
65 #include <tee/tee_cryp_utl.h>
66 #include <trace.h>
67 
68 #define TRNG_BASE            0xF1230000
69 #define TRNG_SIZE            0x10000
70 
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_PRNGSTART_MASK	BIT(5)
81 #define TRNG_CTRL_PRNGXS_MASK		BIT(3)
82 #define TRNG_CTRL_TRSSEN_MASK		BIT(2)
83 #define TRNG_CTRL_PRNGSRST_MASK		BIT(0)
84 #define TRNG_EXT_SEED_0			0x40
85 /*
86  * Below registers are not directly referenced in driver but are accessed
87  * with offset from TRNG_EXT_SEED_0
88  * Register: TRNG_EXT_SEED_1		0x00000044
89  * Register: TRNG_EXT_SEED_2		0x00000048
90  * Register: TRNG_EXT_SEED_3		0x0000004C
91  * Register: TRNG_EXT_SEED_4		0x00000050
92  * Register: TRNG_EXT_SEED_5		0x00000054
93  * Register: TRNG_EXT_SEED_6		0x00000058
94  * Register: TRNG_EXT_SEED_7		0x0000005C
95  * Register: TRNG_EXT_SEED_8		0x00000060
96  * Register: TRNG_EXT_SEED_9		0x00000064
97  * Register: TRNG_EXT_SEED_10		0x00000068
98  * Register: TRNG_EXT_SEED_11		0x0000006C
99  */
100 #define TRNG_PER_STRING_0		0x80
101 /*
102  * Below registers are not directly referenced in driver but are accessed
103  * with offset from TRNG_PER_STRING_0
104  * Register: TRNG_PER_STRING_1		0x00000084
105  * Register: TRNG_PER_STRING_2		0x00000088
106  * Register: TRNG_PER_STRING_3		0x0000008C
107  * Register: TRNG_PER_STRING_4		0x00000090
108  * Register: TRNG_PER_STRING_5		0x00000094
109  * Register: TRNG_PER_STRING_6		0x00000098
110  * Register: TRNG_PER_STRING_7		0x0000009C
111  * Register: TRNG_PER_STRING_8		0x000000A0
112  * Register: TRNG_PER_STRING_9		0x000000A4
113  * Register: TRNG_PER_STRING_10		0x000000A8
114  * Register: TRNG_PER_STRING_11		0x000000AC
115  */
116 #define TRNG_CORE_OUTPUT		0xC0
117 #define TRNG_RESET			0xD0
118 #define TRNG_RESET_VAL_MASK		BIT(0)
119 #define TRNG_OSC_EN			0xD4
120 #define TRNG_OSC_EN_VAL_MASK		BIT(0)
121 
122 /* TRNG configuration  */
123 #define TRNG_BURST_SIZE		16
124 #define TRNG_BURST_SIZE_BITS	128
125 #define TRNG_NUM_INIT_REGS	12
126 #define TRNG_REG_SIZE		32
127 #define TRNG_BYTES_PER_REG	4
128 #define TRNG_MAX_QCNT		4
129 #define TRNG_RESEED_TIMEOUT	15000
130 #define TRNG_GENERATE_TIMEOUT	8000
131 #define TRNG_MIN_DFLENMULT	2
132 #define TRNG_MAX_DFLENMULT	9
133 #define PRNGMODE_RESEED		0
134 #define PRNGMODE_GEN		TRNG_CTRL_PRNGMODE_MASK
135 #define RESET_DELAY		10
136 #define TRNG_SEC_STRENGTH_LEN	32
137 #define TRNG_PERS_STR_REGS	12
138 #define TRNG_PERS_STR_LEN	48
139 #define TRNG_SEED_REGS		12
140 #define TRNG_SEED_LEN		48
141 #define TRNG_GEN_LEN		32
142 #define RAND_BUF_LEN		4
143 #define BYTES_PER_BLOCK		16
144 #define ALL_A_PATTERN_32	0xAAAAAAAA
145 #define ALL_5_PATTERN_32	0x55555555
146 
147 /* Derivative function helper macros */
148 #define DF_SEED			0
149 #define DF_RAND			1
150 #define DF_IP_IV_LEN		4
151 #define DF_PAD_DATA_LEN		8
152 #define MAX_PRE_DF_LEN		160
153 #define MAX_PRE_DF_LEN_WORDS	40
154 #define DF_PERS_STR_LEN		TRNG_PERS_STR_LEN
155 #define DF_PAD_VAL		0x80
156 #define DF_KEY_LEN		32
157 #define BLK_SIZE		16
158 #define MAX_ROUNDS		14
159 
160 enum trng_status {
161 	TRNG_UNINITIALIZED = 0,
162 	TRNG_HEALTHY,
163 	TRNG_ERROR,
164 	TRNG_CATASTROPHIC
165 };
166 
167 enum trng_mode {
168 	TRNG_HRNG = 0,
169 	TRNG_DRNG,
170 	TRNG_PTRNG
171 };
172 
173 struct trng_cfg {
174 	paddr_t base;
175 	vaddr_t addr;
176 	size_t len;
177 };
178 
179 struct trng_usr_cfg {
180 	enum trng_mode mode;
181 	uint64_t seed_life;      /* number of TRNG requests per seed */
182 	bool predict_en;         /* enable prediction resistance     */
183 	bool pstr_en;            /* enable personalization string    */
184 	uint32_t pstr[TRNG_PERS_STR_REGS];
185 	bool iseed_en;           /* enable an initial seed           */
186 	uint32_t init_seed[MAX_PRE_DF_LEN_WORDS];
187 	uint32_t df_disable;     /* disable the derivative function  */
188 	uint32_t dfmul;          /* derivative function multiplier   */
189 };
190 
191 struct trng_stats {
192 	uint64_t bytes;
193 	uint64_t bytes_reseed;
194 	uint64_t elapsed_seed_life;
195 };
196 
197 /* block cipher derivative function algorithm */
198 struct trng_dfin {
199 	uint32_t ivc[DF_IP_IV_LEN];
200 	uint32_t val1;
201 	uint32_t val2;
202 	uint8_t entropy[MAX_PRE_DF_LEN];    /* input entropy                */
203 	uint8_t pstr[DF_PERS_STR_LEN];      /* personalization string       */
204 	uint8_t pad_data[DF_PAD_DATA_LEN];  /* pad to multiples of 16 bytes*/
205 };
206 
207 struct versal_trng {
208 	struct trng_cfg cfg;
209 	struct trng_usr_cfg usr_cfg;
210 	struct trng_stats stats;
211 	enum trng_status status;
212 	uint32_t buf[RAND_BUF_LEN];   /* buffer of random bits      */
213 	size_t len;
214 	struct trng_dfin dfin;
215 	uint8_t dfout[TRNG_SEED_LEN]; /* output of the DF operation */
216 };
217 
218 /* Derivative function variables */
219 static unsigned char sbx1[256];
220 static unsigned char sbx2[256];
221 static unsigned char sbx3[256];
222 static unsigned char schedule[BLK_SIZE * (MAX_ROUNDS + 1)];
223 static unsigned int rounds;
224 
rota4(uint8_t * a,uint8_t * b,uint8_t * c,uint8_t * d)225 static void rota4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d)
226 {
227 	uint8_t t = *a;
228 
229 	*a = sbx1[*b];
230 	*b = sbx1[*c];
231 	*c = sbx1[*d];
232 	*d = sbx1[t];
233 }
234 
rota2(uint8_t * a,uint8_t * b)235 static void rota2(uint8_t *a, uint8_t *b)
236 {
237 	uint8_t t = *a;
238 
239 	*a = sbx1[*b];
240 	*b = sbx1[t];
241 }
242 
sbox4(uint8_t * a,uint8_t * b,uint8_t * c,uint8_t * d)243 static void sbox4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d)
244 {
245 	*a = sbx1[*a];
246 	*b = sbx1[*b];
247 	*c = sbx1[*c];
248 	*d = sbx1[*d];
249 }
250 
xorb(uint8_t * res,const uint8_t * in)251 static void xorb(uint8_t *res,  const uint8_t *in)
252 {
253 	size_t i = 0;
254 
255 	for (i = 0; i < BLK_SIZE; ++i)
256 		res[i] ^= in[i];
257 }
258 
set_key(uint8_t * res,const uint8_t * src,unsigned int roundval)259 static void set_key(uint8_t *res, const uint8_t *src, unsigned int roundval)
260 {
261 	memcpy(res, src, BLK_SIZE);
262 	xorb(res, schedule + roundval * BLK_SIZE);
263 }
264 
mix_column_sbox(uint8_t * dst,const uint8_t * f)265 static void mix_column_sbox(uint8_t *dst, const uint8_t *f)
266 {
267 	size_t i = 0;
268 	size_t a = 0;
269 	size_t b = 0;
270 	size_t c = 0;
271 	size_t d = 0;
272 
273 	for (i = 0; i < 4; i++) {
274 		a = 4 * i;
275 		b = (0x5 + a) % 16;
276 		c = (0xa + a) % 16;
277 		d = (0xf + a) % 16;
278 		dst[0 + a] = sbx2[f[a]] ^ sbx3[f[b]] ^ sbx1[f[c]] ^ sbx1[f[d]];
279 		dst[1 + a] = sbx1[f[a]] ^ sbx2[f[b]] ^ sbx3[f[c]] ^ sbx1[f[d]];
280 		dst[2 + a] = sbx1[f[a]] ^ sbx1[f[b]] ^ sbx2[f[c]] ^ sbx3[f[d]];
281 		dst[3 + a] = sbx3[f[a]] ^ sbx1[f[b]] ^ sbx1[f[c]] ^ sbx2[f[d]];
282 	}
283 }
284 
shift_row_sbox(uint8_t * f)285 static void shift_row_sbox(uint8_t *f)
286 {
287 	sbox4(&f[0], &f[4], &f[8], &f[12]);
288 	rota4(&f[1], &f[5], &f[9], &f[13]);
289 	rota2(&f[2], &f[10]);
290 	rota2(&f[6], &f[14]);
291 	rota4(&f[15], &f[11], &f[7], &f[3]);
292 }
293 
encrypt(uint8_t * in,uint8_t * out)294 static void encrypt(uint8_t *in, uint8_t *out)
295 {
296 	uint8_t fa[BLK_SIZE] = { 0 };
297 	uint8_t fb[BLK_SIZE] = { 0 };
298 	size_t roundval = 0;
299 
300 	set_key(fa, in, 0);
301 	for (roundval = 1; roundval < rounds; ++roundval) {
302 		mix_column_sbox(fb, fa);
303 		set_key(fa, fb, roundval);
304 	}
305 
306 	shift_row_sbox(fa);
307 	set_key(out, fa, roundval);
308 }
309 
checksum(unsigned char * in,uint8_t * iv,int max_blk)310 static void checksum(unsigned char *in, uint8_t *iv, int max_blk)
311 {
312 	while (max_blk > 0) {
313 		xorb(iv, in);
314 		encrypt(iv, iv);
315 		in += BLK_SIZE;
316 		max_blk -= 1;
317 	}
318 }
319 
setup_key(const unsigned char * k,size_t klen)320 static void setup_key(const unsigned char *k, size_t klen)
321 {
322 	unsigned char rcon = 1;
323 	size_t sch_size = 240;
324 	size_t i = 0;
325 
326 	rounds = MAX_ROUNDS;
327 	memcpy(schedule, k, klen);
328 	for (i = klen; i < sch_size; i += 4) {
329 		unsigned char t0 = 0;
330 		unsigned char t1 = 0;
331 		unsigned char t2 = 0;
332 		unsigned char t3 = 0;
333 		int ik = 0;
334 
335 		t0 = schedule[i - 4];
336 		t1 = schedule[i - 3];
337 		t2 = schedule[i - 2];
338 		t3 = schedule[i - 1];
339 		if (i % klen == 0) {
340 			rota4(&t0, &t1, &t2, &t3);
341 			t0 ^= rcon;
342 			rcon = (rcon << 1) ^ (((rcon >> 7) & 1) * 0x1B);
343 		} else if (i % klen == 16) {
344 			sbox4(&t0, &t1, &t2, &t3);
345 		}
346 		ik = i - klen;
347 		schedule[i + 0] = schedule[ik + 0] ^ t0;
348 		schedule[i + 1] = schedule[ik + 1] ^ t1;
349 		schedule[i + 2] = schedule[ik + 2] ^ t2;
350 		schedule[i + 3] = schedule[ik + 3] ^ t3;
351 	}
352 }
353 
trng_df_init(void)354 static void trng_df_init(void)
355 {
356 	const uint8_t sb[] = {
357 		0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01,
358 		0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d,
359 		0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4,
360 		0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
361 		0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7,
362 		0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
363 		0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e,
364 		0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
365 		0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb,
366 		0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb,
367 		0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c,
368 		0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
369 		0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c,
370 		0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d,
371 		0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a,
372 		0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
373 		0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3,
374 		0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
375 		0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a,
376 		0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
377 		0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e,
378 		0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9,
379 		0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9,
380 		0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
381 		0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99,
382 		0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
383 	};
384 	size_t i = 0;
385 
386 	memcpy(sbx1, sb, sizeof(sb));
387 	for (i = 0; i < sizeof(sb); i++) {
388 		sbx2[i] = (sb[i] << 1) ^ (((sb[i] >> 7) & 1) * 0x1B);
389 		sbx3[i] = sbx2[i] ^ sb[i];
390 	}
391 }
392 
393 /*
394  * This function implements the Derivative Function by distilling the entropy
395  * available in its input into a smaller number of bits on the output.
396  * - per NIST SP80090A.
397  *
398  * The Block Cipher algorithm follows sections 10.3.2 and 10.3.3 of the
399  * NIST.SP.800-90Ar1 document
400  */
trng_df_algorithm(struct versal_trng * trng,uint8_t * dfout,uint32_t flag,const uint8_t * pstr)401 static void trng_df_algorithm(struct versal_trng *trng, uint8_t *dfout,
402 			      uint32_t flag, const uint8_t *pstr)
403 {
404 	static bool df_init;
405 	const uint8_t df_key[DF_KEY_LEN] = {
406 		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
407 		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
408 	};
409 	size_t dfin_len = sizeof(struct trng_dfin) + trng->len;
410 	uint8_t *inp_blk = NULL;
411 	uint8_t *out_blk = NULL;
412 	uintptr_t reminder = 0;
413 	size_t xfer_len = 0;
414 	uint32_t index = 0;
415 	uintptr_t src = 0;
416 	uintptr_t dst = 0;
417 	size_t offset = 0;
418 
419 	if (!df_init) {
420 		trng_df_init();
421 		df_init = true;
422 	}
423 
424 	if (flag == DF_SEED)
425 		trng->dfin.val2 = TEE_U32_TO_BIG_ENDIAN(TRNG_PERS_STR_LEN);
426 	else
427 		trng->dfin.val2 = TEE_U32_TO_BIG_ENDIAN(TRNG_GEN_LEN);
428 
429 	trng->dfin.pad_data[0] = DF_PAD_VAL;
430 
431 	if (!pstr) {
432 		if (trng->len > (MAX_PRE_DF_LEN + TRNG_PERS_STR_LEN))
433 			panic();
434 
435 		dfin_len = dfin_len - TRNG_PERS_STR_LEN - MAX_PRE_DF_LEN;
436 		trng->dfin.val1 = TEE_U32_TO_BIG_ENDIAN(trng->len);
437 
438 		xfer_len = DF_PAD_DATA_LEN;
439 		src = (uintptr_t)trng->dfin.pad_data;
440 		offset = MAX_PRE_DF_LEN + TRNG_PERS_STR_LEN - trng->len;
441 	} else {
442 		if (trng->len > MAX_PRE_DF_LEN)
443 			panic();
444 
445 		memcpy(trng->dfin.pstr, pstr, TRNG_PERS_STR_LEN);
446 		dfin_len = dfin_len - MAX_PRE_DF_LEN;
447 		trng->dfin.val1 = TEE_U32_TO_BIG_ENDIAN(trng->len +
448 							TRNG_PERS_STR_LEN);
449 		xfer_len = DF_PAD_DATA_LEN + TRNG_PERS_STR_LEN;
450 		src = (uintptr_t)trng->dfin.pstr;
451 		offset = MAX_PRE_DF_LEN - trng->len;
452 	}
453 
454 	/* Move back into the dfin structure */
455 	dst = src - offset;
456 	reminder = (uintptr_t)&trng->dfin + sizeof(trng->dfin) - offset;
457 	if (offset) {
458 		if (xfer_len > offset)
459 			panic("Overlapping data");
460 
461 		memcpy((void *)dst, (void *)src, xfer_len);
462 		memset((void *)reminder, 0, offset);
463 	}
464 
465 	/* DF algorithm - step 1 */
466 	setup_key(df_key, DF_KEY_LEN);
467 	for (index = 0; index < TRNG_SEED_LEN; index += BLK_SIZE) {
468 		memset((void *)(trng->dfout + index), 0, BLK_SIZE);
469 		trng->dfin.ivc[0] = TEE_U32_TO_BIG_ENDIAN(index / BLK_SIZE);
470 		checksum((unsigned char *)&trng->dfin,
471 			 trng->dfout + index, dfin_len / BLK_SIZE);
472 	}
473 
474 	/* DF algorithm - step 2 */
475 	setup_key(trng->dfout, DF_KEY_LEN);
476 	for (index = 0; index < TRNG_SEED_LEN; index += BLK_SIZE) {
477 		if (!index)
478 			inp_blk = &dfout[TRNG_SEC_STRENGTH_LEN];
479 		else
480 			inp_blk = &dfout[index - BLK_SIZE];
481 
482 		out_blk = &dfout[index];
483 		encrypt(inp_blk, out_blk);
484 	}
485 }
486 
trng_read32(vaddr_t addr,size_t off)487 static uint32_t trng_read32(vaddr_t addr, size_t off)
488 {
489 	return io_read32(addr + off);
490 }
491 
trng_write32(vaddr_t addr,size_t off,uint32_t val)492 static void trng_write32(vaddr_t addr, size_t off, uint32_t val)
493 {
494 	io_write32(addr + off, val);
495 }
496 
trng_clrset32(vaddr_t addr,size_t off,uint32_t mask,uint32_t val)497 static void trng_clrset32(vaddr_t addr, size_t off, uint32_t mask, uint32_t val)
498 {
499 	io_clrsetbits32(addr + off, mask, mask & val);
500 }
501 
trng_write32_range(const struct versal_trng * trng,uint32_t start,uint32_t num_regs,const uint8_t * buf)502 static void trng_write32_range(const struct versal_trng *trng, uint32_t start,
503 			       uint32_t num_regs, const uint8_t *buf)
504 {
505 	size_t off = 0;
506 	uint32_t val = 0;
507 	size_t cnt = 0;
508 	size_t i = 0;
509 
510 	for (i = 0; i < num_regs; ++i) {
511 		if (!buf) {
512 			off = start + i * TRNG_BYTES_PER_REG;
513 			trng_write32(trng->cfg.addr, off, 0);
514 			continue;
515 		}
516 
517 		val = 0;
518 		for (cnt = 0; cnt < TRNG_BYTES_PER_REG; ++cnt)
519 			val = (val << 8) | buf[i * TRNG_BYTES_PER_REG + cnt];
520 
521 		off = start + (TRNG_NUM_INIT_REGS - 1 - i) * TRNG_BYTES_PER_REG;
522 		trng_write32(trng->cfg.addr, off, val);
523 	}
524 }
525 
trng_wait_for_event(vaddr_t addr,size_t off,uint32_t mask,uint32_t event,uint32_t time_out)526 static TEE_Result trng_wait_for_event(vaddr_t addr, size_t off, uint32_t mask,
527 				      uint32_t event, uint32_t time_out)
528 {
529 	uint64_t tref = timeout_init_us(time_out);
530 
531 	do {
532 		if (timeout_elapsed(tref))
533 			break;
534 	} while ((io_read32(addr + off) & mask) != event);
535 
536 	/* Normal world might have suspended the OP-TEE thread, check again  */
537 	if ((io_read32(addr + off) & mask) != event)
538 		return TEE_ERROR_GENERIC;
539 
540 	return TEE_SUCCESS;
541 }
542 
trng_soft_reset(const struct versal_trng * trng)543 static void trng_soft_reset(const struct versal_trng *trng)
544 {
545 	trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSRST_MASK,
546 		      TRNG_CTRL_PRNGSRST_MASK);
547 	udelay(RESET_DELAY);
548 	trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSRST_MASK, 0);
549 }
550 
trng_reset(const struct versal_trng * trng)551 static void trng_reset(const struct versal_trng *trng)
552 {
553 	trng_write32(trng->cfg.addr, TRNG_RESET, TRNG_RESET_VAL_MASK);
554 	udelay(RESET_DELAY);
555 	trng_write32(trng->cfg.addr, TRNG_RESET, 0);
556 	trng_soft_reset(trng);
557 }
558 
trng_hold_reset(const struct versal_trng * trng)559 static void trng_hold_reset(const struct versal_trng *trng)
560 {
561 	trng_clrset32(trng->cfg.addr, TRNG_CTRL,
562 		      TRNG_CTRL_PRNGSRST_MASK, TRNG_CTRL_PRNGSRST_MASK);
563 	trng_write32(trng->cfg.addr, TRNG_RESET, TRNG_RESET_VAL_MASK);
564 	udelay(RESET_DELAY);
565 }
566 
trng_check_seed(uint8_t * entropy,uint32_t len)567 static TEE_Result trng_check_seed(uint8_t *entropy, uint32_t len)
568 {
569 	uint32_t *p = (void *)entropy;
570 	size_t i = 0;
571 
572 	for (i = 0; i < len / sizeof(*p); i++) {
573 		if (p[i] == ALL_A_PATTERN_32)
574 			return TEE_ERROR_GENERIC;
575 
576 		if (p[i] == ALL_5_PATTERN_32)
577 			return TEE_ERROR_GENERIC;
578 	}
579 
580 	return TEE_SUCCESS;
581 }
582 
trng_collect_random(struct versal_trng * trng,uint8_t * dst,size_t len)583 static TEE_Result trng_collect_random(struct versal_trng *trng, uint8_t *dst,
584 				      size_t len)
585 {
586 	const size_t bursts = len / TRNG_BURST_SIZE;
587 	const size_t words = TRNG_BURST_SIZE_BITS / TRNG_REG_SIZE;
588 	uint32_t *p = (void *)dst;
589 	size_t bcnt = 0;
590 	size_t wcnt = 0;
591 	size_t index = 0;
592 	uint32_t val = 0;
593 	bool match = false;
594 
595 	trng_clrset32(trng->cfg.addr, TRNG_CTRL,
596 		      TRNG_CTRL_PRNGSTART_MASK, TRNG_CTRL_PRNGSTART_MASK);
597 
598 	/*
599 	 * Loop as many times based on len requested. In each burst 128 bits
600 	 * are generated, which is reflected in QCNT value of 4 by hardware.
601 	 */
602 	for (bcnt = 0; bcnt < bursts; bcnt++) {
603 		if (trng_wait_for_event(trng->cfg.addr,
604 					TRNG_STATUS, TRNG_STATUS_QCNT_MASK,
605 					TRNG_MAX_QCNT << TRNG_STATUS_QCNT_SHIFT,
606 					TRNG_GENERATE_TIMEOUT)) {
607 			EMSG("Timeout waiting for randomness");
608 			return TEE_ERROR_GENERIC;
609 		}
610 
611 		/*
612 		 * DTF flag set during generate indicates catastrophic
613 		 * condition, which needs to be checked for every time unless we
614 		 * are in PTRNG mode
615 		 */
616 		if (trng->usr_cfg.mode != TRNG_PTRNG) {
617 			val = trng_read32(trng->cfg.addr, TRNG_STATUS);
618 			if (val & TRNG_STATUS_DTF_MASK) {
619 				EMSG("Catastrophic DFT error");
620 				trng->status = TRNG_CATASTROPHIC;
621 
622 				return TEE_ERROR_GENERIC;
623 			}
624 		}
625 		/*
626 		 * Read the core output register 4 times to consume the random
627 		 * data generated for every burst.
628 		 */
629 		match = true;
630 		for (wcnt = 0; wcnt < words; wcnt++) {
631 			val = trng_read32(trng->cfg.addr, TRNG_CORE_OUTPUT);
632 
633 			if (bcnt > 0 && trng->buf[wcnt] != val)
634 				match = false;
635 
636 			trng->buf[wcnt] = val;
637 
638 			if (dst) {
639 				p[index] = TEE_U32_TO_BIG_ENDIAN(val);
640 				index++;
641 			}
642 		}
643 
644 		if (bursts > 1 && bcnt > 0 && match) {
645 			EMSG("Catastrophic software error");
646 			trng->status = TRNG_CATASTROPHIC;
647 			return TEE_ERROR_GENERIC;
648 		}
649 	}
650 
651 	return TEE_SUCCESS;
652 }
653 
trng_reseed_internal_nodf(struct versal_trng * trng,uint8_t * eseed,uint8_t * str)654 static TEE_Result trng_reseed_internal_nodf(struct versal_trng *trng,
655 					    uint8_t *eseed, uint8_t *str)
656 {
657 	uint8_t entropy[TRNG_SEED_LEN] = { 0 };
658 	uint8_t *seed = NULL;
659 
660 	switch (trng->usr_cfg.mode) {
661 	case TRNG_HRNG:
662 		trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK);
663 		trng_soft_reset(trng);
664 		trng_write32(trng->cfg.addr, TRNG_CTRL,
665 			     TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK);
666 
667 		if (trng_collect_random(trng, entropy, TRNG_SEED_LEN))
668 			return TEE_ERROR_GENERIC;
669 
670 		if (trng_check_seed(entropy, TRNG_SEED_LEN))
671 			return TEE_ERROR_GENERIC;
672 
673 		seed = entropy;
674 		break;
675 	case TRNG_DRNG:
676 		seed = eseed;
677 		break;
678 	default:
679 		seed = NULL;
680 		break;
681 	}
682 
683 	trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, seed);
684 	if (str)
685 		trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS,
686 				   str);
687 
688 	return TEE_SUCCESS;
689 }
690 
trng_reseed_internal_df(struct versal_trng * trng,uint8_t * eseed,uint8_t * str)691 static TEE_Result trng_reseed_internal_df(struct versal_trng *trng,
692 					  uint8_t *eseed, uint8_t *str)
693 {
694 	memset(&trng->dfin, 0, sizeof(trng->dfin));
695 
696 	switch (trng->usr_cfg.mode) {
697 	case TRNG_HRNG:
698 		trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK);
699 		trng_soft_reset(trng);
700 		trng_write32(trng->cfg.addr, TRNG_CTRL,
701 			     TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK);
702 
703 		if (trng_collect_random(trng, trng->dfin.entropy, trng->len))
704 			return TEE_ERROR_GENERIC;
705 
706 		if (trng_check_seed(trng->dfin.entropy, trng->len))
707 			return TEE_ERROR_GENERIC;
708 		break;
709 	case TRNG_DRNG:
710 		memcpy(trng->dfin.entropy, eseed, trng->len);
711 		break;
712 	default:
713 		break;
714 	}
715 
716 	trng_df_algorithm(trng, trng->dfout, DF_SEED, str);
717 	trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, trng->dfout);
718 
719 	return TEE_SUCCESS;
720 }
721 
trng_reseed_internal(struct versal_trng * trng,uint8_t * eseed,uint8_t * str,uint32_t mul)722 static TEE_Result trng_reseed_internal(struct versal_trng *trng,
723 				       uint8_t *eseed, uint8_t *str,
724 				       uint32_t mul)
725 {
726 	uint32_t val = 0;
727 
728 	trng->stats.bytes_reseed = 0;
729 	trng->stats.elapsed_seed_life = 0;
730 
731 	if (trng->usr_cfg.df_disable)
732 		trng->len = TRNG_SEED_LEN;
733 	else
734 		trng->len = (mul + 1) * BYTES_PER_BLOCK;
735 
736 	if (trng->usr_cfg.df_disable) {
737 		if (trng_reseed_internal_nodf(trng, eseed, str))
738 			goto error;
739 	} else {
740 		if (trng_reseed_internal_df(trng, eseed, str))
741 			goto error;
742 	}
743 
744 	trng_write32(trng->cfg.addr, TRNG_CTRL,
745 		     PRNGMODE_RESEED | TRNG_CTRL_PRNGXS_MASK);
746 
747 	/* Start the reseed operation */
748 	trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSTART_MASK,
749 		      TRNG_CTRL_PRNGSTART_MASK);
750 
751 	if (trng_wait_for_event(trng->cfg.addr, TRNG_STATUS,
752 				TRNG_STATUS_DONE_MASK, TRNG_STATUS_DONE_MASK,
753 				TRNG_RESEED_TIMEOUT))
754 		goto error;
755 
756 	/* Check SP800 - 90B (entropy health test error) */
757 	val = trng_read32(trng->cfg.addr, TRNG_STATUS) & TRNG_STATUS_CERTF_MASK;
758 	if (val == TRNG_STATUS_CERTF_MASK)
759 		goto error;
760 
761 	trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSTART_MASK, 0);
762 	return TEE_SUCCESS;
763 error:
764 	trng->status = TRNG_ERROR;
765 	return TEE_ERROR_GENERIC;
766 }
767 
trng_instantiate(struct versal_trng * trng,const struct trng_usr_cfg * usr_cfg)768 static TEE_Result trng_instantiate(struct versal_trng *trng,
769 				   const struct trng_usr_cfg *usr_cfg)
770 {
771 	uint8_t *seed = NULL;
772 	uint8_t *pers = NULL;
773 
774 	if (!trng)
775 		return TEE_ERROR_GENERIC;
776 
777 	if (!usr_cfg)
778 		goto error;
779 
780 	if (trng->status != TRNG_UNINITIALIZED)
781 		goto error;
782 
783 	if (usr_cfg->mode != TRNG_HRNG && usr_cfg->mode != TRNG_DRNG &&
784 	    usr_cfg->mode != TRNG_PTRNG)
785 		goto error;
786 
787 	if (usr_cfg->mode != TRNG_PTRNG && !usr_cfg->seed_life)
788 		goto error;
789 
790 	if (!usr_cfg->iseed_en && usr_cfg->mode == TRNG_DRNG)
791 		goto error;
792 
793 	if (usr_cfg->iseed_en && usr_cfg->mode == TRNG_HRNG)
794 		goto error;
795 
796 	if (!usr_cfg->df_disable &&
797 	    (usr_cfg->dfmul < TRNG_MIN_DFLENMULT ||
798 	     usr_cfg->dfmul > TRNG_MAX_DFLENMULT))
799 		goto error;
800 
801 	if (usr_cfg->df_disable && usr_cfg->dfmul)
802 		goto error;
803 
804 	if (usr_cfg->mode == TRNG_PTRNG &&
805 	    (usr_cfg->iseed_en || usr_cfg->pstr_en ||
806 	     usr_cfg->predict_en || usr_cfg->seed_life))
807 		goto error;
808 
809 	memcpy(&trng->usr_cfg, usr_cfg, sizeof(struct trng_usr_cfg));
810 	trng_reset(trng);
811 
812 	if (trng->usr_cfg.iseed_en)
813 		seed = (void *)trng->usr_cfg.init_seed;
814 
815 	if (trng->usr_cfg.pstr_en)
816 		pers = (void *)trng->usr_cfg.pstr;
817 
818 	if (trng->usr_cfg.mode != TRNG_PTRNG) {
819 		if (trng_reseed_internal(trng, seed, pers, trng->usr_cfg.dfmul))
820 			goto error;
821 	}
822 
823 	trng->status = TRNG_HEALTHY;
824 	return TEE_SUCCESS;
825 error:
826 	trng->status = TRNG_ERROR;
827 	return TEE_ERROR_GENERIC;
828 }
829 
trng_reseed(struct versal_trng * trng,uint8_t * eseed,uint32_t mul)830 static TEE_Result trng_reseed(struct versal_trng *trng, uint8_t *eseed,
831 			      uint32_t mul)
832 {
833 	if (!trng)
834 		return TEE_ERROR_GENERIC;
835 
836 	if (trng->status != TRNG_HEALTHY)
837 		goto error;
838 
839 	if (trng->usr_cfg.mode != TRNG_DRNG && trng->usr_cfg.mode != TRNG_HRNG)
840 		goto error;
841 
842 	if (trng->usr_cfg.mode == TRNG_DRNG && !eseed)
843 		goto error;
844 
845 	if (trng->usr_cfg.mode != TRNG_DRNG && eseed)
846 		goto error;
847 
848 	if (!trng->usr_cfg.df_disable) {
849 		if (mul < TRNG_MIN_DFLENMULT || mul > TRNG_MAX_DFLENMULT)
850 			goto error;
851 	}
852 
853 	if (trng->usr_cfg.df_disable && mul)
854 		goto error;
855 
856 	if (eseed && !memcmp(eseed, trng->usr_cfg.init_seed, trng->len))
857 		goto error;
858 
859 	if (trng_reseed_internal(trng, eseed, NULL, mul))
860 		goto error;
861 
862 	return TEE_SUCCESS;
863 error:
864 	trng->status = TRNG_ERROR;
865 	return TEE_ERROR_GENERIC;
866 }
867 
trng_generate(struct versal_trng * trng,uint8_t * buf,size_t blen,bool predict)868 static TEE_Result trng_generate(struct versal_trng *trng, uint8_t *buf,
869 				size_t blen, bool predict)
870 {
871 	uint32_t len = TRNG_SEC_STRENGTH_LEN;
872 	uint8_t *p = buf;
873 
874 	if (!trng)
875 		return TEE_ERROR_GENERIC;
876 
877 	if (!p)
878 		goto error;
879 
880 	if (blen < TRNG_SEC_STRENGTH_LEN)
881 		goto error;
882 
883 	if (trng->status != TRNG_HEALTHY)
884 		goto error;
885 
886 	if (trng->usr_cfg.mode == TRNG_PTRNG && predict)
887 		goto error;
888 
889 	if (!trng->usr_cfg.predict_en && predict)
890 		goto error;
891 
892 	switch (trng->usr_cfg.mode) {
893 	case TRNG_HRNG:
894 		if (trng->stats.elapsed_seed_life >= trng->usr_cfg.seed_life) {
895 			if (trng_reseed_internal(trng, NULL, NULL, 0))
896 				goto error;
897 		}
898 
899 		if (predict && trng->stats.elapsed_seed_life > 0) {
900 			if (trng_reseed_internal(trng, NULL, NULL, 0))
901 				goto error;
902 		}
903 
904 		trng_write32(trng->cfg.addr, TRNG_CTRL, PRNGMODE_GEN);
905 		break;
906 	case TRNG_DRNG:
907 		if (trng->stats.elapsed_seed_life > trng->usr_cfg.seed_life)
908 			goto error;
909 
910 		if (predict && trng->stats.elapsed_seed_life > 0)
911 			goto error;
912 
913 		trng_write32(trng->cfg.addr, TRNG_CTRL, PRNGMODE_GEN);
914 		break;
915 	default:
916 		if (!trng->usr_cfg.df_disable) {
917 			memset(&trng->dfin, 0, sizeof(trng->dfin));
918 			len = (trng->usr_cfg.dfmul + 1) * BYTES_PER_BLOCK;
919 			trng->len = len;
920 			p = trng->dfin.entropy;
921 		}
922 		/* Enable the 8 ring oscillators used for entropy source */
923 		trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK);
924 		trng_soft_reset(trng);
925 		trng_write32(trng->cfg.addr, TRNG_CTRL,
926 			     TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK);
927 		break;
928 	}
929 
930 	if (trng_collect_random(trng, p, len))
931 		goto error;
932 
933 	trng->stats.bytes_reseed += len;
934 	trng->stats.bytes += len;
935 	trng->stats.elapsed_seed_life++;
936 
937 	if (!trng->usr_cfg.df_disable && trng->usr_cfg.mode == TRNG_PTRNG)
938 		trng_df_algorithm(trng, buf, DF_RAND, NULL);
939 
940 	return TEE_SUCCESS;
941 error:
942 	if (trng->status != TRNG_CATASTROPHIC)
943 		trng->status = TRNG_ERROR;
944 
945 	return TEE_ERROR_GENERIC;
946 }
947 
trng_release(struct versal_trng * trng)948 static TEE_Result trng_release(struct versal_trng *trng)
949 {
950 	if (!trng)
951 		return TEE_ERROR_GENERIC;
952 
953 	if (trng->status == TRNG_UNINITIALIZED)
954 		goto error;
955 
956 	trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, NULL);
957 	trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS, NULL);
958 	trng_hold_reset(trng);
959 
960 	/* Clear the instance */
961 	memset(&trng->usr_cfg, 0, sizeof(trng->usr_cfg));
962 	memset(trng->buf, 0, sizeof(trng->buf));
963 	memset(trng->dfout, 0, sizeof(trng->dfout));
964 	trng->status = TRNG_UNINITIALIZED;
965 
966 	return TEE_SUCCESS;
967 error:
968 	trng->status = TRNG_ERROR;
969 
970 	return TEE_ERROR_GENERIC;
971 }
972 
973 /* Health tests should be run when the configured mode is of PTRNG or HRNG */
trng_health_test(struct versal_trng * trng)974 static TEE_Result trng_health_test(struct versal_trng *trng)
975 {
976 	struct trng_usr_cfg tests = {
977 		.mode = TRNG_HRNG,
978 		.seed_life = 10,
979 		.dfmul = 7,
980 		.predict_en = false,
981 		.iseed_en = false,
982 		.pstr_en = false,
983 		.df_disable = false,
984 	};
985 
986 	if (trng_instantiate(trng, &tests))
987 		goto error;
988 
989 	if (trng_release(trng))
990 		goto error;
991 
992 	return TEE_SUCCESS;
993 error:
994 	trng->status = TRNG_ERROR;
995 
996 	return TEE_ERROR_GENERIC;
997 }
998 
999 /*
1000  * The KAT test should be run when the TRNG is configured in DRNG or HRNG mode.
1001  * If KAT fails, the driver has to be put in error state.
1002  */
trng_kat_test(struct versal_trng * trng)1003 static TEE_Result trng_kat_test(struct versal_trng *trng)
1004 {
1005 	struct trng_usr_cfg tests = {
1006 		.mode = TRNG_DRNG,
1007 		.seed_life = 5,
1008 		.dfmul = 2,
1009 		.predict_en = false,
1010 		.iseed_en = true,
1011 		.pstr_en = true,
1012 		.df_disable = false,
1013 	};
1014 	const uint8_t ext_seed[TRNG_SEED_LEN] = {
1015 		0x3BU, 0xC3U, 0xEDU, 0x64U, 0xF4U, 0x80U, 0x1CU, 0xC7U,
1016 		0x14U, 0xCCU, 0x35U, 0xEDU, 0x57U, 0x01U, 0x2AU, 0xE4U,
1017 		0xBCU, 0xEFU, 0xDEU, 0xF6U, 0x7CU, 0x46U, 0xA6U, 0x34U,
1018 		0xC6U, 0x79U, 0xE8U, 0x91U, 0x5DU, 0xB1U, 0xDBU, 0xA7U,
1019 		0x49U, 0xA5U, 0xBBU, 0x4FU, 0xEDU, 0x30U, 0xB3U, 0x7BU,
1020 		0xA9U, 0x8BU, 0xF5U, 0x56U, 0x4DU, 0x40U, 0x18U, 0x9FU,
1021 	};
1022 	const uint8_t pers_str[TRNG_PERS_STR_LEN] = {
1023 		0xB2U, 0x80U, 0x7EU, 0x4CU, 0xD0U, 0xE4U, 0xE2U, 0xA9U,
1024 		0x2FU, 0x1FU, 0x5DU, 0xC1U, 0xA2U, 0x1FU, 0x40U, 0xFCU,
1025 		0x1FU, 0x24U, 0x5DU, 0x42U, 0x61U, 0x80U, 0xE6U, 0xE9U,
1026 		0x71U, 0x05U, 0x17U, 0x5BU, 0xAFU, 0x70U, 0x30U, 0x18U,
1027 		0xBCU, 0x23U, 0x18U, 0x15U, 0xCBU, 0xB8U, 0xA6U, 0x3EU,
1028 		0x83U, 0xB8U, 0x4AU, 0xFEU, 0x38U, 0xFCU, 0x25U, 0x87U,
1029 	};
1030 	const uint8_t expected_out[TRNG_GEN_LEN] = {
1031 		0x91U, 0x9AU, 0x6BU, 0x99U, 0xD5U, 0xBCU, 0x2CU, 0x11U,
1032 		0x5FU, 0x3AU, 0xFCU, 0x0BU, 0x0EU, 0x7BU, 0xC7U, 0x69U,
1033 		0x4DU, 0xE1U, 0xE5U, 0xFEU, 0x59U, 0x9EU, 0xAAU, 0x41U,
1034 		0xD3U, 0x48U, 0xFDU, 0x3DU, 0xD2U, 0xC4U, 0x50U, 0x1EU,
1035 	};
1036 	uint8_t out[TRNG_GEN_LEN] = { 0 };
1037 
1038 	if (!trng)
1039 		return TEE_ERROR_GENERIC;
1040 
1041 	memcpy(&tests.init_seed, ext_seed, sizeof(ext_seed));
1042 	memcpy(tests.pstr, pers_str, sizeof(pers_str));
1043 
1044 	if (trng_instantiate(trng, &tests))
1045 		goto error;
1046 
1047 	if (trng_generate(trng, out, sizeof(out), false))
1048 		goto error;
1049 
1050 	if (memcmp(out, expected_out, TRNG_GEN_LEN)) {
1051 		EMSG("K.A.T mismatch");
1052 		goto error;
1053 	}
1054 
1055 	if (trng_release(trng))
1056 		goto error;
1057 
1058 	return TEE_SUCCESS;
1059 error:
1060 	trng->status = TRNG_ERROR;
1061 	return TEE_ERROR_GENERIC;
1062 }
1063 
1064 static struct versal_trng versal_trng = {
1065 	.cfg.base = TRNG_BASE,
1066 	.cfg.len = TRNG_SIZE,
1067 };
1068 
hw_get_random_bytes(void * buf,size_t len)1069 TEE_Result hw_get_random_bytes(void *buf, size_t len)
1070 {
1071 	uint8_t random[TRNG_SEC_STRENGTH_LEN] = { 0 };
1072 	uint8_t *p = buf;
1073 	size_t i = 0;
1074 
1075 	for (i = 0; i < len / TRNG_SEC_STRENGTH_LEN; i++) {
1076 		if (trng_generate(&versal_trng, p + i * TRNG_SEC_STRENGTH_LEN,
1077 				  TRNG_SEC_STRENGTH_LEN, false))
1078 			panic();
1079 	}
1080 
1081 	if (len % TRNG_SEC_STRENGTH_LEN) {
1082 		if (trng_generate(&versal_trng, random, TRNG_SEC_STRENGTH_LEN,
1083 				  false))
1084 			panic();
1085 		memcpy(p + i * TRNG_SEC_STRENGTH_LEN, random,
1086 		       len % TRNG_SEC_STRENGTH_LEN);
1087 	}
1088 
1089 	return TEE_SUCCESS;
1090 }
1091 
plat_rng_init(void)1092 void plat_rng_init(void)
1093 {
1094 }
1095 
trng_hrng_mode_init(void)1096 static TEE_Result trng_hrng_mode_init(void)
1097 {
1098 	const uint8_t pers_str[TRNG_PERS_STR_LEN] = {
1099 		0xB2, 0x80, 0x7E, 0x4C, 0xD0, 0xE4, 0xE2, 0xA9,
1100 		0x2F, 0x1F, 0x5D, 0xC1, 0xA2, 0x1F, 0x40, 0xFC,
1101 		0x1F, 0x24, 0x5D, 0x42, 0x61, 0x80, 0xE6, 0xE9,
1102 		0x71, 0x05, 0x17, 0x5B, 0xAF, 0x70, 0x30, 0x18,
1103 		0xBC, 0x23, 0x18, 0x15, 0xCB, 0xB8, 0xA6, 0x3E,
1104 		0x83, 0xB8, 0x4A, 0xFE, 0x38, 0xFC, 0x25, 0x87,
1105 	};
1106 	/* configure in hybrid mode with derivative function enabled */
1107 	struct trng_usr_cfg usr_cfg = {
1108 		.mode = TRNG_HRNG,
1109 		.seed_life = CFG_VERSAL_TRNG_SEED_LIFE,
1110 		.predict_en = false,
1111 		.df_disable = false,
1112 		.dfmul = CFG_VERSAL_TRNG_DF_MUL,
1113 		.iseed_en =  false,
1114 		.pstr_en = true,
1115 	};
1116 
1117 	memcpy(usr_cfg.pstr, pers_str, TRNG_PERS_STR_LEN);
1118 	versal_trng.cfg.addr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC,
1119 						     versal_trng.cfg.base,
1120 						     versal_trng.cfg.len);
1121 	if (!versal_trng.cfg.addr) {
1122 		EMSG("Failed to map TRNG");
1123 		panic();
1124 	}
1125 
1126 	if (trng_kat_test(&versal_trng)) {
1127 		EMSG("KAT Failed");
1128 		panic();
1129 	}
1130 
1131 	if (trng_health_test(&versal_trng)) {
1132 		EMSG("RunHealthTest Failed");
1133 		panic();
1134 	}
1135 
1136 	if (trng_instantiate(&versal_trng, &usr_cfg)) {
1137 		EMSG("Driver instantiation Failed");
1138 		panic();
1139 	}
1140 
1141 	if (trng_reseed(&versal_trng, NULL, usr_cfg.dfmul)) {
1142 		EMSG("Reseed Failed");
1143 		panic();
1144 	}
1145 
1146 	return TEE_SUCCESS;
1147 }
1148 
1149 driver_init(trng_hrng_mode_init);
1150