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