
RFC 8548: Cryptographic Protection of TCP Streams (Tcpcrypt) - mjl-
https://tools.ietf.org/html/rfc8548
======
mazieres
Some historical context here. First, the project was begun over 10 years ago,
long before QUIC, before widespread use of https for most web pages, and
before widespread use of ECC certificates. (E.g., americanexpress.com was an
http web page, and while the form had you submit your password to an https
URL, obviously attackers could tamper with the page in transit and make you
submit your username/password elsewhere. Similarly gmail and google search
were unencrypted--only the authentication page had https.) At the time,
performance was a huge deal, because the cost of public key operations
severely limited the number of https requests/second that a server could
handle.

So the goals of the tcpcrypt project back then were 1) solve the performance
problem by making it practical to encrypt essentially all TCP traffic, 2) make
undetectable widespread eavesdropping impractical, 3) provide a pathway for
insecure applications to achieve high network security with minimal effort,
and 4) avoid the traps applications commonly experience such as low-quality
pseudo-random seeds, or leaking session keys through memory errors.

We solved #1 by carefully constructing the protocol to minimize public key
overhead on the server and allow optimized server authentication. In
particular, with low-exponent RSA (popular at the time), the server-side
computation was only encryption (which is much, much cheaper than decryption).
Moreover, for strong security (with server-side authentication), servers could
perform batch signing in which a single signature could be amortized over many
connections. The result was dramatically better performance for the original
version of tcpcrypt, which you can see described here:

[http://www.scs.stanford.edu/~dm/home/papers/bittau:tcpcrypt....](http://www.scs.stanford.edu/~dm/home/papers/bittau:tcpcrypt.pdf)

We solved #2 by encrypting everything, and providing a mechanism to tie
authentication to that encryption. So if an ISP systematically mounted a man-
in-the-middle attack, they would cause authentication to fail. Moreover, it
would be easy to run tests by, for instance, logging session IDs at
connections between various endpoints and comparing them after the fact. That
still meant ISPs could violate the privacy of unauthenticated connections, but
then at least we would know about it and could decide, as a society, whether
we wanted this kind of eavesdropping.

#3 was really the ultimate goal--strong security everywhere even with insecure
legacy protocols. The problem with legacy protocols is that they didn't all
contain a way to add a "STARTTLS" verb. So what we did was give tcpcrypt an
"Application-aware" bit that would allow out-of-band signaling that the
application knows about tcpcrypt. This bit would allow legacy application
maintainers to shoe-horn in stronger security in a completely backwards-
compatible way, and if the project really took off could then ultimately
disable the insecure old unauthenticated protocol.

Finally, #4 was handled by keeping session keys in the kernel (so they can't
leak in core-dumps, uninitialized data, buffer errors, etc.), and providing a
fresh session ID that can be authenticated even without a good source of
randomness.

