diff --git a/Cargo.lock b/Cargo.lock index 3bf0ef6..6c65268 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,7 +410,7 @@ dependencies = [ [[package]] name = "fido2luks" -version = "0.2.19" +version = "0.2.20" dependencies = [ "ctap_hmac", "failure", diff --git a/Cargo.toml b/Cargo.toml index 1e589c5..62bf0f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fido2luks" -version = "0.2.19" +version = "0.2.20" authors = ["shimunn "] edition = "2018" diff --git a/src/cli.rs b/src/cli.rs index 02c4434..1e07bdf 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -259,6 +259,7 @@ pub fn run_cli() -> Fido2LuksResult<()> { secret, name, retries, + allow_discards, .. } | Command::OpenToken { @@ -267,6 +268,7 @@ pub fn run_cli() -> Fido2LuksResult<()> { secret, name, retries, + allow_discards, } => { let pin_string; let pin = if authenticator.pin { @@ -299,7 +301,9 @@ pub fn run_cli() -> Fido2LuksResult<()> { loop { let secret = match &args.command { Command::Open { credentials, .. } => secret(Cow::Borrowed(&credentials.ids.0)) - .and_then(|(secret, _cred)| luks_dev.activate(&name, &secret, luks.slot)), + .and_then(|(secret, _cred)| { + luks_dev.activate(&name, &secret, luks.slot, *allow_discards) + }), Command::OpenToken { .. } => luks_dev.activate_token( &name, Box::new(|credentials: Vec| { @@ -311,6 +315,7 @@ pub fn run_cli() -> Fido2LuksResult<()> { .map(|(secret, cred)| (secret, hex::encode(&cred.id))) }), luks.slot, + *allow_discards, ), _ => unreachable!(), }; diff --git a/src/cli_args/mod.rs b/src/cli_args/mod.rs index 048ae33..f3bb0fd 100644 --- a/src/cli_args/mod.rs +++ b/src/cli_args/mod.rs @@ -216,6 +216,9 @@ pub enum Command { secret: SecretParameters, #[structopt(short = "r", long = "max-retries", default_value = "0")] retries: i32, + /// Pass SSD trim instructions to the underlying block device + #[structopt(long = "allow-discards")] + allow_discards: bool, }, /// Open the LUKS device using credentials embedded in the LUKS 2 header #[structopt(name = "open-token")] @@ -230,6 +233,9 @@ pub enum Command { secret: SecretParameters, #[structopt(short = "r", long = "max-retries", default_value = "0")] retries: i32, + /// Pass SSD trim instructions to the underlying block device + #[structopt(long = "allow-discards")] + allow_discards: bool, }, /// Generate a new FIDO credential #[structopt(name = "credential")] diff --git a/src/luks.rs b/src/luks.rs index 6996eef..f753b9d 100644 --- a/src/luks.rs +++ b/src/luks.rs @@ -1,8 +1,8 @@ use crate::error::*; use libcryptsetup_rs::{ - CryptActivateFlags, CryptDevice, CryptInit, CryptTokenInfo, EncryptionFormat, KeyslotInfo, - TokenInput, + CryptActivateFlag, CryptActivateFlags, CryptDevice, CryptInit, CryptTokenInfo, + EncryptionFormat, KeyslotInfo, TokenInput, }; use std::collections::{HashMap, HashSet}; use std::path::Path; @@ -221,10 +221,15 @@ impl LuksDevice { name: &str, secret: &[u8], slot_hint: Option, + allow_discard: bool, ) -> Fido2LuksResult { + let mut flags = CryptActivateFlags::empty(); + if allow_discard { + flags = CryptActivateFlags::new(vec![CryptActivateFlag::AllowDiscards]); + } self.device .activate_handle() - .activate_by_passphrase(Some(name), slot_hint, secret, CryptActivateFlags::empty()) + .activate_by_passphrase(Some(name), slot_hint, secret, flags) .map_err(LuksError::activate) } @@ -233,6 +238,7 @@ impl LuksDevice { name: &str, secret: impl Fn(Vec) -> Fido2LuksResult<([u8; 32], String)>, slot_hint: Option, + allow_discard: bool, ) -> Fido2LuksResult { if !self.is_luks2()? { return Err(LuksError::Luks2Required.into()); @@ -276,7 +282,7 @@ impl LuksDevice { .chain(std::iter::once(None).take(slots.is_empty() as usize)), // Try all slots as last resort ); for slot in slots { - match self.activate(name, &secret, slot) { + match self.activate(name, &secret, slot, allow_discard) { Err(Fido2LuksError::WrongSecret) => (), res => return res, }