Documentation
¶
Overview ¶
Package bitlocker reads BitLocker (BDE) encrypted volumes in pure Go.
It unlocks a volume made by Windows 7 or later, including BitLocker To Go, with a password, a recovery password, a startup key (.BEK file) or a clear key, and exposes the decrypted volume as an io.ReaderAt. All six methods are read: AES-CBC 128/256 with and without the Elephant diffuser, and AES-XTS 128/256, on 512-byte and 4 KiB sectors.
The decrypted device is the one cryptsetup's bitlkOpen maps, byte for byte: the original first sectors are read from their encrypted copy, the three metadata areas and that copy's location read as zeros. The tests compare SHA-256 sums with cryptsetup's on volumes Windows made.
Usage ¶
dev, err := bitlocker.Open("/path/to/volume.img", []byte("password"))
if err != nil { log.Fatal(err) }
defer dev.Close()
buf := make([]byte, 512)
_, err = dev.ReadAt(buf, 0) // the NTFS or FAT boot sector
The secret is interpreted as cryptsetup interprets it: as a password for password protectors, as a recovery password ("123456-…", 48 digits) for recovery protectors when it has that shape, and as the contents of a .BEK file for startup-key protectors. A clear-key protector (a volume whose protection is suspended) opens with any secret, nil included.
Not supported ¶
Windows Vista metadata, encrypt-on-write ("used space only") volumes and volumes in the middle of an encryption or decryption are refused with ErrUnsupported; their metadata still reads with ReadInfo. TPM and smart card protectors need hardware. Writing is not implemented: WriteAt returns ErrReadOnly.
Untrusted images ¶
Every offset and size an image declares is checked against the device before use, the metadata is authenticated with the volume master key (AES-CCM, then SHA-256 of the metadata block), and Limits bounds how many 2^20-round key derivations an image with many protectors can ask for.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotBitLocker means the volume header carries neither BitLocker // signature: the device is not a BitLocker volume. ErrNotBitLocker = errors.New("bitlocker: not a BitLocker volume") // ErrCorrupt wraps every refusal of a malformed or inconsistent image. ErrCorrupt = errors.New("bitlocker: corrupt volume") // ErrUnsupported is a well-formed volume this package does not open: // Windows Vista (version 1) metadata, encrypt-on-write ("used space // only") volumes, volumes being encrypted or decrypted, unknown methods. ErrUnsupported = errors.New("bitlocker: unsupported volume") // ErrWrongSecret means no protector of the volume opened with the // secret given. ErrWrongSecret = errors.New("bitlocker: no protector opened with this secret") // ErrLimit means the volume asked for more key derivations than the // Limits allow before one opened. ErrLimit = errors.New("bitlocker: limit exceeded") // ErrReadOnly is returned by WriteAt: this version only reads. ErrReadOnly = errors.New("bitlocker: read-only") )
Errors. Every error this package returns for a malformed image wraps ErrCorrupt; the others are distinct and work with errors.Is.
var DefaultLimits = Limits{MaxKeyDerivations: 16}
DefaultLimits allows 16 key derivations: Windows writes one per password or recovery password, and a volume rarely has more than three.
Functions ¶
Types ¶
type Device ¶
type Device struct {
// contains filtered or unexported fields
}
Device is an unlocked BitLocker volume. ReadAt is safe for concurrent use.
func Open ¶
Open opens the BitLocker volume at path read-only and unlocks it with secret. A block device's size is not what Stat reports on every system: open one with OpenFrom and its size.
func OpenFrom ¶
OpenFrom unlocks the BitLocker volume of size bytes in r with secret. Close on the returned Device closes r.
type Info ¶
type Info struct {
ToGo bool
Kind Kind
SectorSize int
VolumeSize uint64 // the size the metadata records
GUID string // the volume identifier
Method Method
Description string
Protectors []Protector
// Normal reports that the volume is fully encrypted and not being
// converted (current and next state both "encrypted").
Normal bool
// MetadataOffsets are the three 64 KiB metadata areas.
MetadataOffsets [3]uint64
// HeaderOffset and HeaderSize locate the encrypted copy of the original
// first sectors of the volume.
HeaderOffset uint64
HeaderSize uint64
// contains filtered or unexported fields
}
Info is what the metadata says, readable without any secret.
type Limits ¶
type Limits struct {
// MaxKeyDerivations is how many protectors may run the key derivation
// (2^20 SHA-256 each, about 0.1 s) before Open gives up with ErrLimit.
MaxKeyDerivations int
}
Limits bounds the work an untrusted image can ask for.
type Method ¶
type Method uint16
Method is the volume's encryption method.
const ( AES128CBCElephant Method = 0x8000 AES256CBCElephant Method = 0x8001 AES128CBC Method = 0x8002 AES256CBC Method = 0x8003 AES128XTS Method = 0x8004 AES256XTS Method = 0x8005 )
The six methods (cryptsetup BITLK_read_sb; libbde "Encryption methods").
type Protection ¶
type Protection uint16
Protection is how a volume master key protector is unlocked.
const ( ClearKey Protection = 0x0000 TPM Protection = 0x0100 StartupKey Protection = 0x0200 TPMAndPIN Protection = 0x0500 RecoveryPassword Protection = 0x0800 SmartCard Protection = 0x1000 Password Protection = 0x2000 )
The protections Windows writes (cryptsetup get_vmk_protection).
func (Protection) String ¶
func (p Protection) String() string
type Protector ¶
type Protector struct {
GUID string
Protection Protection
// contains filtered or unexported fields
}
Protector is one volume master key protector.