RustCrypto Has Insufficient Length Validation in decrypt() in SM2-PKE
Description
RustCrypto: Elliptic Curves is general purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. In versions 0.14.0-pre.0 and 0.14.0-rc.0, a 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. This issue has been patched via commit e60e991.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Unchecked slice::split_at in SM2-PKE decrypt() allows crafted ciphertext to cause a panic-based denial of service.
Vulnerability
Overview
CVE-2026-22700 is a denial-of-service vulnerability in the SM2 public-key encryption (PKE) implementation of the RustCrypto elliptic-curves library. The decrypt() path in sm2/src/pke/decrypting.rs performs unchecked slice::split_at operations using split_at on input buffers derived from untrusted ciphertext. When an attacker submits a short or undersized ciphertext, or a carefully crafted DER-encoded structure, the split_at call triggers a bounds check triggers a Rust panic (unwinding) instead of returning an error, crashing the calling thread or process [1][2].
Attack
Vector and Prerequisites
The vulnerability affects versions 0.14.0-pre.0 and 0.14.0-rc.0 of the sm2 crate. An attacker can exploit this by sending a malformed ciphertext to any application that uses the affected DecryptingKey::decrypt, decrypt_digest, or decrypt_der functions. No authentication is required; the attack is purely network-based if the application exposes the decryption functionality to untrusted input [2]. The root cause is the lack of length validation before calling split_at at three locations in the internal decrypt() function, where the expected lengths (e.g., 65 bytes for C1, 32 bytes for digest) are assumed but not checked [2][4].
Impact
Successful exploitation results in a denial of service: the Rust runtime panics and the thread (or entire process) terminates. This can be used to disrupt services that rely on SM2 decryption, such as secure messaging or certificate handling. The vulnerability does not lead to information disclosure or code execution; it is strictly a crash-based DoS [1][2].
Mitigation
The issue has been patched in commit e60e991, which replaces all split_at calls with split_at_checked and returns an Error on failure instead of panicking [4]. Users should update to any version containing this fix (e.g., the next release after 0.14.0-rc.0). No workaround is available other than applying the patch or avoiding the use of the affected functions with untrusted ciphertext [2].
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
sm2crates.io | >= 0.14.0-pre.0, <= 0.14.0-rc.4 | — |
Affected products
2- Range: 0.14.0-pre.0, 0.14.0-rc.0
- RustCrypto/elliptic-curvesv5Range: = 0.14.0-pre.0
Patches
1e60e99167a9asm2: fix SM2PKE ciphertext parsing DoS [SECURITY] (#1603)
1 file changed · +4 −4
sm2/src/pke/decrypting.rs+4 −4 modified@@ -157,13 +157,13 @@ fn decrypt( secret_scalar: &Scalar, mode: Mode, hasher: &mut dyn DynDigest, - cipher: &[u8], + ciphertext: &[u8], ) -> Result<Vec<u8>> { let q = U256::from_be_hex(FieldElement::MODULUS); let c1_len = q.bits().div_ceil(8) * 2 + 1; // B1: get 𝐶1 from 𝐶 - let (c1, c) = cipher.split_at(c1_len as usize); + let (c1, c) = ciphertext.split_at_checked(c1_len as usize).ok_or(Error)?; let encoded_c1 = EncodedPoint::from_bytes(c1).map_err(Error::from)?; // verify that point c1 satisfies the elliptic curve @@ -182,10 +182,10 @@ fn decrypt( let digest_size = hasher.output_size(); let (c2, c3) = match mode { Mode::C1C3C2 => { - let (c3, c2) = c.split_at(digest_size); + let (c3, c2) = c.split_at_checked(digest_size).ok_or(Error)?; (c2, c3) } - Mode::C1C2C3 => c.split_at(c.len() - digest_size), + Mode::C1C2C3 => c.split_at_checked(c.len() - digest_size).ok_or(Error)?, }; // B4: compute 𝑡 = 𝐾𝐷𝐹(𝑥2 ∥ 𝑦2, 𝑘𝑙𝑒𝑛)
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-j9xq-69pf-pcm8ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-22700ghsaADVISORY
- github.com/RustCrypto/elliptic-curves/commit/e60e99167a9a2b187ebe80c994c5204b0fdaf4abghsax_refsource_MISCWEB
- github.com/RustCrypto/elliptic-curves/pull/1603ghsax_refsource_MISCWEB
- github.com/RustCrypto/elliptic-curves/security/advisories/GHSA-j9xq-69pf-pcm8ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.