Hard drive encryption in Linux

TrueCrypt is no more, but dm-crypt and LUKS are great open source options for setting up and using data encryption

This is the basic information about the LUKS device, it shows the cipher, mode, hashing algorithm and other cryptographic data

Data security has become one of the biggest concerns among Internet users. News of data theft from websites has become very common, but it’s not only the duty of websites to protect your data – there is a lot that we, as the end users, can do for our own safety. Using strong passwords, encrypting our computers’ hard disks and taking care to click on secure links are just a few examples. Hard disk encryption in particular is a critical security boost – not only does it protect you against any Trojans attempting to leak your data all over the web, it also makes sure you are protected against physical attacks.

TrueCrypt, the famous open source disk encryption tool, stopped development in May this year. As most of you know, it was one of highly credible tools available for disk encryption. It’s a pity to see a tool of such calibre disappearing, but such is the greatness of the open source world that there are several other open source tools available to help you achieve highly secure disk encryption, with a great level of configuration possible too. We’ll take a look at two of them – dm-crypt and LUKS – as an alternative for TrueCrypt on a Linux platform. Let’s start with a brief introduction of dm-crypt, followed by LUKS.

This is the basic information about the LUKS device, it shows the cipher, mode, hashing algorithm and other cryptographic data
This is the basic information about the LUKS device, it shows the cipher, mode, hashing algorithm and other cryptographic data


DMCrypt home page
LUKS home page


Step 01 Dm-crypt

Dm-crypt stands for device mapper- crypt. As the name suggests, it is based on device mapper – a Linux kernel framework for mapping block devices to higher-level virtual block devices. Device mapper forms the backbone for several kernel features like dm-cache (creates hybrid volumes), dm-verity (blocks integrity checking target, a part of Chrome OS) and the very popular Docker too. For cryptographic purposes, dm-crypt uses the Linux kernel Crypto API framework.

So, to summarise, dm-crypt is a kernel-level encryption subsystem, offering transparent disk encryption: this means that the files are available immediately after mounting the disk – there is no recognisable delay for the end user. To encrypt data using dm-crypt you can simply specify one of the symmetric ciphers, an encryption mode, a key (of any allowed size), an IV generation mode and then create a new block device in /dev. Now, any writes to this device will be encrypted and reads decrypted. You can mount your file system on it as per usual or stack a dm-crypt device with another device like a RAID or LVM volume. A mapping table for dm-crypt is defined like this:

<start-sector> <size> <target-name> <target-mapping table>

Here, the start-sector is generally 0, size is the size of the device in sectors and target name is the name you want to assign to your encrypted device. The target-mapping table consists of following sections:

<cipher[:keycount]-chainmode-ivmode[:ivopts]> <key> <iv_offset> <device path> <offset> [<#opt_params> <opt_params>]

Check out the dm-crypt Wiki page for more details.

Step 02 LUKS

As we saw in the previous step, dm- crypt can independently encrypt/decrypt your data. But there are a few drawbacks – if used directly, dm-crypt doesn’t create on-disk metadata and this can prove to be a major issue if you want compatibility among different Linux distributions. Also, dm-crypt doesn’t support multiple keys, while multiple keys are very important in a real world scenario.

It was due to these issues that LUKS (Linux Unified Key Setup) came into existence. LUKS is a standard for Linux hard disk encryption, and standardisation facilitates compatibility among different distributions. It also supports multiple keys and passphrase revocation. As a part of standardisation, a LUKS header is added to the encrypted data and this header has all necessary setup information. With the header present with their data, users can seamlessly migrate to different distributions. The dm-crypt project now recommends LUKS as the preferred way of setting up disk encryption. Let’s now have a look at how to install cryptsetup and how we use it to create LUKS-based volumes.

Step 03 Installation

The kernel-level functionality related to dm-crypt is already available in all the Linux distributions; it’s just the front-end tools that are required. The front-end utility we will use is cryptsetup and this is capable of creating volumes based on plain dm-crypt, LUKS and even the good old TrueCrypt. To install cryptsetup on Debian/Ubuntu distributions you can use the following commands:

$ sudo apt-get update
$ sudo apt-get install cryptsetup

The first command synchronises the package index files from their sources: it gets info about the latest versions of all the packages available. The second command downloads and installs the cryptsetup package to your computer. If you are on RHEL/Fedora/CentOS distributions, you can use the yum command to install cryptsetup.

$ yum install cryptsetup-luks

Step 04 Create target file

Now that cryptsetup is successfully installed, we need to create the target file, which will serve as the placeholder for the LUKS container. While there are many ways to create a file, there are a few preconditions to be kept in consideration:

• The file should be a nonsparse file, meaning the full file size should be allocated to the memory, after the file is created.

• Random data should be filled throughout the file, making sure that no one is able tell that the data is encrypted from a completely random piece of data.

The dd command, although a little slow, can help create a file with the above preconditions fulfilled. Just use it with the special device file /dev/random as the input and the target file as the output. A sample command looks like:

 $ dd if=/dev/random of=/home/nitish/basefile bs=1M count=128

This will create a file called basefile of size 128MB inside /home/nitish folder. Be aware, though – this may take quite a while to finish; it took an hour on our expert’s system.

Step 05 Create dm-crypt LUKS

After you have created the target file, you need to create a LUKS partition within the file. This partition serves as the basic layer on top of which the encrypted data rests. On top of this, the header of this partition (LUKS header) contains all the required information for compatibility with all other devices. The crypt setup commandis then used to create the LUKS partition:

$ cryptsetup -y luksFormat /home/nitish/basefile

After confirmation that the data inside the basefile will be irrevocably deleted, followed by a passphrase prompt and its verification, the LUKS partition is created. You can check that using the following file command:

$ file basefile

Note that the passphrase entered here will be used for data decryption. It is very important for you to remember it and keep it secure too, as you will almost certainly lose all the data available in the encrypted partition if you forget the passphrase.

Step 06 Create and mount the file system

The LUKS container we created in the previous step is accessible as a file now. In our example, it is /home/nitish/basefile. It’s not useable yet, but cryptsetup lets you open the LUKS container as an independent device. To do that, first map the container file to a device name and then mount it. The mapping command looks like:

$ cryptsetup luksOpen /home/nitish/basefile volume1

After you successfully authorise with the passphrase created in last step, the LUKS container is mapped to the name volume1. This basically opens the file as a local loopback device so that the rest of the system can now handle the file as if it were a real device.

Step 07 The file system continued

The LUKS container file is now available as a regular device on the system. We need to now format and create a file system on it, before it can be used for any regular operations. You can use any file system supported on your system. For my example, we have used ext4 because it’s the latest for Linux systems.

$ mkfs.ext4 -j /dev/mapper/volume1

After the device is formatted successfully, the next step is to mount it. You need to first create the mount location, preferably inside the /mnt folder (for the sake of sanity).

$ mkdir /mnt/files

Now for the actual mounting:

$ mount /dev/mapper/volume1 /mnt/files

To cross-check, use df –h – you can see the list of devices mounted with “/dev/mapper/volume1” at the end. As you can see, some space is already used up in the device by the LUKS header.

With this step, you are now ready with your LUKS-enabled device, supporting an ext4 file system. Simply use this device to store your files – anything you write to this device will then be encrypted, while anything you read will be decrypted and shown to you.

Step 08 Use the encrypted drive

It took us several steps to reach this point and if you are not very well acquainted with the way things work, you’d most probably be confused about the one-time steps (required for setup) and steps required for regular usage. Let’s consider a scenario: you followed all the above steps successfully and then shut down the computer. The next day when you start your computer, you are not able to find the mounted device – where did it go? To clear the air further, keep in mind that the LUKS container should be mounted after starting the system and unmounted before you shut it down.

Follow these steps every time you switch on your PC, to access the LUKS file and then close it safely before you shut down your PC:

Open the LUKS file (ie /home/nitish/basefile) and enter the password. The command looks like:

$ cryptsetup luksOpen /home/nitish/basefile volume1

After the file is opened, mount it (if it is not mounted automatically):

$ mount /dev/mapper/volume1 /mnt/files

You can now use the mounted device as a regular drive and read/write data to it.
After you are done, unmount the device using:

$ umount /mnt/files

After a successful unmount, close the LUKS file:

$ cryptsetup luksClose volume1

Step 09 Backup

Most of the data losses reported in a LUKS container are due to the corruption of the LUKS header or key slots. While LUKS headers can be corrupted due to even an accidental overwrite on the header memory, complete hard disk failure is also a real possibility. Backup is the best way to be protected against such issues. Let’s see the various backup options available.

To back up the LUKS header file, use the luksHeaderBackup command option:

$ sudo cryptsetup luksHeaderBackup /home/nitish/basefile --header-backup-file /home/nitish/backupfile

Or if you want to restore the backup file, use the luksHeaderRestore command option:

$ sudo cryptsetup luksHeaderRestore /home/ nitish/basefile --header-backup-file /home/nitish/backupfile

For verifying a LUKS header file and to check if the file you are dealing with is a valid LUKS device, you can use isLuks.

$ sudo cryptsetup -v isLuks /home/nitish/basefile

We already saw how to back up LUKS header files, but a LUKS header backup doesn’t actually protect against complete disk failure so you may want to back up the complete partition using this cat command:

$ cat /home/nitish/basefile > basefile.img

Step 10 Tips and tricks

There are several other tips that can be useful while you are using dm-crypt LUKS. Let’s have a look at them.

For the LUKS header dump, cryptsetup command has an option called luksDump. This will let you see a snapshot of the LUKS header file for the device in use. A sample command will look like the following:

$ cryptsetup luksDump /home/nitish/basefile

At the beginning of this tutorial, we mentioned multiple key support with LUKS. Let’s see it in action now by adding a new key slot:

$ cryptsetup luksAddKey --Key-slot 1 /home/nitish/basefile

This command adds a key to the key slot 1, but only after you enter the current passphrase (key present in key slot 0). A total of eight key slots are available, and you can decrypt the data with any of the keys. If you take the header dump after adding the second key, you will see that the second key slot is populated.

You can remove the key slots as well with this:

$ cryptsetup luksRemoveKey /home/nitish/basefile

This removes the key slot with the highest index. Take care not to remove all of them or your data will be lost forever.