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

Eric Rescorla <> Tue, 25 August 2015 16:47 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id 5FA801A033B for <>; Tue, 25 Aug 2015 09:47:01 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: 0.923
X-Spam-Status: No, score=0.923 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, J_CHICKENPOX_31=0.6, MANGLED_BACK=2.3, RCVD_IN_DNSWL_LOW=-0.7] autolearn=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 49XWS558TPDs for <>; Tue, 25 Aug 2015 09:46:57 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id CE5DD1A7000 for <>; Tue, 25 Aug 2015 09:46:18 -0700 (PDT)
Received: by vkfi73 with SMTP id i73so76648086vkf.2 for <>; Tue, 25 Aug 2015 09:46:18 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=KndrHP2aociJCmw7+fFj73Qqld6TYdvoh9jb10Ny0yQ=; b=SdKQ+wi9LxUEcsnxkyG89C5vdmpN0h5jr8pZcYwkcL0Wd1dekgaEKyY/ahNgrkdg81 RWFhWyhMhyiN4Bj27fwMsxSaH2IyLn9CL7dpub5qgU18HxaaIiVHoPGBQZ60j8hJzUve 33OpnmNw+OyvJRqbdUR/kuqGFxl7DYft7c7e6shV5zZikAJd3+fBUO5zUEzjF3SMdZJ+ SWwGKriXh5l0CYa3L9elrs1kkGrvPR/mTCMwODhJt+bIiox99uOW8MEkAaGHu0GzUhkU MpNIHaBd7cWBi6zV6ahOGPNMa0aNUi45hiQyK4f25jSXjX0zTDJ2tIJFFwXS4UL+Azvq exrw==
X-Gm-Message-State: ALoCoQlFxow4zwYG3FLHWzBkea0W+0VTx//8lF4maAx8sJ5SOMuGiDQjeiGrOwY+zna7hT2kKX3P
X-Received: by with SMTP id n8mr39503335vdw.20.1440521177953; Tue, 25 Aug 2015 09:46:17 -0700 (PDT)
MIME-Version: 1.0
Received: by with HTTP; Tue, 25 Aug 2015 09:45:38 -0700 (PDT)
In-Reply-To: <>
References: <> <> <> <>
From: Eric Rescorla <>
Date: Tue, 25 Aug 2015 09:45:38 -0700
Message-ID: <>
To: David Mazieres <>
Content-Type: multipart/alternative; boundary="bcaec501c5941a8d31051e2579c8"
Archived-At: <>
Cc: tcpinc <>
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: Tue, 25 Aug 2015 16:47:01 -0000

On Sun, Aug 23, 2015 at 9:26 AM, David Mazieres <> wrote:

> Eric Rescorla <> writes:
> > But, as I note, at the cost of a byte if you *ever* want to have >1. My
> > experience
> > is that things get more complicated, rather than less.
> Well, I'd say TCP's experience is that option space gets more precious,
> not less.  I think the most common case is going to be that the SYN
> proposes a bunch of one-byte suboptions and the SYN-ACK contains a
> single suboption that is either one byte or variable length.  That's
> what TCP-ENO is optimized for.
> The "things get more complicated" argument is valid because software
> doesn't typically have weight-and-balance-style restrictions like
> aircraft.  Yet the 40-byte option limit is just such a hard limit.
> Anyway, I'm not sure we can usefully debate this point without more
> data, so maybe this question should be deferred until later in the
> process?

The usual way to handle this is with an [[OPEN ISSUE]] marker.

> > 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.
> >
> >
> > I think it's a general issue of protocol hygiene, but with that said,
> this
> > would allow you to have an optional long tiebreaker for NAT penetration.
> That's too general to convince me.

A totally reasonable standard for an individual submission. Less so for a WG
document, which I understand you would like this to be.

> > bit to 1 at the endpoint with the lowest (public-IP-address,
> >> public-port-number) pair.
> >
> >
> > As you say elsewhere, this is common in cases of NAT penetration and
> > generally in NAT penetration cases you don't know your IP address
> > with certainty. For instance, say we have two devices with apparent
> > addresses:
> >
> > A: (host), (srflx)
> > B: (host), (srflx).
> >
> > Which one has the lower IP address?
> Well, assuming the RFC5737 addresses are publicly routable, obviously B
> has a lower IP address.

