#[non_exhaustive]pub enum LuksError {
NotLuks {
found: [u8; 6],
},
UnsupportedVersion {
version: u16,
},
Unsupported {
what: &'static str,
value: String,
},
UnlockBudgetExceeded {
slots_tried: usize,
budget_secs: u64,
},
DerivationBudgetExceeded {
iterations: u32,
projected_secs: u64,
budget_secs: u64,
},
ImplausibleStripes {
stripes: usize,
max: usize,
block_size: usize,
},
DerivationMemoryExceeded {
requested_kib: u32,
max_kib: u32,
},
KeyLengthExceeded {
requested: usize,
max: usize,
},
MalformedHeader {
what: &'static str,
need: usize,
got: usize,
},
AuthenticationFailed,
NoActiveKeyslot,
Io(Error),
}Expand description
A LUKS parse or unlock failure. Every variant names the offending value so an investigator can act on it (never a bare “invalid”).
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
NotLuks
The LUKS\xba\xbe magic is absent — not a LUKS container.
UnsupportedVersion
The header version is neither 1 nor 2.
Unsupported
The cipher/mode/hash combination has no validated decrypt path.
Fields
UnlockBudgetExceeded
The keyslot demands more key-derivation work than the wall-clock budget allows. The iteration count comes from the header, so a crafted container can ask for billions of rounds; refusing is the only way the tool stays responsive on hostile input.
A refusal, never a silent reduction: deriving with fewer rounds than the header specifies produces a different key, which would report a wrong An unlock exhausted its TOTAL time budget across all keyslots.
Distinct from Self::DerivationBudgetExceeded, which bounds a single
derivation. LUKS permits 8 keyslots and the header decides how many are
active and what each costs, so a crafted header can stay under the
per-derivation budget on every slot while the sum runs for hours. Each
individual check passes; nothing owns the total. This variant is that
total.
Fields
DerivationBudgetExceeded
passphrase for a container that would in fact have opened.
Fields
ImplausibleStripes
The keyslot’s anti-forensic stripe count is not plausible.
stripes is a header field, so the container chooses it. It multiplies
the key size to give the key-material length the caller then allocates,
and it is the trip count of the AF merge loop — so an unbounded value is
both an allocation and a spin, on the container’s say-so.
LUKS1 fixes the count at 4000 and cryptsetup writes the same for LUKS2, so the ceiling sits far above anything genuine.
Fields
DerivationMemoryExceeded
The Argon2 keyslot demands more memory than the ceiling allows.
Separate from Self::DerivationBudgetExceeded because memory cannot be
bounded the same way: a time cost can be measured and projected, but
attempting an oversized allocation is itself the harm — the process is
killed by the OS before any deadline could fire. argon2::Params caps
m_cost at u32::MAX 1 KiB blocks (4 TiB) and the header chooses the
value, so the ceiling has to be ours.
Fields
KeyLengthExceeded
The header asks to derive a master key longer than the ceiling allows.
A third cost axis, independent of iterations and of Argon2 memory, and
bounded for the same reason as the memory one: the derived-key length
multiplies the work of every PBKDF2 iteration (ceil(dkLen / hLen) HMAC
blocks each), and it sizes an allocation. Crucially it also sizes the
CALIBRATION probe used to project the iteration cost, so leaving it
unbounded makes the measurement itself the denial of service — the guard
has to run before anything is measured or allocated.
Fields
MalformedHeader
The header is structurally malformed (a field runs past the buffer).
AuthenticationFailed
No keyslot could be unlocked with the supplied passphrase, or the derived master key failed the mk-digest check (wrong passphrase).
NoActiveKeyslot
The container carries no active (enabled) keyslot.
Io(Error)
An I/O error reading the container.
Trait Implementations§
Source§impl Error for LuksError
impl Error for LuksError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()