RustSec Advisories for hpke-rs and libcrux-psq#2647
RustSec Advisories for hpke-rs and libcrux-psq#2647nadimkobeissi wants to merge 9 commits intorustsec:mainfrom
Conversation
| @@ -0,0 +1,23 @@ | |||
| ```toml | |||
| [advisory] | |||
| id = "RUSTSEC-0000-0000" | |||
There was a problem hiding this comment.
You can only submit one advisory per crate in a PR with id RUSTSEC-0000-0000
The lint check fails because it doesn't expect 000-0001.md
There was a problem hiding this comment.
Multiple advisories for one crate in a single PR are possible.
The filename needs to be RUSTSEC-0000-0000.<N>.md where <N> is replaced with a number see https://github.com/rustsec/advisory-db/pull/2254/changes for example
There was a problem hiding this comment.
@Skgland Thanks for this, I had no idea. I'll push a fix now.
Co-authored-by: pinkforest(she/her) <36498018+pinkforest@users.noreply.github.com>
teor2345
left a comment
There was a problem hiding this comment.
Some suggestions for consistency, that apply similarly to all 3 advisories.
| references = ["https://datatracker.ietf.org/doc/rfc9180/"] | ||
|
|
||
| [versions] | ||
| patched = [] |
There was a problem hiding this comment.
This empty "patched" entry is inconsistent with the text below saying the library has been patched.
There was a problem hiding this comment.
Yes I think he fixed already one of them, I also should have said ">= 0.6.0" instead of "> 0.6.0"
| id = "RUSTSEC-0000-0000" | ||
| package = "hpke-rs" | ||
| date = "2026-02-10" | ||
| url = "https://github.com/cryspen/hpke-rs/pull/117" |
There was a problem hiding this comment.
Usually this would point to the fix that was actually merged, see below for a suggestion referencing the original disclosure.
| [versions] | ||
| patched = [] | ||
| ``` | ||
|
|
There was a problem hiding this comment.
I understand their SECURITY.md is very new, but it says:
hpke-rs is still pre-release and does not support any specific versions yet.
Does this impact the severity of this issue, or justify wording something like:
| hpke-rs is currently pre-release, and [not supported for use in production code](https://github.com/cryspen/libcrux/blob/b7187c5b115f64bf98830b7ac7980d68cbe295d6/SECURITY.md?plain=1#L5). |
There was a problem hiding this comment.
If it's published in crates.io so it's covered. Severity isn't affected by things like this but it can be a mention in the advisory itself to ensure tools like cargo audit etc. traps advising that hey you should not use this in production etc. if that type of statement is still left there where people may have missed it when using the library.
Also it's important to keep in mind that when ever people started using the library they might or might not have read the said disclaimer so it should be mentioned in the advisory probably to ensure people understand the status of the library. If this disclaimer would have been from the beginning that would be another but since this is new I would include this info to make sure people understand the status.
There was a problem hiding this comment.
Cryspen has actively lobbied for their “pre-release” software to be used in production in Signal, Google and OpenMLS, where it is today, and I think that speaks way more than a 0.0.x version number.
There was a problem hiding this comment.
You can see the Signal and OpenMLS dependencies here, I assume the Google ones are private (or transitive):
https://crates.io/crates/hpke-rs/reverse_dependencies
There was a problem hiding this comment.
signal does not publish their crates in crates.io - the one signal there is a vendored-in fork who decided to publish it. for advisory-db it hasn't mattered whether there is dependency visible in reverse but only that it is published in crates.io
Co-authored-by: pinkforest(she/her) <36498018+pinkforest@users.noreply.github.com>
Co-authored-by: teor <teor@riseup.net>
| references = ["https://datatracker.ietf.org/doc/rfc9180/"] | ||
|
|
||
| [versions] | ||
| patched = [">0.6.0"] |
There was a problem hiding this comment.
I think using >= for patched is clearer
There was a problem hiding this comment.
Fixed for all advisories.
Can't the attacker compute the session key just as easily when they supply a normal public key for which they know the corresponding private key? So it's not clear to me this has a practical security impact, or if it's just non compliance with the specification.
The claim that an unauthenticated crash vulnerability (which is definitely bad) renders the application not IND-CCA secure because it can't respond to further queries is a rather creative interpretation of IND-CCA. |
I don't understand. It's a classic distinguisher. |
|
Advisories have been merged in #2667 for some of the issues here, but notably not for the hpke-rs issues which include catastrophic nonce reuse. |
This PR proposes three RustSec advisories for cryptographic vulnerabilities discovered during research ("Verification Theatre: False Assurance in Formally Verified Cryptographic Libraries"). The upstream maintainers (Cryspen) have patched these issues but have not filed RustSec advisories, which means
cargo auditdoes not currently flag affected versions.Cryspen has published GitHub Security Advisories (GHSAs) for some of these issues. However, we believe RustSec advisories are still warranted for the reasons outlined below.
Proposed Advisories
1. hpke-rs: Nonce reuse via sequence number overflow
The library stores HPKE encryption context sequence numbers as
u32(max 2^32 - 1) rather than enforcing the RFC 9180 limit of 2^96 - 1. The overflow guard is ineffective in release builds due to Rust's default wrapping behavior for integer overflow, allowing silent counter wrap-around. This enables nonce reuse in AES-GCM, which permits plaintext recovery and authentication key compromise, a critical vulnerability.2. hpke-rs: Missing X25519 zero-check validation
RFC 9180, Section 7.1.4 requires that implementations check whether the Diffie-Hellman shared secret is the all-zero value. hpke-rs omits this check in both its RustCrypto and libcrux backends. An attacker supplying low-order points can force a zero shared secret, enabling session key prediction and message decryption.
3. libcrux-psq: AES-GCM decryption panic on malformed ciphertext
The
decrypt_outmethod calls.unwrap()on AES-GCM 128 decryption results, causing a process crash when presented with malformed ciphertexts. Nine of eighteen supported ciphersuites are affected. An unauthenticated attacker can trigger denial of service by sending corrupted data, rendering the entire implementation not IND-CCA secure, a critical vulnerability.Why RustSec advisories are needed alongside the existing GHSAs
Cryspen published GHSA-g433-pq76-6cmf for hpke-rs and GHSA-435g-fcv3-8j26 for libcrux-psq. While we appreciate that an advisory was issued, there are several gaps that leave downstream users without the information they need:
cargo audit— the standard tool Rust developers rely on to check for known vulnerabilities — does not surface these issues.Prior discussion
These advisories were previously proposed in PR #2637, which was closed. We sought an explanation in #2646. We are resubmitting with the hope of a productive path forward. We are happy to incorporate feedback on advisory wording, severity ratings, or any other aspect of these filings, and to work with both RustSec reviewers and the upstream maintainers to ensure the advisories are accurate and fair.
Thank you for your time and for maintaining this important resource for the Rust ecosystem.