
UDP co-creator on UDP (and NSA killing end-to-end encryption in TCP) - justsee
http://www.reed.com/blog-dpr/?page_id=6
======
pmjordan
While it's _interesting_ that the NSA blocked encryption in TCP, I'm not
convinced it would have been a good idea to do it at that level in practice.
Encryption has moved on quite a lot since then (at the very least due to
Moore's law holding for all that time). Changing the TCP stack (typically in
the kernel) every time encryption moves forward would probably be worse than
the current situation of using SSL/TLS. TCP itself has held up pretty well all
these years; SCTP and such seem to have had zero impact on its popularity.
(not that I'm an expert on either networking or encryption)

~~~
tptacek
SSL/TLS has gone through numerous revisions, many of them after painful flaws,
and was seen at the time it was created as a relatively cutting-edge design
--- particularly vis a vis negotiation and flexibility. There is no chance
encryption baked into TCP would have survived. How would you even key it? This
story seems a bit apocryphal. I'm sure someone had it on a whiteboard
somewhere, but...

~~~
gxti
You could use a Diffie-Hellman exchange to get a shared secret so things are
"obscured by default" but not trusted, then let higher layers deal with trust
validation. For example, the TLS certificate handshake could just be a matter
of constructing a blob containing the two endpoints' DH public keys and
signing it to prove that a man-in-the-middle hasn't intercepted the channel.
All the actual encryption would be handled by the IP stack and offloaded to
hardware, while the application-layer TLS bits would be used once at startup
(and maybe subsequently if the lower layer re-keys) then get out of the way.

Key and cipher negotiation could easily be shoehorned into the three-way-
handshake already used to establish connections. AES with a CTR block mode
would be the obvious cipher choice since each packet would be handled
separately. With TCP you could even just use the sequence number as the
counter, although this would be harder at the IP layer.

But yeah, none of this would have been available at the time. Still, given
today's technology it would not be difficult to future-proof, especially if
the trust machinery is left to the application.

~~~
tptacek
Everything about this comment is horrifying.

Start with AES-CTR (which wouldn't have been an option in 1979; counter mode
hadn't been invented): you can't use TCP sequence numbers as counters; among
other things, multiple segments can be sent with the same sequence number, and
while the byte described at the stream offset of those sequence number
(usually, but not always) agrees with every other packet, no other guarantee
exists about the nature of those segments. Reuse of a counter in CTR mode is a
devastating flaw.

Running DH over an unsecured connection with no previous trust anchor is also
a recipe for disaster; attackers don't even need a fully-functioning man-in-
the-middle to break it; they just need to be able to inject two segments, one
in each direction, to fixate the derived key.

Everything else you propose to layer on top of this DH + AES-CTR connection is
handwaving; if you have to run "application-layer" TLS, what's the value of
hardcoding (broken) crypto into the TCP layer?

Sorry for the rabid response to a well-intentioned comment, but wow I couldn't
disagree with you more strongly.

------
tptacek
Thrilled to have an authoritative source for the silliness of the URG pointer
in TCP; now I can point people who think it has some value to the post that
says it's a vestigial organ from when protocols needed to accomodate old
teletypes.

Startled to see him say that the Internet should have been loose source-routed
by default. I see the end-to-end argument in favor of it (it would have made
it possible for software developers to override and theoretically improve
global routing), but LSRR would have had far-reaching consequences --- for
instance, all IP traffic would be trivially spoofable bidirectionally; also,
it might have played havoc with CDNs.

Reed's paper "The End To End Argument In System Design" is required reading
for pretty much everybody.

------
davidj
whats really weird is that at last years Defcon Dan Kaminsky did a demo
showing that DNS lookups were actually faster in TCP than UDP. His explanation
of why: "... and I have no idea."

~~~
tptacek
No, they aren't. TCP DNS is 10-20ms slower than UDP DNS against large DNS
servers, and probably much worse against slower DNS servers.

I don't know what Dan did to generate this result, but whatever it was, it
appears to have been wrong.

(Heading off a silly argument: the test I just did to confirm this did _not_
make new connections for each query; the 3WH was amortized over all the
requests).

~~~
tptacek
Here's the inevitable Twitter cripple-fight between me and Dan:

<http://bettween.com/tqbf/dakami/Jan-03-2011/Jan-04-2011/desc>

Here's what I think happened:

* Dan wrote this DNS proxy thing for DNSSEC (which, don't use DNSSEC, it's evil) called "phreebird".

* Phreebird uses libevent, which tends to produce zippy fast servers, so Dan benchmarked it and found TCP was faster than UDP.

* But Dan made a bunch of mistakes with libevent and, in fairness, BSD sockets in general; in particular, he only events the read side of the conversation --- his writes block. Since the socket buffers on the TCP side are spread out across a bunch of sockets, and there's only one UDP socket buffer, the UDP socket blocks a lot.

Dan says that when he says TCP is "faster", he means "it gets better
throughput, even though it may not get better latency". Now, I think "latency
vs. throughput" is a refuge for scoundrel arguments, but just to make sure, I
checked, and if you wail on Google DNS with a TCP connection, you _cannot_ in
fact clear 1000 queries faster than if you firehose it with UDP. This just
makes sense, since TCP has congestion control overhead and strict in-order
delivery and UDP doesn't.

