6
6
*
7
7
* SPDX-License-Identifier: Apache-2.0
8
8
*/
9
+ #include <stddef.h>
9
10
#include <zephyr/kernel.h>
10
11
#include <zephyr/device.h>
11
12
#include <zephyr/drivers/entropy.h>
@@ -338,7 +339,7 @@ static int recover_seed_error(RNG_TypeDef *rng)
338
339
}
339
340
#endif /* !STM32_CONDRST_SUPPORT */
340
341
341
- static int random_byte_get ( void )
342
+ static int random_sample_get ( rng_sample_t * rnd_sample )
342
343
{
343
344
int retval = - EAGAIN ;
344
345
unsigned int key ;
@@ -368,16 +369,16 @@ static int random_byte_get(void)
368
369
goto out ;
369
370
}
370
371
371
- retval = ll_rng_read_rand_data (rng );
372
- if (retval == 0 ) {
372
+ * rnd_sample = ll_rng_read_rand_data (rng );
373
+ if (* rnd_sample == 0 ) {
373
374
/* A seed error could have occurred between RNG_SR
374
375
* polling and RND_DR output reading.
375
376
*/
376
377
retval = - EAGAIN ;
377
378
goto out ;
378
379
}
379
380
380
- retval &= 0xFF ;
381
+ retval = 0 ;
381
382
}
382
383
383
384
out :
@@ -390,6 +391,8 @@ static int random_byte_get(void)
390
391
static uint16_t generate_from_isr (uint8_t * buf , uint16_t len )
391
392
{
392
393
uint16_t remaining_len = len ;
394
+ rng_sample_t rnd_sample ;
395
+ int ret ;
393
396
394
397
#if !IRQLESS_TRNG
395
398
__ASSERT_NO_MSG (!irq_is_enabled (IRQN ));
@@ -403,7 +406,7 @@ static uint16_t generate_from_isr(uint8_t *buf, uint16_t len)
403
406
if (ll_rng_is_active_secs (entropy_stm32_rng_data .rng ) ||
404
407
ll_rng_is_active_seis (entropy_stm32_rng_data .rng )) {
405
408
406
- (void )random_byte_get ( ); /* this will recover the error */
409
+ (void )random_sample_get ( & rnd_sample ); /* this will recover the error */
407
410
408
411
return 0 ; /* return cnt is null : no random data available */
409
412
}
@@ -418,8 +421,6 @@ static uint16_t generate_from_isr(uint8_t *buf, uint16_t len)
418
421
#endif /* !IRQLESS_TRNG */
419
422
420
423
do {
421
- int byte ;
422
-
423
424
while (ll_rng_is_active_drdy (
424
425
entropy_stm32_rng_data .rng ) != 1 ) {
425
426
#if !IRQLESS_TRNG
@@ -441,16 +442,23 @@ static uint16_t generate_from_isr(uint8_t *buf, uint16_t len)
441
442
#endif /* !IRQLESS_TRNG */
442
443
}
443
444
444
- byte = random_byte_get ( );
445
+ ret = random_sample_get ( & rnd_sample );
445
446
#if !IRQLESS_TRNG
446
447
NVIC_ClearPendingIRQ (IRQN );
447
448
#endif /* IRQLESS_TRNG */
448
449
449
- if (byte < 0 ) {
450
+ if (ret < 0 ) {
450
451
continue ;
451
452
}
452
453
453
- buf [-- remaining_len ] = byte ;
454
+ /* push each byte of the RNG sample in buffer */
455
+ size_t i = sizeof (rnd_sample );
456
+
457
+ while (remaining_len && i ) {
458
+ buf [-- remaining_len ] = (uint8_t )(rnd_sample & 0xFFu );
459
+ rnd_sample >>= 8 ;
460
+ i -- ;
461
+ }
454
462
} while (remaining_len );
455
463
456
464
return len ;
@@ -604,31 +612,47 @@ static void rng_pool_init(struct rng_pool *rngp, uint16_t size,
604
612
605
613
static int perform_pool_refill (void )
606
614
{
607
- int byte , ret ;
615
+ rng_sample_t rnd_sample ;
616
+ bool refilled_thr = false;
617
+ int ret ;
608
618
609
- byte = random_byte_get ( );
610
- if (byte < 0 ) {
611
- return - EIO ;
619
+ ret = random_sample_get ( & rnd_sample );
620
+ if (ret < 0 ) {
621
+ return ret ;
612
622
}
613
623
614
- ret = rng_pool_put ((struct rng_pool * )(entropy_stm32_rng_data .isr ),
615
- byte );
616
- if (ret < 0 ) {
617
- ret = rng_pool_put (
618
- (struct rng_pool * )(entropy_stm32_rng_data .thr ),
619
- byte );
624
+ /* push each byte of the RNG sample in pools */
625
+ for (size_t i = 0 ; i < sizeof (rnd_sample ); i ++ , rnd_sample >>= 8 ) {
626
+ uint8_t byte = rnd_sample & 0xFFu ;
627
+
628
+ ret = rng_pool_put ((struct rng_pool * )(entropy_stm32_rng_data .isr ), byte );
620
629
if (ret < 0 ) {
630
+ /* Take note that data has been added to thread pool */
631
+ refilled_thr = true;
632
+
633
+ ret = rng_pool_put ((struct rng_pool * )(entropy_stm32_rng_data .thr ), byte );
634
+ if (ret < 0 ) {
621
635
#if !IRQLESS_TRNG
622
- irq_disable (IRQN );
636
+ irq_disable (IRQN );
623
637
#endif /* !IRQLESS_TRNG */
624
- release_rng ();
625
- pm_policy_state_lock_put (PM_STATE_SUSPEND_TO_IDLE , PM_ALL_SUBSTATES );
626
- if (IS_ENABLED (CONFIG_PM_S2RAM )) {
627
- pm_policy_state_lock_put (PM_STATE_SUSPEND_TO_RAM , PM_ALL_SUBSTATES );
638
+ release_rng ();
639
+ pm_policy_state_lock_put (PM_STATE_SUSPEND_TO_IDLE ,
640
+ PM_ALL_SUBSTATES );
641
+ if (IS_ENABLED (CONFIG_PM_S2RAM )) {
642
+ pm_policy_state_lock_put (PM_STATE_SUSPEND_TO_RAM ,
643
+ PM_ALL_SUBSTATES );
644
+ }
645
+ entropy_stm32_rng_data .filling_pools = false;
646
+ break ;
628
647
}
629
- entropy_stm32_rng_data .filling_pools = false;
630
648
}
649
+ }
631
650
651
+ if (refilled_thr ) {
652
+ /**
653
+ * Wake up threads that may be waiting for new data to be
654
+ * available in thread pool if we added entropy in it.
655
+ */
632
656
k_sem_give (& entropy_stm32_rng_data .sem_sync );
633
657
}
634
658
@@ -645,7 +669,8 @@ static void trng_poll_work_item(struct k_work *work)
645
669
if (ll_rng_is_active_secs (entropy_stm32_rng_data .rng ) ||
646
670
ll_rng_is_active_seis (entropy_stm32_rng_data .rng )) {
647
671
648
- (void )random_byte_get (); /* this will recover the error */
672
+ rng_sample_t dummy ;
673
+ (void )random_sample_get (& dummy ); /* this will recover the error */
649
674
} else if (ll_rng_is_active_drdy (rng )) {
650
675
/* Entropy available: read it and fill pools */
651
676
int res = perform_pool_refill ();
0 commit comments