# HG changeset patch # User Matt Johnston # Date 1372311600 0 # Node ID cce426bb6d3e3088a8afba48f3a0f018c0da3d34 # Parent b210df11f968f0a22159100dd5274a419e1a0328 fix rng and short watchdog diff -r b210df11f968 -r cce426bb6d3e Makefile --- 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!): diff -r b210df11f968 -r cce426bb6d3e main.c --- 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},