Encrypt devices using dm-crypt and LUKS

"Encryption is the process of obscuring information to make it unreadable without special knowledge." -WikiPedia-

There are many different methods to encrypt data using various encryption algorithms (ciphers). In this document I describe in short how to encrypt a device with one of the most contemporary methods, using dm-crypt and LUKS. Actually, devices cannot be encrypted. Itís the block devices which are volumes that can be. This means that you can encrypt a hard disk partition, a ZIP disk, a usb flash stick, or even a volume within a file.

dm-crypt is a device mapper that uses the 2.6 kernelís cryptoapi. We will not use dm-crypt directly to setup the block device mappings because of its complexity, but instead weíll use an enhanced version of a program called cryptsetup, which has the LUKS extension enabled. The reason for using LUKS (Linux Unified Key Setup) is that it uses a partition header to store the encryption-setup information, so, in contrast to other existing methods, the user can:

    * change the encrypted volumeís passphrase without having to re-encrypt the data
    * have multiple passphrases for the same data
    * transport or migrate data on different systems

The most important thing though is that all this convenience does not have an impact on data security, meaning that data is still very safe. Well, this is LUKS. Win32 compatibility is not yet possible, but will be in the near future through TrueCrypt.

A Linux 2.6 kernel with device mapper and dm-crypt support is needed. On Fedora Core 4 systems you really donít have to do anything as the kernel has device mapper and dm-crypt enabled as modules (dm-mod and dm-crypt respectively). The modules are loaded automatically when the system needs them.

Before reading any further, you must be sure that you know the exact device node you are going to encrypt. This is no joke, as you can lose your data, by a simple and fool mistake. So, take note!

Furthermore, you need to install cryptsetup-luks package and util-linux package. We will need the latter for encrypting a filesystem within a file, but this is probably already installed.
Encrypting a volume

In this section I will encrypt a ZIP disk. The very same process can be used for any block device that is a volume, meaning that it can be formatted with a mountable filesystem. So, you can encrypt a hard disk partition, a USB stick, a Compact Flash card etc.

First of all, be sure that you know your volumeís exact device node in /dev. If you use multiple hotplugable devices, which you connect to your machine in a random order, you should consider writing some UDEV rules, so that you know which node corresponds with a certain actual device. You can read my blog post on that. A simple mistake can lead to loss of data. I have setup UDEV in a such way, that every time I connect my USB ZIP drive and insert a disk, a symlink to the diskís node is created in a directory /dev/mydev/. So, I can reach the ZIP diskette by directing the commands to the symlink /dev/mydev/zipdisk.

If your volume is already mounted, unmount it before proceeding. Mine is, so I run:

# umount /dev/mydev/zipdisk

Fill the disk with random data

Filling the disk with random data before encrypting is a good habit and it strengthens security as well. If you donít want to do so, you can simply skip this step. This process is CPU intensive and the time it takes depends on the available CPU horsepower, the size of the partition and the speed it can be written. It can be many hours, even days, for very large hard disk partitions. The worst thing is that there is no progress indicator, so you just wait for it to finish. I run this:

# dd if=/dev/urandom of=/dev/mydev/zipdisk

Substitute /dev/mydev/zipdisk with the path to your device node. In my case, it took my USB 1.1 ZIP drive 10 whole minutes to fill an 100MB ZIP disk. Well, itís not the fastest thing in the world, but I still like it.
Create the LUKS partition

Now, I will create a LUKS partition on the ZIP disk. As root I run:

# cryptsetup --verbose --cipher "aes-cbc-essiv:sha256" --key-size 256 --verify-passphrase luksFormat /dev/mydev/zipdisk

If you use a kernel older than 2.6.10, do not include the Ėcipher option. The default AES with 256-bit key is absolutely fine. Cryptsetup will ask for a passphrase twice. What this does is the initialization of the LUKS partition.
Set up the device mapping

In order to use this partition, a device mapping must be set up between the physical partition on the ZIP diskette and a new virtual block device, which can then be mounted. I call it virtual because itís just a layer between the physical ZIP disk and the system. Writes to this virtual block device will be encrypted and reads decrypted. To create the device mapping as root:

# cryptsetup luksOpen /dev/mydev/zipdisk encr-zipdisk

encr-zipdisk is just a name for the new block device that is created in /dev/mapper/. After creating a filesystem on it, this virtual block device can be mounted and used as normal.
Create a filesystem on the new block device

You can create any file system you like on the new volume. For my ZIP diskette, an MSDOS FAT16 filesystem is more than enough, so I run as root:

# mkdosfs -v -F 16 -n "ENCR1" /dev/mapper/encr-zipdisk

What worths mentioning is that you create the filesystem on the virtual volume, /dev/mapper/encr-zipdisk in my case, and not the physical one.
Mount the new volume

Now I can mount the volume as normal. For example:

# mount -t vfat -o rw /dev/mapper/encr-zipdisk /mnt/tmp/

An fstab entry with all the proper mount options could simplify mounting. All data that is written to the disk gets encrypted.

Before removing the disk from the drive, I have to unmount it:

# umount /mnt/tmp/

And then delete the device mapping as root:

# cryptsetup luksClose encr-zipdisk

This removes the association and I normally can eject the ZIP disk.
In short

Just a review of the procedure to mount and unmount the disk, considering that a proper fstab entry has been added.

To mount:

# cryptsetup luksOpen /dev/mydev/zipdisk encr-zipdisk
# mount /dev/mapper/encr-zipdisk

To unmount:

# umount /dev/mapper/encr-zipdisk
# cryptsetup luksClose encr-zipdisk

Pretty fast and easy.
Encrypt a filesystem within a file

In order to use LUKS to encrypt a filesystem that is contained in a file, you actually have to follow the same steps as when encrypting a physical partition, plus two. These include:

    * The creation of a file that will contain the encrypted partition
    * Set up an association between this file and a free loop device, so that it can be used by cryptsetup as a block device. At the moment, cryptsetup cannot use a file as a block device directly. Thatís why this step is needed.

So, letís create the file. The following command creates an 100MB file, named "container1", which is full of random data:

dd if=/dev/urandom of=container1 bs=1024 count=100000

To create a mapping between this file and a free loop device, weíll use losetup (part of util-linux). Check which loop device is free in your system with the command:

losetup -f

For me it was /dev/loop0. So, I map the "container1" file to /dev/loop0. As root:

# losetup /dev/loop0 /path/to/container1

From now on, the steps are exactly the same as before. We just use /dev/loop0 instead of the ZIP disk:

# cryptsetup --verbose --cipher "aes-cbc-essiv:sha256" --key-size 256 --verify-passphrase luksFormat /dev/loop0
# cryptsetup luksOpen /dev/loop0 encr-container1
# mkfs.ext3 /dev/mapper/encr-container1
# mount -t ext3 -o rw,defaults /dev/mapper/encr-container1 /mnt/tmp/

We can now copy some files to our encrypted partition, like on a regular disk partition. We unmount it and delete the device mappings with the following commands:

# umount /mnt/tmp/
# cryptsetup luksClose encr-container1
# losetup -d /dev/loop0

So, to mount a LUKS encrypted filesystem within a file you need to create two device mappings before you mount it for use. Of course some automation can be achieved using scripts, but you will still have to supply the passphrase in order to use the encrypted partitions.

A very good and information website posting information about device encryption inside Linux using LUKS and dm-crypt. If you're curious about Linux and want to have a go with device encryption, then this guide will lead you in the right direction.