1use std::{ffi::CStr, ops::Deref};
6
7use libc::{c_char, c_int};
8
9use crate::err::LibcryptErr;
10
11consts_to_from_enum!(
12 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#[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 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 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 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 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#[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 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 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 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#[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 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 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 CryptRng,
212 u32,
213 Urandom => libcryptsetup_rs_sys::CRYPT_RNG_URANDOM,
214 Random => libcryptsetup_rs_sys::CRYPT_RNG_RANDOM
215);
216
217#[derive(Debug, Eq, PartialEq)]
219pub enum LuksType {
220 #[allow(missing_docs)]
221 Luks1,
222 #[allow(missing_docs)]
223 Luks2,
224}
225
226impl LuksType {
227 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 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 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#[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#[derive(Debug, PartialEq, Eq, Copy, Clone)]
324pub struct KeyslotsSize(u64);
325
326impl KeyslotsSize {
327 const FOUR_KB: u64 = 1 << 12;
329 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 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#[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 assert!(KeyslotsSize::try_from(0).is_ok());
388 assert!(KeyslotsSize::try_from(1 << 27).is_ok());
390 assert!(KeyslotsSize::try_from(1 << 28).is_err());
392 assert!(KeyslotsSize::try_from(1 << 11).is_err());
394 assert!(KeyslotsSize::try_from(1 << 12).is_ok());
396 assert!(KeyslotsSize::try_from(4097).is_err());
398
399 assert!(*KeyslotsSize::try_from(1 << 27).unwrap() == (1 << 27));
401 }
402}