-
Notifications
You must be signed in to change notification settings - Fork 737
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
Base Mode HPKE #1462
base: main
Are you sure you want to change the base?
Base Mode HPKE #1462
Conversation
@tanyav2 Thanks for doing this. Are you still interested in this? If so, I can review it soon. |
Yes, still interested! |
Over in rustls we'd like to implement support for Encrypted Client Hello, which would ideally use this. Failing that, the work in this PR could live in a separate crate but that would need a solution for #331 (happy to provide a PR for that if that is the preferred direction). |
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.
Here are some initial thoughts on the structure of the API, to help you understand how it would fit in with the way the rest of the ring APIs are designed.
suite_id_kem: get_suite_id_kem(kem_id), | ||
kem_id, | ||
hash: &hkdf::HKDF_SHA256, | ||
agreement: &agreement::ECDH_P256, |
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.
The unusual structure of ring, e.g. in how we have "HMAC algorithms" that are thin wrappers around digest algorithms, is to facilitate link-time dead-code elimination by ensuring that we never do this kind of dispatching that potentially would pull in every agreement::Algorithm algorithm.
Following that, it would be better if we had something like:
struct Algorithm {
hkdf: &'static hkdf::Algorithm,
agreement: &'static agreement::Algorithm
}
static P256_SHA256: Algorithm = Algorithm {
hkdf: hkdf::HKDF_SHA56,
agreement: agreement::ECDH_P256
};
In the case of the unimplemented ones, we can just omit them until everything else is OK.
When we need to convert a on-the-wire identifier to an Algorithm
, we need a function like this:
fn algorithm_by_id(
allowed_algorithms: &[&'static Algorithm],
on_the_wire_id: u16)
-> Result<'static Algorithm, error::Unspecified>
{
allowed_algorithms.iter().find(|alg| alg.id == on_the_wire_id).ok_or(error::Unspecified)
}
This way, we again avoid statically referencing any algorithms, and then allow the linker to discard unused ones.
At the top level of the API, we need the caller to be able to pass in a list (slice/iterator) of allowed algorithms. This is the mechanism that lets the calling code (e.g. Rustls) choose which algorithms it wants to allow the use of, and also the priority. We usually use slices because we try to avoid allocations, and that tends to work OK (AFAICT) because the number of different algorithms we support is low so linear search through them is OK.
@ctz, I do think we should solve #331 regardless. In terms of the FIPS project I'm working on, my hope is that we'd implement HPKE outside of the FIPS boundary, by using an implementation of static ECDH that is within the FIPS boundary. Noise needs a solution for #331 anyway, and I believe that a solution for #331 is blocking the next phases of the HPKE implementation, from the "not implemented yet" comments I see in this PR. |
(Sorry, I didn't mean to close this. Reopening.) |
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #1462 +/- ##
==========================================
+ Coverage 93.02% 95.96% +2.93%
==========================================
Files 127 138 +11
Lines 18227 21601 +3374
Branches 195 226 +31
==========================================
+ Hits 16956 20729 +3773
+ Misses 1237 837 -400
- Partials 34 35 +1 ☔ View full report in Codecov by Sentry. |
This is a draft of a base mode implementation of HPKE. Opening this up before implementing the other modes for early feedback. It also includes support for bidirectional encryption, since in practice, almost all applications require it.