[personal profile] mjg59
Here's an article from a French anarchist describing how his (encrypted) laptop was seized after he was arrested, and material from the encrypted partition has since been entered as evidence against him. His encryption password was supposedly greater than 20 characters and included a mixture of cases, numbers, and punctuation, so in the absence of any sort of opsec failures this implies that even relatively complex passwords can now be brute forced, and we should be transitioning to even more secure passphrases.

Or does it? Let's go into what LUKS is doing in the first place. The actual data is typically encrypted with AES, an extremely popular and well-tested encryption algorithm. AES has no known major weaknesses and is not considered to be practically brute-forceable - at least, assuming you have a random key. Unfortunately it's not really practical to ask a user to type in 128 bits of binary every time they want to unlock their drive, so another approach has to be taken.

This is handled using something called a "key derivation function", or KDF. A KDF is a function that takes some input (in this case the user's password) and generates a key. As an extremely simple example, think of MD5 - it takes an input and generates a 128-bit output, so we could simply MD5 the user's password and use the output as an AES key. While this could technically be considered a KDF, it would be an extremely bad one! MD5s can be calculated extremely quickly, so someone attempting to brute-force a disk encryption key could simply generate the MD5 of every plausible password (probably on a lot of machines in parallel, likely using GPUs) and test each of them to see whether it decrypts the drive.

(things are actually slightly more complicated than this - your password is used to generate a key that is then used to encrypt and decrypt the actual encryption key. This is necessary in order to allow you to change your password without having to re-encrypt the entire drive - instead you simply re-encrypt the encryption key with the new password-derived key. This also allows you to have multiple passwords or unlock mechanisms per drive)

Good KDFs reduce this risk by being what's technically referred to as "expensive". Rather than performing one simple calculation to turn a password into a key, they perform a lot of calculations. The number of calculations performed is generally configurable, in order to let you trade off between the amount of security (the number of calculations you'll force an attacker to perform when attempting to generate a key from a potential password) and performance (the amount of time you're willing to wait for your laptop to generate the key after you type in your password so it can actually boot). But, obviously, this tradeoff changes over time - defaults that made sense 10 years ago are not necessarily good defaults now. If you set up your encrypted partition some time ago, the number of calculations required may no longer be considered up to scratch.

And, well, some of these assumptions are kind of bad in the first place! Just making things computationally expensive doesn't help a lot if your adversary has the ability to test a large number of passwords in parallel. GPUs are extremely good at performing the sort of calculations that KDFs generally use, so an attacker can "just" get a whole pile of GPUs and throw them at the problem. KDFs that are computationally expensive don't do a great deal to protect against this. However, there's another axis of expense that can be considered - memory. If the KDF algorithm requires a significant amount of RAM, the degree to which it can be performed in parallel on a GPU is massively reduced. A Geforce 4090 may have 16,384 execution units, but if each password attempt requires 1GB of RAM and the card only has 24GB on board, the attacker is restricted to running 24 attempts in parallel.

So, in these days of attackers with access to a pile of GPUs, a purely computationally expensive KDF is just not a good choice. And, unfortunately, the subject of this story was almost certainly using one of those. Ubuntu 18.04 used the LUKS1 header format, and the only KDF supported in this format is PBKDF2. This is not a memory expensive KDF, and so is vulnerable to GPU-based attacks. But even so, systems using the LUKS2 header format used to default to argon2i, again not a memory expensive KDFwhich is memory strong, but not designed to be resistant to GPU attack (thanks to the comments pointing out my misunderstanding here). New versions default to argon2id, which is. You want to be using argon2id.

What makes this worse is that distributions generally don't update this in any way. If you installed your system and it gave you pbkdf2 as your KDF, you're probably still using pbkdf2 even if you've upgraded to a system that would use argon2id on a fresh install. Thankfully, this can all be fixed-up in place. But note that if anything goes wrong here you could lose access to all your encrypted data, so before doing anything make sure it's all backed up (and figure out how to keep said backup secure so you don't just have your data seized that way).

First, make sure you're running as up-to-date a version of your distribution as possible. Having tools that support the LUKS2 format doesn't mean that your distribution has all of that integrated, and old distribution versions may allow you to update your LUKS setup without actually supporting booting from it. Also, if you're using an encrypted /boot, stop now - very recent versions of grub2 support LUKS2, but they don't support argon2id, and this will render your system unbootable.

Next, figure out which device under /dev corresponds to your encrypted partition. Run

lsblk

and look for entries that have a type of "crypt". The device above that in the tree is the actual encrypted device. Record that name, and run

sudo cryptsetup luksHeaderBackup /dev/whatever --header-backup-file /tmp/luksheader

and copy that to a USB stick or something. If something goes wrong here you'll be able to boot a live image and run

sudo cryptsetup luksHeaderRestore /dev/whatever --header-backup-file luksheader

to restore it.

(Edit to add: Once everything is working, delete this backup! It contains the old weak key, and someone with it can potentially use that to brute force your disk encryption key using the old KDF even if you've updated the on-disk KDF.)

Next, run

sudo cryptsetup luksDump /dev/whatever

and look for the Version: line. If it's version 1, you need to update the header to LUKS2. Run

sudo cryptsetup convert /dev/whatever --type luks2

and follow the prompts. Make sure your system still boots, and if not go back and restore the backup of your header. Assuming everything is ok at this point, run

sudo cryptsetup luksDump /dev/whatever

again and look for the PBKDF: line in each keyslot (pay attention only to the keyslots, ignore any references to pbkdf2 that come after the Digests: line). If the PBKDF is either "pbkdf2" or "argon2i" you should convert to argon2id. Run the following:

sudo cryptsetup luksConvertKey /dev/whatever --pbkdf argon2id

and follow the prompts. If you have multiple passwords associated with your drive you'll have multiple keyslots, and you'll need to repeat this for each password.

Distributions! You should really be handling this sort of thing on upgrade. People who installed their systems with your encryption defaults several years ago are now much less secure than people who perform a fresh install today. Please please please do something about this.
Page 1 of 2 <&lt [1] [2] >&gt

Thanks for the heads up!

Date: 2023-04-18 01:57 am (UTC)
ext_1793530: (Default)
From: [identity profile] unixbhaskar.wordpress.com
My external backup drive is LUKS protected ...time to look in.

systemd-cryptenroll

Date: 2023-04-18 04:00 am (UTC)
From: (Anonymous)

I use systemd-cryptenroll for TPM–based automatic unlock. I’m sure doing so is a bad idea for many reasons, but regardless, I noticed the LUKS keyslot that systemd-cryptenroll creates is hardcoded to pbkdf2.

Indeed, looking at the source, it appears this decision was made because the author “found the Wikipedia entry relevant”:

  • https://github.com/systemd/systemd/blob/25d9c6cdaf82d3f627db92b69f3be3e2a68e06fa/src/cryptenroll/cryptenroll-tpm2.c#L182
  • https://github.com/systemd/systemd/blob/25d9c6cdaf82d3f627db92b69f3be3e2a68e06fa/src/shared/tpm2-util.c#L3068

Re: systemd-cryptenroll

From: (Anonymous) - Date: 2023-04-18 07:29 am (UTC) - Expand

Re: systemd-cryptenroll

From: (Anonymous) - Date: 2023-04-18 07:55 am (UTC) - Expand

Re: systemd-cryptenroll

From: [identity profile] romanticboy.livejournal.com - Date: 2023-11-25 12:44 am (UTC) - Expand

Re: systemd-cryptenroll

From: (Anonymous) - Date: 2023-04-18 07:48 pm (UTC) - Expand

Argon2i is memory hard

Date: 2023-04-18 04:00 am (UTC)
From: (Anonymous)

systems using the LUKS2 header format used to default to argon2i, again not a memory expensive KDF.

Argon2 is parameterized by CPU cost, memory cost, and parallelization factor. You can read more at https://github.com/P-H-C/phc-winner-argon2, but Argon2 is memory hard, which includes Argon2i, Argon2d, and the hybrid Argon2id.

Re: Argon2i is memory hard

Date: 2023-04-18 03:19 pm (UTC)
From: (Anonymous)

Yeah, I saw this submitted on Lobsters and /r/crypto, and went a bit angry and impolite there.

The only way Argon2i is not memory hard would be a new attack I’m not aware of. The author needs to cite their source here. Because whether they’re right or wrong this is kind of important.

Date: 2023-04-18 04:38 am (UTC)
From: (Anonymous)
His encryption password was supposedly greater than 20 characters and included a mixture of cases, numbers, and punctuation

So that's at least 64^20 = 2^120 variants. I call bullshit on brute-forcing. There was some kind of opsec failure.

(no subject)

From: (Anonymous) - Date: 2023-04-18 06:57 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2023-04-18 10:23 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2023-04-18 05:19 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2023-04-19 12:20 am (UTC) - Expand

the problem is the password

From: (Anonymous) - Date: 2023-05-06 12:04 pm (UTC) - Expand

PKBDF2

Date: 2023-04-18 06:52 am (UTC)
From: (Anonymous)

Unfortunately, PBKDF2 is still the only KDF approved by NIST. While this doesn't affect home users, companies that are required to comply with US government regulations are stuck with PBKDF2 for now. Yet another case where NIST's regulations eventually yield questionable security...

Date: 2023-04-18 08:09 am (UTC)
From: (Anonymous)
Thank you for this writeup, it is obviously quite important and hitting the waves.

That said, as a PSA it is not very good. Consider adding a TL;DR or summary. Few people will actually reach the bottom as it's quite a bit of introduction.

"Delete this backup"

Date: 2023-04-18 08:36 am (UTC)
From: (Anonymous)
Hi Matthew,
You mention to delete the luksHeader backup, but you don't mention it should be deleted using wipe(1).

HTH,
Colin

Re: "Delete this backup"

Date: 2023-04-18 09:35 am (UTC)
From: (Anonymous)
what use do you find for wipe on (1) ramdisk, (2) non-spinning-rust, (3) encrypted spinning rust?

Re: "Delete this backup"

From: (Anonymous) - Date: 2023-04-18 11:30 am (UTC) - Expand

Re: "Delete this backup"

From: (Anonymous) - Date: 2023-04-18 02:14 pm (UTC) - Expand

Re: "Delete this backup"

From: (Anonymous) - Date: 2023-04-18 05:58 pm (UTC) - Expand

Re: "Delete this backup"

From: (Anonymous) - Date: 2023-04-19 08:01 am (UTC) - Expand

Re: "Delete this backup"

From: (Anonymous) - Date: 2023-06-22 12:18 am (UTC) - Expand

Changing KDF of digest

Date: 2023-04-18 11:32 am (UTC)
From: (Anonymous)
Hi mjg,

thanks for this helpful post.

I have successfully changed the KDF to argon2id for my keyslots, however, the digest is still using pbkdf2:

Digests:
0: pbkdf2
Hash: sha256
Iterations: 149114
Salt: xxx
Digest: xxx

Is this a security issue? Is is possible to change this to argon2id as well?

Re: Changing KDF of digest

From: (Anonymous) - Date: 2023-10-01 09:08 pm (UTC) - Expand

Date: 2023-04-18 11:59 am (UTC)
From: (Anonymous)
A password of 20 random ASCII characters has more than 130 bits of entropy. Such a password cannot be cracked, even if MD5 is used. His password either was not random at all, or someone stole it from him (keylogger, note etc.).

By the way SHA2 is not really slower than MD5 at all. It is even designed to be fast. The cracking of passwords is hard because of the exponential search space, not because of the algorithm speed. 128 bits are impossible to brute force, so even MD5 is safe in this regard. It is vulnerable to collision attacks, but that does not help with password cracking.

Because of this, KDF slowdown is snakeoil for many applications. The complexity of the password is more important than the slowdown of the KDF function. However, it makes a practical difference so your recommendations are still valid for disk and file encryption.

(no subject)

From: (Anonymous) - Date: 2024-03-25 07:02 am (UTC) - Expand

Initrd

Date: 2023-04-18 12:16 pm (UTC)
From: (Anonymous)
Gentle reminder that initrds are not authenticated at the moment. It's also possible that some software on the machine was insecure (installed on the side or not updated; I doubt they used otherwise unknown issues since they're expensive).

It's pretty likely the group of people in this has been infiltrated at some point, or simply that the places have been for a few minutes at least Evil maid attacks are fairly quick to conduct when the target is simply the initrd.

Re: Initrd

Date: 2023-04-19 08:31 am (UTC)
From: (Anonymous)
If /boot is encrypted, the initrd should not be accessible to be replaced/tampered with.
If Secure Boot is enabled, then grubx64.efi/shimx64.efi will fail if replaced/tampered with.

If the pass-string has sufficient degrees of freedom, a 'weak' key derivation function is not relevant.

Like others, I think OPSEC failure is more likely than technical failure. Good OPSEC is difficult.

Separate header

Date: 2023-04-18 12:34 pm (UTC)
From: (Anonymous)
I always have the header separated from the disks especially when I'm travelling. You can put the headers on some cloud or web server, even maybe as an "addon" to an image etc. They are small, you can always download them from anywhere when you need 'em. At least this makes travelling way easier, no keys, no headers, no questions. Looks like an empty disk. You can always say: I bought the disk/laptop/whatsoever some days ago, haven't used that part of the disk yet...

But anyway, it's always better to see if there's a way to break the encryption. So, thank you for this real good article, I guess, I will start converting the next days...

Re: Separate header

Date: 2023-04-18 01:15 pm (UTC)
From: (Anonymous)
Hi there !
Interested in what you said.
How can I remove the header so the disk looks empty ?

Re: Separate header

From: (Anonymous) - Date: 2023-04-18 02:45 pm (UTC) - Expand

Re: Separate header

From: (Anonymous) - Date: 2023-04-18 08:03 pm (UTC) - Expand

Re: Separate header

From: (Anonymous) - Date: 2023-04-18 03:24 pm (UTC) - Expand

Re: Separate header

From: (Anonymous) - Date: 2023-04-19 01:33 pm (UTC) - Expand

Re: Separate header

From: (Anonymous) - Date: 2023-04-18 04:31 pm (UTC) - Expand

Re: Separate header

From: (Anonymous) - Date: 2023-04-19 01:52 am (UTC) - Expand

Re: Separate header

From: (Anonymous) - Date: 2023-04-19 07:29 am (UTC) - Expand

Re: Separate header

From: (Anonymous) - Date: 2023-04-19 08:07 am (UTC) - Expand

Works for me

Date: 2023-04-18 12:59 pm (UTC)
From: (Anonymous)
Thank you ! Following your step-by-step guide I successfully converted my disk to LUKS2/argon2id.
From: (Anonymous)
Is it possible that current openSUSE ships archaic bits of LUKS1 only?

Is it very much possible that funny de_DE folks at openSUSE ship archaic LUKS1 bits only? they never heard of argon and fancy year old and well aged means such as argon?

Very odd distro they have in the dark old world?
Guess they being left less protected. Who needs protection in dark middle ages of old Yurop anyways?
From: (Anonymous)
At least Opensuse Tumbleweed offers LUKS2. Some of the others like LEAP might not.

https://en.opensuse.org/SDB:LUKS2,_TPM2_and_FIDO2

Re: Is it possible that current openSUSE ships archaic bits of LUKS1 only?

From: (Anonymous) - Date: 2023-05-18 12:19 pm (UTC) - Expand

Date: 2023-04-18 03:39 pm (UTC)
From: (Anonymous)
After following these instructions, is it necessary to refresh the backups of the luks headers? I assume yes, and perhaps this should be mentioned in the tutorial?

GPU attacks against passwords

Date: 2023-04-18 03:41 pm (UTC)
From: (Anonymous)
While I understand that passwords are a weakness in computer security, I'm not sure that memory hardened KDF is the solution. Let's see a demonstration of a GPU cracking a sensible password protected by PBKDF2. Since we don't have money to spend, a simple cracks/second measurement and estimate of cost/time based on the algorithm would suffice.

Date: 2023-04-18 04:29 pm (UTC)
From: (Anonymous)
I would also like to add, governments/authorities also has their paws in many pieces of software now and can take over your machine with them. discord, steam, nord vpn client to name a few, any software company is friendly to the government you have on your pc is intentionally a back door. Imagine they got onto his network and pushed a telegram client upgrade that also contained a keylogger. bam they have your luks container key. But they wont reveal that to the public its supposed to be a secret.

They will say in court they cracked it instead.

Keep your network secure, and be careful about apps. even trusted ones like signal, the authorities can push their own client that is a trojan. I had this happen to me.

Once they are on your network. all sorts of man in the middle attacks can be tailored to your operating system and software used.

Date: 2023-04-20 04:21 pm (UTC)
From: (Anonymous)
This is a particularly salient point. Programs like web browsers are near as well constantly having previously existing zero-days reported, and each of these will translate into keylogging access on any X11 server the program is connected to. (Why X11 still permits full keyboard keystate polling when a client's particular window isn't focused is a conspiracy-worthy mystery on its own.)

Encryption is only as good as the user's opsec. If a password is being typed through the X server, it may be assumed that it has already been transmitted to an interested party of choice. For example: how many of us don't practice the boot partition passphrase a few tens of times in order to commit it to memory? There's even a --test-passphrase option in cryptsetup which enables just that. How many of us switch to the console, perhaps also kill the X server first, before doing that?

Thirdly, assuming keyloggers, the French security apparatus can just as easily present materials as supposedly haxxed from their target's computers when said materials were actually captured as they were typed. The custody chain is generally not very solid, nor its judicial requirements very strict, in "political" cases.

(no subject)

From: (Anonymous) - Date: 2023-04-22 12:53 am (UTC) - Expand

FIDO2 tokens?

Date: 2023-04-18 05:59 pm (UTC)
From: (Anonymous)
If you have an enrolled hardware token, such as a Yubikey, should you still take care of also updating the PBKDF for the slot linked to the token? If I got the article right, the key itself is already a rate-limiting factor for brute force attacks, right?

If not, how to do so? I found no way looking at the manpage.

Date: 2023-04-18 08:11 pm (UTC)
From: (Anonymous)
Although I support the main message "update your header to a state or the art KDF", think you are not making the community a good service here.

Where is the indication that this was an attack against the KDF? For all we know they could have found a bug in the LUKS implementation.

Or much more realistically this was just an evil maid attack, or somebody got his password via "non-technical" means like filming him typing it in a cafe.
From: (Anonymous)
This might be the reason why $distributions do not / cannot upgrade to luks2 type and anything else than pbkdf2.

https://wiki.archlinux.org/title/GRUB#LUKS2
From: (Anonymous)
Booting the *kernel* from an unencrypted /boot allows use of LUKS2 and anything it supports, since the Linux kernel is then in charge of unlocking the rest of the volumes.

Re: Beware upstream GRUB does not support argon2i / argon2id

From: (Anonymous) - Date: 2023-04-18 10:07 pm (UTC) - Expand

Re: Beware upstream GRUB does not support argon2i / argon2id

From: (Anonymous) - Date: 2023-04-19 01:34 pm (UTC) - Expand

Date: 2023-04-18 10:32 pm (UTC)
From: (Anonymous)
For what it's worth a test with the Ubuntu 22.04 amd64 desktop ISO, choosing the encrypt-disk option at installation, seems to do the right thing: Version = 2 and PBKDF = argon2id.

Date: 2023-04-19 02:11 am (UTC)
From: (Anonymous)
Hmm, this conversion process is kind of a pain to do on a system with encrypted root, since the conversion from LUKS version 1 to 2 refuses to run when the device is in use. I suppose I'm going to have to either do the conversion from an initramfs or by pulling the drive.

Date: 2023-04-19 07:39 am (UTC)
From: (Anonymous)
I would assume that booting any live installation ISO would also allow you to run cryptsetup on your internal drive.

(no subject)

From: (Anonymous) - Date: 2023-04-29 04:16 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2024-03-29 09:28 am (UTC) - Expand

Date: 2023-04-19 08:13 am (UTC)
From: (Anonymous)

Something in your analysis doesn't add up.

His encryption password was supposedly greater than 20 characters and included a mixture of cases, numbers, and punctuation

Unfortunately it's not really practical to ask a user to type in 128 bits of binary every time they want to unlock their drive

The user had ~128 bits of entropy. The alphabet they were using consists of 72 characters (26 lower case, 26 upper case, 10 numbers, 10 special characters). Their password length was at least 20. This comes out to log(72**20, 2) = 123 bits of entropy. This much entropy is uncrackable. Unless there is a weakness in AES. The entropy is so high that no key derivation function is needed at all. Key derivation functions are useful to improve weak passwords, not strong ones.

If the password was cracked then it was much weaker than the user claimed (maybe unknowingly). Maybe their password was not very random. Or it was not cracked at all and they got the password through other means.

(The recommendation to upgrade the key derivation function is still good.)

Date: 2023-04-19 08:21 am (UTC)
From: (Anonymous)
I see this has been addressed in other comments already by you. Sorry for not reading all of them. Still I feel this deserves a note in your post when you mention the entropy.

(no subject)

From: (Anonymous) - Date: 2023-04-19 01:00 pm (UTC) - Expand

Date: 2023-04-19 02:15 pm (UTC)
From: (Anonymous)

I don't think this is the correct takeaway from the situation. * What matters is not the length of the password ("20 characters") or included character groups ("letters, digits and symbols"), but its entropy. In particular, obfuscating a word with some digits or symbols does not really gain much. * A slow or memory-hard key derivation function is a band-aid, not a fix. Making hashing harder slows down the attacker linearly. Choosing a longer passphrase slows them down exponentially. * The victim used "Ubuntu 18". This is quite an old distribution and while still in extended support, many packages are not receiving proper security patches any more (IIRC, only "main" is fully supported, while the situation in "universe" is quite bad). It is quite likely that the machine was compromised at runtime.

So my takeaway would be: * Use a proper passphrase. The diceware method with 10 words is a good choice, giving you slightly more than 128 bits of entropy. The KDF does not matter than, it could even be a simple SHA-2. * Always use well-supported software, and do not skip updates. Do not install unneeded software, particularly on machines processing high-risk data. * In addition, make hardware-based attacks harder, particularly if you're a member of a vulnerable group. Check that nobody is watching you while entering the passphrase. Do not leave your computer unattended, especially when turned on or in suspend-to-RAM. Only buy computers in person, and do not use computers returned from police.

Unlikely to be brute forced

Date: 2023-04-20 02:35 am (UTC)
From: (Anonymous)
It's more likely the passphrase/crack was obtained by other means than bruteforcing.

A 21 character password with upper+lower case, numbers and popular punctuation has about 65^21 combinations.

Sure attackers can use many GPUs. Say you have 1 million devices that do 600 million SHA256 per second.

Say pbkdf2 with "only" 10,000 rounds of sha256.

65^21 x 10000 / (1 million x 600 million) seconds = 6.22206506 × 10^19 years. Sure in theory you'd probably might find it less than 50% of the way through but in practice you're going to use a different method.

Thus I doubt the problem was with pbkdf2 and I suspect this article is a distraction from the actual methods used/vulnerability exploited.

Date: 2023-04-20 06:17 am (UTC)
From: (Anonymous)
Hm, but why recent cryptsetup on luksOpen doesn't even warn that insecure variant is used and ask to upgrade?

Date: 2023-04-20 07:07 am (UTC)
From: (Anonymous)
The discussion in the comments shows that the stated "insecurity" of PBKDF2 is at least debatable.

Also: Changing from PBKDF2 to Argon would prevent default GRUB from unlocking and booting an encrypted system.
Page 1 of 2 <&lt [1] [2] >&gt

Profile

Matthew Garrett

About Matthew

Power management, mobile and firmware developer on Linux. Security developer at Aurora. Ex-biologist. [personal profile] mjg59 on Twitter. Content here should not be interpreted as the opinion of my employer. Also on Mastodon.

Page Summary

Expand Cut Tags

No cut tags