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 <markus.lassila@nordicsemi.no>
This commit is contained in:
Markus Lassila 2024-02-02 13:36:58 +02:00 committed by Alberto Escolar
parent f5cab9debc
commit f033cd5601
2 changed files with 29 additions and 8 deletions

View File

@ -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

View File

@ -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,