June 8, 2004

Encrypting partitions using dm-crypt and the 2.6 series kernel

Author: Mike Peters

Back in February of this year, Andrew Morten announced that cryptoloop was being
deprecated in favour of dm-crypt.
Although the initial announcement caused some consternation, dm-crypt was
merged into the stable tree for the 2.6.4 kernel. This article looks at
how to set up an encrypted partition using dm-crypt.

dm-crypt provides a crypto layer for Device-mapper. A Device-mapper driver allows you to define new partitions or logical volumes by specifying ranges of sectors
on existing block devices. The ranges of sectors to be used by these partitions is mapped to targets according to a mapping table. dm-crypt provides just such a target which can be used to transparently encrypt a block device using the new 2.6 kernel cryptoAPI.

Previously, cryptoloop has been used to provide encryption by utilizing a
loopback device. dm-crypt is a cleaner implementation and provides much more flexibility. According to cryptoloop maintainer Fruhwirth Clemens:

dm-crypt is vastly superior to cryptoloop for a number of reasons:

  • It does not suffer from loop.c bugs (there are a lot -- no maintainer)
  • dm-crypt does not depend on a special user space tool (util-linux)
  • dm-crypt uses mempool, which makes it rock-stable compared to cryptoloop

Although it uses a strong crypto algorithm, cryptoloop is seen as a weak implementation, vulnerable to a certain type of plaintext attack. A discussion of the weaknesses of cryptoloop can be found on LWN.net. Dm-crypt uses the same strong crypto algorithm but with a much improved implementation.

Installing dm-crypt

Before you try encrypting any important data using dm-crypt, you should make sure you have working backups of anything essential. Begin by downloading the necessary files. You need the latest Linux kernel from www.kernel.org. Versions 2.6.4 and above should work, but I advise using 2.6.5 or later, as there are problems with some systems hanging with 2.6.4. Also download Device-mapper,
hashalot (optional),
and the cryptsetup.sh
setup script.

Configure your kernel as normal, adding Device-mapper and dm-crypt support,
which are found listed as Device Mapper Support and Crypt
Target Support
under Multi-device support (RAID and LVM). You also need to enable your desired crypto cipher under Cryptographic Options.

Once you have installed and booted your new kernel, if you have configured Device-mapper as a module you need to load it using modprobe dm-mod. The dm-crypt module will be autoloaded by the kernel when needed. Enter the modprobe command into a startup script, along with modprobes for any crypto modules you need.

Device-mapper uses the /dev/mapper directory and the /dev/mapper/control device. To create them, run the scripts/devmap_mknod.sh script from the Device-mapper package. If successful, the script will output the major and minor device numbers of the new node; otherwise, if something goes wrong, it will exit silently.

Next, compile and install the Device-mapper package. Unpack the files and run the usual ./configure, make, and make install commands to install the necessary libraries and the dmsetup utility in /sbin. We use dmsetup to create and remove devices, get information about devices, and reload tables.

Running dmsetup create <name> creates a device of <name> under /dev/mapper/control. dmsetup then expects a mapping table from stdin, or alternatively you may provide a file containing the information as a third parameter. A mapping table takes the form:
<start sector> <sector count> <target type> lt;arguments>
A dm-crypt table takes the form:
0 <sector count> crypt <sector format> <key> <IV offset> <real device> <sector offset>

The <sector format> and <key> are the encryption cipher (such as aes) and the key, as a hexadecimal number, used for encryption of the device. You can find what ciphers are available by checking /proc/crypto or loading the appropriate kernel module with modprobe. <IV offset> will usually be set to 0 except in special cases. <real device> is the actual device to be encrypted, either specified as /dev/xxxx or its device number in the form major:minor. <sector offset> is the sector offset where the encrypted
data begins on the real device.

If this all looks rather confusing, don't worry; the cryptsetup.sh
script makes the process much more user-friendly. The script uses hexdump and hashalot
to create the encryption key. You can do without hashalot if you use the -h plain option. Copy the cryptsetup.sh script to a location in your $PATH (don't forget to make it executable) and install hashalot (./configure, make, make install) if you plan to use it.

Cryptsetup.sh calls dmsetup with the options you provide to set up your
encrypted device. In the example below we'll convert /dev/hdb2 to use /dev/mapper/cryptvol1.

First, unmount the device and run fsck on it to make sure you have a
filesystem free of errors:

umount /dev/hdb2
fsck /dev/hdb2

Now create the dm-crypt device:

cryptsetup.sh -c aes -h ripemd160 -y -b `blockdev --getsize /dev/hdb2` create cryptvol1 /dev/hdb2

You will be asked for a passphrase, which you should enter at the prompt. This creates the device /dev/mapper/cryptvol1 from /dev/hdb2 using the AES cipher and uses hashalot to generate the key from the passphrase (use -h plain here if you don't use hashalot). You can see a full list of cryptsetup's options by running cryptsetup.sh --help

Now you are ready to copy your data to the new device:

dd if=/dev/hdb2 of=/dev/mapper/cryptvol1 bs=4k

Be very careful to check this command before you execute it, as it will overwrite any data on the specified device. Once the command has completed, check the new device for errors with fsck /dev/mapper/cryptvol1. If all has gone well you should be able to mount the new device in place of /dev/hdb2 -- mount /dev/mapper/cryptvol1 /data (presuming you used to use mount /dev/hdb2 /data to mount the partition).

If you need to, you can convert an encrypted device to unencrypted by
using the reverse of this process, copying your data from the encrypted
device to the plain device. Similarly, if you wish to change any options
such as re-encrypting the data or changing your passphrase, you can copy
data between two mapped devices. Currently there is work in progress on a
utility to let you do this on the fly.

Unwanted devices can be removed using the command dmsetup remove
<name>

Cryptsetup creates a mapping for your device, so to remount your
filesystem after a reboot, you merely need to call cryptsetup.sh again, supplying
the same passphrase. For example, if you place the following in a startup script,
you will be asked for the passphrase during boot and your device will be recreated
for you.

if [ -b /dev/mapper/cryptvol1 ] ; then
          /usr/local/sbin/cryptsetup.sh remove cryptvol1
fi

/usr/local/sbin/cryptsetup.sh -c aes -h ripemd160  -b `blockdev --getsize /dev/hdb2` create cryptvol1 /dev/hdb2

/sbin/mount /dev/mapper/cryptvol1 /data

Summary

Dm-crypt is a clean, solid implementation, providing much more flexibility than cryptoloop through its usage of Device-mapper. While dm-crypt is currently functionally similar to cryptoloop, it is extensible, and greater functionality is planned for the future. Although it is unlikely that cryptoloop will be removed entirely from the kernel in the near future, if you are planning to deploy an encrypted filesystem you
should certainly take a look at dm-crypt.

Mike Peters is a freelance consultant and programmer and long-time Linux user.

Category:

  • Security