Tuesday, October 6, 2009

Encrypting your HDD with plausible deniability

Certain government agencies feel they're within their right to seize and copy your data as you pass through their checkpoint if you fall into suspicion for some reason. With the presence of an encrypted partition known, they could also compel you to reveal the password. The idiocy is spreading due to the naive belief that security and privacy are a zero-sum game.

I was searching for a way for someone to pass through such a checkpoint with no indication that the drive contains anything other than random data. While there are plausible ways to deny that you know the password, I couldn't find any to deny the existence of encrypted data in the first place.

A stock Ubuntu Linux load installs onto your hard drive without encryption. With a little extra fiddling (using the alternate installer CD), you can encrypt the root partition. However, someone forensically examining the drive will see an MBR and GRUB bootloader, the /boot partition in all its glory, an extended partition record, and a LUKS header on the encrypted LVM physical volume containing your root and swap volumes.

Here I present a method of encrypting the entire physical hard drive. There is no MBR, no /boot partition, and no LUKS header. It requires only a small USB thumb drive or SD card to boot from (I used a MicroSD).

The example commands below use the Ubuntu 9.04 LiveCD, and assume the laptop's HDD is at /dev/sda and the USB stick at /dev/sdb. Adjust these assumptions as appropriate for your system or distro of choice. It does not seem to work with Ubuntu 9.10; I'm still investigating why. You can always update after the install.

Boot into the LiveCD in evaluate mode (no changes to your computer). Open a terminal window, switch to the root user, and run the following commands. When formatting the USB stick, allocate at least 100MB (or the entire stick) for your boot partition, and set the partition's bootable flag.
  • fdisk /dev/sdb
The apt-get retrieves some utilities needed in the next few steps, and requires an internet connection. WARNING: the dd can take a very long time, and will fill your HDD with randomized data. Filling your disk with random looking bytes is important for deniability, so don't skip it. Oh, and use a strong passphrase; changing the password isn't as easy as it is with LUKS.
  • apt-get update
  • apt-get install watershed lvm2 cryptsetup
  • cryptsetup -y -c aes-cbc-essiv:sha256 create crypt /dev/sda
  • dd bs=16384 if=/dev/zero of=/dev/mapper/crypt
Next, it is time to create the logical volumes on your freshly randomized HDD. Naming the volume group usb is just for misdirection, as you'll see below. Adjust the swap size below to your own requirements.
  • pvcreate /dev/mapper/crypt
  • vgcreate usb /dev/mapper/crypt
  • lvcreate -n swap -L 2G usb
  • lvcreate -n root -l 100%FREE usb
Making the filesystem and swapspace seems to be important for the Ubuntu installer. Skipping these steps would prevent you from selecting them in the graphical partitioner in the steps to follow.
  • mkswap /dev/mapper/usb-swap
  • mke2fs /dev/mapper/usb-root
Now, setting aside the terminal window for later, double-click the Install icon on your desktop. Follow your normal install procedures except for the manual partitioning as specified below, formatting all selected partitions:
  • /boot is installed on the /dev/sdb1 partition created using fdisk above
  • / is installed on /dev/mapper/usb-root
  • swap space is on /dev/mapper/usb-swap

When the install completes, continue testing your LiveCD environment, and return to your shell to complete a few manual steps. First, the same utilities we installed above need to be installed on your new OS and its initramfs on the /boot partition.
  • mount /dev/mapper/usb-root /mnt
  • mount /dev/sdb1 /mnt/boot
  • for p in proc dev sys; do mount -o bind /$p ./mnt/$p; done
  • chroot /mnt
  • apt-get install watershed lvm2 cryptsetup
  • exit
Then, you need to install GRUB onto your USB stick.
  • ln -s /mnt/boot/grub /boot/grub
  • grub-install --root-directory=/mnt /dev/sdb
Finally, cover some tracks left by the installer trying to install an MBR onto the physical drive by zeroing out the first sector on the encrypted mapping.
  • dd if=/dev/zero bs=512 count=1 of=/dev/mapper/crypt
That's it! You're done. Reboot your laptop and boot off of the USB drive, using the BIOS boot menu if needed. You'll see the Ubuntu boot splash screen and progress bar for about 40 seconds until it drops to the (initramfs) prompt complaining about not being able to find /dev/mapper/usb-root. (It's possible to decrease the timeout at the cost of deniability; that exercise is left to you.)

Don't panic yet, that prompt is part of your plausible deniability. That is where you run your cryptsetup command as follows (remember, this is in the initial ram disk's busybox prompt, so there is no shell history retained).
  • cryptsetup -c aes-cbc-essiv:sha256 create crypt /dev/sda
  • exit
When you exit the shell, the boot scripts continue, the LVM volume is detected and mapped, the filesystems are found and mounted, and you should be up and running in your new environment within a few seconds.

If you're not updating anything on the /boot partition (such as the kernel), you can open a shell prompt, umount /boot and pull your USB drive once you're up and running. By itself, it looks like a rescue disk for some undefined Linux install.

