libcryptsetup_rs/consts/
vals.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use std::{ffi::CStr, ops::Deref};
6
7use libc::{c_char, c_int};
8
9use crate::err::LibcryptErr;
10
11consts_to_from_enum!(
12    /// Debug log level
13    CryptDebugLevel, c_int,
14    All => libcryptsetup_rs_sys::CRYPT_DEBUG_ALL as c_int,
15    Json => libcryptsetup_rs_sys::CRYPT_DEBUG_JSON as c_int,
16    None => libcryptsetup_rs_sys::CRYPT_DEBUG_NONE as c_int
17);
18
19/// Device formatting type options
20#[derive(Debug, Eq, PartialEq)]
21pub enum EncryptionFormat {
22    #[allow(missing_docs)]
23    Plain,
24    #[allow(missing_docs)]
25    Luks1,
26    #[allow(missing_docs)]
27    Luks2,
28    #[allow(missing_docs)]
29    Loopaes,
30    #[allow(missing_docs)]
31    Verity,
32    #[allow(missing_docs)]
33    Tcrypt,
34    #[allow(missing_docs)]
35    Integrity,
36}
37
38impl EncryptionFormat {
39    /// Get `EncryptionFormat` as a char pointer
40    pub(crate) fn as_ptr(&self) -> *const c_char {
41        match *self {
42            EncryptionFormat::Plain => libcryptsetup_rs_sys::CRYPT_PLAIN.as_ptr().cast::<c_char>(),
43            EncryptionFormat::Luks1 => libcryptsetup_rs_sys::CRYPT_LUKS1.as_ptr().cast::<c_char>(),
44            EncryptionFormat::Luks2 => libcryptsetup_rs_sys::CRYPT_LUKS2.as_ptr().cast::<c_char>(),
45            EncryptionFormat::Loopaes => libcryptsetup_rs_sys::CRYPT_LOOPAES
46                .as_ptr()
47                .cast::<c_char>(),
48            EncryptionFormat::Verity => {
49                libcryptsetup_rs_sys::CRYPT_VERITY.as_ptr().cast::<c_char>()
50            }
51            EncryptionFormat::Tcrypt => {
52                libcryptsetup_rs_sys::CRYPT_TCRYPT.as_ptr().cast::<c_char>()
53            }
54            EncryptionFormat::Integrity => libcryptsetup_rs_sys::CRYPT_INTEGRITY
55                .as_ptr()
56                .cast::<c_char>(),
57        }
58    }
59
60    /// Get `EncryptionFormat` from a char pointer
61    pub(crate) fn from_ptr(p: *const c_char) -> Result<Self, LibcryptErr> {
62        let p_bytes = unsafe { CStr::from_ptr(p) }.to_bytes_with_nul();
63        if libcryptsetup_rs_sys::CRYPT_PLAIN == p_bytes {
64            Ok(EncryptionFormat::Plain)
65        } else if libcryptsetup_rs_sys::CRYPT_LUKS1 == p_bytes {
66            Ok(EncryptionFormat::Luks1)
67        } else if libcryptsetup_rs_sys::CRYPT_LUKS2 == p_bytes {
68            Ok(EncryptionFormat::Luks2)
69        } else if libcryptsetup_rs_sys::CRYPT_LOOPAES == p_bytes {
70            Ok(EncryptionFormat::Loopaes)
71        } else if libcryptsetup_rs_sys::CRYPT_VERITY == p_bytes {
72            Ok(EncryptionFormat::Verity)
73        } else if libcryptsetup_rs_sys::CRYPT_TCRYPT == p_bytes {
74            Ok(EncryptionFormat::Tcrypt)
75        } else if libcryptsetup_rs_sys::CRYPT_INTEGRITY == p_bytes {
76            Ok(EncryptionFormat::Integrity)
77        } else {
78            Err(LibcryptErr::InvalidConversion)
79        }
80    }
81}
82
83consts_to_from_enum!(
84    /// Value indicating the status of a keyslot
85    KeyslotInfo,
86    u32,
87    Invalid => libcryptsetup_rs_sys::crypt_keyslot_info_CRYPT_SLOT_INVALID,
88    Inactive => libcryptsetup_rs_sys::crypt_keyslot_info_CRYPT_SLOT_INACTIVE,
89    Active => libcryptsetup_rs_sys::crypt_keyslot_info_CRYPT_SLOT_ACTIVE,
90    ActiveLast => libcryptsetup_rs_sys::crypt_keyslot_info_CRYPT_SLOT_ACTIVE_LAST,
91    Unbound => libcryptsetup_rs_sys::crypt_keyslot_info_CRYPT_SLOT_UNBOUND
92);
93
94consts_to_from_enum!(
95    /// Value indicating the priority of a keyslot
96    KeyslotPriority,
97    i32,
98    Invalid => libcryptsetup_rs_sys::crypt_keyslot_priority_CRYPT_SLOT_PRIORITY_INVALID,
99    Ignore => libcryptsetup_rs_sys::crypt_keyslot_priority_CRYPT_SLOT_PRIORITY_IGNORE,
100    Normal => libcryptsetup_rs_sys::crypt_keyslot_priority_CRYPT_SLOT_PRIORITY_NORMAL,
101    Prefer => libcryptsetup_rs_sys::crypt_keyslot_priority_CRYPT_SLOT_PRIORITY_PREFER
102);
103
104/// Logging levels
105#[derive(Debug, Eq, PartialEq)]
106pub enum CryptLogLevel {
107    #[allow(missing_docs)]
108    Normal = libcryptsetup_rs_sys::CRYPT_LOG_NORMAL as isize,
109    #[allow(missing_docs)]
110    Error = libcryptsetup_rs_sys::CRYPT_LOG_ERROR as isize,
111    #[allow(missing_docs)]
112    Verbose = libcryptsetup_rs_sys::CRYPT_LOG_VERBOSE as isize,
113    #[allow(missing_docs)]
114    Debug = libcryptsetup_rs_sys::CRYPT_LOG_DEBUG as isize,
115    #[allow(missing_docs)]
116    DebugJson = libcryptsetup_rs_sys::CRYPT_LOG_DEBUG_JSON as isize,
117}
118
119impl TryFrom<c_int> for CryptLogLevel {
120    type Error = LibcryptErr;
121
122    fn try_from(v: c_int) -> Result<Self, <Self as TryFrom<c_int>>::Error> {
123        let level = match v {
124            i if i == CryptLogLevel::Normal as c_int => CryptLogLevel::Normal,
125            i if i == CryptLogLevel::Error as c_int => CryptLogLevel::Error,
126            i if i == CryptLogLevel::Verbose as c_int => CryptLogLevel::Verbose,
127            i if i == CryptLogLevel::Debug as c_int => CryptLogLevel::Debug,
128            i if i == CryptLogLevel::DebugJson as c_int => CryptLogLevel::DebugJson,
129            _ => return Err(LibcryptErr::InvalidConversion),
130        };
131        Ok(level)
132    }
133}
134
135pub(crate) enum CryptFlagsType {
136    Activation = libcryptsetup_rs_sys::crypt_flags_type_CRYPT_FLAGS_ACTIVATION as isize,
137    Requirements = libcryptsetup_rs_sys::crypt_flags_type_CRYPT_FLAGS_REQUIREMENTS as isize,
138}
139
140consts_to_from_enum!(
141    /// Encryption mode flags
142    CryptReencryptInfo,
143    u32,
144    None => libcryptsetup_rs_sys::crypt_reencrypt_info_CRYPT_REENCRYPT_NONE,
145    Clean => libcryptsetup_rs_sys::crypt_reencrypt_info_CRYPT_REENCRYPT_CLEAN,
146    Crash => libcryptsetup_rs_sys::crypt_reencrypt_info_CRYPT_REENCRYPT_CRASH,
147    Invalid => libcryptsetup_rs_sys::crypt_reencrypt_info_CRYPT_REENCRYPT_INVALID
148);
149
150consts_to_from_enum!(
151    /// Encryption mode flags
152    CryptReencryptModeInfo,
153    u32,
154    Reencrypt => libcryptsetup_rs_sys::crypt_reencrypt_mode_info_CRYPT_REENCRYPT_REENCRYPT,
155    Encrypt => libcryptsetup_rs_sys::crypt_reencrypt_mode_info_CRYPT_REENCRYPT_ENCRYPT,
156    Decrypt => libcryptsetup_rs_sys::crypt_reencrypt_mode_info_CRYPT_REENCRYPT_DECRYPT
157);
158
159consts_to_from_enum!(
160    /// Reencryption direction flags
161    CryptReencryptDirectionInfo,
162    u32,
163    Forward => libcryptsetup_rs_sys::crypt_reencrypt_direction_info_CRYPT_REENCRYPT_FORWARD,
164    Backward => libcryptsetup_rs_sys::crypt_reencrypt_direction_info_CRYPT_REENCRYPT_BACKWARD
165);
166
167/// Rust representation of key generator enum
168#[derive(Debug, Eq, PartialEq)]
169pub enum CryptKdf {
170    #[allow(missing_docs)]
171    Pbkdf2,
172    #[allow(missing_docs)]
173    Argon2I,
174    #[allow(missing_docs)]
175    Argon2Id,
176}
177
178impl CryptKdf {
179    /// Convert to a `char *` for C
180    pub(crate) fn as_ptr(&self) -> *const c_char {
181        match *self {
182            CryptKdf::Pbkdf2 => libcryptsetup_rs_sys::CRYPT_KDF_PBKDF2
183                .as_ptr()
184                .cast::<c_char>(),
185            CryptKdf::Argon2I => libcryptsetup_rs_sys::CRYPT_KDF_ARGON2I
186                .as_ptr()
187                .cast::<c_char>(),
188            CryptKdf::Argon2Id => libcryptsetup_rs_sys::CRYPT_KDF_ARGON2ID
189                .as_ptr()
190                .cast::<c_char>(),
191        }
192    }
193
194    /// Convert from a C `char *`
195    pub(crate) fn from_ptr(ptr: *const c_char) -> Result<Self, LibcryptErr> {
196        let p_bytes = unsafe { CStr::from_ptr(ptr) }.to_bytes_with_nul();
197        if libcryptsetup_rs_sys::CRYPT_KDF_PBKDF2 == p_bytes {
198            Ok(CryptKdf::Pbkdf2)
199        } else if libcryptsetup_rs_sys::CRYPT_KDF_ARGON2I == p_bytes {
200            Ok(CryptKdf::Argon2I)
201        } else if libcryptsetup_rs_sys::CRYPT_KDF_ARGON2ID == p_bytes {
202            Ok(CryptKdf::Argon2Id)
203        } else {
204            Err(LibcryptErr::InvalidConversion)
205        }
206    }
207}
208
209consts_to_from_enum!(
210    /// Rust representation of random number generator enum
211    CryptRng,
212    u32,
213    Urandom => libcryptsetup_rs_sys::CRYPT_RNG_URANDOM,
214    Random => libcryptsetup_rs_sys::CRYPT_RNG_RANDOM
215);
216
217/// LUKS type (1 or 2)
218#[derive(Debug, Eq, PartialEq)]
219pub enum LuksType {
220    #[allow(missing_docs)]
221    Luks1,
222    #[allow(missing_docs)]
223    Luks2,
224}
225
226impl LuksType {
227    /// Convert Rust expression to an equivalent C pointer
228    pub(crate) fn as_ptr(&self) -> *const c_char {
229        match *self {
230            LuksType::Luks1 => libcryptsetup_rs_sys::CRYPT_LUKS1.as_ptr().cast::<c_char>(),
231            LuksType::Luks2 => libcryptsetup_rs_sys::CRYPT_LUKS2.as_ptr().cast::<c_char>(),
232        }
233    }
234}
235
236consts_to_from_enum!(
237    /// Status of a crypt device
238    CryptStatusInfo, u32,
239    Invalid => libcryptsetup_rs_sys::crypt_status_info_CRYPT_INVALID,
240    Inactive => libcryptsetup_rs_sys::crypt_status_info_CRYPT_INACTIVE,
241    Active => libcryptsetup_rs_sys::crypt_status_info_CRYPT_ACTIVE,
242    Busy => libcryptsetup_rs_sys::crypt_status_info_CRYPT_BUSY
243);
244
245consts_to_from_enum!(
246    /// Pattern for disk wipe
247    CryptWipePattern, u32,
248    Zero => libcryptsetup_rs_sys::crypt_wipe_pattern_CRYPT_WIPE_ZERO,
249    Random => libcryptsetup_rs_sys::crypt_wipe_pattern_CRYPT_WIPE_RANDOM,
250    EncryptedZero => libcryptsetup_rs_sys::crypt_wipe_pattern_CRYPT_WIPE_ENCRYPTED_ZERO,
251    Special => libcryptsetup_rs_sys::crypt_wipe_pattern_CRYPT_WIPE_SPECIAL
252);
253
254/// Size allocated for metadata
255#[derive(Debug, PartialEq, Eq, Copy, Clone)]
256pub enum MetadataSize {
257    #[allow(missing_docs)]
258    Default,
259    #[allow(missing_docs)]
260    Kb16,
261    #[allow(missing_docs)]
262    Kb32,
263    #[allow(missing_docs)]
264    Kb64,
265    #[allow(missing_docs)]
266    Kb128,
267    #[allow(missing_docs)]
268    Kb256,
269    #[allow(missing_docs)]
270    Kb512,
271    #[allow(missing_docs)]
272    Kb1024,
273    #[allow(missing_docs)]
274    Kb2048,
275    #[allow(missing_docs)]
276    Kb4096,
277}
278
279impl TryFrom<u64> for MetadataSize {
280    type Error = LibcryptErr;
281
282    fn try_from(v: u64) -> Result<Self, Self::Error> {
283        let size = match v {
284            i if i == *MetadataSize::Default => MetadataSize::Default,
285            i if i == *MetadataSize::Kb16 => MetadataSize::Kb16,
286            i if i == *MetadataSize::Kb32 => MetadataSize::Kb32,
287            i if i == *MetadataSize::Kb64 => MetadataSize::Kb64,
288            i if i == *MetadataSize::Kb128 => MetadataSize::Kb128,
289            i if i == *MetadataSize::Kb256 => MetadataSize::Kb256,
290            i if i == *MetadataSize::Kb512 => MetadataSize::Kb512,
291            i if i == *MetadataSize::Kb1024 => MetadataSize::Kb1024,
292            i if i == *MetadataSize::Kb2048 => MetadataSize::Kb2048,
293            i if i == *MetadataSize::Kb4096 => MetadataSize::Kb4096,
294            _ => return Err(LibcryptErr::InvalidConversion),
295        };
296        Ok(size)
297    }
298}
299
300impl Deref for MetadataSize {
301    type Target = u64;
302
303    fn deref(&self) -> &u64 {
304        match *self {
305            MetadataSize::Default => &0,
306            MetadataSize::Kb16 => &0x4000,
307            MetadataSize::Kb32 => &0x8000,
308            MetadataSize::Kb64 => &0x10000,
309            MetadataSize::Kb128 => &0x20000,
310            MetadataSize::Kb256 => &0x40000,
311            MetadataSize::Kb512 => &0x80000,
312            MetadataSize::Kb1024 => &0x100000,
313            MetadataSize::Kb2048 => &0x200000,
314            MetadataSize::Kb4096 => &0x400000,
315        }
316    }
317}
318
319/// Size in bytes for the keyslots.
320///
321/// The value must be divisible by a 4KB block and no larger than
322/// 128MB.
323#[derive(Debug, PartialEq, Eq, Copy, Clone)]
324pub struct KeyslotsSize(u64);
325
326impl KeyslotsSize {
327    // 4KB block size in bytes
328    const FOUR_KB: u64 = 1 << 12;
329    // 128MB max size in bytes
330    const MAX_MB: u64 = 1 << 27;
331}
332
333impl Deref for KeyslotsSize {
334    type Target = u64;
335
336    fn deref(&self) -> &u64 {
337        &self.0
338    }
339}
340
341impl TryFrom<u64> for KeyslotsSize {
342    type Error = LibcryptErr;
343
344    fn try_from(v: u64) -> Result<Self, Self::Error> {
345        // Must be divisible by 4KB and less than or equal to 128MB
346        if v > Self::MAX_MB || v % Self::FOUR_KB != 0 {
347            return Err(LibcryptErr::InvalidConversion);
348        }
349
350        Ok(KeyslotsSize(v))
351    }
352}
353
354/// State of memory lock
355#[derive(Debug, Eq, PartialEq)]
356pub enum LockState {
357    #[allow(missing_docs)]
358    Unlocked = 0,
359    #[allow(missing_docs)]
360    Locked = 1,
361}
362
363impl From<c_int> for LockState {
364    fn from(v: c_int) -> Self {
365        match v {
366            i if i == LockState::Unlocked as c_int => LockState::Unlocked,
367            _ => LockState::Locked,
368        }
369    }
370}
371
372#[cfg(test)]
373mod test {
374    use super::*;
375
376    #[test]
377    fn test_metadata_size() {
378        assert_eq!(MetadataSize::try_from(0).unwrap(), MetadataSize::Default);
379        assert_eq!(MetadataSize::try_from(0x4000).unwrap(), MetadataSize::Kb16);
380        assert_eq!(MetadataSize::try_from(0x10000).unwrap(), MetadataSize::Kb64);
381        assert!(MetadataSize::try_from(0x10001).is_err());
382    }
383
384    #[test]
385    fn test_keyslots_size() {
386        // Default
387        assert!(KeyslotsSize::try_from(0).is_ok());
388        // Exactly 128MB
389        assert!(KeyslotsSize::try_from(1 << 27).is_ok());
390        // Greater than 128MB
391        assert!(KeyslotsSize::try_from(1 << 28).is_err());
392        // Less than 4KB
393        assert!(KeyslotsSize::try_from(1 << 11).is_err());
394        // Exactly 4KB
395        assert!(KeyslotsSize::try_from(1 << 12).is_ok());
396        // Greater than 4KB and not divisible by 4KB
397        assert!(KeyslotsSize::try_from(4097).is_err());
398
399        // Assert that derefs are equal to the starting value
400        assert!(*KeyslotsSize::try_from(1 << 27).unwrap() == (1 << 27));
401    }
402}