Encrypt any block device
Table of Contents
Goal ∆
A hard drive or a USB stick set up in this way is recognised by common filemanagers (e.g. Thunar, PCManFM) - it shows up as an encrypted device in the side bar, a password dialog pops up, and the twofold decrypt/mount process happens in one click.
Device encryption, performance considerations ∆
We will be using dm-crypt with cryptsetup.
I have done this before on a consumer 32GB USB (3.0) stick but had noticed occasional lag (freezes) when reading files, so this time I am trying to get faster decryption (trading off some security no doubt). Whether this helps remains to be seen. This article suggests that the bottleneck might be elsewhere.
We are root.
Find out which device you want to encrypt with fdisk -l
. Let's say it's dev/sdX
.
By the way, we will be encrypting the whole device, and not create a partition for it first. So there will be only one filesystem on it later, and one - well, partition.
I'm not sure if it's required, but better to a) unmount it and b) nuke it with e.g.: .dd if=/dev/urandom of=/dev/sdX bs=16M count=10
The cryptsetup command offers a benchmark function:
$> cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1 1661768 iterations per second for 256-bit key
PBKDF2-sha256 2088796 iterations per second for 256-bit key
PBKDF2-sha512 1468593 iterations per second for 256-bit key
PBKDF2-ripemd160 851116 iterations per second for 256-bit key
PBKDF2-whirlpool 640156 iterations per second for 256-bit key
argon2i 5 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id 5 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
# Algorithm | Key | Encryption | Decryption
aes-cbc 128b 1086.6 MiB/s 3287.4 MiB/s
serpent-cbc 128b 89.1 MiB/s 707.8 MiB/s
twofish-cbc 128b 199.9 MiB/s 373.4 MiB/s
aes-cbc 256b 834.2 MiB/s 2658.0 MiB/s
serpent-cbc 256b 92.7 MiB/s 707.9 MiB/s
twofish-cbc 256b 205.8 MiB/s 373.0 MiB/s
aes-xts 256b 2054.1 MiB/s 2063.4 MiB/s
serpent-xts 256b 673.1 MiB/s 672.7 MiB/s
twofish-xts 256b 370.5 MiB/s 372.0 MiB/s
aes-xts 512b 1839.7 MiB/s 1891.6 MiB/s
serpent-xts 512b 674.3 MiB/s 674.3 MiB/s
twofish-xts 512b 367.2 MiB/s 370.9 MiB/s
The sentence "Tests are approximate using memory only (no storage IO)" is discouraging for my specific use case.
Nevertheless, I let the numbers dictate my choices:
#> cryptsetup luksFormat --hash sha256 --pbkdf pbkdf2 --iter-time 200 --cipher aes-cbc-essiv:sha256 --key-size 128 --verbose /dev/sdX
For reading, this should be the fastest option.
Create a filesystem (FAT32 is sufficient for my use case, and probably faster than a journaling filesystem, but of course mkfs.ext4
etc. is equally valid here):
#> cryptsetup luksOpen /dev/sdX usbcrypt # "usbcrypt" or whatever label you like
#> mkfs.vfat /dev/mapper/usbcrypt
That's all really.
Fixing permissions for Udisks ∆
Assuming the device shows up in your filemanager's sidebar - it should. If you want to access it through a single click, you have to give polkit permission to do so without additional user authentication (i.e. you only enter the decryption password, not the user or root password).
Are you getting "Not authorized to perform operation" instead, after entering the encryption passphrase, or are you getting an additional password dialog? Both mean the same thing: polkit requires additional authentication for mounting a (internal) device; FAT32 formatted USB drives usually do not require this.
If your filemanager uses udisks2, try this in a terminal first: udisksctl unlock -b /dev/sdX
- if it only asks for the passphrase then it should work in your filemanager, too.
If it asks for AUTHENTICATING FOR org.freedesktop.udisks2.encrypted-unlock-system
etc., you can add this polkit rule:
polkit.addRule(function(action, subject) {
if (
action.id == "org.freedesktop.udisks2.encrypted-unlock-system" &&
subject.local && subject.active && subject.isInGroup("storage")
)
return polkit.Result.YES;
});
Save it in /etc/polkit-1/rules.d/
as e.g. allow-unlock.rules
.
This applies to members of the storage
group. I actually had to add my normal user (let's call it normuser
) to that group with
sudo usermod -a -G storage normuser
, but you could use any other group your user already belongs to.
Check with id
.
Now it should work, command line first:
udisksctl unlock -b /dev/sdX
Passphrase:
Unlocked /dev/sdX as /dev/dm-0.
udisksctl mount -b /dev/dm-0
Mounted /dev/dm-0 at /run/media/normuser/XXXXXXXXX
And the same should happen when you click the device in your filemanager.
Changing ownership ∆
The filesystem on the device belongs to root
. Let's change that. Assuming your normal user is called normuser
:
cd /run/media/normuser/XXXXXXXXX # or wherever udisks mounted your device to
sudo chown -R normuser:normuser . ..
rmdir lost+found # for good measure and a clean slate
Further reading ∆
https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption
https://wiki.gentoo.org/wiki/Dm-crypt_full_disk_encryption