GHSA-78p6-6878-8mj6 SM2-PKE has Unchecked AffinePoint Decoding (unwrap) in decrypt()
SummaryA denial-of-service vulnerability exists in the SM2 PKE decryption path where an invalid elliptic-curve point (C1) is decoded and the resulting value is unwrapped without checking. Specifically, `AffinePoint::from_encoded_point(&encoded_c1)` may return a `None`/`CtOption::None` when the supplied coordinates are syntactically valid but do not lie on the SM2 curve. The calling code previously used `.unwrap()`, causing a panic when presented with such input.Affected Component / VersionsFile: `src/pke/decrypting.rs`Function: internal `decrypt()` (invoked by `DecryptingKey::decrypt*` methods)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)DetailsThe library decodes the C1 field (an EC point) as an `EncodedPoint` and then converts it to an `AffinePoint` using `AffinePoint::from_encoded_point(&encoded_c1)`. That conversion returns a `CtOption<AffinePoint>` (or an `Option` equivalent) which will indicate failure when the coordinates do not satisfy the curve equation. The code then called `.unwrap()` on that result, causing a panic when
`None` was returned. Because `EncodedPoint::from_bytes()` only validates format (length and SEC1
encoding) and not mathematical validity, an attacker can craft `C1 = 0x04 || X || Y` with X and Y of the right length that nonetheless do not satisfy the curve. Such inputs will pass the format check but trigger `from_encoded_point()` failure and therefore panic on `.unwrap()`.Proof of Concept (PoC)`examples/poc_der_invalid_point.rs` constructs an ASN.1 DER `Cipher` structure
with `x` and `y` set to arbitrary 32-byte values (e.g., repeating 0x11 and 0x22),
and passes it to `DecryptingKey::decrypt_der`. With the vulnerable code, this
produces a panic originating at the `unwrap()` call in `decrypt()`. Other APIs such as `DecryptingKey::decrypt` also produce a panic with invalid C1 point.Run locally:The process will panic with a backtrace pointing to `src/pke/decrypting.rs` at the `from_encoded_point(...).unwrap()` call.ImpactDenial of Service: an attacker who can submit ciphertext (or DER ciphertext)
can crash the decrypting thread/process.Low attacker effort: crafting random 32-byte X/Y values that are not on the
curve is trivial.Wide exposure: any service that accepts ciphertext and links this library is
vulnerable.Recommended FixDo not call `.unwrap()` on the result of `AffinePoint::from_encoded_point()`.
Instead, convert the `CtOption` to an `Option` (or inspect it) and return a
library `Err` for invalid points. Example minimal fix:This ensures `decrypt()` returns a controlled error for invalid or malformed points instead of panicking.**Credit**This vulnerability was discovered by:XlabAI Team of Tencent Xuanwu LabAtuin Automated Vulnerability Discovery EngineCVE and credit are preferred.If developers have any questions regarding the vulnerability details, please feel free to reach for further discussion via email at xlabai@tencent.com.**Note**This organization follows 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