Skip to main content

bitlocker/
lib.rs

1//! # bitlocker-core — a from-scratch BitLocker (BDE) reader and decryptor
2//!
3//! Parses the BitLocker Drive Encryption on-disk format (the `-FVE-FS-` /
4//! BitLocker To Go volume header, the FVE metadata block, and its key-protector
5//! entries) and decrypts a volume from a password or recovery password, exposing
6//! a plaintext `Read + Seek` view.
7//!
8//! Scope of this build: the **password** (`0x2000`), **recovery-password**
9//! (`0x0800`), and **clear-key** (`0x0000`, no credential) protectors over **five
10//! of the six** BitLocker ciphers, each validated by a `pybde` oracle —
11//! AES-128-CBC ± Elephant Diffuser (`0x8000` / `0x8002`), AES-256-CBC (`0x8003`),
12//! and XTS-AES-128/256 (`0x8004` / `0x8005`). Only AES-256-CBC + Elephant Diffuser
13//! (`0x8001`) is recognized-but-refused (no oracle yet); startup-key and TPM
14//! protectors are out of scope for *unlock*. The metadata parser still *reports*
15//! every protector and cipher it finds.
16//!
17//! Every primitive comes from an audited crate — `aes`, `cbc`, `ccm`, `sha2`,
18//! and `xts-mode` for the XTS methods — except the Elephant Diffuser, for which
19//! no ecosystem crate exists; it lives in our own [`elephant_diffuser`] crate
20//! (extracted from here) and is validated **in situ** by this repo's Tier-1
21//! oracle (never a self-authored round-trip, which would prove nothing).
22//!
23//! ```no_run
24//! use std::fs::File;
25//! use bitlocker::BitLockerVolume;
26//!
27//! let image = File::open("bdetogo.raw")?;
28//! let mut volume = BitLockerVolume::unlock_with_password(image, "bde-TEST")?;
29//! let mut boot = [0u8; 512];
30//! volume.read_at(0, &mut boot)?;
31//! # Ok::<(), Box<dyn std::error::Error>>(())
32//! ```
33
34#![forbid(unsafe_code)]
35#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
36
37mod bytes;
38mod crypto;
39mod error;
40mod guid;
41mod header;
42mod metadata;
43mod method;
44mod volume;
45
46pub use error::{BdeError, Result};
47pub use guid::format_guid;
48pub use header::{BdeVariant, VolumeHeader};
49pub use metadata::{FveMetadata, MetadataEntry};
50pub use volume::{BitLockerVolume, DecryptedVolume};