CVE-2026-23519: RustCrypto cmov: thumbv6m-none-eabi compiler emits non-constant time assembly when using cmovnz
Summary
thumbv6m-none-eabi (Cortex M0, M0+ and M1) compiler emits non-constant time assembly when using cmovnz (portable version). I did not found any other target with the same behaviour but I did not go through all targets supported by Rust.
Details
It seems that, during mask computation, an LLVM optimisation pass is detecting that bitnz is returning 0 or 1, that can be interpreted as a boolean. This intermediate value is not masked by a call to blackbox and thus the subsequent .wrappingsub(1) can be interpreted as a conditional bitwise conditional not.
PoC
This is an attempt at having a minimal faulty code. In a library crate with an up-to-date cmov as only dependency, the content of src/lib.rs is:
rust #![nostd] use cmov::Cmov;
#[inline(never)] pub fn testctcmov(a: &mut u8, b: u8, c: u8) { a.cmovnz(&b, c); }
The resulting assembly emitted (shown using cargo asm --release --target thumbv6m-none-eabi that uses cargo-show-asm):
<details> <summary>Collapsed assembly</summary>
asm .section .text.notct::testctcmov,"ax",%progbits .globl notct::testctcmov .p2align 1 .type notct::testctcmov,%function .code 16 .thumbfunc notct::testctcmov: .fnstart .cfisections .debugframe .cfistartproc .save {r7, lr} push {r7, lr} .cfidefcfaoffset 8 .cfioffset lr, -4 .cfioffset r7, -8 .setfp r7, sp add r7, sp, #0 .cfidefcfaregister r7 .pad #8 sub sp, #8 movs r3, #0 lsls r2, r2, #24 bne .LBB02 mvns r3, r3 .LBB02: ldrb r2, [r0] str r3, [sp, #4] str r3, [sp] mov r3, sp @APP @NOAPP ldr r3, [sp] bics r1, r3 ands r2, r3 adds r1, r2, r1 strb r1, [r0] add sp, #8 pop {r7, pc}
</details>
The non-constant time assembly is:
asm bne .LBB02 mvns r3, r3 .LBB02:
Impact
The exact impact is unclear, especially since cmov clearly warns users that the portable version is best-effort.
Other sources
RustCrypto CMOV provides conditional move CPU intrinsics which are guaranteed on major platforms to execute in constant-time and not be rewritten as branches by the compiler. Prior to 0.4.4, the thumbv6m-none-eabi (Cortex M0, M0+ and M1) compiler emits non-constant time assembly when using cmovnz (portable version). This vulnerability is fixed in 0.4.4.
— MITRE
Affected Software
Remediation
Event History
Frequently Asked Questions
What is the severity of CVE-2026-23519?
CVE-2026-23519 is considered a high-severity vulnerability due to its potential impact on cryptographic operations.
How do I fix CVE-2026-23519?
To mitigate CVE-2026-23519, upgrade to version 0.4.4 of the cmov package.
What is the impact of CVE-2026-23519?
CVE-2026-23519 can lead to timing attacks that compromise the security of sensitive operations.
Who is affected by CVE-2026-23519?
CVE-2026-23519 affects users of the RustCrypto cmov package compiled with the thumbv6m-none-eabi target.
What is cmovnz in relation to CVE-2026-23519?
Cmovnz is an assembly instruction used in the RustCrypto library that can produce non-constant time execution under certain compiler settings.