Re: [tcpinc] Review of draft-bittau-tcpinc-tcpeno-01

David Mazieres <> Sun, 23 August 2015 05:13 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id AE42F1AC399 for <>; Sat, 22 Aug 2015 22:13:35 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: 4.09
X-Spam-Level: ****
X-Spam-Status: No, score=4.09 tagged_above=-999 required=5 tests=[BAYES_50=0.8, HK_RANDOM_ENVFROM=0.001, HK_RANDOM_FROM=1, MANGLED_BACK=2.3, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id ocKhk0gBArPn for <>; Sat, 22 Aug 2015 22:13:34 -0700 (PDT)
Received: from ( [IPv6:2001:470:806d:1::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 031E61AC398 for <>; Sat, 22 Aug 2015 22:13:33 -0700 (PDT)
Received: from ( []) by (8.14.7/8.14.7) with ESMTP id t7N5DXC7027163; Sat, 22 Aug 2015 22:13:33 -0700 (PDT)
Received: (from dm@localhost) by (8.14.7/8.14.7/Submit) id t7N5DWLb005912; Sat, 22 Aug 2015 22:13:32 -0700 (PDT)
X-Authentication-Warning: dm set sender to using -f
From: David Mazieres <>
To: Eric Rescorla <>, tcpinc <>
In-Reply-To: <>
References: <>
Date: Sat, 22 Aug 2015 22:13:32 -0700
Message-ID: <>
MIME-Version: 1.0
Content-Type: text/plain
Archived-At: <>
Subject: Re: [tcpinc] Review of draft-bittau-tcpinc-tcpeno-01
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: "Discussion list for adding encryption to TCP." <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Sun, 23 Aug 2015 05:13:35 -0000

Eric Rescorla <> writes:

> Review of draft-bittau-tcpinc-tcpeno-01
> I have reviewed the -01 version of the ENO draft. This seems like a good
> general idea, but I have concerns about a number of the details.

Thanks for going through in detail.  I will respond point-by-point.

> S 3.0.
> The variable/non-variable encoding seems suboptimal and in particular
> the restriction that only one suboption can be variable length. What
> are we going to do if two specifications wish to have variable-length
> data in the SYN packets? The specification suggests that you should
> address this by having two ENO options but that seems clumsy.
> I would suggest instead that if the v bit is set the next byte be the
> length. This comes at the cost of one byte for settings where there is
> only one variable-length option but is more efficient when you
> want to have multiple variable-length options, since you don't need
> to repeat the kind byte.

Our intent is to optimize for a future in which people only need one
variable-length option.  For example, the SYN can list a bunch of
options, and then the SYN-ACK can pick one of them.  The current design
saves one byte, which may be quite important.  For instance, you can
just barely fit a P-256 or Curve25519 DH key exchange in TCP options
currently.  If TCPINC is wildly successful, we can imagine a future spec
that does that and squeezes the 8 most popular SYN options into a single
byte or something.  But if we waste even one more byte of option space,
we start closing a lot of doors along that front.

That said, if you can provide an explicit example of why you might want
multiple variable-length suboptions, you could possibly convince us to
optimize for that case.

> S 3.1.
> I am not convinced that a one-bit tiebreaker for simultaneous open
> is going to work. Experience with other protocols that have the
> problem of symmetry (e.g., ICE) is that this sort of thing results
> from confusion about which side is really "first". In that case,
> both sides will try to set the same "b" bit, and you will not break
> the symmetry.
> I believe we must either ignore simultaneous open or use a higher-
> entropy tiebreaker.

A high-level question is whether we should completely abandon enabling
TCP?INC for simultaneous open.  If we allow encryption under some
circumstances after simultaneous open, then the next question is how to
apportion responsibility for making it work.  The high-entropy solution
says make it work with high probability, but at the cost of a lot more
option space.  Since simultaneous open is kind of finicky anyway,
TCP-ENO took the approach of making applications responsible for working
out the roles.  For example, one plausible approach is to set the 'b'
bit to 1 at the endpoint with the lowest (public-IP-address,
public-port-number) pair.  That's obviously not information available to
TCP-ENO, which knows nothing of NATS, but is information available to an
application using STUN to broker simultaneous open.  Perhaps we should
work out an example of simultaneous open in the API document.

As it is, the b bit is an effort to find the knee in the cost-benefit
curve.  I.e., is it worth 4+ bytes of option space to make
simultaneous open work?  Hard to make that case.  But is it worth one
*bit* not to shut the door completely?  Quite possibly.

> S 3.2.
> I am unclear on why the active opener needs to have an ENO segment
> in his first ACK. Can you explain?

There are two reasons:

1. Given the prevalence of asymmetric routes, it's highly likely that
   situations will arise where ENO options are stripped in one
   direction but not the other.  Therefore, both sides need to know
   not only that the other endpoint supports ENO, but that the other
   endpoint can receive ENO options.  If you remove the requirement
   for that ACK, a scenario such as Figure 7 would result in total
   failure of the TCP connection, not just failure to encrypt.  We
   definitely want to avoid that.

2. Suboption data could involve parameters that are not universally
   supported, in which case the active opener may which to disable
   TCPINC based on the contents of the SYN-ACK segment.

> This mechanism for negotiating mechanisms seems over-complex, what
> with A and B each providing lists and then choosing B's top
> preference.  I would suggest instead that we simply have B choose out
> of A's list, as with ALPN. The document offers two reasons why this
> might not work, simultaneous open and inflexible implementations: If
> we resolve simultaneous open in the SYN exchange then this should work
> fine and the issue of implementation seems like a corner case.

If by resolve simultaneous open you mean not support it, I agree.  But
if you mean something else, then things can get tricky.  I would
welcome a detailed design that works, but just saying "do something
like ALPN" is not enough detail to determine whether or not that
approach is viable.  We'd need to see an "A -> B: ... B -> A: ..."-
style example with TCP flags.

One big challenge of simultaneous open is that each side must
acknowledge the other side's SYN before seeing the other side's SYN-ACK.
Moreover, other than the SYN, you can't consume TCP sequence numbers
until you have definitively enabled or disabled TCPINC (and in the
former case negotiated an encryption spec).  So whereas in a three-way
hand-shake, you can do:

   A -> B:  SYN     X
   B -> A:  SYN-ACK X' which depends on X
   A -> B:  ACK     X'' which depends on X and X' and might disable TCPINC

With simultaneous open, you have two pairs of messages sent in parallel:

   A -> B:  SYN X
   B -> A:  SYN Y

   A -> B:  SYN-ACK X' which depends on X and Y, but not X' or Y'
   B -> A:  SYN-ACK Y' which depends on X and Y, but not X' or Y'

So in particular B does not have the opportunity to abort TCPINC in
response to X', but must decide it based on X and Y.  That's why TCP-ENO
determines the spec based only on the first ENO option sent by each

As for inflexible implementations, I actually thought you would like
that, as it means even if TCPINC ends up not exactly using TLS,
library-level TLS implementations could still potentially someday use
TCP-ENO.  We're much more likely to see something like TCPENO_RAW added
to operating systems than to get an upcall API that allows libraries to
compute SYN-ACK options in response to SYN segments.  That said, the
tcpcrypt team is not particularly keen on library-level implementations;
I could easily see removing this feature given a way to address (or a
decision not to address) simultaneous open.

> S 3.3.
> Having two different "application aware" code points (10 and 01) seems
> like it's asking for trouble. I would make one of these reserved.

That seems fair enough.  Maybe reserved in the sense of should not send,
but should still accept and consider compatible with 11.

> S 4.
> I understand the desire to require a minimum cipher length, but I
> would observe that read strictly, "128-bit security" excludes
> Curve25519 and also would exclude AES if any real analytical progress
> is ever made and it becomes secure at (say) 127 bits.

That's a fair point.  We definitely need to say something to rule out
another 40-bit encryption fiasco, but saying "128-bit" security is
probably too specific.  Any suggested wording?

> I'd like to see more clarity around forbidding encryption modes that
> don't supply PFS. For instance, with TLS a common strategy for
> optimizing session resumption is for the client to send the server
> a traffic key encrypted under the server's master key, thus allowing
> the server to be stateless (RFC 5077 Session Tickets). Would this
> be forbidden?

The draft does not mention PFS, only [non-perfect] forward security.  In
this regard, TCP-ENO is just echoing the requirements of the working
group charter.  I happen to think the charter is fine.  If you don't,
then we should separately discuss re-chartering.  Either way, it is
appropriate for ENO to follow the charter on this point.

> S 4.1.
> Given that session IDs are required to be unique, why bother with the
> spec-id prefix?

Precisely to guarantee this uniqueness.  If one spec uses SHA-256 for
session IDs and another uses Keccak, no standard cryptographic
assumption implies uniqueness without that tag byte.

> Instead of describing this as a negotiation between "specs" I would
> describe it as a negotiation between "protocols".

I agree that "spec" is a bit of a weird term, deliberately chosen to be
different from other terms like protocol and cipher suite.  Protocol is
also somewhat inaccurate, because we're selecting a modification of an
existing protocol (TCP), not an entirely new protocol.  I don't feel
super strongly about this.

> I would use the terminology "initiator" and "responder" rather than
> A and B. This matches IKE and is generally more familiar.

If we junk simultaneous open, then we should go with active/passive
opener as the terms, since TCP already has those terms.  Otherwise,
maybe initiator and responder, though that might not be any more clear.
In an earlier draft, we used the terms "virtual active opener" and
"virtual passive opener", to indicate the indented relationship to TCP
while also leaving room to switch things up under simultaneous open.
But from our small sample size, that seemed to confuse people even more,
after which we just decided to introduce terms ("A" and "B") that
deliberately didn't try to leverage (potentially misleading) intuition.
So that's how we ended up there, but again, I don't feel super strongly
about it.

> "Session ID" is a technical term in TLS that means something different
> than here. Perhaps "channel binding" or "channel identifier"?

How about just "Channel ID"?