Subject: [TLS] three ECHO issues

From: Stephen Farrell <[email-masked]>
Date: Sun, 8 Mar 2020 15:18:17 +0000

Hiya,

Thanks for the new ECHO PR. [1] I think this is the
right direction but I have three issues with how it's
done in the PR right now that I think would benefit
from list discussion before a new I-D is produced or
the PR is merged.

1) Padding. This should be easy but somehow seems to be
hard;-( ISTM the current text is broken as it'd expose
length information about ALPN in the CH and also in the
EncryptedExtensions. I think it'd be good if the list
reached some level of agreement on the goals of padding
here rather than keep making different tweaks that don't
work. I think the goal for padding ought be that we
don't expose information about the content of the inner
CH via the length of any h/s message. If we agree that
(or some similar thing) then hopefully it should be just
a matter of tweaking the algorithm so it works. (I've
raised this before but seemingly not convincingly enough;-)

2) Variance between inner and outer CH. The current
scheme is that almost any variation is allowed. In the
work I've done so far looking at how to code that up,
the trial decryption required becomes a major pain in
the client code as soon as the TLS key-share differs
between inner and outer. I don't know if that affects
other code bases or if that's mostly an OpenSSL thing
but think we ought establish on the list if that level
of flexibility is needed now, or maybe later, or even
never. The cost there is not just working out how to
code it up, but this also creates new complex code
paths that will be rarely executed which is usually a
recipe for sadness later. So, I'd hope other code
bases are checked for this before we merge the PR.
(The problem here could be OpenSSL's internal, eh...
"intricacy" is a polite term I guess, or it could be
me being dim, but it seems real;-)

3) I think we might be better off leaving out the
compression stuff for now, and only figuring that out
later. The current OuterExtensions thing is pretty ugly,
and if the result of (2) above were that we constrain
the variance between inner and outer some more then
a generic compression scheme may not be needed. I do
think we will want some compression thing in the RFC
we end up with, but we might be better off to get
interop without that first and then add compression
later. (That's what I plan to do fwiw, so this is
a less pressing issue for me given I'll be ignoring
it for now:-)

Cheers,
S.

[1] https://github.com/tlswg/draft-ietf-tls-esni/pull/207/files

---

From: "Christopher Wood" <[email-masked]>
Date: Sun, 08 Mar 2020 09:07:19 -0700

Thanks for raising these issues! Please see inline below.

> raised this before but seemingly not convincingly enough;-)

We kept maximum_name_length so as to not change “too much” in the 
PR. As this is orthogonal to the overall change, it can be addressed 
separately. Can you please file an issue and propose text?

> me being dim, but it seems real;-)

Yes, this will be a pain to implement. But variance between the inner 
and outer CH is permitted, and indeed a goal.

> a less pressing issue for me given I'll be ignoring

Can you elaborate on why it’s ugly? What could we do differently? Text 
suggestions are welcome!

Thanks,
Chris

---

From: Stephen Farrell <[email-masked]>
Date: Sun, 8 Mar 2020 17:14:23 +0000

Hiya,

On 08/03/2020 16:07, Christopher Wood wrote:
>> Thanks for the new ECHO PR. [1] I think this is the right direction
>> but I have three issues with how it's done in the PR right now that
>> I think would benefit from list discussion before a new I-D is
>> produced or the PR is merged.
>> 
>> 1) Padding. This should be easy but somehow seems to be hard;-(
>> ISTM the current text is broken as it'd expose length information
>> about ALPN in the CH and also in the EncryptedExtensions. I think
>> it'd be good if the list reached some level of agreement on the
>> goals of padding here rather than keep making different tweaks that
>> don't work. I think the goal for padding ought be that we don't
>> expose information about the content of the inner CH via the length
>> of any h/s message. If we agree that (or some similar thing) then
>> hopefully it should be just a matter of tweaking the algorithm so
>> it works. (I've raised this before but seemingly not convincingly
>> enough;-)
> 
> We kept maximum_name_length so as to not change “too much” in the PR.
> As this is orthogonal to the overall change, it can be addressed 

Sure. But ECHO vs. ESNI does make a difference here e.g.
due to the ALPN in the inner. If the outcome of (2) below
is to keep the flexibility they may be other extensions
that create length issues, either just in the inner CH
or else there and possibly also in other bits of the h/s.

That said, if the goal I stated above is something on
which everyone's agreed, I'd be happy to craft a PR. But
if that goal is not agreed, then probably any PR I make
won't be useful, hence raising this on the list.

>> 2) Variance between inner and outer CH. The current scheme is that
>> almost any variation is allowed. In the work I've done so far
>> looking at how to code that up, the trial decryption required
>> becomes a major pain in the client code as soon as the TLS
>> key-share differs between inner and outer. I don't know if that
>> affects other code bases or if that's mostly an OpenSSL thing but
>> think we ought establish on the list if that level of flexibility
>> is needed now, or maybe later, or even never. The cost there is not
>> just working out how to code it up, but this also creates new
>> complex code paths that will be rarely executed which is usually a 
>> recipe for sadness later. So, I'd hope other code bases are checked
>> for this before we merge the PR. (The problem here could be
>> OpenSSL's internal, eh... "intricacy" is a polite term I guess, or
>> it could be me being dim, but it seems real;-)
> 
> Yes, this will be a pain to implement. But variance between the
> inner and outer CH is permitted, and indeed a goal.

