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