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.
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
-
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
– HuckleCommented May 19, 2020 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.
-
1And what if you have national secrets or sensitive corporate data? What do you recommend?– DominikCommented Jan 21, 2019 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 ♦Commented Jan 21, 2019 at 13:44
-
One major difference is that AES-256 is expected to be secure against quantum computers, where AES-128 is not.– dlitzCommented Mar 21, 2023 at 20:14
plain64
rather thanplain
. The two are identical for volume sizes up to 2 TiB, butplain
can potentially leak data when volume sizes grows beyond 2 TiB whereasplain64
does not. Sinceplain64
is identical toplain
for offsets below the 2 TiB mark, there is no real reason to useplain
in favor ofplain64
. The cryptsetup FAQ has a discussion on this under Are there any problems with "plain" IV? What is "plain64"? (currently section 5.15).