1 /* dtls -- a very basic DTLS implementation
3 * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
4 * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
7 * Modified source code for micro-ecc porting,
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
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:
26 * The above copyright notice and this permission notice shall be
27 * included in all copies or substantial portions of the Software.
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
42 #include "dtls_config.h"
57 #include "aes/rijndael.h"
58 #include "sha2/sha2.h"
66 #define HMAC_UPDATE_SEED(Context,Seed,Length) \
67 if (Seed) dtls_hmac_update(Context, (Seed), (Length))
69 static struct dtls_cipher_context_t cipher_context;
71 static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER;
74 static struct dtls_cipher_context_t *dtls_cipher_context_get(void)
77 pthread_mutex_lock(&cipher_context_mutex);
79 return &cipher_context;
82 static void dtls_cipher_context_release(void)
85 pthread_mutex_unlock(&cipher_context_mutex);
94 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
95 return malloc(sizeof(dtls_handshake_parameters_t));
98 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
102 static dtls_security_parameters_t *dtls_security_malloc() {
103 return malloc(sizeof(dtls_security_parameters_t));
106 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
109 #else /* WITH_CONTIKI */
112 MEMB(handshake_storage, dtls_handshake_parameters_t, DTLS_HANDSHAKE_MAX);
113 MEMB(security_storage, dtls_security_parameters_t, DTLS_SECURITY_MAX);
116 memb_init(&handshake_storage);
117 memb_init(&security_storage);
120 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
121 return memb_alloc(&handshake_storage);
124 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
125 memb_free(&handshake_storage, handshake);
128 static dtls_security_parameters_t *dtls_security_malloc() {
129 return memb_alloc(&security_storage);
132 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
133 memb_free(&security_storage, security);
135 #endif /* WITH_CONTIKI */
137 dtls_handshake_parameters_t *dtls_handshake_new()
139 dtls_handshake_parameters_t *handshake;
141 handshake = dtls_handshake_malloc();
143 dtls_crit("can not allocate a handshake struct\n");
147 memset(handshake, 0, sizeof(*handshake));
150 /* initialize the handshake hash wrt. the hard-coded DTLS version */
151 dtls_debug("DTLSv12: initialize HASH_SHA256\n");
152 /* TLS 1.2: PRF(secret, label, seed) = P_<hash>(secret, label + seed) */
153 /* FIXME: we use the default SHA256 here, might need to support other
154 hash functions as well */
155 dtls_hash_init(&handshake->hs_state.hs_hash);
160 void dtls_handshake_free(dtls_handshake_parameters_t *handshake)
165 netq_delete_all(handshake->reorder_queue);
166 dtls_handshake_dealloc(handshake);
169 dtls_security_parameters_t *dtls_security_new()
171 dtls_security_parameters_t *security;
173 security = dtls_security_malloc();
175 dtls_crit("can not allocate a security struct\n");
179 memset(security, 0, sizeof(*security));
182 security->cipher = TLS_NULL_WITH_NULL_NULL;
183 security->compression = TLS_COMPRESSION_NULL;
188 void dtls_security_free(dtls_security_parameters_t *security)
193 dtls_security_dealloc(security);
197 dtls_p_hash(dtls_hashfunc_t h,
198 const unsigned char *key, size_t keylen,
199 const unsigned char *label, size_t labellen,
200 const unsigned char *random1, size_t random1len,
201 const unsigned char *random2, size_t random2len,
202 unsigned char *buf, size_t buflen) {
203 dtls_hmac_context_t *hmac_a, *hmac_p;
205 unsigned char A[DTLS_HMAC_DIGEST_SIZE];
206 unsigned char tmp[DTLS_HMAC_DIGEST_SIZE];
207 size_t dlen; /* digest length */
208 size_t len = 0; /* result length */
210 hmac_a = dtls_hmac_new(key, keylen);
214 /* calculate A(1) from A(0) == seed */
215 HMAC_UPDATE_SEED(hmac_a, label, labellen);
216 HMAC_UPDATE_SEED(hmac_a, random1, random1len);
217 HMAC_UPDATE_SEED(hmac_a, random2, random2len);
219 dlen = dtls_hmac_finalize(hmac_a, A);
221 hmac_p = dtls_hmac_new(key, keylen);
225 while (len + dlen < buflen) {
227 /* FIXME: rewrite loop to avoid superflous call to dtls_hmac_init() */
228 dtls_hmac_init(hmac_p, key, keylen);
229 dtls_hmac_update(hmac_p, A, dlen);
231 HMAC_UPDATE_SEED(hmac_p, label, labellen);
232 HMAC_UPDATE_SEED(hmac_p, random1, random1len);
233 HMAC_UPDATE_SEED(hmac_p, random2, random2len);
235 len += dtls_hmac_finalize(hmac_p, tmp);
236 memcpy(buf, tmp, dlen);
239 /* calculate A(i+1) */
240 dtls_hmac_init(hmac_a, key, keylen);
241 dtls_hmac_update(hmac_a, A, dlen);
242 dtls_hmac_finalize(hmac_a, A);
245 dtls_hmac_init(hmac_p, key, keylen);
246 dtls_hmac_update(hmac_p, A, dlen);
248 HMAC_UPDATE_SEED(hmac_p, label, labellen);
249 HMAC_UPDATE_SEED(hmac_p, random1, random1len);
250 HMAC_UPDATE_SEED(hmac_p, random2, random2len);
252 dtls_hmac_finalize(hmac_p, tmp);
253 memcpy(buf, tmp, buflen - len);
256 dtls_hmac_free(hmac_a);
257 dtls_hmac_free(hmac_p);
263 dtls_prf(const unsigned char *key, size_t keylen,
264 const unsigned char *label, size_t labellen,
265 const unsigned char *random1, size_t random1len,
266 const unsigned char *random2, size_t random2len,
267 unsigned char *buf, size_t buflen) {
269 /* Clear the result buffer */
270 memset(buf, 0, buflen);
271 return dtls_p_hash(HASH_SHA256,
280 dtls_mac(dtls_hmac_context_t *hmac_ctx,
281 const unsigned char *record,
282 const unsigned char *packet, size_t length,
283 unsigned char *buf) {
285 dtls_int_to_uint16(L, length);
288 dtls_hmac_update(hmac_ctx, record +3, sizeof(uint16) + sizeof(uint48));
289 dtls_hmac_update(hmac_ctx, record, sizeof(uint8) + sizeof(uint16));
290 dtls_hmac_update(hmac_ctx, L, sizeof(uint16));
291 dtls_hmac_update(hmac_ctx, packet, length);
293 dtls_hmac_finalize(hmac_ctx, buf);
297 dtls_ccm_encrypt(aes128_t *ccm_ctx, const unsigned char *src, size_t srclen,
299 unsigned char *nounce,
300 const unsigned char *aad, size_t la) {
305 len = dtls_ccm_encrypt_message(&ccm_ctx->ctx, 8 /* M */,
306 max(2, 15 - DTLS_CCM_NONCE_SIZE),
314 dtls_ccm_decrypt(aes128_t *ccm_ctx, const unsigned char *src,
315 size_t srclen, unsigned char *buf,
316 unsigned char *nounce,
317 const unsigned char *aad, size_t la) {
322 len = dtls_ccm_decrypt_message(&ccm_ctx->ctx, 8 /* M */,
323 max(2, 15 - DTLS_CCM_NONCE_SIZE),
331 dtls_cbc_encrypt(aes128_t *aes_ctx,
332 const unsigned char *iv,
333 const unsigned char *src, size_t srclen,
334 unsigned char *buf) {
336 unsigned char cbc[DTLS_BLK_LENGTH];
337 unsigned char tmp[DTLS_BLK_LENGTH];
339 dtls_hash_ctx shactx;
345 dtls_hash_init(&shactx);
346 dtls_hash_update(&shactx, src, srclen);
347 dtls_hash_finalize(pos + srclen, &shactx);
349 memcpy(cbc, iv, DTLS_BLK_LENGTH);
350 blocks = (srclen + SHA256_DIGEST_LENGTH) / DTLS_BLK_LENGTH;
352 for (i = 0; i < blocks; i++) {
353 for (j = 0; j < DTLS_BLK_LENGTH; j++) {
357 rijndael_encrypt(&aes_ctx->ctx, cbc, tmp);
358 memcpy(cbc, tmp, DTLS_BLK_LENGTH);
359 memcpy(pos, cbc, DTLS_BLK_LENGTH);
360 pos += DTLS_BLK_LENGTH;
363 dtls_debug_dump("Encrypted Data:", buf, srclen + SHA256_DIGEST_LENGTH);
365 return srclen + SHA256_DIGEST_LENGTH;
370 dtls_cbc_decrypt(aes128_t *aes_ctx,
371 const unsigned char *iv,
372 const unsigned char *src, size_t srclen,
373 unsigned char *buf) {
375 unsigned char cbc[DTLS_BLK_LENGTH];
376 unsigned char tmp[DTLS_BLK_LENGTH];
377 unsigned char tmp2[DTLS_BLK_LENGTH];
378 unsigned char msg_hash[SHA256_DIGEST_LENGTH];
380 dtls_hash_ctx shactx;
385 memcpy(pos, src, srclen);
387 memcpy(cbc, iv, DTLS_BLK_LENGTH);
388 blocks = srclen / DTLS_BLK_LENGTH;
390 for (i = 0; i < blocks; i++)
392 memcpy(tmp, pos, DTLS_BLK_LENGTH);
393 rijndael_decrypt(&aes_ctx->ctx, pos, tmp2);
394 memcpy(pos, tmp2, DTLS_BLK_LENGTH);
396 for (j = 0; j < DTLS_BLK_LENGTH; j++) {
400 memcpy(cbc, tmp, DTLS_BLK_LENGTH);
401 pos += DTLS_BLK_LENGTH;
404 dtls_hash_init(&shactx);
405 dtls_hash_update(&shactx, buf, srclen - SHA256_DIGEST_LENGTH);
406 dtls_hash_finalize(msg_hash, &shactx);
408 dtls_debug_dump("decrypted data:", buf, srclen);
410 if(memcmp(msg_hash, buf + (srclen - SHA256_DIGEST_LENGTH), SHA256_DIGEST_LENGTH) != 0)
412 dtls_warn("message is broken\n");
416 return srclen - SHA256_DIGEST_LENGTH;
421 dtls_psk_pre_master_secret(unsigned char *key, size_t keylen,
422 unsigned char *result, size_t result_len) {
423 unsigned char *p = result;
425 if (result_len < (2 * (sizeof(uint16) + keylen))) {
429 dtls_int_to_uint16(p, keylen);
432 memset(p, 0, keylen);
435 memcpy(p, result, sizeof(uint16));
438 memcpy(p, key, keylen);
440 return 2 * (sizeof(uint16) + keylen);
442 #endif /* DTLS_PSK */
446 int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size,
447 unsigned char *buf) {
449 unsigned char *buf_orig = buf;
452 for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
455 /* the first bit has to be set to zero, to indicate a poritive integer */
456 if (first && key[i] & 0x80000000) {
459 dtls_int_to_uint32(buf, key[i]);
461 } else if (first && !(key[i] & 0xFF800000)) {
462 buf[0] = (key[i] >> 16) & 0xff;
463 buf[1] = (key[i] >> 8) & 0xff;
464 buf[2] = key[i] & 0xff;
466 } else if (first && !(key[i] & 0xFFFF8000)) {
467 buf[0] = (key[i] >> 8) & 0xff;
468 buf[1] = key[i] & 0xff;
470 } else if (first && !(key[i] & 0xFFFFFF80)) {
471 buf[0] = key[i] & 0xff;
474 dtls_int_to_uint32(buf, key[i]);
479 return buf - buf_orig;
482 int dtls_ecdh_pre_master_secret(unsigned char *priv_key,
483 unsigned char *pub_key_x,
484 unsigned char *pub_key_y,
486 unsigned char *result,
489 uint8_t publicKey[64];
490 uint8_t privateKey[32];
492 if (result_len < key_size) {
497 memcpy(publicKey, pub_key_x, 32);
498 memcpy(publicKey + 32, pub_key_y, 32);
499 memcpy(privateKey, priv_key, 32);
500 uECC_shared_secret(publicKey, privateKey, result);
506 dtls_ecdsa_generate_key(unsigned char *priv_key,
507 unsigned char *pub_key_x,
508 unsigned char *pub_key_y,
511 uint8_t publicKey[64];
512 uint8_t privateKey[32];
514 uECC_make_key(publicKey, privateKey);
515 memcpy(pub_key_x, publicKey, 32);
516 memcpy(pub_key_y, publicKey + 32, 32);
517 memcpy(priv_key, privateKey, 32);
521 /* rfc4492#section-5.4 */
523 dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size,
524 const unsigned char *sign_hash, size_t sign_hash_size,
525 uint32_t point_r[9], uint32_t point_s[9]) {
528 uint8_t privateKey[32];
529 uint8_t hashValue[32];
533 uECC_sign(privateKey, hashValue, sign);
534 memcpy(point_r, sign, 32);
535 memcpy(point_s, sign + 32, 32);
539 dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size,
540 const unsigned char *client_random, size_t client_random_size,
541 const unsigned char *server_random, size_t server_random_size,
542 const unsigned char *keyx_params, size_t keyx_params_size,
543 uint32_t point_r[9], uint32_t point_s[9]) {
545 unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
547 dtls_hash_init(&data);
548 dtls_hash_update(&data, client_random, client_random_size);
549 dtls_hash_update(&data, server_random, server_random_size);
550 dtls_hash_update(&data, keyx_params, keyx_params_size);
551 dtls_hash_finalize(sha256hash, &data);
553 dtls_ecdsa_create_sig_hash(priv_key, key_size, sha256hash,
554 sizeof(sha256hash), point_r, point_s);
557 /* rfc4492#section-5.4 */
559 dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x,
560 const unsigned char *pub_key_y, size_t key_size,
561 const unsigned char *sign_hash, size_t sign_hash_size,
562 unsigned char *result_r, unsigned char *result_s) {
564 uint8_t publicKey[64];
565 uint8_t hashValue[32];
568 memcpy(publicKey, pub_key_x, 32);
569 memcpy(publicKey + 32, pub_key_y, 32);
570 return uECC_verify(publicKey, hashValue, sign);
574 dtls_ecdsa_verify_sig(const unsigned char *pub_key_x,
575 const unsigned char *pub_key_y, size_t key_size,
576 const unsigned char *client_random, size_t client_random_size,
577 const unsigned char *server_random, size_t server_random_size,
578 const unsigned char *keyx_params, size_t keyx_params_size,
579 unsigned char *result_r, unsigned char *result_s) {
581 unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
583 dtls_hash_init(&data);
584 dtls_hash_update(&data, client_random, client_random_size);
585 dtls_hash_update(&data, server_random, server_random_size);
586 dtls_hash_update(&data, keyx_params, keyx_params_size);
587 dtls_hash_finalize(sha256hash, &data);
589 return dtls_ecdsa_verify_sig_hash(pub_key_x, pub_key_y, key_size, sha256hash,
590 sizeof(sha256hash), result_r, result_s);
592 #endif /* DTLS_ECC */
595 dtls_encrypt(const unsigned char *src, size_t length,
597 unsigned char *nounce,
598 unsigned char *key, size_t keylen,
599 const unsigned char *aad, size_t la,
600 const dtls_cipher_t cipher)
603 struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
605 if(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
606 cipher == TLS_PSK_WITH_AES_128_CCM_8) {
607 ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
609 /* cleanup everything in case the key has the wrong size */
610 dtls_warn("cannot set rijndael key\n");
615 memmove(buf, src, length);
616 ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
618 if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA) {
619 ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
621 /* cleanup everything in case the key has the wrong size */
622 dtls_warn("cannot set rijndael key\n");
627 memmove(buf, src, length);
628 ret = dtls_cbc_encrypt(&ctx->data, nounce, src, length, buf);
632 dtls_cipher_context_release();
637 dtls_decrypt(const unsigned char *src, size_t length,
639 unsigned char *nounce,
640 unsigned char *key, size_t keylen,
641 const unsigned char *aad, size_t la,
642 const dtls_cipher_t cipher)
645 struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
647 if(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
648 cipher == TLS_PSK_WITH_AES_128_CCM_8) {
649 ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
651 /* cleanup everything in case the key has the wrong size */
652 dtls_warn("cannot set rijndael key\n");
657 memmove(buf, src, length);
658 ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
661 if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA) {
662 ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
664 /* cleanup everything in case the key has the wrong size */
665 dtls_warn("cannot set rijndael key\n");
670 memmove(buf, src, length);
671 ret = dtls_cbc_decrypt(&ctx->data, nounce, src, length, buf);
675 dtls_cipher_context_release();