Jump to content

LUKS/Advanced: Difference between revisions

From FASSAG Wiki
mNo edit summary
reworked this page
Line 4: Line 4:


= Guide to Decent LUKS Security on Linux =
= Guide to Decent LUKS Security on Linux =
The Main Page gives a high level overview of what different LUKS options can do, but this page intends to go into as much detail as possible about them while still aiming to be easy to understand. If you just want to know the "best" [[command]] to run, you can skip to the bottom. But reading this Guide 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!
The Intermediate Guide gives a high level overview of what different LUKS options can do, but this page intends to go into as much detail as possible about them while still aiming to be easy to understand. If you just want to know the "best" [[command]] to run, you can skip to the bottom. But reading this Guide 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!


== Ciphers ==
== Ciphers ==
Line 11: Line 11:
Of the widely supported options, the two most worth considering are [[Serpent]] and [[AES]].  
Of the widely supported options, the two most 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.
[[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 .
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.
Another consideration is the actual [[implementation]]. Serpent has potential [[Vulnerability|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, almost always not x86, do not have hardware accelerated AES. It's also possible that your CPU may have a vulnerability, so that's something you may want to look into. As far as we are aware though, no vulnerabilities have been reported on any present or past chip with AES support. Practically speaking, the advantages of having hardware accelerated AES make it more secure than using Serpent in nearly all cases.
On the other hand, having [[hardware acceleration]] for AES has a number of advantages for security, most notably resistance to [[Side-channel attack|side-channel attacks]], but of course also speed. Some [[CPU|CPUs]] however, usually CPUs that aren't x86 based, do not have hardware accelerated AES. While it's theoretically possible that your CPU may have a vulnerability, as far as we are aware, no vulnerabilities have been reported on any present or past chip with AES support. Make sure your [[microcode]] is up to date! Practically speaking, the advantages of having hardware accelerated AES make it more secure than using Serpent in nearly all cases.


== On-disk Format ==
== 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 .
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]] is an older on-disk format and should not really be used. It has [[malleability]] vulnerabilities, and also, specially-crafted files can be [[fingerprinted]]. XTS is better at mitigating these issues, so it's the recommended default. It's also hardware accelerated on modern x86 CPUs. If your CPU does not have hardware accelerated AES and XTS, you ''may'' want to use CBC, for better speeds.


== Initialization Vectors ( IV ) ==
== 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 .
The purpose of IV is to add some randomness different blocks of the disk, so that overall patterns cannot be discovered. [[ESSIV]] was previously set as default for CBC to mitigate the fingerprinting issue, but this does not help CBC's issues with malleability. Since XTS has been used, plain64 has been the default. Since XTS is not vulnerable to fingerprinting, it does not need the added overhead of ESSIV.


== Password Hashing ==
== 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 .
The hashing algorithm is intended to make weak passwords harder to break , so a very good password does not really need much hashing. Since it's hard to make ( and remember ) a very secure password, it's still a good idea to hash your password.
 
The best option is generally Argon2, since it is optimized to be impossible to [[Brute-force attack|brute-force]] on devices with limited memory, like [[GPU|GPUs]]. 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 [[Advanced Persistent Threat|APT]] trying to decrypt your data, it is a pretty good tradeoff.  
 
Argon2 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. Similarly, 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.
 
If your device is very memory constrained (like under 4GB), you ''may'' want to consider using PBKDF2 instead. You will want to increase the iteration time as high as you can tolerate, as it is far weaker to GPU brute-forcing.  


== Iteration Time ==
== 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 .
This defines how long your computer is going to spend hashing the password. More iteration is better, and it's just a question of how long you are willing to spend waiting for your computer to has your password. If your password is very insecure though, a long has will not slow down an attacker much. 2 seconds ( 2000ms ) is the recommended default. 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 !
See the [[Password]] Guide for more information about making a secure password.


== Benchmarking ==
== Benchmarking ==
If you want to see for yourself how fast these various algorithms will run on your computer, you can use <code>cryptsetup benchmark .</code>
If you want to see for yourself how fast these various algorithms will run on your computer, you can use <code>cryptsetup benchmark</code>.
  <code># Tests are approximate using memory only (no storage IO).</code>
  <code># Tests are approximate using memory only (no storage IO).</code>
  <code>PBKDF2-sha1      1736052 iterations per second for 256-bit key</code>
  <code>PBKDF2-sha1      1736052 iterations per second for 256-bit key</code>
Line 43: Line 49:
  <code>argon2i       4 iterations, 735656 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)</code>
  <code>argon2i       4 iterations, 735656 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)</code>
  <code>argon2id      4 iterations, 842046 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)</code>
  <code>argon2id      4 iterations, 842046 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)</code>
  <code>    Algorithm |       Key |      Encryption |      Decryption</code>
  <code>    Algorithm |       Key |      Encryption |      Decryption</code>[[entropy]]
  <code>      aes-cbc        128b       594.1 MiB/s      1434.3 MiB/s</code>
  <code>      aes-cbc        128b       594.1 MiB/s      1434.3 MiB/s</code>
  <code>  serpent-cbc        128b        59.8 MiB/s       371.1 MiB/s</code>
  <code>  serpent-cbc        128b        59.8 MiB/s       371.1 MiB/s</code>
