Disk Encryption with dm-crypt and LUKS on Linux
September 20, 2015 · Benjamin Lee · linux · security
dm-crypt is a Linux Device-mapper target that provides transparent encryption of block devices using the kernel crypto API. Plain dm-crypt supports only one passphrase and does not store any metadata on-disk.
Linux Unified Key Setup (LUKS) is a dm-crypt extension and the preferred way to set up disk encryption with dm-crypt. LUKS is a disk encryption standard that adds a header and a key-slot at the start of the device, called a LUKS container. LUKS supports multiple passphrases that can be individually changed and revoked. Passphrases are protected using the PBKDF2 key derivation function, which is also described in RFC 2898.
First, securely erase the target device.
For traditional hard disk drives, simply overwrite the device. Depending on your security requirements you may need to use random data instead of zeros.
cat /dev/zero > /dev/sdz
For solid-state drives (SSDs), clear the memory cells. This can usually be accomplished via ATA Secure Erase but varies by device. I do not recommend overwriting an SSD, which would increase device wear and cause reduced write performance due to write amplification.
sudo hdparm --user-master u --security-set-pass password /dev/sdz sudo hdparm --user-master u --security-erase password /dev/sdz
Next, set up a LUKS device with your desired encryption parameters. The appropriate level of encryption is situation-dependent. I highly recommend choosing algorithms for which your system can use hardware acceleration (for example, the Intel AES-NI instruction set that was introduced with Westmere). Choosing cipher and hash algorithms is discussed at length elsewhere and is beyond the scope of this article.
Initialize a LUKS device and set the initial passphrase. For the block cipher I chose XTS-AES with a 256-bit key (XTS-AES 128), which is recommended in NIST SP 800-38E and used in Apple FileVault 2. For the PBKDF2 passphrase hash I chose SHA-256 with 5 seconds of processing time.
sudo cryptsetup --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 5000 --use-random --verify-passphrase luksFormat /dev/sdz
Open and map the encrypted device. Use --allow-discards if using an SSD that supports TRIM.
sudo cryptsetup --allow-discards luksOpen /dev/sdz secure
Create and mount a filesystem on the encrypted device. Use -o discard if using an SSD that supports TRIM.
sudo mkfs.ext4 /dev/mapper/secure sudo mount -o noatime,discard /dev/mapper/secure /secure
Finally, configure your system to map and mount the encrypted device during boot. These steps vary by distribution and whether you are encrypting the root filesystem, which requires updating your initramfs.
Here is an example configuring a non-root encrypted device on Gentoo Linux.
Add the LUKS device to /etc/conf.d/dmcrypt.
target="secure" source="/dev/sdz" options="--allow-discards"
Add the dmcrypt service to the boot runlevel.
sudo rc-update add dmcrypt boot
Add the encrypted filesystem to /etc/fstab.
/dev/mapper/secure /secure ext4 noatime,discard 0 2
- cryptsetup Frequently Asked Questions
- LUKS On-Disk Format Specification
- Recommendation for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on Storage Devices
- Infiltrate the Vault: Security Analysis and Decryption of Lion Full Disk Encryption
- Arch Linux Wiki: dm-crypt/Device encryption