From 771bbfa523856ef9e5afcc8016ec60e7e64a15a5 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Wed, 14 Apr 2021 18:14:00 +0200 Subject: [PATCH 1/2] ll/rand: restructure rand initialization The late seed initialization in ble_ll_rand() has caused issues as the initial call to jrand48 causes a malloc call inside the libc. As the first call to ble_ll_rand() could be triggered from interrupt context, thread safety mechanisms around malloc to fail. This commit fixes this by restructuring the ble_ll_rand initialization by pulling ble_ll_rand_init(), ble_ll_rand_start(), and the seeding of the pseudo random number generator all into a single function. --- nimble/controller/include/controller/ble_ll.h | 1 - nimble/controller/src/ble_ll.c | 2 - nimble/controller/src/ble_ll_rand.c | 42 +++++++------------ 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 24d7db3003..79130a499f 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -581,7 +581,6 @@ int ble_ll_rand_init(void); void ble_ll_rand_sample(uint8_t rnum); int ble_ll_rand_data_get(uint8_t *buf, uint8_t len); void ble_ll_rand_prand_get(uint8_t *prand); -int ble_ll_rand_start(void); uint32_t ble_ll_rand(void); static inline int diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index cf83b79c38..c3f0e57daa 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1687,8 +1687,6 @@ ble_ll_init(void) /* Initialize random number generation */ ble_ll_rand_init(); - /* Start the random number generator */ - ble_ll_rand_start(); rc = stats_init_and_reg(STATS_HDR(ble_ll_stats), STATS_SIZE_INIT_PARMS(ble_ll_stats, STATS_SIZE_32), diff --git a/nimble/controller/src/ble_ll_rand.c b/nimble/controller/src/ble_ll_rand.c index 8aa7127160..85dd4a0d9a 100644 --- a/nimble/controller/src/ble_ll_rand.c +++ b/nimble/controller/src/ble_ll_rand.c @@ -47,6 +47,8 @@ struct ble_ll_rnum_data struct ble_ll_rnum_data g_ble_ll_rnum_data; uint8_t g_ble_ll_rnum_buf[MYNEWT_VAL(BLE_LL_RNG_BUFSIZE)]; +static unsigned short xsubi[3]; + #define IS_RNUM_BUF_END(x) \ (x == &g_ble_ll_rnum_buf[MYNEWT_VAL(BLE_LL_RNG_BUFSIZE) - 1]) @@ -127,14 +129,6 @@ ble_ll_rand_data_get(uint8_t *buf, uint8_t len) uint32_t ble_ll_rand(void) { - static unsigned short xsubi[3]; - static bool init = true; - - if (init) { - init = false; - ble_ll_rand_data_get((uint8_t *)xsubi, sizeof(xsubi)); - } - return (uint32_t) jrand48(xsubi); } @@ -164,25 +158,6 @@ ble_ll_rand_prand_get(uint8_t *prand) prand[2] |= 0x40; } -/** - * Start the generation of random numbers - * - * @return int - */ -int -ble_ll_rand_start(void) -{ -#if MYNEWT_VAL(TRNG) - /* Nothing to do - this is handled by driver */ -#else - /* Start the generation of numbers if we are not full */ - if (g_ble_ll_rnum_data.rnd_size < MYNEWT_VAL(BLE_LL_RNG_BUFSIZE)) { - ble_hw_rng_start(); - } -#endif - return 0; -} - /** * Initialize LL random number generation. Should be called only once on * initialization. @@ -198,6 +173,19 @@ ble_ll_rand_init(void) g_ble_ll_rnum_data.rnd_in = g_ble_ll_rnum_buf; g_ble_ll_rnum_data.rnd_out = g_ble_ll_rnum_buf; ble_hw_rng_init(ble_ll_rand_sample, 1); + + /* Start the generation of numbers if we are not full */ + if (g_ble_ll_rnum_data.rnd_size < MYNEWT_VAL(BLE_LL_RNG_BUFSIZE)) { + ble_hw_rng_start(); + } + + /* Seed the pseudo random number generator (jrand48) */ + ble_ll_rand_data_get((uint8_t *)xsubi, sizeof(xsubi)); + /* We need to trigger jrand48 once discarding its output, as the initial + * call to jrand48 causes dynamic memory allocation by the libc. We do not + * want this to happen in interrupt context, which can happen if we wait for + * the first actual call to ble_ll_rand(). */ + ble_ll_rand(); #endif return 0; } From 76a24bd8e9862658b0ffc2016689d1f4b62ac2fd Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 15 Apr 2021 09:30:28 +0200 Subject: [PATCH 2/2] fixup! fix scope for PRNG seeding --- nimble/controller/src/ble_ll_rand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_rand.c b/nimble/controller/src/ble_ll_rand.c index 85dd4a0d9a..ee85d8e521 100644 --- a/nimble/controller/src/ble_ll_rand.c +++ b/nimble/controller/src/ble_ll_rand.c @@ -178,6 +178,7 @@ ble_ll_rand_init(void) if (g_ble_ll_rnum_data.rnd_size < MYNEWT_VAL(BLE_LL_RNG_BUFSIZE)) { ble_hw_rng_start(); } +#endif /* Seed the pseudo random number generator (jrand48) */ ble_ll_rand_data_get((uint8_t *)xsubi, sizeof(xsubi)); @@ -186,6 +187,5 @@ ble_ll_rand_init(void) * want this to happen in interrupt context, which can happen if we wait for * the first actual call to ble_ll_rand(). */ ble_ll_rand(); -#endif return 0; }