CVE-2026-6330(NEON)和 CVE-2026-10097(AVX2)。已在 wolfSSL 5.9.2 中修复。
完整技术报告已发布为
Cryptology ePrint Archive, Paper 2026/1682
(本地副本见 paper/)。参见下方 引用。
ML-KEM(Kyber,FIPS 203)之所以能够抵抗 选择密文攻击, 是因为解封装内部存在一项检查:接收方会重新加密刚刚解密的消息,并且仅当结果与输入密文 完全一致时才返回真正的共享秘密。任何不匹配都会触发隐式拒绝,并返回一个伪随机值。 这项检查就是 Fujisaki-Okamoto 变换,它是将 IND-CCA2 方案与底层可延展的 IND-CPA 方案隔离开的唯一关卡。
wolfSSL 在手写的 SIMD 汇编中实现了该比较, 并且在两个后端上仅比较了密文的一部分。在 ARM64 NEON 上,它比较了大约一半, 这一点由 Nicholas Carlini (维基百科)发现并报告 (CVE-2026-6330)。在 x86-64 AVX2 上,它比较了 ML-KEM-1024 中 1568 字节中的 1536 字节 (CVE-2026-10097)。
在任一后端上,被篡改的密文都会被当作合法密文接受,这被报告为对 IND-CCA2 安全性的削弱。
本报告表明该缺陷在两个后端上影响更为深远。检查跳过的字节会泄露解封装的解密噪声,
而该噪声是秘密密钥的线性函数,因此可以通过
最小二乘回归 恢复密钥。这不是一个
格问题,也不是经典的密钥不匹配攻击:在 AVX2 后端上,该缺陷验证了全部 u,
因此那些攻击所需的选定 u 密文会被拒绝。相反,解密噪声回归从未被检查的 v 系数中恢复密钥。
在 AVX2 和 NEON 两个后端上,针对运行中的易受攻击二进制文件,端到端地恢复了完整的
ML-KEM-1024 私钥。
该攻击需要重用 ML-KEM 密钥:HPKE 接收方、KEMTLS,或固定及嵌入的密钥。 临时混合 TLS 1.3 密钥共享每次握手使用新密钥, 无法通过这种方式恢复密钥;在那里该缺陷仅是区分性破坏。两个缺陷均已修复并公开, 本报告为披露后撰写。
“运行中”是指在真实二进制上演示的结果:NEON 需要更多密文(600 对 350), 因为其每系数测量噪声大得多(约 4 倍)。“模型”是一种无噪声检查, 验证回归能否恢复完整密钥(全部 2048 个系数,100%);其密文数量由每个密文产生的方程数决定, 而非噪声,因此与运行中数字不可比,也不反映攻击难度。
两个缺陷均在同一 wolfSSL 发布窗口内被独立发现,并在
5.9.2 中一并修复
(两个 CVE 条目参见 wolfSSL
安全漏洞页面)。
Carlini 的 NEON 缺陷被记录为 IND-CCA2 削弱,而 AVX2 缺陷被列为密钥恢复 CVE。
本仓库中的解密噪声回归攻击在两个后端上均能恢复密钥。后端特定细节见
neon-cve-2026-6330/ 和
avx2-cve-2026-10097/。
wolfSSL 的 ML-KEM 隐式拒绝检查中存在不完整比较,出现在两个 SIMD 汇编后端中。 它比较的密文字节少于全部,因此解封装会接受正确实现会拒绝的密文。 未检查的字节将解封装变成了解密噪声的预言机,当密钥被重用时,这足以恢复私钥。
如果您在包含易受攻击 SIMD 汇编的构建上使用带 ML-KEM 的 wolfSSL,则您会受影响: 5.7.0-5.9.1 中的 AVX2(x86-64),或 5.7.4-5.9.1 中的 ARM64 NEON。 密钥恢复攻击额外需要 ML-KEM 私钥在多次解封装之间重用,例如 HPKE 接收方、 KEMTLS,或固定或嵌入的密钥。 临时混合 TLS 1.3 密钥共享每次握手使用新密钥,无法恢复密钥;在那里该缺陷仅是区分性破坏。 修复位于 wolfSSL 5.9.2 中。
在任一后端上恢复完整的 ML-KEM-1024 秘密密钥,方法是发送精心构造的解封装查询, 并观察每次查询返回的是真实秘密还是拒绝值。针对运行中的二进制, 这大约需要 10^5 到 10^6 次解封装查询即可恢复密钥。
取未检查区域中的一个密文系数。其明文位由舍入决定,m'_j = Compress_1(v_j - (s^T u)_j)。
由于这些字节未被比较,扫描 v_j 的压缩值并观察唯一变化的解封装输出,
即可定位舍入边界,边界位置以约 ±q/64 的精度测量解密噪声 δ_j。
以秘密 (s, e) 和攻击者选择的加密随机性表示:
δ_j = ( e^T y - s^T(e1 + c_u) + e2 + c_v )_j (验证精确;小;永不模 q 回绕)
这是关于 2048 系数秘密 (s, e) 的线性方程,系数为攻击者所知。
每个密文为每个未检查系数提供一个这样的方程。堆叠足够多的密文并求解正规方程即可恢复整个密钥,
最后几个系数由公钥关系 e = t - A·s ∈ CBD(η) 固定。这是普通最小二乘,
而非格问题。
两个后端在泄露量上有所不同。NEON 留下约 50% 的密文未检查(三个频带中的 125 个系数), 而 AVX2 约为 2%(一个频带中的 51 个系数)。NEON 仍需要更多密文, 因为其未检查字节不连续且每系数测量噪声更大,因此此处泄露更多并不会使恢复更容易。
明文检查和密钥不匹配攻击(Ravi 等人 2020,Qin 等人 2021,Băetu 等人 2019)
通过提交具有攻击者选择的稀疏 u 的密文来隔离每次查询中的一个秘密系数,
从而在几千次查询内恢复密钥。AVX2 缺陷会拒绝所有这些攻击:它仅跳过 v 的 32 字节,
并验证整个 u,因此在运行中的二进制上,稀疏 u 密文会被拒绝,
翻转单个 u 位在 30 次尝试中 30 次被拒绝。NEON 缺陷范围更广,
还留下约一半的 u 未检查,因此该论证是 AVX2 特有的;但攻击并不依赖于此。
解密噪声回归在两个后端上从未检查的 v 系数中恢复密钥,
在每种缺陷保留的检查部分下依然有效。
因此,相关的先例不是那些密钥不匹配攻击,而是解密失败攻击 (D'Anvers 等人 2019,参考文献 6)。它们利用相同的解密噪声项——秘密的线性函数—— 但仅通过该术语跨越解码边界并导致解密失败的罕见事件,因此那里的恢复是统计性的, 需要多得多的密文。而不完整比较使同一术语可直接测量,精度约 ±q/64, 因此无需失败事件,攻击简化为上述普通最小二乘回归。
在两个后端的忠实参考模型(kyber-py)中,上述恒等式被验证为精确, 回归恢复了全部 2048 个秘密系数。针对修复前 wolfSSL 运行中二进制, 攻击重用的导出密钥,每个测试框架在报告任何数字之前都会对照预言机导出的真实密钥进行自检:
(s, e) 的 98.0%。单独的秘密 s 在 350 个密文时为
1005/1024 = 98.1%,即 CVE 中记录的数字。(s, e) 的 2018/2048 = 98.5%,
求解器误差单调收敛至精确。恢复的密钥是预言机导出的 wolfSSL 生成的密钥对,攻击针对的是发布形式的 SIMD 汇编,
而非其模型。完整记录:
avx2-cve-2026-10097/live_recover_avx2.out、
neon-cve-2026-6330/live_recover_neon.out。
升级到 wolfSSL 5.9.2 或更高版本 (AVX2 的 PR #10430,NEON 的 PR #10192)。
高,但并非灾难性。它需要重用密钥、接受/拒绝预言机,以及大量但可行的查询次数。 这不是侧信道: 没有时序或功耗测量,只是比较中的逻辑缺陷。它不影响正确实现或 ML-KEM 标准本身。 作为对比,liboqs 的 ML-KEM 解封装中编译器引起的时序泄露 (CVE-2024-36405), 这是 2024 年 ML-KEM 时序泄露浪潮中与 KyberSlash 相关的完整秘密密钥恢复问题, 被 NIST 评为 CVSS 7.5。
各后端的攻击代码、分析和复现步骤见
avx2-cve-2026-10097/ 和
neon-cve-2026-6330/。
本仓库记录了同一 wolfSSL 发布窗口中的两个姊妹发现,以及一个同时攻破两者的攻击。
两个问题均在本报告发布前私下报告、修复并分配了 CVE。已在 wolfSSL 5.9.2 中修复。
完整报告已发布为
Cryptology ePrint Archive, Paper 2026/1682
(本地副本:paper/)。
@misc{cryptoeprint:2026/1682,
author = {Bhabani Sankar Das},
title = {Incomplete Ciphertext Comparison in {ML}-{KEM}: From an {IND}-{CCA2} Break to Key Recovery},
howpublished = {Cryptology {ePrint} Archive, Paper 2026/1682},
year = {2026},
url = {https://eprint.iacr.org/2026/1682}
}
| NEON (CVE-2026-6330) | AVX2 (CVE-2026-10097) |
|---|
| 后端 | ARM64 NEON | x86-64 AVX2 |
| 缺陷 | 比较约一半密文 | 比较 1568 字节中的 1536 字节 |
| 缺陷报告者 | Nicholas Carlini(Anthropic) | 007bsd |
| CVE 严重性 | 中(CVSS 4.0 6.3,CWE-327) | 高(CVSS 4.0 8.3,CWE-697) |
| 密钥恢复,模型 | 完整(约 500 个密文) | 完整(约 1300 个密文) |
| 密钥恢复,运行中二进制 | 98.5% @ 600 个密文(QEMU 模拟) | 98.1% @ 350 个密文(原生) |
| 修复 | PR #10192 | PR #10430 |