Skip to content

Repository files navigation

elephant-diffuser

Crates.io Docs.rs Rust 1.81+ License: Apache-2.0 Sponsor

CI Coverage unsafe forbidden Security advisories

The BitLocker Elephant Diffuser as a standalone, dependency-free Rust primitive — the one part of BitLocker's sector cipher no RustCrypto crate provides, validated byte-for-byte against libbde on a real volume.

BitLocker's CBC-plus-diffuser methods (0x8000, 0x8001) wrap AES-CBC in a keyed byte-mixing layer — the Elephant Diffuser. AES, CBC, CCM and SHA-256 all have audited crates; the diffuser does not. This crate is that missing piece, extracted from bitlocker-core so every consumer shares one reviewed implementation.

use elephant_diffuser::{decrypt, encrypt};

let mut sector = vec![0u8; 512];
let sector_key = [0u8; 32]; // caller-derived (BitLocker: AES-ECB over the offset with the TWEAK key)

// Decrypt: Diffuser B, then Diffuser A, then XOR the sector key.
decrypt(&mut sector, &sector_key);

// Encrypt is the exact inverse: XOR, then Diffuser A, then Diffuser B.
encrypt(&mut sector, &sector_key);

What it is (and isn't)

The Elephant Diffuser is a keyed, invertible diffusion transform, not a cipher: it holds no secret and provides no confidentiality. Applied to a sector after AES-CBC decryption (and before AES-CBC encryption), it spreads each bit across the whole sector so a one-bit change cascades. Confidentiality comes from AES; this is the diffusion layer around it.

  • decrypt(sector, sector_key) — Diffuser B → Diffuser A → XOR the 32-byte sector key.
  • encrypt(sector, sector_key) — the exact inverse: XOR → Diffuser A → Diffuser B.

Both operate in place on a sector of any length (BitLocker uses 512-byte sectors).

Why hand-written — the one documented exception

The fleet rule is never hand-roll crypto — use an audited crate. The Elephant Diffuser is the exception, because no crate exists: it is a format-specific transform defined only by Microsoft's implementation and the community reverse engineering in dislocker (diffuser.c) and libbde. The rotation constants (Ra = {9,0,13,0}, Rb = {0,10,0,25}), the five- and three-cycle counts, and the B-then-A-then-XOR order follow that reference. Isolating it in one crate — reviewed, fuzzed, and validated against real data — is how the exception stays disciplined.

Trust but verify

  • #![forbid(unsafe_code)], panic-free by lint, zero dependencies. No unwrap/expect in production; every index is computed with underflow-free modular arithmetic, so the transform never panics on any input length. A cargo-fuzz target drives decrypt/encrypt over arbitrary bytes with the "must not panic" invariant.
  • Tier-1 validated, in situ. The authoritative proof is bitlocker-core's oracle: this code decrypts the real dfvfs bdetogo.raw volume byte-for-byte against pybde. It is correctness-validated against libbde on real data, not independently security-audited — a keyed diffusion transform, not a secret-branching cipher. See docs/validation.md.

Privacy Policy · Terms of Service · © 2026 Security Ronin Ltd

About

The BitLocker Elephant Diffuser (Diffuser A + Diffuser B + sector-key XOR) in pure Rust — the format primitive with no ecosystem crate, validated in-situ against libbde. no_std, panic-free.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages