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#[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}