Non-constant-time code generation on ARM32 targets
## Summary While the `cmov` crate has a special backend for `aarch64` which uses special CSEL instructions, on 32-bit ARM it uses a portable pure Rust fallback implementation. This implementation uses a combination of bitwise arithmetic and `core::hint::black_box` to attempt to coerce constant-time code generation out of the optimizer, but the implementation in v0.4.3 and earlier failed to do this on 32-bit ARM targets. ## Impact Branch instructions inserted by the LLVM optimizer on 32-bit targets can be leveraged using various microarchitectural sidechannels like cache timing attacks to learn secret information that `cmov` is designed to protect. ## Details The following assembly was emitted when using `Cmov::cmovnz`, a function which implements a conditional move when a provided value is non-zero: ```asm bne .LBB0_2 mvns r3, r3 ``` This includes a branch instruction `bne`: Branch if Not Equal. ## PoC The following code reproduces the issue: ```rust #![no_std] use cmov::Cmov; #[inline(never)] pub fn test_ct_cmov(a: &mut u8, b: u8, c: u8) { a.cmovnz(&b, c); } ``` ## Resolution `cmov` v0.4.4 includes a portable `black_box`-based tactical mitigation for the issue which coerced the compiler into producing the expected codegen, and additionally v0.4.5 added an `asm!` reimplementation of the problematic mask generation function for ARM32 targets which should guarantee that particular function never contains a branch on such targets.
- Products
- cmov
- Affected versions
- Not specified
- Fixed versions
- 0.4.4
- CVEs
- CVE-2026-23519
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 31 Oct 2026, 20:58 UTC · Revision 1
Source evidence
Non-constant-time code generation on ARM32 targets
core-osv · Original sourcePublished 14 Jan 2026, 12:00 UTC
## Summary While the `cmov` crate has a special backend for `aarch64` which uses special CSEL instructions, on 32-bit ARM it uses a portable pure Rust fallback implementation. This implementation uses a combination of bitwise arithmetic and `core::hint::black_box` to attempt to coerce constant-time code generation out of the optimizer, but the implementation in v0.4.3 and earlier failed to do this on 32-bit ARM targets. ## Impact Branch instructions inserted by the LLVM optimizer on 32-bit targets can be leveraged using various microarchitectural sidechannels like cache timing attacks to learn secret information that `cmov` is designed to protect. ## Details The following assembly was emitted when using `Cmov::cmovnz`, a function which implements a conditional move when a provided value is non-zero: ```asm bne .LBB0_2 mvns r3, r3 ``` This includes a branch instruction `bne`: Branch if Not Equal. ## PoC The following code reproduces the issue: ```rust #![no_std] use cmov::Cmov; #[inline(never)] pub fn test_ct_cmov(a: &mut u8, b: u8, c: u8) { a.cmovnz(&b, c); } ``` ## Resolution `cmov` v0.4.4 includes a portable `black_box`-based tactical mitigation for the issue which coerced the compiler into producing the expected codegen, and additionally v0.4.5 added an `asm!` reimplementation of the problematic mask generation function for ARM32 targets which should guarantee that particular function never contains a branch on such targets.
osv:RUSTSEC-2026-0003
cmov
Fixed versions: 0.4.4
Complete source record
{
"id": "09d35e50f0e8471e5f333e111ffde367ba712ae99180d9cc3b72d2e3a264836c",
"url": "https://osv.dev/vulnerability/RUSTSEC-2026-0003",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "Non-constant-time code generation on ARM32 targets",
"summary": "## Summary While the `cmov` crate has a special backend for `aarch64` which uses special CSEL instructions, on 32-bit ARM it uses a portable pure Rust fallback implementation. This implementation uses a combination of bitwise arithmetic and `core::hint::black_box` to attempt to coerce constant-time code generation out of the optimizer, but the implementation in v0.4.3 and earlier failed to do this on 32-bit ARM targets. ## Impact Branch instructions inserted by the LLVM optimizer on 32-bit targets can be leveraged using various microarchitectural sidechannels like cache timing attacks to learn secret information that `cmov` is designed to protect. ## Details The following assembly was emitted when using `Cmov::cmovnz`, a function which implements a conditional move when a provided value is non-zero: ```asm bne .LBB0_2 mvns r3, r3 ``` This includes a branch instruction `bne`: Branch if Not Equal. ## PoC The following code reproduces the issue: ```rust #![no_std] use cmov::Cmov; #[inline(never)] pub fn test_ct_cmov(a: &mut u8, b: u8, c: u8) { a.cmovnz(&b, c); } ``` ## Resolution `cmov` v0.4.4 includes a portable `black_box`-based tactical mitigation for the issue which coerced the compiler into producing the expected codegen, and additionally v0.4.5 added an `asm!` reimplementation of the problematic mask generation function for ARM32 targets which should guarantee that particular function never contains a branch on such targets.",
"evidence": "osv:RUSTSEC-2026-0003",
"products": [
{
"name": {
"value": "cmov",
"evidence": "/affected/0/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "0.4.4",
"evidence": "/affected/0/ranges"
}
],
"affected_versions": []
}
],
"severity": "high",
"structured": {
"id": "RUSTSEC-2026-0003",
"aliases": [
"CVE-2026-23519",
"GHSA-2gqc-6j2q-83qp",
"RUSTSEC-2026-0003"
],
"metrics": [
{
"type": "CVSS_V4",
"score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N"
}
],
"affected": [
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0.0.0-0"
},
{
"fixed": "0.4.4"
}
]
}
],
"package": {
"name": "cmov",
"purl": "pkg:cargo/cmov",
"ecosystem": "crates.io"
},
"database_specific": {
"cvss": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N",
"source": "https://github.com/rustsec/advisory-db/blob/osv/crates/RUSTSEC-2026-0003.json",
"categories": [
"crypto-failure"
],
"informational": null
},
"ecosystem_specific": {
"affects": {
"os": [],
"arch": [],
"functions": []
},
"affected_functions": null
}
}
],
"modified": "2026-10-23T08:41:35.268663457Z",
"provider": "osv",
"references": [
"https://crates.io/crates/cmov",
"https://rustsec.org/advisories/RUSTSEC-2026-0003.html",
"https://github.com/RustCrypto/utils/commit/55977257e7c82a309d5e8abfdd380a774f0f9778"
],
"provider_metadata": {
"license": "CC-BY-4.0"
}
},
"related_cves": [
{
"value": "CVE-2026-23519",
"evidence": "/aliases"
}
],
"security_relevant": true,
"severity_evidence": "/severity/0/score"
},
"source_id": "core-osv",
"document_id": 412606,
"published_at": "2026-01-14T12:00:00+00:00"
}