use alloc::boxed::Box;
use alloc::string::String;
use serde::{Deserialize, Serialize};
pub type Guid = uuid::Uuid;
pub fn guid_from_windows_bytes(bytes: [u8; 16]) -> Guid {
Guid::from_bytes_le(bytes)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum VolumeState {
Encrypt,
Decrypt,
}
impl VolumeState {
pub fn as_u16(self) -> u16 {
match self {
VolumeState::Encrypt => 0,
VolumeState::Decrypt => 1,
}
}
pub fn from_u16(v: u16) -> Self {
match v {
1 => VolumeState::Decrypt,
_ => VolumeState::Encrypt,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EncryptedOffset {
pub sector: u64,
pub total_sectors: u64,
}
impl EncryptedOffset {
pub fn is_encrypted(&self, sector: u64) -> bool {
sector < self.sector
}
pub fn is_fully_encrypted(&self) -> bool {
self.sector >= self.total_sectors
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SectorRange {
pub start: u64,
pub count: u64,
}
impl SectorRange {
pub fn end(&self) -> u64 {
self.start + self.count
}
pub fn contains(&self, sector: u64) -> bool {
sector >= self.start && sector < self.end()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encrypted_offset_boundaries() {
let off = EncryptedOffset {
sector: 10,
total_sectors: 100,
};
assert!(off.is_encrypted(9));
assert!(!off.is_encrypted(10));
assert!(!off.is_fully_encrypted());
let done = EncryptedOffset {
sector: 100,
total_sectors: 100,
};
assert!(done.is_fully_encrypted());
}
#[test]
fn guid_from_windows_bytes_matches_canonical() {
let win = [
0x78, 0x56, 0x34, 0x12, 0xbc, 0x9a, 0xf0, 0xde, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, ];
let guid = guid_from_windows_bytes(win);
let canonical = uuid::Uuid::parse_str("12345678-9abc-def0-1122-334455667788").unwrap();
assert_eq!(guid, canonical);
}
#[test]
fn sector_range_contains() {
let r = SectorRange { start: 5, count: 3 };
assert_eq!(r.end(), 8);
assert!(r.contains(5));
assert!(r.contains(7));
assert!(!r.contains(8));
assert!(!r.contains(4));
}
}
pub trait VolumeCipher: Send + Sync {
fn encrypt_sector(&self, rel_sector: u64, sector: &mut [u8]);
fn decrypt_sector(&self, rel_sector: u64, sector: &mut [u8]);
fn encrypt_area(&self, buf: &mut [u8], sector_size: usize, first_rel_sector: u64);
fn decrypt_area(&self, buf: &mut [u8], sector_size: usize, first_rel_sector: u64);
fn destroy(&mut self) {}
}
pub trait VolumeCipherSupplier: Send + Sync {
fn get_cipher(&self) -> Option<Box<dyn VolumeCipher>>;
}
#[derive(Debug, Clone)]
pub struct VolumeId {
pub partition_guid: Guid,
pub device_path: String,
}