From f033cd5601ac10df27b248b88c5cfa2ab16ee89f Mon Sep 17 00:00:00 2001 From: Markus Lassila Date: Fri, 2 Feb 2024 13:36:58 +0200 Subject: [PATCH] net: sockets: tls: Add config for DTLS max fragment length Add CONFIG_NET_SOCKETS_DTLS_MAX_FRAGMENT_LENGTH for limiting the Maximum Fragment Length (MFL) for DTLS with Mbed TLS. This is needed when MBEDTLS_SSL_OUT_CONTENT_LEN and MBEDTLS_SSL_IN_CONTENT_LEN are set to larger values than the MTU of the network and IP fragmentation is not supported. Signed-off-by: Markus Lassila --- subsys/net/lib/sockets/Kconfig | 17 ++++++++++++++++- subsys/net/lib/sockets/sockets_tls.c | 20 +++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 66009b0e1d3..2ef3e1ba21b 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -147,7 +147,8 @@ config NET_SOCKETS_TLS_SET_MAX_FRAGMENT_LENGTH Maximum Fragment Length (MFL) value is automatically chosen based on MBEDTLS_SSL_OUT_CONTENT_LEN and MBEDTLS_SSL_IN_CONTENT_LEN mbed TLS macros (which are configured by CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN in - case of default mbed TLS config). + case of default mbed TLS config). With DTLS, MFL value may be further + limited with NET_SOCKETS_DTLS_MAX_FRAGMENT_LENGTH. This is mostly useful for TLS client side to tell TLS server what is the maximum supported receive record length. @@ -173,6 +174,20 @@ config NET_SOCKETS_DTLS_TIMEOUT freed only when connection is gracefully closed by peer sending TLS notification or socket is closed. +config NET_SOCKETS_DTLS_MAX_FRAGMENT_LENGTH + int "Maximum DTLS fragment size in bytes" + default 1024 + range 512 4096 + depends on NET_SOCKETS_ENABLE_DTLS + depends on NET_SOCKETS_TLS_SET_MAX_FRAGMENT_LENGTH + help + This variable specifies the Maximum Fragment Length (MFL) value to + be used with DTLS connection when MBEDTLS_SSL_OUT_CONTENT_LEN and + MBEDTLS_SSL_IN_CONTENT_LEN are set to larger values (for TLS). + + With DTLS the MFL should be kept under the network MTU, to avoid + IP fragmentation. + config NET_SOCKETS_TLS_MAX_CONTEXTS int "Maximum number of TLS/DTLS contexts" default 1 diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index a244a20a1b3..fc4cec728d1 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -401,10 +401,8 @@ static inline bool is_handshake_complete(struct tls_context *ctx) BUILD_ASSERT(MBEDTLS_TLS_EXT_ADV_CONTENT_LEN >= 512, "Too small content length!"); -static inline unsigned char tls_mfl_code_from_content_len(void) +static inline unsigned char tls_mfl_code_from_content_len(size_t len) { - size_t len = MBEDTLS_TLS_EXT_ADV_CONTENT_LEN; - if (len >= 4096) { return MBEDTLS_SSL_MAX_FRAG_LEN_4096; } else if (len >= 2048) { @@ -418,14 +416,22 @@ static inline unsigned char tls_mfl_code_from_content_len(void) } } -static inline void tls_set_max_frag_len(mbedtls_ssl_config *config) +static inline void tls_set_max_frag_len(mbedtls_ssl_config *config, enum net_sock_type type) { - unsigned char mfl_code = tls_mfl_code_from_content_len(); + unsigned char mfl_code; + size_t len = MBEDTLS_TLS_EXT_ADV_CONTENT_LEN; + +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) + if (type == SOCK_DGRAM && len > CONFIG_NET_SOCKETS_DTLS_MAX_FRAGMENT_LENGTH) { + len = CONFIG_NET_SOCKETS_DTLS_MAX_FRAGMENT_LENGTH; + } +#endif + mfl_code = tls_mfl_code_from_content_len(len); mbedtls_ssl_conf_max_frag_len(config, mfl_code); } #else -static inline void tls_set_max_frag_len(mbedtls_ssl_config *config) {} +static inline void tls_set_max_frag_len(mbedtls_ssl_config *config, enum net_sock_type type) {} #endif /* Allocate TLS context. */ @@ -458,7 +464,6 @@ static struct tls_context *tls_alloc(void) mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->config); - tls_set_max_frag_len(&tls->config); #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) mbedtls_ssl_cookie_init(&tls->cookie); tls->options.dtls_handshake_timeout_min = @@ -1305,6 +1310,7 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) */ return -ENOMEM; } + tls_set_max_frag_len(&context->config, context->type); #if defined(MBEDTLS_SSL_RENEGOTIATION) mbedtls_ssl_conf_legacy_renegotiation(&context->config,