diff --git a/firmware/l0dable/EXPORTS b/firmware/l0dable/EXPORTS index ea15048..ead6d87 100644 --- a/firmware/l0dable/EXPORTS +++ b/firmware/l0dable/EXPORTS @@ -47,3 +47,10 @@ strcpy xxtea_encode_words getRandom crc16 +f_write +f_close +ECIES_decryptkeygen +bitstr_parse_export +f_get_rc_string +xxtea_decode_words +systickGetTicks diff --git a/firmware/l0dable/recvcard.c b/firmware/l0dable/recvcard.c new file mode 100644 index 0000000..d19da8d --- /dev/null +++ b/firmware/l0dable/recvcard.c @@ -0,0 +1,340 @@ +#include +#include +#include +#include +#include +#include "basic/basic.h" +#include "lcd/render.h" +#include "lcd/allfonts.h" +#include "basic/ecc.h" +#include "funk/nrf24l01p.h" +#include "filesystem/ff.h" +#include "filesystem/diskio.h" +#include "funk/filetransfer.h" +#include "lcd/print.h" +#include +#include "funk/nrf24l01p.h" +#include "funk/filetransfer.h" +#include "funk/rftransfer.h" +#include "basic/basic.h" +#include "basic/xxtea.h" +#include "filesystem/ff.h" +#include "lcd/print.h" +#include "usetable.h" + + +uint8_t mac[5] = {1,2,3,2,1}; + +void ram(void) +{ + if( sendKeys() ) + return; + + char priv[42]; + UINT readbytes; + FIL file; + + if( f_open(&file, "priv.key", FA_OPEN_EXISTING|FA_READ) ){ + return; + } + if( f_read(&file, priv, 41, &readbytes) || readbytes != 41 ){ + return; + } + f_close(&file); + priv[41] = 0; + + uint8_t done = 0; + uint8_t key; + uint8_t k1[16], k2[16], rx[4*NUMWORDS], ry[4*NUMWORDS]; + + while( !done ){ + lcdClear(); + lcdPrintln("Receiving file"); + lcdPrintln("Down=Abort"); + lcdRefresh(); + key = getInput(); + delayms(20); + if( key == BTN_DOWN ){ + return -1; + } + if( receiveR(rx,ry) ) + continue; + lcdPrintln("Creating key"); + lcdRefresh(); + ECIES_decryptkeygen(rx, ry, k1, k2, priv); + if( filetransfer_receive(mac,(uint32_t*)k1) < 0 ) + continue; + lcdPrintln("Right=OK"); + lcdPrintln("Left=Retry"); + lcdPrintln("Down=Abort"); + lcdRefresh(); + + while(1){ + key = getInput(); + delayms(20); + if( key == BTN_LEFT ){ + break; + }else if( key == BTN_RIGHT ){ + done = 1; + break; + }else if( key == BTN_DOWN ){ + return -1; + } + } + } +} + +void sendPublicKey(void) +{ + uint8_t exp[2 + 4*NUMWORDS + 2]; + char buf[42]; + UINT readbytes; + FIL file; + + if( f_open(&file, "pubx.key", FA_OPEN_EXISTING|FA_READ) ){ + return; + } + if( f_read(&file, buf, 41, &readbytes) || readbytes != 41 ){ + return; + } + f_close(&file); + buf[41] = 0; + + exp[0] = 'P'; + bitstr_parse_export((char*)exp+2, buf); + exp[1] = 'X'; + nrf_snd_pkt_crc(32, exp); + delayms(10); + + if( f_open(&file, "puby.key", FA_OPEN_EXISTING|FA_READ) ){ + return; + } + if( f_read(&file, buf, 41, &readbytes) || readbytes != 41 ){ + return; + } + f_close(&file); + buf[41] = 0; + + exp[1] = 'Y'; + bitstr_parse_export((char*)exp+2, buf); + nrf_snd_pkt_crc(32, exp); + delayms(10); +} + + +int receiveKey(uint8_t type, uint8_t *x, uint8_t *y) +{ + uint8_t buf[32]; + uint8_t n; + + n = nrf_rcv_pkt_time(1000, 32, buf); + if( n == 32 && buf[0] == type && buf[1] == 'X' ){ + for(int i=0; i MAXSIZE ) {lcdPrintln("too big"); lcdRefresh(); while(1);} + if( size > MAXSIZE ) return 1; //file to big + //if(fileexists(metadata)) return 1; //file already exists + + //lcdPrint("open"); lcdPrintln((const char*)metadata); lcdRefresh(); + res = f_open(&file, (const char*)metadata, FA_OPEN_ALWAYS|FA_WRITE); + + //lcdPrintln("file opened"); lcdRefresh(); + if( res ) {lcdPrintln("res"); lcdPrint(f_get_rc_string(res)); lcdRefresh(); while(1);} + if( res ) + return res; + + uint16_t wordcount = (size+3)/4; + + //nrf_set_rx_mac(0, 32, 5, mac); + //lcdPrintln("get file"); lcdRefresh(); + int fres = rftransfer_receive(buf, wordcount*4, 1000); + if( fres == -1 ){ + lcdPrintln("checksum wrong"); + }else if( fres == -2 ){ + lcdPrintln("timeout"); + }else{ + //lcdPrintln("got file"); + } + lcdRefresh(); + if( fres < 0 ) + return 1; + //nrf_set_rx_mac(0, 32, 5, macbuf); + + xxtea_decode_words((uint32_t *)buf, wordcount, k); + + res = f_write(&file, buf, size, &written); + f_close(&file); + if( res ) + return res; + if( written != size ) + return 1; //error while writing + lcdClear(); + lcdPrintln("Received"); lcdPrintln((const char*)metadata); lcdRefresh(); + + return 0; +} + +#define MAXPACKET 32 +int16_t rftransfer_receive(uint8_t *buffer, uint16_t maxlen, uint16_t timeout) +{ + uint8_t buf[MAXPACKET]; + uint8_t state = 0; + uint16_t pos = 0, seq = 0, size = 0, rand = 0, crc = 0; + int n,i; + unsigned int currentTick = systickGetTicks(); + unsigned int startTick = currentTick; + + while(systickGetTicks() < (startTick+timeout) ){//this fails if either overflows + n = nrf_rcv_pkt_time(1000, MAXPACKET, buf); + switch(state){ + case 0: + if( n == 32 && buf[0] == 'L' ){ + size = (buf[1] << 8) | buf[2]; + rand = (buf[3] << 8) | buf[4]; + seq = 0; + pos = 0; + if( size <= maxlen ){ + //lcdClear(); + //lcdPrint("got l="); lcdPrintInt(size); + //lcdPrintln(""); lcdRefresh(); + state = 1; + } + } + break; + case 1: + if( n == 32 && buf[0] == 'D' && ((buf[3]<<8)|buf[4])==rand ){ + //lcdPrint("got d"); lcdRefresh(); + if( seq == ((buf[1]<<8)|buf[2]) ){ + //lcdPrintln(" in seq"); lcdRefresh(); + for(i=5; i