libcryptsetup_rs/
settings.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::CString, marker::PhantomData, os::raw::c_int};
6
7use libcryptsetup_rs_sys::crypt_pbkdf_type;
8
9use crate::{
10    consts::{
11        flags::CryptPbkdf,
12        vals::{CryptKdf, CryptRng, KeyslotsSize, LockState, LuksType, MetadataSize},
13    },
14    device::CryptDevice,
15    err::LibcryptErr,
16};
17
18/// Rust representation of `crypt_pbkdf_type`
19pub struct CryptPbkdfType {
20    #[allow(missing_docs)]
21    pub type_: CryptKdf,
22    #[allow(missing_docs)]
23    pub hash: String,
24    #[allow(missing_docs)]
25    pub time_ms: u32,
26    #[allow(missing_docs)]
27    pub iterations: u32,
28    #[allow(missing_docs)]
29    pub max_memory_kb: u32,
30    #[allow(missing_docs)]
31    pub parallel_threads: u32,
32    #[allow(missing_docs)]
33    pub flags: CryptPbkdf,
34}
35
36impl TryFrom<libcryptsetup_rs_sys::crypt_pbkdf_type> for CryptPbkdfType {
37    type Error = LibcryptErr;
38
39    fn try_from(
40        type_: libcryptsetup_rs_sys::crypt_pbkdf_type,
41    ) -> Result<CryptPbkdfType, LibcryptErr> {
42        Ok(CryptPbkdfType {
43            type_: CryptKdf::from_ptr(type_.type_)?,
44            hash: String::from(from_str_ptr!(type_.hash)?),
45            time_ms: type_.time_ms,
46            iterations: type_.iterations,
47            max_memory_kb: type_.max_memory_kb,
48            parallel_threads: type_.parallel_threads,
49            flags: CryptPbkdf::from_bits(type_.flags).ok_or(LibcryptErr::InvalidConversion)?,
50        })
51    }
52}
53
54impl<'a> TryFrom<&'a libcryptsetup_rs_sys::crypt_pbkdf_type> for CryptPbkdfType {
55    type Error = LibcryptErr;
56
57    fn try_from(v: &'a libcryptsetup_rs_sys::crypt_pbkdf_type) -> Result<Self, Self::Error> {
58        Ok(CryptPbkdfType {
59            type_: CryptKdf::from_ptr(v.type_)?,
60            hash: from_str_ptr!(v.hash)?.to_string(),
61            time_ms: v.time_ms,
62            iterations: v.iterations,
63            max_memory_kb: v.max_memory_kb,
64            parallel_threads: v.parallel_threads,
65            flags: CryptPbkdf::from_bits(v.flags).ok_or(LibcryptErr::InvalidConversion)?,
66        })
67    }
68}
69
70/// A type wrapping a PBKDF type with pointers derived from Rust data types and lifetimes to ensure
71/// pointer validity
72pub struct CryptPbkdfTypeRef<'a> {
73    /// Field containing a `crypt_pbkdf_type` that contains pointers valid for the supplied struct lifetime
74    pub inner: crypt_pbkdf_type,
75    #[allow(dead_code)]
76    hash_cstring: CString,
77    phantomdata: PhantomData<&'a ()>,
78}
79
80impl<'a> TryInto<CryptPbkdfTypeRef<'a>> for &'a CryptPbkdfType {
81    type Error = LibcryptErr;
82
83    fn try_into(self) -> Result<CryptPbkdfTypeRef<'a>, Self::Error> {
84        let hash_cstring = CString::new(self.hash.as_bytes()).map_err(LibcryptErr::NullError)?;
85        let inner = libcryptsetup_rs_sys::crypt_pbkdf_type {
86            type_: self.type_.as_ptr(),
87            hash: hash_cstring.as_ptr(),
88            time_ms: self.time_ms,
89            iterations: self.iterations,
90            max_memory_kb: self.max_memory_kb,
91            parallel_threads: self.parallel_threads,
92            flags: self.flags.bits(),
93        };
94        Ok(CryptPbkdfTypeRef {
95            inner,
96            hash_cstring,
97            phantomdata: PhantomData,
98        })
99    }
100}
101
102/// Handle to operate on cryptsetup device settings
103pub struct CryptSettingsHandle<'a> {
104    reference: &'a mut CryptDevice,
105}
106
107impl<'a> CryptSettingsHandle<'a> {
108    pub(crate) fn new(reference: &'a mut CryptDevice) -> Self {
109        CryptSettingsHandle { reference }
110    }
111
112    /// Set random number generator type
113    pub fn set_rng_type(&mut self, rng_type: CryptRng) {
114        let rng_u32: u32 = rng_type.into();
115        mutex!(libcryptsetup_rs_sys::crypt_set_rng_type(
116            self.reference.as_ptr(),
117            rng_u32 as c_int
118        ))
119    }
120
121    /// Get random number generator type
122    pub fn get_rng_type(&mut self) -> Result<CryptRng, LibcryptErr> {
123        CryptRng::try_from(mutex!(libcryptsetup_rs_sys::crypt_get_rng_type(
124            self.reference.as_ptr()
125        )) as u32)
126    }
127
128    /// Set PBKDF type
129    pub fn set_pbkdf_type<'b>(
130        &mut self,
131        pbkdf_type: &'b CryptPbkdfType,
132    ) -> Result<(), LibcryptErr> {
133        let type_: CryptPbkdfTypeRef<'b> = pbkdf_type.try_into()?;
134        errno!(mutex!(libcryptsetup_rs_sys::crypt_set_pbkdf_type(
135            self.reference.as_ptr(),
136            &type_.inner as *const crypt_pbkdf_type,
137        )))
138    }
139
140    /// Get PBKDF parameters
141    pub fn get_pbkdf_type_params(pbkdf_type: &CryptKdf) -> Result<CryptPbkdfType, LibcryptErr> {
142        let type_ = ptr_to_result_with_reference!(mutex!(
143            libcryptsetup_rs_sys::crypt_get_pbkdf_type_params(pbkdf_type.as_ptr())
144        ))?;
145        CryptPbkdfType::try_from(type_)
146    }
147
148    /// Get PBKDF default type
149    pub fn get_pbkdf_default(luks_type: &LuksType) -> Result<CryptPbkdfType, LibcryptErr> {
150        let default = ptr_to_result_with_reference!(mutex!(
151            libcryptsetup_rs_sys::crypt_get_pbkdf_default(luks_type.as_ptr())
152        ))?;
153        CryptPbkdfType::try_from(default)
154    }
155
156    /// Get PBKDF type
157    pub fn get_pbkdf_type(&mut self) -> Result<CryptPbkdfType, LibcryptErr> {
158        let type_ = ptr_to_result_with_reference!(mutex!(
159            libcryptsetup_rs_sys::crypt_get_pbkdf_type(self.reference.as_ptr())
160        ))?;
161        CryptPbkdfType::try_from(type_)
162    }
163
164    /// Set the iteration time in milliseconds
165    pub fn set_iteration_time(&mut self, iteration_time_ms: u64) {
166        mutex!(libcryptsetup_rs_sys::crypt_set_iteration_time(
167            self.reference.as_ptr(),
168            iteration_time_ms,
169        ))
170    }
171
172    /// Lock or unlock memory
173    pub fn memory_lock(&mut self, lock: LockState) -> LockState {
174        int_to_return!(
175            mutex!(libcryptsetup_rs_sys::crypt_memory_lock(
176                self.reference.as_ptr(),
177                lock as c_int
178            )),
179            LockState
180        )
181    }
182
183    /// Lock or unlock the metadata
184    pub fn metadata_locking(&mut self, enable: bool) -> Result<(), LibcryptErr> {
185        errno!(mutex!(libcryptsetup_rs_sys::crypt_metadata_locking(
186            self.reference.as_ptr(),
187            enable as c_int
188        )))
189    }
190
191    /// Set the metadata size and keyslot size
192    pub fn set_metadata_size(
193        &mut self,
194        metadata_size: MetadataSize,
195        keyslots_size: KeyslotsSize,
196    ) -> Result<(), LibcryptErr> {
197        errno!(mutex!(libcryptsetup_rs_sys::crypt_set_metadata_size(
198            self.reference.as_ptr(),
199            *metadata_size,
200            *keyslots_size,
201        )))
202    }
203
204    /// Get the metadata size and keyslot size
205    pub fn get_metadata_size(&mut self) -> Result<(MetadataSize, KeyslotsSize), LibcryptErr> {
206        let mut metadata_size = 0u64;
207        let mut keyslots_size = 0u64;
208        errno!(mutex!(libcryptsetup_rs_sys::crypt_get_metadata_size(
209            self.reference.as_ptr(),
210            &mut metadata_size as *mut u64,
211            &mut keyslots_size as *mut u64,
212        )))?;
213        let msize = MetadataSize::try_from(metadata_size)?;
214        let ksize = KeyslotsSize::try_from(keyslots_size)?;
215        Ok((msize, ksize))
216    }
217}