#![allow(clippy::unwrap_used, clippy::expect_used)]
mod common;
use std::fs::File;
use bitlocker::BitLockerVolume;
use common::{sha256_hex, OffsetReader};
const VOLUME_OFFSET: u64 = 16_777_216;
const RECOVERY_PW: &str = "590238-514580-359986-088242-029766-319495-410509-636911";
#[test]
fn tier1_vault_xts128_matches_pybde() {
let Ok(path) = std::env::var("BDE_XTS_ORACLE") else {
eprintln!("BDE_XTS_ORACLE unset — skipping Tier-1 vault XTS-128 oracle");
return;
};
let file = File::open(&path).expect("open vault.raw");
let reader = OffsetReader::new(file, VOLUME_OFFSET).expect("window volume");
let mut vol = BitLockerVolume::unlock_with_recovery_password(reader, RECOVERY_PW)
.expect("unlock vault.raw");
assert_eq!(
vol.metadata().encryption_method,
0x8004,
"oracle must be XTS-AES-128"
);
let cases: [(u64, &str); 8] = [
(
0,
"7000a9d734628583f2debea8496ef532eb71f82f17a11acbcb084c0e2a27ce67",
),
(
1,
"ef6d6118087d7849e66c32de9859dc5a74b98aa2d28b3f2e6e87275b537eb546",
),
(
2,
"e845941331aaf16324636abd0c499908757d12eaf947c841e02164c4b9e1edad",
),
(
3,
"f49bb7dfe830eaff32cc57199fece014a7120851c126323196877295c94a14fe",
),
(
5,
"e07295e7e678283f029f21271922fe254ee3e6b44f80180a71e9d78b4e7823b3",
),
(
12298,
"62fe68b09231ab0019696043859aeb010a92b224a32b01bd7e7cc47b3d85c324",
),
(
32768,
"b525ecbce7a22825746e9f938498131c3c8d99a22e5c9a47294be43c35a0748d",
),
(
262_144,
"999e459d1b2996dc8bc0826d0ef2e6521c3a8636b8f58a6c5ba192961f674f4a",
),
];
for (lba, want) in cases {
let mut buf = [0u8; 512];
vol.read_at(lba * 512, &mut buf).expect("read_at");
let got = sha256_hex(&buf);
println!("sector {lba}: {got}");
assert_eq!(got, want, "decrypted sector {lba} does not match pybde");
}
let mut boot = [0u8; 512];
vol.read_at(0, &mut boot).unwrap();
assert_eq!(&boot[3..11], b"NTFS ");
assert_eq!(&boot[510..512], &[0x55, 0xaa]);
}