From 7d9fe77a2ae5e71a7b43dd543f44d9f37658fdc0 Mon Sep 17 00:00:00 2001 From: Achim Kraus Date: Thu, 18 Nov 2021 21:50:52 +0100 Subject: [PATCH 1/3] Add client dtls connection ID. Simple client side implementation indicates support and uses the cid of the server, when negotiated by that. Signed-off-by: Achim Kraus --- crypto.h | 27 ++++++- dtls.c | 221 ++++++++++++++++++++++++++++++++++++++++++------------- dtls.h | 1 + global.h | 1 + 4 files changed, 198 insertions(+), 52 deletions(-) diff --git a/crypto.h b/crypto.h index 53547589..6df46ff7 100644 --- a/crypto.h +++ b/crypto.h @@ -110,6 +110,17 @@ typedef struct { uint64_t bitfield; } seqnum_t; +/* Maximum CID length. */ +#ifndef DTLS_MAX_CID_LENGTH +#define DTLS_MAX_CID_LENGTH 16 +#endif + +#if (DTLS_MAX_CID_LENGTH > 0) +#ifndef DTLS_USE_CID_DEFAULT +#define DTLS_USE_CID_DEFAULT 1 +#endif /* DTLS_USE_CID_DEFAULT */ +#endif /* DTLS_MAX_CID_LENGTH > 0 */ + typedef struct { dtls_compression_t compression; /**< compression method */ @@ -124,7 +135,12 @@ typedef struct { * access the components of the key block. */ uint8 key_block[MAX_KEYBLOCK_LENGTH]; - + +#if (DTLS_MAX_CID_LENGTH > 0) + uint8_t write_cid[DTLS_MAX_CID_LENGTH]; + uint8_t write_cid_length; +#endif /* DTLS_MAX_CID_LENGTH > 0 */ + seqnum_t cseq; /** 0) + unsigned int support_cid:1; /** indicate CID support (RFC9146) */ +#endif } dtls_user_parameters_t; typedef struct { @@ -158,6 +177,12 @@ typedef struct { dtls_compression_t compression; /**< compression method */ dtls_user_parameters_t user_parameters; /**< user parameters */ dtls_cipher_index_t cipher_index; /**< internal index for cipher_suite_params, DTLS_CIPHER_INDEX_NULL for TLS_NULL_WITH_NULL_NULL */ + +#if (DTLS_MAX_CID_LENGTH > 0) + uint8_t write_cid[DTLS_MAX_CID_LENGTH]; + uint8_t write_cid_length; +#endif /* DTLS_MAX_CID_LENGTH > 0 */ + unsigned int do_client_auth:1; unsigned int extended_master_secret:1; unsigned int renegotiation_info:1; diff --git a/dtls.c b/dtls.c index 33b352f4..817473fc 100644 --- a/dtls.c +++ b/dtls.c @@ -141,14 +141,15 @@ memarray_t dtlscontext_storage; * ec curves := 8 bytes * ec point format := 6 bytes => 26 * sign. and hash algos := 8 bytes - * extended master secret := 4 bytes => 12 + * extended master secret := 4 bytes + * connection id, empty := 5 bytes => 17 * * (The ClientHello uses TLS_EMPTY_RENEGOTIATION_INFO_SCSV * instead of renegotiation info) */ #define DTLS_CH_LENGTH sizeof(dtls_client_hello_t) /* no variable length fields! */ #define DTLS_COOKIE_LENGTH_MAX 32 -#define DTLS_CH_LENGTH_MAX DTLS_CH_LENGTH + DTLS_COOKIE_LENGTH_MAX + 10 + (2 * DTLS_MAX_CIPHER_SUITES) + 26 + 12 +#define DTLS_CH_LENGTH_MAX DTLS_CH_LENGTH + DTLS_COOKIE_LENGTH_MAX + 10 + (2 * DTLS_MAX_CIPHER_SUITES) + 26 + 17 #define DTLS_HV_LENGTH sizeof(dtls_hello_verify_t) /* * ServerHello: @@ -531,6 +532,7 @@ static char const content_types[] = { DTLS_CT_ALERT, DTLS_CT_HANDSHAKE, DTLS_CT_APPLICATION_DATA, + DTLS_CT_TLS12_CID, 0 /* end marker */ }; @@ -666,6 +668,9 @@ static const dtls_user_parameters_t default_user_parameters = { #endif /* DTLS_DEFAULT_CIPHER_SUITES */ .force_extended_master_secret = 1, .force_renegotiation_info = 1, +#if (DTLS_MAX_CID_LENGTH > 0) + .support_cid = DTLS_USE_CID_DEFAULT, +#endif /* DTLS_MAX_CID_LENGTH > 0 */ }; /** only one compression method is currently defined */ @@ -928,6 +933,8 @@ dtls_message_type_to_name(int type) { return "handshake"; case DTLS_CT_APPLICATION_DATA: return "application_data"; + case DTLS_CT_TLS12_CID: + return "connection_id"; default: return NULL; } @@ -1067,6 +1074,10 @@ calculate_key_block(dtls_context_t *ctx, security->cipher_index = handshake->cipher_index; security->compression = handshake->compression; security->rseq = 0; +#if (DTLS_MAX_CID_LENGTH > 0) + security->write_cid_length = handshake->write_cid_length; + memcpy(security->write_cid, handshake->write_cid, handshake->write_cid_length); +#endif /* DTLS_MAX_CID_LENGTH > 0 */ return 0; } @@ -1173,6 +1184,39 @@ static int verify_ext_sig_hash_algo(uint8 *data, size_t data_length) { return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); } +#if (DTLS_MAX_CID_LENGTH > 0) + +static int +get_ext_connection_id(dtls_handshake_parameters_t *handshake, uint8 *data, + size_t data_length) { + uint8_t i; + + if (sizeof(uint8) > data_length) { + dtls_warn("invalid length (%zu) for extension connection id\n", data_length); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + /* length of the connection id */ + i = dtls_uint8_to_int(data); + data += sizeof(uint8); + if (i + sizeof(uint8) != data_length) { + dtls_warn("invalid connection id length (%d)\n", i); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + if (DTLS_MAX_CID_LENGTH < i) { + dtls_warn("connection id length (%d) exceeds maximum (%d)!\n", i, DTLS_MAX_CID_LENGTH); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + handshake->write_cid_length = i; + memcpy(handshake->write_cid, data, i); + + return 0; +} + +#endif /* DTLS_MAX_CID_LENGTH > 0*/ + /* * Check for some TLS Extensions used by the ECDHE_ECDSA cipher. */ @@ -1266,6 +1310,16 @@ dtls_check_tls_extension(dtls_peer_t *peer, if (verify_ext_sig_hash_algo(data, j)) goto error; break; +#if (DTLS_MAX_CID_LENGTH > 0) + case TLS_EXT_CONNECTION_ID: + if (!is_client_hello && !peer->handshake_params->user_parameters.support_cid) { + dtls_warn("connection id was not sent by client!\n"); + goto error; + } + if (get_ext_connection_id(peer->handshake_params, data, j)) + goto error; + break; +#endif /* DTLS_MAX_CID_LENGTH */ case TLS_EXT_RENEGOTIATION_INFO: /* RFC 5746, minimal version, only empty info is supported */ if (j == 1 && *data == 0) { @@ -1643,9 +1697,10 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security, uint8 *data_array[], size_t data_len_array[], size_t data_array_len, uint8 *sendbuf, size_t *rlen) { - uint8 *p, *start; + uint8 *p; int res; unsigned int i; + uint8_t cid_length = 0; if (*rlen < DTLS_RH_LENGTH) { dtls_alert("The sendbuf (%zu bytes) is too small\n", *rlen); @@ -1658,7 +1713,6 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security, } p = dtls_set_record_header(type, security->epoch, &(security->rseq), sendbuf); - start = p; if (security->cipher_index == DTLS_CIPHER_INDEX_NULL) { /* no cipher suite */ @@ -1679,15 +1733,31 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 or TLS_ECDHE_ECDSA_WITH_AES_128_CCM */ /** + * RFC6347 * length of additional_data for the AEAD cipher which consists of * seq_num(2+6) + type(1) + version(2) + length(2) */ #define A_DATA_LEN 13 + +#if (DTLS_MAX_CID_LENGTH > 0) + /** + * RFC9146 + * length of extra additional_data for the AEAD cipher which consists of + * seq_num_placeholder(8) + type(1) + cid_length(1) + */ +#define A_DATA_CID_EXTRA_LEN 10 +#define A_DATA_MAX_LEN (A_DATA_LEN + A_DATA_CID_EXTRA_LEN + DTLS_MAX_CID_LENGTH) +#else +#define A_DATA_MAX_LEN A_DATA_LEN +#endif + + uint8 *start = p; unsigned char nonce[DTLS_CCM_BLOCKSIZE]; - unsigned char A_DATA[A_DATA_LEN]; + unsigned char A_DATA[A_DATA_MAX_LEN]; const uint8_t mac_len = get_cipher_suite_mac_len(security->cipher_index); const cipher_suite_key_exchange_algorithm_t key_exchange_algorithm = get_key_exchange_algorithm(security->cipher_index); + uint8_t a_data_len = A_DATA_LEN; /* For backwards-compatibility, dtls_encrypt_params is called with * M= and L=3. */ const dtls_ccm_params_t params = { nonce, mac_len, 3 }; @@ -1704,6 +1774,16 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security, } } +#if (DTLS_MAX_CID_LENGTH > 0) + cid_length = security->write_cid_length; + if (cid_length > 0) { + /* add cid to record header */ + memcpy(p - sizeof(uint16_t), security->write_cid, cid_length); + p += cid_length; + start = p; + } +#endif /* DTLS_MAX_CID_LENGTH > 0 */ + /* set nonce from RFC 6655: The "nonce" input to the AEAD algorithm is exactly that of [RFC5288]: @@ -1769,31 +1849,62 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security, dtls_debug_dump("key:", dtls_kb_local_write_key(security, peer->role), dtls_kb_key_size(security, peer->role)); - /* re-use N to create additional data according to RFC 5246, Section 6.2.3.3: - * - * additional_data = seq_num + TLSCompressed.type + - * TLSCompressed.version + TLSCompressed.length; - */ - memcpy(A_DATA, &DTLS_RECORD_HEADER(sendbuf)->epoch, 8); /* epoch and seq_num */ - memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(sendbuf)->content_type, 3); /* type and version */ - dtls_int_to_uint16(A_DATA + 11, res - 8); /* length */ +#if (DTLS_MAX_CID_LENGTH > 0) + if (cid_length > 0) { + /* RFC 9146 */ + + /* inner content type */ + *p = *sendbuf; + *sendbuf = DTLS_CT_TLS12_CID; + p += sizeof(uint8_t); + res += sizeof(uint8_t); + + /* seq_num_placeholder: 8x 0xff */ + memset(A_DATA, 0xff, 8); + /* tls_cid: 25 */ + A_DATA[8] = DTLS_CT_TLS12_CID; + /* cid length */ + A_DATA[9] = cid_length; + /* copy record header */ + memcpy(A_DATA + A_DATA_CID_EXTRA_LEN, sendbuf, A_DATA_LEN + cid_length); + dtls_int_to_uint16(A_DATA + A_DATA_CID_EXTRA_LEN + 11 + cid_length, res - 8); /* length */ + a_data_len = A_DATA_LEN + A_DATA_CID_EXTRA_LEN + cid_length; + + } else { +#endif /* DTLS_MAX_CID_LENGTH > 0 */ + /* RFC 6347 */ + /* re-use N to create additional data according to RFC 5246, Section 6.2.3.3: + * + * additional_data = seq_num + TLSCompressed.type + + * TLSCompressed.version + TLSCompressed.length; + */ + memcpy(A_DATA, &DTLS_RECORD_HEADER(sendbuf)->epoch, 8); /* epoch and seq_num */ + memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(sendbuf)->content_type, 3); /* type and version */ + dtls_int_to_uint16(A_DATA + 11, res - 8); /* length */ + a_data_len = A_DATA_LEN; +#if (DTLS_MAX_CID_LENGTH > 0) + } +#endif /* DTLS_MAX_CID_LENGTH > 0 */ + + dtls_debug_dump("adata:", A_DATA, a_data_len); + dtls_debug_dump("message:", start, res); res = dtls_encrypt_params(¶ms, start + 8, res - 8, start + 8, dtls_kb_local_write_key(security, peer->role), dtls_kb_key_size(security, peer->role), - A_DATA, A_DATA_LEN); + A_DATA, a_data_len); if (res < 0) return res; res += 8; /* increment res by size of nonce_explicit */ - dtls_debug_dump("message:", start, res); + dtls_debug_dump("encrypted-message:", start, res); } /* fix length of fragment in sendbuf */ - dtls_int_to_uint16(sendbuf + 11, res); + dtls_int_to_uint16(sendbuf + 11 + cid_length, res); - *rlen = DTLS_RH_LENGTH + res; + *rlen = DTLS_RH_LENGTH + res + cid_length; return 0; } @@ -2465,15 +2576,12 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer) */ uint8 buf[DTLS_SH_LENGTH + 2 + 5 + 5 + 6 + 4 + 5]; uint8 *p; - uint8 extension_size; + uint8_t *p_extension_size = NULL; + uint16_t extension_size = 0; dtls_handshake_parameters_t * const handshake = peer->handshake_params; const dtls_cipher_t cipher_suite = get_cipher_suite(handshake->cipher_index); const int ecdsa = is_key_exchange_ecdhe_ecdsa(handshake->cipher_index); - extension_size = (handshake->extended_master_secret ? 4 : 0) + - (handshake->renegotiation_info ? 5 : 0) + - (ecdsa ? 5 + 5 + 6 : 0); - /* Handshake header */ p = buf; @@ -2487,7 +2595,8 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer) memcpy(p, handshake->tmp.random.server, DTLS_RANDOM_LENGTH); p += DTLS_RANDOM_LENGTH; - *p++ = 0; /* no session id */ + /* no session id */ + *p++ = 0; if (cipher_suite != TLS_NULL_WITH_NULL_NULL) { /* selected cipher suite */ @@ -2498,11 +2607,10 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer) *p++ = compression_methods[handshake->compression]; } - if (extension_size) { - /* length of the extensions */ - dtls_int_to_uint16(p, extension_size); - p += sizeof(uint16); - } + /* keep pointer to length of the extensions */ + p_extension_size = p; + /* skip length of extensions field */ + p += sizeof(uint16); if (ecdsa) { /* client certificate type extension, 5 bytes */ @@ -2566,6 +2674,10 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer) *p++ = 0; } + /* length of the extensions */ + extension_size = (p - p_extension_size) - sizeof(uint16); + dtls_int_to_uint16(p_extension_size, extension_size); + assert((buf <= p) && ((unsigned int)(p - buf) <= sizeof(buf))); /* TODO use the same record sequence number as in the ClientHello, @@ -3069,10 +3181,9 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer, uint8 cookie[], size_t cookie_length) { uint8 buf[DTLS_CH_LENGTH_MAX]; uint8_t *p = buf; - uint8_t *p_cipher_suites_size = NULL; + uint8_t *p_size = NULL; + uint16_t size = 0; uint8_t index = 0; - uint8_t cipher_suites_size = 0; - uint8_t extension_size = 4; /* extended master secret extension */ #ifdef DTLS_ECC uint8_t ecdsa = 0; #endif @@ -3112,7 +3223,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer, } /* keep pointer to size of cipher suites */ - p_cipher_suites_size = p; + p_size = p; /* skip size of cipher suites field */ p += sizeof(uint16); @@ -3131,8 +3242,8 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer, credentials callback is missing */ } - cipher_suites_size = (p - p_cipher_suites_size) - sizeof(uint16); - if (cipher_suites_size == 0) { + size = (p - p_size) - sizeof(uint16); + if (size == 0) { dtls_crit("no supported cipher suite provided!\n"); return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); } @@ -3140,23 +3251,10 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer, /* RFC5746 add RENEGOTIATION_INFO_SCSV */ dtls_int_to_uint16(p, TLS_EMPTY_RENEGOTIATION_INFO_SCSV); p += sizeof(uint16); - cipher_suites_size += sizeof(uint16); + size += sizeof(uint16); /* set size of known cipher suites */ - dtls_int_to_uint16(p_cipher_suites_size, cipher_suites_size); - -#ifdef DTLS_ECC - if (ecdsa) { - /* - * client_cert_type := 6 bytes - * server_cert_type := 6 bytes - * ec curves := 8 bytes - * ec point format := 6 bytes - * sign. and hash algos := 8 bytes - */ - extension_size += 6 + 6 + 8 + 6 + 8; - } -#endif + dtls_int_to_uint16(p_size, size); /* compression method */ dtls_int_to_uint8(p, 1); @@ -3165,8 +3263,9 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer, dtls_int_to_uint8(p, TLS_COMPRESSION_NULL); p += sizeof(uint8); - /* length of the extensions */ - dtls_int_to_uint16(p, extension_size); + /* keep pointer to length of the extensions */ + p_size = p; + /* skip length of extensions field */ p += sizeof(uint16); #ifdef DTLS_ECC @@ -3263,6 +3362,26 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer, p += sizeof(uint16); handshake->extended_master_secret = 1; +#if (DTLS_MAX_CID_LENGTH > 0) + if (handshake->user_parameters.support_cid) { + /* connection id, empty to indicate support, 5 bytes */ + dtls_int_to_uint16(p, TLS_EXT_CONNECTION_ID); + p += sizeof(uint16); + + /* length of this extension type */ + dtls_int_to_uint16(p, sizeof(uint8)); + p += sizeof(uint16); + + /* empty cid, indicating support for cid extension */ + dtls_int_to_uint8(p, 0); + p += sizeof(uint8); + } +#endif /* DTLS_MAX_CID_LENGTH > 0 */ + + /* length of the extensions */ + size = (p - p_size) - sizeof(uint16); + dtls_int_to_uint16(p_size, size); + handshake->hs_state.read_epoch = dtls_security_params(peer)->epoch; assert((buf <= p) && ((unsigned int)(p - buf) <= sizeof(buf))); diff --git a/dtls.h b/dtls.h index 05f3385c..600e8edc 100644 --- a/dtls.h +++ b/dtls.h @@ -341,6 +341,7 @@ void dtls_check_retransmit(dtls_context_t *context, clock_time_t *next); #define DTLS_CT_ALERT 21 #define DTLS_CT_HANDSHAKE 22 #define DTLS_CT_APPLICATION_DATA 23 +#define DTLS_CT_TLS12_CID 25 #ifdef __GNUC__ #define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) diff --git a/global.h b/global.h index d915aed1..347c1c9e 100644 --- a/global.h +++ b/global.h @@ -93,6 +93,7 @@ typedef enum { #define TLS_EXT_SERVER_CERTIFICATE_TYPE 20 /* see RFC 7250 */ #define TLS_EXT_ENCRYPT_THEN_MAC 22 /* see RFC 7366 */ #define TLS_EXT_EXTENDED_MASTER_SECRET 23 /* see RFC 7627 */ +#define TLS_EXT_CONNECTION_ID 54 /* see RFC 9146 */ #define TLS_EXT_RENEGOTIATION_INFO 65281 /* see RFC 5746 */ #define TLS_CERT_TYPE_RAW_PUBLIC_KEY 2 /* see RFC 7250 */ From 897a60e32e883a958209ab3efe201fcfec9c15dd Mon Sep 17 00:00:00 2001 From: Achim Kraus Date: Tue, 24 Jan 2023 20:08:13 +0100 Subject: [PATCH 2/3] dtls-client.c: add support_cid option. Signed-off-by: Achim Kraus --- tests/dtls-client.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/tests/dtls-client.c b/tests/dtls-client.c index bb27367b..0d24f4e4 100644 --- a/tests/dtls-client.c +++ b/tests/dtls-client.c @@ -69,7 +69,9 @@ static dtls_context_t *orig_dtls_context = NULL; static const dtls_cipher_t* ciphers = NULL; static unsigned int force_extended_master_secret = 0; static unsigned int force_renegotiation_info = 0; - +#if (DTLS_MAX_CID_LENGTH > 0) +static unsigned int support_cid = 0; +#endif #ifdef DTLS_ECC static const unsigned char ecdsa_priv_key[] = { @@ -246,6 +248,9 @@ get_user_parameters(struct dtls_context_t *ctx, (void) session; user_parameters->force_extended_master_secret = force_extended_master_secret; user_parameters->force_renegotiation_info = force_renegotiation_info; +#if (DTLS_MAX_CID_LENGTH > 0) + user_parameters->support_cid = support_cid; +#endif if (ciphers) { int i = 0; while (i < DTLS_MAX_CIPHER_SUITES) { @@ -360,13 +365,18 @@ usage( const char *program, const char *version) { fprintf(stderr, "%s v%s -- DTLS client implementation\n" "(c) 2011-2014 Olaf Bergmann \n\n" + "usage: %s [-c cipher suites] [-e] " #ifdef DTLS_PSK - "usage: %s [-c cipher suites] [-e] [-i file] [-k file] [-o file]\n" - " %*s [-p port] [-r] [-v num] addr [port]\n", + "[-i file] [-k file] [-o file]\n" + " %*s [-p port] [-r] [-v num]" #else /* DTLS_PSK */ - "usage: %s [-c cipher suites] [-e] [-o file] [-p port] [-r]\n" - " %*s [-v num] addr [port]\n", + "[-o file] [-p port] [-r]\n" + " %*s [-v num]" #endif /* DTLS_PSK */ +#if (DTLS_MAX_CID_LENGTH > 0) + " [-z]" +#endif /* DTLS_MAX_CID_LENGTH > 0*/ + " addr [port]\n", program, version, program, (int)strlen(program), ""); cipher_suites_usage(stderr, "\t"); fprintf(stderr, "\t-e\t\tforce extended master secret (RFC7627)\n" @@ -378,7 +388,10 @@ usage( const char *program, const char *version) { "\t \t\t(use '-' for STDOUT)\n" "\t-p port\t\tlisten on specified port (default is %d)\n" "\t-r\t\tforce renegotiation info (RFC5746)\n" - "\t-v num\t\tverbosity level (default: 3)\n", + "\t-v num\t\tverbosity level (default: 3)\n" +#if (DTLS_MAX_CID_LENGTH > 0) + "\t-z\t\tsupport CID (RFC9146)\n", +#endif /* DTLS_MAX_CID_LENGTH > 0*/ DEFAULT_PORT); } @@ -434,7 +447,7 @@ main(int argc, char **argv) { memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length); #endif /* DTLS_PSK */ - while ((opt = getopt(argc, argv, "c:eo:p:rv:" PSK_OPTIONS)) != -1) { + while ((opt = getopt(argc, argv, "c:eo:p:rv:z" PSK_OPTIONS)) != -1) { switch (opt) { #ifdef DTLS_PSK case 'i' : @@ -482,6 +495,9 @@ main(int argc, char **argv) { case 'v' : log_level = strtol(optarg, NULL, 10); break; + case 'z' : + support_cid = 1; + break; default: usage(argv[0], dtls_package_version()); exit(1); From a6412a3d73e742ab0d067817298cf2bba9253832 Mon Sep 17 00:00:00 2001 From: Achim Kraus Date: Wed, 15 Nov 2023 20:03:06 +0100 Subject: [PATCH 3/3] dtls.c: support longer PSK secrets. Use DTLS_KEY_LENGTH for DTLS_PSK_MAX_KEY_LEN only as default. Signed-off-by: Achim Kraus --- crypto.h | 2 ++ dtls.c | 6 ++---- zephyr/CMakeLists.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto.h b/crypto.h index 6df46ff7..4902a49e 100644 --- a/crypto.h +++ b/crypto.h @@ -92,7 +92,9 @@ typedef struct { #endif /* DTLS_PSK_MAX_CLIENT_IDENTITY_LEN */ /* This is the maximal supported length of the pre-shared key. */ +#ifndef DTLS_PSK_MAX_KEY_LEN #define DTLS_PSK_MAX_KEY_LEN DTLS_KEY_LENGTH +#endif /* DTLS_PSK_MAX_KEY_LEN */ typedef struct { uint16_t id_length; diff --git a/dtls.c b/dtls.c index 817473fc..8368a1cb 100644 --- a/dtls.c +++ b/dtls.c @@ -952,7 +952,7 @@ calculate_key_block(dtls_context_t *ctx, dtls_peer_type role) { (void) ctx; (void) session; - unsigned char *pre_master_secret; + unsigned char pre_master_secret[2 * (sizeof(uint16) + DTLS_PSK_MAX_KEY_LEN)]; int pre_master_len = 0; dtls_security_parameters_t *security = dtls_security_params_next(peer); uint8 master_secret[DTLS_MASTER_SECRET_LENGTH]; @@ -962,7 +962,6 @@ calculate_key_block(dtls_context_t *ctx, return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); } - pre_master_secret = security->key_block; switch (get_key_exchange_algorithm(handshake->cipher_index)) { case DTLS_KEY_EXCHANGE_PSK: #ifdef DTLS_PSK @@ -978,10 +977,9 @@ calculate_key_block(dtls_context_t *ctx, dtls_crit("no psk key for session available\n"); return len; } - /* Temporarily use the key_block storage space for the pre master secret. */ pre_master_len = dtls_psk_pre_master_secret(psk, len, pre_master_secret, - MAX_KEYBLOCK_LENGTH); + sizeof(pre_master_secret)); dtls_debug_hexdump("psk", psk, len); diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index a279f770..2c8316a9 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -39,7 +39,7 @@ if(CONFIG_LIBTINYDTLS) set(DTLS_ECC Off) endif() add_subdirectory(.. build) - target_compile_definitions(tinydtls PUBLIC WITH_ZEPHYR) + target_compile_definitions(tinydtls PUBLIC WITH_ZEPHYR DTLS_PSK_MAX_KEY_LEN=32 DTLS_PSK_MAX_CLIENT_IDENTITY_LEN=48) target_link_libraries(tinydtls PUBLIC zephyr_interface) set_property(GLOBAL APPEND PROPERTY ZEPHYR_INTERFACE_LIBS tinydtls) endif()