Skip to content
Chuck Lever edited this page Mar 23, 2022 · 5 revisions

ktls-utils for Linux

Transport Layer Security, or TLS, is comprised of two subprotocols: a handshake protocol and a record protocol. The TLS record protocol encodes data payloads to provide confidential communication between network peers. Using asymmetric cryptography, the TLS handshake protocol establishes unique session keys used by the TLS record protocol, and can also authenticate the communicating peers.

The Linux kernel supports the TLS record protocol via a facility known as KTLS. User space or kernel sockets can become KTLS sockets to take advantage of this support, which offloads the operation of the TLS record protocol to Network Interface Cards or to a software TLS implementation in the kernel.

To initialize a KTLS socket, a TLS handshake is done first. Today this is handled by one of the many user space TLS implementations, such as GnuTLS, and the resulting session key is handed to the kernel to use for the record protocol. To date, only applications running in user space that can directly link to one of these handshake implementations can use KTLS. Such applications include web browsers and system packaging utilities.

ktls-utils provides a suite of user space tooling that handles TLS handshakes for TLS consumers that run strictly in the kernel. Such consumers include storage protocols like NVMe/TCP or NFS, but can also include transport protocols like QUICv1 that employ the TLSv1.3 handshake protocol when establishing connections.

When a kernel consumer needs a TLS session, an upcall is done to a ktls-utils component, which uses a user space TLS implementation to perform a TLS handshake with the peer host. When the handshake completes, ktls-utils instantiates the kernel consumer's socket as a KTLS socket, enabling the kernel consumer to use the TLS record protocol transparently.

Design materials

As the components of ktls-utils are developed, their design can be discussed and documented here on this wiki.

Initially we envision the use of kernel keyrings for two purposes:

  1. Administrative interfaces such as mount.nfs will prime a special kernel keyring (via add_key(2)) with x.509 certificates or pre-shared keys that enable ktls-utils to authenticate the communicating peers. When a handshake is needed, ktls-utils user agents search this keyring for appropriate authentication material.

  2. A second kernel keyring can be used to pass handshake requests to ktls-utils using the request_key mechanism or something similar. The kernel passes a socket that needs to be instantiated for use with KTLS, and the ktls-utils user agent performs a TLS handshake on that socket and returns it to the kernel.

Design documents to appear on separate pages.

Further requirements

  • These mechanisms must maintain the authentication material separately and securely for each network namespace.

  • The user agents must support both initial session establishment and re-keying, both of which are handled via the TLS handshake protocol.

  • It might be possible to share session key material between kernel TLS sessions. Investigation is needed to demonstrate feasibility and benefit.

Items that cannot be supported via a user agent

One long-term requirement is support for NFSROOT using TLS, and the block equivalent of hosting the root filesystem on an NVMe device using TCP with TLS. This usage scenario is impossible to implement with a user agent that is stored on the root filesystem. Once the ktls-utils infrastructure described here is established, some or all of the handshake implementation will have to be moved into the kernel to support protected root filesystems properly.

Clone this wiki locally