-
Notifications
You must be signed in to change notification settings - Fork 918
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: correctly handle calls for GetRNG() when being made from nrf dev…
…ices with SoftDevice enabled. Signed-off-by: deadprogram <[email protected]>
- Loading branch information
1 parent
217f677
commit 678b405
Showing
3 changed files
with
70 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |