-
Notifications
You must be signed in to change notification settings - Fork 49
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
hkdf: increase MAX_HKDF_INFO_LEN #411
Conversation
Reviewing this for myself I realized I forgot to account for one more piece of variability: the label could be either I think that means the upper limit is in fact 101 bytes:
So I think I should set the limit in this branch to 102 bytes instead of 100. I will push a small adjustment. |
Encrypted client hello (ECH) offer confirmation requires computing an 8 byte confirmation value: ``` accept_confirmation = HKDF-Expand-Label( HKDF-Extract(0, ClientHelloInner.random), "ech accept confirmation", transcript_ech_conf, 8) ``` Similarly, in the hello-retry request confirmation case we compute: ``` hrr_accept_confirmation = HKDF-Expand-Label( HKDF-Extract(0, ClientHelloInner1.random), "hrr ech accept confirmation", transcript_hrr_ech_conf, 8) ``` The HKDF-Expand-Label and HKDF-Extract algorithms are unmodified from RFC 8446. For a handshake using SHA-384, or SHA-512, as the digest algorithm it's possible for the `info` parameter to the HKDF expand step to exceed 80 bytes. ``` 2 bytes for the output len 1 byte for the label len 6 bytes for the label prefix 23 bytes for the ECH confirmation label (or 27 for HRR) 1 byte for the context len 48 bytes for the context (SHA-384), or 64 bytes (SHA-512) ------------------------------------------ = 81 or 97 bytes total, SHA-384, non-hrr = 85 or 101 bytes total, SHA-512, hrr Both would exceed the existing `MAX_HKDF_INFO_LEN` limit of 80 bytes, and so produce `Unspecified` errors. This commit increase the limit to 102 bytes (it seemed a nicer value than 101), allowing the use of aws-lc-rs HKDF for ECH confirmation purposes without panic.
Limit, commit message & PR description all updated accordingly. Sorry about the last minute indecision :-) |
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.
Thanks for the PR!
This might be a value we should have in a Box<[u8]>
. Let us know if the larger size impacts performance, we can do some minor refactoring if needed.
Good thought; I will see about running our benchmark suite to see if this unexpectedly regressed performance. @justsmth What are your thoughts on whether this branch should update the Prk::expand docs to mention the limit? Presently it says:
but I think this experience shows it can also return |
Yeah, the documentation should be specific about such limitations -- "too large" is needlessly vague (and applies to more than just |
I updated the docs to provide more specific guidance about the errors of |
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.
Thanks for the doc update, LGTM.
Within our benchmarking framework the change doesn't seem to cause any significant impact (results here). |
@justsmth @skmcgrail 😅 at the risk of hijacking a closed issue I wanted to get your thoughts on whether there might be a broader solution to this problem. Having a fixed maximum for the HKDF info length seems like a sensible optimization for the TLS (and since c358484, ECH) use-case but a one-size-fits-all limit makes general application tricky. As a concrete example while working on rustls/rustls#1963 I found I had to increase the limit to 300 bytes in order to support all of the base mode RFC 9180 test vectors (the largest suite + input produced 298 byte HKDF info input while deriving a key schedule key). Trying to upstream that change feels a bit like whack-a-mole. The next interesting use-case might need an even larger maximum, or we might start to see perf impact from the bloat. I'm trying to intuit the reason for the divergence in implementation between |
Hi there,
I've been working on encrypted client hello (ECH) support in Rustls. As part of that we're using aws-lc-rs for the HKDF operations the draft calls for.
In particular, ECH offer confirmation is determined by computing an 8 byte confirmation value:
Similarly, in the hello-retry request confirmation case we compute:
The HKDF-Expand-Label and HKDF-Extract algorithms are unmodified from RFC 8446.
For a handshake using SHA-384 for the digest algorithm when we confirm ECH acceptance we perform an HKDF expand operation with the
info
:This works out to be:
This exceeds the existing
MAX_HKDF_INFO_LEN
limit of 80 bytes, and so produces anUnspecified
error. Equivalent inputs do not cause an error with*ring*
, where there doesn't seem to be a limit imposed on theinfo
parameter for HKDF.The only point of variability in the input is the context length, which in the ECH case is always a transcript digest and so the length is dependent on the hash algorithm in use. If we assume HRR confirmation (for the longer 27 byte label), and SHA512 for the digest, then the context could be as large as 64 bytes, so I think the largest
info
that would be required to be supported for ECH confirmation is 101 bytes. (2 + 1 + 6 + 27 + 1 + 64 = 101).This PR increase the limit to 102 bytes (it seemed a nicer value than 101), and experimentally all of my ECH confirmation tests using aws-lc-rs for the HKDF operations pass with this limit where previously they resulted in a panic from exceeding the info limit.