While setting up encrypted swap on yet another Linux machine, I wondered what the "best" crypto algorithm would be.
There are plenty of combinations of ciphers, modes, hash algorithms and keysizes to chose from with cryptsetup(8), let's see if we can find a fast, yet sufficiently "secure" one.
Before testing these combinations I wanted to find out which combinations were actually possible. E.g. setting up a dm-crypt device with
aes-cbc-plain with a keysize of 128 or 256 bit would be possible - but any larger keysize was rejected. There were many "invalid" combinations, for reasons rooted deeply in their mathematical properties. So, let's find out these valid combinations then:
[...] cryptsetup -c $CIPHER -s $KEYSIZE -d /dev/urandom create test /dev/sdc 2>/dev/null if [ $? = 0 ]; then echo "Valid combination: cipher $CIPHER size $KEYSIZE" else echo "Invalid combination: cipher $CIPHER - size $KEYSIZE" fiAfter quite some iterations over a predefined set of combinations (12 ciphers, 7 modes, 14 hashing algorithms, 5 keysizes), there were 1125 valid combinations left. Yeah, testing took a while :-)
Now we wanted to see which combinations performed "best". As stated above, the usecase was a blockdevice for encrypted swap - so "fast, yet pretty secure" were the criteria to look for. As a (very) simple test, the following should be done for each newly set up crypto block device:
while [ $i -lt 30 ]; do # Empty all caches, including filesystem buffers sysctl -qw vm.drop_caches=3 dd if=/dev/mapper/test of=/dev/null bs=1M 2>/dev/null i=$((i+1)) done
The results, summarized:
cipher_null*is the fastest - but it's absolutely insecure, because...well, it's a NULL cipher :-)
- Interestingly, PCBC mode is sometimes very slow. As per the Wikipedia article, this mode is not very common anyway, so we'll not choose this one.
- As expected, Twofish is very fast, along with AES and Blowfish.
$ egrep -v 'cipher_null|-(ecb|lrw|pcbc)-|-plain|md|rmd|tgr|crc32|sha1' results | \ grep ' / 256' | sort -nk5 | head -10 twofish-ctr-essiv:sha256 / 256 : 66 <== 66 seconds for 30 runs. Lower is better. twofish-cbc-essiv:sha256 / 256 : 69 twofish-xts-essiv:sha256 / 256 : 73 aes-xts-essiv:sha256 / 256 : 79 blowfish-cbc-essiv:sha256 / 256 : 81 blowfish-ctr-essiv:sha256 / 256 : 86 aes-ctr-essiv:sha256 / 256 : 90 aes-cbc-essiv:sha256 / 256 : 91 camellia-xts-essiv:sha256 / 256 : 103 serpent-ctr-essiv:sha256 / 256 : 103
Now my /etc/crypttab proably looks like this:
swap /dev/sda2 /dev/urandom swap,cipher=twofish-xts-essiv:sha256,size=256,hash=sha512Word of caution: this is a benchmark - some arbitrary test for a very special usecase, executed on one machine and one machine only (Fedora 18 in an ESX virtual machine, equipped with 2 AMD Opteron 848 processors). Before applying these results to your environment, run the benchmark yourself or, better yet: write your own benchmark for your usecase!