25 comments

[ 4.4 ms ] story [ 71.1 ms ] thread
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 ..."

> This seems to primarily only protect against passive listeners [1].

Which is still useful in that it prevents organizations from simply 'tapping glass'.

I'll take the imperfect security of forcing various agencies to expend resources to go after me personally (which is a small chance of happening) versus the ease of them simply vacuuming up all the bits.

It's why I also think that unauthenticated encryption is useful even if it doesn't protect against active attacks: the extra resources needed for the active component forces the adversary to make choices on who to target.

> I'll take the imperfect security of forcing various agencies to expend resources to go after me personally (which is a small chance of happening) versus the ease of them simply vacuuming up all the bits.

On the one hand: protection against passive monitoring is a clear win. On the other hand, in my opinion, saying something like: "which is a small chance of happening" is kinda problematic: you don't need that security, and if some agency targeted you, like, maybe there is a minor chance of personal embarrassment. However, there are also people in the world that when they are targeted, they could face prison time or worse. And the people with the most to lose, are also the most likely to be targeted. So, IMO, it would be somewhat irresponsible to rely on tcpcrypt - it gives people that don't really need protection protection that they don't need, but leaves everyone that does out to dry.

The thing is - I just can't think of a use case where it makes sense. HTTP is often used with TLS - and TLS offers protection against active attackers. Many new protocols are based on HTTP - right or wrong, that generally means they get TLS with whatever library they use. DNS is moving toward DoT and DoH. SMTP has STARTTLS already which does the same thing. FTP has been replaced by SFTP / SCP. Telnet is replaced by SSH. Instant messaging protocols have built in security.

What protocol and who would actually benefit from this?

> What protocol and who would actually benefit from this?

The main promise IMO is providing transparent encryption to old applications and protocols that use TCP without their own encryption layer.

It is not possible to provide transparent authenticated encryption to everyone without some sort of CA system for IPs, but we should still provide the strongest privacy available by default, which is protection against passive eavesdropping.

That sounds like a reasonable goal, I'm just at a loss for what old applications or protocols will benefit. Many of those old applications get stuck running on old kernels which would prevent this type of change from helping them.
> What protocol and who would actually benefit from this?

All of them.

We could have encrypted HTTP back in 2000 if HTTP Upgrade had been more widely deployed:

* https://en.wikipedia.org/wiki/HTTP/1.1_Upgrade_header

How much of the stuff that the NSA (and others) did that Snowden exposed could have been made impossible, or at least more difficult, if there was more encrypted traffic to deal with?

Sure, there wouldn't have been little padlock icons, and active attacks could still be done, but it wouldn't have been as much wholesale surveillance.

Instead, between 2000 and (say) 2016—when Let's Encrypt/ACME went live—we had selective encryption only for 'important' sites where people thought it worth the cost/hassle of getting a cert and going HTTPS.

Even now, there are plenty of legacy HTTP-only sites: why not have an Apache module available that does opportunistic encryption, even if the end-user doesn't get a padlock icon.

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.

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).
You conveniently ignored the 30k LOC crypto framework.
> 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.

The thing is, you still need to validate the session id, if you want to know who you are talking to. And in order to do that, you probably need to do something like use x509 certs. And once you do that, you've basically re-arrived at the same layering issues that TLS has.

So, like, the protection against passive listeners is nice. But, what I don't understand is a specific example of where using tcpcrypt would be better than just using a widely used TLS library.

> 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.

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.

> 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.

> 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.

> 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.

> 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.

> 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.

TLS with client certificates requires securely getting and certifying the certificates. Somehow. Yet many alternatives exist.

For some applications keys might exist in dns-- but in others no dnssec or names could be assumed.

For some applications the endpoints can be assumed to have a shared password, so some SPAKE can be used to authenticate.

For some applications an identity exists in some external consensus system that the other side can provide proof from, but which doesn't fit into the x509 model. (For example, if you wanted to use keys registered in namecoin to authenticate your identity).

For some applications you would like to use an anonymous group signature: "This user is on the authorized list, but beyond that, I don't want to know what user this is."

For some applications each party should be cryptographically unidentified, anonymous, and indistinguishable to from any other party unless both of their keys match, because otherwise you could track the parties around the internet from IP to IP. TLS/client cert lets you achieve this for one side-- you can decline to send the client cert if the server identity isn't to your liking, but you can track the server's identity around.

None of these examples fit nicely into the TLS/x509 model. All of them, including something functionally equivalent to TLS+x509clientcerts can be implemented on top of TCPcrypt.

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.
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.

Tcpcrypt + dnscrypt + https.. would it be too much overhead?
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....

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...

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).