I'm questioning whether that's a good goal or not. In my
analysis of the various extensions, only SNI and ALPN seem
to offer immediate value. Until one gets to new algos,
which may mean PQC, there doesn't seem much more that's
worth supporting really. And when one looks at the level
of complexity to implement generic variance, I'm really
not sure it's worthwhile. That said, I'd hack away at
it as needed if others have taken a look at their code
and found it ok to support. I've just not heard that so
far and am concerned we're trading v, simple text in
the I-D vs. really horribly complex and maybe flakey
code, which doesn't seem like a good plan to me.

Just to be clear: I do like the idea that the analysis
be done on the flexible/full-variance scheme and I also
like the idea of reconstructing a full CH from the
recovered plaintext of the inner CH. Even with all
that though, the ECHO spec can still impose interop
restrictions on inner/outer CH variance to simplify
implementation and make interop easier and more likely.
My guess is that that'd be a worthwhile simplification.

If more variation is needed later (e.g. to help
incremental deployment of PQC algs), then that could
just use a new extension instead of ECHO.

> 
>> 3) I think we might be better off leaving out the compression stuff
>> for now, and only figuring that out later. The current
>> OuterExtensions thing is pretty ugly, and if the result of (2)
>> above were that we constrain the variance between inner and outer
>> some more then a generic compression scheme may not be needed. I
>> do think we will want some compression thing in the RFC we end up
>> with, but we might be better off to get interop without that first
>> and then add compression later. (That's what I plan to do fwiw, so
>> this is a less pressing issue for me given I'll be ignoring it for
>> now:-)
> 
> Can you elaborate on why it’s ugly? 

Allowing more than 1 OuterExtensions - that'd break some
code in OpenSSL's generic extension handling. Not sure
how bad that'll be to handle.

> What could we do differently?

If e.g. we required the same TLS key-share in inner and
outer, then you could just omit most of the octets from
the inner and deterministically reconstruct. With a small
number of such MUSTs, there might be no real need for a
generic compression scheme at all. That's linked to (2)
above though.

If a generic compression is needed, then yes something
ugly will likely be needed, but it could be simple and
ugly, e.g. extension-specific, for those extensions that
would make a difference. (And maybe we could punt on it
too - e.g. require the definition of the PQC stuff to
spec this compression if that's when it actually gets
useful.)

> Text suggestions are welcome!

Sure. And happy to offer some, but would like to see
guidance from the WG on the mailing list first. (Sorry
for being less github-cooperative about this, but being
logged in there is not my normal state of being:-)

Cheers,
S.

> Thanks, Chris

---

From: "Christopher Wood" <[email-masked]>
Date: Sun, 08 Mar 2020 10:25:25 -0700

On 8 Mar 2020, at 10:14, Stephen Farrell wrote:

>> PR.

In general I think it’s a fine goal, but I think it’s probably a bit 
more challenging to specify this correctly than we might think. Take 
ALPN as an example. Servers can’t possibly know what ALPN tokens each 
client might offer up in their CH, so how can they express a maximum 
limit?

> My guess is that that'd be a worthwhile simplification.

Yep, it can, and that’s something we can tighten down as needed later 
on. For example, if we later decide that we never want to duplicate key 
shares, we can just make that so. For now, starting general aligns with 
the analysis and gives us the flexibility we need to further refine as 
needed.

> how bad that'll be to handle.

Whoops! Good catch. We should remove this paragraph:

Multiple "outer_extension" extensions MAY appear in a ClientHelloInner
(this is a violation of normal TLS rules, but the resulting 
ClientHelloInner
is never processed directly). However, there MUST NOT be
multiple "outer_extension" extensions with the same extension code 
point.

That’s leftover from a previous version. I’ll do that now.

> spec this compression if that's when it actually gets

