]> git.earman.xyz Git - sensor-watch.git/commitdiff
use true random number generator to provide entropy
authorJoey Castillo <joeycastillo@utexas.edu>
Sat, 4 Dec 2021 00:42:16 +0000 (19:42 -0500)
committerJoey Castillo <joeycastillo@utexas.edu>
Sat, 4 Dec 2021 02:12:15 +0000 (21:12 -0500)
watch-library/watch/watch_private.c

index 270208dc4d1c6f78ac98261b8c5ad2fa6a9d4cfe..e652b271c324fdacdf6bfa8eacbef8fdf9ff5634 100644 (file)
@@ -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);