From b4a11878f2fdf5b07f895863747153de632ff4e6 Mon Sep 17 00:00:00 2001 From: Christian Seiler Date: Sun, 26 Jan 2014 12:02:49 +0100 Subject: [PATCH] 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 --- man/crypttab.xml | 14 ++++++++++++++ src/cryptsetup/cryptsetup.c | 13 +++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/man/crypttab.xml b/man/crypttab.xml index 90d8ce95f..5f386e55f 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -163,6 +163,20 @@ given by the key size. + + key-slot= + + 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 luks. See + cryptsetup8 + for possible values. The default is to try + all key slots in sequential order. + + luks diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 0a15b503b..033c0cdb7 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -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; -- 2.30.2