Bug 36264 - systemd-cryptsetup can't open drive with keyfile
Summary: systemd-cryptsetup can't open drive with keyfile
Status: RESOLVED FIXED
Alias: None
Product: systemd
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Lennart Poettering
QA Contact:
URL:
Whiteboard:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2011-04-15 09:30 UTC by Martin Jungmann
Modified: 2011-04-26 12:52 UTC (History)
2 users (show)

See Also:
i915 platform:
i915 features:


Attachments
My solution to the problem. (961 bytes, text/plain)
2011-04-15 09:30 UTC, Martin Jungmann
Details
Proposed patch (not tested!) (1.32 KB, patch)
2011-04-21 04:30 UTC, Milan Broz
Details | Splinter Review

Description Martin Jungmann 2011-04-15 09:30:51 UTC
Created attachment 45676 [details]
My solution to the problem. 

After installing systemd, I noticed that systemd couldn't open my encrypted drives.

I did some research and found a difference between systemd-cryptsetup and normal cryptsetup.
-  Normal cryptsetup called crypt_activate_by_keyfile with opt_key_size == 0
- systemd-cryptsetup called crypt_activate_by_keyfile with opt_key_size == 256

I created a patch so crypt_activate_by_keyfile is called with opt_key_size == 0.

Here are some bash commands to reproduce the problem.

# Preparing the drive
head /dev/urandom -c 512 > /tmp/keyfile
dd if=/dev/zero of=/tmp/thedrive.dat bs=1M count=32
losetup /dev/loop0 /tmp/thedrive.dat
cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/loop0 /tmp/keyfile

# Verification: Can I open it with normal cryptsetup
cryptsetup luksOpen /dev/loop0 mysecretdrive -d /tmp/keyfile
cryptsetup luksClose mysecretdrive

# Problem: I can't open it with systemd-cryptsetup (with output)
/lib/systemd/systemd-cryptsetup attach mysecretdrive /dev/loop0 /tmp/keyfile 
Set cipher aes, mode xts-plain, key size 512 bits for device /dev/loop0.
Invalid passphrase.
Set cipher aes, mode xts-plain, key size 512 bits for device /dev/loop0.
Invalid passphrase.
Set cipher aes, mode xts-plain, key size 512 bits for device /dev/loop0.
Invalid passphrase.
Too many attempts.

# Solution: (attached patch) (with output)
/space/systemd/systemd-cryptsetup attach mysecretdrive /dev/loop0 /tmp/keyfile 
Set cipher aes, mode xts-plain, key size 512 bits for device /dev/loop0.

# clear up
cryptsetup luksClose mysecretdrive
rm /tmp/{thedrive.dat,keyfile}
Comment 1 Lennart Poettering 2011-04-19 18:59:45 UTC
Hmm, from a first glance I would guess this is a bug in libcryptsetup?
Comment 2 Björn Busse 2011-04-19 19:26:32 UTC
The patch fixes the problem for me.
Comment 3 Milan Broz 2011-04-20 01:35:56 UTC
Fifth parameter says passphrase lenght read from keyfile
 * @keyfile_size - number of bytes to read from @keyfile, 0 is unlimited

Do not confuse it with volume key size - volume key size is read from LUKS header.

So if you specify 256 here, it means the it will try to read 256 bytes from keyfile, then try to unlock keyslot with this.

0 mean "unlimited" - common case. Limit is ussually needed just for /dev/urandom or so.

IMHO  specifying "size=" for LUKS device should be ignored.
(It makes sense only for plain crypt device.)
No idea if initscript overloads it and uses it for keyfile limitation in LUKS case - but I do not thisnk so, it is not documented.

There was a regression in libcryptsetup which did not fail if keyfile was too short, probably that's why it appeared now.

Anyway, this seems to be bug in systemd, using 0 is probably what you want there :)
Comment 4 Milan Broz 2011-04-20 09:08:04 UTC
So this is the proper fix (opt_key_size should be used only for crypt_format in plain or for crypt_activate_by_volume_key() (when passing volume key directly, without hashing).

- k = crypt_activate_by_keyfile(cd, argv[2], CRYPT_ANY_SLOT, key_file, opt_key_size, flags);
+ k = crypt_activate_by_keyfile(cd, argv[2], CRYPT_ANY_SLOT, key_file, 0, flags);
Comment 5 Lennart Poettering 2011-04-20 10:23:27 UTC
Thanks, fixed now in git.
Comment 6 Lennart Poettering 2011-04-20 18:17:28 UTC
Milan, I had to revert this fix now, since if /dev/random is used as key source (for example for swap devices, using the swap option of /etc/crypttab), then this will read unlimited data from it, thus eating all CPU and freezing the boot.

Not sure where to fix this best, Milan?
Comment 7 Milan Broz 2011-04-21 04:30:53 UTC
Created attachment 45912 [details] [review]
Proposed patch (not tested!)

Hm, yes, I missed that it is used even for non-luks path.

This is problem that crypttab handles luks and plain differently:

for LUKS -
has its header, and it only supports "luks" and keyfile argument in crypttab (the whole keyfile is always read, at least on Debian man page says:
"Note that the entire key file will be used as the passphase; the passphase must not be followed by a newline character.")

You cannot use /dev/random or similar keyfiles with LUKS in crypttab

for plain crypt
no header, so all paramaters must be specified in crypttab.
man page: "At minimum, the field should contain either the string luks or the cipher, hash and size options."

You can use for temporary storadge (like swap) random key (e.g. from /dev/random).

So, my proposed patch (not tested yet!) is use size option only when formatting crypt plain and ignore it for LUKS.

N.B. in previous version you passed keyfile size in bits while keyfile paramater was in bytes. (But for /dev/urandom it is not serious bug :)
Comment 8 Milan Broz 2011-04-25 15:17:50 UTC
Patch also sent to list.

Just now I tested keyfile for both plaincrypt/plain crypt with RNG/LUKS and it works for me correctly with my patch.
Comment 9 Lennart Poettering 2011-04-26 12:52:26 UTC
Thanks a lot! Applied.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.