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

}