Commit 4406017e authored by hark's avatar hark

porting of pagerlib to arduino

parent ad42cbf0
......@@ -6,7 +6,7 @@ all: test
base-tx: base-tx.c
$(CC) -o base-tx base-tx.c $(LIBS) $(CFLAGS)
test: test.c ../libs/pagerlib/pagerlib.c
$(CC) -std=c99 -g -o test test.c ../libs/micro-ecc/uECC.c ../libs/pagerlib/pagerlib.c -lmbedtls -lmbedx509 -lmbedcrypto $(LIBS) $(CFLAGS)
test: test.c ../libs/pagerlib/pagerlib.c ../libs/pagerlib/things.c
$(CC) -std=c99 -g -o test test.c ../libs/micro-ecc/uECC.c ../libs/pagerlib/pagerlib.c ../libs/pagerlib/things.c -lmbedtls -lmbedx509 -lmbedcrypto $(LIBS) $(CFLAGS)
test2: test2.c
$(CC) -std=c99 -o test2 test2.c ../libs/micro-ecc/uECC.c -lmbedtls -lmbedx509 -lmbedcrypto $(LIBS) $(CFLAGS)
......@@ -18,66 +18,33 @@
#endif
int main() {
struct keypair *sender, *receiver;
uint8_t sender_decompressed_point[64];
uint8_t receiver_decompressed_point[64];
uint8_t sender_shared_secret[32] = {0};
uint8_t receiver_shared_secret[32] = {0};
struct pl_keypair *sender, *receiver;
char clear_message[] = "Blaat blaat, dit is een test berichtje :) ";
char crypt_message[128];
char decrypted_message[128];
//unsigned char key[32];
unsigned char iv[16];
unsigned char siv[16]; // for sending the iv
int i;
int c;
// initialise the pager
pl_init();
// initialise the curve
init();
struct pl_pagermessage * sended_msg;
struct pagermessage * sended_msg;
/* create keypairs */
sender = create_keypair();
save_key(sender,"sender.keypair");
receiver = create_keypair();
save_key(receiver,"receiver.keypair");
sender = pl_create_keypair();
pl_save_key(sender,"sender.keypair");
receiver = pl_create_keypair();
pl_save_key(receiver,"receiver.keypair");
sended_msg = send_message(receiver, sender, clear_message);
sended_msg = pl_send_message(receiver, sender, clear_message);
printf("\n The message that was send: \n");
dump_buffer(sizeof(struct pagermessage), sended_msg);
dump_buffer(sizeof(struct pl_pagermessage), sended_msg);
printf("\n ----------------------------\n");
printf("\n The message that decrypted: \n");
receive_message(receiver, sended_msg);
pl_receive_message(receiver, sended_msg);
printf("\n ----------------------------\n");
/* compress sender public key */
// uECC_compress(sender->public, sender->compressed_point, curve);
// printf(" \n Compressed public key: \n");
// dump_buffer(256, sender_compressed_point);
/* now we send the message....
* sender_compressed_key
* crypt_message
* iv??
* */
/*
if (memcmp(sender_public, sender_decompressed_point, sizeof(sender_public)) != 0) {
printf("Original and decompressed points are not identical!\n");
vli_print("Original point = ", sender_public, sizeof(sender_public));
vli_print("Compressed point = ", sender_compressed_point, sizeof(sender_compressed_point));
vli_print("Decompressed point = ", sender_decompressed_point, sizeof(sender_decompressed_point));
}
*/
return 0;
}
......@@ -6,7 +6,7 @@
*/
struct keypair
struct pl_keypair
{
uint8_t public[64];
uint8_t private[32];
......@@ -17,7 +17,7 @@ struct keypair
// (curve size + 1) bytes long; for example, if the curve is secp256r1,
// compressed must be 33 bytes long.
struct pagermessage
struct pl_pagermessage
{
uint8_t sender_compressed_point[33];
char msg[128];
......
......@@ -6,224 +6,61 @@
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/aes.h"
#include "things.h"
#ifdef AVR
#include <avr/pgmspace.h>
const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/"
#else
const char b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
const struct uECC_Curve_t * curve;
#if defined(__AVR_ATmega328P__)
#define ARDUINO
#endif
/* 'Private' declarations */
/* why?
inline void a3_to_a4(unsigned char * a4, unsigned char * a3);
inline void a4_to_a3(unsigned char * a3, unsigned char * a4);
inline unsigned char b64_lookup(char c);
*/
void
dump_buffer(unsigned int n, const unsigned char* buf)
{
const unsigned char *p, *end;
unsigned i, j;
printf("\n Buffer: \n ");
end = buf + n;
for (i = 0; ; i += 16) {
p = buf + i;
for (j = 0; j < 16; j++) {
fprintf(stderr, "%02X ", p[j]);
if (p + j >= end)
goto BREAKOUT;
}
fprintf(stderr, " ");
p = buf + i;
for (j = 0; j < 16; j++) {
fprintf(stderr, "%c", isprint(p[j]) ? p[j] :
'.');
if (p + j >= end)
goto BREAKOUT;
}
fprintf(stderr, "\n");
}
BREAKOUT:
return;
}
void vli_print(char *str, uint8_t *vli, unsigned int size) {
// printf("%s ", str);
for(unsigned i=0; i<size; ++i) {
printf("%02X ", (unsigned)vli[i]);
}
printf("\n");
}
static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}
static inline unsigned char b64_lookup(char c) {
if(c >='A' && c <='Z') return c - 'A';
if(c >='a' && c <='z') return c - 71;
if(c >='0' && c <='9') return c + 4;
if(c == '+') return 62;
if(c == '/') return 63;
return -1;
}
int base64_encode(char *output, char *input, int inputLen) {
int i = 0, j = 0;
int encLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while(inputLen--) {
a3[i++] = *(input++);
if(i == 3) {
a3_to_a4(a4, a3);
for(i = 0; i < 4; i++) {
#ifdef AVR
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]);
#ifdef ARDUINO
#define DBG
#define DB
#else
output[encLen++] = b64_alphabet[a4[i]];
#endif
}
#define DBG(f_, ...) printf((f_), ##__VA_ARGS__);
#define DB(f_, ...) dump_buffer((f_), ##__VA_ARGS__);
i = 0;
}
}
#endif
if(i) {
for(j = i; j < 3; j++) {
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for(j = 0; j < i + 1; j++) {
#ifdef AVR
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]);
#ifdef ARDUINO
aes_context aes_ctx;
//aes_context dec_aes;
#else
output[encLen++] = b64_alphabet[a4[j]];
mbedtls_aes_context aes_ctx;
//mbedtls_aes_context dec_aes;
#endif
}
while((i++ < 3)) {
output[encLen++] = '=';
}
}
output[encLen] = '\0';
return encLen;
}
int base64_decode(char * output, char * input, int inputLen) {
int i = 0, j = 0;
int decLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--) {
if(*input == '=') {
break;
}
a4[i++] = *(input++);
if (i == 4) {
for (i = 0; i <4; i++) {
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3,a4);
for (i = 0; i < 3; i++) {
output[decLen++] = a3[i];
}
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++) {
a4[j] = '\0';
}
for (j = 0; j <4; j++) {
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3,a4);
for (j = 0; j < i - 1; j++) {
output[decLen++] = a3[j];
}
}
output[decLen] = '\0';
return decLen;
}
int base64_enc_len(int plainLen) {
int n = plainLen;
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}
int base64_dec_len(char * input, int inputLen) {
int i = 0;
int numEq = 0;
for(i = inputLen - 1; input[i] == '='; i--) {
numEq++;
}
return ((6 * inputLen) / 8) - numEq;
}
////////////////////////////////////////////////
const struct uECC_Curve_t * curve;
mbedtls_aes_context enc_aes;
mbedtls_aes_context dec_aes;
#define MSG_SIZE 128
#define SHARED_SECRET_SIZE 32
#define IV_SIZE 16
unsigned char fakeiv[] = "123456789abcdefghijklmnop";
void init() {
void pl_init() {
curve = uECC_secp256k1();
}
struct pagermessage * send_message(struct keypair *to, struct keypair *from, char * msg_text) {
struct pagermessage *msg;
struct pl_pagermessage * pl_send_message(struct pl_keypair *to, struct pl_keypair *from, char * msg_text) {
struct pl_pagermessage *msg;
char crypt_message[128];
char decrypted_message[128];
char crypt_message[MSG_SIZE];
char decrypted_message[MSG_SIZE];
//unsigned char key[32];
unsigned char iv[16];
unsigned char iv[IV_SIZE];
uint8_t shared_secret[32] = {0};
uint8_t shared_secret[SHARED_SECRET_SIZE] = {0};
msg = malloc(sizeof(struct pagermessage));
memset(msg, 7, sizeof(struct pagermessage));
msg = malloc(sizeof(struct pl_pagermessage));
memset(msg, 7, sizeof(struct pl_pagermessage));
/* create a random iv */
// TODO (this is stupid)
......@@ -236,90 +73,90 @@ struct pagermessage * send_message(struct keypair *to, struct keypair *from, c
/*calculate shared secret on sender*/
if (!uECC_shared_secret(to->public, from->private, shared_secret, curve)) {
printf("shared_secret() failed (1)\n");
DBG("shared_secret() failed (1)\n");
return 1;
}
// dump_buffer(32, shared_secret);
// dump_buffer(16, msg->iv);
char tm[MSG_SIZE] = "dit is een test berichtje :) ";
mbedtls_aes_init( &enc_aes );
#ifdef ARDUINO
// copy the message into the output
memcpy(msg->msg, tm, MSG_SIZE);
/* encrypt message with aes using shared secret as the key */
mbedtls_aes_setkey_enc( &enc_aes, shared_secret, 256 );
char tm[128] = "dit is een test berichtje :) ";
mbedtls_aes_crypt_cbc( &enc_aes, MBEDTLS_AES_ENCRYPT, MSG_SIZE, iv, tm, msg->msg );
printf("message to send: %s \n ", msg_text);
/*
printf("sender_shared_secrete: \n ");
dump_buffer(sizeof(sender_shared_secret), sender_shared_secret);
printf("clear_message: \n ");
dump_buffer(sizeof(clear_message), clear_message);
printf("crypt_message: \n ");
aes_ctx = aes192_cbc_enc_start(shared_secret, iv);
aes192_cbc_enc_continue(enc_aes, msg->msg, MSG_SIZE);
aes192_cbc_enc_finish(aes_ctx);
char bs_dec[128];
char bs_msg[128];
memset(bs_dec, 0, 128);
memset(bs_msg, 0, 128);
base64_encode(&bs_msg, &clear_message, 128 );
base64_decode(bs_dec, bs_msg, 128 );
#else
mbedtls_aes_init( &aes_ctx );
printf(" \n base64: %128.128s \n dec: %s \n", bs_msg, bs_dec);
/* encrypt message with aes using shared secret as the key */
mbedtls_aes_setkey_enc( &aes_ctx, shared_secret, 256 );
dump_buffer(sizeof(crypt_message), crypt_message);
*/
mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_ENCRYPT, MSG_SIZE, iv, tm, msg->msg );
mbedtls_aes_free (&aes_ctx);
#endif
DBG("message to send: %s \n ", msg_text);
// dump_buffer(sizeof(struct pagermessage), msg);
char to_base64[sizeof(struct keypair)];
base64_encode(&to_base64, to, sizeof(struct keypair));
printf(" \nto (keypair): len: %u base64: \n %129.129s \n", sizeof(struct keypair) ,to_base64, to);
char to_base64[sizeof(struct pl_keypair)];
base64_encode(&to_base64, to, sizeof(struct pl_keypair));
DBG(" \nto (keypair): len: %u base64: \n %129.129s \n", sizeof(struct pl_keypair) ,to_base64, to);
char msg_base64[sizeof(struct pagermessage)];
base64_encode(&msg_base64, msg, sizeof(struct pagermessage));
printf(" \n encmsg: len: %u base64: \n %177.177s \n", sizeof(struct pagermessage) ,msg_base64, msg);
char msg_base64[sizeof(struct pl_pagermessage)];
base64_encode(&msg_base64, msg, sizeof(struct pl_pagermessage));
DBG(" \n encmsg: len: %u base64: \n %177.177s \n", sizeof(struct pl_pagermessage) ,msg_base64, msg);
return msg;
}
void receive_message(struct keypair *me, struct pagermessage *msg)
void pl_receive_message(struct pl_keypair *me, struct pl_pagermessage *msg)
{
uint8_t sender_decompressed_point[64];
uint8_t shared_secret[32] = {0};
uint8_t shared_secret[SHARED_SECRET_SIZE] = {0};
char crypt_message[128];
char decrypted_message[128];
char crypt_message[MSG_SIZE];
char decrypted_message[MSG_SIZE];
/* decompress the senders public key */
uECC_decompress(msg->sender_compressed_point, sender_decompressed_point, curve);
/*calculate shared secret on receiver*/
if (!uECC_shared_secret(sender_decompressed_point, me->private, shared_secret, curve)) {
printf("shared_secret() failed (receive)\n");
DBG("shared_secret() failed (receive)\n");
}
dump_buffer(32, shared_secret);
dump_buffer(16, msg->iv);
DB(SHARED_SECRET_SIZE, shared_secret);
DB(IV_SIZE, msg->iv);
#ifdef ARDUINO
memcpy(decrypted_message, msg->msg, MSG_SIZE);
aes_context aes_ctx;
aes_ctx = aes192_cbc_dec_start(shared_secret, msg->iv);
aes192_cbc_dec_continue(aes_ctx, decrypted_message, MSG_SIZE);
aes192_cbc_dec_finish(aes_ctx);
#else
/* decrypt the message */
mbedtls_aes_init( &dec_aes );
mbedtls_aes_init( &aes_ctx );
mbedtls_aes_setkey_dec( &dec_aes, shared_secret, 256 );
mbedtls_aes_setkey_dec( &aes_ctx, shared_secret, 256 );
mbedtls_aes_crypt_cbc( &dec_aes, MBEDTLS_AES_DECRYPT, 128, msg->iv, msg->msg, decrypted_message );
printf("decrypted_message: %s \n ", decrypted_message);
dump_buffer(sizeof(decrypted_message), decrypted_message);
mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, MSG_SIZE, msg->iv, msg->msg, decrypted_message );
mbedtls_aes_free ( &aes_ctx );
#endif
DBG("decrypted_message: %s \n ", decrypted_message);
DB(sizeof(decrypted_message), decrypted_message);
}
struct keypair * create_keypair() {
struct keypair *keypair;
keypair = malloc(sizeof(struct keypair));
struct pl_keypair * pl_create_keypair() {
struct pl_keypair *keypair;
keypair = malloc(sizeof(struct pl_keypair));
memset(keypair->public, 3, sizeof(keypair->public));
memset(keypair->private, 4, sizeof(keypair->private));
......@@ -328,30 +165,44 @@ struct keypair * create_keypair() {
/* Generate arbitrary EC point (public) on Curve */
if (!uECC_make_key(keypair->public, keypair->private, curve)) {
printf("uECC_make_key() failed\n");
DBG("uECC_make_key() failed\n");
}
uECC_compress(keypair->public, keypair->compressed_point, curve);
printf(" \n comp point \n ");
dump_buffer(32, keypair->compressed_point);
printf(" \n end comp point \n ");
DBG(" \n comp point \n ");
DB(sizeof(keypair->compressed_point), keypair->compressed_point);
DBG(" \n end comp point \n ");
return keypair;
}
save_key(struct keypair *key, char * filename) {
int
pl_save_key(struct pl_keypair *key, char * filename) {
#ifdef ARDUINO
// not implemented
return 0;
#else
FILE *f;
f = fopen(filename, "w");
fwrite(key, 1, sizeof(struct keypair), f);
fwrite(key, 1, sizeof(struct pl_keypair), f);
fclose(f);
#endif
}
load_key(struct keypair *key, char * filename) {
int
pl_load_key(struct pl_keypair *key, char * filename) {
#ifdef ARDUINO
return 0;
#else
FILE *f;
f = fopen(filename, "r");
fread(key, 1, sizeof(struct keypair), f);
fread(key, 1, sizeof(struct pl_keypair), f);
fclose(f);
#endif
}
#include "packets.h"
const struct uECC_Curve_t * curve;
//const struct uECC_Curve_t * curve;
// mbedtls things
//mbedtls_aes_context enc_aes;
//mbedtls_aes_context dec_aes;
void init();
struct pagermessage * send_message(struct keypair *, struct keypair *, char *);
void receive_message(struct keypair *me, struct pagermessage *msg);
void receive_message(struct keypair *, struct pagermessage *);
struct keypair * create_keypair();
void save_key(struct keypair *key, char * filename);
void load_key(struct keypair *key, char * filename);
struct keypair * pl_create_keypair();
struct pagermessage * pl_send_message(struct keypair *, struct keypair *, char *);
// common.h
void dump_buffer(unsigned int , const unsigned char* );
void pl_receive_message(struct keypair *, struct pagermessage *);
void vli_print(char *, uint8_t *, unsigned int);
/* b64_alphabet:
* Description: Base64 alphabet table, a mapping between integers
* and base64 digits
* Notes: This is an extern here but is defined in Base64.c
*/
extern const char b64_alphabet[];
/* base64_encode:
* Description:
* Encode a string of characters as base64
* Parameters:
* output: the output buffer for the encoding, stores the encoded string
* input: the input buffer for the encoding, stores the binary to be encoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the encoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_encode(char *output, char *input, int inputLen);
/* base64_decode:
* Description:
* Decode a base64 encoded string into bytes
* Parameters:
* output: the output buffer for the decoding,
* stores the decoded binary
* input: the input buffer for the decoding,
* stores the base64 string to be decoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the decoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0