How to encrypt a USB storage device with ‘Linux Unified Key Setup’ (LUKS)

The Linux Unified Key Setup or LUKS is a disk-encryption specification created by Clemens Fruhwirth and originally intended for GNU/Linux. While most disk encryption software implements different and incompatible, undocumented formats, LUKS specifies a platform-independent standard on-disk format for use in various tools. This facilitates compatibility and interoperability amongst different programs.

The reference implementation for LUKS operates on GNU/Linux and is based on an enhanced version of cryptsetup, using dm-crypt as the disk encryption backend. Under Microsoft Windows, LUKS-encrypted disks can be used with FreeOTFE (discontinued) or DoxBox.

In September 2013, Phoronix published a performance comparison between LUKS and eCryptfs. They got better performance by encrypting the entire disk with LUKS, that only the home directory with eCryptfs.

There are several ways to use LUKS to encrypt data stored on a USB device. On this occasion, I will see only one way to encrypt a partition. In another article we will see how to encrypt a file.

In any case, it is necessary to have the cryptsetup package and all its dependencies installed. In Debian:

~$ su -
~# apt-get update
~# apt-get upgrade
~# apt-get install cryptsetup

Encrypt a partition with LUKS

Due to the lack of functionality in Windows, it can only be used the first partition of the drive. So, if you want to encrypt a partition and that it is portable between the two operating systems (GNU/Linux and Windows), you have to format the USB drive with a single partition.

Current file managers, such as Thunar (Xfce) or Nautilus (Gnome), support the automatic recognition of LUKS partitions. These managers request the password of the encrypted device when it is connected and mount the partition as a removable drive. This integration is extremely useful for dayly work but means you can not use a “key-file”, you can only enter the password manually.

1. Extract all USB storage devices

Unmount and disconnect all storage devices that are tapped into any USB port (hard drives, USB sticks, SD cards even).

2. Connect the storage device to encrypt

Connects to a reliable USB port the storage unit you go to encrypt. If a hard drive have its own power source, remember to connect it to work…

3. Determines which unit was assigned to the device to encrypt

Use the dmesg command to get the name assigned to the recently connected device. Check it carefully, if you mess you could delete the entire contents of a partition of the internal hard drive of your computer.

~$ dmesg

In this case, the last lines are these:

sd 8:0:0:0: [sdc] Attached SCSI disk
EXT4-fs (sdc1): mounting ext3 file system using the ext4 subsystem
EXT4-fs (sdc1): mounted filesystem with ordered data mode. Opts: (null)

Thus, in this example, the unit will be the sdc (/dev/sdc) and the first and only partition will be the sdc1 (/dev/sdc1).

4. Unmount the partition

From here you need to sign in as root user:

~$ su -

Unmount the partition with the umount command:

~# umount /dev/sdc1

5. Delete the partition table and create a new one

Use the fdiskcommand:

~# fdisk /dev/scd

To eliminate currently existing partition table on the drive and create a new empty table, use the o option:

Command (m for help): o

That will return something like this:

Building a new DOS disklabel with disk identifier 0x2a43cc04.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Now write the changes to with w option:

Command (m for help): w

That, if all went well, return this:

The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.

6. Create a new partition

Create a new primary partition that will contain the data encrypted with LUKS. For this, use fdisk again:

~# fdisk /dev/sdc

Use the n option to create the new partition:

Command (m for help): n

Use the p option to make the new partition as primary (default option, pressing Enter is sufficient):

Partition type:
p   primary (0 primary, 0 extended, 4 free)
e   extended
Select (default p): p

The new primary partition will be the first (default option, pressing Enter is sufficient):

Partition number (1-4, default 1): 1

Indicate what will be the first sector of the new partition (the lowest default, pressing Enter is sufficient):

First sector (2048-1953525167, default 2048): 2048

Indicate which one will be the last sector of the new partition. In this case, a single primary partition will occupy the entire storage unit (the highest value default, pressing Enter is sufficient):

Last sector, +sectors or +size{K,M,G} (2048-1953525167, default 1953525167): 1953525167

Now you must write all changes, with w option:

Command (m for help): w

That, if all went well, return this:

The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.

The new partition will now be accessible at /dev/sdc1.

7. Encrypt the new partition

Use the cryptsetup command with the luksFormat option to encrypt the new LUKS partition:

~# cryptsetup luksFormat /dev/sdc1

It will ask if you are sure (escribre YES, in capitals) and a passphrase or a long-and-complex-password twice:

This will overwrite data on /dev/sdc1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: NKu3yi8_mf93+msKL6*lg4aq
Verify passphrase: NKu3yi8_mf93+msKL6*lg4aq

8. Format the new encrypted partition

Use the cryptsetup command again but this time with the luksOpen option to decrypt the partition. You should also give it a unique name for the mapping, in this example we will use the name LUKS0001:

~# cryptsetup luksOpen /dev/sdc1 LUKS0001

That prompted the assigned password in the previous step:

Enter passphrase for /dev/sdc1: NKu3yi8_mf93+msKL6*lg4aq

You must now choose the format that best suits your needs. If you intend to use the device on GNU/Linux and Windows alike, you should opt for FAT32 (mkfs.vfat command, required to have the dosfstools package installed) or NTFS (mkfs.ntfs command, required to have the ntfs-3g package installed). If you use only on machines with GNU/Linux, EXT4 (command mkfs.ext4) will be a good choice.

The -L and -n options are used to provide a recognizable name to the unit. In this example we will use in the name ENCRYPTED.

To format as EXT4:

~# mkfs.ext4 /dev/mapper/LUKS0001 -L ENCRYPTED

To format as FAT32:

~# mkfs.vfat /dev/mapper/LUKS0001 -n ENCRYPTED

To format as NTFS:

~# mkfs.ntfs /dev/mapper/LUKS0001 -L ENCRYPTED

Finally, close the partition:

~# cryptsetup luksClose LUKS0001

9. Testing…

Now disconnect the storage device and reconnect. If all goes well, and depending on your desktop environment and how you have it configured, before you can access the contents of the storage device you must provide the assigned password:

LUKS volume in Xfce.
Xfce (Thunar) will require the password of the encrypted LUKS volume.

Miguel Menéndez

SysAdmin, Network & Security Auditor.