diff --git a/src/crypto/rand/rand_baremetal.go b/src/crypto/rand/rand_baremetal.go new file mode 100644 index 00000000..3fe4cae7 --- /dev/null +++ b/src/crypto/rand/rand_baremetal.go @@ -0,0 +1,36 @@ +//go:build stm32wle5 +// +build stm32wle5 + +package rand + +import ( + "machine" +) + +func init() { + Reader = &reader{} +} + +type reader struct { +} + +func (r *reader) Read(b []byte) (n int, err error) { + if len(b) == 0 { + return + } + + var randomByte uint32 + for i := range b { + if i%4 == 0 { + randomByte, err = machine.GetRNG() + if err != nil { + return n, err + } + } else { + randomByte >>= 8 + } + b[i] = byte(randomByte) + } + + return len(b), nil +} diff --git a/src/machine/machine.go b/src/machine/machine.go index 0d7dc53e..06274220 100644 --- a/src/machine/machine.go +++ b/src/machine/machine.go @@ -3,6 +3,7 @@ package machine import "errors" var ( + ErrTimeoutRNG = errors.New("machine: RNG Timeout") ErrInvalidInputPin = errors.New("machine: invalid input pin") ErrInvalidOutputPin = errors.New("machine: invalid output pin") ErrInvalidClockPin = errors.New("machine: invalid clock pin") diff --git a/src/machine/machine_stm32wle5.go b/src/machine/machine_stm32wle5.go index 29c9c584..63992325 100644 --- a/src/machine/machine_stm32wle5.go +++ b/src/machine/machine_stm32wle5.go @@ -13,6 +13,8 @@ import ( "unsafe" ) +var rngInitDone = false + const ( AF0_SYSTEM = 0 AF1_TIM1_2_LPTIM1 = 1 @@ -30,9 +32,10 @@ const ( ) const ( - SYSCLK = 48e6 - APB1_TIM_FREQ = SYSCLK - APB2_TIM_FREQ = SYSCLK + SYSCLK = 48e6 + APB1_TIM_FREQ = SYSCLK + APB2_TIM_FREQ = SYSCLK + RNG_MAX_READ_RETRIES = 1000 ) func CPUFrequency() uint32 { @@ -396,6 +399,27 @@ func (t *TIM) enableMainOutput() { t.Device.BDTR.SetBits(stm32.TIM_BDTR_MOE) } +// GetRNG returns 32 bits of cryptographically secure random data +func GetRNG() (uint32, error) { + + if !rngInitDone { + stm32.RCC.AHB3ENR.SetBits(stm32.RCC_AHB3ENR_RNGEN) + stm32.RNG.CR.SetBits(stm32.RNG_CR_RNGEN) + rngInitDone = true + } + cnt := RNG_MAX_READ_RETRIES + for cnt > 0 && !stm32.RNG.SR.HasBits(stm32.RNG_SR_DRDY) { + cnt-- + } + if cnt == 0 { + return 0, ErrTimeoutRNG + } + ret := stm32.RNG.DR.Get() + return ret, nil +} + +//---------- + type arrtype = uint32 type arrRegType = volatile.Register32 diff --git a/src/runtime/runtime_stm32wle5.go b/src/runtime/runtime_stm32wle5.go index 7a431f64..671ffd65 100644 --- a/src/runtime/runtime_stm32wle5.go +++ b/src/runtime/runtime_stm32wle5.go @@ -57,7 +57,7 @@ func initCLK() { ((PLL_Q - 1) << stm32.RCC_PLLCFGR_PLLQ_Pos) | ((PLL_R - 1) << stm32.RCC_PLLCFGR_PLLR_Pos) | ((PLL_P - 1) << stm32.RCC_PLLCFGR_PLLP_Pos) | - stm32.RCC_PLLCFGR_PLLSRC_HSE32 | stm32.RCC_PLLCFGR_PLLPEN) + stm32.RCC_PLLCFGR_PLLSRC_HSE32 | stm32.RCC_PLLCFGR_PLLPEN | stm32.RCC_PLLCFGR_PLLQEN) // Enable PLL stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) @@ -98,6 +98,7 @@ func initCLK() { stm32.RCC.CFGR.ReplaceBits(stm32.RCC_CFGR_SW_PLLR, stm32.RCC_CFGR_SW_Msk, 0) for (stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk) != (stm32.RCC_CFGR_SWS_PLLR << stm32.RCC_CFGR_SWS_Pos) { } + } func putchar(c byte) {