cryptsetup_rs/
luks2.rs

1use std::convert::TryFrom;
2use std::fs::File;
3use std::path::Path;
4
5use uuid::Uuid;
6
7use blkid_rs::{Luks2Header, LuksHeader};
8
9use crate::api::{crypt_pbkdf_algo_type, crypt_token_info, CryptDeviceHandle};
10use crate::api::{CryptDeviceType, Luks2CryptDevice, LuksCryptDevice};
11use crate::device::{
12    Error, Keyslot, Luks2FormatPbkdf, Luks2TokenHandlerBox, Luks2TokenHandlerRaw, Luks2TokenId, Result,
13};
14use crate::luks2_meta::Luks2Token;
15
16/// Struct for storing LUKS2 parameters in memory
17#[derive(Debug, PartialEq)]
18pub struct Luks2Params {
19    label: Option<String>,
20    subsystem: Option<String>,
21    seqid: u64,
22    header_size: u64,
23    header_offset: u64,
24    // TODO do we need to expose others?
25}
26
27impl Luks2Params {
28    pub(crate) fn from(header: impl Luks2Header) -> Result<Luks2Params> {
29        let label = header.label()?.map(|s| s.to_owned());
30        let subsystem = header.subsystem()?.map(|s| s.to_owned());
31        let seqid = header.seqid();
32        let header_size = header.header_size();
33        let header_offset = header.header_offset();
34        Ok(Luks2Params {
35            label,
36            subsystem,
37            seqid,
38            header_size,
39            header_offset,
40        })
41    }
42
43    pub(crate) fn from_path<P: AsRef<Path>>(path: P) -> Result<Luks2Params> {
44        let device_file = File::open(path.as_ref())?;
45        match LuksHeader::read(device_file)? {
46            LuksHeader::Luks2(v2) => Luks2Params::from(v2),
47            _ => Err(Error::InvalidLuksVersion),
48        }
49    }
50}
51
52impl LuksCryptDevice for CryptDeviceHandle<Luks2Params> {
53    fn activate(&mut self, name: &str, key: &[u8]) -> Result<u8> {
54        crate::device::luks_activate(&mut self.cd, name, key)
55    }
56
57    fn deactivate(self, name: &str) -> Result<()> {
58        crate::device::deactivate(self.cd, name)
59    }
60
61    fn destroy_keyslot(&mut self, slot: Keyslot) -> Result<()> {
62        crate::device::luks_destroy_keyslot(&mut self.cd, slot)
63    }
64
65    fn keyslot_status(&self, keyslot: Keyslot) -> raw::crypt_keyslot_info {
66        crate::device::keyslot_status(&self.cd, keyslot)
67    }
68
69    fn dump(&self) {
70        crate::device::dump(&self.cd).expect("Dump should be fine for initialised device")
71    }
72
73    fn uuid(&self) -> Uuid {
74        crate::device::uuid(&self.cd).expect("Initialised device should have UUID")
75    }
76
77    fn add_keyslot(
78        &mut self,
79        key: &[u8],
80        maybe_prev_key: Option<&[u8]>,
81        maybe_keyslot: Option<Keyslot>,
82    ) -> Result<Keyslot> {
83        crate::device::luks_add_keyslot(&mut self.cd, key, maybe_prev_key, maybe_keyslot)
84    }
85
86    fn update_keyslot(&mut self, key: &[u8], prev_key: &[u8], maybe_keyslot: Option<Keyslot>) -> Result<Keyslot> {
87        crate::device::luks_update_keyslot(&mut self.cd, key, prev_key, maybe_keyslot)
88    }
89}
90
91impl Luks2CryptDevice for CryptDeviceHandle<Luks2Params> {
92    fn register_new_token_handler<Handler: Luks2TokenHandlerRaw>() -> Result<Luks2TokenHandlerBox<Handler>> {
93        let b = Luks2TokenHandlerBox::new();
94        Self::register_token_handler(&b)?;
95        Ok(b)
96    }
97
98    fn register_token_handler<Handler: Luks2TokenHandlerRaw>(handler: &Luks2TokenHandlerBox<Handler>) -> Result<()> {
99        crate::device::luks2_register_token_handler::<Handler>(handler)
100    }
101
102    fn token_status(&mut self, token_id: Luks2TokenId) -> (crypt_token_info, Option<String>) {
103        crate::device::luks2_token_status(&mut self.cd, token_id)
104    }
105
106    fn get_token(&mut self, token_id: Luks2TokenId) -> Result<Luks2Token> {
107        let json = crate::device::luks2_token_json(&mut self.cd, token_id)?;
108        let token = Luks2Token::try_from(json.as_str()).map_err(|err| Error::InvalidJson(format!("{}", err)))?;
109        Ok(token)
110    }
111
112    fn add_token_with_id(&mut self, token: &Luks2Token, token_id: Luks2TokenId) -> Result<()> {
113        let js = String::try_from(token).map_err(|err| Error::InvalidJson(format!("{}", err)))?;
114        crate::device::luks2_token_json_allocate(&mut self.cd, js.as_str(), Some(token_id))?;
115        Ok(())
116    }
117
118    fn add_token(&mut self, token: &Luks2Token) -> Result<Luks2TokenId> {
119        let js = String::try_from(token).map_err(|err| Error::InvalidJson(format!("{}", err)))?;
120        crate::device::luks2_token_json_allocate(&mut self.cd, js.as_str(), None)
121    }
122
123    fn remove_token(&mut self, token_id: Luks2TokenId) -> Result<()> {
124        crate::device::luks2_token_remove(&mut self.cd, token_id)
125    }
126
127    fn assign_token_to_keyslot(&mut self, token_id: Luks2TokenId, keyslot_opt: Option<Keyslot>) -> Result<()> {
128        crate::device::luks2_token_assign_keyslot(&mut self.cd, token_id, keyslot_opt)
129    }
130
131    fn unassign_token_keyslot(&mut self, token_id: Luks2TokenId, keyslot_opt: Option<Keyslot>) -> Result<()> {
132        crate::device::luks2_token_unassign_keyslot(&mut self.cd, token_id, keyslot_opt)
133    }
134
135    fn token_keyslot_is_assigned(&mut self, token_id: Luks2TokenId, keyslot: Keyslot) -> Result<bool> {
136        crate::device::luks2_token_is_assigned(&mut self.cd, token_id, keyslot)
137    }
138
139    fn activate_with_token(&mut self, name: &str, token_id: Luks2TokenId) -> Result<Keyslot> {
140        crate::device::luks2_activate_by_token(&mut self.cd, Some(name), Some(token_id))
141    }
142
143    fn check_activation_with_token(&mut self, token_id: Luks2TokenId) -> Result<Keyslot> {
144        crate::device::luks2_activate_by_token(&mut self.cd, None, Some(token_id))
145    }
146
147    fn set_pbkdf_params(
148        &mut self,
149        type_: crypt_pbkdf_algo_type,
150        hash: &str,
151        time_ms: u32,
152        iterations: u32,
153        max_memory_kb: u32,
154        parallel_threads: u32,
155    ) -> Result<()> {
156        let params = Luks2FormatPbkdf {
157            type_,
158            hash,
159            time_ms,
160            iterations,
161            max_memory_kb,
162            parallel_threads,
163            flags: 0,
164        };
165        crate::device::luks2_set_pbkdf_type(&mut self.cd, &params)
166    }
167}
168
169impl CryptDeviceType for CryptDeviceHandle<Luks2Params> {
170    fn device_type(&self) -> raw::crypt_device_type {
171        raw::crypt_device_type::LUKS2
172    }
173}