How to interpret `cryptsetup benchmark` results

benchmarkcryptsetupluks

Summary: I can run cryptsetup benchmark and sort the results, but seek guidance in their interpretation. E.g., should I give more weight to encryption speed or decryption speed? Should key-derivation speed override either? And how should my usecase affect how I weight/interpret results?

Pointers to doc are appreciated: I have websearched, but haven't seen anything definitive-looking. Particularly, this does not seem to be

Details:

I'm preparing to reinstall OS on a 2007-ish laptop (so presumably no processor support for AES), this time with LUKS+LVM2. (It's my one remaining box with Plain Old Partitions.) I don't have time to run several loops of the sequence [install LUKS+LVM2+OS, run a real disk benchmark, measure results], though that would obviously give much more empirical guidance. Instead, I'm trying to choose a rational (even optimal 🙂 LUKS cipher specification string "up front" using cryptsetup benchmark, though I know that one "cannot directly predict real storage encryption speed from it"[2].

When this box runs sudo cryptsetup benchmark it outputs (after tweaking to label and separate the issues and to sort by speed decreasing):

# key derivation:
PBKDF2-sha1       557753 iterations per second
PBKDF2-sha256     356173 iterations per second
PBKDF2-ripemd160  336082 iterations per second
PBKDF2-sha512     256000 iterations per second
PBKDF2-whirlpool  112219 iterations per second

# encryption:
#  Algorithm | Key |  Encryption 
 serpent-xts   512b   144.7 MiB/s     
 serpent-xts   256b   144.0 MiB/s     
 twofish-xts   256b   132.1 MiB/s     
 twofish-xts   512b   132.0 MiB/s     
     aes-xts   256b   128.4 MiB/s     
     aes-cbc   128b   109.7 MiB/s     
 twofish-cbc   256b   108.2 MiB/s     
 twofish-cbc   128b   107.9 MiB/s     
     aes-xts   512b    96.7 MiB/s     
     aes-cbc   256b    86.5 MiB/s     
 serpent-cbc   256b    42.1 MiB/s     
 serpent-cbc   128b    42.1 MiB/s     

# decryption:
#  Algorithm | Key  | Decryption
 serpent-cbc   256b   160.0 MiB/s
 serpent-cbc   128b   159.5 MiB/s
 serpent-xts   512b   149.0 MiB/s
 serpent-xts   256b   148.4 MiB/s
 twofish-cbc   256b   142.1 MiB/s
 twofish-cbc   128b   141.6 MiB/s
 twofish-xts   256b   133.5 MiB/s
 twofish-xts   512b   133.4 MiB/s
     aes-cbc   128b   127.5 MiB/s
     aes-xts   256b   126.0 MiB/s
     aes-cbc   256b    96.0 MiB/s
     aes-xts   512b    95.2 MiB/s

The above results show

  1. encryption: serpent-xts/512 is fastest, serpent-cbc/* is slowest
  2. decryption: serpent-cbc/256 is fastest, serpent-xts/512 is 3rd fastest
  3. key derivation: sha1 is significantly faster than sha256 is significantly faster than sha512

Less certainly, I believe

  1. sha1 is being retired, so for compatibility going forward, I should deweight (to zero) the significant KDF speed advantage of sha1 over sha256.
  2. "For the normal use-case of an authorized user [on a workstation, the key derivation function] will only need to be calculated once per session,"[3] so I should deweight the significant KDF advantage of sha256 over sha512.

So a specific question is:

  1. Should I give more weight to the significant speed advantage of sha256 in key derivation (|356173 - 256000| / ((356173 + 256000)/2) ~= 0.327), or to the modest speed advantage of sha512 (which I'm assuming is also more secure) in both decryption and encryption?

A more general question is:

  1. How should one's usecase affect one's weighting of the importance of speed in key derivation, decryption, and encryption? E.g., will a headless server spend more or less time decrypting (or whatever) than a headful workstation? I'm assuming that decryption is done on read and encryption on write, but I don't know about how one's usecase affects the relative incidence/weight of read and write.

FWIW, the box I'm setting up will be my second-string headful production box for now, so it basically needs to

  • run an editor and a browser
  • make SSH connections
  • play video and music
  • be a loaner for folks who want to try Linux
  • be ready to go if I hose my first-string production laptop

(It will be running Debian, if that makes a difference.) Of course, I generally prefer faster performance to slower (and more reliability to less) but I'm obviously willing to pay some price for security.

Even more general questions are:

  1. Can one generally rank importance of speed of key derivation, decryption, and encryption? I'm guessing KDF speed is much less important[3], but that decryption and encryption speeds are of equal weight for most usecases. (But ICBW.)

  2. I know that default, no-argument runs of cryptsetup benchmark "[measure only a] few common configurations"[2] and that to "benchmark other ciphers or modes, you need to specify --cipher and --key-size options or --hash for KDF test."[2]. This section of the ArchWiki gives a bit more detail on how one can do this, but I'm not aware of one or more lists of either

4.1. the valid option parameters for specifying non-default cryptographics (ciphers, hashes, keysizes, modes) to cryptsetup benchmark. Can anyone point to definitive doc for this?

4.2. other, non-default cryptographics one should specify and benchmark, given current technologies and kernel support. Your suggestions appreciated (provided you also provide the appropriate option parameters 🙂

  1. Are there "better" tools to use for LUKS performance pre-tuning than cryptsetup benchmark? If so, what and how?

[1]: e.g., https://wiki.archlinux.org/index.php/Dm-crypt/Device_Encryption#Encryption_options_for_LUKS_mode , https://wiki.archlinux.org/index.php/Disk_encryption#Cryptographic_metadata

[2]: run info cryptsetup or man cryptsetup

[3]: see https://wiki.archlinux.org/index.php/Disk_encryption#Cryptographic_metadata

Best Answer

KDF speed is important, but contrary to your belief, it should be SLOW.

With LUKS, your encrypted drive contains a header with an encrypted master key that is used to encrypt your device. This master key gets decrypted with one of the keys in your key slots when you boot/open the device (try cryptsetup luksDump /dev/sdx to see information contained in the LUKS header).

When you first format the LUKS device, it will ask you for a passphrase (or keyfile). This passphrase is then used to create and encrypt a key that will be added in keyslot 0. Your passphrase is also hashed and stored, so that LUKS can verify if you entered the right passphrase when you open the device. This is important to understand, because if you use a fast hashing algorithm, it is easier to crack the passphrase since an attacker can test a lot more combinations in shorter time.

Therefore, you should go for the slowest and most secure hashing algorithm (sha512 or whirlpool) and use a high --iter-time. The --iter-time option allows you to set the time it takes to do 1 hashing iteration. The only downside to a high iteration time is that it takes just that long to actually open the encrypted device. Say you use an --iter-time of 10000 (10 seconds) on your root device, then it will take 10 seconds for your system to get the actual encryption key and thus you will have to wait that long after your password before booting continues. This only happens once when you open the device, so further performance is not affected.

For your actual encryption cipher, it depends on how fast your underlying physical device can read/write and how much workload is on the machine. The encryption/decryption is performed by your CPU, so if you go with the slowest one there is a good chance that it will affect other programs running at the same time. As of right now, aes-xts-plain64 is considered the most secure LUKS cipher, so if you have very confidential information you should probably go with aes-xts-plain64 and a keysize of 512 (since with xts the key is split in 2 so you actually get aes with 256-bit keys).

If I were to make a recommendation on your setup, it would be sha512 as hashing algorithm with an iter-time between 2s-10s and using aes-xts-plain64 with a keysize of 256, since AES-128 is still considered secure.

Related Question