Playing with Kernel TLS in Linux 4.13 and Go
blog.filippo.io
blog.filippo.io
Ew.
Might all be brilliant and flawless, but it's not obvious.
On a first look at the first function (tls_sw_sendmsg), we appear to have:
- send_end is the normal cleanup target at the end of the function, that's common and found almost everywhere;
- alloc_encrypted, alloc_plaintext, push_record seem to be "retry" labels, where the code goes back and tries again;
- fallback_to_reg_send is the "then" case of an if, could be removed by inverting the sense of the test;
- wait_for_sndbuf, wait_for_memory are in the style of a cleanup target, but they end by jumping to one of the "retry" labels above;
- trim_sgl is... well, it seems an attempt to avoid code duplication, or something like that, the "goto trim_sgl;" could be replaced by "trim_both_sgl(sk, orig_size); goto send_end;"
Yeah, this code looks more like assembly than C. That appears to be the kind of hand-optimized code usually reserved for hot functions, where the "normal" case encounters as few branches as possible; the fallback_to_reg_send case points to that (the normal case would be the one without the goto). So the way to understand the control flow of these functions would be: ignore the gotos on first reading, since that would be the normal case, and after that look at each goto and understand what it does.
It also did not require applications to support/know about SSL/TLS. So after moving to Solaris 10 we were able to make some legacy apps use SSL/TLS without adding any code at all! Pretty cool stuff.
They did have a few vulnerabilities causing kernel panic that Snorcle had to fix - so in terms of adding more complexity to the kernel it's a risky approach but in our case it was totally worth it and it helped that the SSL/TLS traffic was all internal - nothing public facing.
How did you deal with certificate validation?
TL;DR: The kernel does it all and passes the unencrypted traffic to the local port specified. There's a command to configure it with the appropriate keys, etc.
[0] http://www.c0t0d0s0.org/archives/5575-Less-known-Solaris-Fea...
Edit: @Mister_Snuggles points to a link below if you wanted to run through the whole process.
He mentions that fb noticed significant performance improvement [1].
You should see improvements in some cases, ie. when you can do zero-copy transfers (avoiding kernel->user and then user->kernel data copying), in other words when you pipe data from one socket/file to the other socket/file.
> I ran a simple HTTPS web server with net/http, loaded a page on Chrome, and instead of causing a kernel panic...
Followed by demonstrating it working.
However, the point remains that he only got it working up to doing a toy hello world. The part that would be important for performance would be what he mentioned isn't finished, which is allowing it to be used with sendfile so that web servers can just sendfile over a TLS connection and let the kernel handle all of the IO.