CVE-2026-46344
Description
liboqs is a C-language cryptographic library that provides implementations of post-quantum cryptography algorithms. Prior to 0.16.0, an out-of-bounds read has been identified in the XMSS and XMSS^MT stateful signature verification code. When the verification function is called with a correctly-sized signature buffer for the declared algorithm but a public key whose OID bytes (pk[0..3]) reference a different XMSS parameter set with a larger sig_bytes, the implementation re-parses the OID from the public key inside xmss_sign_open / xmssmt_sign_open and uses the resulting (larger) sig_bytes to index the caller-supplied signature buffer. As with CVE-2026-44518, the out-of-bounds bytes are consumed only as input to an internal hash computation and are not returned to the caller, so no oracle exists to leak their contents to an attacker. The primary observable effect is a possible crash (denial of service) of the verifying process if the read crosses into an unmapped memory page. This vulnerability is fixed in 0.16.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Out-of-bounds read in liboqs XMSS/XMSS^MT signature verification when public key OID mismatches declared algorithm, leading to potential denial of service.
Vulnerability
An out-of-bounds read exists in the XMSS and XMSS^MT stateful signature verification code of liboqs prior to version 0.16.0 [1]. When the verification function is called with a signature buffer correctly sized for the declared algorithm but a public key whose OID bytes (pk[0..3]) reference a different XMSS parameter set with a larger sig_bytes, the implementation re-parses the OID from the public key inside xmss_sign_open / xmssmt_sign_open and uses the resulting larger sig_bytes to index the caller-supplied signature buffer. This issue is distinct from but related to CVE-2026-44518 [1].
Exploitation
An attacker must supply a public key with a mismatched OID and a signature buffer sized for the declared algorithm. The attacker does not need authentication if the caller accepts public keys from untrusted sources (e.g., firmware update metadata, certificate stores) [1]. The verification function then reads out-of-bounds bytes from the signature buffer. The out-of-bounds bytes are consumed only as input to an internal hash computation and are not returned to the caller, so no oracle exists to leak their contents [1]. The primary observable effect is a possible crash if the read crosses into an unmapped memory page [1].
Impact
The primary impact is denial of service (crash) of the verifying process [1]. No mechanism has been identified by which the out-of-bounds data could influence the verification result to cause an invalid signature to be accepted, nor by which their contents could be exfiltrated [1]. Therefore, confidentiality and integrity are not affected.
Mitigation
The vulnerability is fixed in liboqs version 0.16.0 and in the main branch via commit 077e32a [1][2]. The fix validates the OID mismatch at the wrapper layer, preventing the out-of-bounds read. Users should update to 0.16.0 or later. As a workaround, ensure that public keys are obtained from trusted sources and that the declared algorithm matches the public key's OID [1]. No KEV listing is known.
AI Insight generated on May 29, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2(expand)+ 1 more
- (no CPE)
- (no CPE)range: <0.16.0
Patches
1077e32a94f39Merge commit from fork
2 files changed · +33 −1
src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c+12 −0 modified@@ -76,6 +76,18 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss##xmss_v##_verify(const uint8_t *message if (signature_len != OQS_SIG_STFL_alg_xmss##xmss_v##_length_signature) {\ return OQS_ERROR;\ }\ + if (public_key == NULL) {\ + return OQS_ERROR;\ + }\ + /* Reject pks whose OID disagrees with the variant the caller invoked. */\ + /* Without this, a mutated OID can steer xmss_sign_open into a parameter */\ + /* set whose sig_bytes exceeds signature_len, causing an OOB read in */\ + /* xmss_commons.c (GHSA-2wxh-55qf-c7wg). */\ + uint32_t pk_oid = ((uint32_t)public_key[0] << 24) | ((uint32_t)public_key[1] << 16)\ + | ((uint32_t)public_key[2] << 8) | ((uint32_t)public_key[3]);\ + if (pk_oid != (uint32_t)OQS_SIG_STFL_alg_xmss##xmss_v##_oid) {\ + return OQS_ERROR;\ + }\ return OQS_SIG_STFL_alg_xmss##mt##_verify(message, message_len, signature, signature_len, public_key);\ }\ \
tests/test_sig_stfl.c+21 −1 modified@@ -435,8 +435,28 @@ static OQS_STATUS test_invalid_sig(const char *method_name) { uint8_t message[] = "test"; uint8_t malicious_sig[TEST_INVALID_SIG_MALICIOUS_SIG_LEN] = {0}; - // This triggers the bug via proper API + // Sub-case 1 (GHSA-wf7v-fhxj-73m2): caller-supplied signature_len shorter than the + // declared algorithm's expected size. Must be rejected by the wrapper length check. OQS_STATUS status = OQS_SIG_STFL_verify(sig, message, sizeof(message) - 1, malicious_sig, TEST_INVALID_SIG_MALICIOUS_SIG_LEN, pk); + if (status == OQS_SUCCESS) { + OQS_SIG_STFL_free(sig); + return OQS_ERROR; + } + + // Sub-case 2 (GHSA-2wxh-55qf-c7wg): correctly-sized signature buffer for the declared + // algorithm, but the pk's OID bytes reference a different parameter set. Pre-fix, this + // caused xmssmt_core_sign_open to index sig_bytes (derived from the mutated OID) past + // the end of the caller-supplied signature buffer (OOB read, see xmss_commons.c). + // Post-fix, the wrapper rejects the OID mismatch before the OOB read. + uint8_t *full_sig = OQS_MEM_malloc(sig->length_signature); + if (full_sig == NULL) { + OQS_SIG_STFL_free(sig); + return OQS_ERROR; + } + memset(full_sig, 0, sig->length_signature); + pk[TEST_XMSS_OID_LEN - 1] = 0x02; // mirrors the GHSA-2wxh-55qf-c7wg PoC for XMSS-SHA2_10_256 + status = OQS_SIG_STFL_verify(sig, message, sizeof(message) - 1, full_sig, sig->length_signature, pk); + OQS_MEM_insecure_free(full_sig); OQS_SIG_STFL_free(sig); if (status == OQS_SUCCESS) { return OQS_ERROR;
Vulnerability mechanics
Root cause
"Missing validation that the OID encoded in the public key matches the declared algorithm's compile-time OID constant allows an out-of-bounds read during signature verification."
Attack vector
An attacker supplies a public key whose first four OID bytes (`pk[0..3]`) encode a different XMSS parameter set with a larger `sig_bytes` than the declared algorithm. The per-variant verify wrapper validates the signature buffer length against the declared algorithm's compile-time constant but does not check that the OID in the public key matches that constant. Control flows to `xmss_sign_open`, which re-parses the OID from the public key and uses the inflated `sig_bytes` to index the caller-supplied signature buffer, causing an out-of-bounds read. The out-of-bounds bytes are consumed only as input to an internal hash computation and are not returned to the attacker, so the primary impact is a crash (denial of service) if the read crosses an unmapped memory page [ref_id=1].
Affected code
The out-of-bounds read occurs in `xmssmt_core_sign_open` in `src/sig_stfl/xmss/external/xmss_commons.c` (line 194), reached via `xmss_sign_open` / `xmssmt_sign_open` in `src/sig_stfl/xmss/external/xmss.c`. The per-variant verify wrappers in `src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c` are the entry point where the missing OID consistency check allowed the mismatch to propagate [ref_id=1].
What the fix does
The fix adds an OID consistency check at the wrapper layer in `src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c`. The per-variant verify wrapper now decodes `pk[0..3]` as a big-endian OID and rejects the call if it does not equal the variant's compile-time OID constant. This prevents control from reaching `xmss_sign_open` with a mismatched OID, closing the out-of-bounds read vector that the earlier length check (CVE-2026-44518 fix) did not address [ref_id=1][patch_id=3105908].
Preconditions
- inputThe caller must accept a public key from an untrusted or tampered source (e.g., firmware update metadata, TUF metadata, or certificate stores).
- inputThe public key's first four bytes must encode an OID for a different XMSS parameter set with a larger sig_bytes than the declared algorithm.
- inputThe signature buffer must be sized correctly for the declared algorithm (passing the wrapper's length check).
Generated on May 29, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
0No linked articles in our index yet.