That might work, too. For now, I’d prefer we not get bogged down in 
compression as it’s merely an optimization.

> logged in there is not my normal state of being:-)

No problem. :-)

Cheers,
Chris

---

From: Stephen Farrell <[email-masked]>
Date: Sun, 8 Mar 2020 17:38:38 +0000

Moar below... :-)

On 08/03/2020 17:25, Christopher Wood wrote:
>>>> Thanks for the new ECHO PR. [1] I think this is the right
>>>> direction but I have three issues with how it's done in the PR
>>>> right now that I think would benefit from list discussion
>>>> before a new I-D is produced or the PR is merged.
>>>> 
>>>> hard;-( ISTM the current text is broken as it'd expose length
>>>> information about ALPN in the CH and also in the
>>>> EncryptedExtensions. I think it'd be good if the list reached
>>>> some level of agreement on the goals of padding here rather
>>>> than keep making different tweaks that don't work. I think the
>>>> goal for padding ought be that we don't expose information
>>>> about the content of the inner CH via the length of any h/s
>>>> message. If we agree that (or some similar thing) then 
>>>> hopefully it should be just a matter of tweaking the algorithm
>>>> so it works. (I've raised this before but seemingly not
>>>> convincingly enough;-)
>>> 
>>> PR. As this is orthogonal to the overall change, it can be
>>> addressed separately. Can you please file an issue and propose
>>> text?
>> 
>> Sure. But ECHO vs. ESNI does make a difference here e.g. due to the
>> ALPN in the inner. If the outcome of (2) below is to keep the
>> flexibility they may be other extensions that create length issues,
>> either just in the inner CH or else there and possibly also in
>> other bits of the h/s.
>> 
>> That said, if the goal I stated above is something on which
>> everyone's agreed, I'd be happy to craft a PR. But if that goal is
>> not agreed, then probably any PR I make won't be useful, hence
>> raising this on the list.
> 
> ALPN as an example. Servers can’t possibly know what ALPN tokens
> each client might offer up in their CH, so how can they express a
> maximum limit?

IMO there's no need. If a server wants to opine, then it
could publish a min-length-inner-CH-plaintext value, to
match the longest total of SNI+ALPN it knows about, but
it no longer makes sense for a server to opine on the
length of parts of the plaintext inner CH, only on the
overall plaintext length, if even that. The client, being
the one who knows what's in the inner CH plaintext and how
those fields might vary in length, is really the only one
who can figure out the padding.

> 
>> 
>>>> 2) Variance between inner and outer CH. The current scheme is
>>>> that almost any variation is allowed. In the work I've done so
>>>> far looking at how to code that up, the trial decryption
>>>> required becomes a major pain in the client code as soon as the
>>>> TLS key-share differs between inner and outer. I don't know if
>>>> that affects other code bases or if that's mostly an OpenSSL
>>>> thing but think we ought establish on the list if that level of
>>>> flexibility is needed now, or maybe later, or even never. The
>>>> cost there is not just working out how to code it up, but this
>>>> also creates new complex code paths that will be rarely
>>>> executed which is usually a recipe for sadness later. So, I'd
>>>> hope other code bases are checked for this before we merge the
>>>> PR. (The problem here could be OpenSSL's internal, eh...
>>>> "intricacy" is a polite term I guess, or it could be me being
>>>> dim, but it seems real;-)
>>> 
>> I'm questioning whether that's a good goal or not. In my analysis
>> of the various extensions, only SNI and ALPN seem to offer
>> immediate value. Until one gets to new algos, which may mean PQC,
>> there doesn't seem much more that's worth supporting really. And
>> when one looks at the level of complexity to implement generic
>> variance, I'm really not sure it's worthwhile. That said, I'd hack
>> away at it as needed if others have taken a look at their code and
>> found it ok to support. I've just not heard that so far and am
>> concerned we're trading v, simple text in the I-D vs. really
>> horribly complex and maybe flakey code, which doesn't seem like a
>> good plan to me.
>> 
>> Just to be clear: I do like the idea that the analysis be done on
>> the flexible/full-variance scheme and I also like the idea of
>> reconstructing a full CH from the recovered plaintext of the inner
>> CH. Even with all that though, the ECHO spec can still impose
>> interop restrictions on inner/outer CH variance to simplify 
>> implementation and make interop easier and more likely. My guess is
>> that that'd be a worthwhile simplification.
> 
> Yep, it can, and that’s something we can tighten down as needed
> later on. For example, if we later decide that we never want to
> duplicate key shares, we can just make that so. For now, starting
> general aligns with the analysis and gives us the flexibility we need
> to further refine as needed.

