diff --git a/templates/bluepill/test.py b/templates/bluepill/test.py index cea19d5..4ad0430 100755 --- a/templates/bluepill/test.py +++ b/templates/bluepill/test.py @@ -8,8 +8,7 @@ from test_common import ( eprint, test_main, OpenOcd, - FileMutex, - run_nist_lws_aead_test + FileMutex ) @@ -95,6 +94,8 @@ class BluePill(DeviceUnderTestAeadUARTP): eprint("Reset!") def dump_ram(self): + return None + # Broken for now res = self.ocd.send( 'dump_image %s 0x20000000 0x%x' % (self.ram_dump_path, BluePill.RAM_SIZE)) diff --git a/templates/esp32/test.py b/templates/esp32/test.py index b92c369..ac95903 100755 --- a/templates/esp32/test.py +++ b/templates/esp32/test.py @@ -9,8 +9,7 @@ from test_common import ( DeviceUnderTestAeadUARTP, eprint, test_main, - FileMutex, - run_nist_lws_aead_test, + FileMutex ) diff --git a/templates/f1-libopencm3/test.py b/templates/f1-libopencm3/test.py index cea19d5..69b48ff 100755 --- a/templates/f1-libopencm3/test.py +++ b/templates/f1-libopencm3/test.py @@ -8,8 +8,7 @@ from test_common import ( eprint, test_main, OpenOcd, - FileMutex, - run_nist_lws_aead_test + FileMutex ) @@ -21,11 +20,11 @@ def get_serial(): if p.serial_number == 'FT2XCRZ1' ] devices.sort() - eprint("Serial port for BluePill is %s" % devices[0]) + eprint("Serial port for STM32F1 is %s" % devices[0]) return devices[0] -class BluePill(DeviceUnderTestAeadUARTP): +class STM32F1(DeviceUnderTestAeadUARTP): RAM_SIZE = 0x5000 def __init__(self, build_dir): @@ -97,19 +96,19 @@ class BluePill(DeviceUnderTestAeadUARTP): def dump_ram(self): res = self.ocd.send( 'dump_image %s 0x20000000 0x%x' % - (self.ram_dump_path, BluePill.RAM_SIZE)) + (self.ram_dump_path, STM32F1.RAM_SIZE)) eprint(res) assert res == '' eprint("RAM dumped.") with open(self.ram_dump_path, 'rb') as ram: ram = ram.read() - if len(ram) != BluePill.RAM_SIZE: + if len(ram) != STM32F1.RAM_SIZE: raise Exception( "RAM dump was %d bytes instead of %d" % - (len(ram), BluePill.RAM_SIZE)) + (len(ram), STM32F1.RAM_SIZE)) return ram if __name__ == "__main__": - sys.exit(test_main(BluePill, 0x0002, sys.argv)) + sys.exit(test_main(STM32F1, 0x0002, sys.argv)) diff --git a/templates/f7/test.py b/templates/f7/test.py index b66935f..fc50585 100755 --- a/templates/f7/test.py +++ b/templates/f7/test.py @@ -8,8 +8,7 @@ from test_common import ( DeviceUnderTestAeadUARTP, eprint, test_main, - FileMutex, - run_nist_lws_aead_test, + FileMutex ) diff --git a/templates/longan-nano/Makefile b/templates/longan-nano/Makefile new file mode 100644 index 0000000..41fc3b6 --- /dev/null +++ b/templates/longan-nano/Makefile @@ -0,0 +1,15 @@ +NISTGCCFLAGS=-std=c99 -Wall -Wextra -Wshadow -fsanitize=address,undefined -O2 +LFLAGS=-lm +PIO_ENV = sipeed-longan-nano-lite +all: ${PIO_ENV} + +${PIO_ENV}: .pioenvs/${PIO_ENV}/firmware.elf + +.pioenvs/${PIO_ENV}/firmware.elf: FORCE + platformio run -e ${PIO_ENV} + +FORCE: ; +.PHONY: clean + +clean: + -rm .pioenvs/${PIO_ENV}/firmware.elf diff --git a/templates/longan-nano/cleanup b/templates/longan-nano/cleanup new file mode 100755 index 0000000..4db6720 --- /dev/null +++ b/templates/longan-nano/cleanup @@ -0,0 +1,4 @@ +#!/bin/bash + +mv .pio/build/sipeed-longan-nano-lite/firmware.* . +exit 0 diff --git a/templates/longan-nano/configure b/templates/longan-nano/configure new file mode 100755 index 0000000..dfa9981 --- /dev/null +++ b/templates/longan-nano/configure @@ -0,0 +1,12 @@ +#!/bin/bash + +# Rename all *.s to *.S +for f in *.s; do + mv -- "$f" "${f%.s}.S" +done + +mv -n *.c *.S src/ +mv -n *.dat *.inc *.h include/ +sed -i src/encrypt.c -e "s/\(\s\)init(/\1encrypt_init(/g" + +exit 0 diff --git a/templates/longan-nano/empty_ram.bin b/templates/longan-nano/empty_ram.bin new file mode 100644 index 0000000..abdf77b Binary files /dev/null and b/templates/longan-nano/empty_ram.bin differ diff --git a/templates/longan-nano/include/crypto_aead.h b/templates/longan-nano/include/crypto_aead.h new file mode 100644 index 0000000..651490c --- /dev/null +++ b/templates/longan-nano/include/crypto_aead.h @@ -0,0 +1,26 @@ +#ifdef __cplusplus +extern "C" { +#endif + +int crypto_aead_encrypt( + unsigned char *c,unsigned long long *clen, + const unsigned char *m,unsigned long long mlen, + const unsigned char *ad,unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k + ); + + +int crypto_aead_decrypt( + unsigned char *m,unsigned long long *outputmlen, + unsigned char *nsec, + const unsigned char *c,unsigned long long clen, + const unsigned char *ad,unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k + ); + +#ifdef __cplusplus +} +#endif diff --git a/templates/longan-nano/include/uartp.h b/templates/longan-nano/include/uartp.h new file mode 100644 index 0000000..3a80a60 --- /dev/null +++ b/templates/longan-nano/include/uartp.h @@ -0,0 +1,11 @@ +#pragma once +#ifdef __cplusplus +extern "C" { +#endif + +void uartp_send(const void *src, uint16_t len); +uint16_t uartp_recv(void *dst, uint16_t buf_len); + +#ifdef __cplusplus +} +#endif diff --git a/templates/longan-nano/openocd.cfg b/templates/longan-nano/openocd.cfg new file mode 100644 index 0000000..e71c78b --- /dev/null +++ b/templates/longan-nano/openocd.cfg @@ -0,0 +1,32 @@ +interface ftdi +ftdi_device_desc "FT2232H MiniModule" +ftdi_vid_pid 0x0403 0x6010 +ftdi_serial FT2XAA99 +ftdi_channel 0 + +transport select jtag + + +ftdi_layout_init 0x0038 0x003b +ftdi_layout_signal nSRST -data 0x0020 + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d +jtag newtap $_CHIPNAME.1 cpu -irlen 5 -expected-id 0x790007a3 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME gd32vf103 0x08000000 0 0 0 $_TARGETNAME + +riscv expose_csrs 3040-3071 + +adapter_khz 1000 +adapter_nsrst_delay 100 +jtag_ntrst_delay 100 +#reset_config srst_nogate +#reset_config srst_only srst_push_pull srst_nogate connect_assert_srst +reset_config srst_only srst_push_pull srst_nogate + diff --git a/templates/longan-nano/platformio.ini b/templates/longan-nano/platformio.ini new file mode 100644 index 0000000..b3cc17c --- /dev/null +++ b/templates/longan-nano/platformio.ini @@ -0,0 +1,19 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:sipeed-longan-nano-lite] +platform = gd32v +board = sipeed-longan-nano-lite +framework = arduino +board_build.mcu = GD32VF103C8T6 +board_build.f_cpu = 108000000L +build_flags = -O3 -UDEBUG -DNDEBUG +build_unflags = -Os +build_type = release diff --git a/templates/longan-nano/src/main.ino b/templates/longan-nano/src/main.ino new file mode 100644 index 0000000..e760eec --- /dev/null +++ b/templates/longan-nano/src/main.ino @@ -0,0 +1,143 @@ +#include +#include "crypto_aead.h" +#include "api.h" +#include "uartp.h" + +#define MAX_BYTES 172 +#define CMDBUF_LEN 200 +static uint8_t cmdbuf[CMDBUF_LEN]; + +#define CRYPTO_BUSY PA7 +#define noInterrupts() eclic_global_interrupt_disable() +#define interrupts() eclic_global_interrupt_disable() +#define yield() do {} while(0) + +uint8_t npub[CRYPTO_NPUBBYTES]; +uint8_t nsec[CRYPTO_NSECBYTES]; +uint8_t k[CRYPTO_KEYBYTES]; +uint8_t ad[MAX_BYTES]; +uint8_t m[MAX_BYTES]; +uint8_t c[MAX_BYTES]; +unsigned long long int adlen = 0; +unsigned long long int mlen = 0; +unsigned long long int clen = 0; +int res = 0; + +void setup(); +void loop(); + +#ifdef __cplusplus +extern "C" { +#endif + +static void init_uart0(void) +{ + // enable GPIO clock + rcu_periph_clock_enable(RCU_GPIOA); + // enable USART0 clock + rcu_periph_clock_enable(RCU_USART0); + // configure USART0 + usart_deinit(USART0); + usart_baudrate_set(USART0, 4*115200); + usart_word_length_set(USART0, USART_WL_8BIT); + usart_stop_bit_set(USART0, USART_STB_1BIT); + usart_parity_config(USART0, USART_PM_NONE); + usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); + usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); + usart_receive_config(USART0, USART_RECEIVE_ENABLE); + usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); + usart_enable(USART0); +} + +void uart_wbyte(uint8_t x) { + while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET); + usart_data_transmit(USART0, x); + while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET); +} + +uint8_t uart_rbyte() { + while (usart_flag_get(USART0, USART_FLAG_RBNE) == RESET); + return (uint8_t) usart_data_receive(USART0); +} + +void uart_wstr(const char *str) { + char x; + while ((x = *(str++)) != 0) { + uart_wbyte((uint8_t) x); + } +} + +#ifdef __cplusplus +} +#endif + +void my_assert(bool b) { + if (b) + return; + for(;;) + yield(); +} + +void setup() { + init_uart0(); + pinMode(CRYPTO_BUSY, OUTPUT); + digitalWrite(CRYPTO_BUSY, HIGH); + delay(100); + memset(npub, 0, CRYPTO_NPUBBYTES); + memset(nsec, 0, CRYPTO_NSECBYTES); + memset(k, 0, CRYPTO_KEYBYTES); + memset(ad, 0, MAX_BYTES); + memset(m, 0, MAX_BYTES); + memset(c, 0, MAX_BYTES); + uart_wstr("Hello, World!"); +} + +void loop() { + int res; + uint16_t len = uartp_recv(cmdbuf, CMDBUF_LEN - 1); + uint8_t action = cmdbuf[0]; + if (len == 0 || len > CMDBUF_LEN - 1) + return; + + uint16_t l = len - 1; + uint16_t rl = 0; + uint8_t *var = cmdbuf+1; + switch (action) { + case 'm': my_assert(l <= MAX_BYTES); memcpy(m, var, l); mlen = l; break; + case 'c': my_assert(l <= MAX_BYTES); memcpy(c, var, l); clen = l; break; + case 'a': my_assert(l <= MAX_BYTES); memcpy(ad, var, l); adlen = l; break; + case 'k': my_assert(l == CRYPTO_KEYBYTES); memcpy(k, var, l); break; + case 'p': my_assert(l == CRYPTO_NPUBBYTES); memcpy(npub, var, l); break; + case 's': my_assert(l == CRYPTO_NSECBYTES); memcpy(nsec, var, l); break; + case 'e': + noInterrupts(); + asm("nop"); + digitalWrite(CRYPTO_BUSY, LOW); + res = crypto_aead_encrypt(c, &clen, m, mlen, ad, adlen, nsec, npub, k); + digitalWrite(CRYPTO_BUSY, HIGH); + asm("nop"); + interrupts(); + break; + case 'd': + noInterrupts(); + asm("nop"); + digitalWrite(CRYPTO_BUSY, LOW); + res = crypto_aead_decrypt(m, &mlen, nsec, c, clen, ad, adlen, npub, k); + digitalWrite(CRYPTO_BUSY, HIGH); + asm("nop"); + interrupts(); + break; + case'M': var = m; rl = mlen; break; + case'C': var = c; rl = clen; break; + case'A': var = ad; rl = adlen; break; + case'K': var = k; rl = CRYPTO_KEYBYTES; break; + case'P': var = npub; rl = CRYPTO_NPUBBYTES; break; + case'S': var = nsec; rl = CRYPTO_NSECBYTES; break; + case'R': var = (uint8_t *) &res; rl = sizeof(res); break; + default: + my_assert(false); + } + cmdbuf[0] = action; + memcpy(cmdbuf+1, var, rl); + uartp_send(cmdbuf, rl+1); +} diff --git a/templates/longan-nano/src/uartp.c b/templates/longan-nano/src/uartp.c new file mode 100644 index 0000000..03267dd --- /dev/null +++ b/templates/longan-nano/src/uartp.c @@ -0,0 +1,76 @@ +#include +#include "uartp.h" + +extern void uart_wbyte(uint8_t x); +extern uint8_t uart_rbyte(); + +// Simple serial protocol with packets and checksum +const uint8_t AMUX_TAG = 0xf9; +const uint8_t AMUX_END = 0xf3; +const uint8_t AMUX_EXT = 0x80; + +void uartp_send(const void *src, uint16_t len) { + uint8_t len_ind_0, len_ind_1, fcs, info; + const uint8_t *buf = (const uint8_t *) src; + + uart_wbyte(AMUX_TAG); + len_ind_0 = (uint8_t) (0xff & len); + len_ind_1 = (uint8_t) (0xff & (len >> 7)); + if (len < 128) { + uart_wbyte(len_ind_0); + } else { + uart_wbyte(len_ind_0 | AMUX_EXT); + uart_wbyte(len_ind_1); + } + fcs = 0; + for (uint16_t i = 0; i < len; i++) { + info = buf[i]; + fcs += info; + uart_wbyte(buf[i]); + } + fcs = 255 - fcs; + uart_wbyte(fcs); + uart_wbyte(AMUX_END); +} + + +uint16_t uartp_recv(void *dst, uint16_t buf_len) { + uint8_t *buf = (uint8_t *) dst; + uint8_t tag_old, tag, info, cs; + uint16_t len; + + tag = AMUX_END; + while (1) { + + do { + tag_old = tag; + tag = uart_rbyte(); + } while(tag != AMUX_TAG || tag_old != AMUX_END); + + len = (uint16_t) uart_rbyte(); + if (len & AMUX_EXT) { + len &= (~AMUX_EXT); + len |= (uint16_t) (uart_rbyte() << 7); + } + if (len > buf_len) { + return len; + } + + uint16_t i = 0; + cs = 0; + for (i = 0; i < len; i++) { + info = uart_rbyte(); + buf[i] = info; + cs += info; + } + cs += uart_rbyte(); + tag = uart_rbyte(); + if (0xff == cs) { + if (AMUX_END == tag) { + return len; + } + } + + } +} + diff --git a/templates/longan-nano/test.py b/templates/longan-nano/test.py new file mode 100755 index 0000000..a3006df --- /dev/null +++ b/templates/longan-nano/test.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 + +import os +import sys +import serial.tools.list_ports +from test_common import ( + DeviceUnderTestAeadUARTP, + eprint, + test_main, + OpenOcd, + FileMutex +) + + +def get_serial(): + ports = serial.tools.list_ports.comports() + devices = [ + p.device + for p in ports + if p.serial_number == 'FT2XAA99' + ] + devices.sort() + eprint("Serial port for LonganNano is %s" % devices[-1]) + return devices[-1] + + +class LonganNano(DeviceUnderTestAeadUARTP): + RAM_SIZE = 0x5000 + + def __init__(self, build_dir): + DeviceUnderTestAeadUARTP.__init__(self) + + self.uart_device = get_serial() + devname = os.path.basename(self.uart_device) + self.lock = FileMutex('/var/lock/lwc-compare.%s.lock' % devname) + self.build_dir = build_dir + self.template_path = os.path.dirname(sys.argv[0]) + + self.firmware_path = os.path.join( + build_dir, 'firmware.elf') + self.firmware_bin_path = os.path.join( + build_dir, 'firmware.bin') + self.ram_pattern_path = os.path.join( + self.template_path, 'empty_ram.bin') + self.ram_dump_path = os.path.join( + build_dir, 'ram_dump.bin') + self.openocd_cfg_path = os.path.join( + self.template_path, 'openocd.cfg') + + oocd_exe = '$HOME/.platformio/packages/tool-openocd-gd32v/bin/openocd' + oocd_exe = os.path.expandvars(oocd_exe) + self.ocd = OpenOcd(self.openocd_cfg_path, + executable=oocd_exe, tcl_port=6665) + + self.ser = serial.Serial( + self.uart_device, + baudrate=4*115200, + timeout=5) + + def firmware_size(self): + return os.stat(self.firmware_bin_path).st_size + + def flash(self): + eprint("Flashing firmware...") + ocd_cmd = 'program %s verify' % self.firmware_path + res = self.ocd.send(ocd_cmd) + eprint(res) + assert res == '' + eprint("Firmware flashed.") + + ocd_cmd = 'reset halt' + res = self.ocd.send(ocd_cmd) + eprint(res) + assert res == '' + + ocd_cmd = 'load_image %s 0x20000000' % self.ram_pattern_path + res = self.ocd.send(ocd_cmd) + if res.startswith('20480 bytes written at address 0x20000000'): + eprint("RAM loaded.") + else: + raise Exception("RAM load error", res) + + + ocd_cmd = 'resume' + res = self.ocd.send(ocd_cmd) + eprint(res) + assert res == '' + + self.ser = serial.Serial( + self.uart_device, + baudrate=4*115200, + timeout=5) + self.reset() + + def reset(self, halt=False): + ocd_cmd = 'reset halt' if halt else 'reset run' + res = self.ocd.send(ocd_cmd) + eprint(res) + assert res == '' + eprint("Reset!") + + def dump_ram(self): + + res = self.ocd.send('halt') + eprint(res) + assert res == '' + + res = self.ocd.send( + 'dump_image %s 0x20000000 0x%x' % + (self.ram_dump_path, LonganNano.RAM_SIZE)) + eprint(res) + assert res.startswith("dumped 20480 bytes in ") + + eprint("RAM dumped.") + + with open(self.ram_dump_path, 'rb') as ram: + ram = ram.read() + if len(ram) != LonganNano.RAM_SIZE: + raise Exception( + "RAM dump was %d bytes instead of %d" % + (len(ram), LonganNano.RAM_SIZE)) + + res = self.ocd.send('resume') + eprint(res) + assert res == '' + + return ram + + +if __name__ == "__main__": + sys.exit(test_main(LonganNano, 0x0200, sys.argv)) diff --git a/templates/maixduino/test.py b/templates/maixduino/test.py index ff12472..ad62415 100755 --- a/templates/maixduino/test.py +++ b/templates/maixduino/test.py @@ -9,8 +9,7 @@ from test_common import ( DeviceUnderTestAeadUARTP, FileMutex, eprint, - test_main, - run_nist_lws_aead_test, + test_main ) diff --git a/templates/uno/test.py b/templates/uno/test.py index a91908c..8745b66 100755 --- a/templates/uno/test.py +++ b/templates/uno/test.py @@ -10,8 +10,7 @@ from test_common import ( DeviceUnderTestAeadUARTP, eprint, test_main, - FileMutex, - run_nist_lws_aead_test, + FileMutex ) diff --git a/test_common.py b/test_common.py index 7d175fa..a0d1b6c 100755 --- a/test_common.py +++ b/test_common.py @@ -285,11 +285,14 @@ class LogicMultiplexerTimeMeasurements(TimeMeasurementTool): def begin_measurement(self): import socket - server_addr = os.path.expandvars('$XDG_RUNTIME_DIR/lwc-logic-socket') + #self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + #server_addr = ("127.0.0.1", 2255) + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + server_addr = os.path.expandvars('$XDG_RUNTIME_DIR/lwc-logic-socket') + self.sock.settimeout(0) - self.server_addr = server_addr - self.sock.connect(self.server_addr) + self.sock.connect(server_addr) self.sock.send(struct.pack("