diff options
author | Joey Castillo <joeycastillo@utexas.edu> | 2021-12-03 19:42:16 -0500 |
---|---|---|
committer | Joey Castillo <joeycastillo@utexas.edu> | 2021-12-03 21:12:15 -0500 |
commit | bbd394a19aaa334a179c36cf2ed2a066f1bb312c (patch) | |
tree | 8406ff96ded0bd664bcfa06b4dc5d13e862f9913 /watch-library/watch/watch_private.c | |
parent | 5a6bf6bfe24c4631a02e53b06f352b654b147dba (diff) | |
download | Sensor-Watch-bbd394a19aaa334a179c36cf2ed2a066f1bb312c.tar.gz Sensor-Watch-bbd394a19aaa334a179c36cf2ed2a066f1bb312c.tar.bz2 Sensor-Watch-bbd394a19aaa334a179c36cf2ed2a066f1bb312c.zip |
use true random number generator to provide entropy
Diffstat (limited to 'watch-library/watch/watch_private.c')
-rw-r--r-- | watch-library/watch/watch_private.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/watch-library/watch/watch_private.c b/watch-library/watch/watch_private.c index 270208dc..e652b271 100644 --- a/watch-library/watch/watch_private.c +++ b/watch-library/watch/watch_private.c @@ -65,6 +65,38 @@ void _watch_init() { a4_callback = NULL; } +static inline void _watch_wait_for_entropy() { + while (!hri_trng_get_INTFLAG_reg(TRNG, TRNG_INTFLAG_DATARDY)); +} + +// this function is called by arc4random to get entropy for random number generation. +// let's use the SAM L22's true random number generator to seed the PRNG! +int getentropy(void *buf, size_t buflen) { + hri_mclk_set_APBCMASK_TRNG_bit(MCLK); + hri_trng_set_CTRLA_ENABLE_bit(TRNG); + + size_t i = 0; + while(i < buflen / 4) { + _watch_wait_for_entropy(); + ((uint32_t *)buf)[i++] = hri_trng_read_DATA_reg(TRNG); + } + + // but what if they asked for an awkward number of bytes? + if (buflen % 4) { + // all good: let's fill in one, two or three bytes at the end of the buffer. + _watch_wait_for_entropy(); + uint32_t last_little_bit = hri_trng_read_DATA_reg(TRNG); + for(size_t j = 0; j <= (buflen % 4); j++) { + ((uint8_t *)buf)[i * 4 + j] = (last_little_bit >> (j * 8)) & 0xFF; + } + } + + hri_trng_clear_CTRLA_ENABLE_bit(TRNG); + hri_mclk_clear_APBCMASK_TRNG_bit(MCLK); + + return 0; +} + void _watch_enable_tcc() { // clock TCC0 with the main clock (8 MHz) and enable the peripheral clock. hri_gclk_write_PCHCTRL_reg(GCLK, TCC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK0_Val | GCLK_PCHCTRL_CHEN); |