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        if libcryptsetup_rs_sys::CRYPT_KDF_PBKDF2 == unsafe { CStr::from_ptr(ptr) }.to_bytes() {
197            Ok(CryptKdf::Pbkdf2)
198        } else if libcryptsetup_rs_sys::CRYPT_KDF_ARGON2I
199            == unsafe { CStr::from_ptr(ptr) }.to_bytes()
200        {
201            Ok(CryptKdf::Argon2I)
202        } else if libcryptsetup_rs_sys::CRYPT_KDF_ARGON2ID
203            == unsafe { CStr::from_ptr(ptr) }.to_bytes()
204        {
205            Ok(CryptKdf::Argon2Id)
206        } else {
207            Err(LibcryptErr::InvalidConversion)
208        }
209    }
210}
211
212consts_to_from_enum!(
213    /// Rust representation of random number generator enum
214    CryptRng,
215    u32,
216    Urandom => libcryptsetup_rs_sys::CRYPT_RNG_URANDOM,
217    Random => libcryptsetup_rs_sys::CRYPT_RNG_RANDOM
218);
219
220/// LUKS type (1 or 2)
221#[derive(Debug, Eq, PartialEq)]
222pub enum LuksType {
223    #[allow(missing_docs)]
224    Luks1,
225    #[allow(missing_docs)]
226    Luks2,
227}
228
229impl LuksType {
230    /// Convert Rust expression to an equivalent C pointer
231    pub(crate) fn as_ptr(&self) -> *const c_char {
232        match *self {
233            LuksType::Luks1 => libcryptsetup_rs_sys::CRYPT_LUKS1.as_ptr().cast::<c_char>(),
234            LuksType::Luks2 => libcryptsetup_rs_sys::CRYPT_LUKS2.as_ptr().cast::<c_char>(),
235        }
236    }
237}
238
239consts_to_from_enum!(
240    /// Status of a crypt device
241    CryptStatusInfo, u32,
242    Invalid => libcryptsetup_rs_sys::crypt_status_info_CRYPT_INVALID,
243    Inactive => libcryptsetup_rs_sys::crypt_status_info_CRYPT_INACTIVE,
244    Active => libcryptsetup_rs_sys::crypt_status_info_CRYPT_ACTIVE,
245    Busy => libcryptsetup_rs_sys::crypt_status_info_CRYPT_BUSY
246);
247
248consts_to_from_enum!(
249    /// Pattern for disk wipe
250    CryptWipePattern, u32,
251    Zero => libcryptsetup_rs_sys::crypt_wipe_pattern_CRYPT_WIPE_ZERO,
252    Random => libcryptsetup_rs_sys::crypt_wipe_pattern_CRYPT_WIPE_RANDOM,
253    EncryptedZero => libcryptsetup_rs_sys::crypt_wipe_pattern_CRYPT_WIPE_ENCRYPTED_ZERO,
254    Special => libcryptsetup_rs_sys::crypt_wipe_pattern_CRYPT_WIPE_SPECIAL
255);
256
257/// Size allocated for metadata
258#[derive(Debug, PartialEq, Eq, Copy, Clone)]
259pub enum MetadataSize {
260    #[allow(missing_docs)]
261    Default,
262    #[allow(missing_docs)]
263    Kb16,
264    #[allow(missing_docs)]
265    Kb32,
266    #[allow(missing_docs)]
267    Kb64,
268    #[allow(missing_docs)]
269    Kb128,
270    #[allow(missing_docs)]
271    Kb256,
272    #[allow(missing_docs)]
273    Kb512,
274    #[allow(missing_docs)]
275    Kb1024,
276    #[allow(missing_docs)]
277    Kb2048,
278    #[allow(missing_docs)]
279    Kb4096,
280}
281
282impl TryFrom<u64> for MetadataSize {
283    type Error = LibcryptErr;
284
285    fn try_from(v: u64) -> Result<Self, Self::Error> {
286        let size = match v {
287            i if i == *MetadataSize::Default => MetadataSize::Default,
288            i if i == *MetadataSize::Kb16 => MetadataSize::Kb16,
289            i if i == *MetadataSize::Kb32 => MetadataSize::Kb32,
290            i if i == *MetadataSize::Kb64 => MetadataSize::Kb64,
291            i if i == *MetadataSize::Kb128 => MetadataSize::Kb128,
292            i if i == *MetadataSize::Kb256 => MetadataSize::Kb256,
293            i if i == *MetadataSize::Kb512 => MetadataSize::Kb512,
294            i if i == *MetadataSize::Kb1024 => MetadataSize::Kb1024,
295            i if i == *MetadataSize::Kb2048 => MetadataSize::Kb2048,
296            i if i == *MetadataSize::Kb4096 => MetadataSize::Kb4096,
297            _ => return Err(LibcryptErr::InvalidConversion),
298        };
299        Ok(size)
300    }
301}
302
303impl Deref for MetadataSize {
304    type Target = u64;
305
306    fn deref(&self) -> &u64 {
307        match *self {
308            MetadataSize::Default => &0,
309            MetadataSize::Kb16 => &0x4000,
310            MetadataSize::Kb32 => &0x8000,
311            MetadataSize::Kb64 => &0x10000,
312            MetadataSize::Kb128 => &0x20000,
313            MetadataSize::Kb256 => &0x40000,
314            MetadataSize::Kb512 => &0x80000,
315            MetadataSize::Kb1024 => &0x100000,
316            MetadataSize::Kb2048 => &0x200000,
317            MetadataSize::Kb4096 => &0x400000,
318        }
319    }
320}
321
322/// Size in bytes for the keyslots.
323///
324/// The value must be divisible by a 4KB block and no larger than
325/// 128MB.
326#[derive(Debug, PartialEq, Eq, Copy, Clone)]
327pub struct KeyslotsSize(u64);
328
329impl KeyslotsSize {
330    // 4KB block size in bytes
331    const FOUR_KB: u64 = 1 << 12;
332    // 128MB max size in bytes
333    const MAX_MB: u64 = 1 << 27;
334}
335
336impl Deref for KeyslotsSize {
337    type Target = u64;
338
339    fn deref(&self) -> &u64 {
340        &self.0
341    }
342}
343
344impl TryFrom<u64> for KeyslotsSize {
345    type Error = LibcryptErr;
346
347    fn try_from(v: u64) -> Result<Self, Self::Error> {
348        // Must be divisible by 4KB and less than or equal to 128MB
349        if v > Self::MAX_MB || v % Self::FOUR_KB != 0 {
350            return Err(LibcryptErr::InvalidConversion);
351        }
352
353        Ok(KeyslotsSize(v))
354    }
355}
356
357/// State of memory lock
358#[derive(Debug, Eq, PartialEq)]
359pub enum LockState {
360    #[allow(missing_docs)]
361    Unlocked = 0,
362    #[allow(missing_docs)]
363    Locked = 1,
364}
365
366impl From<c_int> for LockState {
367    fn from(v: c_int) -> Self {
368        match v {
369            i if i == LockState::Unlocked as c_int => LockState::Unlocked,
370            _ => LockState::Locked,
371        }
372    }
373}
374
375#[cfg(test)]
376mod test {
377    use super::*;
378
379    #[test]
380    fn test_metadata_size() {
381        assert_eq!(MetadataSize::try_from(0).unwrap(), MetadataSize::Default);
382        assert_eq!(MetadataSize::try_from(0x4000).unwrap(), MetadataSize::Kb16);
383        assert_eq!(MetadataSize::try_from(0x10000).unwrap(), MetadataSize::Kb64);
384        assert!(MetadataSize::try_from(0x10001).is_err());
385    }
386
387    #[test]
388    fn test_keyslots_size() {
389        // Default
390        assert!(KeyslotsSize::try_from(0).is_ok());
391        // Exactly 128MB
392        assert!(KeyslotsSize::try_from(1 << 27).is_ok());
393        // Greater than 128MB
394        assert!(KeyslotsSize::try_from(1 << 28).is_err());
395        // Less than 4KB
396        assert!(KeyslotsSize::try_from(1 << 11).is_err());
397        // Exactly 4KB
398        assert!(KeyslotsSize::try_from(1 << 12).is_ok());
399        // Greater than 4KB and not divisible by 4KB
400        assert!(KeyslotsSize::try_from(4097).is_err());
401
402        // Assert that derefs are equal to the starting value
403        assert!(*KeyslotsSize::try_from(1 << 27).unwrap() == (1 << 27));
404    }
405}