changeset 35:cce426bb6d3e

fix rng and short watchdog
author Matt Johnston <matt@ucc.asn.au>
date Thu, 27 Jun 2013 05:40:00 +0000
parents b210df11f968
children c6f77df67dde
files Makefile main.c
diffstat 2 files changed, 61 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Jun 27 12:03:40 2013 +0800
+++ b/Makefile	Thu Jun 27 05:40:00 2013 +0000
@@ -21,7 +21,7 @@
 PROGDEVICE     = atmega328p
 CLOCK      = 11059200L
 PROGRAMMER = #-c stk500v2 -P avrdoper
-PROGRAMMER = -c stk500 -P ~/dev/stk500 -p $(PROGDEVICE)  -B 2
+PROGRAMMER = -c arduino -b 115200 -P /dev/ttyAMA0 -p $(PROGDEVICE)  -B 2
 SOURCE_1WIRE = onewire.c simple_ds18b20.c crc8.c
 SOURCE_CRYPTO = hmac-sha1.c sha1-asm.S aes.c
 SOURCE_SD = byteordering.c fat.c  partition.c sd_raw.c 
@@ -36,14 +36,26 @@
 FUSES      = -U hfuse:w:0xd9:m -U lfuse:w:0x77:m -U efuse:w:0xfd:m
 
 #LOCKBIT
-# -U lock:w:0x28:m
+# prevent bootloader write protect:
+# -U lock:w:0x2f:m
 # 0  unused bit7
 # 0  unused
 # 1 blb12  no writing to bootloader
 # 0 blb11
-# 1 blb02  no writing to app
+# 1 blb02  bootloader can write to app
+# 1 blb01
+# 1 lb2           external serial prog unrestricted
+# 1 lb1 bit0
+
+# stop everything:
+# -U lock:w:0x20:m
+# 0  unused bit7
+# 0  unused
+# 1 blb12  no writing to bootloader
+# 0 blb11
+# 0 blb02  
 # 0 blb01
-# 0 lb2
+# 0 lb2            
 # 0 lb1 bit0
 
 # ATMega8 fuse bits used above (fuse bits for other devices are different!):
--- a/main.c	Thu Jun 27 12:03:40 2013 +0800
+++ b/main.c	Thu Jun 27 05:40:00 2013 +0000
@@ -422,6 +422,30 @@
     }
 }
 
+// returns 1 if they are equal, timing independent
+static uint8_t
+safe_mem_eq(const uint8_t *a, const uint8_t *b, int len)
+{
+    uint8_t result = 0;
+    for (int i = 0; i < len; i++)
+    {
+        result |= a[i] ^ b[i];
+    }
+    return result == 0;
+}
+
+// returns 1 if they are equal
+static uint8_t
+safe_str_eq(const char *a, const char *b)
+{
+    int la = strlen(a);
+    if (la != strlen(b))
+    {
+        return 0;
+    }
+    return safe_mem_eq((const uint8_t*)a, (const uint8_t*)b, la);
+}
+
 uint8_t from_hex(char c)
 {
     if (c >= '0' && c <= '9') {
@@ -558,7 +582,7 @@
     memcpy(&output[2], &indata[HMACLEN], AESLEN);
     hmac_sha1(output, avr_keys[key_index], KEYLEN*8, output, (2+AESLEN)*8);
 
-    if (memcmp(output, indata, HMACLEN) != 0) {
+    if (!safe_mem_eq(output, indata, HMACLEN)) {
         printf_P(PSTR("FAIL: hmac mismatch\n"));
     }
 
@@ -633,6 +657,16 @@
 }
 
 static void
+cmd_poke()
+{
+    printf_P(PSTR("Ah, good.\n"));
+    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+    {
+        watchdog_short_count = 0;
+    }
+}
+
+static void
 cmd_vcc()
 {
     uint16_t vcc = adc_vcc();
@@ -657,7 +691,7 @@
 static void
 cmd_prog(const char* arg)
 {
-    if (strcmp(arg, PROG_PASSWORD) != 0)
+    if (safe_str_eq(arg, PROG_PASSWORD))
     {
         printf_P(PSTR("Bad prog password\n"));
         return;
@@ -715,23 +749,26 @@
     loop_until_bit_is_clear(ADCSRA, ADSC);
     uint8_t low = ADCL;
     uint8_t high = ADCH;
-    return (popcnt(low)&1) ^ (popcnt(high)&1);
+    uint8_t ret = (popcnt(low)&1) ^ (popcnt(high)&1);
+    return ret;
 }
 
 static void
 adc_random(uint8_t admux, 
     uint8_t *out, uint16_t num, uint32_t *tries)
 {
-    uint8_t ret = 0;
-    uint8_t count = 0;
-
     PRR &= ~_BV(PRADC);
     // /16 prescaler for 691mhz, no interrupt
     ADCSRA = _BV(ADEN) | _BV(ADPS2);
 
+    ADMUX = admux;
+
     *tries = 0;
     for (int i = 0; i < num; i++)
     {
+        uint8_t ret = 0;
+        uint8_t count = 0;
+
         while (count <= 7)
         {
             (*tries)++;
@@ -897,6 +934,7 @@
     LOCAL_PSTR(hmac);
     LOCAL_PSTR(decrypt);
     LOCAL_PSTR(alive);
+    LOCAL_PSTR(poke);
     LOCAL_PSTR(vcc);
     LOCAL_PSTR(reset);
     LOCAL_PSTR(newboot);
@@ -920,6 +958,7 @@
     } handlers[] PROGMEM = 
     {
         {alive_str, cmd_alive, NULL},
+        {poke_str, cmd_poke, NULL},
         {newboot_str, cmd_newboot, NULL},
         {oldboot_str, cmd_oldboot, NULL},
         {oneshot_str, cmd_oneshot_reboot, oneshot_help},