mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-18 11:33:59 +00:00
fix: correctly handle calls for GetRNG() when being made from nrf devices with SoftDevice enabled.
Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
@@ -318,9 +318,9 @@ func (i2c *I2C) signalStop() error {
|
|||||||
|
|
||||||
var rngStarted = false
|
var rngStarted = false
|
||||||
|
|
||||||
// GetRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
|
// getRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
|
||||||
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
|
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
|
||||||
func GetRNG() (ret uint32, err error) {
|
func getRNG() (ret uint32, err error) {
|
||||||
// There's no apparent way to check the status of the RNG peripheral's task, so simply start it
|
// There's no apparent way to check the status of the RNG peripheral's task, so simply start it
|
||||||
// to avoid deadlocking while waiting for output.
|
// to avoid deadlocking while waiting for output.
|
||||||
if !rngStarted {
|
if !rngStarted {
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
//go:build nrf && !softdevice
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
// GetRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
|
||||||
|
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
|
||||||
|
func GetRNG() (ret uint32, err error) {
|
||||||
|
return getRNG()
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
//go:build nrf && softdevice
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/arm"
|
||||||
|
"device/nrf"
|
||||||
|
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// avoid a heap allocation in GetRNG.
|
||||||
|
var (
|
||||||
|
softdeviceEnabled uint8
|
||||||
|
bytesAvailable uint8
|
||||||
|
buf [4]uint8
|
||||||
|
|
||||||
|
errNoSoftDeviceSupport = errors.New("rng: softdevice not supported on this device")
|
||||||
|
errNotEnoughRandomData = errors.New("rng: not enough random data available")
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
|
||||||
|
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
|
||||||
|
func GetRNG() (ret uint32, err error) {
|
||||||
|
// First check whether the SoftDevice is enabled.
|
||||||
|
// sd_rand_application_bytes_available_get cannot be called when the SoftDevice is not enabled.
|
||||||
|
arm.SVCall1(0x12, &softdeviceEnabled) // sd_softdevice_is_enabled
|
||||||
|
|
||||||
|
if softdeviceEnabled == 0 {
|
||||||
|
return getRNG()
|
||||||
|
}
|
||||||
|
|
||||||
|
// call into the SoftDevice to get random data bytes available
|
||||||
|
switch nrf.Device {
|
||||||
|
case "nrf51":
|
||||||
|
// sd_rand_application_bytes_available_get: SOC_SVC_BASE_NOT_AVAILABLE + 4
|
||||||
|
arm.SVCall1(0x2B+4, &bytesAvailable)
|
||||||
|
case "nrf52", "nrf52840", "nrf52833":
|
||||||
|
// sd_rand_application_bytes_available_get: SOC_SVC_BASE_NOT_AVAILABLE + 4
|
||||||
|
arm.SVCall1(0x2C+4, &bytesAvailable)
|
||||||
|
default:
|
||||||
|
return 0, errNoSoftDeviceSupport
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytesAvailable < 4 {
|
||||||
|
return 0, errNotEnoughRandomData
|
||||||
|
}
|
||||||
|
|
||||||
|
switch nrf.Device {
|
||||||
|
case "nrf51":
|
||||||
|
// sd_rand_application_vector_get: SOC_SVC_BASE_NOT_AVAILABLE + 5
|
||||||
|
arm.SVCall2(0x2B+5, &buf, 4)
|
||||||
|
case "nrf52", "nrf52840", "nrf52833":
|
||||||
|
// sd_rand_application_vector_get: SOC_SVC_BASE_NOT_AVAILABLE + 5
|
||||||
|
arm.SVCall2(0x2C+5, &buf, 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user