1use std::{os::raw::c_int, path::Path, ptr};
6
7use crate::{
8 consts::vals::EncryptionFormat, device::CryptDevice, err::LibcryptErr, format::CryptParams,
9};
10
11use either::Either;
12use uuid::Uuid;
13
14pub struct CryptContextHandle<'a> {
16 reference: &'a mut CryptDevice,
17}
18
19impl<'a> CryptContextHandle<'a> {
20 pub(crate) fn new(reference: &'a mut CryptDevice) -> Self {
21 CryptContextHandle { reference }
22 }
23
24 pub fn format<T: CryptParams>(
34 &mut self,
35 type_: EncryptionFormat,
36 cipher_and_mode: (&str, &str),
37 uuid: Option<Uuid>,
38 volume_key: Either<&[u8], usize>,
39 params: Option<&mut T>,
40 ) -> Result<(), LibcryptErr> {
41 let uuid_c_string = match uuid {
42 Some(u) => Some(to_cstring!(u.to_string())?),
43 None => None,
44 };
45 let (volume_key_ptr, volume_key_len) = match volume_key {
46 Either::Left(vk) => (to_byte_ptr!(vk), vk.len()),
47 Either::Right(len) => (ptr::null(), len),
48 };
49 let (cipher, cipher_mode) = cipher_and_mode;
50 let cipher_cstring = to_cstring!(cipher)?;
51 let cipher_mode_cstring = to_cstring!(cipher_mode)?;
52 errno!(mutex!(libcryptsetup_rs_sys::crypt_format(
53 self.reference.as_ptr(),
54 type_.as_ptr(),
55 cipher_cstring.as_ptr(),
56 cipher_mode_cstring.as_ptr(),
57 uuid_c_string
58 .as_ref()
59 .map(|cs| cs.as_ptr())
60 .unwrap_or_else(ptr::null),
61 volume_key_ptr,
62 volume_key_len,
63 params.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()),
64 )))?;
65 Ok(())
66 }
67
68 pub fn convert<T: CryptParams>(
70 &mut self,
71 type_: EncryptionFormat,
72 params: Option<&mut T>,
73 ) -> Result<(), LibcryptErr> {
74 errno!(mutex!(libcryptsetup_rs_sys::crypt_convert(
75 self.reference.as_ptr(),
76 type_.as_ptr(),
77 params.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()),
78 )))
79 }
80
81 pub fn set_uuid(&mut self, uuid: Option<Uuid>) -> Result<(), LibcryptErr> {
83 let c_string = match uuid {
84 Some(u) => Some(to_cstring!(u.to_string())?),
85 None => None,
86 };
87 errno!(mutex!(libcryptsetup_rs_sys::crypt_set_uuid(
88 self.reference.as_ptr(),
89 c_string
90 .as_ref()
91 .map(|cs| cs.as_ptr())
92 .unwrap_or_else(ptr::null)
93 )))
94 }
95
96 pub fn set_label(
98 &mut self,
99 label: Option<&str>,
100 subsystem_label: Option<&str>,
101 ) -> Result<(), LibcryptErr> {
102 let (lcstring, slcstring) = match (label, subsystem_label) {
103 (Some(l), Some(sl)) => (Some(to_cstring!(l)?), Some(to_cstring!(sl)?)),
104 (Some(l), _) => (Some(to_cstring!(l)?), None),
105 (_, Some(sl)) => (None, Some(to_cstring!(sl)?)),
106 (_, _) => (None, None),
107 };
108 errno!(mutex!(libcryptsetup_rs_sys::crypt_set_label(
109 self.reference.as_ptr(),
110 lcstring
111 .as_ref()
112 .map(|cs| cs.as_ptr())
113 .unwrap_or(ptr::null()),
114 slcstring
115 .as_ref()
116 .map(|cs| cs.as_ptr())
117 .unwrap_or(ptr::null()),
118 )))
119 }
120
121 pub fn volume_key_keyring(&mut self, enable: bool) -> Result<(), LibcryptErr> {
123 errno!(mutex!(libcryptsetup_rs_sys::crypt_volume_key_keyring(
124 self.reference.as_ptr(),
125 enable as c_int
126 )))
127 }
128
129 pub fn load<T: CryptParams>(
131 &mut self,
132 type_: Option<EncryptionFormat>,
133 params: Option<&mut T>,
134 ) -> Result<(), LibcryptErr> {
135 errno!(mutex!(libcryptsetup_rs_sys::crypt_load(
136 self.reference.as_ptr(),
137 type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
138 params.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()),
139 )))?;
140 Ok(())
141 }
142
143 pub fn repair<T: CryptParams>(
145 &mut self,
146 type_: EncryptionFormat,
147 params: Option<&mut T>,
148 ) -> Result<(), LibcryptErr> {
149 errno!(mutex!(libcryptsetup_rs_sys::crypt_repair(
150 self.reference.as_ptr(),
151 type_.as_ptr(),
152 params.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()),
153 )))
154 }
155
156 pub fn resize(&mut self, name: &str, new_size: u64) -> Result<(), LibcryptErr> {
158 let name_cstring = to_cstring!(name)?;
159 errno!(mutex!(libcryptsetup_rs_sys::crypt_resize(
160 self.reference.as_ptr(),
161 name_cstring.as_ptr(),
162 new_size,
163 )))
164 }
165
166 pub fn suspend(&mut self, name: &str) -> Result<(), LibcryptErr> {
168 let name_cstring = to_cstring!(name)?;
169 errno!(mutex!(libcryptsetup_rs_sys::crypt_suspend(
170 self.reference.as_ptr(),
171 name_cstring.as_ptr()
172 )))
173 }
174
175 pub fn resume_by_passphrase(
177 &mut self,
178 name: &str,
179 keyslot: c_int,
180 passphrase: &str,
181 ) -> Result<c_int, LibcryptErr> {
182 let name_cstring = to_cstring!(name)?;
183 let passphrase_cstring = to_cstring!(passphrase)?;
184 errno_int_success!(mutex!(libcryptsetup_rs_sys::crypt_resume_by_passphrase(
185 self.reference.as_ptr(),
186 name_cstring.as_ptr(),
187 keyslot,
188 passphrase_cstring.as_ptr(),
189 passphrase.len() as crate::size_t,
190 )))
191 }
192
193 pub fn resume_by_keyfile_device_offset(
195 &mut self,
196 name: &str,
197 keyslot: c_int,
198 keyfile: &Path,
199 keyfile_size: crate::size_t,
200 keyfile_offset: u64,
201 ) -> Result<c_int, LibcryptErr> {
202 let name_cstring = to_cstring!(name)?;
203 let keyfile_cstring = path_to_cstring!(keyfile)?;
204 errno_int_success!(mutex!(
205 libcryptsetup_rs_sys::crypt_resume_by_keyfile_device_offset(
206 self.reference.as_ptr(),
207 name_cstring.as_ptr(),
208 keyslot,
209 keyfile_cstring.as_ptr(),
210 keyfile_size,
211 keyfile_offset,
212 )
213 ))
214 }
215}