Simple Disk or File-System Image Encryption with dm-crypt
dm-crypt is a part of modern Linux’s device mapper system which allows for the transparent application of a broad range of block cyphers to a virtual block device. The virtual block device is configured with the cryptsetup command and can point to a real block device (i.e. a real hard drive or partition) or a file which has been attached to a loop device as the underlaying source.
There are a lot of great reasons to use LUKS (Linux Unified Key Setup), not the least of which is the ability to encrypt the host operating system’s partition or change the encrypted volume’s passphrase. In this article however, we will simply be covering the mundane encryption of block devices with dm-crypt.
One of the advantages of encrypting a physical hard drive from head to toe is that there is no partition table around to leak metrics; if you followed Filling a Drive with Random Data: urandom, dd and Patience your encrypted file system will span the size of the device and any cryptographic boundaries should be undetectable.
If you will be working with a file instead of a real block device it will be necessary to create the file and set it up on a loop device before proceeding. Just as with wiping a disk it is recommended that /dev/urandom is used to initialize the file insted of /dev/zero but you may find the same benefit for much less time in simply creating a sparse file (please see Managing Raw Disk/File System Image Files for more details).
# dd if=/dev/urandom of=encrypted.img bs=1M count=1000 OR # dd if=/dev/zero of=encrypted.img seek=1000 bs=1M count=0 THEN # losetup /dev/loop0 encrypted.img
Now we’re going to run the device through dm-crypt using 256 bit AES and SHA256 ESSIV. ESSIV is a method of generating initialization vectors which are difficult to predict; this helps protect against watermarking attacks. You will be asked to provide a passphrase, the longer and more complex the better.
# cryptsetup -c aes-cbc-essiv:sha256 create encryptedVolume /dev/loop0 (or /dev/sdd, etc) Enter passphrase:
Alternatively, you may prefer to use a large chunk of random data stored in a file, perhaps on a USB stick.
# dd if=/dev/urandom of=/mnt/usb/passphrase.key bs=1K count=4 # cat /mnt/usb/passphrase.key | cryptsetup -c aes-cbc-essiv:sha256 create encryptedVolume /dev/loop0
This method provides excellent protection against brute force attacks but may add a physical security dilemma. Consider a case where law enforcement agents have a warrant to search and sieze your property; if they find the USB stick and figure out that it contains the key to your encrypted drive they don’t have to pressure you for your passphrase to use it. On the other hand, depending where and with whom the key is stored this approach could have benefits in a rubber-hose attack situation as 4K of random data is virtually impossible to memorize.
Our new virtual block device is located under /dev/mapper. Now we can create the filesystem of our choice on it:
# mke2fs -j /dev/mapper/encryptedVolume
Once the filesystem is in place the device can be mounted and used like any regular block or loop device:
# mkdir /mnt/encrypted # mount /dev/mapper/encryptedVolume /mnt/encrypted
As long as the device is available through device mapper the contents of the encrypted volume are vulnerable to the same kind of attacks any part of your regular system is: malware, viruses, cockpit error and so on. When not in use be sure to unmount the file system and destroy the device mapper entry:
# umount /mnt/encrypted # cryptsetup remove encryptedVolume
If your volume is file-backed it is now safe to unhitch it from the loop device:
# losetup -d /dev/loop0