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>
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:
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
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
30 #include "dtls_config.h"
52 #define HMAC_UPDATE_SEED(Context,Seed,Length) \
53 if (Seed) dtls_hmac_update(Context, (Seed), (Length))
55 static struct dtls_cipher_context_t cipher_context;
57 static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER;
60 static struct dtls_cipher_context_t *dtls_cipher_context_get(void)
63 pthread_mutex_lock(&cipher_context_mutex);
65 return &cipher_context;
68 static void dtls_cipher_context_release(void)
71 pthread_mutex_unlock(&cipher_context_mutex);
80 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
81 return malloc(sizeof(dtls_handshake_parameters_t));
84 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
88 static dtls_security_parameters_t *dtls_security_malloc() {
89 return malloc(sizeof(dtls_security_parameters_t));
92 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
95 #else /* WITH_CONTIKI */
98 MEMB(handshake_storage, dtls_handshake_parameters_t, DTLS_HANDSHAKE_MAX);
99 MEMB(security_storage, dtls_security_parameters_t, DTLS_SECURITY_MAX);
102 memb_init(&handshake_storage);
103 memb_init(&security_storage);
106 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
107 return memb_alloc(&handshake_storage);
110 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
111 memb_free(&handshake_storage, handshake);
114 static dtls_security_parameters_t *dtls_security_malloc() {
115 return memb_alloc(&security_storage);
118 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
119 memb_free(&security_storage, security);
121 #endif /* WITH_CONTIKI */
123 dtls_handshake_parameters_t *dtls_handshake_new()
125 dtls_handshake_parameters_t *handshake;
127 handshake = dtls_handshake_malloc();
129 dtls_crit("can not allocate a handshake struct\n");
133 memset(handshake, 0, sizeof(*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);
146 void dtls_handshake_free(dtls_handshake_parameters_t *handshake)
151 netq_delete_all(handshake->reorder_queue);
152 dtls_handshake_dealloc(handshake);
155 dtls_security_parameters_t *dtls_security_new()
157 dtls_security_parameters_t *security;
159 security = dtls_security_malloc();
161 dtls_crit("can not allocate a security struct\n");
165 memset(security, 0, sizeof(*security));
168 security->cipher = TLS_NULL_WITH_NULL_NULL;
169 security->compression = TLS_COMPRESSION_NULL;
174 void dtls_security_free(dtls_security_parameters_t *security)
179 dtls_security_dealloc(security);
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;
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 */
196 hmac_a = dtls_hmac_new(key, keylen);
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);
205 dlen = dtls_hmac_finalize(hmac_a, A);
207 hmac_p = dtls_hmac_new(key, keylen);
211 while (len + dlen < buflen) {
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);
217 HMAC_UPDATE_SEED(hmac_p, label, labellen);
218 HMAC_UPDATE_SEED(hmac_p, random1, random1len);
219 HMAC_UPDATE_SEED(hmac_p, random2, random2len);
221 len += dtls_hmac_finalize(hmac_p, tmp);
222 memcpy(buf, tmp, dlen);
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);
231 dtls_hmac_init(hmac_p, key, keylen);
232 dtls_hmac_update(hmac_p, A, dlen);
234 HMAC_UPDATE_SEED(hmac_p, label, labellen);
235 HMAC_UPDATE_SEED(hmac_p, random1, random1len);
236 HMAC_UPDATE_SEED(hmac_p, random2, random2len);
238 dtls_hmac_finalize(hmac_p, tmp);
239 memcpy(buf, tmp, buflen - len);
242 dtls_hmac_free(hmac_a);
243 dtls_hmac_free(hmac_p);
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) {
255 /* Clear the result buffer */
256 memset(buf, 0, buflen);
257 return dtls_p_hash(HASH_SHA256,
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) {
271 dtls_int_to_uint16(L, length);
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);
279 dtls_hmac_finalize(hmac_ctx, buf);
283 dtls_ccm_encrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, size_t srclen,
285 unsigned char *nounce,
286 const unsigned char *aad, size_t la) {
291 len = dtls_ccm_encrypt_message(&ccm_ctx->ctx, 8 /* M */,
292 max(2, 15 - DTLS_CCM_NONCE_SIZE),
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) {
308 len = dtls_ccm_decrypt_message(&ccm_ctx->ctx, 8 /* M */,
309 max(2, 15 - DTLS_CCM_NONCE_SIZE),
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;
322 if (result_len < (2 * (sizeof(uint16) + keylen))) {
326 dtls_int_to_uint16(p, keylen);
329 memset(p, 0, keylen);
332 memcpy(p, result, sizeof(uint16));
335 memcpy(p, key, keylen);
337 return 2 * (sizeof(uint16) + keylen);
339 #endif /* DTLS_PSK */
342 static void dtls_ec_key_to_uint32(const unsigned char *key, size_t key_size,
346 for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
347 *result = dtls_uint32_to_int(&key[i * sizeof(uint32_t)]);
352 static void dtls_ec_key_from_uint32(const uint32_t *key, size_t key_size,
353 unsigned char *result) {
356 for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
357 dtls_int_to_uint32(result, key[i]);
362 int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size,
363 unsigned char *buf) {
365 unsigned char *buf_orig = buf;
368 for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
371 /* the first bit has to be set to zero, to indicate a poritive integer */
372 if (first && key[i] & 0x80000000) {
375 dtls_int_to_uint32(buf, key[i]);
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;
382 } else if (first && !(key[i] & 0xFFFF8000)) {
383 buf[0] = (key[i] >> 8) & 0xff;
384 buf[1] = key[i] & 0xff;
386 } else if (first && !(key[i] & 0xFFFFFF80)) {
387 buf[0] = key[i] & 0xff;
390 dtls_int_to_uint32(buf, key[i]);
395 return buf - buf_orig;
398 int dtls_ecdh_pre_master_secret(unsigned char *priv_key,
399 unsigned char *pub_key_x,
400 unsigned char *pub_key_y,
402 unsigned char *result,
407 uint32_t result_x[8];
408 uint32_t result_y[8];
410 if (result_len < key_size) {
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);
418 ecc_ecdh(pub_x, pub_y, priv, result_x, result_y);
420 dtls_ec_key_from_uint32(result_x, key_size, result);
425 dtls_ecdsa_generate_key(unsigned char *priv_key,
426 unsigned char *pub_key_x,
427 unsigned char *pub_key_y,
434 dtls_prng((unsigned char *)priv, key_size);
435 } while (!ecc_is_valid_key(priv));
437 ecc_gen_pub_key(priv, pub_x, pub_y);
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);
444 /* rfc4492#section-5.4 */
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]) {
454 dtls_ec_key_to_uint32(priv_key, key_size, priv);
455 dtls_ec_key_to_uint32(sign_hash, sign_hash_size, hash);
457 dtls_prng((unsigned char *)rand, key_size);
458 ret = ecc_ecdsa_sign(priv, hash, rand, point_r, point_s);
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]) {
469 unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
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);
477 dtls_ecdsa_create_sig_hash(priv_key, key_size, sha256hash,
478 sizeof(sha256hash), point_r, point_s);
481 /* rfc4492#section-5.4 */
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) {
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);
499 return ecc_ecdsa_validate(pub_x, pub_y, hash, point_r, point_s);
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) {
510 unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
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);
518 return dtls_ecdsa_verify_sig_hash(pub_key_x, pub_key_y, key_size, sha256hash,
519 sizeof(sha256hash), result_r, result_s);
521 #endif /* DTLS_ECC */
524 dtls_encrypt(const unsigned char *src, size_t length,
526 unsigned char *nounce,
527 unsigned char *key, size_t keylen,
528 const unsigned char *aad, size_t la)
531 struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
533 ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
535 /* cleanup everything in case the key has the wrong size */
536 dtls_warn("cannot set rijndael key\n");
541 memmove(buf, src, length);
542 ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
545 dtls_cipher_context_release();
550 dtls_decrypt(const unsigned char *src, size_t length,
552 unsigned char *nounce,
553 unsigned char *key, size_t keylen,
554 const unsigned char *aad, size_t la)
557 struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
559 ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
561 /* cleanup everything in case the key has the wrong size */
562 dtls_warn("cannot set rijndael key\n");
567 memmove(buf, src, length);
568 ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
571 dtls_cipher_context_release();