GHSA-j9xq-69pf-pcm8 RustCrypto Has Insufficient Length Validation in decrypt() in SM2-PKE
SummaryA denial-of-service vulnerability exists in the SM2 public-key encryption (PKE) implementation: the `decrypt()` path performs unchecked `slice::split_at` operations on input buffers derived from untrusted ciphertext. An attacker can submit short/undersized ciphertext or carefully-crafted DER-encoded structures to trigger bounds-check panics (Rust unwinding) which crash the calling thread or process.Affected Component / VersionsFile: `src/pke/decrypting.rs`Functions: `DecryptingKey::decrypt_digest/decrypt/decrypt_der`, internal `decrypt()` implementationAffected releases:sm2 0.14.0-rc.0 (https://crates.io/crates/sm2/0.14.0-rc.0)sm2 0.14.0-pre.0 (https://crates.io/crates/sm2/0.14.0-pre.0)DetailsThe vulnerability is located in the file `sm2/src/pke/decrypting.rs`. The **fundamental cause** of the vulnerability is that the decryption function **does not strictly check** the ciphertext's format and length information. Consequently, a maliciously crafted ciphertext can trigger Rust's **panic mechanism** instead of the expected error handling (`Error`) mechanism. The Rust function `C.split_at(L)` will trigger a Panic if the length is less than `L`, as shown in the code comment below: the `decrypting` function has **at least three locations** where a slice operation might trigger a Panic.Rust's `slice::split_at` panics when the split index is greater than the slice length. A panic in library code typically unwinds the thread and can crash an application if not explicitly caught. This means an attacker that can submit ciphertexts to a service using this library may cause a DoS.Proof of Concept (PoC)Two PoCs were added to this repository under `examples/` demonstrating the two
common ways to trigger the issue:`examples/poc_short_ciphertext.rs` — constructs a deliberately undersized
ciphertext (e.g., `vec![0u8; 10]`) and passes it to `DecryptingKey::decrypt`.
This triggers the `cipher.split_at(c1_len)` panic.`examples/poc_der_short.rs` — constructs an ASN.1 `Cipher` structure with
valid-length `x`/`y` coordinates (from a generated public key) but with tiny
`digest` and `cipher` OCTET STRING fields (1 byte each). When run with the
crate built with `--features std`, `Cipher::from_der` accepts the DER and the
call flows into `decrypt()`, which then panics on the later `split_at`.Reproduction (from repository root):ImpactDirect Denial of Service: remote untrusted input can crash the thread/process handling decryption.Low attacker effort: crafting short inputs or small DER octet strings is trivial.Wide exposure: any application that exposes decryption endpoints and links this library is at risk.Recommended FixPerform defensive length checks before any `split_at` usage and return a controlled `Err` instead of allowing a panic. Minimal fixes in `decrypt()`:After applying these checks, `decrypt()` will return an error for short or malformed inputs instead of panicking.**Credit**This vulnerability was discovered by:XlabAI Team of Tencent Xuanwu LabAtuin Automated Vulnerability Discovery EngineCVE and credit are preferred.If you have any questions regarding the vulnerability details, please feel free to reach out to us for further discussion. Our email address is xlabai@tencent.com.**Note**We follow the security industry standard disclosure policy—the 90+30 policy (reference: https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-policy.html). If the aforementioned vulnerabilities cannot be fixed within 90 days of submission, we reserve the right to publicly disclose all information about the issues after this timeframe.
CVSS v3.1 score: 7.5