From 47ac3edbade8ab5f4a205f2c1bad11ec9643b8b6 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 90d8ce9..5f386e5 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -164,6 +164,20 @@ + 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 Force LUKS mode. When this mode diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 39f7db7..6a76d21 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; @@ -432,7 +441,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) { @@ -446,7 +455,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;