#![allow(clippy::unwrap_used, clippy::expect_used)]
mod common;
use std::fs::File;
use common::sha256_hex;
use veracrypt::VeraVolume;
const PASSWORD: &[u8] = b"aaaaaaaaaaaa";
#[test]
fn tier1_cascade3_aes_twofish_serpent_matches_veracrypt() {
let Ok(path) = std::env::var("VC_CASCADE3_ORACLE") else {
eprintln!("VC_CASCADE3_ORACLE unset — skipping Tier-1 3-cipher cascade oracle");
return;
};
let file = File::open(&path).expect("open 3-cascade vc image");
let mut vol = VeraVolume::unlock_with_password(file, PASSWORD).expect("unlock 3-cascade");
assert_eq!(
vol.info().ciphers.len(),
3,
"must brute to a 3-cipher cascade"
);
let mut buf = [0u8; 512];
vol.read_at(0, &mut buf).expect("read_at");
let got = sha256_hex(&buf);
println!("cascade3 sector 0: {got} ({})", vol.info().cipher_display());
assert_eq!(
got, "9ae00053bc19932a4b069c522ab0141863c434732a0e50450fb01ffcd2c58142",
"3-cascade sector 0 does not match veracrypt"
);
}
#[test]
fn tier1_cascade_aes_twofish_matches_veracrypt() {
let Ok(path) = std::env::var("VC_CASCADE_ORACLE") else {
eprintln!("VC_CASCADE_ORACLE unset — skipping Tier-1 cascade oracle");
return;
};
let file = File::open(&path).expect("open cascade vc image");
let mut vol = VeraVolume::unlock_with_password(file, PASSWORD).expect("unlock cascade volume");
assert_eq!(
vol.info().cipher_display(),
"aes-twofish",
"must brute to the AES-Twofish cascade"
);
let mut buf = [0u8; 512];
vol.read_at(0, &mut buf).expect("read_at");
let got = sha256_hex(&buf);
println!("cascade sector 0: {got}");
assert_eq!(
got, "da09622b78baeeb1fa8e6532f1eb23afc733a8449097d3a08d612286d4161492",
"cascade sector 0 does not match veracrypt/cryptsetup"
);
}
#[test]
fn tier1_serpent256_matches_cryptsetup() {
let Ok(path) = std::env::var("VC_SERPENT_ORACLE") else {
eprintln!("VC_SERPENT_ORACLE unset — skipping Tier-1 Serpent oracle");
return;
};
let file = File::open(&path).expect("open serpent vc image");
let mut vol = VeraVolume::unlock_with_password(file, PASSWORD).expect("unlock serpent volume");
assert_eq!(
vol.info().cipher_display(),
"serpent",
"must brute to serpent"
);
let cases: [(u64, &str); 2] = [
(
0,
"479ad71598de182171230acbe3322cdac3b9bb9f70894a7cc3e7b526be46693b",
),
(
1,
"479ad71598de182171230acbe3322cdac3b9bb9f70894a7cc3e7b526be46693b",
),
];
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!("serpent sector {lba}: {got}");
assert_eq!(got, want, "serpent sector {lba} does not match cryptsetup");
}
}
#[test]
fn tier1_vc_sha512_xts_aes_matches_cryptsetup() {
let Ok(path) = std::env::var("VC_ORACLE") else {
eprintln!("VC_ORACLE unset — skipping Tier-1 VeraCrypt oracle");
return;
};
let file = File::open(&path).expect("open vc image");
let mut vol = VeraVolume::unlock_with_password(file, PASSWORD).expect("unlock vc volume");
assert_eq!(vol.info().prf.name(), "sha512");
assert_eq!(vol.info().cipher_display(), "aes");
assert_eq!(vol.info().encrypted_area_start, 131_072);
let cases: [(u64, &str); 4] = [
(
0,
"76a9e8419a1e688732c03236e01e564c6b3660c0bcdc4561eb05e1d1de8ff8fa",
),
(
1,
"076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560",
),
(
2,
"6242cb7cb043b219a77ffa2bd0aedab6735389bbbe8b3b2e88410cf5f74247a5",
),
(
16,
"00882984fac5e7298c45bae80bad8debc4456d06d5189bb91f9f3901ecee4b0f",
),
];
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 cryptsetup"
);
}
}
#[test]
fn tier1_hidden_volume_matches_cryptsetup() {
let Ok(path) = std::env::var("VC_HIDDEN_ORACLE") else {
eprintln!("VC_HIDDEN_ORACLE unset — skipping Tier-1 hidden-volume oracle");
return;
};
let file = File::open(&path).expect("open hidden vc image");
let mut vol = VeraVolume::unlock_hidden_with_password(file, b"bbbbbbbbbbbb")
.expect("unlock hidden volume");
assert_eq!(vol.info().encrypted_area_start, 165_888);
let cases: [(u64, &str); 2] = [
(
0,
"79a162bda41b98338009c880004ce44d3d84c2bf412f76271fea08279bffed8e",
),
(
2,
"6242cb7cb043b219a77ffa2bd0aedab6735389bbbe8b3b2e88410cf5f74247a5",
),
];
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!("hidden sector {lba}: {got}");
assert_eq!(got, want, "hidden sector {lba} does not match cryptsetup");
}
}
#[test]
fn wrong_password_fails() {
let Ok(path) = std::env::var("VC_ORACLE") else {
return;
};
let file = File::open(&path).unwrap();
assert!(VeraVolume::unlock_with_pim(file, b"wrongpassword", 1).is_err());
}