How do I determine what ciphers & cipher modes I can use in dm-crypt/LUKS?

There are many, many documents and man pages to read through, but one document that might particularly interest you is the LUKS On-Disk Format Specification (PDF).

Appendix B (which is, naturally, near the end) says,

Cipher and Hash specification registry

Even if the cipher-name and cipher-mode strings are not interpreted by any LUKS operation, they must have the same meaning for all implementations to achieve compatibility among different LUKS-based implementations. LUKS has to ensure that the underlaying cipher system can utilise the cipher name and cipher mode strings, and as these strings might not always be native to the cipher system, LUKS might need to map them into something appropriate.

Valid cipher names are listed in Table 1.

Valid cipher modes are listed in Table 2. By contract, cipher modes using IVs and tweaks must start from the all-zero IV / tweak. This applies for all calls to the encrypt / decrypt primitives especially when handling key material. Further, these IVs / tweaks cipher modes usually cut the cipher stream into independent blocks by reseeding tweaks / IVs at sector boundaries. The all-zero IV / tweak requirement for the first encrypted / decrypted block is equivalent to the requirement that the first block is defined to rest at sector 0.

Table 3 lists valid hash specs for hash-spec field. A compliant implementation does not have to support all cipher, cipher mode or hash specifications.

Table 1: Valid cipher names

  • aes - Advanced Encryption Standard - FIPS PUB 197
  • twofish - Twofish: A 128-Bit Block Cipher - http://www.schneier.com/paper-twofish-paper.html    (See below)
  • serpent - http://www.cl.cam.ac.uk/~rja14/serpent.html
  • cast5 - RFC 2144
  • cast6 - RFC 2612

Table 2: Valid cipher modes

  • ecb - The cipher output is used directly
  • cbc-plain - The cipher is operated in CBC mode. The CBC chaining is cut every sector, and reinitialised with the sector number as initial vector (converted to 32-bit and to little-endian). This mode is specified in [Fru05b], Chapter 4.
  • cbc-essiv:hash - The cipher is operated in ESSIV mode using hash for generating the IV key for the original key. For instance, when using sha256 as hash, the cipher mode spec is “cbcessiv:sha256”. ESSIV is specified in [Fru05b], Chapter 4.
  • xts-plain64 - http://grouper.ieee.org/groups/1619/email/pdf00086.pdf, plain64 is 64-bit version of plain initial vector

Table 3: Valid hash specifications

  • sha1 - RFC 3174 - US Secure Hash Algorithm 1 (SHA1)
  • sha256 - SHA variant according to FIPS 180-2
  • sha512 - SHA variant according to FIPS 180-2
  • ripemd160 - http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html   (See below)

Editor’s Note: The above is copied from the specification.  Subsequent to its writing, these documents’ URLs have changed:

  • Twofish: A 128-Bit Block Cipher   (new URL)
  • The hash function RIPEMD-160   (new URL)

The 5.1 kernel, current at the time I write this, has two different formats the for cipher string, the "old" format and the "new" format. Everything in this question so far, and apparently all docs too, deals with the "old" format, so I'll describe it here. This is for just encryption. If using integrity with dm-crypt, then one must consider AEAD ciphers and it gets even more complicated.

The format parsed by the kernel is "cipher[:keycount]-mode-ivmode[:ivopts]". Examples: aes-xts-plain64, blowfish-cbc-essiv:sha256, aes:64-cbc-lmk.

  • cipher The cipher to use, examples are aes, anubis, twofish, arc4, etc. The kernel dm-crypt driver does not have a list of ciphers. This is passed through to the Linux Crypto API, so any suitable cipher supported by the kernel can be used.

  • keycount Optional power of two number of keys to use with cipher. This defaults to 1 for everything except the lmk ivmode, where it defaults to 64. This really only applies to LMK and values other than 1 will will not work properly with other modes.

  • mode The block chaining mode to use with the cipher. Examples are ecb, cbc, xts. Other than knowing that ecb uses no IV, the md-crypt driver passes this through to the Linux Crypto API and can use any chaining mode supported by the kernel.

  • ivmode The algorithm used to generate the initialization vector (IV) for each sector. In typical symmetric key encryption, unlike dm-crypt, the IV is another bit of data passed into the cipher along with the key when encrypting or decrypting. There is just one IV passed in for the entire operation. Since dm-crypt needs to be able to read and write each sector individually, it does not encrypt the entire disk as a single operation. Instead, there is an IV for each sector. Rather than passing in the IV as data, an algorithm for creating the IVs is specified here. This isn't part of the Linux Crypto API, since IV generation isn't done by the cipher, and the allowed ivmode values are defined the dm-crypt driver. They are:

    • plain, plain64, plain64be, benbi These simply use the sector number, in various formats, as the IV. Meant for block modes like XTS that are designed to resist attacks like watermarking when using a simple and predictable IV. plain64 appears to be the most commonly recommended.
    • null IV is always zero. For testing and backward compatibility, you shouldn't use this.
    • lmk Compatible with the Loop-AES encryption scheme.
    • tcw Compatible with TrueCrypt.
    • essiv Uses sector number encrypted with a hash of the key. Meant for modes, like CBC, that are not resistant to various attacks when using a simple IV like plain64.
  • ivopts The hash to be used with essiv ivmode, ignored for all other modes.

As a special case, "cipher-plain" or just "cipher" are interpreted as "cipher-cbc-plain". Another special case is that ecb mode has no ivmode to specify.

How this relates to /proc/crypto

