Merge "Adding tinyDTLS into iotivity repo"
[platform/upstream/iotivity.git] / extlibs / tinydtls / crypto.c
1 /* dtls -- a very basic DTLS implementation
2  *
3  * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
4  * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use, copy,
10  * modify, merge, publish, distribute, sublicense, and/or sell copies
11  * of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26
27 #include <stdio.h>
28
29 #include "tinydtls.h"
30 #include "dtls_config.h"
31
32 #ifdef HAVE_ASSERT_H
33 #include <assert.h>
34 #else
35 #define assert(x)
36 #endif
37
38 #include "global.h"
39 #include "debug.h"
40 #include "numeric.h"
41 #include "dtls.h"
42 #include "crypto.h"
43 #include "ccm.h"
44 #include "ecc/ecc.h"
45 #include "prng.h"
46 #include "netq.h"
47
48 #ifndef WITH_CONTIKI
49 #include <pthread.h>
50 #endif
51
52 #define HMAC_UPDATE_SEED(Context,Seed,Length)           \
53   if (Seed) dtls_hmac_update(Context, (Seed), (Length))
54
55 static struct dtls_cipher_context_t cipher_context;
56 #ifndef WITH_CONTIKI
57 static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER;
58 #endif
59
60 static struct dtls_cipher_context_t *dtls_cipher_context_get(void)
61 {
62 #ifndef WITH_CONTIKI
63   pthread_mutex_lock(&cipher_context_mutex);
64 #endif
65   return &cipher_context;
66 }
67
68 static void dtls_cipher_context_release(void)
69 {
70 #ifndef WITH_CONTIKI
71   pthread_mutex_unlock(&cipher_context_mutex);
72 #endif
73 }
74
75 #ifndef WITH_CONTIKI
76 void crypto_init()
77 {
78 }
79
80 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
81   return malloc(sizeof(dtls_handshake_parameters_t));
82 }
83
84 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
85   free(handshake);
86 }
87
88 static dtls_security_parameters_t *dtls_security_malloc() {
89   return malloc(sizeof(dtls_security_parameters_t));
90 }
91
92 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
93   free(security);
94 }
95 #else /* WITH_CONTIKI */
96
97 #include "memb.h"
98 MEMB(handshake_storage, dtls_handshake_parameters_t, DTLS_HANDSHAKE_MAX);
99 MEMB(security_storage, dtls_security_parameters_t, DTLS_SECURITY_MAX);
100
101 void crypto_init() {
102   memb_init(&handshake_storage);
103   memb_init(&security_storage);
104 }
105
106 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
107   return memb_alloc(&handshake_storage);
108 }
109
110 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
111   memb_free(&handshake_storage, handshake);
112 }
113
114 static dtls_security_parameters_t *dtls_security_malloc() {
115   return memb_alloc(&security_storage);
116 }
117
118 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
119   memb_free(&security_storage, security);
120 }
121 #endif /* WITH_CONTIKI */
122
123 dtls_handshake_parameters_t *dtls_handshake_new()
124 {
125   dtls_handshake_parameters_t *handshake;
126
127   handshake = dtls_handshake_malloc();
128   if (!handshake) {
129     dtls_crit("can not allocate a handshake struct\n");
130     return NULL;
131   }
132
133   memset(handshake, 0, sizeof(*handshake));
134
135   if (handshake) {
136     /* initialize the handshake hash wrt. the hard-coded DTLS version */
137     dtls_debug("DTLSv12: initialize HASH_SHA256\n");
138     /* TLS 1.2:  PRF(secret, label, seed) = P_<hash>(secret, label + seed) */
139     /* FIXME: we use the default SHA256 here, might need to support other 
140               hash functions as well */
141     dtls_hash_init(&handshake->hs_state.hs_hash);
142   }
143   return handshake;
144 }
145
146 void dtls_handshake_free(dtls_handshake_parameters_t *handshake)
147 {
148   if (!handshake)
149     return;
150
151   netq_delete_all(handshake->reorder_queue);
152   dtls_handshake_dealloc(handshake);
153 }
154
155 dtls_security_parameters_t *dtls_security_new()
156 {
157   dtls_security_parameters_t *security;
158
159   security = dtls_security_malloc();
160   if (!security) {
161     dtls_crit("can not allocate a security struct\n");
162     return NULL;
163   }
164
165   memset(security, 0, sizeof(*security));
166
167   if (security) {
168     security->cipher = TLS_NULL_WITH_NULL_NULL;
169     security->compression = TLS_COMPRESSION_NULL;
170   }
171   return security;
172 }
173
174 void dtls_security_free(dtls_security_parameters_t *security)
175 {
176   if (!security)
177     return;
178
179   dtls_security_dealloc(security);
180 }
181
182 size_t
183 dtls_p_hash(dtls_hashfunc_t h,
184             const unsigned char *key, size_t keylen,
185             const unsigned char *label, size_t labellen,
186             const unsigned char *random1, size_t random1len,
187             const unsigned char *random2, size_t random2len,
188             unsigned char *buf, size_t buflen) {
189   dtls_hmac_context_t *hmac_a, *hmac_p;
190
191   unsigned char A[DTLS_HMAC_DIGEST_SIZE];
192   unsigned char tmp[DTLS_HMAC_DIGEST_SIZE];
193   size_t dlen;                  /* digest length */
194   size_t len = 0;                       /* result length */
195
196   hmac_a = dtls_hmac_new(key, keylen);
197   if (!hmac_a)
198     return 0;
199
200   /* calculate A(1) from A(0) == seed */
201   HMAC_UPDATE_SEED(hmac_a, label, labellen);
202   HMAC_UPDATE_SEED(hmac_a, random1, random1len);
203   HMAC_UPDATE_SEED(hmac_a, random2, random2len);
204
205   dlen = dtls_hmac_finalize(hmac_a, A);
206
207   hmac_p = dtls_hmac_new(key, keylen);
208   if (!hmac_p)
209     goto error;
210
211   while (len + dlen < buflen) {
212
213     /* FIXME: rewrite loop to avoid superflous call to dtls_hmac_init() */
214     dtls_hmac_init(hmac_p, key, keylen);
215     dtls_hmac_update(hmac_p, A, dlen);
216
217     HMAC_UPDATE_SEED(hmac_p, label, labellen);
218     HMAC_UPDATE_SEED(hmac_p, random1, random1len);
219     HMAC_UPDATE_SEED(hmac_p, random2, random2len);
220
221     len += dtls_hmac_finalize(hmac_p, tmp);
222     memcpy(buf, tmp, dlen);
223     buf += dlen;
224
225     /* calculate A(i+1) */
226     dtls_hmac_init(hmac_a, key, keylen);
227     dtls_hmac_update(hmac_a, A, dlen);
228     dtls_hmac_finalize(hmac_a, A);
229   }
230
231   dtls_hmac_init(hmac_p, key, keylen);
232   dtls_hmac_update(hmac_p, A, dlen);
233   
234   HMAC_UPDATE_SEED(hmac_p, label, labellen);
235   HMAC_UPDATE_SEED(hmac_p, random1, random1len);
236   HMAC_UPDATE_SEED(hmac_p, random2, random2len);
237   
238   dtls_hmac_finalize(hmac_p, tmp);
239   memcpy(buf, tmp, buflen - len);
240
241  error:
242   dtls_hmac_free(hmac_a);
243   dtls_hmac_free(hmac_p);
244
245   return buflen;
246 }
247
248 size_t 
249 dtls_prf(const unsigned char *key, size_t keylen,
250          const unsigned char *label, size_t labellen,
251          const unsigned char *random1, size_t random1len,
252          const unsigned char *random2, size_t random2len,
253          unsigned char *buf, size_t buflen) {
254
255   /* Clear the result buffer */
256   memset(buf, 0, buflen);
257   return dtls_p_hash(HASH_SHA256, 
258                      key, keylen, 
259                      label, labellen, 
260                      random1, random1len,
261                      random2, random2len,
262                      buf, buflen);
263 }
264
265 void
266 dtls_mac(dtls_hmac_context_t *hmac_ctx, 
267          const unsigned char *record,
268          const unsigned char *packet, size_t length,
269          unsigned char *buf) {
270   uint16 L;
271   dtls_int_to_uint16(L, length);
272
273   assert(hmac_ctx);
274   dtls_hmac_update(hmac_ctx, record +3, sizeof(uint16) + sizeof(uint48));
275   dtls_hmac_update(hmac_ctx, record, sizeof(uint8) + sizeof(uint16));
276   dtls_hmac_update(hmac_ctx, L, sizeof(uint16));
277   dtls_hmac_update(hmac_ctx, packet, length);
278   
279   dtls_hmac_finalize(hmac_ctx, buf);
280 }
281
282 static size_t
283 dtls_ccm_encrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, size_t srclen,
284                  unsigned char *buf, 
285                  unsigned char *nounce,
286                  const unsigned char *aad, size_t la) {
287   long int len;
288
289   assert(ccm_ctx);
290
291   len = dtls_ccm_encrypt_message(&ccm_ctx->ctx, 8 /* M */, 
292                                  max(2, 15 - DTLS_CCM_NONCE_SIZE),
293                                  nounce,
294                                  buf, srclen, 
295                                  aad, la);
296   return len;
297 }
298
299 static size_t
300 dtls_ccm_decrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src,
301                  size_t srclen, unsigned char *buf,
302                  unsigned char *nounce,
303                  const unsigned char *aad, size_t la) {
304   long int len;
305
306   assert(ccm_ctx);
307
308   len = dtls_ccm_decrypt_message(&ccm_ctx->ctx, 8 /* M */, 
309                                  max(2, 15 - DTLS_CCM_NONCE_SIZE),
310                                  nounce,
311                                  buf, srclen, 
312                                  aad, la);
313   return len;
314 }
315
316 #ifdef DTLS_PSK
317 int
318 dtls_psk_pre_master_secret(unsigned char *key, size_t keylen,
319                            unsigned char *result, size_t result_len) {
320   unsigned char *p = result;
321
322   if (result_len < (2 * (sizeof(uint16) + keylen))) {
323     return -1;
324   }
325
326   dtls_int_to_uint16(p, keylen);
327   p += sizeof(uint16);
328
329   memset(p, 0, keylen);
330   p += keylen;
331
332   memcpy(p, result, sizeof(uint16));
333   p += sizeof(uint16);
334   
335   memcpy(p, key, keylen);
336
337   return 2 * (sizeof(uint16) + keylen);
338 }
339 #endif /* DTLS_PSK */
340
341 #ifdef DTLS_ECC
342 static void dtls_ec_key_to_uint32(const unsigned char *key, size_t key_size,
343                                   uint32_t *result) {
344   int i;
345
346   for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
347     *result = dtls_uint32_to_int(&key[i * sizeof(uint32_t)]);
348     result++;
349   }
350 }
351
352 static void dtls_ec_key_from_uint32(const uint32_t *key, size_t key_size,
353                                     unsigned char *result) {
354   int i;
355
356   for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
357     dtls_int_to_uint32(result, key[i]);
358     result += 4;
359   }
360 }
361
362 int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size,
363                                  unsigned char *buf) {
364   int i;
365   unsigned char *buf_orig = buf;
366   int first = 1; 
367
368   for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
369     if (key[i] == 0)
370       continue;
371     /* the first bit has to be set to zero, to indicate a poritive integer */
372     if (first && key[i] & 0x80000000) {
373       *buf = 0;
374       buf++;
375       dtls_int_to_uint32(buf, key[i]);
376       buf += 4;      
377     } else if (first && !(key[i] & 0xFF800000)) {
378       buf[0] = (key[i] >> 16) & 0xff;
379       buf[1] = (key[i] >> 8) & 0xff;
380       buf[2] = key[i] & 0xff;
381       buf += 3;
382     } else if (first && !(key[i] & 0xFFFF8000)) {
383       buf[0] = (key[i] >> 8) & 0xff;
384       buf[1] = key[i] & 0xff;
385       buf += 2;
386     } else if (first && !(key[i] & 0xFFFFFF80)) {
387       buf[0] = key[i] & 0xff;
388       buf += 1;
389     } else {
390       dtls_int_to_uint32(buf, key[i]);
391       buf += 4;
392     }
393     first = 0;
394   }
395   return buf - buf_orig;
396 }
397
398 int dtls_ecdh_pre_master_secret(unsigned char *priv_key,
399                                    unsigned char *pub_key_x,
400                                    unsigned char *pub_key_y,
401                                    size_t key_size,
402                                    unsigned char *result,
403                                    size_t result_len) {
404   uint32_t priv[8];
405   uint32_t pub_x[8];
406   uint32_t pub_y[8];
407   uint32_t result_x[8];
408   uint32_t result_y[8];
409
410   if (result_len < key_size) {
411     return -1;
412   }
413
414   dtls_ec_key_to_uint32(priv_key, key_size, priv);
415   dtls_ec_key_to_uint32(pub_key_x, key_size, pub_x);
416   dtls_ec_key_to_uint32(pub_key_y, key_size, pub_y);
417
418   ecc_ecdh(pub_x, pub_y, priv, result_x, result_y);
419
420   dtls_ec_key_from_uint32(result_x, key_size, result);
421   return key_size;
422 }
423
424 void
425 dtls_ecdsa_generate_key(unsigned char *priv_key,
426                         unsigned char *pub_key_x,
427                         unsigned char *pub_key_y,
428                         size_t key_size) {
429   uint32_t priv[8];
430   uint32_t pub_x[8];
431   uint32_t pub_y[8];
432
433   do {
434     dtls_prng((unsigned char *)priv, key_size);
435   } while (!ecc_is_valid_key(priv));
436
437   ecc_gen_pub_key(priv, pub_x, pub_y);
438
439   dtls_ec_key_from_uint32(priv, key_size, priv_key);
440   dtls_ec_key_from_uint32(pub_x, key_size, pub_key_x);
441   dtls_ec_key_from_uint32(pub_y, key_size, pub_key_y);
442 }
443
444 /* rfc4492#section-5.4 */
445 void
446 dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size,
447                            const unsigned char *sign_hash, size_t sign_hash_size,
448                            uint32_t point_r[9], uint32_t point_s[9]) {
449   int ret;
450   uint32_t priv[8];
451   uint32_t hash[8];
452   uint32_t rand[8];
453   
454   dtls_ec_key_to_uint32(priv_key, key_size, priv);
455   dtls_ec_key_to_uint32(sign_hash, sign_hash_size, hash);
456   do {
457     dtls_prng((unsigned char *)rand, key_size);
458     ret = ecc_ecdsa_sign(priv, hash, rand, point_r, point_s);
459   } while (ret);
460 }
461
462 void
463 dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size,
464                       const unsigned char *client_random, size_t client_random_size,
465                       const unsigned char *server_random, size_t server_random_size,
466                       const unsigned char *keyx_params, size_t keyx_params_size,
467                       uint32_t point_r[9], uint32_t point_s[9]) {
468   dtls_hash_ctx data;
469   unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
470
471   dtls_hash_init(&data);
472   dtls_hash_update(&data, client_random, client_random_size);
473   dtls_hash_update(&data, server_random, server_random_size);
474   dtls_hash_update(&data, keyx_params, keyx_params_size);
475   dtls_hash_finalize(sha256hash, &data);
476   
477   dtls_ecdsa_create_sig_hash(priv_key, key_size, sha256hash,
478                              sizeof(sha256hash), point_r, point_s);
479 }
480
481 /* rfc4492#section-5.4 */
482 int
483 dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x,
484                            const unsigned char *pub_key_y, size_t key_size,
485                            const unsigned char *sign_hash, size_t sign_hash_size,
486                            unsigned char *result_r, unsigned char *result_s) {
487   uint32_t pub_x[8];
488   uint32_t pub_y[8];
489   uint32_t hash[8];
490   uint32_t point_r[8];
491   uint32_t point_s[8];
492
493   dtls_ec_key_to_uint32(pub_key_x, key_size, pub_x);
494   dtls_ec_key_to_uint32(pub_key_y, key_size, pub_y);
495   dtls_ec_key_to_uint32(result_r, key_size, point_r);
496   dtls_ec_key_to_uint32(result_s, key_size, point_s);
497   dtls_ec_key_to_uint32(sign_hash, sign_hash_size, hash);
498
499   return ecc_ecdsa_validate(pub_x, pub_y, hash, point_r, point_s);
500 }
501
502 int
503 dtls_ecdsa_verify_sig(const unsigned char *pub_key_x,
504                       const unsigned char *pub_key_y, size_t key_size,
505                       const unsigned char *client_random, size_t client_random_size,
506                       const unsigned char *server_random, size_t server_random_size,
507                       const unsigned char *keyx_params, size_t keyx_params_size,
508                       unsigned char *result_r, unsigned char *result_s) {
509   dtls_hash_ctx data;
510   unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
511   
512   dtls_hash_init(&data);
513   dtls_hash_update(&data, client_random, client_random_size);
514   dtls_hash_update(&data, server_random, server_random_size);
515   dtls_hash_update(&data, keyx_params, keyx_params_size);
516   dtls_hash_finalize(sha256hash, &data);
517
518   return dtls_ecdsa_verify_sig_hash(pub_key_x, pub_key_y, key_size, sha256hash,
519                                     sizeof(sha256hash), result_r, result_s);
520 }
521 #endif /* DTLS_ECC */
522
523 int 
524 dtls_encrypt(const unsigned char *src, size_t length,
525              unsigned char *buf,
526              unsigned char *nounce,
527              unsigned char *key, size_t keylen,
528              const unsigned char *aad, size_t la)
529 {
530   int ret;
531   struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
532
533   ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
534   if (ret < 0) {
535     /* cleanup everything in case the key has the wrong size */
536     dtls_warn("cannot set rijndael key\n");
537     goto error;
538   }
539
540   if (src != buf)
541     memmove(buf, src, length);
542   ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
543
544 error:
545   dtls_cipher_context_release();
546   return ret;
547 }
548
549 int 
550 dtls_decrypt(const unsigned char *src, size_t length,
551              unsigned char *buf,
552              unsigned char *nounce,
553              unsigned char *key, size_t keylen,
554              const unsigned char *aad, size_t la)
555 {
556   int ret;
557   struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
558
559   ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
560   if (ret < 0) {
561     /* cleanup everything in case the key has the wrong size */
562     dtls_warn("cannot set rijndael key\n");
563     goto error;
564   }
565
566   if (src != buf)
567     memmove(buf, src, length);
568   ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
569
570 error:
571   dtls_cipher_context_release();
572   return ret;
573 }
574