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.
/lib/modules/*/kernel/crypto/
is a likely place to look, but modules can be anywhere on the filesystem./proc/crypto
is great, but it doesn't list the valid cipher strings; things likeaes-xts-plain64
oraes-cbc-essiv:sha256
. A good answer would provide that information and show which modules from/lib/modules...
need to be loaded to use them./proc/crypto
. It doesn't make sense.