Files
tinygo/src/machine/machine_rp2040_rng.go
T
Ayke van Laethem d3863f337d rp2040: do not use GetRNG in crypto/rand
The crypto/rand package is used for sensitive cryptographic operations.
Do not use the rp2040 RNG for this purpose, because it's not strong
enough for cryptography.

I think it is _possible_ to make use of the RP2040 RNG to create
cryptographically secure pseudo-random numbers, but it needs some
entropy calculation and secure hashing (blake2s or so) to make them
truly unpredictable.
2022-09-16 14:48:41 +02:00

43 lines
969 B
Go

//go:build rp2040
// +build rp2040
// Implementation based on code located here:
// https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_lwip/random.c
package machine
import (
"device/rp"
)
const numberOfCycles = 32
// GetRNG returns 32 bits of semi-random data based on ring oscillator.
//
// Unlike some other implementations of GetRNG, these random numbers are not
// cryptographically secure and must not be used for cryptographic operations
// (nonces, etc).
func GetRNG() (uint32, error) {
var val uint32
for i := 0; i < 4; i++ {
val = (val << 8) | uint32(roscRandByte())
}
return val, nil
}
var randomByte uint8
func roscRandByte() uint8 {
var poly uint8
for i := 0; i < numberOfCycles; i++ {
if randomByte&0x80 != 0 {
poly = 0x35
} else {
poly = 0
}
randomByte = ((randomByte << 1) | uint8(rp.ROSC.GetRANDOMBIT()) ^ poly)
// TODO: delay a little because the random bit is a little slow
}
return randomByte
}