Skip to main content

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