pagerlib.c 9.26 KB
Newer Older
hark's avatar
hark committed
1 2 3 4 5
#include <stdio.h>
#include <string.h>
#include "../micro-ecc/uECC.h"
#include "packets.h"
#include <stdlib.h>
hark's avatar
hark committed
6
#include "things.h"
hark's avatar
dingen  
hark committed
7
#include "pagerlib.h"
yids's avatar
yids committed
8 9 10 11 12 13

#ifndef ARDUINO
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
hark's avatar
hark committed
14

hark's avatar
dingen  
hark committed
15
unsigned char fakeiv[] = "123456789abcdefghijklmnop";
hark's avatar
hark committed
16

yids's avatar
yids committed
17 18 19 20 21 22
/*
* int rng (uint8_t *dest, unsigned size)
* random number generator
* uint8_t *dest destination for the random numbers
* unsigned size number of random bytes to put in dest
*/
hark's avatar
dingen  
hark committed
23
int rng (uint8_t *dest, unsigned size) {
hark's avatar
hark committed
24
#ifndef ARDUINO
hark's avatar
hark committed
25
  int fd = open("/dev/urandom", O_RDONLY);
hark's avatar
hark committed
26
  if (fd == -1) {
hark's avatar
hark committed
27
    fd = open("/dev/random", O_RDONLY);
hark's avatar
hark committed
28 29 30 31
    if (fd == -1) {
      return 0;
    }
  }
hark's avatar
hark committed
32

hark's avatar
hark committed
33 34 35 36 37 38 39 40 41 42 43
  char *ptr = (char *)dest;
  size_t left = size;
  while (left > 0) {
    size_t bytes_read = read(fd, ptr, left);
    if (bytes_read <= 0) { // read failed
      close(fd);
      return 0;
    }
    left -= bytes_read;
    ptr += bytes_read;
  }
hark's avatar
hark committed
44

hark's avatar
hark committed
45 46 47
  close(fd);
  return 1;
#else
48
  // arduino rng comes here
hark's avatar
dingen  
hark committed
49
  return 0;
hark's avatar
hark committed
50
#endif
hark's avatar
dingen  
hark committed
51
}
hark's avatar
hark committed
52

yids's avatar
yids committed
53 54 55 56 57
/* 
* uint32_t compressed_point_to_addr( uint8_t input[])
* takes an compressed point and turns it into an address
* should become a proper hash function one day
*/
58 59 60 61
uint32_t compressed_point_to_addr( uint8_t input[])
{
  uint32_t hashval;
  int i = 0;
yids's avatar
yids committed
62
  //  DBM("hash address input", ECC_COMPRESSED_SIZE, input);
63
  while( hashval < UINT32_MAX && i < ECC_COMPRESSED_SIZE ) {
yids's avatar
yids committed
64 65 66 67 68
    //printf("hashval %u  i: %u\n ", hashval, i);
    hashval = hashval << 8;
    hashval += input[ i ];
    i++;
  }
69 70
  return hashval;
}
hark's avatar
hark committed
71

yids's avatar
yids committed
72 73 74 75 76
/*
* inline struct pl_ctx * pl_init()
* allocate memory for all the stuff in pl_ctx
* returns a pointer to pl_ctx
*/
hark's avatar
hark committed
77
inline struct pl_ctx * pl_init() {
hark's avatar
dingen  
hark committed
78 79
  struct pl_ctx * ctx;
  ctx = (struct pl_ctx *) malloc(sizeof(struct pl_ctx));
hark's avatar
hark committed
80 81 82
  ctx->curve = CURVE;
  ctx->msg = (struct pl_pagermessage *) malloc(sizeof(struct pl_pagermessage));
  memset(ctx->msg, 7, sizeof(struct pl_pagermessage));
hark's avatar
dingen  
hark committed
83 84
  ctx->kp = (struct pl_keypair *) malloc(sizeof(struct pl_keypair));
  memset(ctx->kp, 9, sizeof(struct pl_keypair));
85
//  ctx->keypairs = (struct list_kp *) malloc( sizeof(struct list_kp) ); 
hark's avatar
dingen  
hark committed
86 87
  uECC_set_rng(rng);
  return ctx;
hark's avatar
update  
hark committed
88
}
hark's avatar
hark committed
89