Well, at the cost of code complexity and likely harder
interop, I'd say. I'd much prefer we make it easier to
implement now, but with the ability to be more flexible
later. (That's the bit where I think having multiple
implementers comment will be useful.)

Like I said, I like that the abstract scheme is general,
and flexible, but much prefer we start with some added MUSTs to make it
easier now. If we added one line that
the inner and outer CH MUST use the same TLS key-share
(and suites etc.) that'd be a really big help in getting
multiple interoperable implementations sooner is my bet.

> 
>> 
>> If more variation is needed later (e.g. to help incremental
>> deployment of PQC algs), then that could just use a new extension
>> instead of ECHO.
>> 
>>> 
>>>> 3) I think we might be better off leaving out the compression
>>>> stuff for now, and only figuring that out later. The current 
>>>> above were that we constrain the variance between inner and
>>>> outer some more then a generic compression scheme may not be
>>>> needed. I do think we will want some compression thing in the
>>>> RFC we end up with, but we might be better off to get interop
>>>> without that first and then add compression later. (That's what
>>>> I plan to do fwiw, so this is a less pressing issue for me
>>>> given I'll be ignoring it for now:-)
>>> 
>> Allowing more than 1 OuterExtensions - that'd break some code in
>> OpenSSL's generic extension handling. Not sure how bad that'll be
>> to handle.
> 
> Multiple "outer_extension" extensions MAY appear in a
> ClientHelloInner (this is a violation of normal TLS rules, but the
> resulting ClientHelloInner is never processed directly). However,
> there MUST NOT be multiple "outer_extension" extensions with the same
> extension code point.
> 
>> If e.g. we required the same TLS key-share in inner and outer, then
>> you could just omit most of the octets from the inner and
>> deterministically reconstruct. With a small number of such MUSTs,
>> there might be no real need for a generic compression scheme at
>> all. That's linked to (2) above though.
>> 
>> If a generic compression is needed, then yes something ugly will
>> likely be needed, but it could be simple and ugly, e.g.
>> extension-specific, for those extensions that would make a
>> difference. (And maybe we could punt on it too - e.g. require the
>> definition of the PQC stuff to spec this compression if that's when
>> it actually gets useful.)
> 

Me too! Just encouraging nobody to implement it for now
would be fine by me, so we'd not have to code it up and
interop would be that bit easier. Adding a line to the
PR that says "don't write this code yet" would be great.

Cheers,
S.

>> Sure. And happy to offer some, but would like to see guidance from
>> the WG on the mailing list first. (Sorry for being less
>> github-cooperative about this, but being logged in there is not my
>> normal state of being:-)
> 
> No problem. :-)
> 
> Cheers, Chris

---

From: Christian Huitema <[email-masked]>
Date: Sun, 8 Mar 2020 19:13:05 -0700

On 3/8/2020 10:14 AM, Stephen Farrell wrote:

> to offer immediate value.

Uh, No. First, we do have fingerprinting attacks that look at the
pattern of extensions. If the extensions are encrypted in the ESNI, they
cannot do that. And then, we have extensions that reveal a lot about the
app, like for example the QUIC parameters extension. Those are just as
sensitive as the ALPN.

-- Christian Huitema

---

From: Rob Sayre <[email-masked]>
Date: Sun, 8 Mar 2020 19:30:44 -0700

> Thanks for raising these issues! Please see inline below.

Were the comments on the previous PR considered in drafting this one? Some
of them were just nits, but others were substantive.

If there's no answer, I'd be happy to inspect the new PR for the old issues.

thanks,
Rob

---

From: "Christopher Wood" <[email-masked]>
Date: Sun, 08 Mar 2020 20:19:23 -0700

On Sun, Mar 8, 2020, at 7:30 PM, Rob Sayre wrote:
> Were the comments on the previous PR considered in drafting this one? 
> Some of them were just nits, but others were substantive.
> 

Yes, they were. Please do check the diffs!

Best,
Chris

---

From: Stephen Farrell <[email-masked]>
Date: Mon, 9 Mar 2020 10:49:15 +0000

Hiya,

On 09/03/2020 02:13, Christian Huitema wrote:
> cannot do that. 

Well... that depends on whether or not the outer CH that
includes the inner exposes fingerprintable detail. If it
were possible to define a minimal outer CH profile that
everyone could use, then I'd be for that, but not sure
it's feasible.

> And then, we have extensions that reveal a lot about the

Wasn't in the OpenSSL code I looked at:-) But sure, if
there are others that offer immediate value, good to know
about 'em. What's a good ref for that? (I've not been
keeping up to date with QUIC-detail.)

