Skip to content

docs: add the kernel TLS design notes - #730

Open
lneto wants to merge 1 commit into
masterfrom
claude_ktls_docs
Open

docs: add the kernel TLS design notes#730
lneto wants to merge 1 commit into
masterfrom
claude_ktls_docs

Conversation

@lneto

@lneto lneto commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Design notes for the kernel TLS (kTLS) epic (#723), in the same shape as the other
doc/design/<theme>/ sets: plan, proposed API, verified kernel reference, test strategy.

doc/design/ktls/ covers a kTLS binding so Lua scripts can key a connected socket for TLS, read and
write plaintext while the kernel does the record-layer crypto, delegate the handshake to tlshd
through the kernel handshake upcall, and splice plaintext between sockets — enough for a TLS proxy or
an in-kernel TLS tunnel in Lua.

The design turns on one fact, stated up front so a contributor does not rediscover it the hard way:

The Linux kernel implements the TLS record layer but not the handshake. Every honest "in-kernel TLS"
— nginx SSL_sendfile, HAProxy, Cilium's Envoy-based visibility, tlshd — keeps the handshake,
certificate validation and policy in userspace and only kernelizes record crypto and byte movement.
So a "TLS tunnel in Lua" is a plaintext-splicing proxy over already-keyed kTLS sockets, not a kernel
TLS stack — design against that, or you fork net/tls like the 2020 GSoC project did.

It is built incrementally, and half the foundation already exists on a parked claude_tls branch
(socket:setsockopt, a tls crypto-info packer, a handshake-upcall binding — but not on master,
and without the data path). The early phases rebase that; the later phases add plaintext I/O with
control records, the handshake plumbing, and the tunnel. kTLS is a TCP ULP and a socket carries one
ULP, so we ride the kernel's tls ULP; a Lua ULP (the successor to Pedro Tammela's ulp-lua) is a
separate project, kept as a non goal.

The kernel-notes.md facts were verified against Linux 6.8 source and the running kernel's exported
symbols: the two-step setsockopt keying, the module-callable handshake upcall (tls_client_hello_*,
all plain EXPORT_SYMBOL), the -EIO-without-a-control-buffer gotcha on the plaintext read path, and
the version drift (TLS 1.3 KeyUpdate lands in 6.14, absent in 6.8).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant