LUKS
THIS PAGE IS A DRAFT ! Information on this page is in need of further research and refinement !
This page will need to be split into " difficulty teirs " and since it's the first page this has been needed on , it makes it an excellent test subject to figure out the best way to do so .
Beginners Guide to Decent LUKS Security on Linux
If you just want to know the " best " command to run , you can skip to the bottom . But reading this post is encouraged , as it will give you a better understand of what the options do , and how they will affect the security of your data !
If you want even more info on this topic , check the cryptsetup FAQ , as good amount of this information is pulled from there !
For more information on how to use LUKS tools , the arch wiki is a great resource .
Ciphers
Ciphers are the algorithms that encrypt the data that will be written to the disk . Picking one that is resistant to attacks is critical , as otherwise your data is potentially vulnerable , even without the key .
Of the widely supported options , generally the two worth considering are Serpent and AES . Twofish may be better in lower-security applications where there's no AES acceleration and writes happen more often than reads , but generally , not a great option .
Serpent may theoretically be more secure , though in practice its potential advantages seem pretty minimal . It also hasn't been tested as much as AES , so it may have potential vulnerabilities not yet known about .
Another consideration is the actual implementation . Serpent has potential vulnerabilities depending on the details of the implementation . Without looking into the specific implementation in-depth , it's hard to say how secure it is .
On the other hand , having hardware acceleration for AES has a number of advantages for security , most notably resistance to side channel attacks , and of course , speed . Some chips however , ( usually not x86 ) , do not have hardware accelerated AES . It's also possible that your CPU may have a vulnerability , so that's something you want to look into . Not currently aware of anything like this , though some Ryzen chips recently had an AES vulnerability that allowed unauthorized microcode to be installed . To be very clear , this has been patched with a microcode update , and is also not directly relevant to use in disk unlocking . Practically speaking , the advantages of having hardware accelerated AES likely make it more secure than using Serpent in nearly all cases .
On-disk Format
The on-disk format defines how the encrypted data is stored on the disk itself . While you could just write the encrypted blocks directly to the disk , you would be at risk of a number of different attacks . CBC ( Cipher-block chaining ) is an older on-disk format and should not really be used . It has malleability vulnerabilities ( meaning data can be inserted without knowing the encryption key ) , and also , specially-crafted files can be " fingerprinted " , meaning they can be located on the disk . XTS ( XEX-based tweaked-codebook mode with ciphertext stealing ) is better at mitigating these issues , so it's the recommended default . It's also usually hardware accelerated on x86 . XTS does have its own vulnerabilities , but most of these issues can be mitigated by using a filesystem that can verify and repair corrupted data , like ZFS or BTRFS .
Initialization Vectors ( IV )
The purpose of IV is to ad some randomness different blocks of the disk , so that overall patterns cannot be discovered . ESSIV ( Encrypted salt-sector initialization vector ) was set as default for CBC to mitigate the fingerprinting issue , but this does not help CBC's issues with malleability . For XTS , plain64 is recommended over plain , since it has no performance impact , and plain has some data leaking vulnerabilities that are viable on disks larger than 2TiB . XTS not being vulnerable to fingerprinitng , does not need the added overhead of ESSIV .
Password Hashing
The hashing algorithm is intended to make weak passwords harder to break , so a very good password does not really need much hashing . Argon2 is optimized to be impossible to brute-force on devices with limited memory , most notably , graphics cards . The point is to force the attacker to use their CPU , which is not usually not nearly as quick as a GPU for this kind of task . Unless you're primarily concerned about some APT trying to break into your device , it is pretty good tradeoff . If your device is very memory constrained ( like under 4GB ), you may want to consider using PBKDF2 ( Password-Based Key Derivation Function ) . You will almost certainly want to increase the iteration time more though , as it is far weaker to GPU brute-forcing . For a small note on Argon2 , it has a few different variants . Argon2i is weakest to brute-forcing , but has strong side-channel protection . It's generally not safe to use 2i with anything less than 10 iterations . Conversely , while Argon2d is most secure against brute force attacks , it is more susceptible to side channel timing attacks than Argon2id . Unless you are really not concerned about side-channel attacks , Argon2id is the most well rounded and therefore the best choice .
Iteration Time
This defines how long your computer is going to spend hashing the password . More iteration is generally better , and is mostly a question of how long you willing to spend waiting for your computer to initially decrypt the drive . Do note that it doesn't decrease the speed of the drive after the key is decrypted . To be very clear , high iteration count is not an alternative to a secure password ! 2 seconds ( 2000ms ) is generally the recommended default , though of course you are welcome to set it as high as you are willing to tolerate . Make sure your computer is not set to any " low-power mode " when setting up the disk , as this will affect the time it takes to hash .
Very important note ! Make sure your password is secure ! Using something short is a very bad idea . Using a string of characters from a well known book is also not a great idea ! Something like a diceware password with at least 6 words is generally a good idea !
Benchmarking
If you want to see for yourself how fast these various algorithms will run on your computer, you can use cryptsetup benchmark .
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1 1736052 iterations per second for 256-bit key
PBKDF2-sha256 3355443 iterations per second for 256-bit key
PBKDF2-sha512 1096836 iterations per second for 256-bit key
PBKDF2-ripemd160 434733 iterations per second for 256-bit key
PBKDF2-whirlpool 364088 iterations per second for 256-bit key
argon2i 4 iterations, 735656 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id 4 iterations, 842046 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
- Algorithm | Key | Encryption | Decryption
aes-cbc 128b 594.1 MiB/s 1434.3 MiB/s
serpent-cbc 128b 59.8 MiB/s 371.1 MiB/s
twofish-cbc 128b 123.5 MiB/s 200.0 MiB/s
aes-cbc 256b 423.9 MiB/s 1284.2 MiB/s
serpent-cbc 256b 61.0 MiB/s 394.5 MiB/s
twofish-cbc 256b 136.8 MiB/s 240.4 MiB/s
aes-xts 256b 2196.7 MiB/s 2414.8 MiB/s
serpent-xts 256b 445.6 MiB/s 401.0 MiB/s
twofish-xts 256b 220.3 MiB/s 236.9 MiB/s
aes-xts 512b 2031.5 MiB/s 2117.4 MiB/s
serpent-xts 512b 445.2 MiB/s 437.6 MiB/s
twofish-xts 512b 221.9 MiB/s 249.3 MiB/s
As you can see from this sample output , aes-xts is the fastest ! Assuming you're on an x86 machine , this will almost certainly also be the case for you . You'll also notice Argon2i only has 4 iterations here , making it unsafe to use . You can add -i 5000 to test 5000ms as an example , to see how many iterations it achieves .
/dev/urandom
Though unlikely , to avoid an entropy-starved situation ( meaning the random numbers are not random enough ) , you can use --use-random when setting up the disk .
There's apparently a lot of debate and conflicting information online about the difference between /dev/random and /dev/urandom online . The main difference is that /dev/random will wait when it estimates that not enough entropy has been gathered . Since it only affects when you initially setup the disk though , waiting for it to gather enough entropy is generally a good idea . Whether its method of ensuring it has gathered enough data is effective , is also somewhat debated , but it certainly doesn't hurt .
Summary
Unless you have a strong reason to doubt AES-256 ( which is also post-quantum resistant ) , AES should be used . Using CBC even with ESSIV does not have any compelling reasons for consideration , so XTS likely your best choice , especially since it will be significantly faster to encrypt / decrypt on x86 . These options are the default for good reason , and unless you have a particularly special setup or threat model ; like if for example , if your CPU does not have hardware accelerated AES , or if it had a known vulnerability . Lastly , Argon2id is generally your best option for hashing .
Disk Setup
Assuming your disk is already correctly partitioned , setting up the disk is as simple as :
cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --hash sha256 --iter-time 2000 --key-size 256 --pbkdf argon2id --use-random --verify-passphrase /dev/YOURPARTITIONHERE
As mentioned previously , these settings are the default on the latest cryptsetup ( with the exception of --use-random ) , but setting them manually ensures that they are correct on older versions . You can also check what the defaults are for your system by running cryptsetup --help . You can then verify that it was setup correctly with :
cryptsetup luksDump /dev/YOURPARTITIONHERE
Once it has been setup , it can be opened with :
cryptsetup open /dev/YOURPARTITIONHERE dm_name
Note that " dm_name " can be set to whatever you like , and the disk will be available at :
/dev/mapper/dm_name
Then you will need to format it , via something like :
mkfs.ext4 /dev/mapper/dm_name
Of course , you'll want to replace mkfs.ext4 with the setup command for your preferred partition type .