Line 56: Line 62:
  <code>  serpent-xts        512b       445.2 MiB/s       437.6 MiB/s</code>
  <code>  serpent-xts        512b       445.2 MiB/s       437.6 MiB/s</code>
  <code>  twofish-xts        512b       221.9 MiB/s       249.3 MiB/s</code>
  <code>  twofish-xts        512b       221.9 MiB/s       249.3 MiB/s</code>
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 <code>-i 5000</code> to test 5000ms as an example , to see how many iterations it achieves .
As you can see from this sample output, <code>aes-xts</code> 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 <code>-i 5000</code> to test 5000ms as an example, to see how many iterations it achieves.


== /dev/urandom ==
== [[Entropy]] ==
Though unlikely , to avoid an entropy-starved situation ( meaning the random numbers are not random enough ) , you can use <code>--use-random</code> when setting up the disk .
Though unlikely, to avoid an [[Entropy Starvation|entropy starved]] situation, you can use <code>--use-random</code> 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 .
There's a lot of debate and conflicting information online about the difference between <code>/dev/random</code> and <code>/dev/urandom</code> online. The main difference is that <code>/dev/random</code> will wait until it detects 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 =
An easy way to ensure you have enough entropy, is to gather it from an external source. For example, you can run: <code>curl -Ss <nowiki>https://www.random.org/cgi-bin/randbyte?nbytes=16384&format=f</nowiki> > /dev/random</code>. This command gathers random bytes from [https://random.org random.org]. Using an external source like this is ok, since Linux has ways to gather entropy besides this that an attacker would not be able to replicate.
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 ==
== Disk Setup ==
Assuming you know what partition you want to use, setting up the disk is as simple as :
Assuming you know what partition you want to use, setting up the disk is as simple as:


<code>cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --hash sha256 --iter-time 2000 --key-size 256 --pbkdf argon2id --use-random --verify-passphrase /dev/YOURPARTITIONHERE</code>
<code>cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --hash sha256 --iter-time 2000 --key-size 256 --pbkdf argon2id --use-random --verify-passphrase /dev/YOURPARTITIONHERE</code>


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 :
As mentioned previously, these settings are the default on the latest cryptsetup (with the exception of <code>--use-random</code>). Setting them manually ensures that they are correct on older versions. You can check what the defaults are for your system by running <code>cryptsetup --help</code>. You can then verify that it was setup correctly with:


<code>cryptsetup luksDump /dev/YOURPARTITIONHERE</code>
<code>cryptsetup luksDump /dev/YOURPARTITIONHERE</code>


Once it has been setup , it can be opened with :
Once it has been setup, it can be opened with:


<code>cryptsetup open /dev/YOURPARTITIONHERE dm_name</code>
<code>cryptsetup open /dev/YOURPARTITIONHERE dm_name</code>


Note that " dm_name " can be set to whatever you like , and the disk will be available at :
Note that "dm_name" can be set to whatever you like, and the disk will be available at:


<code>/dev/mapper/dm_name</code>
<code>/dev/mapper/dm_name</code>


Then you will need to format it , via something like :
Then you will need to format it, via something like:


<code>mkfs.ext4 /dev/mapper/dm_name</code>
<code>mkfs.ext4 /dev/mapper/dm_name</code>
Of course , you'll want to replace mkfs.ext4 with the setup command for your preferred partition type .

Revision as of 01:20, 1 July 2026

This is currently a draft. It has not yet been completed.

This is an Advanced complexity guide. All versions:

For more more info on this topic, check the cryptsetup FAQ, the Arch Wiki.

Guide to Decent LUKS Security on Linux

The Intermediate Guide gives a high level overview of what different LUKS options can do, but this page intends to go into as much detail as possible about them while still aiming to be easy to understand. If you just want to know the "best" command to run, you can skip to the bottom. But reading this Guide 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!

Ciphers

Ciphers are the algorithms used to encrypt data. Picking the best algorithm is very important for ensuring your data is secure. If your cipher can be broken, then your data can be accessed without the key.

Of the widely supported options, the two most 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, but of course also speed. Some CPUs however, usually CPUs that aren't x86 based, do not have hardware accelerated AES. While it's theoretically possible that your CPU may have a vulnerability, as far as we are aware, no vulnerabilities have been reported on any present or past chip with AES support. Make sure your microcode is up to date! Practically speaking, the advantages of having hardware accelerated AES 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 is an older on-disk format and should not really be used. It has malleability vulnerabilities, and also, specially-crafted files can be fingerprinted. XTS is better at mitigating these issues, so it's the recommended default. It's also hardware accelerated on modern x86 CPUs. If your CPU does not have hardware accelerated AES and XTS, you may want to use CBC, for better speeds.

Initialization Vectors ( IV )

The purpose of IV is to add some randomness different blocks of the disk, so that overall patterns cannot be discovered. ESSIV was previously set as default for CBC to mitigate the fingerprinting issue, but this does not help CBC's issues with malleability. Since XTS has been used, plain64 has been the default. Since XTS is not vulnerable to fingerprinting, it 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. Since it's hard to make ( and remember ) a very secure password, it's still a good idea to hash your password.

The best option is generally Argon2, since it is optimized to be impossible to brute-force on devices with limited memory, like GPUs. 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 decrypt your data, it is a pretty good tradeoff.

Argon2 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. Similarly, 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.

If your device is very memory constrained (like under 4GB), you may want to consider using PBKDF2 instead. You will want to increase the iteration time as high as you can tolerate, as it is far weaker to GPU brute-forcing.

Iteration Time

This defines how long your computer is going to spend hashing the password. More iteration is better, and it's just a question of how long you are willing to spend waiting for your computer to has your password. If your password is very insecure though, a long has will not slow down an attacker much. 2 seconds ( 2000ms ) is the recommended default. 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.

See the Password Guide for more information about making a secure password.

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 |      Decryptionentropy
      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.

Though unlikely, to avoid an entropy starved situation, you can use --use-random when setting up the disk.

There's 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 until it detects 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.

An easy way to ensure you have enough entropy, is to gather it from an external source. For example, you can run: curl -Ss https://www.random.org/cgi-bin/randbyte?nbytes=16384&format=f > /dev/random. This command gathers random bytes from random.org. Using an external source like this is ok, since Linux has ways to gather entropy besides this that an attacker would not be able to replicate.

Disk Setup

Assuming you know what partition you want to use, 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). Setting them manually ensures that they are correct on older versions. You can 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