Re: [TLS] ECH/ESNI - is accept confirmation calculation brittle in the face of errors?

2021-03-19 Thread David Benjamin
On Thu, Mar 18, 2021 at 4:07 PM Stephen Farrell 
wrote:

>
> Hiya,
>
> On 18/03/2021 19:17, David Benjamin wrote:
> > I don't think I'd agree that *most* of the work is in the secret
>  > computation per se. Actually doing trial decryption with
>  > the secret requires reaching down into the record layer.
>  > This is especially onerous for QUIC, where the record layer
>  > is offloaded to another protocol (often outside the TLS
>  > library).
>
> Ah, fair point - I've not looked at QUIC at all. But how
> are encrypted extensions and tickets handled in such cases?
> If those are handled in the original library then a trial
> decryption should be possible too maybe?
>

QUIC replaces the record layer and keeps the TLS handshake. So as the TLS
handshake progresses, it hands keys (handshake traffic keys, etc.), to
QUIC to install. When TLS needs to write an EncryptedExtensions or so, it
hands QUIC cleartext to encrypt. When QUIC decrypts a record and sees a
CRYPTO frame, it hands the results to TLS to process as handshake messages.
The draft is here:
https://datatracker.ietf.org/doc/draft-ietf-quic-tls/

In all the stacks I'm aware of, there are QUIC-specific APIs to install a
custom record layer of sorts. And thus the nuisance with trial decryption
and friends. Every new feature we push down to the record layer changes
that record layer interface. This means more coordination between QUIC and
TLS. Something like trial decryption would require TLS hand QUIC both sets
of handshake keys. Then QUIC would need to do the trial decryption and
report back to TLS which set of keys won.

(If you're working on an OpenSSL ECH implementation, you probably won't see
this because OpenSSL doesn't have APIs for QUIC yet.)

David
___
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls


Re: [TLS] ECH/ESNI - is accept confirmation calculation brittle in the face of errors?

2021-03-19 Thread Christian Huitema


On 3/19/2021 2:58 PM, David Benjamin wrote:

On Thu, Mar 18, 2021 at 4:07 PM Stephen Farrell
wrote:


Hiya,

On 18/03/2021 19:17, David Benjamin wrote:

I don't think I'd agree that*most*  of the work is in the secret

  > computation per se. Actually doing trial decryption with
  > the secret requires reaching down into the record layer.
  > This is especially onerous for QUIC, where the record layer
  > is offloaded to another protocol (often outside the TLS
  > library).

Ah, fair point - I've not looked at QUIC at all. But how
are encrypted extensions and tickets handled in such cases?
If those are handled in the original library then a trial
decryption should be possible too maybe?


QUIC replaces the record layer and keeps the TLS handshake. So as the TLS
handshake progresses, it hands keys (handshake traffic keys, etc.), to
QUIC to install. When TLS needs to write an EncryptedExtensions or so, it
hands QUIC cleartext to encrypt. When QUIC decrypts a record and sees a
CRYPTO frame, it hands the results to TLS to process as handshake messages.
The draft is here:
https://datatracker.ietf.org/doc/draft-ietf-quic-tls/

In all the stacks I'm aware of, there are QUIC-specific APIs to install a
custom record layer of sorts. And thus the nuisance with trial decryption
and friends. Every new feature we push down to the record layer changes
that record layer interface. This means more coordination between QUIC and
TLS. Something like trial decryption would require TLS hand QUIC both sets
of handshake keys. Then QUIC would need to do the trial decryption and
report back to TLS which set of keys won.

(If you're working on an OpenSSL ECH implementation, you probably won't see
this because OpenSSL doesn't have APIs for QUIC yet.)


That, or try race two connection contexts corresponding to the two 
trials, and keep the first that succeeds. Which would indeed require TLS 
to tell QUIC that "the key might be K1 or K2". That's also very 
complicated. For the QUIC client, the current text is much better.


Let's come back to the original discussion. If I look back at the 
discussion of issue 274 
(https://github.com/tlswg/draft-ietf-tls-esni/issues/274), we ended up 
at some point with a set of alternatives, including these two:


    * accept_confirmation = PRF(ClientHelloInner.random, 
ServerHello.random[0:24])
    * accept_confirmation = PRF(ClientHelloInner.random, 
ServerHello.KeyShare)


The issue was closed by PR #287 
(https://github.com/tlswg/draft-ietf-tls-esni/pull/287/files) which 
selected the first of these two options. But this was later updated by 
PR #353 (https://github.com/tlswg/draft-ietf-tls-esni/pull/353), which 
changed that to the second option, the one including the server key 
share. The correction allows mitigating an attack in which the 
interceptor copies the server hello but substitutes its own key share, 
and thus can test whether ECH was used.


Look at the comment, "This change is definitely more invasive than the 
existing signal, but not all that hard to implement. (E.g., 
cloudflare/go#38 .)" later in 
the thread.


We do have new information that this is somewhat costly to implement 
because it requires computing two handshake secrets on the client. On 
the other hand, it seems that the cost is only there if the client 
starts by testing the wrong hypothesis. If the client is fairly certain 
that the server supports ECH, the CPU overhead ought to be minimal -- 
cases in which the client is using the wrong ECH key, or when an 
interceptor interfered with the exchange.


-- Christian Huitema

___
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls


Re: [TLS] ECH/ESNI - is accept confirmation calculation brittle in the face of errors?

2021-03-19 Thread Stephen Farrell


Hiya,

I agree with your analysis except for the very last part...

On 19/03/2021 23:59, Christian Huitema wrote:
 
We do have new information that this is somewhat costly to implement 
because it requires computing two handshake secrets on the client. On 
the other hand, it seems that the cost is only there if the client 
starts by testing the wrong hypothesis. If the client is fairly certain 
that the server supports ECH, the CPU overhead ought to be minimal -- 
cases in which the client is using the wrong ECH key, or when an 
interceptor interfered with the exchange.


The CPU overhead isn't a problem from my POV.

The problem is that the case where the wrong ECH was used is
kinda like doing 1.5 handshakes. And as/if new ServerHello
extensions come into play (esp PQC), or when we deal with old
code interacting with but unrelated to ECH, or with custom-
extension handling code that we'll never see, or with some
other random change to the transcript, any of that might
expose the brittleness of a 1.5 handshake design.

As it happens, I've fixed the memory leaks this error case
causes but its still messy - someone changing some unrelated
bit of OpenSSL code in a year or two for some other reason
could make my clean-up code break something in unpredictable
ways. (Should my code end up upstream etc. etc.)

So, quoting you out of order:

> Look at the comment, "This change is definitely more >
> invasive than the existing signal, but not all that hard to
> implement. (E.g., cloudflare/go#38  /cloudflare/go/pull/38>.)" later in the thread.

I think the right thing here would be to analyse that attack
again and re-evaluate which of the two answers now seems
best. For me, the github issue discussion didn't leave
behind enough information to do that. (Or I need to stare
at it some more maybe:-)

Cheers,
S.






-- Christian Huitema




OpenPGP_0x5AB2FAF17B172BEA.asc
Description: application/pgp-keys


OpenPGP_signature
Description: OpenPGP digital signature
___
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls