diff --git a/firmware/applications/vcard.c b/firmware/applications/vcard.c new file mode 100644 index 0000000..817ef02 --- /dev/null +++ b/firmware/applications/vcard.c @@ -0,0 +1,313 @@ +#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" + + +FATFS FatFs[_VOLUMES]; /* File system object for logical drive */ +/**************************************************************************/ + +uint8_t mac[5] = {1,2,3,2,1}; +char *Px = "1c56d302cf642a8e1ba4b48cc4fbe2845ee32dce7"; +char *Py = "45f46eb303edf2e62f74bd68368d979e265ee3c03"; +char *Priv ="0e10e787036941e6c78daf8a0e8e1dbfac68e26d2"; + +void sendPublicKey(char *px, char *py) +{ + uint8_t exp[2 + 4*NUMWORDS]; + exp[0] = 'P'; + bitstr_parse_export((char*)exp+2, px); + exp[1] = 'X'; + nrf_snd_pkt_crc(30, exp); + delayms(10); + exp[1] = 'Y'; + bitstr_parse_export((char*)exp+2, py); + nrf_snd_pkt_crc(30, exp); + delayms(10); +} + +void sendR(uint8_t *rx, uint8_t *ry) +{ + uint8_t exp[2 + 4*NUMWORDS]; + exp[0] = 'R'; + for(int i=0; i<4*NUMWORDS; i++) + exp[2+i] = rx[i]; + exp[1] = 'X'; + nrf_snd_pkt_crc(30, exp); + delayms(10); + exp[1] = 'Y'; + for(int i=0; i<4*NUMWORDS; i++) + exp[2+i] = ry[i]; + nrf_snd_pkt_crc(30, exp); + delayms(10); +} + +int receiveKey(uint8_t type, uint8_t *x, uint8_t *y) +{ + uint8_t buf[30]; + uint8_t n; + + n = nrf_rcv_pkt_time(1000, 30, buf); + if( n == 30 && buf[0] == type && buf[1] == 'X' ){ + for(int i=0; i #include #include +#include "ecc.h" + +exp_t base_order; +elem_t poly; /* the reduction polynomial */ +elem_t coeff_b, base_x, base_y; static int xrandm=100000000; static int xrandm1=10000; @@ -34,22 +39,10 @@ return a & 0xff; } - #define MACRO(A) do { A; } while(0) #define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define NO_HTONL - -#ifndef NO_HTONL -#define INT2CHARS(ptr, val) MACRO( *(uint32_t*)(ptr) = htonl(val) ) -#define CHARS2INT(ptr) ntohl(*(uint32_t*)(ptr)) -#else - - -#if 1 - //compiles to a quite reasonable assembly code - //void INT2CHARS (unsigned char *ptr, uint32_t val) void INT2CHARS (char *ptr, uint32_t val) { @@ -71,44 +64,6 @@ r|=*ptr--; return r; } -#else - -/* ARM architecture has a problem with non-word-aligned addresses - the load/store of a 32-bit register behaves very counterintuitively in such a case - -void INT2CHARS (char *ptr, const uint32_t val) -{ -uint32_t *p = (uint32_t *)ptr; -*p=val; -} - -uint32_t CHARS2INT(const char *ptr) -{ -uint32_t *p = (uint32_t *)ptr; -return *p; -} -*/ - -/* this has the same problem */ -#define INT2CHARS(ptr, val) MACRO( *(uint32_t*)(ptr) = (uint32_t)val ) -#define CHARS2INT(ptr) (*(uint32_t*)(ptr)) - -#endif - - -#endif - - - -/******************************************************************************/ - -#define DEGREE 163 /* the degree of the field polynomial */ -#define MARGIN 3 /* don't touch this */ -#define NUMWORDS ((DEGREE + MARGIN + 31) / 32) - - /* the following type will represent bit vectors of length (DEGREE+MARGIN) */ -typedef uint32_t bitstr_t[NUMWORDS]; - /* some basic bit-manipulation routines that act on these vectors follow */ #define bitstr_getbit(A, idx) ((A[(idx) / 32] >> ((idx) % 32)) & 1) #define bitstr_setbit(A, idx) MACRO( A[(idx) / 32] |= 1 << ((idx) % 32) ) @@ -229,11 +184,19 @@ int bitstr_parse(bitstr_t x, const char *s) return len; } +int bitstr_parse_export(char *exp, const char *s) +{ + bitstr_t x; + if( bitstr_parse(x, s) != -1 ){ + bitstr_export(exp, x); + return 0; + } + return -1; +} + /******************************************************************************/ -typedef bitstr_t elem_t; /* this type will represent field elements */ -elem_t poly; /* the reduction polynomial */ #define field_set1(A) MACRO( A[0] = 1; memset(A + 1, 0, sizeof(elem_t) - 4) ) @@ -304,7 +267,6 @@ void field_invert(elem_t z, const elem_t x) /* field inversion */ curves). Coefficient 'b' is given in 'coeff_b'. '(base_x, base_y)' is a point that generates a large prime order group. */ -elem_t coeff_b, base_x, base_y; #define point_is_zero(x, y) (bitstr_is_clear(x) && bitstr_is_clear(y)) #define point_set_zero(x, y) MACRO( bitstr_clear(x); bitstr_clear(y) ) @@ -380,9 +342,7 @@ void point_add(elem_t x1, elem_t y1, const elem_t x2, const elem_t y2) /******************************************************************************/ -typedef bitstr_t exp_t; -exp_t base_order; /* point multiplication via double-and-add algorithm */ void point_mult(elem_t x, elem_t y, const exp_t exp) @@ -543,15 +503,15 @@ void ECIES_kdf(char *k1, char *k2, const elem_t Zx, /* a non-standard KDF */ buf[12 * NUMWORDS] = 3; XTEA_davies_meyer(k2 + 8, buf, bufsize / 16); } -void ECIES_encyptkeygen(const char *Px, const char *Py, +void ECIES_encyptkeygen(uint8_t *px, uint8_t *py, uint8_t k1[16], uint8_t k2[16], uint8_t *Rx_exp, uint8_t *Ry_exp) { elem_t Rx, Ry, Zx, Zy; exp_t k; do { get_random_exponent(k); - bitstr_parse(Zx, Px); - bitstr_parse(Zy, Py); + bitstr_import(Zx, (char*)px); + bitstr_import(Zy, (char*)py); point_mult(Zx, Zy, k); point_double(Zx, Zy); /* cofactor h = 2 on B163 */ } while(point_is_zero(Zx, Zy)); @@ -562,13 +522,13 @@ void ECIES_encyptkeygen(const char *Px, const char *Py, bitstr_export((char*)Ry_exp, Ry); } -int ECIES_decryptkeygen(const char *Rx_imp, const char *Ry_imp, +int ECIES_decryptkeygen(uint8_t *rx, uint8_t *ry, uint8_t k1[16], uint8_t k2[16], const char *privkey) { elem_t Rx, Ry, Zx, Zy; exp_t d; - bitstr_import(Rx, Rx_imp); - bitstr_import(Ry, Ry_imp); + bitstr_import(Rx, (char*)rx); + bitstr_import(Ry, (char*)ry); if (ECIES_embedded_public_key_validation(Rx, Ry) < 0) return -1; bitstr_parse(d, privkey); @@ -581,6 +541,15 @@ int ECIES_decryptkeygen(const char *Rx_imp, const char *Ry_imp, return 0; } +void ECIES_setup(void) +{ + bitstr_parse(poly, "800000000000000000000000000000000000000c9"); + bitstr_parse(coeff_b, "20a601907b8c953ca1481eb10512f78744a3205fd"); + bitstr_parse(base_x, "3f0eba16286a2d57ea0991168d4994637e8343e36"); + bitstr_parse(base_y, "0d51fbc6c71a0094fa2cdd545b11c5c0c797324f1"); + bitstr_parse(base_order, "40000000000000000000292fe77e70c12a4234c33"); +} + #define ECIES_OVERHEAD (8 * NUMWORDS + 8) /* ECIES encryption; the resulting cipher text message will be diff --git a/firmware/basic/ecc.h b/firmware/basic/ecc.h index c07bd9e..73512e2 100644 --- a/firmware/basic/ecc.h +++ b/firmware/basic/ecc.h @@ -1,10 +1,26 @@ #ifndef _ECC_H_ #define _ECC_H_H +#include -void ECIES_encyptkeygen(const char *Px, const char *Py, +/******************************************************************************/ + +#define DEGREE 163 /* the degree of the field polynomial */ +#define MARGIN 3 /* don't touch this */ +#define NUMWORDS ((DEGREE + MARGIN + 31) / 32) + + /* the following type will represent bit vectors of length (DEGREE+MARGIN) */ +typedef uint32_t bitstr_t[NUMWORDS]; +typedef bitstr_t elem_t; /* this type will represent field elements */ +typedef bitstr_t exp_t; + +int bitstr_parse_export(char *exp, const char *s); + +void ECIES_setup(void); + +void ECIES_encyptkeygen(uint8_t *px, uint8_t *py, uint8_t k1[16], uint8_t k2[16], uint8_t *Rx_exp, uint8_t *Ry_exp); -int ECIES_decryptkeygen(const char *Rx_imp, const char *Ry_imp, +int ECIES_decryptkeygen(uint8_t *rx, uint8_t *ry, uint8_t k1[16], uint8_t k2[16], const char *privkey); #define ECIES_OVERHEAD (8 * NUMWORDS + 8) @@ -12,7 +28,6 @@ int ECIES_decryptkeygen(const char *Rx_imp, const char *Ry_imp, (len + ECIES_OVERHEAD) bytes long */ void ECIES_encryption(char *msg, const char *text, int len, const char *Px, const char *Py); -{ /* ECIES decryption */ int ECIES_decryption(char *text, const char *msg, int len, const char *privkey); diff --git a/firmware/basic/xxtea.c b/firmware/basic/xxtea.c index 96a5236..306c72b 100644 --- a/firmware/basic/xxtea.c +++ b/firmware/basic/xxtea.c @@ -96,6 +96,7 @@ void xxtea_decode(uint8_t *data, int n, uint32_t const k[4]) void xxtea_encode_words(uint32_t *v, int n, uint32_t const k[4]) { + if(k[0] == 0 && k[1] == 0 && k[2] == 0 && k[3] == 0) return; uint32_t y, z, sum; unsigned p, rounds, e; rounds = 6 + 52/n; @@ -115,6 +116,7 @@ void xxtea_encode_words(uint32_t *v, int n, uint32_t const k[4]) void xxtea_decode_words(uint32_t *v, int n, uint32_t const k[4]) { + if(k[0] == 0 && k[1] == 0 && k[2] == 0 && k[3] == 0) return; uint32_t y, z, sum; unsigned p, rounds, e; diff --git a/firmware/funk/rftransfer.c b/firmware/funk/rftransfer.c index fb359a2..725bc15 100644 --- a/firmware/funk/rftransfer.c +++ b/firmware/funk/rftransfer.c @@ -15,7 +15,8 @@ void rftransfer_send(uint16_t size, uint8_t *data) buf[3] = rand >> 8; buf[4] = rand & 0xFF; - nrf_snd_pkt_crc(5,buf); //setup packet + //nrf_snd_pkt_crc(5,buf); //setup packet + nrf_snd_pkt_crc(30,buf); //setup packet delayms(10); uint16_t index = 0; uint8_t i; @@ -31,7 +32,8 @@ void rftransfer_send(uint16_t size, uint8_t *data) buf[i] = *data++; } index++; - nrf_snd_pkt_crc(i,buf); //data packet + //nrf_snd_pkt_crc(i,buf); //data packet + nrf_snd_pkt_crc(30,buf); //setup packet delayms(10); } @@ -40,7 +42,8 @@ void rftransfer_send(uint16_t size, uint8_t *data) buf[2] = crc & 0xFF; buf[3] = rand >> 8; buf[4] = rand & 0xFF; - nrf_snd_pkt_crc(5,buf); //crc packet + //nrf_snd_pkt_crc(5,buf); //crc packet + nrf_snd_pkt_crc(30,buf); //setup packet delayms(10); }