GnuTLS should transparently use KTLS if it's available
The Linux kernel has been supporting KTLS for some time now.
This is basically a kernel-side TLS record encryption offloading. The kernel receives plaintext data on the socket descriptor via write()
and it builds a valid TLS record around it. The same happens when data is read with read()
: a TLS record is expected, then decrypted and the plaintext it contains returned. Another benefit is that you can send an entire file with sendfile()
, which will also be transparently encrypted in suitable TLS records.
After a successful TLS handshake (this happens normally on userland), you need to obtain the TLS secrets. You do this with gnutls_record_get_state()
.
Then you enable KTLS on a connected TCP socket with setsockopt
:
setsockopt(sockfd, SOL_TCP, TCP_ULP, "tls", sizeof("tls");
And finally you copy the TLS master secret to the kernel so that it can build the read and write keys.
I think GnuTLS should transparently use KTLS if it's available, when either gnutls_record_recv()
or gnutls_record_write()
are called.
If it's not available, fall back to userland encryption using Nettle, just like now.