As time went on, the performance argument (#1) became much less relevant, with
the result that tcpcrypt now uses ECC crypto instead of RSA. (Though the
batch-authentication optimization is still available.) However, #2 actually
became more relevant (at least in 2013), and #4 even more so with all these
catastrophic bugs (like heartbleed, or Debian disabling randomness in
OpenSSL). It's also still much, much harder than it should be to write
software that encrypts network traffic, particularly where one doesn't just
want the standard anonymous-client to server-with-X.509-certificate setup. If
people adopt tcpcrypt, setting up an authenticated, encrypted TCP connection
will become comparable to checking a unix password--just a few lines of code.

A lot of this is clearer if you read the companion TCP-ENO RFC, rather than
tcpcrypt. The goals and rationale and overall negotiation mechanism were
broken out into a separate document to allow better upgradability to future
encryption protocols:
[https://tools.ietf.org/html/rfc8547](https://tools.ietf.org/html/rfc8547)

------
jiveturkey
> In particular, tcpcrypt does not protect against active network attackers
> unless applications authenticate the session ID. If it can be established
> that the session IDs computed at each end of the connection match, then
> tcpcrypt guarantees that no man-in-the-middle attacks occurred unless the
> attacker has broken the underlying cryptographic primitives, e.g., Elliptic
> Curve Diffie-Hellman (ECDH).

What am I missing here? An active attacker will just terminate the connection
on both ends. There will be 2 authenticated session IDs at L3. At L7, how will
an application authenticate the L3 ID in such a way as to discover a MITM?
Even if it can, there needs to be a new ioctl (or similar) for the application
to learn the L3 ID. That's rough for the large legacy of applications that
might otherwise benefit from this.

I'm sure I'm missing it, since this has been 10 years in the making, authored
by well known folks. The referenced USENIX paper discusses how both ends of
the tcpcrypt connection can know there's no MITM. However, in the case of
intercept, the other end of the connection _is_ the MITM.

Because tcpcrypt uses ephemeral public keys, there's no L7 identity proof,
such as is offered by TLS (as far as it can). This further permits MITM.

An active attacker can also just strip the TCP-ENO bits from the SYN. If
[just] one side insists, the attacker can strip it just from the other side,
for performance.

~~~
nullc
They introduce a new IOCTL which you can use to discover the session id and
then authenticate it however you like.

In particular, it is possible to use a zero knowledge protocol where a MITM
attacker cannot determine if authentication were actually used or not except
via changes in user behavior if there are any. For protocols which have a
mixture of authed and non-authed usage, this can create a significant risk of
discovery for an active attacker.

In any case, authentication is inherently tied up with "identity" which is
significant UI and application specific considerations which simply do not
exist for ephemeral encryption. TCPcrypt achieves an appropriate layering
which separates these concerns while killing content observation by passive
attack and increasing the risk of detection otherwise.

Re: stripping, again-- how to handle the absence of encryption is also an
application relevant decision. TCPcrypt provides sufficient tools for
applications to set appropriate policies.

~~~
dagenix
> They introduce a new IOCTL which you can use to discover the session id and
> then authenticate it however you like.

> In particular, it is possible to use a zero knowledge protocol where a MITM
> attacker cannot determine if authentication were actually used or not except
> via changes in user behavior if there are any.

I'd love for you to expand more on this. What I can't think of is a realistic
scenario where it's possible to validate the session id in a secure way, but
there is also some reason that we couldn't just use TLS with client
certificates.

~~~
mazieres
> I'd love for you to expand more on this. What I can't think of is a
> realistic scenario where it's possible to validate the session id in a
> secure way, but there is also some reason that we couldn't just use TLS with
> client certificates.

An example would be if you don't have a certificate. Maybe you just have a
pre-shared secret or a kerberos ticket. Or worse, maybe you just have a
password, and so need to use a PAKE protocol or something to authenticate the
session. Or maybe you are using an RPC protocol, like NFS, that doesn't let
you add TLS in a backwards-compatible way, but where the client and server do
share some secret file handle.

~~~
dagenix
> An example would be if you don't have a certificate.

Given that letsencrypt exists, I don't see why you wouldn't have a cert.

> Maybe you just have a pre-shared secret or a kerberos ticket.

The pre-shared secret could be a cert which would work with TLS.

> Or worse, maybe you just have a password, and so need to use a PAKE protocol
> or something to authenticate the session.

I can't think of a realistic example of such a protocol. What protocol uses
PAKE, but doesn't support encryption, but will verify a session id? It seems
like using TLS would be simpler.

> Or maybe you are using an RPC protocol, like NFS, that doesn't let you add
> TLS in a backwards-compatible way, but where the client and server do share
> some secret file handle.

Such a scenario still requires modifications to the NFS server and client
software, which, if done, isn't clear why it would be better than just
layering TLS onto the protocol.

~~~
nullc
> Given that letsencrypt exists, I don't see why you wouldn't have a cert.

That makes an enormous number of assumptions-- that you have a domain name,
that you accept inbound connections, and that "gee some server connected to my
name and got me once" is a remotely acceptable criteria for identity in your
application.

------
dagenix
This seems to primarily only protect against passive listeners [1]. So, while
I guess this could be useful to transparently increase security of unencrypted
protocols, it seems like the use cases would be somewhat narrow and that TLS
over TCP and QUIC will continue to be much better solutions.

[1]. From Section 8: "... tcpcrypt does not protect against active network
attackers unless applications authenticate the session ID. If it can be
established that the session IDs computed at each end of the connection match,
then tcpcrypt guarantees that no man-in-the-middle attacks occurred ..."

~~~
nullc
In my view one of the most significant advances of TCPCrypt is setting
appropriate layering.

Past cryptographic network transports have committed the sin of layer
violation by conflating stream management with correspondent authentication.
Authenticating that you are talking to whom you think you're talking to is a
complex, highly application specific process which in many cases even requires
its own UI.

The code to implement authentication is complex and has (e.g. x509 parsing)
frequently been a source of vulnerabilities, making it unattractive for
implementation in network stacks. Witness the use of TLS for non-webby
applications where there aren't readily user provided domain names and things
don't fit nicely into a one-side-authenticated server/client model-- they
often turn into key management nightmares.

TCPcrypt handles the stream encryption and integrity in the network layer
where it can do so seamlessly. It hands up the stack the required hooks so
that authentication can be performed in whatever way makes sense for the
application. As a bonus, even when authentication isn't used applications are
protected against dragnet passive content surveillance.

~~~
tptacek
WireGuard authenticates traffic, using modern constructions, and its kernel
implementation is famously fewer than 5000 lines of code, and can be
implemented without dynamic allocation. Just because TLS is complicated
doesn't mean that cryptographic authentication is fundamentally difficult.
Watson Ladd once said, on the CFRG mailing list, that if TLS 1.1 had been
turned in as an undergraduate assignment, it would have gotten a D. (I'm
paraphrasing from memory).

~~~
nullc
> WireGuard authenticates traffic, using modern constructions

Assuming you know in advance of your connection a correct public key for the
corespondent. How you got it, how you know it's correct is ... left up to you.
Yet it isn't secure if its not done exactly right.

This is like arguing that a one time pad provides for unbreakable encryption.
True in one sense, often not true in practice.

------
3xblah
Is this the same "Tcpcrypt" that was called a "marketing stunt" in this
presentation?

[https://cr.yp.to/talks/2012.03.08-1/slides.pdf](https://cr.yp.to/talks/2012.03.08-1/slides.pdf)

~~~
otterley
It appears so:
[https://web.archive.org/web/20180810123522/http://tcpcrypt.o...](https://web.archive.org/web/20180810123522/http://tcpcrypt.org/)

------
zzo38computer
Tcpcrypt seem it would not be so bad idea, although then there will need some
way to configure it, such as a /etc/tcpcrypt file which you can specify what
keys to use, where to force tcpcrypt, where to disallow it, what to verify
certificates and so on. It can then be protocol independent and not have to
deal with individual programs to get it to work properly; you can configure a
program that does not understand tcpcrypt to use it, if the other end is also
configured to use tcpcrypt (either mandatorily or optionally, depending on
configuration).

------
adrianratnapala
The RFC is written by and for people who have already discussed in depth what
problem they are trying to solve. But little old I can't figure it out by
reading the text.

Can anyone enlighten me about what it's for? How does it fit in compared on
the one hand to TLS and on the other hand to things like WireGuard.

------
IloveHN84
Tcpcrypt + dnscrypt + https.. would it be too much overhead?

------
peterwwillis
The part about the middleboxes worries me more than mitm. If you're going to
have a custom protocol, just make a whole new protocol. No need to call it
"tcp-esque". We've already got quic, we just need to improve it and make it a
4th layer protocol. Give it a trendy name and make up some marketing BS about
how it revolutionizes the internet, and then let middlebox vendors use its
industry name to sell new gear. The special interests get rich and we get to
offload implementing custom protocols and crypto to the operating system, with
some glue to let the application do complex auth.

