-
Notifications
You must be signed in to change notification settings - Fork 750
crypto: add HPKE module and traits, provider-example impl #1589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like the trait is fairly specialized to the hpke-rs interface, might be good to think about the conceptually ideal interface for this?
I think it is pretty close to the ideal interface. The main change I can think to suggest is to tailor the traits to only supporting |
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #1589 +/- ##
==========================================
- Coverage 96.13% 96.09% -0.04%
==========================================
Files 76 77 +1
Lines 15745 15738 -7
==========================================
- Hits 15137 15124 -13
- Misses 608 614 +6 ☔ View full report in Codecov by Sentry. |
I think this makes sense -- no need to make this trait generic enough for non-TLS use cases. |
rustls/src/crypto/hpke.rs
Outdated
/// | ||
/// This is a stateful object that can be used to seal messages for receipt by | ||
/// a receiver. | ||
pub trait HpkeSender: Debug + Send + Sync { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be minded to start with a one-shot interface for the sake of simplicity. Then move to a streaming interface once everything is up and running?
That would obviate HpkeSender
and HpkeReceiver
, and make the methods in trait Hpke
something like:
fn open(&self,
pk_r: &HpkePublicKey,
info: &[u8],
aad; &[u8],
pt: &[u8],
) -> Result<(EncapsulatedSecret, Vec<u8>), Error>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switched to one-shot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be minded to start with a one-shot interface for the sake of simplicity.
Leaving a note here: we do need the non-one-shot interface for ECH: specifically for handling HelloRetryRequests.
Section 6.1.5 "Handshaking with ClientHelloInner" says:
It encrypts EncodedClientHelloInner as described in Section 6.1.1, using the second partial ClientHelloOuterAAD, to obtain a second ClientHelloOuter. It reuses the original HPKE encryption context computed in Section 6.1 and uses the empty string for enc.
The HPKE context maintains a sequence number, so this operation internally uses a fresh nonce for each AEAD operation. Reusing the HPKE context avoids an attack described in Section 10.11.2.
So we specifically need to maintain the HPKE context used for the original client hello so that we can re-use it when creating the updated extension for a HRR response.
I'm trying to bundle up some required changes and will make sure this is one of them.
73d45ca
to
70ab492
Compare
This commit introduces a trait for a hybrid public key encryption (HPKE) provider. HPKE is specified in RFC 9180[0], and is a pre-requisite for implementing encrypted client hello (ECH). Implementations of this trait can use the cryptographic provider of their choice to provide HPKE using existing primitives from the crypto provider. We've tailored the HPKE trait in Rustls to just what is required for ECH, e.g. it doesn't support modes other than the unauthenticated 'base' mode, and it only offers the "single-shot" APIs. [0]: https://www.rfc-editor.org/rfc/rfc9180
fd06b54
to
18485b8
Compare
This commit implements the Rustls HPKE provider traits using hpke-rs[0] with the rust-crypto backend. Since HPKE is not yet used in Rustls (but will be for ECH support), a unit test based on the RFC 9180 test vectors is added. Likely in the future we will want to move this test somewhere outside of the provider-example crate and use it to test a *ring* HPKE implementation using the same test vector data. [0]: https://github.com/franziskuskiefer/hpke-rs
18485b8
to
2f350f7
Compare
This branch introduces a trait for a hybrid public key encryption (HPKE) provider. HPKE is specified in RFC 9180, and is a pre-requisite for implementing encrypted client hello (ECH). Implementations of these traits can use the cryptographic provider of their choice to provide HPKE using existing primitives from the crypto provider.
We've tailored the HPKE trait in Rustls to just what is required for ECH, e.g. it doesn't support modes other than the unauthenticated 'base' mode, and it only offers the "single-shot" APIs.
Demonstration of implementing the traits is achieved using hpke-rs with the rust-crypto backend. Separately we expect to implement a HPKE provider using the ring crypto provider for proper ECH support.
Since the HPKE traits are not yet used in Rustls a unit test of the provider-example HPKE provider based on the RFC 9180 test vectors is added to prevent bitrot and ensure the traits are workable. Likely in the future we will want to move this test logic somewhere outside of the provider-example crate and use it to test the other HPKE provider implementations.