Encrypt a disk using Luks on Linux

August 13, 2007 at 2:31 pm | Posted in encryption, luks | 1 Comment



This HOWTO shows you how to take a completely new hard disk and encrypt its entire contents using dm-crypt and LUKS. Actually, it’s the partitions that are encrypted, not the disk itself (details below). So if you wish, you can make multiple partitions with different passphrases, or some not encrypted. With a bit of work, you can adapt these instructions to make an encrypted partition on an existing disk, possibly with some unencrypted partitions on the same disk.

dm-crypt asks for a passphrase before you can mount the disk. This provides good protection against your PC getting stolen – once they reboot your PC, the thieves have lost access to your data. Throughout, I will use the ‘cryptsetup’ interface to dm-crypt.

What is LUKS? See http://luks.endorphin.org/about. In simple terms, it’s better encryption, but more importantly to the end user, it allows you to change the password for your disk, without requiring a very slow re-encode of the whole disk. You also have the option of having several different passwords for the same data.

Note : if you want your encryption to defeat a full cryptoanalytic attack, not just casual snooping, you need to fill the disk with high quality random data. Badblocks below justs uses ‘libc’ random(), but is fast (your limitation will be disk speed, not CPU speed). /dev/urandom is better (takes about 5 minutes per gigabyte on my system), /dev/random is best (takes about 1 year per gigabyte on my system, much too slow!).

Step 0: Get the right cryptsetup

You need the version of cryptsetup with luks enabled, you can get it at http://luks.endorphin.org/dm-crypt. To test whether it’s installed, try:

# cryptsetup –help

If you see a help page including details like ‘luksFormat’, then you have the right version already.

Step1a : (Optional) Check the hard disk for errors (side effect, fill it with random data).

It’s probably a good idea to check your entire disk for errors before you start. Not only is this good practise, but modern hard disks contain a few ‘spare’ sectors, and if they detect errors in reading, they can silently replace the bad sector with a backup sector (this is invisible to the OS). So writing and reading the entire disk before you start should allow this to happen.

You need to know what device your new disk is attached to. For PATA disks (parallel ATA) on Linux, they’ll probably be /dev/hda, /dev/hdb and so on. For SATA, SCSI or USB attached disks, they’ll probably be /dev/sda, /dev/sdb, /dev/sdc and so on. I am attaching a USB disk, I already have 2 SATA disks so this disk seems to appear under /dev/sdc. Make sure you find out, and adapt the below commands as necessary, or you may overwrite your existing data!

It’s good to fill an encrypted disk with initial random data. This makes breaking the passphrase so much harder. The below method is sufficient for a casual attack but is not ‘random enough’ to defeat sophisticated cryptographers. If you need that, use the ‘/dev/urandom’ method below or read a good book on cryptography and random numbers!

I recommend the disk check and the fill with random data be done at the same time. Read the man page for more details on this command:

# /sbin/badblocks -c 10240 -s -w -t random -v /dev/sdc
(wait several hours…)
Checking for bad blocks in read-write mode
From block 0 to 295360984
Reading and comparing: done
Pass completed, 0 bad blocks found.

This will take some time, on my USB-attached 300Gb disk it took around 8 hours. Phase 1 will write random data to the disk, phase 2 will read it back and verify it.

Step 1b (Optional) Fill the disk with random data

If you didn’t do step 1a, do step 1b. This will take a long time (around 5 minutes per gigabyte on my system), because generating good quality random data is very CPU intensive. Method 1a has an easy progress indicator, while “dd” only shows its progress when a USR1 signal is sent to it (“kill -USR1 `pidof dd`”). However, this method is ‘more random’ (and more secure) than the primitive random number generator included in ‘badblocks’, above.

# dd if=/dev/urandom of=/dev/sdc
(wait several hours…)


Step 2 : Partition the disk

Remember, the data on a hard disk consists of (1) a partition table (2) one or more partitions.

The way dm-crypt works is, you mount an encrypted partition. So we won’t encrypt the whole hard disk, rather we’ll create a partition table (unencrypted) as usual, then create one or more partitions on the disk, as usual, except the partition(s) can be encrypted if we choose.

So, we partition the hard disk. In my case, I am partitioning my entire 300Gb hard disk as a single partition.

# /sbin/fdisk /dev/sdc
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won’t be recoverable.

The number of cylinders for this disk is set to 36481.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): p

Disk /dev/sdc: 300.0 GB, 300069052416 bytes
255 heads, 63 sectors/track, 36481 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System

