1use std::{
6 ffi::{c_void, CString},
7 os::raw::c_uint,
8 path::PathBuf,
9 ptr, slice,
10};
11
12use libcryptsetup_rs_sys::{
13 crypt_params_integrity, crypt_params_loopaes, crypt_params_luks1, crypt_params_luks2,
14 crypt_params_plain, crypt_params_tcrypt, crypt_params_verity,
15};
16
17use crate::{
18 consts::{
19 flags::{CryptTcrypt, CryptVerity},
20 vals::EncryptionFormat,
21 },
22 device::CryptDevice,
23 err::LibcryptErr,
24 settings::{CryptPbkdfType, CryptPbkdfTypeRef},
25};
26
27pub trait CryptParams {
28 fn as_ptr(&mut self) -> *mut c_void;
29}
30
31impl CryptParams for () {
32 fn as_ptr(&mut self) -> *mut c_void {
33 ptr::null_mut()
34 }
35}
36
37pub struct CryptParamsLuks1Ref<'a> {
39 inner: libcryptsetup_rs_sys::crypt_params_luks1,
42 #[allow(dead_code)]
43 reference: &'a CryptParamsLuks1,
44 #[allow(dead_code)]
45 hash_cstring: CString,
46 #[allow(dead_code)]
47 data_device_cstring: Option<CString>,
48}
49
50pub struct CryptParamsLuks1 {
52 #[allow(missing_docs)]
53 pub hash: String,
54 #[allow(missing_docs)]
55 pub data_alignment: usize,
56 #[allow(missing_docs)]
57 pub data_device: Option<PathBuf>,
58}
59
60impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_luks1> for CryptParamsLuks1 {
61 type Error = LibcryptErr;
62
63 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_luks1) -> Result<Self, Self::Error> {
64 Ok(CryptParamsLuks1 {
65 hash: from_str_ptr_to_owned!(v.hash)?,
66 data_alignment: v.data_alignment,
67 data_device: match ptr_to_option!(v.data_device) {
68 Some(s) => Some(PathBuf::from(from_str_ptr_to_owned!(s)?)),
69 None => None,
70 },
71 })
72 }
73}
74
75impl<'a> TryInto<CryptParamsLuks1Ref<'a>> for &'a CryptParamsLuks1 {
76 type Error = LibcryptErr;
77
78 fn try_into(self) -> Result<CryptParamsLuks1Ref<'a>, Self::Error> {
79 let hash_cstring = to_cstring!(self.hash)?;
80 let data_device_cstring = match self.data_device {
81 Some(ref dd) => Some(path_to_cstring!(dd)?),
82 None => None,
83 };
84
85 let inner = libcryptsetup_rs_sys::crypt_params_luks1 {
86 hash: hash_cstring.as_ptr(),
87 data_alignment: self.data_alignment,
88 data_device: data_device_cstring
89 .as_ref()
90 .map(|dd| dd.as_ptr())
91 .unwrap_or(ptr::null()),
92 };
93 Ok(CryptParamsLuks1Ref {
94 inner,
95 reference: self,
96 hash_cstring,
97 data_device_cstring,
98 })
99 }
100}
101
102impl CryptParams for CryptParamsLuks1Ref<'_> {
103 fn as_ptr(&mut self) -> *mut c_void {
104 (&mut self.inner as *mut crypt_params_luks1).cast::<c_void>()
105 }
106}
107
108pub struct CryptParamsLuks2Ref<'a> {
111 #[allow(missing_docs)]
112 inner: libcryptsetup_rs_sys::crypt_params_luks2,
113 #[allow(dead_code)]
114 reference: &'a CryptParamsLuks2,
115 #[allow(dead_code)]
116 pbkdf_type: Option<Box<CryptPbkdfTypeRef<'a>>>,
117 #[allow(dead_code)]
118 integrity_params: Option<Box<CryptParamsIntegrityRef<'a>>>,
119 #[allow(dead_code)]
120 integrity_cstring_opt: Option<CString>,
121 #[allow(dead_code)]
122 data_device_cstring: Option<CString>,
123 #[allow(dead_code)]
124 label_cstring: Option<CString>,
125 #[allow(dead_code)]
126 subsystem_cstring: Option<CString>,
127}
128
129pub struct CryptParamsLuks2 {
131 #[allow(missing_docs)]
132 pub pbkdf: Option<CryptPbkdfType>,
133 #[allow(missing_docs)]
134 pub integrity: Option<String>,
135 #[allow(missing_docs)]
136 pub integrity_params: Option<CryptParamsIntegrity>,
137 #[allow(missing_docs)]
138 pub data_alignment: crate::size_t,
139 #[allow(missing_docs)]
140 pub data_device: Option<PathBuf>,
141 #[allow(missing_docs)]
142 pub sector_size: u32,
143 #[allow(missing_docs)]
144 pub label: Option<String>,
145 #[allow(missing_docs)]
146 pub subsystem: Option<String>,
147}
148
149impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_luks2> for CryptParamsLuks2 {
150 type Error = LibcryptErr;
151
152 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_luks2) -> Result<Self, Self::Error> {
153 Ok(CryptParamsLuks2 {
154 pbkdf: match ptr_to_option_with_reference!(v.pbkdf) {
155 Some(reference) => Some(CryptPbkdfType::try_from(reference)?),
156 None => None,
157 },
158 integrity: match ptr_to_option!(v.integrity) {
159 Some(ptr) => Some(from_str_ptr_to_owned!(ptr)?),
160 None => None,
161 },
162 integrity_params: match ptr_to_option_with_reference!(v.integrity_params) {
163 Some(ptr) => Some(CryptParamsIntegrity::try_from(ptr)?),
164 None => None,
165 },
166 data_alignment: v.data_alignment,
167 data_device: match ptr_to_option!(v.data_device) {
168 Some(ptr) => Some(PathBuf::from(from_str_ptr_to_owned!(ptr)?)),
169 None => None,
170 },
171 sector_size: v.sector_size,
172 label: match ptr_to_option!(v.label) {
173 Some(ptr) => Some(from_str_ptr_to_owned!(ptr)?),
174 None => None,
175 },
176 subsystem: match ptr_to_option!(v.subsystem) {
177 Some(ptr) => Some(from_str_ptr_to_owned!(ptr)?),
178 None => None,
179 },
180 })
181 }
182}
183
184impl<'a> TryInto<CryptParamsLuks2Ref<'a>> for &'a CryptParamsLuks2 {
185 type Error = LibcryptErr;
186
187 fn try_into(self) -> Result<CryptParamsLuks2Ref<'a>, Self::Error> {
188 let pbkdf_type: Option<Box<CryptPbkdfTypeRef<'a>>> = match self.pbkdf {
189 Some(ref pbkdf) => Some(Box::new(pbkdf.try_into()?)),
190 None => None,
191 };
192 let integrity_params: Option<Box<CryptParamsIntegrityRef<'a>>> = match self.integrity_params
193 {
194 Some(ref integrity) => Some(Box::new(integrity.try_into()?)),
195 None => None,
196 };
197
198 let integrity_cstring_opt = match self.integrity {
199 Some(ref intg) => Some(to_cstring!(intg)?),
200 None => None,
201 };
202 let data_device_cstring = match self.data_device {
203 Some(ref dd) => Some(path_to_cstring!(dd)?),
204 None => None,
205 };
206 let label_cstring = match self.label {
207 Some(ref label) => Some(to_cstring!(label)?),
208 None => None,
209 };
210 let subsystem_cstring = match self.subsystem {
211 Some(ref subsystem) => Some(to_cstring!(subsystem)?),
212 None => None,
213 };
214
215 let inner = libcryptsetup_rs_sys::crypt_params_luks2 {
216 pbkdf: pbkdf_type
217 .as_ref()
218 .map(|pt| &pt.inner as *const _)
219 .unwrap_or(ptr::null()),
220 integrity: integrity_cstring_opt
221 .as_ref()
222 .map(|cs| cs.as_ptr())
223 .unwrap_or(ptr::null()),
224 integrity_params: integrity_params
225 .as_ref()
226 .map(|ip| &ip.inner as *const _)
227 .unwrap_or(ptr::null()),
228 data_alignment: self.data_alignment,
229 data_device: data_device_cstring
230 .as_ref()
231 .map(|dd| dd.as_ptr())
232 .unwrap_or(ptr::null()),
233 sector_size: self.sector_size,
234 label: label_cstring
235 .as_ref()
236 .map(|l| l.as_ptr())
237 .unwrap_or(ptr::null()),
238 subsystem: subsystem_cstring
239 .as_ref()
240 .map(|s| s.as_ptr())
241 .unwrap_or(ptr::null()),
242 };
243 Ok(CryptParamsLuks2Ref {
244 inner,
245 reference: self,
246 pbkdf_type,
247 integrity_params,
248 integrity_cstring_opt,
249 data_device_cstring,
250 label_cstring,
251 subsystem_cstring,
252 })
253 }
254}
255
256impl CryptParams for CryptParamsLuks2Ref<'_> {
257 fn as_ptr(&mut self) -> *mut c_void {
258 (&mut self.inner as *mut crypt_params_luks2).cast::<c_void>()
259 }
260}
261
262pub struct CryptParamsVerityRef<'a> {
264 inner: libcryptsetup_rs_sys::crypt_params_verity,
266 #[allow(dead_code)]
267 reference: &'a CryptParamsVerity,
268 #[allow(dead_code)]
269 hash_name_cstring: CString,
270 #[allow(dead_code)]
271 data_device_cstring: CString,
272 #[allow(dead_code)]
273 hash_device_cstring: CString,
274 #[allow(dead_code)]
275 fec_device_cstring: CString,
276}
277
278pub struct CryptParamsVerity {
280 #[allow(missing_docs)]
281 pub hash_name: String,
282 #[allow(missing_docs)]
283 pub data_device: PathBuf,
284 #[allow(missing_docs)]
285 pub hash_device: PathBuf,
286 #[allow(missing_docs)]
287 pub fec_device: PathBuf,
288 #[allow(missing_docs)]
289 pub salt: Vec<u8>,
290 #[allow(missing_docs)]
291 pub hash_type: u32,
292 #[allow(missing_docs)]
293 pub data_block_size: u32,
294 #[allow(missing_docs)]
295 pub hash_block_size: u32,
296 #[allow(missing_docs)]
297 pub data_size: u64,
298 #[allow(missing_docs)]
299 pub hash_area_offset: u64,
300 #[allow(missing_docs)]
301 pub fec_area_offset: u64,
302 #[allow(missing_docs)]
303 pub fec_roots: u32,
304 #[allow(missing_docs)]
305 pub flags: CryptVerity,
306}
307
308impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_verity> for CryptParamsVerity {
309 type Error = LibcryptErr;
310
311 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_verity) -> Result<Self, Self::Error> {
312 Ok(CryptParamsVerity {
313 hash_name: from_str_ptr_to_owned!(v.hash_name)?,
314 data_device: PathBuf::from(from_str_ptr_to_owned!(v.data_device)?),
315 hash_device: PathBuf::from(from_str_ptr_to_owned!(v.hash_device)?),
316 fec_device: PathBuf::from(from_str_ptr_to_owned!(v.fec_device)?),
317 salt: Vec::from(unsafe {
318 std::slice::from_raw_parts(v.salt.cast::<u8>(), v.salt_size as usize)
319 }),
320 hash_type: v.hash_type,
321 data_block_size: v.data_block_size,
322 hash_block_size: v.hash_block_size,
323 data_size: v.data_size,
324 hash_area_offset: v.hash_area_offset,
325 fec_area_offset: v.fec_area_offset,
326 fec_roots: v.fec_roots,
327 flags: CryptVerity::from_bits(v.flags).ok_or(LibcryptErr::InvalidConversion)?,
328 })
329 }
330}
331
332impl<'a> TryInto<CryptParamsVerityRef<'a>> for &'a CryptParamsVerity {
333 type Error = LibcryptErr;
334
335 fn try_into(self) -> Result<CryptParamsVerityRef<'a>, Self::Error> {
336 let hash_name_cstring = to_cstring!(self.hash_name)?;
337 let data_device_cstring = path_to_cstring!(self.data_device)?;
338 let hash_device_cstring = path_to_cstring!(self.hash_device)?;
339 let fec_device_cstring = path_to_cstring!(self.fec_device)?;
340 Ok(CryptParamsVerityRef {
341 inner: libcryptsetup_rs_sys::crypt_params_verity {
342 hash_name: hash_name_cstring.as_ptr(),
343 data_device: data_device_cstring.as_ptr(),
344 hash_device: hash_device_cstring.as_ptr(),
345 fec_device: fec_device_cstring.as_ptr(),
346 salt: self.salt.as_ptr().cast::<libc::c_char>(),
347 salt_size: self.salt.len() as u32,
348 hash_type: self.hash_type,
349 data_block_size: self.data_block_size,
350 hash_block_size: self.hash_block_size,
351 data_size: self.data_size,
352 hash_area_offset: self.hash_area_offset,
353 fec_area_offset: self.fec_area_offset,
354 fec_roots: self.fec_roots,
355 flags: self.flags.bits(),
356 },
357 reference: self,
358 hash_name_cstring,
359 data_device_cstring,
360 hash_device_cstring,
361 fec_device_cstring,
362 })
363 }
364}
365
366impl CryptParams for CryptParamsVerityRef<'_> {
367 fn as_ptr(&mut self) -> *mut c_void {
368 (&mut self.inner as *mut crypt_params_verity).cast::<c_void>()
369 }
370}
371
372pub struct CryptParamsLoopaesRef<'a> {
374 inner: libcryptsetup_rs_sys::crypt_params_loopaes,
376 #[allow(dead_code)]
377 reference: &'a CryptParamsLoopaes,
378 #[allow(dead_code)]
379 hash_cstring: CString,
380}
381
382pub struct CryptParamsLoopaes {
384 #[allow(missing_docs)]
385 pub hash: String,
386 #[allow(missing_docs)]
387 pub offset: u64,
388 #[allow(missing_docs)]
389 pub skip: u64,
390}
391
392impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_loopaes> for CryptParamsLoopaes {
393 type Error = LibcryptErr;
394
395 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_loopaes) -> Result<Self, Self::Error> {
396 Ok(CryptParamsLoopaes {
397 hash: from_str_ptr_to_owned!(v.hash)?,
398 offset: v.offset,
399 skip: v.skip,
400 })
401 }
402}
403
404impl<'a> TryInto<CryptParamsLoopaesRef<'a>> for &'a CryptParamsLoopaes {
405 type Error = LibcryptErr;
406
407 fn try_into(self) -> Result<CryptParamsLoopaesRef<'a>, Self::Error> {
408 let hash_cstring = to_cstring!(self.hash)?;
409 Ok(CryptParamsLoopaesRef {
410 inner: libcryptsetup_rs_sys::crypt_params_loopaes {
411 hash: hash_cstring.as_ptr(),
412 offset: self.offset,
413 skip: self.skip,
414 },
415 reference: self,
416 hash_cstring,
417 })
418 }
419}
420
421impl CryptParams for CryptParamsLoopaesRef<'_> {
422 fn as_ptr(&mut self) -> *mut c_void {
423 (&mut self.inner as *mut crypt_params_loopaes).cast::<c_void>()
424 }
425}
426
427pub struct CryptParamsIntegrityRef<'a> {
430 #[allow(missing_docs)]
431 inner: libcryptsetup_rs_sys::crypt_params_integrity,
432 #[allow(dead_code)]
433 reference: &'a CryptParamsIntegrity,
434 #[allow(dead_code)]
435 integrity_cstring: CString,
436 #[allow(dead_code)]
437 journal_integrity_cstring: CString,
438 #[allow(dead_code)]
439 journal_crypt_cstring: CString,
440}
441
442pub struct CryptParamsIntegrity {
444 #[allow(missing_docs)]
445 pub journal_size: u64,
446 #[allow(missing_docs)]
447 pub journal_watermark: c_uint,
448 #[allow(missing_docs)]
449 pub journal_commit_time: c_uint,
450 #[allow(missing_docs)]
451 pub interleave_sectors: u32,
452 #[allow(missing_docs)]
453 pub tag_size: u32,
454 #[allow(missing_docs)]
455 pub sector_size: u32,
456 #[allow(missing_docs)]
457 pub buffer_sectors: u32,
458 #[allow(missing_docs)]
459 pub integrity: String,
460 #[allow(missing_docs)]
461 pub integrity_key_size: u32,
462 #[allow(missing_docs)]
463 pub journal_integrity: String,
464 #[allow(missing_docs)]
465 pub journal_integrity_key: Vec<u8>,
466 #[allow(missing_docs)]
467 pub journal_crypt: String,
468 #[allow(missing_docs)]
469 pub journal_crypt_key: Vec<u8>,
470}
471
472impl<'a> TryInto<CryptParamsIntegrityRef<'a>> for &'a CryptParamsIntegrity {
473 type Error = LibcryptErr;
474
475 fn try_into(self) -> Result<CryptParamsIntegrityRef<'a>, Self::Error> {
476 let integrity_cstring = to_cstring!(self.integrity)?;
477 let journal_integrity_cstring = to_cstring!(self.journal_integrity)?;
478 let journal_crypt_cstring = to_cstring!(self.journal_crypt)?;
479 let inner = libcryptsetup_rs_sys::crypt_params_integrity {
480 journal_size: self.journal_size,
481 journal_watermark: self.journal_watermark,
482 journal_commit_time: self.journal_commit_time,
483 interleave_sectors: self.interleave_sectors,
484 tag_size: self.tag_size,
485 sector_size: self.sector_size,
486 buffer_sectors: self.buffer_sectors,
487 integrity: integrity_cstring.as_ptr(),
488 integrity_key_size: self.integrity_key_size,
489 journal_integrity: journal_integrity_cstring.as_ptr(),
490 journal_integrity_key: to_byte_ptr!(self.journal_integrity_key),
491 journal_integrity_key_size: self.journal_integrity_key.len() as u32,
492 journal_crypt: journal_crypt_cstring.as_ptr(),
493 journal_crypt_key: to_byte_ptr!(self.journal_crypt_key),
494 journal_crypt_key_size: self.journal_crypt_key.len() as u32,
495 };
496 Ok(CryptParamsIntegrityRef {
497 inner,
498 reference: self,
499 integrity_cstring,
500 journal_integrity_cstring,
501 journal_crypt_cstring,
502 })
503 }
504}
505
506impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_integrity> for CryptParamsIntegrity {
507 type Error = LibcryptErr;
508
509 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_integrity) -> Result<Self, Self::Error> {
510 Ok(CryptParamsIntegrity {
511 journal_size: v.journal_size,
512 journal_watermark: v.journal_watermark,
513 journal_commit_time: v.journal_commit_time,
514 interleave_sectors: v.interleave_sectors,
515 tag_size: v.tag_size,
516 sector_size: v.sector_size,
517 buffer_sectors: v.buffer_sectors,
518 integrity: from_str_ptr_to_owned!(v.integrity)?,
519 integrity_key_size: v.integrity_key_size,
520 journal_integrity: from_str_ptr_to_owned!(v.journal_integrity)?,
521 journal_integrity_key: Vec::from(unsafe {
522 std::slice::from_raw_parts(
523 v.journal_integrity_key.cast::<u8>(),
524 v.journal_integrity_key_size as usize,
525 )
526 }),
527 journal_crypt: from_str_ptr_to_owned!(v.journal_crypt)?,
528 journal_crypt_key: Vec::from(unsafe {
529 std::slice::from_raw_parts(
530 v.journal_crypt_key.cast::<u8>(),
531 v.journal_crypt_key_size as usize,
532 )
533 }),
534 })
535 }
536}
537
538impl CryptParams for CryptParamsIntegrityRef<'_> {
539 fn as_ptr(&mut self) -> *mut c_void {
540 (&mut self.inner as *mut crypt_params_integrity).cast::<c_void>()
541 }
542}
543
544pub struct CryptParamsPlainRef<'a> {
546 inner: libcryptsetup_rs_sys::crypt_params_plain,
548 #[allow(dead_code)]
549 reference: &'a CryptParamsPlain,
550 #[allow(dead_code)]
551 hash_cstring: CString,
552}
553
554pub struct CryptParamsPlain {
556 pub hash: String,
558 pub offset: u64,
560 pub sector_size: u32,
562 pub size: u64,
564 pub skip: u64,
566}
567
568impl<'a> TryInto<CryptParamsPlainRef<'a>> for &'a CryptParamsPlain {
569 type Error = LibcryptErr;
570
571 fn try_into(self) -> Result<CryptParamsPlainRef<'a>, Self::Error> {
572 let hash_cstring = to_cstring!(self.hash)?;
573 Ok(CryptParamsPlainRef {
574 inner: libcryptsetup_rs_sys::crypt_params_plain {
575 hash: hash_cstring.as_ptr(),
576 offset: self.offset,
577 sector_size: self.sector_size,
578 size: self.size,
579 skip: self.skip,
580 },
581 reference: self,
582 hash_cstring,
583 })
584 }
585}
586
587impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_plain> for CryptParamsPlain {
588 type Error = LibcryptErr;
589
590 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_plain) -> Result<Self, Self::Error> {
591 Ok(CryptParamsPlain {
592 hash: from_str_ptr_to_owned!(v.hash)?,
593 offset: v.offset,
594 sector_size: v.sector_size,
595 size: v.size,
596 skip: v.skip,
597 })
598 }
599}
600
601impl CryptParams for CryptParamsPlainRef<'_> {
602 fn as_ptr(&mut self) -> *mut c_void {
603 (&mut self.inner as *mut crypt_params_plain).cast::<c_void>()
604 }
605}
606
607pub struct CryptParamsTcryptRef<'a> {
609 inner: libcryptsetup_rs_sys::crypt_params_tcrypt,
611 #[allow(dead_code)]
612 reference: &'a CryptParamsTcrypt,
613 #[allow(dead_code)]
614 keyfiles_cstrings: Vec<CString>,
615 #[allow(dead_code)]
616 keyfiles_ptrs: Vec<*const libc::c_char>,
617 #[allow(dead_code)]
618 hash_name_cstring: CString,
619 #[allow(dead_code)]
620 cipher_cstring: CString,
621 #[allow(dead_code)]
622 mode_cstring: CString,
623}
624
625pub struct CryptParamsTcrypt {
627 #[allow(missing_docs)]
628 pub passphrase: Option<Vec<u8>>,
629 #[allow(missing_docs)]
630 pub keyfiles: Option<Vec<PathBuf>>,
631 #[allow(missing_docs)]
632 pub hash_name: String,
633 #[allow(missing_docs)]
634 pub cipher: String,
635 #[allow(missing_docs)]
636 pub mode: String,
637 #[allow(missing_docs)]
638 pub key_size: usize,
639 #[allow(missing_docs)]
640 pub flags: CryptTcrypt,
641 #[allow(missing_docs)]
642 pub veracrypt_pim: u32,
643}
644
645impl<'a> TryInto<CryptParamsTcryptRef<'a>> for &'a CryptParamsTcrypt {
646 type Error = LibcryptErr;
647
648 fn try_into(self) -> Result<CryptParamsTcryptRef<'a>, Self::Error> {
649 let mut keyfiles_cstrings = Vec::new();
650 if let Some(ref keyfiles) = self.keyfiles {
651 for keyfile in keyfiles.iter() {
652 keyfiles_cstrings.push(path_to_cstring!(keyfile)?);
653 }
654 }
655 let mut keyfiles_ptrs: Vec<*const libc::c_char> =
656 keyfiles_cstrings.iter().map(|cs| cs.as_ptr()).collect();
657 let hash_name_cstring = to_cstring!(self.hash_name)?;
658 let cipher_cstring = to_cstring!(self.cipher)?;
659 let mode_cstring = to_cstring!(self.mode)?;
660 Ok(CryptParamsTcryptRef {
661 inner: libcryptsetup_rs_sys::crypt_params_tcrypt {
662 passphrase: match self.passphrase {
663 Some(ref pass) => pass.as_ptr().cast::<libc::c_char>(),
664 None => std::ptr::null(),
665 },
666 passphrase_size: match self.passphrase {
667 Some(ref pass) => pass.len(),
668 None => 0,
669 },
670 keyfiles: keyfiles_ptrs.as_mut_ptr(),
671 keyfiles_count: keyfiles_cstrings.len() as u32,
672 hash_name: hash_name_cstring.as_ptr(),
673 cipher: cipher_cstring.as_ptr(),
674 mode: mode_cstring.as_ptr(),
675 flags: self.flags.bits(),
676 key_size: self.key_size,
677 veracrypt_pim: self.veracrypt_pim,
678 },
679 reference: self,
680 keyfiles_cstrings,
681 keyfiles_ptrs,
682 hash_name_cstring,
683 cipher_cstring,
684 mode_cstring,
685 })
686 }
687}
688
689impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_tcrypt> for CryptParamsTcrypt {
690 type Error = LibcryptErr;
691
692 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_tcrypt) -> Result<Self, Self::Error> {
693 let mut keyfiles = Vec::new();
694 let keyfiles_ptrs = unsafe { slice::from_raw_parts(v.keyfiles, v.keyfiles_count as usize) };
695 for keyfile_ptr in keyfiles_ptrs {
696 keyfiles.push(PathBuf::from(from_str_ptr_to_owned!(*keyfile_ptr)?));
697 }
698 Ok(CryptParamsTcrypt {
699 passphrase: ptr_to_option!(v.passphrase).map(|p| {
700 unsafe { slice::from_raw_parts(p.cast::<u8>(), v.passphrase_size) }.to_vec()
701 }),
702 keyfiles: if keyfiles.is_empty() {
703 None
704 } else {
705 Some(keyfiles)
706 },
707 hash_name: from_str_ptr_to_owned!(v.hash_name)?,
708 cipher: from_str_ptr_to_owned!(v.cipher)?,
709 mode: from_str_ptr_to_owned!(v.mode)?,
710 flags: CryptTcrypt::from_bits(v.flags).ok_or(LibcryptErr::InvalidConversion)?,
711 key_size: v.key_size,
712 veracrypt_pim: v.veracrypt_pim,
713 })
714 }
715}
716
717impl CryptParams for CryptParamsTcryptRef<'_> {
718 fn as_ptr(&mut self) -> *mut c_void {
719 (&mut self.inner as *mut crypt_params_tcrypt).cast::<c_void>()
720 }
721}
722
723pub struct CryptFormatHandle<'a> {
725 reference: &'a mut CryptDevice,
726}
727
728impl<'a> CryptFormatHandle<'a> {
729 pub(crate) fn new(reference: &'a mut CryptDevice) -> Self {
730 CryptFormatHandle { reference }
731 }
732
733 pub fn get_type(&mut self) -> Result<EncryptionFormat, LibcryptErr> {
735 EncryptionFormat::from_ptr(ptr_to_result!(mutex!(
736 libcryptsetup_rs_sys::crypt_get_type(self.reference.as_ptr())
737 ))?)
738 }
739
740 pub fn get_default_type() -> Result<EncryptionFormat, LibcryptErr> {
742 EncryptionFormat::from_ptr(ptr_to_result!(mutex!(
743 libcryptsetup_rs_sys::crypt_get_default_type()
744 ))?)
745 }
746}
747
748#[cfg(test)]
749mod test {
750 use super::EncryptionFormat;
751
752 #[test]
753 fn test_encryption_format_partialeq() {
754 #[allow(clippy::eq_op)]
755 {
756 assert_eq!(EncryptionFormat::Luks1, EncryptionFormat::Luks1);
757 }
758 assert_ne!(EncryptionFormat::Luks1, EncryptionFormat::Luks2);
759 }
760
761 #[test]
762 fn test_encryption_format_from_ptr() {
763 for format in &[
764 EncryptionFormat::Integrity,
765 EncryptionFormat::Tcrypt,
766 EncryptionFormat::Verity,
767 EncryptionFormat::Luks2,
768 EncryptionFormat::Loopaes,
769 EncryptionFormat::Luks1,
770 EncryptionFormat::Plain,
771 ] {
772 assert_eq!(
773 EncryptionFormat::from_ptr(format.as_ptr()).unwrap(),
774 *format
775 );
776 }
777 }
778}