The main problems I've seen in inner/outer variance
so far relate to the TLS key share though - because
that (and associated values) generate loads of internal
state that has to be duplicated and that can have a
bunch of hard to track side-effects in the code when
the trial decryption is being checked. For most other
outer CH extensions, I expect values would have little
or no effect really, as the client should either give
up or try again with new ESNI public keys, but that
might not be true of QUIC stuff - any idea?

Anyway, if the consensus ends up to be to code up
a fully flexible outer CH, then I'll try do that,
but I'd love to hear that others have looked at
their code and (still) figure that's a good plan.

Cheers,
S.

---

From: Ben Schwartz <[email-masked]>
Date: Mon, 9 Mar 2020 11:23:21 -0400

> everyone could use, then I'd be for that, but not sure

Instead of one profile for "everyone", the ECHOConfig could provide
instructions for forming the ClientHelloOuter.

BTW, enumerating the supported ALPNs in the ECHOConfig would solve the ALPN
padding problem (but now we're awfully close to cTLS...).

> the trial decryption is being checked.

It seems like trial decryption can be avoided by tagging the ServerHello.
For example, the client could include X random bytes in the
ClientHelloInner, and the server could echo them in cleartext if ECHO is in
use, or send X random bytes if ECHO decryption failed.  (The extra upstream
bytes can probably be avoided by returning a hash of the nonce or
something.)  Would this make implementation easier?

> For most other
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: "Christopher Wood" <[email-masked]>
Date: Mon, 09 Mar 2020 08:31:33 -0700

On Mon, Mar 9, 2020, at 8:23 AM, Ben Schwartz wrote:
> 
> 
> On Mon, Mar 9, 2020 at 6:49 AM Stephen Farrell 
> <[email-masked]> wrote:
> > 
> >  Hiya,
> > 
> BTW, enumerating the supported ALPNs in the ECHOConfig would solve the 
> ALPN padding problem (but now we're awfully close to cTLS...).
> 
> It seems like trial decryption can be avoided by tagging the 
> ServerHello. For example, the client could include X random bytes in 
> the ClientHelloInner, and the server could echo them in cleartext if 
> ECHO is in use, or send X random bytes if ECHO decryption failed. (The 
> extra upstream bytes can probably be avoided by returning a hash of the 
> nonce or something.) Would this make implementation easier?

We might also consider dropping the "do not stick out" requirement altogether. That would make this much simpler: just put a flag in SH. 

Best,
Chris

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 9 Mar 2020 09:24:55 -0700

I tend to agree. there's an open issue in the spec about this and I've sort
of come to the conclusion that it's going to be pretty easy to determine
just by sending your own ECH with the same key id and looking at what comes
back.

On Mon, Mar 9, 2020 at 8:32 AM Christopher Wood <[email-masked]> wrote:

> We might also consider dropping the "do not stick out" requirement
> altogether. That would make this much simpler: just put a flag in SH.
>
> Best,
> Chris
>

---

From: Ilari Liusvaara <[email-masked]>
Date: Mon, 9 Mar 2020 18:25:54 +0200

> app, like for example the QUIC parameters extension. Those are just as

The extensions Stephen was complaining about are related to "crypto-
graphic context". And these extensions differing in meaning across
the two client hellos seems like asking for trouble to me. There are
some harmless differences tho, e.g., omitting some banned in TLS 1.3
group from inner supported_groups.

These extensions are the ones that are valid in HRR or SH (except
tls_cert_with_extern_psk, which is not cryptographic context despite
being in SH), plus a few others (supported_groups, record_size_limit,
psk_key_exchange_modes). Also included is non-extension ciphersuite
list.

Then there is the special snowflake that is pre_shared_key. One
wants both inner and outer pre_shared_key to have the same number of
PSKs, with the same associated hash functions (if the PSKs are real at
all). But obviously binders have to differ.

Intuitive rule would be for servers to establish cryptographic context
before even looking at ECHO. And then if the front server determines
that split mode should be used, forward to/from back server, at which
point the decisions on cryptographic context are just moot (and the back
server does its own cryptographic context based on inner client hello).

Unfortunately I suspect that would not actually work due to PSKs. A
shared-mode server sees PSK that can be resumed and then resumes it.
Now what if the inner client hello contains SNI which is unknown?
I suspect pretending that ECHO did not exist would be the best
option.

And there are more annoying corner cases:

What keys would be used for 0-RTT? Inner and outer client hello gives
different 0-RTT keys, even if all cryptographic context is as same as
possible.

And how is lame (misconfiguration) back server supposed to reject
the forwarded connection? Plaintext unrecognized name alert?

-Ilari