hark's avatar
hark committed
90
inline int pl_set_receiver(struct pl_ctx *ctx, struct pl_keypair *keypair)
hark's avatar
hark committed
91 92
{

hark's avatar
hark committed
93
  return 1; 
hark's avatar
hark committed
94
}
hark's avatar
hark committed
95

hark's avatar
hark committed
96 97
/*
 * This sends a message (encrypts it)
hark's avatar
bla  
hark committed
98
 * Before calling this make sure u set sender ( ctx->kp , ctx->msg->sender_compressed_point) and receiver ctx->receiver_compressed_point, and the message you want to send in ctx->msg->msg
hark's avatar
hark committed
99
 */
hark's avatar
hark committed
100

hark's avatar
hark committed
101
inline int pl_send_message(struct pl_ctx *ctx) {
hark's avatar
hark committed
102

hark's avatar
hark committed
103
  memset(ctx->shared_secret, 7, sizeof(ctx->shared_secret));
hark's avatar
hark committed
104 105

  /* create a random iv */ 
hark's avatar
hark committed
106
  rng(&ctx->msg->iv, sizeof(ctx->msg->iv));
hark's avatar
bla  
hark committed
107

hark's avatar
hark committed
108
  // copy compressed point into pager message
hark's avatar
hark committed
109
  memcpy(&ctx->msg->sender_compressed_point, &ctx->kp->compressed_point, sizeof(ctx->msg->sender_compressed_point));
hark's avatar
hark committed
110

hark's avatar
bla  
hark committed
111
  //DBG("Sending message \n");
hark's avatar
update  
hark committed
112
#ifndef NOCRYPT
hark's avatar
dingen  
hark committed
113
  /* decompress key */
hark's avatar
hark committed
114 115
  uECC_decompress(&ctx->receiver_compressed_point, &ctx->decompressed_point, ctx->curve);
  
116 117
 // DBM("#receiver compressed point ",sizeof(ctx->receiver_compressed_point) , &ctx->receiver_compressed_point);
 // DBM("#decompr point ",sizeof(ctx->decompressed_point) , &ctx->decompressed_point);
hark's avatar
dingen  
hark committed
118

119
  ctx->msg->address = compressed_point_to_addr(ctx->receiver_compressed_point);
hark's avatar
bla  
hark committed
120 121
 // DBM("address: ", sizeof(ctx->msg->address), &ctx->msg->address);
  //printf(">>>>>>>>>>>>>>>>>>>address: %u \n \n", ctx->msg->address );
hark's avatar
update  
hark committed
122
  /*calculate shared secret on sender*/
hark's avatar
dingen  
hark committed
123 124
  
  if (!uECC_shared_secret(&ctx->decompressed_point, &ctx->kp->private_key, &ctx->shared_secret, ctx->curve)) {
hark's avatar
hark committed
125
    DBG("shared_secret() failed in send_message (1)\n");
hark's avatar
update  
hark committed
126 127
    return 1;
  }
hark's avatar
hark committed
128
  
129 130
//  DBM("msg->msg in pl_send_message before crypt", sizeof(ctx->msg->msg), &ctx->msg->msg);
//  DBM("shared secret in pl_send_message", sizeof(ctx->shared_secret), &ctx->shared_secret);
hark's avatar
dingen  
hark committed
131

hark's avatar
hark committed
132
#ifdef ARDUINO
hark's avatar
update  
hark committed
133
  
hark's avatar
hark committed
134 135 136
     ctx->aes_ctx = aes192_cbc_enc_start(&ctx->shared_secret, ctx->msg->iv);
     aes192_cbc_enc_continue(ctx->aes_ctx, ctx->msg->msg, MSG_SIZE);
     aes192_cbc_enc_finish(ctx->aes_ctx);
hark's avatar
update  
hark committed
137
 
hark's avatar
hark committed
138
#else
hark's avatar
hark committed
139
  mbedtls_aes_init( &ctx->aes_ctx );
hark's avatar
hark committed
140

141
/* encrypt message with aes using shared secret as the key */
hark's avatar
hark committed
142
  mbedtls_aes_setkey_enc( &ctx->aes_ctx, &ctx->shared_secret, AES_KEYSIZE );
hark's avatar
hark committed
143

hark's avatar
update  
hark committed
144
  char cmsg[MSG_SIZE];
hark's avatar
hark committed
145 146 147 148
  memcpy(&cmsg, &ctx->msg->msg, MSG_SIZE);
  char civ[IV_SIZE];
  memcpy(&civ, &ctx->msg->iv, IV_SIZE);

149
//  DBM("iv in pl_send_message before crypt", sizeof(ctx->msg->iv), &ctx->msg->iv);
hark's avatar
hark committed
150 151


hark's avatar
hark committed
152
  mbedtls_aes_crypt_cbc( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, MSG_SIZE, civ, &cmsg, &ctx->msg->msg );
hark's avatar
hark committed
153
  mbedtls_aes_free (&ctx->aes_ctx);
154
//  DBG("message to send: %s \n ", ctx->msg);
hark's avatar
update  
hark committed
155 156
#endif
#endif
yids's avatar
yids committed
157

hark's avatar
update  
hark committed
158 159 160 161 162 163 164 165 166
  /*
     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 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);
     */
167 168
//  DBM("msg->msg in pl_send_message after crypt", sizeof(ctx->msg->msg), &ctx->msg->msg);
//  DBM("iv in pl_send_message after crypt", sizeof(ctx->msg->iv), &ctx->msg->iv);
hark's avatar
hark committed
169

hark's avatar
hark committed
170
  return 0;
hark's avatar
hark committed
171
}
yids's avatar
yids committed
172

