bitlocker-forensic
Unlock a BitLocker volume from its password and read the plaintext — a
from-scratch, pure-Rust BitLocker (BDE) decryptor, validated byte-for-byte
against pybde on real disk images.
No dislocker C dependency, no FUSE, no mounting: one library that parses the
FVE metadata, derives the keys from a password, and decrypts sectors
(AES-128-CBC + Elephant Diffuser).
use File;
use BitLockerVolume;
// Unlock the dfvfs BitLocker To Go test image with its published password.
let mut vol = unlock_with_password?;
let mut boot = ;
vol.read_at?; // decrypted FAT boot sector
assert_eq!;
# Ok::
Scope
This build targets exactly what the Tier-1 oracle validates: the password
protector (0x2000) over AES-128-CBC + Elephant Diffuser (method 0x8000).
AES-XTS, recovery-password, startup-key, and TPM protectors are deliberately out
of scope for unlock — but the metadata parser still reports every protector
and cipher it finds. See docs/RESEARCH.md.
The two-crate split
Following the fleet reader/analyzer standard:
| Crate | Role | Emits |
|---|---|---|
bitlocker-core |
reader / decryptor (aes · cbc · ccm · sha2) |
plaintext Read + Seek view + typed FVE metadata |
bitlocker-forensic |
anomaly analyzer over the metadata | graded forensicnomicon::report Findings |
Analyzer findings
| Code | Severity | Meaning |
|---|---|---|
BDE-CLEAR-KEY-PRESENT |
High | a clear-key protector (0x0000) is present ⇒ the volume is effectively unencrypted |
BDE-PROTECTOR-INVENTORY |
Info | one per protector (password / recovery / TPM / startup key / …) |
BDE-WEAK-CIPHER |
Low | AES-CBC ± diffuser is weaker than AES-XTS — consistent with an older OS |
BDE-TO-GO |
Info | a BitLocker To Go removable-media volume |
Findings are observations, never verdicts — the examiner draws conclusions.
Trust but verify
- Every primitive is an audited RustCrypto crate (
aes,cbc,ccm,sha2). The only hand-written cryptographic routine is the Elephant Diffuser — no crate exists for it — implemented to thelibbdereference and validated only against the independentpybdeoracle on the realbdetogo.rawimage, never a self-authored round-trip. - Panic-free, bounds-checked parsing of untrusted volumes;
unwrap/expectdenied in production code (#![forbid(unsafe_code)]); the metadata parser is fuzzed. - Tier-1 validated: decrypted sectors match
pybdebyte-for-byte — seedocs/validation.md.
Privacy Policy · Terms of Service · © 2026 Security Ronin Ltd