Remove unused pkg dependancy
[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 "aes/rijndael.h"
58 #include "sha2/sha2.h"
59 #include "prng.h"
60 #include "netq.h"
61 #include "hmac.h"
62
63 #if !defined(WITH_CONTIKI) && !defined(_WIN32)
64 #include <pthread.h>
65 #endif
66
67 #define HMAC_UPDATE_SEED(Context,Seed,Length)           \
68   if (Seed) dtls_hmac_update(Context, (Seed), (Length))
69
70 static struct dtls_cipher_context_t cipher_context;
71 #if !defined(WITH_CONTIKI) && !defined(_WIN32)
72 static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER;
73 #endif
74
75 static struct dtls_cipher_context_t *dtls_cipher_context_get(void)
76 {
77 #if !defined(WITH_CONTIKI) && !defined(_WIN32)
78   pthread_mutex_lock(&cipher_context_mutex);
79 #endif
80   return &cipher_context;
81 }
82
83 static void dtls_cipher_context_release(void)
84 {
85 #if !defined(WITH_CONTIKI) && !defined(_WIN32)
86   pthread_mutex_unlock(&cipher_context_mutex);
87 #endif
88 }
89
90 #ifndef WITH_CONTIKI
91 void crypto_init()
92 {
93 }
94
95 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
96   return malloc(sizeof(dtls_handshake_parameters_t));
97 }
98
99 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
100   free(handshake);
101 }
102
103 static dtls_security_parameters_t *dtls_security_malloc() {
104   return malloc(sizeof(dtls_security_parameters_t));
105 }
106
107 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
108   free(security);
109 }
110 #else /* WITH_CONTIKI */
111
112 #include "memb.h"
113 MEMB(handshake_storage, dtls_handshake_parameters_t, DTLS_HANDSHAKE_MAX);
114 MEMB(security_storage, dtls_security_parameters_t, DTLS_SECURITY_MAX);
115
116 void crypto_init() {
117   memb_init(&handshake_storage);
118   memb_init(&security_storage);
119 }
120
121 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
122   return memb_alloc(&handshake_storage);
123 }
124
125 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
126   memb_free(&handshake_storage, handshake);
127 }
128
129 static dtls_security_parameters_t *dtls_security_malloc() {
130   return memb_alloc(&security_storage);
131 }
132
133 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
134   memb_free(&security_storage, security);
135 }
136 #endif /* WITH_CONTIKI */
137
138 dtls_handshake_parameters_t *dtls_handshake_new()
139 {
140   dtls_handshake_parameters_t *handshake;
141
142   handshake = dtls_handshake_malloc();
143   if (!handshake) {
144     dtls_crit("can not allocate a handshake struct\n");
145     return NULL;
146   }
147
148   memset(handshake, 0, sizeof(*handshake));
149
150   if (handshake) {
151     /* initialize the handshake hash wrt. the hard-coded DTLS version */
152     dtls_debug("DTLSv12: initialize HASH_SHA256\n");
153     /* TLS 1.2:  PRF(secret, label, seed) = P_<hash>(secret, label + seed) */
154     /* FIXME: we use the default SHA256 here, might need to support other
155               hash functions as well */
156     dtls_hash_init(&handshake->hs_state.hs_hash);
157   }
158   return handshake;
159 }
160
161 void dtls_handshake_free(dtls_handshake_parameters_t *handshake)
162 {
163   if (!handshake)
164     return;
165
166   netq_delete_all(handshake->reorder_queue);
167   dtls_handshake_dealloc(handshake);
168 }
169
170 dtls_security_parameters_t *dtls_security_new()
171 {
172   dtls_security_parameters_t *security;
173
174   security = dtls_security_malloc();
175   if (!security) {
176     dtls_crit("can not allocate a security struct\n");
177     return NULL;
178   }
179
180   memset(security, 0, sizeof(*security));
181
182   if (security) {
183     security->cipher = TLS_NULL_WITH_NULL_NULL;
184     security->compression = TLS_COMPRESSION_NULL;
185   }
186   return security;
187 }
188
189 void dtls_security_free(dtls_security_parameters_t *security)
190 {
191   if (!security)
192     return;
193
194   dtls_security_dealloc(security);
195 }
196
197 size_t
198 dtls_p_hash(dtls_hashfunc_t h,
199             const unsigned char *key, size_t keylen,
200             const unsigned char *label, size_t labellen,
201             const unsigned char *random1, size_t random1len,
202             const unsigned char *random2, size_t random2len,
203             unsigned char *buf, size_t buflen) {
204   dtls_hmac_context_t *hmac_a, *hmac_p;
205
206   unsigned char A[DTLS_HMAC_DIGEST_SIZE];
207   unsigned char tmp[DTLS_HMAC_DIGEST_SIZE];
208   size_t dlen;                  /* digest length */
209   size_t len = 0;                       /* result length */
210
211   hmac_a = dtls_hmac_new(key, keylen);
212   if (!hmac_a)
213     return 0;
214
215   /* calculate A(1) from A(0) == seed */
216   HMAC_UPDATE_SEED(hmac_a, label, labellen);
217   HMAC_UPDATE_SEED(hmac_a, random1, random1len);
218   HMAC_UPDATE_SEED(hmac_a, random2, random2len);
219
220   dlen = dtls_hmac_finalize(hmac_a, A);
221
222   hmac_p = dtls_hmac_new(key, keylen);
223   if (!hmac_p)
224     goto error;
225
226   while (len + dlen < buflen) {
227
228     /* FIXME: rewrite loop to avoid superflous call to dtls_hmac_init() */
229     dtls_hmac_init(hmac_p, key, keylen);
230     dtls_hmac_update(hmac_p, A, dlen);
231
232     HMAC_UPDATE_SEED(hmac_p, label, labellen);
233     HMAC_UPDATE_SEED(hmac_p, random1, random1len);
234     HMAC_UPDATE_SEED(hmac_p, random2, random2len);
235
236     len += dtls_hmac_finalize(hmac_p, tmp);
237     memcpy(buf, tmp, dlen);
238     buf += dlen;
239
240     /* calculate A(i+1) */
241     dtls_hmac_init(hmac_a, key, keylen);
242     dtls_hmac_update(hmac_a, A, dlen);
243     dtls_hmac_finalize(hmac_a, A);
244   }
245
246   dtls_hmac_init(hmac_p, key, keylen);
247   dtls_hmac_update(hmac_p, A, dlen);
248
249   HMAC_UPDATE_SEED(hmac_p, label, labellen);
250   HMAC_UPDATE_SEED(hmac_p, random1, random1len);
251   HMAC_UPDATE_SEED(hmac_p, random2, random2len);
252
253   dtls_hmac_finalize(hmac_p, tmp);
254   memcpy(buf, tmp, buflen - len);
255
256  error:
257   dtls_hmac_free(hmac_a);
258   dtls_hmac_free(hmac_p);
259
260   return buflen;
261 }
262
263 size_t
264 dtls_prf(const unsigned char *key, size_t keylen,
265          const unsigned char *label, size_t labellen,
266          const unsigned char *random1, size_t random1len,
267          const unsigned char *random2, size_t random2len,
268          unsigned char *buf, size_t buflen) {
269
270   /* Clear the result buffer */
271   memset(buf, 0, buflen);
272   return dtls_p_hash(HASH_SHA256,
273                      key, keylen,
274                      label, labellen,
275                      random1, random1len,
276                      random2, random2len,
277                      buf, buflen);
278 }
279
280 void
281 dtls_mac(dtls_hmac_context_t *hmac_ctx,
282          const unsigned char *record,
283          const unsigned char *packet, size_t length,
284          unsigned char *buf) {
285   uint16 L;
286   dtls_int_to_uint16(L, length);
287
288   assert(hmac_ctx);
289   dtls_hmac_update(hmac_ctx, record +3, sizeof(uint16) + sizeof(uint48));
290   dtls_hmac_update(hmac_ctx, record, sizeof(uint8) + sizeof(uint16));
291   dtls_hmac_update(hmac_ctx, L, sizeof(uint16));
292   dtls_hmac_update(hmac_ctx, packet, length);
293
294   dtls_hmac_finalize(hmac_ctx, buf);
295 }
296
297 static size_t
298 dtls_ccm_encrypt(aes128_t *ccm_ctx, const unsigned char *src, size_t srclen,
299                  unsigned char *buf,
300                  unsigned char *nounce,
301                  const unsigned char *aad, size_t la) {
302   long int len;
303
304   assert(ccm_ctx);
305
306   len = dtls_ccm_encrypt_message(&ccm_ctx->ctx, 8 /* M */,
307                                  max(2, 15 - DTLS_CCM_NONCE_SIZE),
308                                  nounce,
309                                  buf, srclen,
310                                  aad, la);
311   return len;
312 }
313
314 static size_t
315 dtls_ccm_decrypt(aes128_t *ccm_ctx, const unsigned char *src,
316                  size_t srclen, unsigned char *buf,
317                  unsigned char *nounce,
318                  const unsigned char *aad, size_t la) {
319   long int len;
320
321   assert(ccm_ctx);
322
323   len = dtls_ccm_decrypt_message(&ccm_ctx->ctx, 8 /* M */,
324                                  max(2, 15 - DTLS_CCM_NONCE_SIZE),
325                                  nounce,
326                                  buf, srclen,
327                                  aad, la);
328   return len;
329 }
330
331 static size_t
332 dtls_cbc_encrypt(aes128_t *aes_ctx,
333                  unsigned char *mac_key, size_t mac_keylen,
334                  const unsigned char *iv,
335                  const unsigned char *src, size_t srclen,
336                  unsigned char *buf) {
337
338     unsigned char cbc[DTLS_BLK_LENGTH];
339     unsigned char tmp[DTLS_BLK_LENGTH];
340     unsigned char *pos;
341     const unsigned char *dtls_hdr = NULL;
342     int i, j;
343     int blocks;
344     dtls_hmac_context_t* hmac_ctx = NULL;
345     int paddinglen = 0;
346
347     pos = buf;
348
349     dtls_hdr = src - DTLS_CBC_IV_LENGTH - sizeof(dtls_record_header_t);
350
351     //Calculate MAC : Append the MAC code to end of content
352     hmac_ctx = dtls_hmac_new(mac_key, mac_keylen);
353     dtls_mac(hmac_ctx,
354              dtls_hdr,
355              src, srclen,
356              buf + srclen);
357     dtls_hmac_free(hmac_ctx);
358     
359     dtls_debug_dump("[MAC]",
360                     buf + srclen,
361                     DTLS_HMAC_DIGEST_SIZE);
362
363     paddinglen = DTLS_BLK_LENGTH - ((srclen + DTLS_HMAC_DIGEST_SIZE) % DTLS_BLK_LENGTH);
364     
365     //TLS padding
366     memset(buf + (srclen + DTLS_HMAC_DIGEST_SIZE), paddinglen - 1, paddinglen);
367
368     memcpy(cbc, iv, DTLS_BLK_LENGTH);
369     blocks = (srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen) / DTLS_BLK_LENGTH;
370
371     for (i = 0; i < blocks; i++) {
372         for (j = 0; j < DTLS_BLK_LENGTH; j++) {
373             cbc[j] ^= pos[j];
374         }
375
376         rijndael_encrypt(&aes_ctx->ctx, cbc, tmp);
377         memcpy(cbc, tmp, DTLS_BLK_LENGTH);
378         memcpy(pos, cbc, DTLS_BLK_LENGTH);
379         pos += DTLS_BLK_LENGTH;
380     }
381
382     dtls_debug_dump("[Encrypted Data]",
383                     buf,
384                     srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen);
385     
386     return srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen;
387 }
388
389
390 static size_t
391 dtls_cbc_decrypt(aes128_t *aes_ctx,
392                  unsigned char *mac_key, size_t mac_keylen,
393                  const unsigned char *iv,
394                  const unsigned char *src, size_t srclen,
395                  unsigned char *buf) {
396
397     unsigned char cbc[DTLS_BLK_LENGTH];
398     unsigned char tmp[DTLS_BLK_LENGTH];
399     unsigned char tmp2[DTLS_BLK_LENGTH];
400     unsigned char mac_buf[DTLS_HMAC_DIGEST_SIZE] = {0,};
401     const unsigned char *dtls_hdr = NULL;
402     unsigned char *pos;
403     int i, j;
404     int blocks;
405     int depaddinglen = 0;
406     uint8_t wrongpadding_flag = 0;
407     dtls_hmac_context_t* hmac_ctx = NULL;
408
409     pos = buf;
410
411     dtls_hdr = src - DTLS_CBC_IV_LENGTH - sizeof(dtls_record_header_t);
412
413     memcpy(cbc, iv, DTLS_BLK_LENGTH);
414     blocks = srclen / DTLS_BLK_LENGTH;
415
416     for (i = 0; i < blocks; i++)
417     {
418         memcpy(tmp, pos, DTLS_BLK_LENGTH);
419         rijndael_decrypt(&aes_ctx->ctx, pos, tmp2);
420         memcpy(pos, tmp2, DTLS_BLK_LENGTH);
421
422         for (j = 0; j < DTLS_BLK_LENGTH; j++) {
423             pos[j] ^= cbc[j];
424         }
425
426         memcpy(cbc, tmp, DTLS_BLK_LENGTH);
427         pos += DTLS_BLK_LENGTH;
428     }
429
430     //de-padding
431     depaddinglen = buf[srclen -1];
432
433     /**
434      * message validation check in case of wrong key.
435      * In case of wrong padding legnth was detected
436      * set depadding length to zero in order to resist the padding oracle attack
437      * and prevent invalid memory access.
438      */
439     if(srclen <= DTLS_HMAC_DIGEST_SIZE + depaddinglen + 1) {
440         depaddinglen = 0;
441         wrongpadding_flag = 1;
442     }
443
444     //Calculate MAC
445     hmac_ctx = dtls_hmac_new(mac_key, mac_keylen);
446     if(!hmac_ctx) {
447         return -1;
448     }
449     dtls_mac(hmac_ctx, dtls_hdr, buf,
450              srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1,
451              mac_buf);
452     dtls_hmac_free(hmac_ctx);
453
454     dtls_debug_dump("[MAC]",
455                     mac_buf,
456                     DTLS_HMAC_DIGEST_SIZE);
457     dtls_debug_dump("[Decrypted data]",
458                     buf,
459                     srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1);
460
461     //verify the MAC
462     if(memcmp(mac_buf,
463               buf + (srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1),
464               DTLS_HMAC_DIGEST_SIZE) != 0 || wrongpadding_flag)
465     {
466         dtls_crit("Failed to verification of MAC\n");
467         return -1;
468     }
469
470     //verify the padding bytes
471     for (i =0; i < depaddinglen; i++)
472     {
473         if (buf[srclen - depaddinglen - 1 + i] != depaddinglen)
474         {
475             dtls_crit("Failed to verify padding bytes\n");
476             return -1;
477         }
478     }
479
480     return srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1;
481 }
482
483 #ifdef DTLS_PSK
484 int
485 dtls_psk_pre_master_secret(unsigned char *key, size_t keylen,
486                            unsigned char *result, size_t result_len) {
487   unsigned char *p = result;
488
489   if (result_len < (2 * (sizeof(uint16) + keylen))) {
490     return -1;
491   }
492
493   dtls_int_to_uint16(p, keylen);
494   p += sizeof(uint16);
495
496   memset(p, 0, keylen);
497   p += keylen;
498
499   memcpy(p, result, sizeof(uint16));
500   p += sizeof(uint16);
501
502   memcpy(p, key, keylen);
503
504   return 2 * (sizeof(uint16) + keylen);
505 }
506 #endif /* DTLS_PSK */
507
508 #if defined(DTLS_ECC) || defined(DTLS_X509)
509
510 int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size,
511                                  unsigned char *buf) {
512   int i;
513   unsigned char *buf_orig = buf;
514   int first = 1;
515
516   for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
517     if (key[i] == 0)
518       continue;
519     /* the first bit has to be set to zero, to indicate a poritive integer */
520     if (first && key[i] & 0x80000000) {
521       *buf = 0;
522       buf++;
523       dtls_int_to_uint32(buf, key[i]);
524       buf += 4;
525     } else if (first && !(key[i] & 0xFF800000)) {
526       buf[0] = (key[i] >> 16) & 0xff;
527       buf[1] = (key[i] >> 8) & 0xff;
528       buf[2] = key[i] & 0xff;
529       buf += 3;
530     } else if (first && !(key[i] & 0xFFFF8000)) {
531       buf[0] = (key[i] >> 8) & 0xff;
532       buf[1] = key[i] & 0xff;
533       buf += 2;
534     } else if (first && !(key[i] & 0xFFFFFF80)) {
535       buf[0] = key[i] & 0xff;
536       buf += 1;
537     } else {
538       dtls_int_to_uint32(buf, key[i]);
539       buf += 4;
540     }
541     first = 0;
542   }
543   return buf - buf_orig;
544 }
545
546 int dtls_ecdh_pre_master_secret(unsigned char *priv_key,
547                                    unsigned char *pub_key_x,
548                                    unsigned char *pub_key_y,
549                                    size_t key_size,
550                                    unsigned char *result,
551                                    size_t result_len) {
552
553   uint8_t publicKey[64];
554   uint8_t privateKey[32];
555
556   if (result_len < key_size) {
557     return -1;
558   }
559
560
561   memcpy(publicKey, pub_key_x, 32);
562   memcpy(publicKey + 32, pub_key_y, 32);
563   memcpy(privateKey, priv_key, 32);
564   uECC_shared_secret(publicKey, privateKey, result);
565
566   return key_size;
567 }
568
569 void
570 dtls_ecdsa_generate_key(unsigned char *priv_key,
571                         unsigned char *pub_key_x,
572                         unsigned char *pub_key_y,
573                         size_t key_size) {
574
575   uint8_t publicKey[64];
576   uint8_t privateKey[32];
577
578   uECC_make_key(publicKey, privateKey);
579   memcpy(pub_key_x, publicKey, 32);
580   memcpy(pub_key_y, publicKey + 32, 32);
581   memcpy(priv_key, privateKey, 32);
582
583 }
584
585 /* rfc4492#section-5.4 */
586 void
587 dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size,
588                            const unsigned char *sign_hash, size_t sign_hash_size,
589                            uint32_t point_r[9], uint32_t point_s[9])
590 {
591     uint8_t sign[64];
592
593     // Check the buffers
594     if (priv_key == NULL || key_size < 32)
595         return;
596     if (sign_hash == NULL || sign_hash_size < 32)
597         return;
598
599     uECC_sign(priv_key, sign_hash, sign);
600
601     int i;
602     for (i = 0; i < 32; i++)
603     {
604         ((uint8_t *) point_r)[i] = sign[31 - i];
605         ((uint8_t *) point_s)[i] = sign[63 - i];
606     }
607 }
608
609 void
610 dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size,
611                       const unsigned char *client_random, size_t client_random_size,
612                       const unsigned char *server_random, size_t server_random_size,
613                       const unsigned char *keyx_params, size_t keyx_params_size,
614                       uint32_t point_r[9], uint32_t point_s[9]) {
615   dtls_hash_ctx data;
616   unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
617
618   dtls_hash_init(&data);
619   dtls_hash_update(&data, client_random, client_random_size);
620   dtls_hash_update(&data, server_random, server_random_size);
621   dtls_hash_update(&data, keyx_params, keyx_params_size);
622   dtls_hash_finalize(sha256hash, &data);
623
624   dtls_ecdsa_create_sig_hash(priv_key, key_size, sha256hash,
625                              sizeof(sha256hash), point_r, point_s);
626 }
627
628 /* rfc4492#section-5.4 */
629 int
630 dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x,
631                            const unsigned char *pub_key_y, size_t key_size,
632                            const unsigned char *sign_hash, size_t sign_hash_size,
633                            unsigned char *result_r, unsigned char *result_s)
634 {
635     uint8_t publicKey[64];
636     uint8_t sign[64];
637
638     // Check the buffers
639     if (pub_key_x == NULL || pub_key_y == NULL || key_size < 32)
640         return 0;
641     if (sign_hash == NULL || sign_hash_size < 32)
642         return 0;
643     if (result_r == NULL || result_s == NULL)
644         return 0;
645
646     // Copy the public key into a single buffer
647     memcpy(publicKey, pub_key_x, 32);
648     memcpy(publicKey + 32, pub_key_y, 32);
649
650     // Copy the signature into a single buffer
651     memcpy(sign, result_r, 32);
652     memcpy(sign + 32, result_s, 32);
653
654     return uECC_verify(publicKey, sign_hash, sign);
655 }
656
657 int
658 dtls_ecdsa_verify_sig(const unsigned char *pub_key_x,
659                       const unsigned char *pub_key_y, size_t key_size,
660                       const unsigned char *client_random, size_t client_random_size,
661                       const unsigned char *server_random, size_t server_random_size,
662                       const unsigned char *keyx_params, size_t keyx_params_size,
663                       unsigned char *result_r, unsigned char *result_s) {
664   dtls_hash_ctx data;
665   unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
666
667   dtls_hash_init(&data);
668   dtls_hash_update(&data, client_random, client_random_size);
669   dtls_hash_update(&data, server_random, server_random_size);
670   dtls_hash_update(&data, keyx_params, keyx_params_size);
671   dtls_hash_finalize(sha256hash, &data);
672
673   return dtls_ecdsa_verify_sig_hash(pub_key_x, pub_key_y, key_size, sha256hash,
674                                     sizeof(sha256hash), result_r, result_s);
675 }
676 #endif /* DTLS_ECC */
677
678 #if defined(DTLS_PSK) && defined(DTLS_ECC)
679 int dtls_ecdhe_psk_pre_master_secret(unsigned char *psk, size_t psklen,
680                                      unsigned char *ecc_priv_key,
681                                      unsigned char *ecc_pub_key_x,
682                                      unsigned char *ecc_pub_key_y,
683                                      size_t ecc_key_size,
684                                      unsigned char *result,
685                                      size_t result_len)
686 {
687   uint8_t eccPublicKey[64];
688   uint8_t eccPrivateKey[32];
689   unsigned char *p = result;
690
691   if (result_len < uECC_BYTES + psklen + (sizeof(uint16) * 2)) {
692     return -1;
693   }
694
695   dtls_int_to_uint16(p, uECC_BYTES);
696   p += sizeof(uint16);
697
698   memcpy(eccPublicKey, ecc_pub_key_x, 32);
699   memcpy(eccPublicKey + 32, ecc_pub_key_y, 32);
700   memcpy(eccPrivateKey, ecc_priv_key, 32);
701   uECC_shared_secret(eccPublicKey, eccPrivateKey, p);
702   p += uECC_BYTES;
703
704   dtls_int_to_uint16(p, psklen);
705   p += sizeof(uint16);
706
707   memcpy(p, psk, psklen);
708
709   return uECC_BYTES + psklen + (sizeof(uint16) * 2);
710 }
711 #endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
712
713 int
714 dtls_encrypt(const unsigned char *src, size_t length,
715              unsigned char *buf,
716              unsigned char *nounce,
717              unsigned char *write_key, size_t write_keylen,
718              unsigned char *mac_key, size_t mac_keylen,
719              const unsigned char *aad, size_t la,
720              const dtls_cipher_t cipher)
721 {
722   int ret = 0;
723   struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
724
725   if(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
726      cipher == TLS_PSK_WITH_AES_128_CCM_8) {
727       ret = rijndael_set_key_enc_only(&ctx->data.ctx, write_key, 8 * write_keylen);
728       if (ret < 0) {
729         /* cleanup everything in case the key has the wrong size */
730         dtls_warn("cannot set rijndael key\n");
731         goto error;
732       }
733
734       if (src != buf)
735         memmove(buf, src, length);
736       ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
737   }
738   if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
739      cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
740       ret = rijndael_set_key(&ctx->data.ctx, write_key, 8 * write_keylen);
741       if (ret < 0) {
742         /* cleanup everything in case the key has the wrong size */
743         dtls_warn("cannot set rijndael key\n");
744         goto error;
745       }
746
747       if (src != buf)
748         memmove(buf, src, length);
749       ret = dtls_cbc_encrypt(&ctx->data, mac_key, mac_keylen, nounce, src, length, buf);
750   }
751
752 error:
753   dtls_cipher_context_release();
754   return ret;
755 }
756
757 int
758 dtls_decrypt(const unsigned char *src, size_t length,
759              unsigned char *buf,
760              unsigned char *nounce,
761              unsigned char *read_key, size_t read_keylen,
762              unsigned char *mac_key, size_t mac_keylen,
763              const unsigned char *aad, size_t la,
764              const dtls_cipher_t cipher)
765 {
766   int ret = 0;
767   struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
768
769   if(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
770      cipher == TLS_PSK_WITH_AES_128_CCM_8) {
771       ret = rijndael_set_key_enc_only(&ctx->data.ctx, read_key, 8 * read_keylen);
772       if (ret < 0) {
773         /* cleanup everything in case the key has the wrong size */
774         dtls_warn("cannot set rijndael key\n");
775         goto error;
776       }
777
778       if (src != buf)
779         memmove(buf, src, length);
780       ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
781   }
782
783   if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
784      cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
785       ret = rijndael_set_key(&ctx->data.ctx, read_key, 8 * read_keylen);
786       if (ret < 0) {
787         /* cleanup everything in case the key has the wrong size */
788         dtls_warn("cannot set rijndael key\n");
789         goto error;
790       }
791
792       if (src != buf)
793         memmove(buf, src, length);
794       ret = dtls_cbc_decrypt(&ctx->data, mac_key, mac_keylen, nounce, src, length, buf);
795     }
796
797 error:
798   dtls_cipher_context_release();
799   return ret;
800 }
801