Skip to content

WIP: ECH Draft-10#663

Closed
sayrer wants to merge 69 commits into
rustls:mainfrom
grafica:grafica-ech-draft-10
Closed

WIP: ECH Draft-10#663
sayrer wants to merge 69 commits into
rustls:mainfrom
grafica:grafica-ech-draft-10

Conversation

@sayrer

@sayrer sayrer commented Apr 19, 2021

Copy link
Copy Markdown
Contributor

No description provided.

@codecov-commenter

codecov-commenter commented Apr 19, 2021

Copy link
Copy Markdown

Codecov Report

Merging #663 (ab6c143) into main (beef0be) will decrease coverage by 0.38%.
The diff coverage is 91.49%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #663      +/-   ##
==========================================
- Coverage   96.41%   96.03%   -0.39%     
==========================================
  Files          57       59       +2     
  Lines        9125     9807     +682     
==========================================
+ Hits         8798     9418     +620     
- Misses        327      389      +62     
Impacted Files Coverage Δ
rustls/src/lib.rs 100.00% <ø> (ø)
rustls/src/msgs/mod.rs 100.00% <ø> (ø)
rustls/src/key_schedule.rs 96.25% <20.00%> (-2.70%) ⬇️
rustls/src/client/mod.rs 94.73% <75.00%> (-2.22%) ⬇️
rustls/src/client/tls13.rs 96.42% <86.66%> (-0.31%) ⬇️
rustls/src/msgs/ech.rs 90.26% <90.26%> (ø)
rustls/src/msgs/handshake.rs 96.70% <91.39%> (-0.51%) ⬇️
rustls/src/client/hs.rs 97.12% <91.89%> (-0.73%) ⬇️
rustls/src/ech_key.rs 99.22% <99.22%> (ø)
rustls/src/error.rs 88.29% <100.00%> (+0.25%) ⬆️
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update beef0be...ab6c143. Read the comment docs.

@sayrer

sayrer commented Apr 19, 2021

Copy link
Copy Markdown
Contributor Author

I removed the minimal-versions check temporarily, since that error is being caused by the "hpke" crate. I don't plan to leave that dependency in the end, but I want to be able to spot other errors easily.

@briansmith

Copy link
Copy Markdown
Contributor

@sayrer Are you wanting feedback on this? Not sure what your intent is RE the "WIP:" prefix.

@sayrer

sayrer commented Apr 22, 2021

Copy link
Copy Markdown
Contributor Author

@sayrer Are you wanting feedback on this? Not sure what your intent is RE the "WIP:" prefix.

No, not yet. In particular, the ech_key.rs file is just for bootstrapping from other open-source implementations. My goal is to get the signing / authentication parts right for one ECH ciphersuite. I believe that can be tested only with messages, before integrating the code into the handshake.

@sayrer

sayrer commented May 3, 2021

Copy link
Copy Markdown
Contributor Author

I switched this to hpke-rs for now. It's a bit easier to use since it uses the enum-heavy style that Rustls does. The hpke crate worked fine, but I would've had to implement some macros we won't end up using. Also, using hpke-rs with the "hazmat" feature lets you do things like get private key bytes. This will be good for testing during development, but I don't expect ring will support anything like this.

@sayrer

sayrer commented May 6, 2021

Copy link
Copy Markdown
Contributor Author

I'm a little mystified by this Catalina test failure. It passes here on Big Sur, and also seems to pass on Linux (looking through the logs).

@sayrer

sayrer commented May 6, 2021

Copy link
Copy Markdown
Contributor Author

This latest patch is only failing on code coverage metrics. I am not sure what's going on with the macOS tests--I think I'll wait it out since they pass on my local Macs.

The next step is to work through the ClientHello transformations required by the spec, and then sign that plaintext and aad. This patch shows that HPKE itself works when instantiated from the TLS wire format.

@sayrer

sayrer commented May 7, 2021

Copy link
Copy Markdown
Contributor Author

Looks like the GitHub CI machines are pretty old--they don't have AES-NI and/or AVX instructions, which Evercrypt requires.

@sayrer

sayrer commented May 18, 2021

Copy link
Copy Markdown
Contributor Author
% cargo run --example tls_ech_client
Error: Custom { kind: InvalidData, error: PeerMisbehavedError("server sent unsolicited encrypted extension") }

I can add EncryptedClientHello to be expected, and get past this.

The ClientHelloInner must be wrong, because I'm getting a ServerExtension::EncryptedClientHello with the same configuration as the initial one. [edit: The info argument to HPKE::SetupBaseS is wrong. Will fix.]

@sayrer

sayrer commented May 19, 2021

Copy link
Copy Markdown
Contributor Author

It looks like the server is accepting the ECH now. There's some work to do in handle_server_hello to update the transcript upon acceptance. Getting this after that point:

Error: Custom { kind: InvalidData, error: DecryptError }

@sayrer

sayrer commented May 20, 2021

Copy link
Copy Markdown
Contributor Author

