BitLocker Drive Encryption (BDE) format
The BitLocker Drive Encryption (BDE) format is used by Microsoft Windows to encrypt volumes.
Overview
There are multiple versions of BitLocker Drive Encryption (BDE):
- BitLocker Windows Vista, Windows 7 and 10; used to encrypt volumes on fixed storage media, like harddisks, which typically contain NTFS file systems.
- BitLocker To Go; introduced in Windows 7; used to encrypt removable drives, which typically contain FAT file systems.
- BitLocker Used Disk Space Only encryption; used to encrypt only the used space of volumes, which presumably was introduced in Windows 8.
- BitLocker Encrypt-on-Write (EOW), which presumably was introduced in Windows 10 (1511).
Note that Windows treats NTFS volumes on removable drives are treated as NTFS volumes on fixed storage media.
Characteristics
| Characteristics | Description |
|---|---|
| Byte order | little-endian |
| Date and time values | FILETIME in UTC |
| Character strings | UCS-2 little-endian, which allows for unpaired Unicode surrogates such as "U+d800" and "U+dc00" |
Identifiers
BitLocker is known to use the following identifiers:
- 4967d63b-2e29-4ad8-8399-f6a339e3d001, for BitLocker and BitLocker To Go
- 92a84d3b-dd80-4d0e-9e4e-b1e3284eaed8, for BitLocker Used Disk Space Only encryption
Metadata files
BitLocker exposes various files in the “\System Volume Information” directory of the unencrypted volume that correspond to the BitLocker metadata areas.
The contents of the metadata files, on an unencrypted volume, consists of 0-byte values. It is assumed that these files are used to prevent the BitLocker metadata to be overwritten.
Note that not all tools zero out the metadata areas.
BitLocker Windows Vista
In BitLocker Windows Vista the “\System Volume Information” directory contains the following BitLocker related files:
- “FVE.{e40ad34d-dae9-4bc7-95bd-b16218c10f72}.[123]” maps a metadata block; typically 16384 bytes in size.
BitLocker Windows Windows 7 and later
In BitLocker Windows 7 and later the “\System Volume Information” directory contains the following BitLocker related files:
- “FVE2.{09cf57b8-9e6c-43d4-ae1f-0408882a397d}.[1-6]”, maps an Encrypt-on-Write (EOW) block map area, used by “Used Disk Space Only encryption”.
- “FVE2.{24e6f0ae-6a00-4f73-984b-75ce9942852d}” maps the block that contains the encrypted boot record; typically 8192 bytes in size.
- “FVE2.{93de4bce-e958-48b6-9fac-602d0294e5ef}.[12]”, maps Encrypt-on-Write (EOW) descriptor, used by “Used Disk Space Only encryption”.
- “FVE2.{aff97bac-a69b-45da-aba1-2cfbce434750}.[12]”, introduced in Windows 8, typically 512 bytes in size (possibly 1 sector in size?).
- “FVE2.{c9ca54a3-6983-46b7-8684-a7e5e23499e3}.[1-6]”, maps an Encrypt-on-Write (EOW) relocation log area, used by “Used Disk Space Only encryption”.
- “FVE2.{da392a22-cae0-4f0f-9a30-b8830385d046}”, introduced in Windows 10, typically 65536 bytes in size.
- “FVE2.{e40ad34d-dae9-4bc7-95bd-b16218c10f72}.[1-3]” maps a metadata block; typically 65536 bytes in size.
BitLocker To Go
BitLocker To Go uses a hybrid volume that has a encrypted and an unencrypted part. The unencrypted part contains various files. Application files for the BitLocker To Go helper application; which can also be found in:
C:\Windows\BitLockerDiscoveryVolumeContents\
- “COV 0000. BL” maps the block that contains the BitLocker To Go GUID and the offsets to the metadata; typically 32768 bytes in size.
- “COV 0000. ER” maps the encrypted data.
- “PAD 0000. PD” maps padding.
- “PAD 0000. NG” unknown; typically 0 bytes in size.
It has been observed that the “COV 0000. ER” and “PAD 0000. NG” files can be split in multiple 4294934528 byte (4 GiB - 32768) on a FAT32 volume, such as “COV 0001. ER”, “COV 0002. ER”, … or “PAD 0001. NG”, …
The “PAD 0000. NG” are presumaly used to fill the root directory with entries so that no new files may be created on the volume.
Keys
To encrypt storage media BitLocker uses different kind of keys.
Volume Master Key (VMK)
The Volume Master Key (VMK) is 256-bit of size and is stored in multiple Volume Master Key (VMK) structures. The VMK is stored encrypted with either the recovery password, external key, or the TPM.
It is also possible that the VMK is stored unencrypted which is referred to as clear key.
Full Volume Encryption Key (FVEK)
The Full Volume Encryption Key (FVEK) is stored encrypted with the Volume Master Key (VMK). The size of the FVEK is dependent on the encryption method used:
- For AES 128-bit the key is 128-bit of size
- For AES 256-bit the key is 256-bit of size
When Elephant Diffuser is used the key data of the structure that hold the FVEK is always 512-bit of size. The First 256-bit are reserved for the FVEK and the other 256-bit for the TWEAK key. Only 128-bit of the 256-bits are used when the encryption method is AES 128-bit.
TWEAK key
The TWEAK is stored encrypted with the Volume Master Key (VMK). The size of the TWEAK key is dependent on the encryption method used:
- For AES 128-bit the key is 128-bit of size
- For AES 256-bit the key is 256-bit of size
The TWEAK key is only present when Elephant Diffuser is used. The TWEAK key is stored in the key data of the structure that hold the Full Volume Encryption Key (FVEK) is always 512-bit of size. The First 256-bit are reserved for the FVEK and the other 256-bit for the TWEAK key. Only 128-bit of the 256-bits are used when the encryption method is AES 128-bit.
Recovery password
BitLocker provides for a recovery (or numerical) password to unlock the encrypted data. The recovery password is used to determine a recovery password key. Not to be confused with the “recovery key” key protector.
Example recovery password:
471207-278498-422125-177177-561902-537405-468006-693451
A valid recovery password consists of 48 digits where every number is dividable by 11 with a remainder of 0. The result of a division by 11 of a number is a 16-bit value. The individual 16-bit values make up a 128-bit key.
The corresponding recovery password key is calculated using the following approach, written partially in pseudo C:
Initialize a structure consisting of:
uint8_t last_sha256[ 32 ];
uint8_t initial_sha256[ 32 ];
uint8_t salt[ 16 ];
uint64_t count;
Initialize both the last SHA-256 and the count to 0.
Calculate the SHA-256 of the 128-bit key and update the initial SHA-256 value.
The salt is stored on disk in the stretch key which is stored in the recovery password key protected Volume Master Key (VMK).
Loop for 1048576 (0x100000) times:
- calculate the SHA-256 of the structure and update the last SHA-256 value
- increment the count by 1
The last SHA-256 value contains the 256-bit key which is recovery pass key that can unlock the recovery password key protected Volume Master Key (VMK).
Clear key
The clear key is an unprotected 256-bit key stored on the volume to decrypt the VMK. It is used when the encrypted volume is being decrypted.
External key
The external key is used by the “startup key” and “recovery key” key protectors. The external key is stored in a file named “{%GUID%}.BEK”. The GUID in the filename equals the key identifier in the BitLocker metadata.
There can be multiple external keys for a single BitLocker encrypted volume. Each key is identified a by a different key identifier.
User key
BitLocker To Go provides for a user password (or passphrase) to unlock the encrypted data. The user password is used to determine a user key.
TODO: check if the password can be maximal 49 characters in size.
Convert the user password into a UCS-2 little-endian string.
Initialize a structure consisting of:
uint8_t last_sha256[ 32 ];
uint8_t initial_sha256[ 32 ];
uint8_t salt[ 16 ];
uint64_t count;
Initialize both the last SHA-256 and the count to 0.
Calculate the SHA-256 of the user password.
Calculate the SHA-256 of the SHA-256 of the user password, and set it as the initial SHA-256 value.
The salt is stored on disk in the stretch key which is stored in the user key (or password) protected Volume Master Key (VMK).
Loop for 1048576 (0x100000) times:
- calculate the SHA-256 of the structure and update the last SHA-256 value
- increment the count by 1
The last SHA-256 value contains the 256-bit key which is user key that can unlock the user key (or password) protected Volume Master Key (VMK).
Encryption methods
BitLocker uses different kind of encryption methods. To encrypt the sector data it either uses AES-CBC (Cipher Block Chaining) with or without Elephant Elephant Diffuser or AES-XTS (XEX-based tweaked-codebook mode with ciphertext stealing).
To encrypt the key data BitLocker uses AES-CCM (Counter with cipher block chaining message authentication code (CBC-MAC)).
AES-CBC
Both encryption and decryption use:
- AES-CBC with FVEK decryption of sector data
The initialization vector of the AES-CBC is the sector offset AES-ECB encrypted with the FVEK stored as a 16-byte little-endian value. The sector offset is the offset of the sector relative from the start of the volume.
AES-CBC with Elephant Diffuser
Encryption:
- XOR with sector key
- Elephant Elephant Diffuser A
- Elephant Elephant Diffuser B
- AES-CBC with FVEK
Decryption:
- AES-CBC with FVEK
- Elephant Elephant Diffuser B
- Elephant Elephant Diffuser A
- XOR with sector key
The initialization vector of the AES-CBC is the sector offset AES-ECB encrypted with the FVEK stored as a 16-byte little-endian value. The sector offset is the offset of the sector relative from the start of the volume.
The sector key 32-byte of size and contains:
- the lower 16-byte contain a little-endian version of the offset of the sector, relative from the start of the volume, AES-ECB encrypted with the TWEAK key
- the upper 16-byte contain a 16-byte little-endian version of the offset of the sector, relative from the start of the volume, with the most upper bit set (or upper byte set to 0x80) AES-ECB encrypted with the TWEAK key
AES-CCM
The key data is encrypted using AES-CCM with an initialization vector of 0.
AES-XTS
The FVEK contains both XTS keys.
Both encryption and decryption use:
- AES-XTS with FVEK decryption of sector data
The initialization vector of the AES-XTS is the sector number stored as a 16-byte little-endian value. The sector number is the offset of the sector relative from the start of the volume divided by the sector size.
Elephant Diffuser
The Elephant Diffuser A and B variants are described in “AES-CBC + Elephant diffuser - A Disk Encryption Algorithm for Windows Vista”.
Virtual sector(s)
In BitLocker the certain sector(s) of the encrypted storage media are handled in a specific manner. These are sectors to store:
- the unencrypted boot record
- the BitLocker metadata
BitLocker Windows Vista
In BitLocker Windows Vista the first sector of the unencrypted boot recored sector is reconstructed by replacing values in the BitLocker boot record, namely
- replacing the “File system signature” with “NTFS\x20\x20\x20\x20”
- replacing the “metadata block 1 cluster block number” with the “MTF mirror cluster block number”
The 15 sectors directly following the first sector are also unencrypted.
The sectors that contain the BDE metadata are shown as empty sectors; containing 0-byte values.
BitLocker Windows 7 and To Go
Both BitLocker Windows 7 and To Go store an encrypted version of the unencrypted boot record in a specific location. This location is defined in the metadata area descriptors.
The encrypted boot record is commonly 8192 bytes an size, entailing the first 16 sectors.
The sectors that contain the encrypted boot recored and the BDE metadata are shown as empty sectors; containing 0-byte values.
BitLocker Windows 10
In later versions of Bitlocker Windows 10 the metadata area descriptors is not always present.
The number of boot record sectors in the metadata block header can be used to determine the boot record size.
The encrypted boot record is commonly 8192 bytes an size, entailing the first 16 sectors.
Boot record
BitLocker Windows Vista
The BitLocker Windows Vista boot record is similar to a NTFS boot record. The differences have been emphasized in bold. The boot record is 512 bytes of size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 3 | "\xeb\x52\x90" | Boot entry point |
| 3 | 8 | "-FVE-FS-" | File system signature |
| DOS version 2.0 BIOS parameter block (BPB) | |||
| 11 | 2 | Bytes per sector. Note that the following values are supported by mkntfs: 256, 512, 1024, 2048 and 4096 | |
| 13 | 1 | Number of sectors per cluster block | |
| 14 | 2 | 0 | Unknown (Reserved Sectors), which is not used by NTFS and must be 0 |
| 16 | 1 | 0 | Number of cluster block allocation tables, which is not used by NTFS and must be 0 |
| 17 | 2 | 0 | Number of root directory entries, which is not not used by NTFS and must be 0 |
| 19 | 2 | 0 | Number of sectors (16-bit), which is not used by NTFS must be 0 |
| 21 | 1 | Media descriptor | |
| 22 | 2 | 0 | Cluster block allocation table size (16-bit) in number of sectors, which is not used by NTFS and must be 0 |
| DOS version 3.4 BIOS parameter block (BPB) | |||
| 24 | 2 | 0x3f | Sectors per track, which is not used by NTFS |
| 26 | 2 | 0xff | Number of heads, which is not used by NTFS |
| 28 | 4 | 0x3f | Number of hidden sectors, which is not used by NTFS |
| 32 | 4 | 0x00 | Number of sectors (32-bit), which is not used by NTFS must be 0 |
| NTFS version 8.0 BIOS parameter block (BPB) or extended BPB, which was introduced in Windows NT 3.1 | |||
| 36 | 1 | 0x80 | Unknown (Disc unit number), which is not used by NTFS |
| 37 | 1 | 0x00 | Unknown (Flags), which is not used by NTFS |
| 38 | 1 | 0x80 | Unknown (BPB version signature byte), which is not used by NTFS |
| 39 | 1 | 0x00 | Unknown (Reserved), which is not used by NTFS |
| 40 | 8 | Number of sectors (64-bit) | |
| 48 | 8 | Master File Table (MFT) cluster block number | |
| 56 | 8 | Metadata block 1 cluster block number | |
| 64 | 4 | MFT entry size | |
| 68 | 4 | Index entry size | |
| 72 | 8 | Volume serial number | |
| 80 | 4 | 0 | Checksum, which is not used by NTFS |
| Common | |||
| 84 | 426 | Boot code | |
| 510 | 2 | "\x55\xaa" | The (boot) signature |
Note that the number of sectors can be 1 less then the value indicated in the partition table.
BitLocker Windows 7 and later
The BitLocker Windows 7 boot record for a NTFS volume is similar to a FAT32 boot record. The differences have been emphasized in bold. The boot record is 512 bytes of size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 3 | "\xeb\x58\x90" | Boot entry point Boot entry point (JMP +90, NOP) |
| 3 | 8 | "-FVE-FS-" | File system signature (or OEM name) |
| DOS version 2.0 BIOS parameter block (BPB) | |||
| 11 | 2 | Bytes per sector, which must be 512, 1024, 2048 or 4096 | |
| 13 | 1 | Sectors per cluster block, which must be 1, 2, 4, 8, 16, 32, 64 or 128 | |
| 14 | 2 | Number of reserved sectors (reserved region), which starts at the first sector of the volume (sector 0) and must be 1 or more (typically 1 or 32) | |
| 16 | 1 | Number of cluster block allocation tables, which must be 1 or more (typically 2) | |
| 17 | 2 | Number of root directory entries | |
| 19 | 2 | Total number of sectors (16-bit) | |
| 21 | 1 | Media descriptor | |
| 22 | 2 | Cluster block allocation table size (16-bit) | |
| DOS version 3.4 BIOS parameter block (BPB) | |||
| 24 | 2 | Number of sectors per track | |
| 26 | 2 | Number of heads | |
| 28 | 4 | Number of hidden sectors, which contains the volume start sector number | |
| 32 | 4 | Total number of sectors (32-bit) | |
| 36 | 4 | Cluster block allocation table size (32-bit), in number of sectors | |
| 40 | 2 | Extended flags | |
| 42 | 1 | Format revision minor number | |
| 43 | 1 | Format revision major number | |
| 44 | 4 | Root directory start cluster | |
| 48 | 2 | File system information (FSINFO) sector number | |
| 50 | 2 | Boot record sector number | |
| 52 | 12 | Unknown (reserved) | |
| 64 | 1 | Drive number | |
| 65 | 1 | Unknown (reserved for Windows NT) | |
| 66 | 1 | Extended boot signature | |
| If extended boot signature == 0x29 | |||
| 67 | 4 | Volume serial number, which can be derived from the system current date and time | |
| 71 | 11 | Volume label, which contains a narrow character string or "NO\x20NAME\x20\x20\x20\x20" if not set | |
| 82 | 8 | "FAT32\x20\x20\x20" | File system hint, which is informational and not required |
| If extended boot signature != 0x29 | |||
| 67 | 23 | Unknown | |
| Common | |||
| 90 | 70 | Bootcode | |
| 160 | 16 | BitLocker identifier, which contains a GUID | |
| 176 | 8 | Metadata block 1 offset, which is relative to the start of the volume | |
| 184 | 8 | Metadata block 2 offset, which is relative to the start of the volume | |
| 192 | 8 | Metadata block 3 offset, which is relative to the start of the volume | |
| 200 | 310 | Unknown (part of bootcode) | |
| 510 | 2 | 0x55 0xaa | Sector signature |
BitLocker To Go
BitLocker To Go on an NTFS volume is similar to BitLocker Windows 7. The BitLocker Windows To Go boot record for a FAT volume is similar to FAT32 boot record. The differences have been emphasized in bold. The boot record is 512 bytes in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 3 | "\xeb\x58\x90" | Boot entry point |
| 3 | 8 | "MSWIN4.1" | File system signature (or OEM name) |
| DOS version 2.0 BIOS parameter block (BPB) | |||
| 11 | 2 | Bytes per sector, which must be 512, 1024, 2048 or 4096 | |
| 13 | 1 | Sectors per cluster block, which must be 1, 2, 4, 8, 16, 32, 64 or 128 | |
| 14 | 2 | Number of reserved sectors (reserved region), which starts at the first sector of the volume (sector 0) and must be 1 or more (typically 1 or 32) | |
| 16 | 1 | Number of cluster block allocation tables, which must be 1 or more (typically 2) | |
| 17 | 2 | Number of root directory entries | |
| 19 | 2 | Total number of sectors (16-bit) | |
| 21 | 1 | Media descriptor | |
| 22 | 2 | Cluster block allocation table size (16-bit) | |
| DOS version 3.4 BIOS parameter block (BPB) | |||
| 24 | 2 | Number of sectors per track | |
| 26 | 2 | Number of heads | |
| 28 | 4 | Number of hidden sectors | |
| 32 | 4 | Total number of sectors (32-bit) | |
| 36 | 4 | Cluster block allocation table size (32-bit), in number of sectors | |
| 40 | 2 | Extended flags | |
| 42 | 1 | Format revision minor number | |
| 43 | 1 | Format revision major number | |
| 44 | 4 | Root directory start cluster | |
| 48 | 2 | File system information (FSINFO) sector number | |
| 50 | 2 | Boot record sector number | |
| 52 | 12 | Unknown (reserved) | |
| 64 | 1 | Drive number | |
| 65 | 1 | Unknown (reserved for Windows NT) | |
| 66 | 1 | Extended boot signature | |
| If extended boot signature == 0x29 | |||
| 67 | 4 | Volume serial number, which can be derived from the system current date and time | |
| 71 | 11 | Volume label, which contains a narrow character string or "NO\x20NAME\x20\x20\x20\x20" if not set | |
| 82 | 8 | "FAT32\x20\x20\x20" | File system hint, which is informational and not required |
| If extended boot signature != 0x29 | |||
| 67 | 23 | Unknown | |
| Common | |||
| 90 | 334 | Bootcode | |
| 424 | 16 | BitLocker identifier, which contains a GUID | |
| 440 | 8 | Metadata block 1 offset, which is relative to the start of the volume | |
| 448 | 8 | Metadata block 2 offset, which is relative to the start of the volume | |
| 456 | 8 | Metadata block 3 offset, which is relative to the start of the volume | |
| 464 | 46 | Unknown | |
| 510 | 2 | 0x55 0xaa | Sector signature |
BitLocker Used Disk Space Only encryption
The BitLocker Used Disk Space Only encryption boot record for a NTFS volume is similar to a BitLocker Windows 7 and later boot record. The differences have been emphasized in bold. The boot record is 512 bytes of size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 3 | "\xeb\x58\x90" | Boot entry point Boot entry point (JMP +90, NOP) |
| 3 | 8 | "-FVE-FS-" | File system signature (or OEM name) |
| DOS version 2.0 BIOS parameter block (BPB) | |||
| 11 | 2 | Bytes per sector, which must be 512, 1024, 2048 or 4096 | |
| 13 | 1 | Sectors per cluster block, which must be 1, 2, 4, 8, 16, 32, 64 or 128 | |
| 14 | 2 | Number of reserved sectors (reserved region), which starts at the first sector of the volume (sector 0) and must be 1 or more (typically 1 or 32) | |
| 16 | 1 | Number of cluster block allocation tables, which must be 1 or more (typically 2) | |
| 17 | 2 | Number of root directory entries | |
| 19 | 2 | Total number of sectors (16-bit) | |
| 21 | 1 | Media descriptor | |
| 22 | 2 | Cluster block allocation table size (16-bit) | |
| DOS version 3.4 BIOS parameter block (BPB) | |||
| 24 | 2 | Number of sectors per track | |
| 26 | 2 | Number of heads | |
| 28 | 4 | Number of hidden sectors, which contains the volume start sector number | |
| 32 | 4 | Total number of sectors (32-bit) | |
| 36 | 4 | Cluster block allocation table size (32-bit), in number of sectors | |
| 40 | 2 | Extended flags | |
| 42 | 1 | Format revision minor number | |
| 43 | 1 | Format revision major number | |
| 44 | 4 | Root directory start cluster | |
| 48 | 2 | File system information (FSINFO) sector number | |
| 50 | 2 | Boot record sector number | |
| 52 | 12 | Unknown (reserved) | |
| 64 | 1 | Drive number | |
| 65 | 1 | Unknown (reserved for Windows NT) | |
| 66 | 1 | Extended boot signature | |
| If extended boot signature == 0x29 | |||
| 67 | 4 | Volume serial number, which can be derived from the system current date and time | |
| 71 | 11 | Volume label, which contains a narrow character string or "NO\x20NAME\x20\x20\x20\x20" if not set | |
| 82 | 8 | "FAT32\x20\x20\x20" | File system hint, which is informational and not required |
| If extended boot signature != 0x29 | |||
| 67 | 23 | Unknown | |
| Common | |||
| 90 | 70 | Bootcode | |
| 160 | 16 | BitLocker Used Disk Space Only identifier, which contains a GUID | |
| 176 | 8 | Metadata block 1 offset, which is relative to the start of the volume | |
| 184 | 8 | Metadata block 2 offset, which is relative to the start of the volume | |
| 192 | 8 | Metadata block 3 offset, which is relative to the start of the volume | |
| 200 | 8 | Encrypt-on-Write descriptor 1 offset, which is relative to the start of the volume | |
| 208 | 8 | Encrypt-on-Write descriptor 2 offset, which is relative to the start of the volume | |
| 216 | 294 | Unknown (part of bootcode) | |
| 510 | 2 | 0x55 0xaa | Sector signature |
Note that Windows 10 version for Bitlocker without “Used Disk Space Only encryption” can also contain Encrypt-on-Write structures within the metadata blocks, these might be remnants of of encrypting the volume.
Metadata block
A BitLocker encrypted volume contains 3 metadata blocks. Which is typically:
- 12384 bytes in size for BitLocker Windows Vista;
- 65536 bytes in size for BitLocker Windows 7 and later.
A metadata block consists of:
- a (metadata) block header
- a metadata header
- an array of metadata entries
- padding (0-byte values)
Metadata block header
Metadata block header version 1 - Windows Vista
The metadata block header version 1 is 64 bytes in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 8 | "-FVE-FS-" | Signature |
| 8 | 2 | Unknown (Header size?) | |
| 10 | 2 | 1 | Format version |
| 12 | 2 | Unknown, which is commonly 0x04 | |
| 14 | 2 | Unknown, which is commonly 0x04 | |
| 16 | 16 | 0 | Unknown (empty values) |
| 32 | 8 | metadata block 1 offset, which is relative to the start of the volume | |
| 40 | 8 | metadata block 2 offset, which is relative to the start of the volume | |
| 48 | 8 | metadata block 3 offset, which is relative to the start of the volume | |
| 56 | 8 | MFT mirror cluster block number |
Metadata block header version 2 – Windows 7 and later
The metadata block header version 2 is 64 bytes in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 8 | "-FVE-FS-" | Signature |
| 8 | 2 | Unknown (Header size?) | |
| 10 | 2 | 2 | Format version |
| 12 | 2 | Unknown, which is commonly 0x04, but 0x05 has been observed in a partial decrypted volume (protection status?) | |
| 14 | 2 | Unknown, which is commonly 0x04, but 0x01 has been observed in a partial decrypted volume | |
| 16 | 8 | Encrypted volume size, in number of bytes | |
| 24 | 4 | Unknown | |
| 28 | 4 | Number of boot record sectors | |
| 32 | 8 | metadata block 1 offset, which is relative to the start of the volume | |
| 40 | 8 | metadata block 2 offset, which is relative to the start of the volume | |
| 48 | 8 | metadata block 3 offset, which is relative to the start of the volume | |
| 56 | 8 | Boot record offset, which is relative to the start of the volume and contains the offset of the boot record of the unencrypted bolume |
Note that when decrypting BitLocker will decrypt from the back to the front. The encrypted volume size contains the number of bytes of the volume that are still encrypted (or need to be decrypted).
Metadata header
The metadata header is 48 bytes in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 4 | Metadata size, which includes the size value but not the size of the metadata block header | |
| 4 | 4 | 1 | Format version |
| 8 | 4 | 48 | Metadata header size |
| 12 | 4 | Metadata size copy | |
| 16 | 16 | Volume identifier, which contains a GUID | |
| 32 | 4 | Next nonce counter | |
| 36 | 2 | Encryption method | |
| 38 | 2 | Copy of encryption method | |
| 40 | 8 | Creation time, which contains a FILETIME |
Note that it is currently unknown what the copy of encryption method value is used for.
Encryption methods
| Value | Identifier | Description |
|---|---|---|
| 0x0000 | Unknown (Not encrypted/External Key) | |
| 0x1000 | Unknown (Used in stretch key) | |
| 0x1001 | Unknown (Used in stretch key) | |
| 0x2000 | Unknown (Used in AES-CCM encrypted key) | |
| 0x2001 | Unknown (Used in AES-CCM encrypted key) | |
| 0x2002 | Unknown (Used in AES-CCM encrypted key) | |
| 0x2003 | Unknown (Used in AES-CCM encrypted key) | |
| 0x2004 | Unknown (Used in AES-CCM encrypted key) | |
| 0x2005 | Unknown (Used in AES-CCM encrypted key) | |
| 0x8000 | AES-128-CBC with Elephant Diffuser | |
| 0x8001 | AES-256-CBC with Elephant Diffuser | |
| 0x8002 | AES-128-CBC | |
| 0x8003 | AES-256-CBC | |
| 0x8004 | AES-128-XTS | |
| 0x8005 | AES-256-XTS |
Metadata entry
The metadata entry is of variable size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 2 | Entry size, which includes the size value | |
| 2 | 2 | Entry type | |
| 4 | 2 | Value type | |
| 6 | 2 | Unknown (Flags? Values of 0x0001, 0x0003, 0x0005 and 0x0105 have been observed) | |
| 8 | ... | Entry data |
Metadata entry types
| Value | Identifier | Description |
|---|---|---|
| 0x0000 | None, entry is a property | |
| 0x0002 | Volume Master Key (VMK) | |
| 0x0003 | Full Volume Encryption Key (FVEK) | |
| 0x0004 | Unknown (Validation) | |
| 0x0006 | Startup key | |
| 0x0007 | Description (Drive label), which contains computer name, volume name and date | |
| 0x000b | Unknown (FVEAutoUnlock key?) | |
| 0x000f | Metadata area descriptors |
Note that older versions of BitLocker use a locale dependent date format in the description, such as “MM/DD/YYYY”. Recent versions of BitLocker use “YYYY-MM-DD”.
Metadata value types
| Value | Identifier | Description |
|---|---|---|
| 0x0000 | Erased | |
| 0x0001 | Key | |
| 0x0002 | String, which contains an UCS-2 little-endian string with end-of-string character | |
| 0x0003 | Stretch Key | |
| 0x0004 | Use Key | |
| 0x0005 | AES-CCM encrypted key | |
| 0x0006 | TPM encoded key | |
| 0x0007 | Validation | |
| 0x0008 | Volume master key | |
| 0x0009 | External key | |
| 0x000a | Update | |
| 0x000b | Error | |
| 0x000f | Metadata area descriptors |
Key encrypted key (KEK)
The key encrypted key has value type 0x0001 and is variable in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 2 | Encryption method | |
| 2 | 2 | Unknown | |
| 4 | ... | Key data |
Stretch encrypted key
The stretch encrypted key has value type 0x0003 and is variable in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 2 | Encryption method | |
| 2 | 2 | Unknown | |
| 4 | 16 | Salt | |
| 20 | ... | Metadata entry, which contains an AES-CCM encrypted key |
AES-CCM encrypted key
The AES-CCM encrypted key has value type 0x0005 and is variable in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| Nonce | |||
| 0 | 8 | Nonce date and time, which contains a FILETIME | |
| 8 | 4 | Nonce counter | |
| 12 | 16 | AES-CCM tag (CBC-MAC) | |
| 28 | ... | AES-CCM encrypted data | |
Unencrypted (AES-CCM encrypted) data
The unencrypted (AES-CCM encrypted) data is of variable size and consist of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 4 | Size, which does not include the size of the MAC | |
| 4 | 2 | 1 | Unknown (Format version) |
| 6 | 2 | Unknown | |
| 8 | 2 | Encryption method | |
| 10 | 2 | Unknown | |
| 12 | ... | Unencrypted key data |
TPM encoded key
The TPM encoded key has value type 0x0006 and is variable in size and consists of:
TODO: complete section
Validation
The validation has value type 0x0007 and is variable in size and consists of:
TODO: complete section
Volume Master Key (VMK)
The Volume Master Key has value type 0x0008 and is variable in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 16 | Key identifier, which contains a GUID | |
| 16 | 8 | Last modification date and time, which contains a FILETIME | |
| 24 | 2 | Unknown | |
| 26 | 2 | Protector type | |
| 28 | ... | Properties, which contains an array of metadata entries, where entry type is 0 |
The available properties depend on the VMK type.
The clear key protected VMK consists of:
- key (with 256-bit of key data)
- AES-CCM encrypted key
The external key protected VMK consists of:
- optional description string containing “ExternalKey\x00”
- Stretch Key
- AES-CCM encrypted key
The password protected VMK consists of:
- optional description string containing “ExternalKey\x00”
- Stretch Key
- AES-CCM encrypted key
The recovery password key protected VMK consists of:
- optional description string containing “DiskPassword\x00”
- Stretch Key
- AES-CCM encrypted key
The TPM protected VMK consists of:
- optional description string containing “TPM Protection\x00”
- TPM encoded key
Key protector types
| Value | Identifier | Description |
|---|---|---|
| 0x0000 | VMK protected with clear key, which basically is an unprotected VMK | |
| 0x0100 | VMK protected with TPM | |
| 0x0200 | VMK protected with external key (startup key or recovery key) | |
| 0x0500 | VMK protected with TPM and PIN | |
| 0x0800 | VMK protected with recovery password | |
| 0x2000 | VMK protected with password (or passphrase) |
TODO: SID (or Active Directory account or group) protector
External Key
The External Key has value type 0x0009 and is variable in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 16 | Key identifier, which contains a GUID | |
| 16 | 8 | Last modification date and time, which contains a FILETIME | |
| 24 | ... | Properties, which contains an array of metadata entries where the entry type is set to 0 |
The available properties:
- optional description string containing “ExternalKey\x00”
- key
Metadata area descriptors
The metadata area descriptors has value type 0x000f and is 16 or more bytes in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 8 | Boot record offset | |
| 8 | 8 | Boot record size | |
| If size > 16, related to "FVE2.{aff97bac-a69b-45da-aba1-2cfbce434750}.[12]"? | |||
| 16 | 2 | 3, 4 or 5 | Unknown (format version or number of descriptors?) |
| 18 | 2 | 36, 60 or 76 | Unknown (size of additional data?) |
| 20 | 4 | Unknown | |
| 24 | 8 | Unknown (flags?) | |
| 32 | 8 | Unknown (offset?) | |
| 40 | 4 | Unknown (size?) | |
| 44 | 4 | 512 | Logical sector size |
| 48 | 4 | 512 or 4096 | Physical sector size |
| If additional data size > 36 | |||
| 52 | 8 | 10 | Unknown |
| 60 | 4 | 0x0000295a, 0x00004a61, 0x00004a62 or 0x00004a65 | Unknown |
| 64 | 8 | 2 | Unknown |
| 72 | 4 | 0x02010110 | Unknown |
| If additional data size > 60 | |||
| 76 | 8 | Unknown area offset, related to "FVE2.{da392a22-cae0-4f0f-9a30-b8830385d046}" | |
| 84 | 8 | Unknown area size, related to "FVE2.{da392a22-cae0-4f0f-9a30-b8830385d046}" | |
The metadata area descriptors seems to have been introduced in Windows 7. They specify the location, within the encrypted volume, where certain metadata is stored, such as the unencrypted boot record.
The unencrypted boot record is commonly 8192 bytes in size for BitLocker Windows 7 (and later) and 5365760 bytes for BitLocker To Go.
Unknown flags
| Value | Identifier | Description |
|---|---|---|
| 0x01 | ||
| 0x02 | ||
| 0x04 | ||
| 0x08 | ||
| 0x10 | ||
| 0x20 | ||
| 0x40 | Unknown (related to pause? seen: 0x4b while paused of used disk space only) | |
| 0x80 | Unknown (related to pause? seen: 0xcb after initialization of used disk space only) |
BitLocker External Key (BEK) file
A BitLocker External Key (BEK) file is commonly 156 bytes in size and consists of:
- a file header
- an array of metadata entries
BEK file header
The BEK file header is similar to the metadata header. The BEK file header is 48 bytes in size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 4 | Metadata size, which includes the size value | |
| 4 | 4 | 1 | Format version |
| 8 | 4 | 48 | Metadata header size |
| 12 | 4 | Unknown (Metadata size copy) | |
| 16 | 16 | Volume identifier, which contains a GUID | |
| 32 | 4 | Next nonce counter | |
| 36 | 4 | Encryption method | |
| 40 | 8 | Creation time, which contains a FILETIME |
The key identifier in the file must match the key identifier in the Volume Master Key (VMK).
BEK metadata entry
The format of a BEK metadata entry is similar to the format of a metadata entry.
The metadata in a BEK file consists of an external key, which contains 256-bits of unprotected key data.
The identifier of the VMK should match the identifier in the BEK file header.
Encrypt-on-Write (EOW)
Checksums use a CRC-32 with the polynominal 0xedb88320 and initial value 0.
Encrypt-on-Write (FVE-EOW) descriptor
The Encrypt-on-Write (FVE-EOW) descriptor is variable of size and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| Header | |||
| 0 | 8 | "FVE-EOW\x00" | Signature |
| 8 | 2 | 56 | Header size |
| 10 | 2 | Data size | |
| 12 | 4 | Logical sector size (or EOW data sector size?) | |
| 16 | 4 | Physical sector size (or block record size?) | |
| 20 | 4 | Relocation block size | |
| 24 | 4 | Encrypt-on-Write relocation log area size | |
| 28 | 4 | Encrypt-on-Write relocation log entry size | |
| 32 | 4 | Number of block map offsets | |
| 36 | 4 | Checksum of the data from the start of the Encrypt-on-Write descriptor upto data size with the checksum value set to 0 | |
| 40 | 8 | Encrypt-on-Write descriptor 1 offset | |
| 48 | 8 | Encrypt-on-Write descriptor 2 offset | |
| 56 | number x 8 | Array of 64-bit block map area offsets | |
| ... | ... | Unknown (empty values) | |
Note that Encrypt-on-Write descriptor 1 and 2 are copies and should reference the same block map areas.
Encrypt-on-Write block map area
The Encrypt-on-Write block map area is variable of size and consists of:
- Encrypt-on-Write block map (FVE-EOWBM)
- One or more Encrypt-on-Write block (map) records
Note that “FVE2.{09cf57b8-9e6c-43d4-ae1f-0408882a397d}.[1-6]” masks the Encrypt-on-Write block map area, with a 4096 aligment size.
Encrypt-on-Write block map (FVE-EOWBM)
The Encrypt-on-Write block map (FVE-EOWBM) is variable of size, stored as a (physical) sector, and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| Header | |||
| 0 | 10 | "FVE-EOWBM\x00" | Signature |
| 10 | 2 | 60 | Header size |
| 12 | 4 | Block map size, including the size of the block records | |
| 16 | 4 | Block map index, corresponds to the index in the offset array of the EOW data | |
| 20 | 8 | Volume region offset, region (or area) of the volume this block map represents | |
| 28 | 8 | Volume region size | |
| 36 | 8 | Encrypt-on-Write relocation log area offset | |
| 44 | 4 | Block record offset 1, relative to start of the block map | |
| 48 | 4 | Block record offset 2, relative to start of the block map | |
| 52 | 4 | Block record size | |
| 56 | 4 | Checksum, of the (physical) sector data with the checksum value set to 0 | |
| 60 | ... | Unknown (empty values) | |
Encrypt-on-Write block (map) record (FVE-EOWBR)
The Encrypt-on-Write block (map) record (FVE-EOWBR) is variable of size, stored as one or more (physical) sectors, and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| Header | |||
| 0 | 10 | "FVE-EOWBR\x00" | Signature |
| 10 | 2 | 36 | Header size |
| 12 | 4 | Physical sector size | |
| 16 | 4 | Unknown (bitmap size, in number of bits?) | |
| 20 | 4 | Sequence number | |
| 24 | 4 | 0 | Unknown |
| 28 | 4 | Unknown (flags?, seen 0 and 1) | |
| 32 | 4 | Checksum, of the (physical) sectors data with the checksum value set to 0 | |
| 36 | ... | Bitmap | |
| ... | ... | Unknown (empty values) | |
Encrypt-on-Write relocation log area
The Encrypt-on-Write Encrypt-on-Write relocation log area is variable of size and consists of:
- Encrypt-on-Write relocation log area (OLRDHEVF2) header
- Encrypt-on-Write relocation log entries
- Encrypt-on-Write relocation log entry descriptor
- encrypted sector data or 0-byte values
- backup of Encrypt-on-Write relocation log entry descriptor
- backup of Encrypt-on-Write relocation log area (OLRDHEVF2) header
- Unknown (empty values)
Note that “FVE2.{c9ca54a3-6983-46b7-8684-a7e5e23499e3}.[1-6]” masks the Encrypt-on-Write relocation log area, with a 4096 aligment size.
Encrypt-on-Write relocation log area (OLRDHEVF2) header
The Encrypt-on-Write relocation log area (OLRDHEVF2) header is variable of size, stored as a (logical) sector, and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 10 | "OLRDHEVF2\x00" | Signature |
| 10 | 2 | 1 | Unknown |
| 12 | 2 | 2 | Unknown (Number of entries?) |
| 14 | 4 | Unknown (Logical sector or entry descriptor size?) | |
| 18 | 8 | (Encrypted) volume size | |
| 26 | 4 | Relocation block size | |
| 30 | 4 | Encrypt-on-Write relocation log entry size | |
| 34 | 4 | 32 | Unknown |
| 38 | 4 | 2 | Unknown |
| 42 | 8 | Volume region offset, region (or area) of the volume this relocation log represents |
Encrypt-on-Write relocation log entry descriptor
The Encrypt-on-Write relocation log entry descriptor is variable of size, stored as a (logical) sector, and consists of:
| Offset | Size | Value | Description |
|---|---|---|---|
| 0 | 2 | 32 | Unknown |
| 2 | 2 | 1 | Unknown |
| 4 | 2 | Unknown (0 if unencrypted region?) | |
| 6 | 2 | 0 | Unknown |
| 8 | 4 | 0 | Unknown |
| 12 | 8 | Volume region offset, region (or area) of the volume this relocation log entry represents, or 0 if the region is not used by the relocation log | |
| 20 | 4 | (Used) encrypted sector data size | |
| 38 | 4 | Checksum of the encrypted sectors data | |
| 42 | 4 | Unknown (checksum of the unencrypted sectors data?) |
Note that an Encrypt-on-Write relocation log entry descriptor can be empty (filled with 0-byte values).
Encrypt-on-Write encrypted sector data
- 16 bytes of encrypted sector data per sector? decryption sector key is the corresponding volume region offset
TODO: determine if 32 is a compression factor, given 16 x 32 = 512