Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement FVEAutoUnlock key unwrapping #37

Open
marcan opened this issue Jan 3, 2019 · 4 comments
Open

Implement FVEAutoUnlock key unwrapping #37

marcan opened this issue Jan 3, 2019 · 4 comments
Assignees

Comments

@marcan
Copy link

marcan commented Jan 3, 2019

Remember that metadata entry 0x000b? This is what that is for.

Windows supports auto-unlocking BitLocker fixed volumes (which are unlocked before user login). This works only when the OS drive is itself using BitLocker. It works like this:

  1. The OS drive gets a 0x000b metadata key entry, which is wrapped with its VMK in the same way the FVEK is. Let's call this the LIBBDE_ENTRY_TYPE_AUTO_UNLOCK_KEY
  2. When a secondary fixed drive is configured to auto unlock, a new VMK record is created in the secondary metadata of the "Startup key" type (name: ExternalKey). This uses a new key to wrap the VMK for the secondary volume.
  3. That new key is subsequently wrapped with the OS drive's AUTO_UNLOCK_KEY, yielding an aes_ccm_encrypted_key
  4. A registry key is created at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FVEAutoUnlock\{volume identifier guid} and a binary value named Data is created with the following format:
  • uint32_t length; // 0x70
  • uint32_t unknown; // 0x9 here
  • GUID vmk_identifier // GUID identifier of the VMK slot in the secondary drive
  • aes_ccm_encrypted key (standard metadata format: u16 size=80; u16 type=0; u16 valuetype=5; u16 version=1; u8 nonce[12]; u8 tag[16]; u8 ciphertext[...])

So the question here is how should this be implemented in libbde? It involves somewhat complex interaction between two volumes and the registry. The steps would have to be something like this:

  • Extract the plaintext AUTO_UNLOCK_KEY from the OS volume (e.g. new bdeinfo feature?)
  • Use bdemount on the OS volume, and then use e.g. the chntpw toolset to inspect the SYSTEM registry and extract the FVEAutoUnlock key
  • Feed both the AUTO_UNLOCK_KEY from the OS volume and the extracted FVEAutoUnlock blob from the registry into libbde, plus the secondary volume. libbde would then have all the information needed to mount the secondary volume, decrypting the FVEAutoUnlockBlob and using the result to decrypt the VMK and finally the volume's FVEK.

Any hints as to what this should look like in libbde? I can give a shot at implementing it once the right way forward is clear.

@joachimmetz
Copy link
Member

@marcan interesting, thx for the update.

So the question here is how should this be implemented in libbde?

I want like to keep the functionality of the library as scoped to BDE itself as possible. I think it would be possible to extend libbde to handle 'AUTO_UNLOCK_KEY + FVEAutoUnlock blob' similar to the start-up key.

Doing the 'AUTO_UNLOCK_KEY + FVEAutoUnlock blob' extraction process IMHO would be more something for dfVFS volume scanner.

@marcan
Copy link
Author

marcan commented Jan 4, 2019

Yeah, I don't think the registry part belongs in libbde. I think it should do the two steps around that: puling the AUTO_UNLOCK_KEY from the OS volume (which is just decrypting key 0x000b just like the FVEK is right now, but dumping it to a file or hex instead) and taking in that key + FVEAutoUnlock blob to unlock a subvolume (which is just an extra decryption step and then works like a normal external key).

@cqjjjzr
Copy link

cqjjjzr commented Jul 23, 2023

I'm trying to playing with this and found that it seems that the Data binary format given by the OP isn't accurate... Here's my speculation:

u32 length = 0x70;
u32 unknown = 0x9;
guid128 vmk_identifier;
filetime64 time_unknown; // What's this for??
u16 length_inner = 0x50;
u16 type = 0;
u16 valuetype = 5;
u16 version = 1;
{filetime64 time; u32 counter} nonce; // For the "counter", I found 0x10000000, 0x10000001 and 0x10000002 across three different volumes' FVEAutoUnlock blob on the same OS installation, so it is really a "counter"?
// What's the "tag" in the OP stands for?
u8 ciphertext[?];

@marcan
Copy link
Author

marcan commented Aug 28, 2023

See #36 for what a "tag" is, why the nonce is opaque and there's no point in trying to interpret is, and how libbde currently botches CCM decryption and thus makes this confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants