xref: /optee_os/core/drivers/stm32_rng.c (revision 5f7f88c6b9d618d1e068166bbf2b07757350791d)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2018-2023, STMicroelectronics
4  */
5 
6 #include <assert.h>
7 #include <drivers/clk.h>
8 #include <drivers/clk_dt.h>
9 #include <drivers/rstctrl.h>
10 #include <io.h>
11 #include <kernel/delay.h>
12 #include <kernel/dt.h>
13 #include <kernel/dt_driver.h>
14 #include <kernel/boot.h>
15 #include <kernel/panic.h>
16 #include <kernel/pm.h>
17 #include <kernel/thread.h>
18 #include <libfdt.h>
19 #include <mm/core_memprot.h>
20 #include <rng_support.h>
21 #include <stdbool.h>
22 #include <stm32_util.h>
23 #include <string.h>
24 #include <tee/tee_cryp_utl.h>
25 
26 #define RNG_CR			U(0x00)
27 #define RNG_SR			U(0x04)
28 #define RNG_DR			U(0x08)
29 
30 #define RNG_CR_RNGEN		BIT(2)
31 #define RNG_CR_IE		BIT(3)
32 #define RNG_CR_CED		BIT(5)
33 #define RNG_CR_CLKDIV		GENMASK_32(19, 16)
34 #define RNG_CR_CLKDIV_SHIFT	U(16)
35 #define RNG_CR_CONDRST		BIT(30)
36 
37 #define RNG_SR_DRDY		BIT(0)
38 #define RNG_SR_CECS		BIT(1)
39 #define RNG_SR_SECS		BIT(2)
40 #define RNG_SR_CEIS		BIT(5)
41 #define RNG_SR_SEIS		BIT(6)
42 
43 #if TRACE_LEVEL > TRACE_DEBUG
44 #define RNG_READY_TIMEOUT_US	U(100000)
45 #else
46 #define RNG_READY_TIMEOUT_US	U(10000)
47 #endif
48 #define RNG_RESET_TIMEOUT_US	U(1000)
49 
50 #define RNG_FIFO_BYTE_DEPTH	U(16)
51 
52 #define RNG_NIST_CONFIG_A	U(0x0F00D00)
53 #define RNG_NIST_CONFIG_B	U(0x1801000)
54 #define RNG_NIST_CONFIG_MASK	GENMASK_32(25, 8)
55 
56 #define RNG_MAX_NOISE_CLK_FREQ	U(3000000)
57 
58 struct stm32_rng_driver_data {
59 	bool has_cond_reset;
60 };
61 
62 struct stm32_rng_instance {
63 	struct io_pa_va base;
64 	struct clk *clock;
65 	struct rstctrl *rstctrl;
66 	const struct stm32_rng_driver_data *ddata;
67 	unsigned int lock;
68 	bool release_post_boot;
69 	bool clock_error;
70 	bool error_conceal;
71 	uint64_t error_to_ref;
72 };
73 
74 /* Expect at most a single RNG instance */
75 static struct stm32_rng_instance *stm32_rng;
76 
77 static vaddr_t get_base(void)
78 {
79 	assert(stm32_rng);
80 
81 	return io_pa_or_va(&stm32_rng->base, 1);
82 }
83 
84 /*
85  * Extracts from the STM32 RNG specification when RNG supports CONDRST.
86  *
87  * When a noise source (or seed) error occurs, the RNG stops generating
88  * random numbers and sets to “1” both SEIS and SECS bits to indicate
89  * that a seed error occurred. (...)
90  *
91  * 1. Software reset by writing CONDRST at 1 and at 0 (see bitfield
92  * description for details). This step is needed only if SECS is set.
93  * Indeed, when SEIS is set and SECS is cleared it means RNG performed
94  * the reset automatically (auto-reset).
95  * 2. If SECS was set in step 1 (no auto-reset) wait for CONDRST
96  * to be cleared in the RNG_CR register, then confirm that SEIS is
97  * cleared in the RNG_SR register. Otherwise just clear SEIS bit in
98  * the RNG_SR register.
99  * 3. If SECS was set in step 1 (no auto-reset) wait for SECS to be
100  * cleared by RNG. The random number generation is now back to normal.
101  */
102 static void conceal_seed_error_cond_reset(void)
103 {
104 	struct stm32_rng_instance *dev = stm32_rng;
105 	vaddr_t rng_base = get_base();
106 
107 	if (!dev->error_conceal) {
108 		uint32_t sr = io_read32(rng_base + RNG_SR);
109 
110 		if (sr & RNG_SR_SECS) {
111 			/* Conceal by resetting the subsystem (step 1.) */
112 			io_setbits32(rng_base + RNG_CR, RNG_CR_CONDRST);
113 			io_clrbits32(rng_base + RNG_CR, RNG_CR_CONDRST);
114 
115 			/* Arm timeout for error_conceal sequence */
116 			dev->error_to_ref =
117 				timeout_init_us(RNG_READY_TIMEOUT_US);
118 			dev->error_conceal = true;
119 		} else {
120 			/* RNG auto-reset (step 2.) */
121 			io_clrbits32(rng_base + RNG_SR, RNG_SR_SEIS);
122 		}
123 	} else {
124 		/* Measure time before possible reschedule */
125 		bool timed_out = timeout_elapsed(dev->error_to_ref);
126 
127 		/* Wait CONDRST is cleared (step 2.) */
128 		if (io_read32(rng_base + RNG_CR) & RNG_CR_CONDRST) {
129 			if (timed_out)
130 				panic();
131 
132 			/* Wait subsystem reset cycle completes */
133 			return;
134 		}
135 
136 		/* Check SEIS is cleared (step 2.) */
137 		if (io_read32(rng_base + RNG_SR) & RNG_SR_SEIS)
138 			panic();
139 
140 		/* Wait SECS is cleared (step 3.) */
141 		if (io_read32(rng_base + RNG_SR) & RNG_SR_SECS) {
142 			if (timed_out)
143 				panic();
144 
145 			/* Wait subsystem reset cycle completes */
146 			return;
147 		}
148 
149 		dev->error_conceal = false;
150 	}
151 }
152 
153 /*
154  * Extracts from the STM32 RNG specification, when CONDRST is not supported
155  *
156  * When a noise source (or seed) error occurs, the RNG stops generating
157  * random numbers and sets to “1” both SEIS and SECS bits to indicate
158  * that a seed error occurred. (...)
159  *
160  * The following sequence shall be used to fully recover from a seed
161  * error after the RNG initialization:
162  * 1. Clear the SEIS bit by writing it to “0”.
163  * 2. Read out 12 words from the RNG_DR register, and discard each of
164  * them in order to clean the pipeline.
165  * 3. Confirm that SEIS is still cleared. Random number generation is
166  * back to normal.
167  */
168 static void conceal_seed_error_sw_reset(void)
169 {
170 	vaddr_t rng_base = get_base();
171 	size_t i = 0;
172 
173 	io_clrbits32(rng_base + RNG_SR, RNG_SR_SEIS);
174 
175 	for (i = 12; i != 0; i--)
176 		(void)io_read32(rng_base + RNG_DR);
177 
178 	if (io_read32(rng_base + RNG_SR) & RNG_SR_SEIS)
179 		panic("RNG noise");
180 }
181 
182 static void conceal_seed_error(void)
183 {
184 	if (stm32_rng->ddata->has_cond_reset)
185 		conceal_seed_error_cond_reset();
186 	else
187 		conceal_seed_error_sw_reset();
188 }
189 
190 static TEE_Result read_available(vaddr_t rng_base, uint8_t *out, size_t *size)
191 {
192 	struct stm32_rng_instance *dev = stm32_rng;
193 	uint8_t *buf = NULL;
194 	size_t req_size = 0;
195 	size_t len = 0;
196 
197 	if (dev->error_conceal || io_read32(rng_base + RNG_SR) & RNG_SR_SEIS)
198 		conceal_seed_error();
199 
200 	if (!(io_read32(rng_base + RNG_SR) & RNG_SR_DRDY)) {
201 		FMSG("RNG not ready");
202 		return TEE_ERROR_NO_DATA;
203 	}
204 
205 	if (io_read32(rng_base + RNG_SR) & RNG_SR_SEIS) {
206 		FMSG("RNG noise error");
207 		return TEE_ERROR_NO_DATA;
208 	}
209 
210 	buf = out;
211 	req_size = MIN(RNG_FIFO_BYTE_DEPTH, *size);
212 	len = req_size;
213 
214 	/* RNG is ready: read up to 4 32bit words */
215 	while (len) {
216 		uint32_t data32 = 0;
217 		size_t sz = MIN(len, sizeof(uint32_t));
218 
219 		if (!(io_read32(rng_base + RNG_SR) & RNG_SR_DRDY))
220 			break;
221 		data32 = io_read32(rng_base + RNG_DR);
222 
223 		/* Late seed error case: DR being 0 is an error status */
224 		if (!data32) {
225 			conceal_seed_error();
226 			return TEE_ERROR_NO_DATA;
227 		}
228 
229 		memcpy(buf, &data32, sz);
230 		buf += sz;
231 		len -= sz;
232 	}
233 
234 	*size = req_size - len;
235 
236 	return TEE_SUCCESS;
237 }
238 
239 static uint32_t stm32_rng_clock_freq_restrain(void)
240 {
241 	struct stm32_rng_instance *dev = stm32_rng;
242 	unsigned long clock_rate = 0;
243 	uint32_t clock_div = 0;
244 
245 	clock_rate = clk_get_rate(dev->clock);
246 
247 	/*
248 	 * Get the exponent to apply on the CLKDIV field in RNG_CR register
249 	 * No need to handle the case when clock-div > 0xF as it is physically
250 	 * impossible
251 	 */
252 	while ((clock_rate >> clock_div) > RNG_MAX_NOISE_CLK_FREQ)
253 		clock_div++;
254 
255 	DMSG("RNG clk rate : %lu", clk_get_rate(dev->clock) >> clock_div);
256 
257 	return clock_div;
258 }
259 
260 static TEE_Result init_rng(void)
261 {
262 	vaddr_t rng_base = get_base();
263 	uint64_t timeout_ref = 0;
264 	uint32_t cr_ced_mask = 0;
265 
266 	if (!stm32_rng->clock_error)
267 		cr_ced_mask = RNG_CR_CED;
268 
269 	/* Clean error indications */
270 	io_write32(rng_base + RNG_SR, 0);
271 
272 	if (stm32_rng->ddata->has_cond_reset) {
273 		uint32_t clock_div = stm32_rng_clock_freq_restrain();
274 
275 		/* Update configuration fields */
276 		io_clrsetbits32(rng_base + RNG_CR, RNG_NIST_CONFIG_MASK,
277 				RNG_NIST_CONFIG_B | RNG_CR_CONDRST |
278 				cr_ced_mask);
279 		io_clrsetbits32(rng_base + RNG_CR, RNG_CR_CLKDIV,
280 				clock_div << RNG_CR_CLKDIV_SHIFT);
281 
282 		io_clrsetbits32(rng_base + RNG_CR, RNG_CR_CONDRST,
283 				RNG_CR_RNGEN);
284 
285 		timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
286 		while (io_read32(rng_base + RNG_CR) & RNG_CR_CONDRST)
287 			if (timeout_elapsed(timeout_ref))
288 				break;
289 		if (io_read32(rng_base + RNG_CR) & RNG_CR_CONDRST)
290 			panic();
291 	} else {
292 		io_setbits32(rng_base + RNG_CR, RNG_CR_RNGEN | cr_ced_mask);
293 	}
294 
295 	timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
296 	while (!(io_read32(rng_base + RNG_SR) & RNG_SR_DRDY))
297 		if (timeout_elapsed(timeout_ref))
298 			break;
299 
300 	if (!(io_read32(rng_base + RNG_SR) & RNG_SR_DRDY))
301 		return TEE_ERROR_GENERIC;
302 
303 	return TEE_SUCCESS;
304 }
305 
306 static TEE_Result stm32_rng_read(uint8_t *out, size_t size)
307 {
308 	TEE_Result rc = TEE_ERROR_GENERIC;
309 	bool burst_timeout = false;
310 	uint64_t timeout_ref = 0;
311 	uint32_t exceptions = 0;
312 	uint8_t *out_ptr = out;
313 	vaddr_t rng_base = 0;
314 	size_t out_size = 0;
315 
316 	if (!stm32_rng) {
317 		DMSG("No RNG");
318 		return TEE_ERROR_NOT_SUPPORTED;
319 	}
320 
321 	rc = clk_enable(stm32_rng->clock);
322 	if (rc)
323 		return rc;
324 
325 	rng_base = get_base();
326 
327 	/* Arm timeout */
328 	timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
329 	burst_timeout = false;
330 
331 	while (out_size < size) {
332 		/* Read by chunks of the size the RNG FIFO depth */
333 		size_t sz = size - out_size;
334 
335 		exceptions = may_spin_lock(&stm32_rng->lock);
336 
337 		rc = read_available(rng_base, out_ptr, &sz);
338 
339 		/* Raise timeout only if we failed to get some samples */
340 		assert(!rc || rc == TEE_ERROR_NO_DATA);
341 		if (rc)
342 			burst_timeout = timeout_elapsed(timeout_ref);
343 
344 		may_spin_unlock(&stm32_rng->lock, exceptions);
345 
346 		if (burst_timeout) {
347 			rc = TEE_ERROR_GENERIC;
348 			goto out;
349 		}
350 
351 		if (!rc) {
352 			out_size += sz;
353 			out_ptr += sz;
354 			/* Re-arm timeout */
355 			timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
356 			burst_timeout = false;
357 		}
358 	}
359 
360 out:
361 	assert(!rc || rc == TEE_ERROR_GENERIC);
362 	clk_disable(stm32_rng->clock);
363 
364 	return rc;
365 }
366 
367 #ifdef CFG_WITH_SOFTWARE_PRNG
368 /* Override weak plat_rng_init with platform handler to seed PRNG */
369 void plat_rng_init(void)
370 {
371 	uint8_t seed[RNG_FIFO_BYTE_DEPTH] = { };
372 
373 	if (stm32_rng_read(seed, sizeof(seed)))
374 		panic();
375 
376 	if (crypto_rng_init(seed, sizeof(seed)))
377 		panic();
378 
379 	DMSG("PRNG seeded with RNG");
380 }
381 #else
382 TEE_Result hw_get_random_bytes(void *out, size_t size)
383 {
384 	return stm32_rng_read(out, size);
385 }
386 
387 void plat_rng_init(void)
388 {
389 }
390 #endif
391 
392 static TEE_Result stm32_rng_pm_resume(uint32_t pm_cr)
393 {
394 	vaddr_t base = get_base();
395 
396 	/* Clean error indications */
397 	io_write32(base + RNG_SR, 0);
398 
399 	if (stm32_rng->ddata->has_cond_reset) {
400 		uint64_t timeout_ref = 0;
401 
402 		/*
403 		 * Configuration must be set in the same access that sets
404 		 * RNG_CR_CONDRST bit. Otherwise, the configuration setting is
405 		 * not taken into account. CONFIGLOCK bit is always cleared in
406 		 * this configuration.
407 		 */
408 		io_write32(base + RNG_CR, pm_cr | RNG_CR_CONDRST);
409 
410 		io_clrsetbits32(base + RNG_CR, RNG_CR_CONDRST, RNG_CR_RNGEN);
411 
412 		timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
413 		while (io_read32(base + RNG_CR) & RNG_CR_CONDRST)
414 			if (timeout_elapsed(timeout_ref))
415 				break;
416 		if (io_read32(base + RNG_CR) & RNG_CR_CONDRST)
417 			panic();
418 	} else {
419 		io_write32(base + RNG_CR, RNG_CR_RNGEN | pm_cr);
420 	}
421 
422 	return TEE_SUCCESS;
423 }
424 
425 static TEE_Result
426 stm32_rng_pm(enum pm_op op, unsigned int pm_hint __unused,
427 	     const struct pm_callback_handle *pm_handle __unused)
428 {
429 	static uint32_t pm_cr;
430 	TEE_Result res = TEE_ERROR_GENERIC;
431 
432 	assert(stm32_rng && (op == PM_OP_SUSPEND || op == PM_OP_RESUME));
433 
434 	res = clk_enable(stm32_rng->clock);
435 	if (res)
436 		return res;
437 
438 	if (op == PM_OP_SUSPEND)
439 		pm_cr = io_read32(get_base() + RNG_CR);
440 	else
441 		res = stm32_rng_pm_resume(pm_cr);
442 
443 	clk_disable(stm32_rng->clock);
444 
445 	return res;
446 }
447 DECLARE_KEEP_PAGER(stm32_rng_pm);
448 
449 static TEE_Result stm32_rng_parse_fdt(const void *fdt, int node)
450 {
451 	TEE_Result res = TEE_ERROR_GENERIC;
452 	struct dt_node_info dt_rng = { };
453 
454 	fdt_fill_device_info(fdt, &dt_rng, node);
455 	if (dt_rng.reg == DT_INFO_INVALID_REG)
456 		return TEE_ERROR_BAD_PARAMETERS;
457 
458 	stm32_rng->base.pa = dt_rng.reg;
459 	stm32_rng->base.va = io_pa_or_va_secure(&stm32_rng->base,
460 						dt_rng.reg_size);
461 	assert(stm32_rng->base.va);
462 
463 	res = rstctrl_dt_get_by_index(fdt, node, 0, &stm32_rng->rstctrl);
464 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
465 		return res;
466 
467 	res = clk_dt_get_by_index(fdt, node, 0, &stm32_rng->clock);
468 	if (res)
469 		return res;
470 
471 	if (fdt_getprop(fdt, node, "clock-error-detect", NULL))
472 		stm32_rng->clock_error = true;
473 
474 	/* Release device if not used at runtime or for pm transitions */
475 	stm32_rng->release_post_boot = IS_ENABLED(CFG_WITH_SOFTWARE_PRNG) &&
476 				       !IS_ENABLED(CFG_PM);
477 
478 	return TEE_SUCCESS;
479 }
480 
481 static TEE_Result stm32_rng_probe(const void *fdt, int offs,
482 				  const void *compat_data)
483 {
484 	TEE_Result res = TEE_ERROR_GENERIC;
485 
486 	/* Expect a single RNG instance */
487 	assert(!stm32_rng);
488 
489 	stm32_rng = calloc(1, sizeof(*stm32_rng));
490 	if (!stm32_rng)
491 		panic();
492 
493 	res = stm32_rng_parse_fdt(fdt, offs);
494 	if (res)
495 		goto err;
496 
497 	stm32_rng->ddata = compat_data;
498 	assert(stm32_rng->ddata);
499 
500 	res = clk_enable(stm32_rng->clock);
501 	if (res)
502 		goto err;
503 
504 	if (stm32_rng->rstctrl &&
505 	    rstctrl_assert_to(stm32_rng->rstctrl, RNG_RESET_TIMEOUT_US)) {
506 		res = TEE_ERROR_GENERIC;
507 		goto err_clk;
508 	}
509 
510 	if (stm32_rng->rstctrl &&
511 	    rstctrl_deassert_to(stm32_rng->rstctrl, RNG_RESET_TIMEOUT_US)) {
512 		res = TEE_ERROR_GENERIC;
513 		goto err_clk;
514 	}
515 
516 	res = init_rng();
517 	if (res)
518 		goto err_clk;
519 
520 	clk_disable(stm32_rng->clock);
521 
522 	if (stm32_rng->release_post_boot)
523 		stm32mp_register_non_secure_periph_iomem(stm32_rng->base.pa);
524 	else
525 		stm32mp_register_secure_periph_iomem(stm32_rng->base.pa);
526 
527 	register_pm_core_service_cb(stm32_rng_pm, &stm32_rng, "rng-service");
528 
529 	return TEE_SUCCESS;
530 
531 err_clk:
532 	clk_disable(stm32_rng->clock);
533 err:
534 	free(stm32_rng);
535 	stm32_rng = NULL;
536 
537 	return res;
538 }
539 
540 static const struct stm32_rng_driver_data mp13_data[] = {
541 	{ .has_cond_reset = true },
542 };
543 
544 static const struct stm32_rng_driver_data mp15_data[] = {
545 	{ .has_cond_reset = false },
546 };
547 DECLARE_KEEP_PAGER(mp15_data);
548 
549 static const struct dt_device_match rng_match_table[] = {
550 	{ .compatible = "st,stm32-rng", .compat_data = &mp15_data },
551 	{ .compatible = "st,stm32mp13-rng", .compat_data = &mp13_data },
552 	{ }
553 };
554 
555 DEFINE_DT_DRIVER(stm32_rng_dt_driver) = {
556 	.name = "stm32_rng",
557 	.match_table = rng_match_table,
558 	.probe = stm32_rng_probe,
559 };
560 
561 static TEE_Result stm32_rng_release(void)
562 {
563 	if (stm32_rng && stm32_rng->release_post_boot) {
564 		DMSG("Release RNG driver");
565 		free(stm32_rng);
566 		stm32_rng = NULL;
567 	}
568 
569 	return TEE_SUCCESS;
570 }
571 
572 release_init_resource(stm32_rng_release);
573