From 10877bed2f5b771420b21560ea334d38603c31b2 Mon Sep 17 00:00:00 2001 From: Enrico Pozzobon Date: Sun, 17 Nov 2019 12:01:11 +0100 Subject: [PATCH] maixduino template --- templates/maixduino/.gitignore | 1 + templates/maixduino/Makefile | 13 +++++++++++++ templates/maixduino/configure | 5 +++++ templates/maixduino/include/crypto_aead.h | 26 ++++++++++++++++++++++++++ templates/maixduino/include/uartp.h | 11 +++++++++++ templates/maixduino/platformio.ini | 17 +++++++++++++++++ templates/maixduino/src/main.ino | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ templates/maixduino/src/uartp.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ templates/maixduino/test | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 457 insertions(+) create mode 100644 templates/maixduino/.gitignore create mode 100644 templates/maixduino/Makefile create mode 100755 templates/maixduino/configure create mode 100644 templates/maixduino/include/crypto_aead.h create mode 100644 templates/maixduino/include/uartp.h create mode 100644 templates/maixduino/platformio.ini create mode 100644 templates/maixduino/src/main.ino create mode 100644 templates/maixduino/src/uartp.c create mode 100755 templates/maixduino/test diff --git a/templates/maixduino/.gitignore b/templates/maixduino/.gitignore new file mode 100644 index 0000000..93ac46c --- /dev/null +++ b/templates/maixduino/.gitignore @@ -0,0 +1 @@ +.pioenvs diff --git a/templates/maixduino/Makefile b/templates/maixduino/Makefile new file mode 100644 index 0000000..777637a --- /dev/null +++ b/templates/maixduino/Makefile @@ -0,0 +1,13 @@ +LFLAGS=-lm +all: sipeed-maixduino + +sipeed-maixduino: .pioenvs/sipeed-maixduino/firmware.bin + +.pioenvs/sipeed-maixduino/firmware.bin: FORCE + platformio run -e sipeed-maixduino + +FORCE: ; +.PHONY: clean + +clean: + -rm .pioenvs/sipeed-maixduino/firmware.bin diff --git a/templates/maixduino/configure b/templates/maixduino/configure new file mode 100755 index 0000000..d3c9b5f --- /dev/null +++ b/templates/maixduino/configure @@ -0,0 +1,5 @@ +#!/bin/bash +mv -n *.c *.s *.S src/ +mv -n *.dat *.inc *.h include/ +sed -i src/encrypt.c -e "s/\(\s\)init(/\1_init(/g" +exit 0 diff --git a/templates/maixduino/include/crypto_aead.h b/templates/maixduino/include/crypto_aead.h new file mode 100644 index 0000000..651490c --- /dev/null +++ b/templates/maixduino/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/maixduino/include/uartp.h b/templates/maixduino/include/uartp.h new file mode 100644 index 0000000..3a80a60 --- /dev/null +++ b/templates/maixduino/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/maixduino/platformio.ini b/templates/maixduino/platformio.ini new file mode 100644 index 0000000..d429a69 --- /dev/null +++ b/templates/maixduino/platformio.ini @@ -0,0 +1,17 @@ +[env:sipeed-maixduino] +platform = kendryte210 +board = sipeed-maixduino +framework = arduino + +; change microcontroller +board_build.mcu = K210 + +; change MCU frequency +board_build.f_cpu = 600000000L + +; upload speed +upload_speed = 750000 + +; compiler optimizations to favour speed over size +build_flags = -O3 +build_unflags = -Os diff --git a/templates/maixduino/src/main.ino b/templates/maixduino/src/main.ino new file mode 100644 index 0000000..dc1f117 --- /dev/null +++ b/templates/maixduino/src/main.ino @@ -0,0 +1,115 @@ +#include "crypto_aead.h" +#include "api.h" +#include "uartp.h" + +#define MAX_BYTES 100 +#define CMDBUF_LEN 72 +static uint8_t cmdbuf[CMDBUF_LEN]; + +#define CRYPTO_BUSY 12 +#define SerialOut Serial + +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 + +void uart_wbyte(uint8_t x) { + SerialOut.write((uint8_t) (x)); +} + +uint8_t uart_rbyte() { + int r; + do { + r = SerialOut.read(); + } while (r == -1); + return (uint8_t) (0xff & r); +} + +#ifdef __cplusplus +} +#endif + +void my_assert(bool b) { + if (b) + return; + for(;;) + yield(); +} + +void setup() { + SerialOut.begin(115200); + 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); + SerialOut.print("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/maixduino/src/uartp.c b/templates/maixduino/src/uartp.c new file mode 100644 index 0000000..e520cfc --- /dev/null +++ b/templates/maixduino/src/uartp.c @@ -0,0 +1,75 @@ +#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, info, cs; + uint16_t len; + + tag = AMUX_END; + while (1) { + + do { + tag = uart_rbyte(); + } while(tag != AMUX_TAG); + + 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/maixduino/test b/templates/maixduino/test new file mode 100755 index 0000000..0d959a8 --- /dev/null +++ b/templates/maixduino/test @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 + +import os +import sys +import time +import struct +import serial +import subprocess + + + +def eprint(*args, **kargs): + print(*args, file=sys.stderr, **kargs) + + +def flash(tty=None): + pipe = subprocess.PIPE + cmd = ['platformio', 'run', '--target', 'upload'] + if tty is not None: + cmd.extend(['--upload-port', tty]) + p = subprocess.Popen(cmd, + stdout=sys.stderr, stdin=pipe) + stdout, stderr = p.communicate("") + +def get_serial(): + import serial.tools.list_ports + ports = serial.tools.list_ports.comports() + sipeed_devices = [ c.device + for c in ports + if c.product == 'Sipeed-Debug'] + sipeed_devices.sort() + return sipeed_devices[0] + + +class UARTP: + def __init__(self, ser): + UARTP.SYN = 0xf9 + UARTP.FIN = 0xf3 + self.ser = ser + + def uart_read(self): + r = self.ser.read(1) + if len(r) != 1: + raise Exception("Serial read error") + return r[0] + + def uart_write(self, c): + b = struct.pack("B", c) + r = self.ser.write(b) + if r != len(b): + raise Exception("Serial write error") + return r + + def send(self, buf): + self.uart_write(UARTP.SYN) + len_ind_0 = 0xff & len(buf) + len_ind_1 = 0xff & (len(buf) >> 7) + if len(buf) < 128: + self.uart_write(len_ind_0) + else: + self.uart_write(len_ind_0 | 0x80) + self.uart_write(len_ind_1) + fcs = 0 + for i in range(len(buf)): + info = buf[i] + fcs = (fcs + info) & 0xff + self.uart_write(buf[i]) + fcs = (0xff - fcs) & 0xff + self.uart_write(fcs) + self.uart_write(UARTP.FIN) + eprint("sent frame '%s'" % buf.hex()) + + def recv(self): + tag_old = UARTP.FIN + while 1: + tag = tag_old + while 1: + if tag_old == UARTP.FIN: + if tag == UARTP.SYN: + break + tag_old = tag + tag = self.uart_read() + tag_old = tag + + l = self.uart_read() + if l & 0x80: + l &= 0x7f + l |= self.uart_read() << 7 + + fcs = 0 + buf = [] + for i in range(l): + info = self.uart_read() + buf.append(info) + fcs = (fcs + info) & 0xff + fcs = (fcs + self.uart_read()) & 0xff + + tag = self.uart_read() + if fcs == 0xff: + if tag == UARTP.FIN: + buf = bytes(buf) + eprint("rcvd frame '%s'" % buf.hex()) + if len(buf) >= 1 and buf[0] == 0xde: + sys.stderr.buffer.write(buf[1:]) + sys.stderr.flush() + else: + return buf + + +def stdin_read(n): + b = sys.stdin.buffer.read(n) + if len(b) != n: + sys.exit(1) + return b + + +def stdin_readvar(): + l = stdin_read(4) + (l, ) = struct.unpack(" 0: + os.chdir(script_dir) + + + dev = get_serial() + flash(dev) + eprint("Flashed") + time.sleep(0.1) + ser = serial.Serial(dev, baudrate=115200, timeout=5) + uartp = UARTP(ser) + + ser.setRTS(True) + time.sleep(0.1) + ser.setRTS(False) + time.sleep(0.1) + ser.setRTS(True) + time.sleep(1) + + exp_hello = b"Hello, World!" + hello = ser.read(len(exp_hello)) + if hello != exp_hello: + eprint("Improper board initialization message: ") + return 1 + eprint("Board initialized properly") + sys.stdout.write("Hello, World!\n") + sys.stdout.flush() + + while 1: + action = stdin_read(1)[0] + eprint("Command %c from stdin" % action) + + if action in b"ackmps": + v = stdin_readvar() + uartp.send(struct.pack("B", action) + v) + ack = uartp.recv() + if len(ack) != 1 or ack[0] != action: + raise Exception("Unacknowledged variable transfer") + eprint("Var %c successfully sent to board" % action) + + elif action in b"ACKMPS": + c = struct.pack("B", action) + uartp.send(c) + v = uartp.recv() + if len(v) < 1 or v[0] != action: + raise Exception("Could not obtain variable from board") + v = v[1:] + eprint("Var %c received from board: %s" % (action, v.hex())) + l = struct.pack("