Back to Dm-crypt.
This section covers how to manually utilize dm-crypt from the command line to encrypt a system.
- 1 Preparation
- 2 Cryptsetup usage
- 3 Encryption options with dm-crypt
- 4 Encrypting devices with cryptsetup
- 5 Cryptsetup actions specific for LUKS
- 6 Keyfiles
- 6.1 Types of keyfiles
- 6.2 Creating a keyfile with random characters
- 6.3 Configuring LUKS to make use of the keyfile
- 6.4 Unlock at boot
- 6.5 Unlock the root partition at boot using a keyfile
dm-crypt kernel module is loaded.
Cryptsetup is the command line tool to interface with dm-crypt for creating, accessing and managing encrypted devices. The tool was later expanded to support different encryption types that rely on the Linux kernel device-mapper and the cryptographic modules. The most notable expansion was for the Linux Unified Key Setup (LUKS) extension, which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use. Devices accessed via the device-mapper are called blockdevices. For further information see Disk_encryption#Block_device_encryption.
The tool is used as follows:
# cryptsetup <OPTIONS> <action> <action-specific-options> <device> <dmname>
It has compiled-in defaults for the options and the encryption mode, which will be used if no others are specified on the command line. Have a look at
$ cryptsetup --help
which lists options, actions and the default parameters for the encryption modes in that order. A full list of options can be found on the man page. Since different parameters are required or optional, depending on encryption mode and action, the following sections point out differences further. Blockdevice encryption is fast, but speed matters a lot too. Since changing an encryption cipher of a blockdevice after setup is difficult, it is important to check dm-crypt performance for the individual parameters in advance:
$ cryptsetup benchmark
can give guidance on deciding for an algorithm and key-size prior to installation. If certain AES ciphers excel with a considerable higher throughput, these are probably the ones with hardware support in the CPU.
Cryptsetup passphrases and keys
An encrypted blockdevice is protected by a key. A key is either a:
Both key types have default maximum sizes: A passphrase can be up to 512 characters and a keyfile can have 8192kB.
An important distinction of LUKS to note at this point is that the key is used to unlock the master-key of a LUKS-encrypted device and can be changed with root access. Other encryption modes do not support changing the key after setup, because they do not employ a master-key for the encryption. See Disk_encryption#Block_device_encryption for details.
Encryption options with dm-crypt
Cryptsetup supports different encryption operating modes to use with dm-crypt. The most common (and default) is
The other ones are
--type plainfor using dm-crypt plain mode,
--type loopaesfor a loopaes legacy mode, and
--type tcryptfor a Truecrypt compatibility mode.
The basic cryptographic options for encryption cipher and hashes available can be used for all modes and rely on the kernel cryptographic backend features. All that are loaded at runtime can be viewed with
$ less /proc/crypto
and are available to use as options. If the list is short, execute
cryptsetup benchmark which will trigger loading available modules.
The following introduces encryption options for the first two modes. Note that the tables list options used in the respective examples in this article and not all available ones.
Encryption options for LUKS mode
The cryptsetup action to set up a new dm-crypt device in LUKS encryption mode is luksFormat. Unlike the name implies, it does not format the device, but sets up the LUKS device header and encrypts the master-key with the desired cryptographic options.
As LUKS is the default encryption mode:
# cryptsetup -v luksFormat <device>
is all needed to perform it with default parameters (
-v optional). For comparison, we can specify the default options manually too:
# cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha1 --iter-time 1000 --use-urandom --verify-passphrase luksFormat <device>
These options used are compared below in the left column, with another set in the right column:
|Options||Cryptsetup (1.6.2) defaults||Example||Comment|
||The example uses the same cipher as the default: the AES-cipher with XTS.|
|| The default uses a 256 bit key-size. XTS splits the supplied key into fraternal twins. For an effective AES-256 the XTS key-size must be |
||Hash algorithm used for PBKDF2. Due to this processing, SHA1 is considered adequate as of January 2014.|
||Number of milliseconds to spend with PBKDF2 passphrase processing. Using a hash stronger than sha1 results in less iterations if iter-time is not increased.|
||/dev/urandom is used as randomness source for the (long-term) volume master key. Avoid generating an insecure master key if low on entropy. The last three options only affect the encryption of the master key and not the disk operations.|
|--verify-passphrase, -y||Yes||-||Default only for luksFormat and luksAddKey. No need to type for Arch Linux with LUKS mode at the moment.|
The options used in the example column result in the following:
# cryptsetup -v --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random luksFormat <device>
Please note that with release 1.6.0, the defaults have changed to an AES cipher in XTS mode. It is advised against using the previous default
--cipher aes-cbc-essiv, because of its known issues and practical attacks against them.
Encryption options for plain mode
In dm-crypt plain mode, there is no master-key on the device, hence, there is no need to set it up. Instead the encryption options to be employed are used directly to create the mapping between an encrypted disk and a named device. The mapping can be created against a partition or a full device. In the latter case not even a partition table is needed.
To create a plain mode mapping with cryptsetup's default parameters:
# cryptsetup <options> open --type plain <device> <dmname>
Executing it will prompt for a password, which should have very high entropy. Below a comparison of default parameters with the example in Dm-crypt/Encrypting_an_entire_system#Plain dm-crypt
|Option||Cryptsetup defaults (1.6.2)||Example||Comment|
||The hash is used to create the key from the passphrase or keyfile|
||The cipher consists of three parts: cipher-chainmode-IV generator. Please see Disk encryption#Ciphers_and_modes_of_operation for an explanation of these settings, and the DMCrypt documentation for some of the options available.|
||The key size (in bits). The size will depend on the cipher being used and also the chainmode in use. Xts mode requires twice the key size of cbc.|
||The offset from the beginning of the target disk from which to start the mapping|
|--key-file||default uses a passphrase||
||The device or file to be used as a key. See #Keyfiles for further details.|
||Offset from the beginning of the file where the key starts (in bytes).|
||- (default applies)||Limits the bytes read from the key file.|
Using the device
/dev/sdX, the above right column example results in:
# cryptsetup --hash=sha512 --cipher=twofish-xts-plain64 --offset=0 --key-file=/dev/sdZ --key-size=512 open --type=plain /dev/sdX enc
Unlike encrypting with LUKS, the above command must be executed in full whenever the mapping needs to be re-established, so it is important to remember the cipher, hash and key file details. We can now check that the mapping has been made:
# fdisk -l
An entry should now exist for
Encrypting devices with cryptsetup
This section shows how to employ the options for creating new encrypted blockdevices and accessing them manually.
Encrypting devices with LUKS mode
Formatting LUKS partitions
In order to setup a partition as an encrypted LUKS partition execute:
# cryptsetup -c <cipher> -y -s <key size> luksFormat /dev/<partition name>
Enter passphrase: <password> Verify passphrase: <password>
first to setup the encrypted master-key. Checking results can be done with:
# cryptsetup luksDump /dev/<drive>
This should be repeated for all partitions to be encrypted (except for
/boot). You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition.
The following example will create an encrypted root partition using the default AES cipher in XTS mode with an effective 256-bit encryption
# cryptsetup -s 512 luksFormat /dev/sdaX
Using LUKS to Format Partitions with a Keyfile
When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:
# cryptsetup -c <desired cipher> -s <key size> luksFormat /dev/<volume to encrypt> /path/to/mykeyfile
This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.
See #Keyfiles for instructions on how to generate and manage keyfiles.
Unlocking/Mapping LUKS partitions with the device mapper
Once the LUKS partitions have been created it is time to unlock them.
The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that
/dev/<partition name> is actually an encrypted device and should be addressed through LUKS using the
/dev/mapper/<name> so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to backup the cryptheader after finishing setup.
In order to open an encrypted LUKS partition execute:
# cryptsetup open --type luks /dev/<partition name> <device-mapper name>
Enter any LUKS passphrase: <password> key slot 0 unlocked. Command successful.
Usually the device mapped name is descriptive of the function of the partition that is mapped, example:
# cryptsetup open --type luks /dev/sdaX root
Once opened, the root partition device address would be
/dev/mapper/root instead of the partition (e.g.
# cryptsetup open --type luks /dev/sda3 lvmpool
For setting up LVM ontop the encryption layer the device file for the decrypted volume group would be anything like
/dev/mapper/lvmpool instead of
/dev/sdaX. LVM will then give additional names to all logical volumes created, e.g.
In order to write encrypted data into the partition it must be accessed through the device mapped name. The first step of access will typically be to create a filesystem
# mkfs -t ext4 /dev/mapper/root
and mount it
# mount -t ext4 /dev/mapper/root /mnt
The mounted blockdevice can then be used like any other partition. Once done, closing the device locks it again
# umount /mnt # cryptsetup close root
Encrypting devices with plain mode
The creation and subsequent access of a dm-crypt plain mode encryption both require not more than using the cryptsetup
open action with correct parameters. The following shows that with two examples of non-root devices, but adds a quirk by stacking both (i.e. the second is created inside the first). Obviously, stacking the encryption doubles overhead. The usecase here is simply to illustrate another example of the cipher option usage.
A first mapper is created with cryptsetup's plain-mode defaults, as described in the table's left column above
# cryptsetup --type plain -v open /dev/sdaX plain1 Enter passphrase: Command successful. #
Now we add the second blockdevice inside it, using different encryption parameters and with an (optional) offset, create a filesystem and mount it
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2 Enter passphrase: # lsblk -p NAME /dev/sda ├─/dev/sdaX │ └─/dev/mapper/plain1 │ └─/dev/mapper/plain2 ... # mkfs -t ext2 /dev/mapper/plain2 # mount -t ext2 /dev/mapper/plain2 /mnt # echo "This is stacked. one passphrase per foot to shoot." > /mnt/stacked.txt
We close the stack to check access works
# cryptsetup close plain2 # cryptsetup close plain1
First, let's try to open the filesystem directly:
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/sdaX plain2 # mount -t ext2 /dev/mapper/plain2 /mnt mount: wrong fs type, bad option, bad superblock on /dev/mapper/plain2, missing codepage or helper program, or other error
Why that did not work? Because the "plain2" starting block (10) is still encrypted with the cipher from "plain1". It can only be accessed via the stacked mapper. The error is arbitrary though, trying a wrong passphrase or wrong options will yield the same. For dm-crypt plain mode, the
open action will not error out itself.
Trying again in correct order:
# cryptsetup close plain2 # dysfunctional mapper from previous try # cryptsetup --type plain open /dev/sdaX plain1 Enter passphrase: # cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2 Enter passphrase: # mount /dev/mapper/plain2 /mnt && cat /mnt/stacked.txt This is stacked. one passphrase per foot to shoot. # exit
dm-crypt will handle stacked encryption with some mixed modes too. For example LUKS mode could be stacked on the "plain1" mapper. Its header would then be encrypted inside "plain1" when that is closed.
Available for plain mode only is the option
--shared. With it a single device can be segmented into different non-overlapping mappers. We do that in the next example, using a loopaes compatible cipher mode for "plain2" this time:
# cryptsetup --type plain --offset 0 --size 1000 open /dev/sdaX plain1 Enter passphrase: # cryptsetup --type plain --offset 1000 --size 1000 --shared --cipher=aes-cbc-lmk --hash=sha256 open /dev/sdaX plain2 Enter passphrase: # lsblk -p NAME dev/sdaX ├─/dev/sdaX │ ├─/dev/mapper/plain1 │ └─/dev/mapper/plain2 ...
As the devicetree shows both reside on the same level, i.e. are not stacked and "plain2" can be opened individually.
Cryptsetup actions specific for LUKS
It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage: In a so-called key escrow, one key is used for daily usage, another kept in escrow to gain access to the partition in case the daily passphrase is forgotten or a keyfile is lost/damaged. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again.
Once an encrypted partition has been created, the initial keyslot 0 is created (if no other was specified manually). Additional keyslots are numbered from 1 to 7. Which keyslots are used can be seen by issuing
# cryptsetup luksDump /dev/<device> |grep BLED
Key Slot 0: ENABLED Key Slot 1: ENABLED Key Slot 2: ENABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED
Where <device> is the volume containing the LUKS header. This and all the following commands in this section work on header backup files as well.
Adding LUKS keys
Adding new keyslots is accomplished using cryptsetup with the
luksAddKey action. For safety it will always, i.e. also for already unlocked devices, ask for a valid existing key ("any passphrase") before a new one may be entered:
# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) Enter any passphrase: Enter new passphrase for key slot: Verify passphrase:
/path/to/<additionalkeyfile> is given, cryptsetup will add a new keyslot for <additionalkeyfile>. Otherwise a new passphrase will be prompted for twice. For using an existing keyfile to authorize the action, the
-d option followed by the "old" <keyfile> will try to unlock all available keyfile keyslots:
# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) -d /path/to/<keyfile>
If it is intended to use multiple keys and change or revoke them, the
-S option may be used to specify the slot:
# cryptsetup luksAddKey /dev/<device> -S 6 Enter any passphrase: Enter new passphrase for key slot: Verify passphrase: # cryptsetup luksDump /dev/sda8 |grep 'Slot 6' Key Slot 6: ENABLED
To show an associated action in this example, we decide to change the key right away:
# cryptsetup luksChangeKey /dev/<device> -S 6 Enter LUKS passphrase to be changed: Enter new LUKS passphrase:
before continuing to remove it.
Removing LUKS keys
There are two different actions to remove keys from the header:
luksRemoveKeyis used to remove a key by specifying its passphrase/key-file and
luksKillSlotmay be used to remove a key from a specific key slot (using another key). Obviously, this is extremely useful if you have forgotten a passphrase, lost a key-file, or have no access to it.
For above warning it is good to know the key we want to keep is valid. An easy check is to unlock the device with the
-v option, which will specify which slot it occupies:
# cryptsetup -v open /dev/<device> testcrypt Enter passphrase for /dev/<device>: Key slot 1 unlocked. Command successful.
Now we can remove the key added in the previous subsection using its passphrase:
# cryptsetup luksRemoveKey /dev/<device> Enter LUKS passphrase to be deleted:
If we had used the same passphrase for two keyslots, the first slot would be wiped now. Only executing it again would remove the second one.
Alternatively, we can specify the key slot:
# cryptsetup luksKillSlot /dev/<device> 6 Enter any remaining LUKS passphrase:
Note that in both cases, no confirmation was required.
# cryptsetup luksDump /dev/sda8 |grep 'Slot 6' Key Slot 6: DISABLED
To re-iterate the warning above: If the same passphrase had been used for key slots 1 and 6, both would be gone now.
Backup and restore
If the header of a LUKS encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much as a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. A damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table.
Therefore, having a backup of the header and storing it on another disk might be a good idea.
Attention: Many people recommend NOT backing up the cryptheader, but even so it's a single point of failure! In short, the problem is that LUKS is not aware of the duplicated cryptheader, which contains the master key used to encrypt all files on the partition. Of course this master key is encrypted with your passphrases or keyfiles. But if one of those gets compromised and you want to revoke it you have to do this on all copies of the cryptheader! I.e. if someone obtains a copy of the cryptheader and one of your keys he can decrypt the master key and access all your data. Of course the same is true for all backups you create of partitions. So you decide if you are one of those paranoids brave enough to go without a backup for the sake of security or not. See also the LUKS FAQ for further details on this.
Backup using cryptsetup
luksHeaderBackup action stores a binary backup of the LUKS header and keyslot area:
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img
where <device> is the partition containing the LUKS volume.
# mkdir /root/<tmp>/ # mount ramfs /root/<tmp>/ -t ramfs # cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /root/<tmp>/<file>.img # gpg2 --recipient <User ID> --encrypt /root/<tmp>/<file>.img # cp /root/<tmp>/<file>.img.gpg /mnt/<backup>/ # umount /root/<tmp>
Restore using cryptsetup
In order to evade restoring a wrong header, you can ensure it does work by using it as a remote
# cryptsetup -v --header /mnt/<backup>/<file>.img open /dev/<device> test Key slot 0 unlocked. Command successful. # mount /dev/mapper/test /mnt/test && ls /mnt/test # umount /mnt/test # cryptsetup close test
Now that the check succeeded, the restore may be performed:
# cryptsetup luksHeaderRestore /dev/<device> --header-backup-file ./mnt/<backup>/<file>.img
Now that all the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing the command.
Manual backup and restore
The header always resides at the beginning of the device and a backup can be performed without access to cryptsetup as well. First you have to find out the payload offset of the crypted partition:
# cryptsetup luksDump /dev/<device> | grep "Payload offset"
Payload offset: 4040
Second check the sector size of the drive
# fdisk -l /dev/<device> |grep "Sector size"
Sector size (logical/physical): 512 bytes / 512 bytes
Now that you know the values, you can backup the header with a simple dd command:
# dd if=/dev/<device> of=/path/to/<file>.img bs=512 count=4040
and store it safely.
A restore can then be performed using the same values as when backing up:
# dd if=./<file>.img of=/dev/<device> bs=512 count=4040
What is a keyfile?
A keyfile is any file in which the data contained within it is used as the passphrase to unlock an encrypted volume. Therefore if these files are lost or changed, decrypting the volume will no longer be possible.
Why use a keyfile?
There are many kinds of keyfiles. Each type of keyfile used has benefits and disadvantages summarized below:
Types of keyfiles
This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.
This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.
Example: fjqweifj830149-57 819y4my1-38t1934yt8-91m 34co3;t8y;9p3y-
This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.
Example: images, text, video, ...
Creating a keyfile with random characters
Storing the keyfile on a filesystem
A keyfile can be of arbitrary content and size.
dd is used to generate a keyfile of 2048 random bytes, storing it in the file
# dd bs=512 count=4 if=/dev/random of=/etc/mykeyfile iflag=fullblock
If you are planning to store the keyfile on an external device, you can also simply change the outputfile to the corresponding directory:
# dd bs=512 count=4 if=/dev/random of=/media/usbstick/mykeyfile iflag=fullblock
Securely overwriting stored keyfiles
If you stored your temporary keyfile on a physical storage device, and want to delete it, remember to not just remove the keyfile later on, but use something like
# shred --remove --zero mykeyfile
to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to wipe the entire device or at least the keyfiles partition.
Storing the keyfile in tmpfs
Alternatively, you can mount a tmpfs for storing the keyfile temporarily:
# mkdir mytmpfs # mount tmpfs mytmpfs -t tmpfs -o size=32m # cd mytmpfs
The advantage is that it resides in RAM and not on a physical disk, therefore it can not be recovered after unmounting the tmpfs. On the other hand this requires you to copy the keyfile to another filesystem you consider secure before unmounting.
Configuring LUKS to make use of the keyfile
Add a keyslot for the keyfile to the LUKS header:
# cryptsetup luksAddKey /dev/sda2 mykeyfile
Enter any LUKS passphrase: key slot 0 unlocked. Command successful.
Unlock at boot
If the keyfile for a secondary file system is itself stored inside an encrypted root, it is safe while the system is powered off but can be sourced to automatically unlock the mount during with boot via crypttab. Following above first example
home /dev/sda2 /etc/mykeyfile
is all needed for unlocking, and
/dev/mapper/home /home ext defaults 0 2for mounting it with the generated keyfile.
Unlock the root partition at boot using a keyfile
The following method uses an USB-stick to store the keyfile and configures
mkinitcpio to load the keyfile and unlock the root partition at boot.
You have to add two extra modules in your
/etc/mkinitcpio.conf, one for the drive's file system (vfat module in the example below) and one for the codepage (nls_cp437 module) :
In this example it is assumed that you use a FAT formatted USB drive (vfat module). Replace those module names if you use another file system on your USB stick (e.g. ext2) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here. If it complains of bad superblock and bad codepage at boot, then you need an extra codepage module to be loaded. For instance, you may need nls_iso8859-1 module for iso8859-1 codepage.
If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the
keymap hook before
Generate a new initramfs image:
# mkinitcpio -p linux
Configuring the kernel parameters
Add the following options to the kernel parameters:
Choosing a plain filename for your key provides a bit of 'security through obscurity'. The keyfile can not be a hidden file, that means the filename must not start with a dot, or the
encrypt hook will fail to find the keyfile during the boot process.
The naming of device nodes like
/dev/sdb1 is not guaranteed to stay the same across reboots. It is more reliable to access the device with udev's persistent block device naming instead. To assure that the
encrypt hook finds your keyfile when reading it from an external storage device, persistent block device names must be used. See the article persistent block device naming.