Encrypt devices using dm-crypt and LUKS

Secure your data in encrypted partitions and removable volumes, or even volumes within a file, using dm-crypt and the flexibility of LUKS. In this article I describe how I encrypted a ZIP diskette and a partition contained in a file.

"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.

Prerequisites

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.

Unmounting

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.

Further Reading

The cryptsetup and losetup man pages contain all the information you will ever need to create encrypted containers.

Encrypt devices using dm-crypt and LUKS by George Notaras, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Copyright © 2005 - Some Rights Reserved

15 responses on “Encrypt devices using dm-crypt and LUKS

  1. angelina nieves Permalink →

    Please help me find out what I am doing wrong here. I followed your instructions to dm-crypt a partition, but keep getting the following error when formatting the partition:

    # /sbin/mkfs -V -t ext3 /dev/mapper/partaa
    mkfs version 2.12p (May 4 2005)
    mkfs.ext3 /dev/mapper/partaa
    mke2fs 1.37 (21-Mar-2005)
    Could not stat /dev/mapper/partaa — Permission denied

  2. angelina nieves Permalink →

    I forgot to inform you, I am running fedora core 4 on a pentium III box. The partition being encrypted is the first of 8 in a new secondary hard disk.

    Thank you so much in advance.

  3. George Notaras Post authorPermalink →

    Hi Angelina, the “Permission denied” message shows that the user does not have enough privileges to run mkfs. Usually, only root can create filesystems and, as I have written in the above guide, mkfs should be run as root. I guess this will get you going…

  4. Andre Permalink →

    Hello,

    Nice guide. Just would like to add that you can use FreeOTFE to read Linux-encrypted partitions:

    http://www.freeotfe.org/

    I haven’t used it yet, but there is a complete section on their manual about how to create the encrypted volumes on Linux and accesssing them on Windows.

  5. SK Permalink →

    “The worst thing is that there is no progress indicator…” true, but sending a SIGUSR1 signal to the process does give you some stats, on Linux at least.

  6. George Notaras Post authorPermalink →

    @Andre: Judging by its feature list, FreeOTFE is a very interesting application. I noticed that it supports dm-crypt and LUKS, which makes it possible to read LUKS formatted volumes in the Wndows OS. This may prove to be very useful. Thanks.

    @SK: Also, there is a very handy utility I happen to like very much, called pv. This is a pipe monitoring utility. When injected between two pipes, it displays the progress of the data flow through the pipe. I highly recommend it. Also, thanks for the info about the SIGUSR1 signal. I did not know about it.

  7. Santiago Urueña Permalink →

    Filling the disk with random data before encrypting is a good habit and it strengthens security as well.

    In my opinion, a better approach is to use ‘shred’ from GNU coreutils, a tool that really performs a secure delete of a file or a complete device, and also fill the disk with random data…

  8. George Notaras Post authorPermalink →

    Hi Santiago.

    Indeed, shred is an excellent alternative.

    The greatest question with filling the disk with random data, regardless of the generator that is used, is how long it will take to complete the operation. Generally, it takes long, but I think that using shred will require much more time, but I haven’t tried it.

  9. gtkfreak Permalink →

    I use Fedora Core 6. losetup -d /dev/loop0 does not work. Is there any reason why? I am logged in as a normal user, then done a su for container encryption. Everything works fine, except the destroy of the losetup -d /dev/loop0. When I check the process status, the [loop] is still visible there. But even a kill does not remove that process.

  10. Kate Ward Permalink →

    You might take a look at a script I wrote called luksmount (mod: link is down) that automates a lot of the mounting and unmounting headaches of LUKS.

  11. George Notaras Post authorPermalink →

    Hello Kate. Very convenient! Thanks.
    I will add some info and links in the main article when I have the time.

  12. angelina nieves Permalink →

    Thanks GNot. Sorry for the long interval. I shelved the dm-crypt project since and now just got back. hope you can still reply.

    Anyway, when I did the steps I mentioned, I was indeed running as root. Still can’t figure out what I do wrong.

  13. Frank Permalink →

    Great! Trying this now.

    And about having no progress indicator on dd – I’ve found a few sources on how to do it, but I’ve summed it up to just one line:

    ddpid=$(pgrep -l '^dd$' | pgrep "^dd") && kill -USR1 $ddpid

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>