Command (m for help): n
Command action
e extended
p primary partition (1-4)
Partition number (1-4): 1
First cylinder (1-36481, default 1): 1
Last cylinder or +size or +sizeM or +sizeK (1-36481, default 36481): (enter)
Using default value 36481

Command (m for help): p

Disk /dev/sdc: 300.0 GB, 300069052416 bytes
255 heads, 63 sectors/track, 36481 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System
/dev/sdc1 1 36481 293033601 83 Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.


Step 3 : Create mapping between logical and physical partitions

dm-crypt works by transparently translating (in the kernel) between a physical on-disk partition (which is encrypted) and a logical partition which you can then mount and use as normal. This step takes no time and writes no data, it just establishes the mapping for future use.

The physical (encrypted) partition will be /dev/something
The logical (unencrypted) partition will be /dev/mapper/something2

I prefer to keep the names the same, so something=something2. That makes things easier to remember.

# cryptsetup –verbose –verify-passphrase luksFormat /dev/sdc1

This will overwrite data on /dev/sdc1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: (enter your passphrase, and write it down somewhere!)
Verify passphrase: (repeat passphrase)

# cryptsetup luksOpen /dev/sdc1 sdc1
Enter LUKS passphrase:

If all is well, you now have a special file called /dev/mapper/sdc1. This is what you will mount.

# ls -l /dev/mapper/
total 0
crw——- 1 root root 10, 63 Jul 16 01:34 control
brw-r—– 1 root root 253, 0 Jul 16 01:52 sdc1


Step 4 : Create a filesystem on the logical partition

This is just like making a normal filesystem, just point ‘mkfs’ at the logical partition. Use your favourite options, filesystem type etc (I use ext3) or just copy my options. As always, remember to change ‘sdc1’ as appropriate.

# /sbin/mkfs.ext3 -j -m 1 -O dir_index,filetype,sparse_super /dev/mapper/sdc1
(wait several minutes…)
mke2fs 1.35 (28-Feb-2004)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
36634624 inodes, 73258400 blocks
732584 blocks (1.00%) reserved for the super user
First data block=0
2236 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616

Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 39 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.


Step 5 : Mount the Filesystem


This is just like a normal mount, except you use the logical (/dev/mapper) device. First make a mount point if necessary. In my case I am using /home4

# mkdir /home4
# mount /dev/mapper/sdc1 /home4
# df -H
Filesystem Size Used Avail Use% Mounted on
/dev/hda3 11G 5.2G 4.2G 56% /
/dev/hda1 510M 63M 395M 14% /boot
/dev/hda2 11G 3.5G 5.9G 37% /usr
none 797M 0 797M 0% /dev/shm
/dev/mapper/sdc1 296G 34M 294G 1% /home4

Hoorah! Now just use /home4(or whatever) as normal. In my case, I now have another 300Gb to play with biggrin It may be slower than a normal disk, due to the CPU time required to encrypt/decrypt. If you wish, use /sbin/hdparm to benchmark. However my benchmarks on an AMD Athlon 3200 indicate no great difference between an encrypted and a normal unencrypted partition.

Step 6: Mounting and unmounting in future

This is a simple procedure. You may be even able to edit your /etc/rc.local script to prompt for a password and mount your encrypted partition at boot.

To mount:

# cryptsetup luksOpen /dev/sdc1 sdc1
Enter LUKS passphrase: (enter passphrase)
key slot 0 unlocked.
# mount /dev/mapper/sdc1 /home4

To unmount:

# umount /home4
# cryptsetup luksClose sdc1

To add an additional password, so you can unlock your partition with a choice of different passwords (you can do this with the encrypted partition mounted, if you wish):

#cryptsetup luksAddKey /dev/sdc1
Enter any LUKS passphrase: (enter an existing password for this partition)
key slot 0 unlocked.
Enter new passphrase for key slot: (enter the extra password)

To delete an existing password (but don’t delete the last one, your data will be lost forever, you will be warned if you try this), you need to know which slot the password is in. The first password goes in slot 0, any additional passwords go in slot 1, 2 etc. You can do this with the encrypted partition mounted, if you wish. So to delete the very first password you used, use:

#cryptsetup luksDelKey /dev/sdc1 0

To change the password, first add an additional password then delete the original password.




1 Comment »

RSS feed for comments on this post. TrackBack URI

  1. webpage

    Encrypt a disk using Luks on Linux | element14

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: