Encrypted partition in Debian 7

Using LUKS with dm-crypt

LUKS logo

Creating a LUKS encrypted partition with dm-crypt on Debian 7 or similar (such as Ubuntu or Raspbian) is simple. Mounting and using it in KDE is even simpler.

Preparation

Requirements

  • cryptsetup tool (1.4)
  • dm-crypt support in kernel (by default)
  • root or sudo permissions (run below commands as root)
  • empty partition
$ aptitude install cryptsetup

Determine right partition

Make sure that the target partition or block device is empty, has the right size, and you know its exact device name (eg. /dev/sdb1). All data on it will be lost therefore double check its device name using commands such as:

$ fdisk -l /dev/sdb
$ gdisk -l /dev/sdb

Overwrite with random data

To actually remove all previous data from a partition, deleting all files will not be enough as forensics can reconstruct them, therefore one has to overwrite every single byte of the partition. Overwriting them with random data also makes it impossible to distinguish which sectors include encrypted data and which not.

An obvious way of doing this with the /dev/urandom random generator is also very very slow and takes days on larger partitions (>10GB):

$ dd if=/dev/urandom of=/dev/sdb1 bs=16M

A much faster randomization method is to use a temporary encryption layer on the partition and fill it with zeros. Encrypting the zeros with an arbitrary cipher will result in data looking like randomly generated. Choose a temporary random password for this procedure:

$ cryptsetup luksFormat /dev/sdb1

WARNING!
========
This will overwrite data on /dev/sdb1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: (random)
Verify passphrase: (random)

$ cryptsetup luksOpen /dev/sdb1 sdb1_crypt
Enter passphrase for /dev/sdb1: (random)

$ dd if=/dev/zero of=/dev/mapper/sdb1_crypt bs=16M
1464+0 records in
1463+0 records out
196369113088 bytes (196 GB) copied, 5341.39 s, 36.8 MB/s

$ cryptsetup luksClose sdb1_crypt

Formatting

The encrypted partition consists of an encryption layer, such as dm-crypt with LUKS, and a file system inside it.

LUKS encryption volume

First step of setting up a user-friendly encrypted partition is formatting it as a LUKS volume. LUKS specifies a standard secure key management system and format for disk encryption.

For encryption any cipher, key size, and hashing function supported by the kernel can be used. Unfortunately the default aes-cbc-essiv:sha256 has weaknesses and it is therefore recommended to select a stronger scheme such as aes-xts-plain64 (safe for >1TB, doesn’t dependent on essiv, better tampering protection). To format the LUKS volume:

$ cryptsetup luksFormat --cipher aes-xts-plain64 /dev/sdb1

WARNING!
========
This will overwrite data on /dev/sdb1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: [password]
Verify passphrase: [password]

Because there is nothing you can do if you forget the above password, it is highly recommended to setup an alternative emergency-restore password and put it in a safe place. Luckily LUKS supports up to 8 different passwords or key slots for unlocking the partition (protected against dictionary attacks using PBKDF2 iteration scheme).

$ cryptsetup luksAddKey /dev/sdb1 --key-slot 7
Enter any passphrase: [password]
Enter new passphrase for key slot: [emergency]
Verify passphrase: [emergency]

Check LUKS header information if everything went well. It should look something like:

$ cryptsetup luksDump /dev/sdb1
LUKS header information for /dev/sdb1

Version:        1
Cipher name:    aes
Cipher mode:    xts-plain64
Hash spec:      sha1
Payload offset: 4096
MK bits:        256
MK digest:      21 34 ...
MK salt:        5a e6 ...
MK iterations:  30000
UUID:           a84f890c-...

Key Slot 0: ENABLED
        Iterations:             200000
        Salt:                   81 b0 ...
        Key material offset:    8
        AF stripes:             4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: ENABLED
        Iterations:             200000
        Salt:                   33 b7 ...
        Key material offset:    1800
        AF stripes:             4000

File system inside

After setting up the encryption layer that can be opened when needed, one should format a file system inside the LUKS volume. Nowadays ext4 or btrfs are commonly chosen:

$ cryptsetup luksOpen /dev/sdb1 sdb1_crypt
Enter passphrase for /dev/sdb1: [password]

$ mkfs -t ext4 -L sdb1_crypt /dev/mapper/sdb1_crypt
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=sdb1_crypt
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
11993088 inodes, 47941678 blocks
2397083 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
1464 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, ...

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

$ cryptsetup luksClose sdb1_crypt

Usage

Now the encrypted partition is ready to be mounted and used.

If you are using KDE, the default file manager Dolphin is capable of mounting the encrypted partition just by clicking on it. Afterwards it can be used just like a normal folder, yet your data will be seamlessly encrypted in the background.

From command line it can be mounted to /mnt/sdb1 using:

$ cryptsetup luksOpen /dev/sdb1 sdb1_crypt
$ mount /dev/mapper/sdb1_crypt /mnt/sdb1

It is also possible to setup automatic mounting at boot time by specifying it in /etc/crypttab and /etc/fstab. Afterwards do not forget to update the boot-time initramfs archive.

$ grep sdb1_crypt /etc/crypttab
sdb1_crypt UUID=a84f890c-... none luks
$ grep sdb1_crypt /etc/fstab
/dev/mapper/sdb1_crypt  /mnt/sdb1  ext4  relatime  0  2
$ update-initramfs -u
$ reboot