VYPR
High severityOSV Advisory· Published Jan 15, 2026· Updated Jan 15, 2026

RustCrypto cmov: thumbv6m-none-eabi compiler emits non-constant time assembly when using cmovnz

CVE-2026-23519

Description

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.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
cmovcrates.io
< 0.4.40.4.4

Affected products

1
  • Range: base64ct-v0.1.0, base64ct-v0.1.1, base64ct-v0.1.2, …

Patches

1
55977257e7c8

cmov: fix portable `cmovnz` for `thumbv6m-none-eabi` (#1332)

https://github.com/RustCrypto/utilsNicsJan 14, 2026via ghsa
2 files changed · +9 5
  • cmov/src/portable.rs+5 5 modified
    @@ -12,7 +12,7 @@ use core::hint::black_box;
     /// Bitwise non-zero: returns `1` if `x != 0`, and otherwise returns `0`.
     macro_rules! bitnz {
         ($value:expr, $bits:expr) => {
    -        ($value | $value.wrapping_neg()) >> ($bits - 1)
    +        black_box(($value | $value.wrapping_neg()) >> ($bits - 1))
         };
     }
     
    @@ -75,13 +75,13 @@ impl CmovEq for u32 {
     impl Cmov for u64 {
         #[inline]
         fn cmovnz(&mut self, value: &Self, condition: Condition) {
    -        let mask = black_box((bitnz!(condition, u8::BITS) as u64).wrapping_sub(1));
    +        let mask = (bitnz!(condition, u8::BITS) as u64).wrapping_sub(1);
             *self = (*self & mask) | (*value & !mask);
         }
     
         #[inline]
         fn cmovz(&mut self, value: &Self, condition: Condition) {
    -        let mask = black_box((1 ^ bitnz!(condition, u8::BITS) as u64).wrapping_sub(1));
    +        let mask = (1 ^ bitnz!(condition, u8::BITS) as u64).wrapping_sub(1);
             *self = (*self & mask) | (*value & !mask);
         }
     }
    @@ -90,12 +90,12 @@ impl CmovEq for u64 {
         #[inline]
         fn cmovne(&self, rhs: &Self, input: Condition, output: &mut Condition) {
             let ne = bitnz!(self ^ rhs, u64::BITS) as u8;
    -        output.cmovnz(&input, black_box(ne));
    +        output.cmovnz(&input, ne);
         }
     
         #[inline]
         fn cmoveq(&self, rhs: &Self, input: Condition, output: &mut Condition) {
             let ne = bitnz!(self ^ rhs, u64::BITS) as u8;
    -        output.cmovnz(&input, black_box(ne ^ 1));
    +        output.cmovnz(&input, ne ^ 1);
         }
     }
    
  • .typos.toml+4 0 modified
    @@ -2,3 +2,7 @@
     extend-exclude = [
         ".git/"
     ]
    +
    +[default.extend-words]
    +# Prefix of Conditional MOVe
    +"CMO" = "CMO"
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.