github.com/f-secure-foundry/tamago@v0.0.0-20220307101044-d73fcdd7f11b/soc/imx6/rng.go (about)

     1  // NXP Random Number Generator (RNGB) driver
     2  // https://github.com/f-secure-foundry/tamago
     3  //
     4  // Copyright (c) F-Secure Corporation
     5  // https://foundry.f-secure.com
     6  //
     7  // Use of this source code is governed by the license
     8  // that can be found in the LICENSE file.
     9  
    10  package imx6
    11  
    12  import (
    13  	_ "unsafe"
    14  
    15  	"github.com/f-secure-foundry/tamago/soc/imx6/rngb"
    16  )
    17  
    18  var lcg uint32
    19  var getRandomDataFn func([]byte)
    20  
    21  //go:linkname initRNG runtime.initRNG
    22  func initRNG() {
    23  	if Family == IMX6ULL && Native {
    24  		rngb.Init()
    25  		getRandomDataFn = rngb.GetRandomData
    26  	} else {
    27  		getRandomDataFn = getLCGData
    28  	}
    29  }
    30  
    31  //go:linkname getRandomData runtime.getRandomData
    32  func getRandomData(b []byte) {
    33  	getRandomDataFn(b)
    34  }
    35  
    36  // getLCGData implements a Linear Congruential Generator
    37  // (https://en.wikipedia.org/wiki/Linear_congruential_generator).
    38  func getLCGData(b []byte) {
    39  	if lcg == 0 {
    40  		lcg = uint32(ARM.TimerFn())
    41  	}
    42  
    43  	read := 0
    44  	need := len(b)
    45  
    46  	for read < need {
    47  		lcg = (1103515245*lcg + 12345) % (1 << 31)
    48  		read = rngb.Fill(b, read, lcg)
    49  	}
    50  }
    51  
    52  // SetRNG allows to override the random number generator function selected
    53  // internally by TamaGo as runtime.getRandomData.
    54  //
    55  // At runtime initialization the imx6 package selects either the NXP True
    56  // Random Number Generator (RNGB) driver or a timer seeded LCG, depending
    57  // whether a real or emulated SoC is detected.
    58  func SetRNG(getRandomData func([]byte)) {
    59  	getRandomDataFn = getRandomData
    60  }