OK, that was what I was expecting you to say, but unfortunately the
isn't always so simple. Consider what happens from A's perspective if
he is doing trickle ICE and assume for simplicity that B is non-NATed so
he just has the address.

A        Signaling        B        STUN

STUN Check ------------------------->
Host Cand ---->
              Host Cand -->
              <-- Candidate
<--- Candidate
SYN -------------------------------->   X
<---------------------- STUN Response

At the point when A sends his first SYN (labelled X) he knows his host
( and B's srflx ( so he thinks his address is lower.
after he gets the STUN response from the server, he learns his srflx and
that it's higher than B's (note: in ICE you do only one check from both
the srflx and the host candidates).

There may be some way to resolve this, but it's not clear to me that in
it will be possible, and it's not clear to me in any case how the "b" bit

If the simultaneous open is happening in any kind of application, the
> two sides will need to use STUN or some other service to figure out
> their public IP addresses and determine that they are behind the
> appropriate kind of NAT.

ICE actually does the combinatoric explosion of all the IP address
pairs, not NAT characterization.

> > In the case where that was worked out most carefully at IETF (RFC 5245),
> > a much larger tiebreaker is used.
> RFC5245 uses an 8-byte tie-breaker.  So to put our options in a table:
>                    +--------------+--------------+-------------+
>                    |              | application- |   option    |
>                    |  works ever  | transparent  |   space     |
> +------------------+--------------+--------------+-------------+
> |drop simultaneous |      no      |      no      |      0      |
> |open support      |              |              |             |
> +------------------+--------------+--------------+-------------+
> |TCP-ENO draft     |     yes      |      no*     |  0 / 1 bit  |
> +------------------+--------------+--------------+-------------+
> |TCP-use-TLS       |     yes      |      no*     | 0 / 48 bits |
> +------------------+--------------+--------------+-------------+
> |always-on RFC5245 |     yes      |     yes      |   48 bits** |
> +------------------+--------------+--------------+-------------+
> *TCP-ENO requires applications to break the tie, while TCP-use-TLS only
>  requires applications to set a single bit indicating they are about to
>  engage in a simultaneous open.
> **RFC5245 uses 64 bits, but TCP-use-TLS shows you can do the same thing
>   with only 48 bits.

Well, 48 versus 64 is just a matter of statistics. I.e., how many failures
are you willing to accept with simultaneous open? To be honest, 32 bits
is probably enough.

> > 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.
> >
> >
> > This would be more convincing if you provided an example where it
> > actually added value. In the case you suggest above, where the sides
> > are independently able to break the symmetry, why not simply do so
> > via signaling?
> I'm not sure I know what you mean about signaling.

What I mean is that whatever mechanism you used to determine who should
set the 'b' bit seems like it could just as easily determine which side
adopt the initiator versus responder role.

> But suppose two
> hosts are behind NATs and an application cannot use TCP between the two
> hosts except through simultaneous open.  Here are three realistic
> scenarios in which applications can easily be modified to break the
> symmetry.  Again, this isn't transparent, but it's not a huge burden,
> either:
>   * The applications use STUN to learn their public IP address and NAT
>     type and communicate this to the other node or register it with a
>     public rendezvous service.  The applications can then set b based on
>     the public IP addresses and ports as previously discussed.

If you're using a rendezvous service like this, you can just put a
tiebreaker in
those messages, no?

  * The applications are part of a DHT in which each node has a unique
>     node ID.  In this case, the application can set b based on lowest
>     node ID.
>   * The simultaneous open is triggered by some external broker service
>     that sends a message to both hosts, in which case the broker can
>     assign the b bit to the two sides.

I don't understand why the 'b' bit is adding any value in this case, since
each side actually knows in advance which side will be assuming the
initiator role. Why not simply just tell the stack "adopt this role for this
connection regardless of simultaneous open"

>> > 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.
> >
> >
> > These seem like an argument for having the passive opener supply one
> > in the SYN/ACK, not for having the active opener supply one in his first
> > ACK.
> Neither of the two examples I made will work if you do not require ENO
> in the first ACK from each side (including the active opener--obviously
> the SYN-ACK includes an ENO option).  To see this for my point #1 above,
> let's look at the example from Figure 7:
>         (1) A -> B:  SYN      ENO<X,Y>
>         (2) B -> A:  SYN-ACK  ENO<X>    [ENO stripped by middlebox]
>         (3) A -> B:  ACK
> Now suppose B is not expecting an ENO option on flow 3.  B will enable
> encryption, while A will not, and the whole TCP connection will fail
> (not just fail to encrypt).  That's very bad.

All right. I'm willing to concede this point.

To see this for #2, imagine Y is a variable-length suboption:
>         (1) A -> B:  SYN      ENO<X,Y>
>         (2) B -> A:  SYN-ACK  ENO<Y 123>
>         (3) A -> B:  ACK                [A does not like parameter 123]
> Here B chooses some sort of parameter 123 that A does not support.  123
> might be a bitmask of B's supported public key ciphers, and the
> designated set might not intersect with A's.  In TCP-ENO, A disables
> encryption by not sending an ENO option in its ACK.  However, if B does
> not expect the ENO option, B will already have committed to spec Y
> encryption after flow 2 and again the whole TCP connection will fail.

I don't find this convincing. Better to make the application protocol fall

> > Consider the version in the TCP-use-TLS draft where in the case of
> > simultaneous
> > open you have a large tiebreaker in both the SYN and the SYN/ACK. In that
> > case, it's quite straightforward to determine who is is who. In that
> case,
> > you
> > can negotiate as I indicate above.
> I understand how TCP-use-TLS does this, but at this point we are going
> around in circles.  Ultimately this comes down to a question of
> subjective design priorities.  I'd like to hear how you and other
> working group members answer the following two questions a scale of 1 to
> 10:
>    A. How much do you care about conserving TCP option space?
>    B. How much do you care about simultaneous open.
> For me, I'd rate A a 9/10 and rate B a 5/10, which is why TCP-ENO looks
> the way it does.

I think there's a 'C'. How much do you care about preserving option space
*in* simultaneous open? And the answer for me is "not much".

> > I've read the charter, but I don't think it's actually that clear here.
> It's
> > obvious that tcpinc doesn't supply PFS if you have a long-running
> > connection and never re-key, so I think the question is what the
> > desired properties are between connections. This language doesn't
> > actually seem particularly helpful on this point. In any case, if
> > part of the point of TCP-ENO is to allow for negotiating protocols
> > defined outside of TCPINC, then this seems like an unnecessary
> > restriction (as, in fact, do the rest of these).
> Again, please don't confuse things by mentioning PFS, which is required
> by neither the charter nor the TCP-ENO draft.  The charter contains the
> following language:
>         When encryption is enabled, then the protocol:
>         - must always provide forward secrecy.
> This is verbatim, no ellipsis or anything.  Seems pretty clear to me.

As I said, I don't think it's particularly dispositive with regard to the
I made above about the relationship of forward secrecy to long-running

The TCP-ENO draft contains the following language:
>    o  Specs MUST NOT allow the negotiation of encryption modes that do
>       not provide forward secrecy.
> I do not favor amending the charter to weaken confidentiality, but that
> is a debate we can have.  However, given the current charter, it seems
> beyond debate that TCP-ENO should ensure the same basic security
> properties as TCPINC.

It doesn't seem even obvious to me, let alone beyond debate.

>> 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.
> >
> >
> > Can you unpack this some?
> Let's say that we can compute two transcripts, A and B, such that
> SHA-256(A) == KECCAK-256(B).  This doesn't violate any standard
> cryptographic assumptions.  Yet without the tag byte, it would be
> devastating to TCP-ENO's security in the event that different specs use
> different hash functions.

Given that I would expect specs to have hash agility, it seems like if we
in fact have this situation, we have a fairly serious problem, and it's
unfortunate that "standard" assumptions don't capture that.