Remember that in many countries, lying to a government agent is a crime in itself. I am not a lawyer, this is not legal advice, and you should obey the law. But, with this setup, if you keep your mouth shut and don't indicate elsewhere that there is encrypted data on the drive, there is nothing on the drive itself to indicate to the courts that there is. As far as any forensic examiner is concerned, the drive could just as well have been freshly wiped with random data.


  1. Very interesting. Any way to do this for an already existing lvm+crypt standard "alternative CD" install?

  2. There should be. Copy (or recreate) your /boot partition onto flash, mark the partition as bootable, install GRUB, update /etc/fstab, and verify it boots. You could even delete the disk's boot partition entry via fdisk to verify you're actually using the flash.

    Once that's verified, boot into a liveCD, manually map your encrypted volume, create a second encrypted device map for the full disk, and dd from one to the other.

    # cryptsetup luksOpen /dev/sda5 luksroot
    # cryptsetup -c aes-cbc-essiv:sha256 create devroot /dev/sda
    # dd if=/dev/mapper/luksroot of=/dev/mapper/devroot

    Once completed, you could even expand your filesystem to reclaim the unused space.

    # cryptsetup luksClose /dev/mapper/luksroot
    # resize2fs /dev/mapper/devroot

    By the way, Setting up two device maps and copying between is how you'll change passwords too. I had a link explaining it, but it went stale.

    For deniability, if your drive gets imaged, you will want to change your passphrase anyway. Otherwise, a second image would plainly show modifications to only certain areas of the disk corresponding with typical filesystem changes, foiling your deniability.

  3. How would you go about changing the password for an encrypted volume like this? Everything would need to be re-encrypted, but how?

    1. Zorb, I see the saout.de link that I used when writing this is no longer valid. There is a version in the Internet Archive at http://web.archive.org/web/20101230202817/http://www.saout.de/tikiwiki/tiki-index.php?page=ChangePassword

      Changing the password would not be as easy as if you were using LUKS. With LUKS, the session key used for the disk encryption is a randomly generated key. Your password is just used to encrypt this session key. So changing your password merely re-encrypts the session key with your new password.

      With the above method, the session key is generated directly from a hash of your password. Therefore, if you wish to use a different password, you must re-encrypt the entire drive. Here's how I would recommend doing that.

      0. Back up. Always the first step...

      1. Boot up to your initramfs prompt.

      2. Create a device mapping using your old password to old-crypt:

      # cryptsetup -c aes-cbc-essiv:sha256 create old-crypt /dev/sda
      # lvm pvscan /dev/mapper/old-crypt

      3. Create a device mapping to new-crypt using your new password (-y prompts twice for your new password to help prevent mistypes):

      # cryptsetup -y -c aes-cbc-essiv:sha256 create new-crypt /dev/sda

      4. At this point, /dev/mapper/old-crypt is a block device containing a valid LVM physical volume with root and swap logical volumes, and /dev/mapper/new-crypt contains gibberish. Before you re-encrypt, please make sure that watershed hasn't located the volume group in the background and mounted any logical volumes it has detected.

      # lvm vgchange --available n /dev/mapper/old-crypt

      (If this fails, check to see if the root filesystem is mounted and umount it first.)

      5. Re-encrypt

      # dd if=/dev/mapper/old-crypt of=/dev/mapper/new-crypt

      This is where the magic happens. Dd reads a block through the old mapping, decrypting it while it reads, and then writes it to the new mapping, encrypting it while it writes. Dd cannot write a block before it reads it, so there is no worry about ordering the reads and writes, despite them going to the same underlying physical device (/dev/sda).

      However, there is no good way of tracking progress, and interrupting it before completion will give you an unusable drive. Well, that's not strictly true, but recovery would be difficult and is beyond the scope of this comment.

      Just be sure you're running on reliable power. That means a UPS if you're using a desktop, or a good, fully charged battery that's plugged in if you're on a laptop.

      6. Before you delete the mappings, you may wish to verify that new-crypt shows up in LVM as a valid physical volume using

      # lvm pvscan.

      7. Once the copy has finished, delete the device mappings and reboot.

      # cryptsetup delete old-crypt
      # cryptsetup delete new-crypt
      # reboot

      When it comes back up, if it fails to boot, check that the volume group is available. You may need to undo the vgchange you issued above with

      # lvm vgchange --available y /dev/mapper/crypt
      # exit

      I'd recommend practicing this first and having someone who knows the device mapper and LVM subsystems handy. The above steps are what I believe would work, but I have not personally gone through them on a test system to verify syntax and validity. Good luck.

    2. Unfortunately these instructions do not work as cryptsetup no longer allows one to map the same device two times (removed non-exclusive flag). Is there a way to get around this? Here https://code.google.com/p/cryptsetup/issues/detail?id=105#c6 some say we could use cryptsetup on top of a dmsetup -a... map but I'm not sure whether/how this will work. Do you have any suggestions? Thanks.

    3. Looks like the maintainer introduced the --shared option to cryptsetup to accommodate this. I haven't tested it yet, though, so YMMV.

      As for using dmsetup, it would be a matter of adding two linear tables to the raw device first, then running cryptsetup against those mapped devices instead of the physical device. The actual command will vary depending on the size of your HDD and the offset of the encrypted container. For instance, if you're reencrypting all of /dev/sda, run

      # blockdev --getsz /dev/sda

      to determine the number of 512-byte sectors. Use that number in place of [devsize] below.

      # echo "0 [devsize] linear 0 /dev/sda" | dmsetup create sda-1
      # echo "0 [devsize] linear 0 /dev/sda" | dmsetup create sda-2

      Then use the /dev/mapper/sda-* devices those two commands created to create the old-crypt and new-crypt mappings as explained above.

      That's the theory, anyway. I haven't tested this personally, so please make sure you are familiar enough with dmsetup to be able to verify they're all doing what you expect it to do. Or find someone who is to help you. I assume no liability for lost data.