mirror of https://github.com/ARMmbed/mbed-os.git
Fix TRNG for NRF52
* When multiple TRNG objects are initialized, destroying the first object will turn the TRNG off for the other objects. This fix adds a counter to ensure that only when the last object is destroyed will it cause the TRNG to be disabled. * The corner case where a user request 0 bytes is correctly handled and will now return immediately.pull/6547/head
parent
5d5277336a
commit
fa79e685fc
|
@ -37,21 +37,39 @@
|
|||
*/
|
||||
|
||||
#if defined(DEVICE_TRNG)
|
||||
#include "trng_api.h"
|
||||
|
||||
#include "hal/trng_api.h"
|
||||
#include "hal/critical_section_api.h"
|
||||
|
||||
#include "nrf_drv_rng.h"
|
||||
|
||||
/* Keep track of instantiated FlashIAP objects. */
|
||||
static int nordic_trng_counter = 0;
|
||||
|
||||
void trng_init(trng_t *obj)
|
||||
{
|
||||
(void) obj;
|
||||
MBED_ASSERT(obj);
|
||||
|
||||
(void)nrf_drv_rng_init(NULL);
|
||||
/* Increment global counter. */
|
||||
nordic_trng_counter++;
|
||||
|
||||
/* Initialize TRNG on first object only. */
|
||||
if (nordic_trng_counter == 1) {
|
||||
nrf_drv_rng_init(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void trng_free(trng_t *obj)
|
||||
{
|
||||
(void) obj;
|
||||
MBED_ASSERT(obj);
|
||||
|
||||
nrf_drv_rng_uninit();
|
||||
/* Decrement global counter. */
|
||||
nordic_trng_counter--;
|
||||
|
||||
/* Deinitialize TRNG when all objects have been freed. */
|
||||
if (nordic_trng_counter == 0) {
|
||||
nrf_drv_rng_uninit();
|
||||
}
|
||||
}
|
||||
|
||||
/* Get random data from NRF5x TRNG peripheral.
|
||||
|
@ -61,30 +79,45 @@ void trng_free(trng_t *obj)
|
|||
*/
|
||||
int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length)
|
||||
{
|
||||
uint8_t bytes_available;
|
||||
MBED_ASSERT(obj);
|
||||
MBED_ASSERT(output);
|
||||
MBED_ASSERT(output_length);
|
||||
|
||||
(void) obj;
|
||||
int result = 0;
|
||||
|
||||
nrf_drv_rng_bytes_available(&bytes_available);
|
||||
/* Return immediately if requested length is zero. */
|
||||
if (length != 0) {
|
||||
|
||||
if (bytes_available == 0) {
|
||||
nrf_drv_rng_block_rand(output, 1);
|
||||
*output_length = 1;
|
||||
} else {
|
||||
/* Query how many bytes are available. */
|
||||
uint8_t bytes_available;
|
||||
nrf_drv_rng_bytes_available(&bytes_available);
|
||||
|
||||
if (bytes_available > length) {
|
||||
bytes_available = length;
|
||||
}
|
||||
|
||||
if (nrf_drv_rng_rand(output, bytes_available) != NRF_SUCCESS) {
|
||||
*output_length = 0;
|
||||
return -1;
|
||||
/* If no bytes are cached, block until at least 1 byte is available. */
|
||||
if (bytes_available == 0) {
|
||||
nrf_drv_rng_block_rand(output, 1);
|
||||
*output_length = 1;
|
||||
} else {
|
||||
*output_length = bytes_available;
|
||||
|
||||
/* Get up to the requested number of bytes. */
|
||||
if (bytes_available > length) {
|
||||
bytes_available = length;
|
||||
}
|
||||
|
||||
ret_code_t result = nrf_drv_rng_rand(output, bytes_available);
|
||||
|
||||
/* Set output length with available bytes. */
|
||||
if (result == NRF_SUCCESS) {
|
||||
*output_length = bytes_available;
|
||||
} else {
|
||||
*output_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set return value based on how many bytes were read. */
|
||||
result = (*output_length == 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3508,6 +3508,7 @@
|
|||
"ITM",
|
||||
"TRNG",
|
||||
"FLASH",
|
||||
"TRNG",
|
||||
"STCLK_OFF_DURING_SLEEP"
|
||||
],
|
||||
"extra_labels": [
|
||||
|
@ -3541,7 +3542,7 @@
|
|||
"supported_form_factors": ["ARDUINO"],
|
||||
"inherits": ["MCU_NRF52832"],
|
||||
"macros_add": ["BOARD_PCA10040", "NRF52_PAN_12", "NRF52_PAN_15", "NRF52_PAN_58", "NRF52_PAN_55", "NRF52_PAN_54", "NRF52_PAN_31", "NRF52_PAN_30", "NRF52_PAN_51", "NRF52_PAN_36", "NRF52_PAN_53", "S132", "CONFIG_GPIO_AS_PINRESET", "BLE_STACK_SUPPORT_REQD", "SWI_DISABLE0", "NRF52_PAN_20", "NRF52_PAN_64", "NRF52_PAN_62", "NRF52_PAN_63"],
|
||||
"device_has_add": ["ANALOGIN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE", "TRNG"],
|
||||
"device_has_add": ["ANALOGIN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"],
|
||||
"release_versions": ["5"],
|
||||
"device_name": "nRF52832_xxAA"
|
||||
},
|
||||
|
@ -3638,6 +3639,7 @@
|
|||
"device_has": [
|
||||
"ITM",
|
||||
"FLASH",
|
||||
"TRNG",
|
||||
"STCLK_OFF_DURING_SLEEP"
|
||||
],
|
||||
"extra_labels": [
|
||||
|
@ -3671,7 +3673,7 @@
|
|||
"supported_form_factors": ["ARDUINO"],
|
||||
"inherits": ["MCU_NRF52840"],
|
||||
"macros_add": ["BOARD_PCA10056", "CONFIG_GPIO_AS_PINRESET", "SWI_DISABLE0", "NRF52_ERRATA_20"],
|
||||
"device_has_add": ["ANALOGIN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "TRNG"],
|
||||
"device_has_add": ["ANALOGIN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE"],
|
||||
"release_versions": ["5"],
|
||||
"device_name": "nRF52840_xxAA",
|
||||
"bootloader_supported": true
|
||||
|
|
Loading…
Reference in New Issue