It looks like there are two issues now:

  1. The spec isn't very precise about what goes in the transcript, so I am writing unit tests for this. I've tried to write it a few times, but the EncodedClientHelloInner and what's in the transcript are not the same. It seems to just vary by message envelopes etc.

  2. In order to confirm ECH was accepted, the first 8 bytes of a ring::Prk need to be examined. see: https://tlswg.org/draft-ietf-tls-esni/draft-ietf-tls-esni.html#section-7.2.

@sayrer

sayrer commented May 22, 2021

Copy link
Copy Markdown
Contributor Author

OK, I got this to work, at least for non-HRR requests. The issue was that the ECH transcript needs to be calculated from an unsent inner ClientHello message, which differs in a few ways from the EncodedClientHelloInner used in HPKE. Upon ECH acceptance, the transcript from the ClientHelloOuter is discarded, then substituted with one calculated from the unsent inner ClientHello message, and the client random is changed to the inner random value. After that, the ServerHello message is added to the transcript as normal.

The code is still messy, so I'm not going to update the PR yet. You can see it here.

@sayrer

sayrer commented May 23, 2021

Copy link
Copy Markdown
Contributor Author

The draft-10 patch will have some refactors concerning ExpectServerHello::handle and tls13::handle_server_hello. I don't think they will be necessary in later drafts due to this change: https://github.com/tlswg/draft-ietf-tls-esni/pull/420/files

@sayrer

sayrer commented May 27, 2021

Copy link
Copy Markdown
Contributor Author

I got these two things working, so I'm going to add HRR support, more tests, and clean this patch up enough to be ready for feedback. I don't think it will make sense to merge, because the draft-10 design is invasive to the client handshake in ways that draft-11 won't be. I'll add some notes on that via comments. After that, I'll work on the server.

secret
}

pub fn server_ech_confirmation_secret(&mut self, hs_hash: &Digest) -> PayloadU8 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea behind the the ring HKDF API is that you would do something like this:

pub struct Iv([u8; aead::NONCE_LEN]);
struct IvLen;

impl hkdf::KeyType for IvLen {
    fn len(&self) -> usize {
        aead::NONCE_LEN
    }
}

s/Iv/EchConfirmationSecret/.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this code will live on in the final implementation, given https://github.com/tlswg/draft-ietf-tls-esni/pull/420/files, so I just did the easiest thing for interop testing in draft-10.

@briansmith briansmith May 28, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would say all the existing uses of PayloadU8Len are unfortunate, so I wouldn't copy them. derive_ticket_psk in particular should not be using Vec<u8> as its return type, but instead it should use a stronger key type.

Ideally export_keying_material would have a more sophisticated API as well, more like ring's HKDF API; I think the desire to avoid ring types in Rust's public API is what makes that difficult.

OTOH, probably it makes more sense for server_ech_confirmation_secret to compute the return the entire Random including the 24 random bytes and the 8 derived bytes.

@sayrer sayrer May 28, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To add to my above comment, I think the draft-11 ECH confirmation will be able to happen entirely in client/hs.rs. The draft-10 design requires changes to client/tls13.rs and key_schedule.rs, but I don't think those will be needed in the future.

@sayrer

sayrer commented Jun 16, 2021

Copy link
Copy Markdown
Contributor Author

I've been exchanging some emails with Cloudflare regarding HRR. They have a bug fix for their server deploying later this week: https://github.com/cloudflare/go/pull/85/files

They're also going to disable P-384 and P-521 on their test server, so it will be easy to trigger HRR.

@cjpatton

cjpatton commented Jan 4, 2022

Copy link
Copy Markdown
Contributor

I'm curious if anyone plans to pick this up in the next few months. By the way, the current version is draft-13, which (we hope!) will be simpler to implement on the client side.

@cpu
cpu marked this pull request as draft March 31, 2023 18:44
@cpu

cpu commented Oct 16, 2023

Copy link
Copy Markdown
Member

I think we should close this PR to reflect that it is:

i. Not under active development by anyone at this time
ii. Has substantial conflicts with main
iii. Is out-of-date with the current ECH drafts

I think it would be great to revive the ECH effort, but leaving this draft PR open doesn't feel like it will help advance that goal. It also comes at the cost of distracting from other work closer to being mergeable in the PR queue.

@djc

djc commented Oct 17, 2023

Copy link
Copy Markdown
Member

I think it would be great to revive the ECH effort, but leaving this draft PR open doesn't feel like it will help advance that goal.

Agreed.

It also comes at the cost of distracting from other work closer to being mergeable in the PR queue.

This doesn't feel like a big win by itself...

@cpu

cpu commented Oct 17, 2023

Copy link
Copy Markdown
Member

This doesn't feel like a big win by itself...

For one PR in isolation it's not a huge win, but as more of them enter into this state the clutter gives the appearance of an unmaintained project. This branch in particular hasn't had a commit since 2021, it's very stale.

In either case, reopening closed PRs if someone feels differently is practically free ;-)

@cjpatton

Copy link
Copy Markdown
Contributor

I support closing. The protocol (not to mention rustls itself) has changed so much since draft-10 that I think it would be worth starting fresh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants