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: Option<CString>,
274 #[allow(dead_code)]
275 fec_device_cstring: Option<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: Option<PathBuf>,
286 #[allow(missing_docs)]
287 pub fec_device: Option<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: match ptr_to_option!(v.hash_device) {
316 Some(s) => Some(PathBuf::from(from_str_ptr_to_owned!(s)?)),
317 None => None,
318 },
319 fec_device: match ptr_to_option!(v.fec_device) {
320 Some(s) => Some(PathBuf::from(from_str_ptr_to_owned!(s)?)),
321 None => None,
322 },
323 salt: Vec::from(unsafe {
324 std::slice::from_raw_parts(v.salt.cast::<u8>(), v.salt_size as usize)
325 }),
326 hash_type: v.hash_type,
327 data_block_size: v.data_block_size,
328 hash_block_size: v.hash_block_size,
329 data_size: v.data_size,
330 hash_area_offset: v.hash_area_offset,
331 fec_area_offset: v.fec_area_offset,
332 fec_roots: v.fec_roots,
333 flags: CryptVerity::from_bits(v.flags).ok_or(LibcryptErr::InvalidConversion)?,
334 })
335 }
336}
337
338impl<'a> TryInto<CryptParamsVerityRef<'a>> for &'a CryptParamsVerity {
339 type Error = LibcryptErr;
340
341 fn try_into(self) -> Result<CryptParamsVerityRef<'a>, Self::Error> {
342 let hash_name_cstring = to_cstring!(self.hash_name)?;
343 let data_device_cstring = path_to_cstring!(self.data_device)?;
344 let hash_device_cstring = match self.hash_device {
345 Some(ref hash_device) => Some(path_to_cstring!(hash_device)?),
346 None => None,
347 };
348 let fec_device_cstring = match self.fec_device {
349 Some(ref fec_device) => Some(path_to_cstring!(fec_device)?),
350 None => None,
351 };
352 Ok(CryptParamsVerityRef {
353 inner: libcryptsetup_rs_sys::crypt_params_verity {
354 hash_name: hash_name_cstring.as_ptr(),
355 data_device: data_device_cstring.as_ptr(),
356 hash_device: hash_device_cstring
357 .as_ref()
358 .map(|hd| hd.as_ptr())
359 .unwrap_or(ptr::null()),
360 fec_device: fec_device_cstring
361 .as_ref()
362 .map(|fd| fd.as_ptr())
363 .unwrap_or(ptr::null()),
364 salt: self.salt.as_ptr().cast::<libc::c_char>(),
365 salt_size: self.salt.len() as u32,
366 hash_type: self.hash_type,
367 data_block_size: self.data_block_size,
368 hash_block_size: self.hash_block_size,
369 data_size: self.data_size,
370 hash_area_offset: self.hash_area_offset,
371 fec_area_offset: self.fec_area_offset,
372 fec_roots: self.fec_roots,
373 flags: self.flags.bits(),
374 },
375 reference: self,
376 hash_name_cstring,
377 data_device_cstring,
378 hash_device_cstring,
379 fec_device_cstring,
380 })
381 }
382}
383
384impl CryptParams for CryptParamsVerityRef<'_> {
385 fn as_ptr(&mut self) -> *mut c_void {
386 (&mut self.inner as *mut crypt_params_verity).cast::<c_void>()
387 }
388}
389
390pub struct CryptParamsLoopaesRef<'a> {
392 inner: libcryptsetup_rs_sys::crypt_params_loopaes,
394 #[allow(dead_code)]
395 reference: &'a CryptParamsLoopaes,
396 #[allow(dead_code)]
397 hash_cstring: CString,
398}
399
400pub struct CryptParamsLoopaes {
402 #[allow(missing_docs)]
403 pub hash: String,
404 #[allow(missing_docs)]
405 pub offset: u64,
406 #[allow(missing_docs)]
407 pub skip: u64,
408}
409
410impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_loopaes> for CryptParamsLoopaes {
411 type Error = LibcryptErr;
412
413 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_loopaes) -> Result<Self, Self::Error> {
414 Ok(CryptParamsLoopaes {
415 hash: from_str_ptr_to_owned!(v.hash)?,
416 offset: v.offset,
417 skip: v.skip,
418 })
419 }
420}
421
422impl<'a> TryInto<CryptParamsLoopaesRef<'a>> for &'a CryptParamsLoopaes {
423 type Error = LibcryptErr;
424
425 fn try_into(self) -> Result<CryptParamsLoopaesRef<'a>, Self::Error> {
426 let hash_cstring = to_cstring!(self.hash)?;
427 Ok(CryptParamsLoopaesRef {
428 inner: libcryptsetup_rs_sys::crypt_params_loopaes {
429 hash: hash_cstring.as_ptr(),
430 offset: self.offset,
431 skip: self.skip,
432 },
433 reference: self,
434 hash_cstring,
435 })
436 }
437}
438
439impl CryptParams for CryptParamsLoopaesRef<'_> {
440 fn as_ptr(&mut self) -> *mut c_void {
441 (&mut self.inner as *mut crypt_params_loopaes).cast::<c_void>()
442 }
443}
444
445pub struct CryptParamsIntegrityRef<'a> {
448 #[allow(missing_docs)]
449 inner: libcryptsetup_rs_sys::crypt_params_integrity,
450 #[allow(dead_code)]
451 reference: &'a CryptParamsIntegrity,
452 #[allow(dead_code)]
453 integrity_cstring: CString,
454 #[allow(dead_code)]
455 journal_integrity_cstring: CString,
456 #[allow(dead_code)]
457 journal_crypt_cstring: CString,
458}
459
460pub struct CryptParamsIntegrity {
462 #[allow(missing_docs)]
463 pub journal_size: u64,
464 #[allow(missing_docs)]
465 pub journal_watermark: c_uint,
466 #[allow(missing_docs)]
467 pub journal_commit_time: c_uint,
468 #[allow(missing_docs)]
469 pub interleave_sectors: u32,
470 #[allow(missing_docs)]
471 pub tag_size: u32,
472 #[allow(missing_docs)]
473 pub sector_size: u32,
474 #[allow(missing_docs)]
475 pub buffer_sectors: u32,
476 #[allow(missing_docs)]
477 pub integrity: String,
478 #[allow(missing_docs)]
479 pub integrity_key_size: u32,
480 #[allow(missing_docs)]
481 pub journal_integrity: String,
482 #[allow(missing_docs)]
483 pub journal_integrity_key: Vec<u8>,
484 #[allow(missing_docs)]
485 pub journal_crypt: String,
486 #[allow(missing_docs)]
487 pub journal_crypt_key: Vec<u8>,
488}
489
490impl<'a> TryInto<CryptParamsIntegrityRef<'a>> for &'a CryptParamsIntegrity {
491 type Error = LibcryptErr;
492
493 fn try_into(self) -> Result<CryptParamsIntegrityRef<'a>, Self::Error> {
494 let integrity_cstring = to_cstring!(self.integrity)?;
495 let journal_integrity_cstring = to_cstring!(self.journal_integrity)?;
496 let journal_crypt_cstring = to_cstring!(self.journal_crypt)?;
497 let inner = libcryptsetup_rs_sys::crypt_params_integrity {
498 journal_size: self.journal_size,
499 journal_watermark: self.journal_watermark,
500 journal_commit_time: self.journal_commit_time,
501 interleave_sectors: self.interleave_sectors,
502 tag_size: self.tag_size,
503 sector_size: self.sector_size,
504 buffer_sectors: self.buffer_sectors,
505 integrity: integrity_cstring.as_ptr(),
506 integrity_key_size: self.integrity_key_size,
507 journal_integrity: journal_integrity_cstring.as_ptr(),
508 journal_integrity_key: to_byte_ptr!(self.journal_integrity_key),
509 journal_integrity_key_size: self.journal_integrity_key.len() as u32,
510 journal_crypt: journal_crypt_cstring.as_ptr(),
511 journal_crypt_key: to_byte_ptr!(self.journal_crypt_key),
512 journal_crypt_key_size: self.journal_crypt_key.len() as u32,
513 };
514 Ok(CryptParamsIntegrityRef {
515 inner,
516 reference: self,
517 integrity_cstring,
518 journal_integrity_cstring,
519 journal_crypt_cstring,
520 })
521 }
522}
523
524impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_integrity> for CryptParamsIntegrity {
525 type Error = LibcryptErr;
526
527 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_integrity) -> Result<Self, Self::Error> {
528 Ok(CryptParamsIntegrity {
529 journal_size: v.journal_size,
530 journal_watermark: v.journal_watermark,
531 journal_commit_time: v.journal_commit_time,
532 interleave_sectors: v.interleave_sectors,
533 tag_size: v.tag_size,
534 sector_size: v.sector_size,
535 buffer_sectors: v.buffer_sectors,
536 integrity: from_str_ptr_to_owned!(v.integrity)?,
537 integrity_key_size: v.integrity_key_size,
538 journal_integrity: from_str_ptr_to_owned!(v.journal_integrity)?,
539 journal_integrity_key: Vec::from(unsafe {
540 std::slice::from_raw_parts(
541 v.journal_integrity_key.cast::<u8>(),
542 v.journal_integrity_key_size as usize,
543 )
544 }),
545 journal_crypt: from_str_ptr_to_owned!(v.journal_crypt)?,
546 journal_crypt_key: Vec::from(unsafe {
547 std::slice::from_raw_parts(
548 v.journal_crypt_key.cast::<u8>(),
549 v.journal_crypt_key_size as usize,
550 )
551 }),
552 })
553 }
554}
555
556impl CryptParams for CryptParamsIntegrityRef<'_> {
557 fn as_ptr(&mut self) -> *mut c_void {
558 (&mut self.inner as *mut crypt_params_integrity).cast::<c_void>()
559 }
560}
561
562pub struct CryptParamsPlainRef<'a> {
564 inner: libcryptsetup_rs_sys::crypt_params_plain,
566 #[allow(dead_code)]
567 reference: &'a CryptParamsPlain,
568 #[allow(dead_code)]
569 hash_cstring: CString,
570}
571
572pub struct CryptParamsPlain {
574 pub hash: String,
576 pub offset: u64,
578 pub sector_size: u32,
580 pub size: u64,
582 pub skip: u64,
584}
585
586impl<'a> TryInto<CryptParamsPlainRef<'a>> for &'a CryptParamsPlain {
587 type Error = LibcryptErr;
588
589 fn try_into(self) -> Result<CryptParamsPlainRef<'a>, Self::Error> {
590 let hash_cstring = to_cstring!(self.hash)?;
591 Ok(CryptParamsPlainRef {
592 inner: libcryptsetup_rs_sys::crypt_params_plain {
593 hash: hash_cstring.as_ptr(),
594 offset: self.offset,
595 sector_size: self.sector_size,
596 size: self.size,
597 skip: self.skip,
598 },
599 reference: self,
600 hash_cstring,
601 })
602 }
603}
604
605impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_plain> for CryptParamsPlain {
606 type Error = LibcryptErr;
607
608 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_plain) -> Result<Self, Self::Error> {
609 Ok(CryptParamsPlain {
610 hash: from_str_ptr_to_owned!(v.hash)?,
611 offset: v.offset,
612 sector_size: v.sector_size,
613 size: v.size,
614 skip: v.skip,
615 })
616 }
617}
618
619impl CryptParams for CryptParamsPlainRef<'_> {
620 fn as_ptr(&mut self) -> *mut c_void {
621 (&mut self.inner as *mut crypt_params_plain).cast::<c_void>()
622 }
623}
624
625pub struct CryptParamsTcryptRef<'a> {
627 inner: libcryptsetup_rs_sys::crypt_params_tcrypt,
629 #[allow(dead_code)]
630 reference: &'a CryptParamsTcrypt,
631 #[allow(dead_code)]
632 keyfiles_cstrings: Vec<CString>,
633 #[allow(dead_code)]
634 keyfiles_ptrs: Vec<*const libc::c_char>,
635 #[allow(dead_code)]
636 hash_name_cstring: CString,
637 #[allow(dead_code)]
638 cipher_cstring: CString,
639 #[allow(dead_code)]
640 mode_cstring: CString,
641}
642
643pub struct CryptParamsTcrypt {
645 #[allow(missing_docs)]
646 pub passphrase: Option<Vec<u8>>,
647 #[allow(missing_docs)]
648 pub keyfiles: Option<Vec<PathBuf>>,
649 #[allow(missing_docs)]
650 pub hash_name: String,
651 #[allow(missing_docs)]
652 pub cipher: String,
653 #[allow(missing_docs)]
654 pub mode: String,
655 #[allow(missing_docs)]
656 pub key_size: usize,
657 #[allow(missing_docs)]
658 pub flags: CryptTcrypt,
659 #[allow(missing_docs)]
660 pub veracrypt_pim: u32,
661}
662
663impl<'a> TryInto<CryptParamsTcryptRef<'a>> for &'a CryptParamsTcrypt {
664 type Error = LibcryptErr;
665
666 fn try_into(self) -> Result<CryptParamsTcryptRef<'a>, Self::Error> {
667 let mut keyfiles_cstrings = Vec::new();
668 if let Some(ref keyfiles) = self.keyfiles {
669 for keyfile in keyfiles.iter() {
670 keyfiles_cstrings.push(path_to_cstring!(keyfile)?);
671 }
672 }
673 let mut keyfiles_ptrs: Vec<*const libc::c_char> =
674 keyfiles_cstrings.iter().map(|cs| cs.as_ptr()).collect();
675 let hash_name_cstring = to_cstring!(self.hash_name)?;
676 let cipher_cstring = to_cstring!(self.cipher)?;
677 let mode_cstring = to_cstring!(self.mode)?;
678 Ok(CryptParamsTcryptRef {
679 inner: libcryptsetup_rs_sys::crypt_params_tcrypt {
680 passphrase: match self.passphrase {
681 Some(ref pass) => pass.as_ptr().cast::<libc::c_char>(),
682 None => std::ptr::null(),
683 },
684 passphrase_size: match self.passphrase {
685 Some(ref pass) => pass.len(),
686 None => 0,
687 },
688 keyfiles: keyfiles_ptrs.as_mut_ptr(),
689 keyfiles_count: keyfiles_cstrings.len() as u32,
690 hash_name: hash_name_cstring.as_ptr(),
691 cipher: cipher_cstring.as_ptr(),
692 mode: mode_cstring.as_ptr(),
693 flags: self.flags.bits(),
694 key_size: self.key_size,
695 veracrypt_pim: self.veracrypt_pim,
696 },
697 reference: self,
698 keyfiles_cstrings,
699 keyfiles_ptrs,
700 hash_name_cstring,
701 cipher_cstring,
702 mode_cstring,
703 })
704 }
705}
706
707impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_params_tcrypt> for CryptParamsTcrypt {
708 type Error = LibcryptErr;
709
710 fn try_from(v: &'a libcryptsetup_rs_sys::crypt_params_tcrypt) -> Result<Self, Self::Error> {
711 let mut keyfiles = Vec::new();
712 let keyfiles_ptrs = unsafe { slice::from_raw_parts(v.keyfiles, v.keyfiles_count as usize) };
713 for keyfile_ptr in keyfiles_ptrs {
714 keyfiles.push(PathBuf::from(from_str_ptr_to_owned!(*keyfile_ptr)?));
715 }
716 Ok(CryptParamsTcrypt {
717 passphrase: ptr_to_option!(v.passphrase).map(|p| {
718 unsafe { slice::from_raw_parts(p.cast::<u8>(), v.passphrase_size) }.to_vec()
719 }),
720 keyfiles: if keyfiles.is_empty() {
721 None
722 } else {
723 Some(keyfiles)
724 },
725 hash_name: from_str_ptr_to_owned!(v.hash_name)?,
726 cipher: from_str_ptr_to_owned!(v.cipher)?,
727 mode: from_str_ptr_to_owned!(v.mode)?,
728 flags: CryptTcrypt::from_bits(v.flags).ok_or(LibcryptErr::InvalidConversion)?,
729 key_size: v.key_size,
730 veracrypt_pim: v.veracrypt_pim,
731 })
732 }
733}
734
735impl CryptParams for CryptParamsTcryptRef<'_> {
736 fn as_ptr(&mut self) -> *mut c_void {
737 (&mut self.inner as *mut crypt_params_tcrypt).cast::<c_void>()
738 }
739}
740
741pub struct CryptFormatHandle<'a> {
743 reference: &'a mut CryptDevice,
744}
745
746impl<'a> CryptFormatHandle<'a> {
747 pub(crate) fn new(reference: &'a mut CryptDevice) -> Self {
748 CryptFormatHandle { reference }
749 }
750
751 pub fn get_type(&mut self) -> Result<EncryptionFormat, LibcryptErr> {
753 EncryptionFormat::from_ptr(ptr_to_result!(mutex!(
754 libcryptsetup_rs_sys::crypt_get_type(self.reference.as_ptr())
755 ))?)
756 }
757
758 pub fn get_default_type() -> Result<EncryptionFormat, LibcryptErr> {
760 EncryptionFormat::from_ptr(ptr_to_result!(mutex!(
761 libcryptsetup_rs_sys::crypt_get_default_type()
762 ))?)
763 }
764}
765
766#[cfg(test)]
767mod test {
768 use super::EncryptionFormat;
769
770 #[test]
771 fn test_encryption_format_partialeq() {
772 #[allow(clippy::eq_op)]
773 {
774 assert_eq!(EncryptionFormat::Luks1, EncryptionFormat::Luks1);
775 }
776 assert_ne!(EncryptionFormat::Luks1, EncryptionFormat::Luks2);
777 }
778
779 #[test]
780 fn test_encryption_format_from_ptr() {
781 for format in &[
782 EncryptionFormat::Integrity,
783 EncryptionFormat::Tcrypt,
784 EncryptionFormat::Verity,
785 EncryptionFormat::Luks2,
786 EncryptionFormat::Loopaes,
787 EncryptionFormat::Luks1,
788 EncryptionFormat::Plain,
789 ] {
790 assert_eq!(
791 EncryptionFormat::from_ptr(format.as_ptr()).unwrap(),
792 *format
793 );
794 }
795 }
796}