xref: /optee_os/core/drivers/stm32_rng.c (revision c2c5b4bed35605fa265475409350d7d563eb2a39)
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 		/* No need to wait for RNG_CR_CONDRST toggle as we enable clk */
283 		io_clrsetbits32(rng_base + RNG_CR, RNG_CR_CONDRST,
284 				RNG_CR_RNGEN);
285 	} else {
286 		io_setbits32(rng_base + RNG_CR, RNG_CR_RNGEN | cr_ced_mask);
287 	}
288 
289 	timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
290 	while (!(io_read32(rng_base + RNG_SR) & RNG_SR_DRDY))
291 		if (timeout_elapsed(timeout_ref))
292 			break;
293 
294 	if (!(io_read32(rng_base + RNG_SR) & RNG_SR_DRDY))
295 		return TEE_ERROR_GENERIC;
296 
297 	return TEE_SUCCESS;
298 }
299 
300 static TEE_Result stm32_rng_read(uint8_t *out, size_t size)
301 {
302 	TEE_Result rc = TEE_ERROR_GENERIC;
303 	bool burst_timeout = false;
304 	uint64_t timeout_ref = 0;
305 	uint32_t exceptions = 0;
306 	uint8_t *out_ptr = out;
307 	vaddr_t rng_base = 0;
308 	size_t out_size = 0;
309 
310 	if (!stm32_rng) {
311 		DMSG("No RNG");
312 		return TEE_ERROR_NOT_SUPPORTED;
313 	}
314 
315 	rc = clk_enable(stm32_rng->clock);
316 	if (rc)
317 		return rc;
318 
319 	rng_base = get_base();
320 
321 	/* Arm timeout */
322 	timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
323 	burst_timeout = false;
324 
325 	while (out_size < size) {
326 		/* Read by chunks of the size the RNG FIFO depth */
327 		size_t sz = size - out_size;
328 
329 		exceptions = may_spin_lock(&stm32_rng->lock);
330 
331 		rc = read_available(rng_base, out_ptr, &sz);
332 
333 		/* Raise timeout only if we failed to get some samples */
334 		assert(!rc || rc == TEE_ERROR_NO_DATA);
335 		if (rc)
336 			burst_timeout = timeout_elapsed(timeout_ref);
337 
338 		may_spin_unlock(&stm32_rng->lock, exceptions);
339 
340 		if (burst_timeout) {
341 			rc = TEE_ERROR_GENERIC;
342 			goto out;
343 		}
344 
345 		if (!rc) {
346 			out_size += sz;
347 			out_ptr += sz;
348 			/* Re-arm timeout */
349 			timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
350 			burst_timeout = false;
351 		}
352 	}
353 
354 out:
355 	assert(!rc || rc == TEE_ERROR_GENERIC);
356 	clk_disable(stm32_rng->clock);
357 
358 	return rc;
359 }
360 
361 #ifdef CFG_WITH_SOFTWARE_PRNG
362 /* Override weak plat_rng_init with platform handler to seed PRNG */
363 void plat_rng_init(void)
364 {
365 	uint8_t seed[RNG_FIFO_BYTE_DEPTH] = { };
366 
367 	if (stm32_rng_read(seed, sizeof(seed)))
368 		panic();
369 
370 	if (crypto_rng_init(seed, sizeof(seed)))
371 		panic();
372 
373 	DMSG("PRNG seeded with RNG");
374 }
375 #else
376 TEE_Result hw_get_random_bytes(void *out, size_t size)
377 {
378 	return stm32_rng_read(out, size);
379 }
380 
381 void plat_rng_init(void)
382 {
383 }
384 #endif
385 
386 static TEE_Result stm32_rng_pm_resume(uint32_t pm_cr)
387 {
388 	vaddr_t base = get_base();
389 
390 	/* Clean error indications */
391 	io_write32(base + RNG_SR, 0);
392 
393 	if (stm32_rng->ddata->has_cond_reset) {
394 		/*
395 		 * Configuration must be set in the same access that sets
396 		 * RNG_CR_CONDRST bit. Otherwise, the configuration setting is
397 		 * not taken into account. CONFIGLOCK bit is always cleared in
398 		 * this configuration.
399 		 */
400 		io_write32(base + RNG_CR, pm_cr | RNG_CR_CONDRST);
401 
402 		io_clrsetbits32(base + RNG_CR, RNG_CR_CONDRST, RNG_CR_RNGEN);
403 	} else {
404 		io_write32(base + RNG_CR, RNG_CR_RNGEN | pm_cr);
405 	}
406 
407 	return TEE_SUCCESS;
408 }
409 
410 static TEE_Result
411 stm32_rng_pm(enum pm_op op, unsigned int pm_hint __unused,
412 	     const struct pm_callback_handle *pm_handle __unused)
413 {
414 	static uint32_t pm_cr;
415 	TEE_Result res = TEE_ERROR_GENERIC;
416 
417 	assert(stm32_rng && (op == PM_OP_SUSPEND || op == PM_OP_RESUME));
418 
419 	res = clk_enable(stm32_rng->clock);
420 	if (res)
421 		return res;
422 
423 	if (op == PM_OP_SUSPEND)
424 		pm_cr = io_read32(get_base() + RNG_CR);
425 	else
426 		res = stm32_rng_pm_resume(pm_cr);
427 
428 	clk_disable(stm32_rng->clock);
429 
430 	return res;
431 }
432 DECLARE_KEEP_PAGER(stm32_rng_pm);
433 
434 static TEE_Result stm32_rng_parse_fdt(const void *fdt, int node)
435 {
436 	TEE_Result res = TEE_ERROR_GENERIC;
437 	struct dt_node_info dt_rng = { };
438 
439 	fdt_fill_device_info(fdt, &dt_rng, node);
440 	if (dt_rng.reg == DT_INFO_INVALID_REG)
441 		return TEE_ERROR_BAD_PARAMETERS;
442 
443 	stm32_rng->base.pa = dt_rng.reg;
444 	stm32_rng->base.va = io_pa_or_va_secure(&stm32_rng->base,
445 						dt_rng.reg_size);
446 	assert(stm32_rng->base.va);
447 
448 	res = rstctrl_dt_get_by_index(fdt, node, 0, &stm32_rng->rstctrl);
449 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
450 		return res;
451 
452 	res = clk_dt_get_by_index(fdt, node, 0, &stm32_rng->clock);
453 	if (res)
454 		return res;
455 
456 	if (fdt_getprop(fdt, node, "clock-error-detect", NULL))
457 		stm32_rng->clock_error = true;
458 
459 	/* Release device if not used at runtime or for pm transitions */
460 	stm32_rng->release_post_boot = IS_ENABLED(CFG_WITH_SOFTWARE_PRNG) &&
461 				       !IS_ENABLED(CFG_PM);
462 
463 	return TEE_SUCCESS;
464 }
465 
466 static TEE_Result stm32_rng_probe(const void *fdt, int offs,
467 				  const void *compat_data)
468 {
469 	TEE_Result res = TEE_ERROR_GENERIC;
470 
471 	/* Expect a single RNG instance */
472 	assert(!stm32_rng);
473 
474 	stm32_rng = calloc(1, sizeof(*stm32_rng));
475 	if (!stm32_rng)
476 		panic();
477 
478 	res = stm32_rng_parse_fdt(fdt, offs);
479 	if (res)
480 		goto err;
481 
482 	stm32_rng->ddata = compat_data;
483 	assert(stm32_rng->ddata);
484 
485 	res = clk_enable(stm32_rng->clock);
486 	if (res)
487 		goto err;
488 
489 	if (stm32_rng->rstctrl &&
490 	    rstctrl_assert_to(stm32_rng->rstctrl, RNG_RESET_TIMEOUT_US)) {
491 		res = TEE_ERROR_GENERIC;
492 		goto err_clk;
493 	}
494 
495 	if (stm32_rng->rstctrl &&
496 	    rstctrl_deassert_to(stm32_rng->rstctrl, RNG_RESET_TIMEOUT_US)) {
497 		res = TEE_ERROR_GENERIC;
498 		goto err_clk;
499 	}
500 
501 	res = init_rng();
502 	if (res)
503 		goto err_clk;
504 
505 	clk_disable(stm32_rng->clock);
506 
507 	if (stm32_rng->release_post_boot)
508 		stm32mp_register_non_secure_periph_iomem(stm32_rng->base.pa);
509 	else
510 		stm32mp_register_secure_periph_iomem(stm32_rng->base.pa);
511 
512 	register_pm_core_service_cb(stm32_rng_pm, &stm32_rng, "rng-service");
513 
514 	return TEE_SUCCESS;
515 
516 err_clk:
517 	clk_disable(stm32_rng->clock);
518 err:
519 	free(stm32_rng);
520 	stm32_rng = NULL;
521 
522 	return res;
523 }
524 
525 static const struct stm32_rng_driver_data mp13_data[] = {
526 	{ .has_cond_reset = true },
527 };
528 
529 static const struct stm32_rng_driver_data mp15_data[] = {
530 	{ .has_cond_reset = false },
531 };
532 DECLARE_KEEP_PAGER(mp15_data);
533 
534 static const struct dt_device_match rng_match_table[] = {
535 	{ .compatible = "st,stm32-rng", .compat_data = &mp15_data },
536 	{ .compatible = "st,stm32mp13-rng", .compat_data = &mp13_data },
537 	{ }
538 };
539 
540 DEFINE_DT_DRIVER(stm32_rng_dt_driver) = {
541 	.name = "stm32_rng",
542 	.match_table = rng_match_table,
543 	.probe = stm32_rng_probe,
544 };
545 
546 static TEE_Result stm32_rng_release(void)
547 {
548 	if (stm32_rng && stm32_rng->release_post_boot) {
549 		DMSG("Release RNG driver");
550 		free(stm32_rng);
551 		stm32_rng = NULL;
552 	}
553 
554 	return TEE_SUCCESS;
555 }
556 
557 release_init_resource(stm32_rng_release);
558