dm-crypt is a disk encryption system using the kernels crypto API framework and device mapper subsystem. With dm-crypt, administrators can encrypt entire disks, logical volumes, partitions, but also single files.
The dm-crypt subsystem supports the Linux Unified Key Setup (LUKS) structure, which allows for multiple keys to access the encrypted data, as well as manipulate the keys (such as changing the keys, adding additional passphrases, etc.) Although dm-crypt supports non-LUKS setups as well, this article will focus on the LUKS functionality mostly due to its flexibility, manageability as well as broad support in the community.
There are two prerequisites before one can start using dm-crypt:
- Configuration of the Linux kernel
- Installation of the sys-fs/cryptsetup package
To use dm-crypt there are a number of configuration entries that are necessary.
First of all, support for the device mapper infrastructure as well as the crypt target must be included:
[*] Enable loadable module support Device Drivers ---> [*] Multiple devices driver support (RAID and LVM) ---> <*> Device mapper support <*> Crypt target support
Next, the Linux kernel needs to support the set of cryptographic APIs that the administrator wants to use for encryption. These can be found under the Cryptographic API section:
[*] Cryptographic API ---> <*> XTS support <*> SHA224 and SHA256 digest algorithm <*> AES cipher algorithms <*> AES cipher algorithms (x86_64) <*> User-space interface for hash algorithms <*> User-space interface for symmetric key cipher algorithms
If the root file system will be encrypted as well, then an initial ram file system needs to be created in which the root filesystem is decrypted before it is mounted. Thus this requires initramfs support as well:
General setup ---> [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
If using the tcrypt encryption option (TrueCrypt/tcplay/VeraCrypt compatibility mode), then the following items will also need to be added to the kernel. Otherwise, cryptsetup will return the following errors: "device-mapper: reload ioctl failed: Invalid argument" and "Kernel doesn't support TCRYPT compatible mapping".
Device Drivers ---> [*] Block Devices ---> <*> Loopback device support File systems ---> <*> FUSE (Filesystem in Userspace) support [*] Cryptographic API ---> <*> RIPEMD-160 digest algorithm <*> SHA384 and SHA512 digest algorithms <*> Whirlpool digest algorithms <*> LRW support <*> Serpent cipher algorithm <*> Twofish cipher algorithm
The sys-fs/cryptsetup package provides the cryptsetup command, which is used to open or close the encrypted storage as well as manage the passphrases or keys associated with it.
emerge --ask sys-fs/cryptsetup
Keyfile or passphrase
In order to start with encrypted storage, the administrator will need to decide which method to use for the encryption key. With cryptsetup the choice is either a passphrase or a keyfile. In case of a keyfile, this can be any file, but it is recommended to use a file with random data which is properly protected (considering that access to this keyfile will mean access to the encrypted data).
To create a keyfile, one can use the dd command:
dd if=/dev/urandom of=/etc/keys/enc.key bs=1 count=4096
In the next sections, we will show every command for both situations - passphrase and keyfile. Of course, only one method is necessary.
Creating an encrypted storage platform
In order to create an encrypted storage platform (which can be a disk, partition, file, ...) use the cryptsetup command with the
For instance, to have /dev/vdb2 as the storage medium for the encrypted data:
cryptsetup -s 512 luksFormat /dev/vdb2
This will overwrite data on /dev/vdb2 irrevocably. Are you sure? (Type uppercase yes): YES Enter LUKS passphrase: ... Verify passphrase: ...
To use a keyfile instead of a passphrase:
cryptsetup -s 512 luksFormat /dev/vdb2 /etc/keys/enc.key
This will overwrite data on /dev/vdb2 irrevocably. Are you sure? (Type uppercase yes): YES
-s 512 tells cryptsetup which keylength to use for the real encryption key (unlike the passphrase or keyfile, which are used to access this real encryption key).
Opening the encrypted storage
In order to open up the encrypted storage (i.e. make the real data accessible through transparent decryption), use the
cryptsetup luksOpen /dev/vdb2 myname
Enter passphrase for /dev/vdb2: ...
If a keyfile is used, then the command would look like so:
cryptsetup luksOpen -d /etc/keys/enc.key /dev/vdb2 myname
When the command finishes successfully, then a new device file called /dev/mapper/myname will be made available.
If this is the first time this encrypted device is used, it needs to be formatted. The following example uses the Btrfs file system but of course any other file system will do:
Once the file system is formatted, or the formatting was already done in the past, then the device file can be mounted on the system:
mount /dev/mapper/myname /home
Closing the encrypted storage
In order to close the encrypted storage (i.e. ensure that the real data is no longer accessible through transparent decryption), use the
cryptsetup luksClose myname
Of course, make sure that the device is no longer in use.
Manipulating LUKS keys
LUKS keys are used to access the real encryption key. They are stored in slots in the header of the (encrypted) partition, disk or file.
Listing the slots
luksDump action, information about the encrypted partition, disk or file can be shown. This includes the slots:
cryptsetup luksDump /dev/vdb2
LUKS header information for /dev/vdb2 Version: 1 Cipher name: aes Cipher mode: xts-plain64 Hash spec: sha1 Payload offset: 4096 MK bits: 512 MK digest: 34 3b ec ac 10 af 19 e7 e2 d4 c8 90 eb a8 da 3c e4 4f 2e ce MK salt: ff 7c 7f 53 db 53 48 02 a4 32 dc e0 22 fc a3 51 06 ba b3 48 b3 28 13 a8 7a 68 43 d6 46 79 14 fe MK iterations: 59375 UUID: 2921a7c9-7ccb-4300-92f4-38160804e08c Key Slot 0: ENABLED Iterations: 241053 Salt: 90 0f 0f db cf 66 ea a9 6c 7c 0c 0d b0 28 05 2f 8a 5c 14 54 98 62 1a 29 f3 08 25 0c ec c2 b1 68 Key material offset: 8 AF stripes: 4000 Key Slot 1: ENABLED Iterations: 273211 Salt: 01 4c 26 ed ff 18 75 31 b9 89 5d a6 e0 b5 f4 14 48 d0 23 47 a9 85 78 fb 76 c4 a9 d0 cd 63 fb d7 Key material offset: 512 AF stripes: 4000 Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED
In the above example, two slots are used. Note that
luksDump does not give away anything sensitive - it is merely displaying the LUKS header content. No decryption key has to be provided in order to call
Adding a keyfile or passphrase
In order to add an additional keyfile or passphrase to access the encrypted storage, use the
cryptsetup luksAddKey /dev/vdb2
Enter any passphrase: (Enter a valid, previously used passphrase to unlock the key) Enter new passphrase for key slot: ... Verify passphrase: ...
To use a keyfile to unlock the key (but still add in a passphrase):
cryptsetup luksAddKey -d /etc/keys/enc.key /dev/vdb2
Enter new passphrase for key slot: ... Verify passphrase: '''
If a keyfile is to be added (say /etc/keys/backup.key):
cryptsetup luksAddKey /dev/vdb2 /etc/keys/backup.key
Or, to use the first keyfile to unlock the main key:
cryptsetup luksAddKey -d /etc/keys/enc.key /dev/vdb2 /etc/keys/backup.key
Removing a keyfile or passphrase
luksRemoveKey action, a keyfile or passphrase can be removed (so they can no longer be used to decrypt the storage):
cryptsetup luksRemoveKey /dev/vdb2
Enter LUKS passphrase to be deleted: ...
Or to remove a keyfile:
cryptsetup luksRemoveKey -d /etc/keys/backup.key /dev/vdb2
Make sure that at least one method for accessing the data is still available. Once a passphrase or keyfile is removed for use, this cannot be recovered again.
Emptying a slot
Suppose the passphrase or keyfile is no longer known, then the slot can be freed. Of course, this does require prior knowledge of which slot that the passphrase or keyfile was stored in.
For instance, to empty out slot 2 (which is the third slot as slots are numbered starting from 0):
cryptsetup luksKillSlot /dev/vdb2 2
This command will ask for a valid passphrase before continuing. Or one can pass on the keyfile to use:
cryptsetup luksKillSlot -d /etc/keys/enc.key /dev/vdb2 2
Automate mounting encrypted file systems
Until now, the article focused on manual setup and mounting/unmounting of encrypted file systems. An init service dmcrypt exists which automates the decrypting and mounting of encrypted file systems.
Edit the /etc/conf.d/dmcrypt file and add in entries for each file system. The supported entries are well documented in the file, the below example is just that - an example:
# Definition for /dev/mapper/home (for /home) target=home source=UUID="abcdef12-321a-a324-a88c-cac412befd98" key=/etc/keys/home.key # Definition for /dev/mapper/local (for /usr/local) target=local source=UUID="fedcba34-4823-b423-a94c-cadbefda2943" key=/etc/keys/local.key
The next step is to configure /etc/fstab to automatically mount the (decrypted) file systems when they become available. It is recommended to first obtain the UUID of the decrypted (mounted) file system:
/dev/mapper/home: UUID="4321421a-4321-a6c9-de52-ba6421efab76" TYPE="ext4"
Then, update the /etc/fstab file accordingly:
UUID="4321421a-4321-a6c9-de52-ba6421efab76" /home ext4 defaults 0 0 UUID="bdef2432-3bd1-4ab4-523d-badcf234a342" /usr/local ext4 defaults 0 0
Add initscript to bootlevel
Don't forget to have the dmcrypt init service launched at boot:
rc-update add dmcrypt boot
Mounting TrueCrypt/tcplay/VeraCrypt volumes
cryptsetup --type tcrypt open container-to-mount container-name
Replace container-to-mount with the device file under /dev or the path to the file you wish to open. Upon successful opening, the plaintext device will appear as /dev/mapper/container-name, which you can
mount like any normal device.
If you are using key files, supply them using the
--key-file option, to open a hidden volume, supply the
--tcrypt-hidden option and for a partition or whole drive that is encrypted in system mode use the
unmount the volume, and close the container using the following command:
cryptsetup close container-name