On 3/19/2021 2:58 PM, David Benjamin wrote:
On Thu, Mar 18, 2021 at 4:07 PM Stephen Farrell<stephen.farr...@cs.tcd.ie>
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 <https://github.com/cloudflare/go/pull/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