-
Notifications
You must be signed in to change notification settings - Fork 929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stm32wl RNG #2351
Stm32wl RNG #2351
Conversation
I definetly think this should be implemented as a Func (Rand) Uint32() uint32 { This could then make it easier to develop third party libraries that depend on Randers |
Hi @soypat, Thanks for your feedback. |
In the spirit of compatibility with base golang, I believe that this is where TRNG would be implemented. https://pkg.go.dev/crypto/rand https://cs.opensource.google/go/go/+/master:src/crypto/rand/ Is the tinygo team's relationship with the main branch team of golang such that they would accept a PR into the main repo for a "machine" build tag? |
rayozzie's suggestion seems to be the ideal implementation. Maybe we could have a The way to go about this would be to add a |
Honestly, to make things more tractable for the golang team, wouldn’t it make more sense to have a standard interface in the machine package so as to just bother them once? Many stm32 variants and many non-stm32’ s have TRNG’s (mine, for example, is STM32L4R5) and it would seem best IMO to just submit a PR once for all of tinygo and then manage the variants in our world separately. No? This is all assuming, of course, that they’ll accept a PR for tinygo at all. |
Hi, Don't you think I'd be simpler to have a private, tinygo-only Rand implementation. What would be the benefits of having a full Go crypto/rand.Reader implementation ? How can we deal with MCUs without RNG devices ? |
My apologies, but I am not familiar with the overall tinygo philosophy as it relates to 'trying to stay consistent with the base language and core libraries' vs divergence. It may make sense to do just that. Please interpret my comment as "if the high order bit is to do it the same way as go, here's what probably makes sense". And to be clear, it's impossible to 'simulate' trng else it would be prng. And so i (personally) would just not implement the machine support for those platforms and let there be a compile error that needs to be dealt with by the dev. |
I wasn't talking about bothering the Golang team by asking them to add a |
I finally :
That works fine when testing on nucleo-wl55jc board |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
src/crypto/rand/rand_stm32wle5.go
Outdated
// Enable TRNG clock and peripheral | ||
stm32.RCC.AHB3ENR.SetBits(stm32.RCC_AHB3ENR_RNGEN) | ||
if !stm32.RNG.CR.HasBits(stm32.RNG_CR_RNGEN) { | ||
stm32.RNG.CR.SetBits(stm32.RNG_CR_RNGEN) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need to do this for every call or this is something that can be done once, for example in the init or Read function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the code looks very portable to most stm32. Perhaps put just the initialization code that references AHB3 in a chip-specific file, and the other code for all stm32? @ofauchon if you don’t fancy doing that, I can take a pass after this is merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4c117d8
to
bbd159a
Compare
I'm not entirely happy with putting such low-level chip specific code in the crypto/rand package. I would prefer if low-level code was centralized in the machine and runtime packages. However, in that case it still needs to be used from the crypto/rand package. So I would propose the following:
I've picked uint32 (instead of uint8) because that's what many microcontroller families output. I've checked stm32, esp32, nrf, and atsamd51 (nrf is the only one with 8 bit output). Also: if you request random data for cryptographic operations, you probably want a multiple of 4 bytes anyway (128 bits, 256 bits, etc) so there is little loss on a chip that outputs only bytes of random data, for example. |
To chime in on @aykevl comment: I would like to be able to implement this hypothetical |
Why not having a fallback crypto/rand/rand_external.go (When it's not freebsd,linux, windows ...etc). Then, any machine or external tinygo-driver could 'register' a Randomer interface/functions in rand_external.go Later, If you try to use crypto/rand and no Randomer is registered -> Read will fire an error. Sorry If I misunderstood the problem or if it' a bad solution :-) |
@ofauchon just read your last comment. That sounds like a good strategy to me! |
Actually, it's much simpler. Ron's use case could be solved simply by setting the You can easily do something like this: import "tinygo.org/x/drivers/somedriver"
import "crypto/rand"
func init() {
rand.Reader = somedriver.New(...)
}
func main() {
rand.Read(...)
} Of course that doesn't make it fully magical: you still need to initialize the driver. But I don't think that's a bad thing in this case. @deadprogram would this work for you?
Nothing hypothetical, it already exists. It is called |
OK that sounds perfect. Also, I am in total agreement about not consuming drivers from within the compiler packages. |
58daeea
to
4065599
Compare
Hi all, Thanks for this gread discussion. Please note :
Thanks again on time spend on this review . Olivier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. However, I think we can name the file rand_baremetal.go instead of rand_stm32.go because there are many other chips with a RNG and they should all use the same machine functions.
4065599
to
d7f9bc0
Compare
src/crypto/rand/rand_baremetal.go
Outdated
func init() { | ||
|
||
Reader = &reader{} | ||
machine.InitRNG() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of the naming for these 2 functions or the tedious InitRNG
as a requirement.
It would be simpler to do lazy initialization on the first call to ReadRNG
. This simplifies the requirements on any machine
that implements it to a single function call, which I would propose be renamed GetRNG
, since it is a fixed-length return variable unlike the various Read
functions.
If the machine
chooses it wants to add automatic initRNG
, it can do so privately in its own init
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me. It does make reading random numbers slightly slower but that's probably negligible and IMHO outweighs the API simplicity.
No strong opinions on GetRNG
vs ReadRNG
from me. I picked ReadRNG
because it makes it clear that it's not just a getter, but on the other hand you also have getrandom
and getentropy
syscalls (with a get
prefix).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the
machine
chooses it wants to add automaticinitRNG
, it can do so privately in its owninit
.
I don't think we should do that because it means the RNG is always initialized, even when unused (which might result in higher current consumption, etc).
8186117
to
b5ce8ff
Compare
Hi. I tried to i include most of your proposals in this last commit :
Hope this is the good one :-) |
b5ce8ff
to
8c9bbe9
Compare
The last changes were tested on nucleo-wl55jc board |
Thank you @ofauchon for your persistence in getting this feature added, and thank you to everyone who helped to define it. Now merging! |
This is code for using STM32WL's True Random Number Generator:
I added the GetRand32() function in machine package, but I'm not sure this is the good place.
(not even sure it should be part of tinygo core...)
All comments welcome.