Improve cryptsetup luksOpen performance on slow hardware - jandelgado/general GitHub Wiki
Problem
Opening (i.e. the cryptsetup luksOpen
operation) an encrypted USB harddisk on an embedded device with just about 500Mhz CPU (in my case a GL.iNet-MT300N-V2 mini router running a custom OpenWRT) took minutes. After the device was opened, performance was on par with expectations.
Cause
The disk was initially encrypted (cryptsetup luksFormat
) on a performant Xeon server. During storage of the key, a so called Iteration
value is determined based on the hosts performance and stored alongside with the encrypted key on the disk. The faster the host used during initialization, the higher the calculated iteration count. This results in bad performance during cryptsetup luksOpen
on a host with significant less CPU power.
Solution
Add another key/passphrase in a different slot and set the iterations value manually:
$ sudo cryptsetup luksAddKey -S 7 --pbkdf-force-iterations 1000 --force-password /dev/sdb1
When opening the disk, provide the key slot to use, e.g. cryptsetup luksOpen -S 7 /dev/sdb1 crypto
Performance comparison
For demonstration we use a disk encrypted with two keys. On with a high iteration count (3536512) in slot 0
and
another one with an iteration count set to 1000 in slot 7
. Example output of cryptsetup luksDump
with irrelevant data removed:
root@lede-mobile: ~# cryptsetup luksDump /dev/sda1
LUKS header information for /dev/sda1
Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha256
Payload offset: 4096
MK bits: 256
MK digest: ...
MK salt: ...
...
MK iterations: ...
UUID: ...
Key Slot 0: ENABLED
Iterations: 3536512
Salt: ...
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
...
Key Slot 7: ENABLED
Iterations: 1000
Salt: ...
Key material offset: 1800
AF stripes: 4000
In the example the key in Slot 7
was set with --pbkdf-force-iterations
parameter set to 1000
,
bypassing performance based calculation of the value.
Let's compare performance of opening the disk with keyslot 0 and 7:
root@lede-mobile: ~# time cryptsetup luksOpen -S0 /dev/sda1 crypto
Enter passphrase for /dev/sda1:
real 6m 36.46s
user 6m 27.50s
sys 0m 0.09s
root@lede-mobile: ~# cryptsetup close crypto
root@lede-mobile: ~# time cryptsetup luksOpen -S7 /dev/sda1 crypto
Enter passphrase for /dev/sda1:
real 0m 24.83s
user 0m 21.04s
sys 0m 0.04s
Duration of cryptsetup luksOpen
changes from 6m36s for opening using key slot 0
to 24s with key slot 7
- a clear improvement.
Note that of course you need the right balance between speed and iteration count to ensure security (left to the reader as excercise ;)