I'm about to encrypt two of my hard drives using LUKS, since I can't really do it myself I use the guide on the Arch Linux wiki (which can be found here). In an example in the guide the cipher specified is aes-xts-plain
with a 512-bit key size.
Is aes-xts-plain
the best choice or is there a better cipher to use? I'd prefer security over speed.
![](../../users/profiles/414.webp)
- 50,912
- 13
- 120
- 179
![](../../users/profiles/3301.webp)
- 261
- 1
- 3
- 3
-
1If you'd like more comprehensive answers, then perhaps you could list the ciphers supported by LUKS by their common names. I don't know which ciphers LUKS support, and I imageine others here have it the same way. – Jul 12 '11 at 16:29
-
See also [How secure is Ubuntu's default full-disk encryption?](http://security.stackexchange.com/q/39306) – Martin Schröder Oct 09 '14 at 20:19
-
In terms of the cipher alone, Serpent is generally agreed upon to be the most secure common cipher for LUKS. Note that the mode of operation (e.g. xts, cbc-essiv:sha256, etc) is highly dependent on your use case, so I won't go into that here. – forest Apr 05 '16 at 05:31
-
I suggest to pay attention at the Key Derivation process as well: the master key will be encrypted with a key derived from your user password/passphrase (if not keyfile). Thus either you provide a really strong passphrase (correct-horse-battery-staple level: https://xkcd.com/936/), either you pay more attention to the parameters used in deriving this user key. In particular look at: iteration count, hashing pseudo-random-function. I suggest > 1M i.c. if on laptop, or more, and SHA256. Now I see the age of this question, my comment is valid for the current versions of LUKS. – refex Aug 19 '16 at 21:43
-
2You should always use `plain64` rather than `plain`. The two are identical for volume sizes up to 2 TiB, but `plain` can potentially leak data when volume sizes grows beyond 2 TiB whereas `plain64` does not. Since `plain64` is identical to `plain` for offsets below the 2 TiB mark, there is no real reason to use `plain` in favor of `plain64`. The [cryptsetup FAQ](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions) has a discussion on this under *Are there any problems with "plain" IV? What is "plain64"?* (currently section 5.15). – user Feb 09 '17 at 12:31
-
@refex SHA-512 is a better choice since it is (paradoxically) faster than SHA-256 on 64-bit processors. – forest Feb 20 '19 at 04:25
3 Answers
There's three components you need to understand in any block cipher usage and they apply explicitly here:
- The block cipher primitive. This could be one of your familiar, AES-candidate ciphers such as, well, AES, Serpent, Twofish, Blowfish, ...
- The mode of operation. Using a block cipher as is, block by block is called electronic code book, but there are other modes such as cipher block chaining and counter mode, with their various advantages and disadvantages.
- The initialisation vector generation scheme, such as essiv which combats various fingerprinting techniques available to attackers against CBC used for disk encryption.
So when you pick an option, e.g. aes-cbc-essiv
, you're actually asking for AES, used in CBC mode with encrypted IV's based on some per-block identifier, whereas aes-xts-plain
uses AES in XTS mode with plain old IVs generated from some per-block information.
It boils down to whether you trust that XTS has sufficient resistance to whitening (which ESSIV combats) baked in to the mode of encryption. At this stage, XTS is a more modern mode with more technical advantages, but has undergone less cryptographic testing than say CBC.
One point to note with XTS, from wikipedia:
Because of the splitting, users wanting AES 256 and AES 128 encryption will need to choose key sizes of 512 bits and 256 bits respectively.
Care needs to be chosen generating key sizes with this mode such that each block uses a key of the desired bit size. I have not looked at the LUKS information to see how it, or cryptsetup, divide up its keys; this may be something you wish to do to ensure you have the correct level of security you desire. As such, following your guide, 256-bit encryption has been used per block (with the 512 key split into two parts).
Most preferable cipher is aes-xts-plain64
and it is used distro wide (RedHat, CentOS, Oracle Linux, Ubuntu) by default. Most of the people use AES
because lots of the appliance, application support it and the performance of AES
can be accelerated on Intel Processor. And this kind of acceleration feature gives AES
a lot of advantages on other ciphers. You can read the performance comparison between Simple implementation of AES
vs Hardware Accelerated AES
here. Another thing to mention that if you use AES
due to its widespread use if there is an attack available on the internet you will know about it fast and you probably will get an update/patch fast. There are some passive attacks available on the implementation of AES
as disk encryption which you can read from here.
But your choice can be different. And while choosing the cipher you just have to make sure that the cipher you choose is not compromised yet. You can check it from here. There are other similar ciphers available which's are not efficient (from i/o perspective) like AES
but good alternatives. If you are not planning to use AES
then there are two successors of AES
which's are secure than AES
is Anubis and Serpent if you are preparing to sacrifice speed for security.
Fortunately, you can use them in LUKS
. And if you want to encrypt some data for compliance than AES
is enough I guess because AES
is preferred in FISMA
and NIST-Special-Publication-800-53-Revision-4.
For LUKS
, with an encryption algorithm, you should be serious about the hashing algorithm, in my opinion. If you use a weak hash than your super-secure algorithm won't help you much. Because hashing plays a vital part in LUKS
encryption process. So you shouldn't use sha1
and other weak hashing algorithms. But sha512
is secure enough. But you can also use whirepool or the winner of recent password hashing competition argon2i.
From my other answer about LUKS
,
You can list the ciphers supported by your kernels with the following command,
[root@arif]# ls /lib/modules/$(uname -r)/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
![](../../users/profiles/95272.webp)
- 1,088
- 13
- 24
-
1Rather that listing out modules files, you should consult `/proc/crypto` as not all of them are implemented in separate modules, some are in the kernel itself. `sed -nre '/^name/{N;N;/module +: +kernel/p}' /proc/crypto` – Huckle May 19 '20 at 20:15
As mentioned on your original post on SU, for most purposes, the level of security required should be enough that an attacker has no reasonable chance of breaking it in a useful timeframe (eg for your personal data, you might want that to be a 10 year span).
So in this example assuming you don't have national secrets or sensitive corporate data on your PC, AES-XTS-PLAIN is expected to be resistant for a reasonable timeframe against an attacker.
![](../../users/profiles/485.webp)
- 61,367
- 12
- 115
- 320
-
1And what if you have national secrets or sensitive corporate data? What do you recommend? – Dominik Jan 21 '19 at 13:36
-
1@Dominik - that's a whole separate question, and it becomes much more of an opinion based piece. But you would use stronger ciphers, plus physical controls plus etc... Each country tends to have their own specific requirements, that may or may not be made public. – Rory Alsop Jan 21 '19 at 13:44