Skip to content

Commit 91e9c84

Browse files
aykevldeadprogram
authored andcommitted
nrf: make GetRNG available to all chips
All nrf chips have a cryptographically secure RNG on board. Therefore, I've made the code more portable so that it works on all nrf chips. I did remove a number of exported functions. I am of the opinion that these should only be made available once we have an agreed upon API for multiple chips. People who want to have greater control over the RNG should use the device/nrf package directly instead. I have also changed the behavior to always enable digital error correction. Enabling it seems like a more conservative (and secure) default to me. Again, people who would like to have it disabled can use the device/nrf package directly.
1 parent 4af530f commit 91e9c84

File tree

3 files changed

+29
-62
lines changed

3 files changed

+29
-62
lines changed

src/crypto/rand/rand_baremetal.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//go:build nrf52840 || stm32 || (sam && atsamd51) || (sam && atsame5x)
2-
// +build nrf52840 stm32 sam,atsamd51 sam,atsame5x
1+
//go:build nrf || stm32 || (sam && atsamd51) || (sam && atsame5x)
2+
// +build nrf stm32 sam,atsamd51 sam,atsame5x
33

44
package rand
55

src/machine/machine_nrf.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,30 @@ func (i2c *I2C) readByte() (byte, error) {
350350
i2c.Bus.EVENTS_RXDREADY.Set(0)
351351
return byte(i2c.Bus.RXD.Get()), nil
352352
}
353+
354+
var rngStarted = false
355+
356+
// GetRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
357+
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
358+
func GetRNG() (ret uint32, err error) {
359+
// There's no apparent way to check the status of the RNG peripheral's task, so simply start it
360+
// to avoid deadlocking while waiting for output.
361+
if !rngStarted {
362+
nrf.RNG.TASKS_START.Set(1)
363+
nrf.RNG.SetCONFIG_DERCEN(nrf.RNG_CONFIG_DERCEN_Enabled)
364+
rngStarted = true
365+
}
366+
367+
// The RNG returns one byte at a time, so stack up four bytes into a single uint32 for return.
368+
for i := 0; i < 4; i++ {
369+
// Wait for data to be ready.
370+
for nrf.RNG.EVENTS_VALRDY.Get() == 0 {
371+
}
372+
// Append random byte to output.
373+
ret = (ret << 8) ^ nrf.RNG.GetVALUE()
374+
// Unset the EVENTS_VALRDY register to avoid reading the same random output twice.
375+
nrf.RNG.EVENTS_VALRDY.Set(0)
376+
}
377+
378+
return ret, nil
379+
}

src/machine/machine_nrf52840_rng.go

Lines changed: 0 additions & 60 deletions
This file was deleted.

0 commit comments

Comments
 (0)