cryptsetup: Support key-slot option

Debian recently introduced the option key-slot to /etc/crypttab to
specify the LUKS key slot to be used for decrypting the device. On
systems where a keyfile is used and the key is not in the first slot,
this can speed up the boot process quite a bit, since cryptsetup does
not need to try all of the slots sequentially. (Unsuccessfully testing
a key slot typically takes up to about 1 second.)

This patch makes systemd aware of this option.

Debian bug that introduced the feature:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=704470
This commit is contained in:
Christian Seiler 2014-01-26 12:02:49 +01:00 committed by Tom Gundersen
parent 0a75bc612d
commit b4a11878f2
2 changed files with 25 additions and 2 deletions

View File

@ -163,6 +163,20 @@
given by the key size.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>key-slot=</varname></term>
<listitem><para>Specifies the key slot to
compare the passphrase or key against.
If the key slot does not match the given
passphrase or key, but another would, the
setup of the device will fail regardless.
This implies <varname>luks</varname>. See
<citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
for possible values. The default is to try
all key slots in sequential order.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>luks</varname></term>

View File

@ -39,6 +39,7 @@
static const char *opt_type = NULL; /* CRYPT_LUKS1, CRYPT_TCRYPT or CRYPT_PLAIN */
static char *opt_cipher = NULL;
static unsigned opt_key_size = 0;
static int opt_key_slot = CRYPT_ANY_SLOT;
static unsigned opt_keyfile_size = 0;
static unsigned opt_keyfile_offset = 0;
static char *opt_hash = NULL;
@ -87,6 +88,14 @@ static int parse_one_option(const char *option) {
return 0;
}
} else if (startswith(option, "key-slot=")) {
opt_type = CRYPT_LUKS1;
if (safe_atoi(option+9, &opt_key_slot) < 0) {
log_error("key-slot= parse failure, ignoring.");
return 0;
}
} else if (startswith(option, "tcrypt-keyfile=")) {
opt_type = CRYPT_TCRYPT;
@ -425,7 +434,7 @@ static int attach_luks_or_plain(struct crypt_device *cd,
crypt_get_device_name(cd));
if (key_file) {
r = crypt_activate_by_keyfile_offset(cd, name, CRYPT_ANY_SLOT,
r = crypt_activate_by_keyfile_offset(cd, name, opt_key_slot,
key_file, opt_keyfile_size,
opt_keyfile_offset, flags);
if (r < 0) {
@ -439,7 +448,7 @@ static int attach_luks_or_plain(struct crypt_device *cd,
if (pass_volume_key)
r = crypt_activate_by_volume_key(cd, name, *p, opt_key_size, flags);
else
r = crypt_activate_by_passphrase(cd, name, CRYPT_ANY_SLOT, *p, strlen(*p), flags);
r = crypt_activate_by_passphrase(cd, name, opt_key_slot, *p, strlen(*p), flags);
if (r >= 0)
break;