use true random number generator to provide entropy

This commit is contained in:
Joey Castillo 2021-12-03 19:42:16 -05:00
parent 5a6bf6bfe2
commit bbd394a19a

View File

@ -65,6 +65,38 @@ void _watch_init() {
a4_callback = NULL; 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() { void _watch_enable_tcc() {
// clock TCC0 with the main clock (8 MHz) and enable the peripheral clock. // 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); hri_gclk_write_PCHCTRL_reg(GCLK, TCC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK0_Val | GCLK_PCHCTRL_CHEN);