cryptsetup_rs/
luks1.rs

1use std::fs::File;
2use std::path::Path;
3
4use uuid::Uuid;
5
6use blkid_rs::{Luks1Header, LuksHeader};
7
8use crate::api::CryptDeviceHandle;
9use crate::api::{CryptDeviceType, Luks1CryptDevice, LuksCryptDevice};
10use crate::device::{Error, Keyslot, Result};
11
12/// Struct for storing LUKS1 parameters in memory
13#[derive(Debug, PartialEq)]
14pub struct Luks1Params {
15    hash_spec: String,
16    payload_offset: u32,
17    mk_bits: u32,
18    mk_digest: [u8; 20],
19    mk_salt: [u8; 32],
20    mk_iterations: u32,
21}
22
23impl Luks1Params {
24    fn from(header: impl Luks1Header) -> Result<Luks1Params> {
25        let hash_spec = header.hash_spec()?.to_owned();
26        let payload_offset = header.payload_offset();
27        let mk_bits = header.key_bytes() * 8;
28        let mut mk_digest = [0u8; 20];
29        mk_digest.copy_from_slice(header.mk_digest());
30        let mut mk_salt = [0u8; 32];
31        mk_salt.copy_from_slice(header.mk_digest_salt());
32        let mk_iterations = header.mk_digest_iterations();
33        Ok(Luks1Params {
34            hash_spec,
35            payload_offset,
36            mk_bits,
37            mk_digest,
38            mk_salt,
39            mk_iterations,
40        })
41    }
42
43    pub(crate) fn from_path<P: AsRef<Path>>(path: P) -> Result<Luks1Params> {
44        let device_file = File::open(path.as_ref())?;
45        match LuksHeader::read(device_file)? {
46            LuksHeader::Luks1(v1) => Luks1Params::from(v1),
47            _ => Err(Error::InvalidLuksVersion),
48        }
49    }
50}
51
52impl LuksCryptDevice for CryptDeviceHandle<Luks1Params> {
53    fn activate(&mut self, name: &str, key: &[u8]) -> Result<Keyslot> {
54        crate::device::luks_activate(&mut self.cd, name, key)
55    }
56
57    fn deactivate(self, name: &str) -> Result<()> {
58        crate::device::deactivate(self.cd, name)
59    }
60
61    fn destroy_keyslot(&mut self, slot: Keyslot) -> Result<()> {
62        crate::device::luks_destroy_keyslot(&mut self.cd, slot)
63    }
64
65    fn keyslot_status(&self, keyslot: Keyslot) -> raw::crypt_keyslot_info {
66        crate::device::keyslot_status(&self.cd, keyslot)
67    }
68
69    fn dump(&self) {
70        crate::device::dump(&self.cd).expect("Dump should be fine for initialised device")
71    }
72
73    fn uuid(&self) -> Uuid {
74        crate::device::uuid(&self.cd).expect("Initialised device should have UUID")
75    }
76
77    fn add_keyslot(
78        &mut self,
79        key: &[u8],
80        maybe_prev_key: Option<&[u8]>,
81        maybe_keyslot: Option<Keyslot>,
82    ) -> Result<Keyslot> {
83        crate::device::luks_add_keyslot(&mut self.cd, key, maybe_prev_key, maybe_keyslot)
84    }
85
86    fn update_keyslot(&mut self, key: &[u8], prev_key: &[u8], maybe_keyslot: Option<Keyslot>) -> Result<Keyslot> {
87        crate::device::luks_update_keyslot(&mut self.cd, key, prev_key, maybe_keyslot)
88    }
89}
90
91impl Luks1CryptDevice for CryptDeviceHandle<Luks1Params> {
92    fn hash_spec(&self) -> &str {
93        self.params.hash_spec.as_ref()
94    }
95
96    fn mk_bits(&self) -> u32 {
97        self.params.mk_bits
98    }
99
100    fn mk_digest(&self) -> &[u8; 20] {
101        &self.params.mk_digest
102    }
103
104    fn mk_iterations(&self) -> u32 {
105        self.params.mk_iterations
106    }
107
108    fn mk_salt(&self) -> &[u8; 32] {
109        &self.params.mk_salt
110    }
111
112    fn payload_offset(&self) -> u32 {
113        self.params.payload_offset
114    }
115}
116
117impl CryptDeviceType for CryptDeviceHandle<Luks1Params> {
118    fn device_type(&self) -> raw::crypt_device_type {
119        raw::crypt_device_type::LUKS1
120    }
121}