hark's avatar
hark committed
173
inline int pl_receive_message(struct pl_ctx * ctx)
hark's avatar
hark committed
174
{
hark's avatar
hark committed
175 176
  memset(&ctx->shared_secret, 7, sizeof(ctx->shared_secret));
  memset(&ctx->clear_message, 7, sizeof(ctx->clear_message));
hark's avatar
hark committed
177

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
 // DBM("msg->msg in pl_receive_message before crypt", sizeof(ctx->msg->msg), &ctx->msg->msg);

 /* check if message is for us */ 
    struct list_kp * list;
    int found = 0;
    for(list = ctx->keypairs; list != NULL; list = list->next) {
        printf("\n address in msg: %u address in list: %u \n", ctx->msg->address, list->id );
              if (ctx->msg->address == list->id) 
              {
                // set keypair to use
                ctx->kp = list->kp;
                found = 1;
              }
        }
    // exit when address not found
    if (found == 0) return 1;

hark's avatar
hark committed
195

hark's avatar
update  
hark committed
196
  /* decompress the senders public key */
hark's avatar
hark committed
197
  uECC_decompress(&ctx->msg->sender_compressed_point, &ctx->decompressed_point, ctx->curve);
198 199
  //DBM("ctx->kp", sizeof(struct pl_pagermessage),&ctx->kp);
  //DBM("ctx->kp->private_key", sizeof(ctx->kp->private_key),&ctx->kp->private_key);
hark's avatar
update  
hark committed
200
  /*calculate shared secret on receiver*/
hark's avatar
hark committed
201
  if (!uECC_shared_secret(&ctx->decompressed_point, &ctx->kp->private_key, &ctx->shared_secret, ctx->curve)) {
hark's avatar
update  
hark committed
202 203
    DBG("shared_secret() failed (receive)\n");
  }
204
//  DBM("shared secret in pl_receive_message", sizeof(ctx->shared_secret), &ctx->shared_secret);
hark's avatar
dingen  
hark committed
205

hark's avatar
hark committed
206

hark's avatar
update  
hark committed
207
#ifndef NOCRYPT
hark's avatar
hark committed
208
#ifdef ARDUINO
hark's avatar
hark committed
209
  memcpy(ctx->clear_message, ctx->msg->msg, MSG_SIZE);
hark's avatar
update  
hark committed
210 211
/*
  aes_context aes_ctx;
hark's avatar
hark committed
212 213
  aes_ctx = aes192_cbc_dec_start(ctx->shared_secret, ctx->msg->iv);
  aes192_cbc_dec_continue(aes_ctx, ctx->clear_message, MSG_SIZE);
hark's avatar
update  
hark committed
214 215
  aes192_cbc_dec_finish(aes_ctx);
 */
hark's avatar
hark committed
216
#else
hark's avatar
update  
hark committed
217
  /* decrypt the message */
hark's avatar
dingen  
hark committed
218
  mbedtls_aes_init( &ctx->aes_ctx );
219
  //DBM("iv in pl_receive_message", sizeof(ctx->msg->iv), &ctx->msg->iv);
hark's avatar
hark committed
220

hark's avatar
hark committed
221
  mbedtls_aes_setkey_dec( &ctx->aes_ctx, &ctx->shared_secret, AES_KEYSIZE );
hark's avatar
hark committed
222

hark's avatar
hark committed
223
  mbedtls_aes_crypt_cbc( &ctx->aes_ctx, MBEDTLS_AES_DECRYPT, MSG_SIZE, ctx->msg->iv, &ctx->msg->msg, &ctx->clear_message );
hark's avatar
dingen  
hark committed
224
  mbedtls_aes_free ( &ctx->aes_ctx );
hark's avatar
hark committed
225 226
  memcpy(ctx->msg->msg, ctx->clear_message, MSG_SIZE);

hark's avatar
update  
hark committed
227
#endif
hark's avatar
hark committed
228
#endif
hark's avatar
hark committed
229 230
  DBM("msg->msg in pl_receive_message after crypt", sizeof(ctx->msg->msg), &ctx->msg->msg);
  DBM("iv in pl_receive_message after crypt", sizeof(ctx->msg->iv), &ctx->msg->iv);
hark's avatar
dingen  
hark committed
231

hark's avatar
hark committed
232 233 234 235
}