With respect to /proc/crypto, only the cipher and mode are relevant. dm-crypt with construct a Crypto API specification of the form "mode(cipher)" and request this from the kernel. This is what one should look for in /proc/crypto as the name for a skcipher. Example:

name         : xts(aes)
driver       : xts-aes-aesni
module       : kernel
priority     : 401
refcnt       : 1
selftest     : passed
internal     : no
type         : skcipher
async        : yes
blocksize    : 16
min keysize  : 32
max keysize  : 64
ivsize       : 16
chunksize    : 16
walksize     : 16

The type of skcipher indicates this a symmetric key cipher, what dm-crypt uses, and the name of xts(aes) would be written aes-xts when specified with dm-crypt. The keysize fields also tell us what key sizes can be used with this cipher.

If this was from a module, the module name might show up in the module line. However, many ciphers (usually those in software that don't have any hardware specific code) are implement as a generic cipher that is combined with generic block chaining code to produce the final skcipher. For example:

name         : xts(anubis)
driver       : xts(ecb(anubis-generic))
module       : kernel
type         : skcipher

name         : anubis
driver       : anubis-generic
module       : anubis
type         : cipher

In this case the anubis cipher is combined with the kernel XTS block chaining mode code to produce the final cipher xts(anbuis), which has been assigned a module of kernel. But in order to have this available we need the generic anubis cipher, which is from the anubis module. Most ciphers have a module alias of "crypto-cipher" that can be used to load them, e.g. modprobe crypto-anubis would load module that provides the anubis cipher.

When using the cryptsetup benchmark command, only the cipher and mode matter, since that is all that is benchmarked. If mode is not specified it defaults to CBC. The ivmode is totally ignored. Thus, for benchmarking, aes, aes-cbc, and aes-cbc-foobar are all equivalent.


You can list the ciphers supported by your kernels with the following command,

[root@arif]# ls /lib/modules/[your kernel version]/kernel/crypto/
algif_rng.ko.xz   blowfish_common.ko.xz   cmac.ko.xz               cts.ko.xz          gf128mul.ko.xz           michael_mic.ko.xz  rsa_generic.ko.xz      tgr192.ko.xz           xts.ko.xz
ansi_cprng.ko.xz  blowfish_generic.ko.xz  crc32_generic.ko.xz      deflate.ko.xz      ghash-generic.ko.xz      pcbc.ko.xz         salsa20_generic.ko.xz  twofish_common.ko.xz   zlib.ko.xz
anubis.ko.xz      camellia_generic.ko.xz  crct10dif_common.ko.xz   des_generic.ko.xz  jitterentropy_rng.ko.xz  pcrypt.ko.xz       seed.ko.xz             twofish_generic.ko.xz
arc4.ko.xz        cast5_generic.ko.xz     crct10dif_generic.ko.xz  dh_generic.ko.xz   khazad.ko.xz             rmd128.ko.xz       serpent_generic.ko.xz  vmac.ko.xz
async_tx          cast6_generic.ko.xz     cryptd.ko.xz             drbg.ko.xz         lrw.ko.xz                rmd160.ko.xz       sha512_generic.ko.xz   wp512.ko.xz
authencesn.ko.xz  cast_common.ko.xz       crypto_null.ko.xz        fcrypt.ko.xz       mcryptd.ko.xz            rmd256.ko.xz       tcrypt.ko.xz           xcbc.ko.xz
authenc.ko.xz     ccm.ko.xz               crypto_user.ko.xz        gcm.ko.xz          md4.ko.xz                rmd320.ko.xz       tea.ko.xz              xor.ko.xz

You can list the ciphers and hashes you can use and their I/O comparison by for luks by the following command,

[root@arif arif]# cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1       289342 iterations per second for 256-bit key
PBKDF2-sha256     353293 iterations per second for 256-bit key
PBKDF2-sha512     227555 iterations per second for 256-bit key
PBKDF2-ripemd160  233224 iterations per second for 256-bit key
PBKDF2-whirlpool  236165 iterations per second for 256-bit key
argon2i       4 iterations, 917485 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id      4 iterations, 951672 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
#     Algorithm |       Key |      Encryption |      Decryption
        aes-cbc        128b       642.2 MiB/s      2495.8 MiB/s
    serpent-cbc        128b        89.3 MiB/s       542.6 MiB/s
    twofish-cbc        128b       100.4 MiB/s       343.1 MiB/s
        aes-cbc        256b       477.2 MiB/s      1979.2 MiB/s
    serpent-cbc        256b        89.3 MiB/s       538.9 MiB/s
    twofish-cbc        256b       173.3 MiB/s       343.1 MiB/s
        aes-xts        256b      1668.0 MiB/s      1664.1 MiB/s
    serpent-xts        256b       535.7 MiB/s       523.4 MiB/s
    twofish-xts        256b       332.6 MiB/s       339.8 MiB/s
        aes-xts        512b      1384.5 MiB/s      1380.7 MiB/s
    serpent-xts        512b       539.3 MiB/s       524.4 MiB/s
    twofish-xts        512b       335.0 MiB/s       340.1 MiB/s

You can compare specific ciphers by the following command,

[root@arif]# ciphers="aes-xts serpent-xts anubis-xts"

[root@arif]# echo "#     Algorithm |       Key |      Encryption |      Decryption";for i in $ciphers ; do cryptsetup benchmark --cipher $i|tail -n 1; done

#     Algorithm |       Key |      Encryption |      Decryption
        aes-xts        256b      1613.9 MiB/s      1642.8 MiB/s
    serpent-xts        256b       538.9 MiB/s       521.9 MiB/s
     anubis-xts        256b       182.0 MiB/s       182.1 MiB/s