rustsec-2026-0385
debian_rustsec## Summary The `ctutils::Choice` type has mask generation functions for each unsigned integer size (`u8`, `u16`, `u32`, `u64`, `u128`). These are `const fn` and therefore can't reuse the `asm!`-backed mask generation in the `cmov` crate that's otherwise used to ensure constant-time. In releases prior to v0.4.4, the generated code from these functions could include a branch on commonly used platforms. This has been corrected in this release and now verified on several platforms using BINSEC. Additionally, `u128` comparison operations provided via `ctutils::Choice` and intended to work in constant-time were generating branches on 32-bit targets. This has been resolved via a special case implementation of these functions for such targets. ## Impact Branch instructions on secret values can potentially leak such values via covert channels. This can enable attackers to potentially recover such secrets. ## Resolution This has been resolved by calling `Choice::to_u8()` when generating the mask, which in turn uses `black_box` as an optimization barrier. Verification that this resulted in the desired change in the generated assembly across a variety of target CPU architectures was performed by BINSEC, which now runs automatically in CI using `cargo checkct`.
- Published
- unknown
- Last Modified
- unknown
CVSS details not available.
No product information available.
No references available.
No linked vulnerabilities found.
{
"aliases": [],
"categories": [
"crypto-failure"
],
"crate": "ctutils",
"cves": [],
"cvss": 0.0,
"database_specific": {
"severity": ""
},
"date": "2026-10-23",
"deb_packages": [
{
"crate_name": "cargo-c",
"deb_name": "cargo-c",
"version": "0.10.25-1"
},
{
"crate_name": "cargo-debstatus",
"deb_name": "cargo-debstatus",
"version": "0.6.6-2"
},
{
"crate_name": "cargo-outdated",
"deb_name": "cargo-outdated",
"version": "0.19.0-4"
},
{
"crate_name": "debcargo",
"deb_name": "debcargo",
"version": "2.8.4-5"
},
{
"crate_name": "debian-lsp",
"deb_name": "debian-lsp",
"version": "0.1.8-5+b2"
},
{
"crate_name": "doxx",
"deb_name": "doxx",
"version": "0.1.4+ds-1"
},
{
"crate_name": null,
"deb_name": "glome-cli",
"version": "0.3.0-6"
},
{
"crate_name": "hussh",
"deb_name": "hussh",
"version": "0.2.3-1"
},
{
"crate_name": "ctutils",
"deb_name": "librust-ctutils-dev",
"version": "0.4.3-2"
},
{
"crate_name": "rage",
"deb_name": "rage",
"version": "0.12.1-2"
},
{
"crate_name": "magic-wormhole-cli",
"deb_name": "wormhole-rs",
"version": "0.8.1-1"
}
],
"description": "## Summary\n\nThe `ctutils::Choice` type has mask generation functions for each unsigned\ninteger size (`u8`, `u16`, `u32`, `u64`, `u128`). These are `const fn` and\ntherefore can't reuse the `asm!`-backed mask generation in the `cmov` crate\nthat's otherwise used to ensure constant-time.\n\nIn releases prior to v0.4.4, the generated code from these functions could\ninclude a branch on commonly used platforms. This has been corrected in this\nrelease and now verified on several platforms using BINSEC.\n\nAdditionally, `u128` comparison operations provided via `ctutils::Choice` and\nintended to work in constant-time were generating branches on 32-bit targets.\nThis has been resolved via a special case implementation of these functions\nfor such targets.\n\n## Impact\n\nBranch instructions on secret values can potentially leak such values via\ncovert channels. This can enable attackers to potentially recover such secrets.\n\n## Resolution\n\nThis has been resolved by calling `Choice::to_u8()` when generating the mask,\nwhich in turn uses `black_box` as an optimization barrier. Verification that\nthis resulted in the desired change in the generated assembly across a variety\nof target CPU architectures was performed by BINSEC, which now runs\nautomatically in CI using `cargo checkct`.",
"id": "RUSTSEC-2026-0385",
"keywords": [],
"patched_versions": [
">=0.4.4"
],
"source": "debian_rustsec",
"title": "Non-constant-time mask generation and `u128` comparisons",
"url": "https://github.com/RustCrypto/utils/pull/1569"
}