hark's avatar
hark committed
236
inline int pl_create_keypair(struct pl_ctx *ctx, struct pl_keypair *keypair) {
hark's avatar
update  
hark committed
237
  
hark's avatar
hark committed
238

hark's avatar
update  
hark committed
239 240 241
//  memset(keypair->public_key, 3, sizeof(keypair->public_key));
//  memset(keypair->private_key, 4, sizeof(keypair->private_key));
//  memset(keypair->compressed_point, 5, sizeof(keypair->compressed_point));
hark's avatar
hark committed
242 243 244


  /* Generate arbitrary EC point (public) on Curve */
hark's avatar
hark committed
245
  if (!uECC_make_key(&ctx->decompressed_point, &keypair->private_key, ctx->curve)) {
hark's avatar
hark committed
246
    DBG("uECC_make_key() failed\n");
hark's avatar
hark committed
247
  }
hark's avatar
hark committed
248 249 250
  uECC_compress(&ctx->decompressed_point, &keypair->compressed_point, ctx->curve);
//    DBG("compress failed in create_keypair");
 
hark's avatar
dingen  
hark committed
251
  return 0;
hark's avatar
hark committed
252 253
}

hark's avatar
hark committed
254
inline int
hark's avatar
hark committed
255 256 257 258 259 260 261
pl_save_key(struct pl_keypair *key, char * filename) {

#ifdef ARDUINO
  // not implemented
  return 0;
#else

hark's avatar
hark committed
262 263 264 265
  FILE  *sf;
  sf = fopen(filename, "w");
  fwrite(key, 1, sizeof(struct pl_keypair), sf);
  fclose(sf);
hark's avatar
hark committed
266 267
#endif

hark's avatar
hark committed
268 269
}

hark's avatar
hark committed
270
inline int
hark's avatar
hark committed
271 272 273 274
pl_load_key(struct pl_keypair *key, char * filename) {
#ifdef ARDUINO
  return 0;
#else
hark's avatar
hark committed
275 276 277 278 279
  FILE  *lf;
  lf = fopen(filename, "r");
  fread(key, 1, sizeof(struct pl_keypair), lf);

  fclose(lf);
hark's avatar
hark committed
280
#endif
hark's avatar
hark committed
281 282
}

283 284 285 286
pl_load_key_in_list(struct pl_ctx *ctx, struct pl_keypair *key){

  struct list_kp *list, *ni, *last;
  list = ctx->keypairs;
hark's avatar
hark committed
287

288 289 290 291 292
  // make new list item
  ni = (struct list_kp *) malloc( sizeof(struct list_kp) ); 
  ni->next = NULL;
  ni->id = compressed_point_to_addr(key->compressed_point);
  ni->kp = key;
hark's avatar
hark committed
293 294


295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
  // check if list exists
  if (list == NULL) {
//    last = ni;
//    list = ni;
    ctx->keypairs = ni;
  }
  else
  {

    // walk to end of list
    for(1; 1; list = list->next) {
//      printf("walk: %u \n ", list->next);
      if (list->next == NULL) break;
    }
    list->next = ni;
  }

}

pl_print_keylist(struct pl_ctx *ctx) {
    struct list_kp * list;
    printf("the list of loaded keys: \n ");
    for(list = ctx->keypairs; list != NULL; list = list->next) {
        printf("address in list: %u \n", list->id );
hark's avatar
bla  
hark committed
319 320

    }
321 322

}