Skip to content

Commit 500eead

Browse files
committed
tlshd: support setting the record size limit
RFC 8449 [1] Section 4 defines the record_size_limit TLS extension, which allows peers to negotiate a maximum plaintext record size during the TLS handshake. The value must be between 64 bytes and 16,384 bytes (2^14). If a TLS endpoint receives a record larger than its advertised limit, it must send a fatal record_overflow alert. This patch fetches maximum support send size as specified by the record size limit extension or as defined in GnuTLS, this value is then passed to the kernel through setsockopt() using the new TLS_TX_MAX_PAYLOAD_LEN option, such that the kernel can ensure outgoing records do not exceed the size specified. The respective kernel changes are currently applied to net-next [2]. [1] https://www.rfc-editor.org/rfc/rfc8449#section-4 [2] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=82cb5be6ad64198a3a028aeb49dcc7f6224d558a Signed-off-by: Wilfred Mallawa <[email protected]>
1 parent c85d09d commit 500eead

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ AC_CHECK_LIB([gnutls], [gnutls_get_system_config_file],
8585
AC_CHECK_LIB([gnutls], [gnutls_psk_allocate_client_credentials2],
8686
[AC_DEFINE([HAVE_GNUTLS_PSK_ALLOCATE_CREDENTIALS2], [1],
8787
[Define to 1 if you have the gnutls_psk_allocate_client_credentials2 function.])])
88+
AC_CHECK_LIB([gnutls], [gnutls_record_get_max_send_size],
89+
[AC_DEFINE([HAVE_GNUTLS_RECORD_GET_MAX_SEND_SIZE], [1],
90+
[Define to 1 if you have the gnutls_record_get_max_send_size function.])])
8891

8992
AC_MSG_CHECKING(for ML-DSA support in gnutls)
9093
AC_COMPILE_IFELSE(

src/tlshd/handshake.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,31 @@
4343
#include <gnutls/abstract.h>
4444

4545
#include <glib.h>
46+
#include <linux/tls.h>
4647

4748
#include "tlshd.h"
4849
#include "netlink.h"
4950

51+
#ifdef HAVE_GNUTLS_RECORD_GET_MAX_SEND_SIZE
52+
int tlshd_set_record_size(gnutls_session_t session)
53+
{
54+
uint16_t max_send_size;
55+
int ret;
56+
57+
max_send_size = gnutls_record_get_max_send_size(session);
58+
/* For TLS 1.3 kernel expects us to account for the ContentType */
59+
if (gnutls_protocol_get_version(session) == GNUTLS_TLS1_3)
60+
max_send_size -= 1;
61+
62+
ret = setsockopt(gnutls_transport_get_int(session), SOL_TLS,
63+
TLS_TX_MAX_PAYLOAD_LEN, &max_send_size, sizeof(max_send_size));
64+
if (ret < 0)
65+
tlshd_log_perror("setsockopt (TLS_TX_MAX_PAYLOAD_LEN)");
66+
67+
return ret;
68+
}
69+
#endif
70+
5071
/**
5172
* @brief Toggle the use of the Nagle algorithm
5273
* @param[in] session TLS session to modify
@@ -125,6 +146,7 @@ void tlshd_start_tls_handshake(gnutls_session_t session,
125146
gnutls_free(desc);
126147

127148
parms->session_status = tlshd_initialize_ktls(session);
149+
tlshd_set_record_size(session);
128150
}
129151

130152
/**

src/tlshd/ktls.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ unsigned int tlshd_initialize_ktls(gnutls_session_t session)
363363
return EIO;
364364
}
365365

366+
if (tlshd_set_record_size(session) < 0)
367+
return EIO;
368+
366369
gnutls_transport_get_int2(session, &sockin, &sockout);
367370

368371
switch (gnutls_cipher_get(session)) {

src/tlshd/tlshd.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ extern void tlshd_start_tls_handshake(gnutls_session_t session,
8383
struct tlshd_handshake_parms *parms);
8484
extern void tlshd_service_socket(void);
8585

86+
#ifdef HAVE_GNUTLS_RECORD_GET_MAX_SEND_SIZE
87+
extern int tlshd_set_record_size(gnutls_session_t session);
88+
#else
89+
static inline int tlshd_set_record_size(gnutls_session_t session __attribute__((unused))) { return 0; }
90+
#endif
8691
/* keyring.c */
8792
extern bool tlshd_keyring_get_psk_username(key_serial_t serial,
8893
char **username);

0 commit comments

Comments
 (0)