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"
64 #define HMAC_UPDATE_SEED(Context,Seed,Length) \
65 if (Seed) dtls_hmac_update(Context, (Seed), (Length))
67 static struct dtls_cipher_context_t cipher_context;
69 static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER;
72 static struct dtls_cipher_context_t *dtls_cipher_context_get(void)
75 pthread_mutex_lock(&cipher_context_mutex);
77 return &cipher_context;
80 static void dtls_cipher_context_release(void)
83 pthread_mutex_unlock(&cipher_context_mutex);
92 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
93 return malloc(sizeof(dtls_handshake_parameters_t));
96 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
100 static dtls_security_parameters_t *dtls_security_malloc() {
101 return malloc(sizeof(dtls_security_parameters_t));
104 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
107 #else /* WITH_CONTIKI */
110 MEMB(handshake_storage, dtls_handshake_parameters_t, DTLS_HANDSHAKE_MAX);
111 MEMB(security_storage, dtls_security_parameters_t, DTLS_SECURITY_MAX);
114 memb_init(&handshake_storage);
115 memb_init(&security_storage);
118 static dtls_handshake_parameters_t *dtls_handshake_malloc() {
119 return memb_alloc(&handshake_storage);
122 static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) {
123 memb_free(&handshake_storage, handshake);
126 static dtls_security_parameters_t *dtls_security_malloc() {
127 return memb_alloc(&security_storage);
130 static void dtls_security_dealloc(dtls_security_parameters_t *security) {
131 memb_free(&security_storage, security);
133 #endif /* WITH_CONTIKI */
135 dtls_handshake_parameters_t *dtls_handshake_new()
137 dtls_handshake_parameters_t *handshake;
139 handshake = dtls_handshake_malloc();
141 dtls_crit("can not allocate a handshake struct\n");
145 memset(handshake, 0, sizeof(*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);
158 void dtls_handshake_free(dtls_handshake_parameters_t *handshake)
163 netq_delete_all(handshake->reorder_queue);
164 dtls_handshake_dealloc(handshake);
167 dtls_security_parameters_t *dtls_security_new()
169 dtls_security_parameters_t *security;
171 security = dtls_security_malloc();
173 dtls_crit("can not allocate a security struct\n");
177 memset(security, 0, sizeof(*security));
180 security->cipher = TLS_NULL_WITH_NULL_NULL;
181 security->compression = TLS_COMPRESSION_NULL;
186 void dtls_security_free(dtls_security_parameters_t *security)
191 dtls_security_dealloc(security);
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;
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 */
208 hmac_a = dtls_hmac_new(key, keylen);
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);
217 dlen = dtls_hmac_finalize(hmac_a, A);
219 hmac_p = dtls_hmac_new(key, keylen);
223 while (len + dlen < buflen) {
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);
229 HMAC_UPDATE_SEED(hmac_p, label, labellen);
230 HMAC_UPDATE_SEED(hmac_p, random1, random1len);
231 HMAC_UPDATE_SEED(hmac_p, random2, random2len);
233 len += dtls_hmac_finalize(hmac_p, tmp);
234 memcpy(buf, tmp, dlen);
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);
243 dtls_hmac_init(hmac_p, key, keylen);
244 dtls_hmac_update(hmac_p, A, dlen);
246 HMAC_UPDATE_SEED(hmac_p, label, labellen);
247 HMAC_UPDATE_SEED(hmac_p, random1, random1len);
248 HMAC_UPDATE_SEED(hmac_p, random2, random2len);
250 dtls_hmac_finalize(hmac_p, tmp);
251 memcpy(buf, tmp, buflen - len);
254 dtls_hmac_free(hmac_a);
255 dtls_hmac_free(hmac_p);
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) {
267 /* Clear the result buffer */
268 memset(buf, 0, buflen);
269 return dtls_p_hash(HASH_SHA256,
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) {
283 dtls_int_to_uint16(L, length);
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);
291 dtls_hmac_finalize(hmac_ctx, buf);
295 dtls_ccm_encrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, size_t srclen,
297 unsigned char *nounce,
298 const unsigned char *aad, size_t la) {
303 len = dtls_ccm_encrypt_message(&ccm_ctx->ctx, 8 /* M */,
304 max(2, 15 - DTLS_CCM_NONCE_SIZE),
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) {
320 len = dtls_ccm_decrypt_message(&ccm_ctx->ctx, 8 /* M */,
321 max(2, 15 - DTLS_CCM_NONCE_SIZE),
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;
334 if (result_len < (2 * (sizeof(uint16) + keylen))) {
338 dtls_int_to_uint16(p, keylen);
341 memset(p, 0, keylen);
344 memcpy(p, result, sizeof(uint16));
347 memcpy(p, key, keylen);
349 return 2 * (sizeof(uint16) + keylen);
351 #endif /* DTLS_PSK */
355 int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size,
356 unsigned char *buf) {
358 unsigned char *buf_orig = buf;
361 for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) {
364 /* the first bit has to be set to zero, to indicate a poritive integer */
365 if (first && key[i] & 0x80000000) {
368 dtls_int_to_uint32(buf, key[i]);
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;
375 } else if (first && !(key[i] & 0xFFFF8000)) {
376 buf[0] = (key[i] >> 8) & 0xff;
377 buf[1] = key[i] & 0xff;
379 } else if (first && !(key[i] & 0xFFFFFF80)) {
380 buf[0] = key[i] & 0xff;
383 dtls_int_to_uint32(buf, key[i]);
388 return buf - buf_orig;
391 int dtls_ecdh_pre_master_secret(unsigned char *priv_key,
392 unsigned char *pub_key_x,
393 unsigned char *pub_key_y,
395 unsigned char *result,
398 uint8_t publicKey[64];
399 uint8_t privateKey[32];
401 if (result_len < key_size) {
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);
415 dtls_ecdsa_generate_key(unsigned char *priv_key,
416 unsigned char *pub_key_x,
417 unsigned char *pub_key_y,
420 uint8_t publicKey[64];
421 uint8_t privateKey[32];
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);
430 /* rfc4492#section-5.4 */
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]) {
437 uint8_t privateKey[32];
438 uint8_t hashValue[32];
442 uECC_sign(privateKey, hashValue, sign);
443 memcpy(point_r, sign, 32);
444 memcpy(point_s, sign + 32, 32);
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]) {
454 unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
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);
462 dtls_ecdsa_create_sig_hash(priv_key, key_size, sha256hash,
463 sizeof(sha256hash), point_r, point_s);
466 /* rfc4492#section-5.4 */
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) {
473 uint8_t publicKey[64];
474 uint8_t hashValue[32];
477 memcpy(publicKey, pub_key_x, 32);
478 memcpy(publicKey + 32, pub_key_y, 32);
479 return uECC_verify(publicKey, hashValue, sign);
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) {
490 unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE];
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);
498 return dtls_ecdsa_verify_sig_hash(pub_key_x, pub_key_y, key_size, sha256hash,
499 sizeof(sha256hash), result_r, result_s);
501 #endif /* DTLS_ECC */
504 dtls_encrypt(const unsigned char *src, size_t length,
506 unsigned char *nounce,
507 unsigned char *key, size_t keylen,
508 const unsigned char *aad, size_t la)
511 struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
513 ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
515 /* cleanup everything in case the key has the wrong size */
516 dtls_warn("cannot set rijndael key\n");
521 memmove(buf, src, length);
522 ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
525 dtls_cipher_context_release();
530 dtls_decrypt(const unsigned char *src, size_t length,
532 unsigned char *nounce,
533 unsigned char *key, size_t keylen,
534 const unsigned char *aad, size_t la)
537 struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
539 ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
541 /* cleanup everything in case the key has the wrong size */
542 dtls_warn("cannot set rijndael key\n");
547 memmove(buf, src, length);
548 ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
551 dtls_cipher_context_release();