From 03f36e9c0174f983e832c6ced80492ebefd34e46 Mon Sep 17 00:00:00 2001 From: Jan B Date: Wed, 27 Jul 2022 13:35:13 +0200 Subject: [PATCH 1/3] cryptenroll: adding the option to use a keyfile to unlock the device --- src/cryptenroll/cryptenroll.c | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/cryptenroll/cryptenroll.c b/src/cryptenroll/cryptenroll.c index 045adf871a..d6f2571a5f 100644 --- a/src/cryptenroll/cryptenroll.c +++ b/src/cryptenroll/cryptenroll.c @@ -14,6 +14,7 @@ #include "cryptsetup-util.h" #include "env-util.h" #include "escape.h" +#include "fileio.h" #include "libfido2-util.h" #include "main-func.h" #include "memory-util.h" @@ -28,6 +29,7 @@ #include "tpm2-util.h" static EnrollType arg_enroll_type = _ENROLL_TYPE_INVALID; +static char *arg_unlock_keyfile = NULL; static char *arg_pkcs11_token_uri = NULL; static char *arg_fido2_device = NULL; static char *arg_tpm2_device = NULL; @@ -47,6 +49,7 @@ static int arg_fido2_cred_alg = 0; assert_cc(sizeof(arg_wipe_slots_mask) * 8 >= _ENROLL_TYPE_MAX); +STATIC_DESTRUCTOR_REGISTER(arg_unlock_keyfile, freep); STATIC_DESTRUCTOR_REGISTER(arg_pkcs11_token_uri, freep); STATIC_DESTRUCTOR_REGISTER(arg_fido2_device, freep); STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep); @@ -92,6 +95,8 @@ static int help(void) { " --version Show package version\n" " --password Enroll a user-supplied password\n" " --recovery-key Enroll a recovery key\n" + " --unlock-key-file=PATH\n" + " Use a file to unlock the volume\n" " --pkcs11-token-uri=URI\n" " Specify PKCS#11 security token URI\n" " --fido2-credential-algorithm=STRING\n" @@ -127,6 +132,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERSION = 0x100, ARG_PASSWORD, ARG_RECOVERY_KEY, + ARG_UNLOCK_KEYFILE, ARG_PKCS11_TOKEN_URI, ARG_FIDO2_DEVICE, ARG_TPM2_DEVICE, @@ -144,6 +150,7 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "password", no_argument, NULL, ARG_PASSWORD }, { "recovery-key", no_argument, NULL, ARG_RECOVERY_KEY }, + { "unlock-key-file", required_argument, NULL, ARG_UNLOCK_KEYFILE }, { "pkcs11-token-uri", required_argument, NULL, ARG_PKCS11_TOKEN_URI }, { "fido2-credential-algorithm", required_argument, NULL, ARG_FIDO2_CRED_ALG }, { "fido2-device", required_argument, NULL, ARG_FIDO2_DEVICE }, @@ -221,6 +228,12 @@ static int parse_argv(int argc, char *argv[]) { arg_enroll_type = ENROLL_RECOVERY; break; + case ARG_UNLOCK_KEYFILE: + r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_unlock_keyfile); + if (r < 0) + return r; + break; + case ARG_PKCS11_TOKEN_URI: { _cleanup_free_ char *uri = NULL; @@ -473,6 +486,35 @@ static int prepare_luks( if (!vk) return log_oom(); + if (arg_unlock_keyfile) { + _cleanup_(erase_and_freep) char *password = NULL; + size_t password_len; + + r = read_full_file_full( + AT_FDCWD, + arg_unlock_keyfile, + 0, + SIZE_MAX, + READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET, + NULL, + &password, + &password_len); + if (r < 0) + return log_error_errno(r, "Reading keyfile %s failed: %m", arg_unlock_keyfile); + + r = crypt_volume_key_get( + cd, + CRYPT_ANY_SLOT, + vk, + &vks, + password, + password_len); + if (r < 0) + return log_error_errno(r, "Unlocking via keyfile failed: %m"); + + goto out; + } + r = getenv_steal_erase("PASSWORD", &envpw); if (r < 0) return log_error_errno(r, "Failed to acquire password from environment: %m"); @@ -536,6 +578,7 @@ static int prepare_luks( } } +out: *ret_cd = TAKE_PTR(cd); *ret_volume_key = TAKE_PTR(vk); *ret_volume_key_size = vks; From 1f4190244bc4134919dcf7c29428029a74755e61 Mon Sep 17 00:00:00 2001 From: Jan B Date: Wed, 27 Jul 2022 22:03:35 +0200 Subject: [PATCH 2/3] docs: adding "--unlock-key-file" to systemd-cryptenroll --- man/systemd-cryptenroll.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/man/systemd-cryptenroll.xml b/man/systemd-cryptenroll.xml index 2aa396e300..afde0fad7e 100644 --- a/man/systemd-cryptenroll.xml +++ b/man/systemd-cryptenroll.xml @@ -100,6 +100,15 @@ + + PATH + + Use a file instead of a password/passphrase read from stdin to unlock the volume. + Expects the PATH to the file containing your key to unlock the volume. Currently there is nothing like + or so this file has to only + contain the full key. + + URI From 7fd55538aa4d227709b5dc9c3460b54675b45ee1 Mon Sep 17 00:00:00 2001 From: Jan B Date: Wed, 27 Jul 2022 22:10:07 +0200 Subject: [PATCH 3/3] tests: systemd-cryptenroll: unlock volume with keyfile --- test/units/testsuite-70.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/units/testsuite-70.sh b/test/units/testsuite-70.sh index 6ebb1c72c9..fdd24e2862 100755 --- a/test/units/testsuite-70.sh +++ b/test/units/testsuite-70.sh @@ -11,6 +11,9 @@ dd if=/dev/zero of=$img bs=1024k count=20 status=none echo -n passphrase >/tmp/passphrase cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom $img /tmp/passphrase +# Unlocking via keyfile +systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto $img + # Enroll unlock with default PCR policy env PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto $img /usr/lib/systemd/systemd-cryptsetup attach test-volume $img - tpm2-device=auto,headless=1