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)
|
#if defined(DEVICE_TRNG)
|
||||||
#include "trng_api.h"
|
|
||||||
|
#include "hal/trng_api.h"
|
||||||
|
#include "hal/critical_section_api.h"
|
||||||
|
|
||||||
#include "nrf_drv_rng.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 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 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.
|
/* 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)
|
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) {
|
/* Query how many bytes are available. */
|
||||||
nrf_drv_rng_block_rand(output, 1);
|
uint8_t bytes_available;
|
||||||
*output_length = 1;
|
nrf_drv_rng_bytes_available(&bytes_available);
|
||||||
} else {
|
|
||||||
|
|
||||||
if (bytes_available > length) {
|
/* If no bytes are cached, block until at least 1 byte is available. */
|
||||||
bytes_available = length;
|
if (bytes_available == 0) {
|
||||||
}
|
nrf_drv_rng_block_rand(output, 1);
|
||||||
|
*output_length = 1;
|
||||||
if (nrf_drv_rng_rand(output, bytes_available) != NRF_SUCCESS) {
|
|
||||||
*output_length = 0;
|
|
||||||
return -1;
|
|
||||||
} else {
|
} 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
|
#endif
|
||||||
|
|
|
@ -3508,6 +3508,7 @@
|
||||||
"ITM",
|
"ITM",
|
||||||
"TRNG",
|
"TRNG",
|
||||||
"FLASH",
|
"FLASH",
|
||||||
|
"TRNG",
|
||||||
"STCLK_OFF_DURING_SLEEP"
|
"STCLK_OFF_DURING_SLEEP"
|
||||||
],
|
],
|
||||||
"extra_labels": [
|
"extra_labels": [
|
||||||
|
@ -3541,7 +3542,7 @@
|
||||||
"supported_form_factors": ["ARDUINO"],
|
"supported_form_factors": ["ARDUINO"],
|
||||||
"inherits": ["MCU_NRF52832"],
|
"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"],
|
"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"],
|
"release_versions": ["5"],
|
||||||
"device_name": "nRF52832_xxAA"
|
"device_name": "nRF52832_xxAA"
|
||||||
},
|
},
|
||||||
|
@ -3638,6 +3639,7 @@
|
||||||
"device_has": [
|
"device_has": [
|
||||||
"ITM",
|
"ITM",
|
||||||
"FLASH",
|
"FLASH",
|
||||||
|
"TRNG",
|
||||||
"STCLK_OFF_DURING_SLEEP"
|
"STCLK_OFF_DURING_SLEEP"
|
||||||
],
|
],
|
||||||
"extra_labels": [
|
"extra_labels": [
|
||||||
|
@ -3671,7 +3673,7 @@
|
||||||
"supported_form_factors": ["ARDUINO"],
|
"supported_form_factors": ["ARDUINO"],
|
||||||
"inherits": ["MCU_NRF52840"],
|
"inherits": ["MCU_NRF52840"],
|
||||||
"macros_add": ["BOARD_PCA10056", "CONFIG_GPIO_AS_PINRESET", "SWI_DISABLE0", "NRF52_ERRATA_20"],
|
"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"],
|
"release_versions": ["5"],
|
||||||
"device_name": "nRF52840_xxAA",
|
"device_name": "nRF52840_xxAA",
|
||||||
"bootloader_supported": true
|
"bootloader_supported": true
|
||||||
|
|
Loading…
Reference in New Issue