Accessing BitLocker Partitions in Linux

I use VeraCrypt for my own cross-platform encryption needs — but not everyone has it installed. I try not to be that person who makes everyone install thirty different applications just to communicate with them and exchange files. We all know that person.

I’m sure you’re a lot of fun at all the parties you don’t get invited to. Really. (Image attribution Creative Commons

Today I was asked to provide a few hundred megabytes of potentially sensitive configuration information to a customer stakeholder. That’s pretty close to impossible over email even if it weren’t unwise so I needed to prepare a removable drive.

It’s our company policy as well as industry best practice that any customer data needs to be transported encrypted. I’m fairly certain my customer doesn’t use VeraCrypt though and he’s very windowsy. It makes the most sense to use my work machine to BitLocker encrypt a USB stick for him. But what if I want to access the data in transit ?

A quick google for ‘bitlocker linux’ brought up dislocker. What an excellent little utility written by a no doubt wonderful human being. Let’s dive straight in.

unit@potato ~ $ git clone
unit@potato ~ $ ls CMakeFiles cmake_uninstall.cmake man
cmake cmake_install.cmake include LICENSE.txt
CMakeCache.txt CMakeLists.txt install_manifest.txt Makefile src

That’s a pretty normal looking cmake project. Let’s take a look at the because I am a modern new age human person and I can read instructions.

This file describes how to install dislocker onto your machine.
You need:
- Compiler, gcc or clang;
- cmake (at least version 2.6);
- make (or gmake, for FreeBSD);
- Headers for FUSE;
- Headers for PolarSSL/mbedTLS;
- A partition encrypted with BitLocker, from Windows Vista, 7 or 8.

That looks relatively straightforward. PolarSSL has been renamed and the project is now called mbedTLS, so the command to pull down the build dependencies is as below.

unit-0xbcd@potato ~ $ apt install gcc cmake make libfuse-dev libmbedtls-dev ruby-dev

Now we have the build dependencies we can configure and compile the code. It’s best to do these steps as an unprivileged user when compiling from source or you end up with ugly root owned files in your source trees that make it irritating to update the source tree or make clean.

Cmake will not default to the current directory. You must specify the current directory with . at the end of the cmake command. You are far too broken to remember this having worked as a software developer before cmake became popular and you will forget this every time.

unit-0xbcd@potato ~ $ cmake .
unit-0xbcd@potato ~ $ make
unit-0xbcd@potato ~ $ sudo make install

After watching all the pretty cmake colours and installing the new binaries we should in theory have a dislocker. None of the steps complained about missing libraries but it’s always good to check that we have ended up with what we expected to get.

unit-0xbcd@potato ~ $ ldd `which dislocker` => (0x00007ffd1f566000) => /lib/x86_64-linux-gnu/ (0x00007f26eeb55000) => /usr/local/lib/ (0x00007f26ee93b000) => /lib/x86_64-linux-gnu/ (0x00007f26ee571000) => /lib/x86_64-linux-gnu/ (0x00007f26ee36d000) => /lib/x86_64-linux-gnu/ (0x00007f26ee150000) => /usr/lib/x86_64-linux-gnu/ (0x00007f26edefa000) => /usr/lib/x86_64-linux-gnu/ (0x00007f26eda7c000)
/lib64/ (0x0000556941579000) => /usr/lib/x86_64-linux-gnu/ (0x00007f26ed7fc000) => /lib/x86_64-linux-gnu/ (0x00007f26ed5c3000) => /lib/x86_64-linux-gnu/ (0x00007f26ed2ba000)

We can see that the binary has linked against libfuse, libmbedcrypto and libruby so the optional features are enabled and the also less optional one of actually decrypting things. Let’s try it. Plugging in time!

unit-0xbcd@potato ~ $ dmesg | grep Attached
[ 1093.925998] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 1096.388980] sd 0:0:0:0: [sda] Attached SCSI removable disk
[ 2978.112786] sd 1:0:0:0: Attached scsi generic sg0 type 0
[ 2978.394436] sd 1:0:0:0: [sda] Attached SCSI removable disk

Here my USB stick has shown up as /dev/sda. I already know there’s only one partition on it so I’ll try using dislocker to unlock /dev/sda1. We will need to become root for these steps.

According to man dislocker I want -v for verbose, -V to specify the volume and -p to supply the recovery key which I conscientiously saved when I created the partition. Somewhere.

root@potato ~ # mkdir /mnt/stuff
root@potato ~ # dislocker -v -V /dev/sda1 -pxxxxxx-xxxxxx-xxxxxx /mnt/stuff

No errors!

root@potato ~ # ls /mnt/stuff/

I wasn’t quite expecting this. Perhaps I should have read the man page past the first few lines.

root@potato ~ # file /mnt/stuff/dislocker-file 
/mnt/stuff/dislocker-file: DOS/MBR boot sector, code offset 0x58+2, OEM-ID "MSDOS5.0", sectors/cluster 32, reserved sectors 3216, Media descriptor 0xf8, sectors/track 63, heads 255, hidden sectors 2048, sectors 60551168 (volumes > 32 MB) , FAT (32 bit), sectors/FAT 14776, serial number 0x321678b5, unlabeled

Ok that’s not so bad — we have ended up with a flat file that contains a Fat32 filesystem. Now to mount that file loopback to gain access to the contents. I’m going to mount it read-only because I’m a little bit terrified. Ok, I’m really very terrified.

root@potato ~ # mkdir /mnt/foo
root@potato ~ # mount -r -o loop /mnt/stuff/dislocker-file /mnt/foo
root@potato ~ # cd /mnt/foo/
root@potato foo # ls
my secret file.txt System Volume Information

Excellent. I can now get to the files and so can my corporate Windows laptop toting stakeholder. Privacy and convenience is served. is indeed a wonderful human being and probably very handsome and kind to kittens as well.