aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordberg.se>2016-05-18 12:07:50 +0200
committerLinus Nordberg <linus@nordberg.se>2016-05-18 12:07:50 +0200
commit7ebd56579f5e90861c39fdf46fa7d53446cfeccf (patch)
treef651b62eed0fbecfb476758e12abafe69f9a1678
Read from and write to MKM when panic button is pressed.
-rw-r--r--Makefile14
-rw-r--r--README.md33
-rw-r--r--tamper.c227
-rwxr-xr-xupload.sh6
4 files changed, 280 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..8ac277b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+CC = avr-gcc
+CFLAGS = -Wall -Werror -mmcu=avr25 -D__AVR_ATtiny828__
+OBJCOPY = avr-objcopy
+
+all: tamper.hex
+
+%.elf: %.c
+ $(CC) $(CFLAGS) -o $@ $^
+
+%.hex: %.elf
+ $(OBJCOPY) -O ihex $< $@
+
+clean:
+ -rm *.o *.elf *.hex
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2ccba7d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+Tamper detection for Atmel AVR ATtiny828 MCU on the Cryptech alpha
+board, rev02.
+
+ *************
+ * P A N I C *
+ * button *
+ *************
+ /
+ /
+ /
+ AVR ---- SPI mux ---- FPGA
+ | |
+ | ARM
+ MKM
+
+AVR -- Atmel MCU
+FPGA -- FPGA
+MKM -- Master Key Memory, 23K640 SRAM
+SPI mux -- 2 x MC74AC244DW
+ARM -- ARM CPU
+
+The MKM holds the master key for the device.
+
+The AVR, MKM and the mux are battery powered.
+
+The AVR and the FPGA are sharing access to the MKM through the mux,
+with the AVR connected to the pins used for deciding who's in control
+of the memory. The FPGA is in control by default.
+
+When the panic button is pressed, the AVR grabs the MKM and writes
+zeros to it as quickly as possible. In idle mode, i.e. when the panic
+button is not pressed, the AVR tries to consume as little power as
+possible.
diff --git a/tamper.c b/tamper.c
new file mode 100644
index 0000000..ca3cb2d
--- /dev/null
+++ b/tamper.c
@@ -0,0 +1,227 @@
+/* FIXME: copyright */
+
+#include <inttypes.h>
+#include <avr/io.h> /* -D__AVR_ATtiny828__ will include <avr/iotn828.h> */
+
+/* Mapping of pins to names. */
+#define AVR_LED1 PORTA0
+#define AVR_LED2 PORTA3
+#define AVR_LED3 PORTA2
+#define AVR_LED4 PORTA1
+#define AVR_PANIC PORTA4
+
+#define MKM_AVR_CS_N PORTA5
+#define MKM_CONTROL_AVR_ENA PORTA6
+#define MKM_CONTROL_FPGA_DIS PORTA7
+
+#define MKM_AVR_MOSI PORTD0
+#define MKM_AVR_MISO PORTD1
+#define MKM_AVR_SCK PORTD3
+
+
+/* Input pins. */
+#define AVR_PANIC_PIN PINA /* Panic button. */
+#define AVR_PANIC_BIT PINA4 /* 0 = panic. */
+
+/* Output ports. */
+#define AVR_LED_PORT PORTA
+#define AVR_LED_BLUE_BIT PORTA0
+#define AVR_LED_RED_BIT PORTA3
+#define AVR_LED_YELLOW_BIT PORTA2
+#define AVR_LED_GREEN_BIT PORTA1
+
+#define MKM_CS_PORT PORTA /* MKM chip select. */
+#define MKM_CS_BIT MKM_AVR_CS_N /* 0 -> selected. */
+
+#define MKM_CONTROL_AVR_PORT PORTA /* AVR in control. */
+#define MKM_CONTROL_AVR_BIT MKM_CONTROL_AVR_ENA /* 0 -> in control. */
+
+#define MKM_CONTROL_FPGA_PORT PORTA /* FPGA in control. */
+#define MKM_CONTROL_FPGA_BIT MKM_CONTROL_FPGA_DIS /* 0 -> in control. */
+
+/* SPI. */
+#define MKM_AVR_MOSI_PORT PORTD
+#define MKM_AVR_MOSI_BIT MKM_AVR_MOSI /* PD0, Master Out Slave In. */
+#define MKM_AVR_MISO_PORT PORTD
+#define MKM_AVR_MISO_BIT PORTD1 /* PD1, Master In Slave Out. */
+#define MKM_AVR_SCK_PORT PORTD
+#define MKM_AVR_SCK_BIT PORTD3 /* PD3, SPI clock. */
+
+/*******/
+/* MKM */
+static inline void
+mkm_chip_select(int select_flag)
+{
+ if (select_flag)
+ MKM_CS_PORT &= ~_BV(MKM_CS_BIT); /* CS low. */
+ else
+ MKM_CS_PORT |= _BV(MKM_CS_BIT); /* CS high. */
+}
+
+static inline void
+mkm_grab()
+{
+ MKM_CONTROL_FPGA_PORT |= _BV(MKM_CONTROL_FPGA_BIT);
+ MKM_CONTROL_AVR_PORT &= ~_BV(MKM_CONTROL_AVR_BIT);
+}
+
+static inline void
+mkm_release()
+{
+ MKM_CONTROL_AVR_PORT |= _BV(MKM_CONTROL_AVR_BIT);
+ MKM_CONTROL_FPGA_PORT &= ~_BV(MKM_CONTROL_FPGA_BIT);
+}
+
+/*******/
+/* SPI */
+#define SPI_SS DDRC0 /* SPI slave select. */
+
+static inline void
+spi_setup(int on_flag)
+{
+ if (on_flag)
+ {
+ /* Disable SPI power reduction. */
+ PRR &= ~_BV(PRSPI);
+
+ /* Set MOSI and SCK to output. */
+ DDRD = _BV(MKM_AVR_MOSI_BIT) | _BV(MKM_AVR_SCK_BIT);
+
+ /* Make sure SPI slave select (SS) is configured as output before
+ enabling SPI master mode!. */
+ DDRC |= _BV(SPI_SS);
+
+ /* Enable SPI in master mode, clock rate f/16. */
+ SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
+ }
+ else
+ {
+ SPCR &= ~_BV(SPE);
+ PRR |= _BV(PRSPI);
+ }
+}
+
+/* SPI commands for MKM (23K640). */
+#define SPI_READ 0x03
+#define SPI_WRITE 0x02
+#define SPI_RDSR 0x05 /* Read status register. */
+#define SPI_WRSR 0x01 /* Write status register. */
+
+static inline void
+spi_write(uint8_t val)
+{
+ SPDR = val;
+ loop_until_bit_is_set(SPSR, SPIF);
+}
+
+static inline uint8_t
+spi_read()
+{
+ spi_write(0);
+ return SPDR;
+}
+
+static inline uint8_t
+spi_read_status()
+{
+ spi_write(SPI_RDSR);
+ return SPDR;
+}
+
+static inline void
+spi_set_operation_byte()
+{
+ spi_write(SPI_WRSR);
+ spi_write(0x00);
+}
+
+static inline void
+spi_set_operation_page()
+{
+ spi_write(SPI_WRSR);
+ spi_write(0x80);
+}
+
+static inline void
+spi_set_operation_seq()
+{
+ spi_write(SPI_WRSR);
+ spi_write(0x40);
+}
+
+static void
+spi_write_byte(uint16_t addr, uint8_t data)
+{
+ mkm_chip_select(1);
+ spi_write(SPI_WRITE);
+ spi_write(addr & 0xff00);
+ spi_write(addr & 0x00ff);
+ spi_write(data);
+ mkm_chip_select(0);
+}
+
+static uint8_t
+spi_read_byte(uint16_t addr)
+{
+ mkm_chip_select(1);
+ spi_write(SPI_READ);
+ spi_write(addr & 0xff00);
+ spi_write(addr & 0x00ff);
+ uint8_t data = spi_read();
+ mkm_chip_select(0);
+ return data;
+}
+
+static inline int
+panic_p()
+{
+ return !bit_is_set(AVR_PANIC_PIN, AVR_PANIC_BIT);
+}
+
+
+static inline void
+init_ports()
+{
+ /* Configure all PORTA pins except the tamper detection pin to
+ outputs. */
+ DDRA = 0xff & ~_BV(AVR_PANIC_BIT);
+}
+
+int
+main()
+{
+ init_ports();
+
+ int i, j = 0, wait;
+ uint8_t mkm_val = 0;
+ while (1)
+ {
+ if (panic_p())
+ {
+ spi_setup(1);
+ mkm_grab();
+
+ spi_write_byte(0, spi_read_byte(0) + 1);
+ mkm_val = spi_read_byte(0);
+ AVR_LED_PORT = (AVR_LED_PORT & 0xf0) | (mkm_val & 0x0f);
+
+ wait = 32000;
+ }
+ else
+ {
+ mkm_release();
+ spi_setup(0);
+
+ if ((j++ & 1) == 0)
+ AVR_LED_PORT = (AVR_LED_PORT & 0xf0) | 0xa;
+ else
+ AVR_LED_PORT = (AVR_LED_PORT & 0xf0) | 0x5;
+
+ wait = 16000;
+ }
+
+ for (i = 0; i < wait; i++);
+ }
+
+ return 0;
+}
diff --git a/upload.sh b/upload.sh
new file mode 100755
index 0000000..d34d4ed
--- /dev/null
+++ b/upload.sh
@@ -0,0 +1,6 @@
+#! /bin/sh
+
+HEXFILE=$1
+[ -z "$HEXFILE" ] && exit 1
+
+avrdude -c usbtiny -p attiny828 -U flash:w:$HEXFILE