From: Lennart Poettering Date: Fri, 29 May 2026 09:29:32 +0000 (+0200) Subject: cryptenroll: add --unlock-empty to unlock via an empty password X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f2d4fb6233caf821bb304cc3dd47ac8cb0cb332;p=thirdparty%2Fsystemd.git cryptenroll: add --unlock-empty to unlock via an empty password --- diff --git a/man/systemd-cryptenroll.xml b/man/systemd-cryptenroll.xml index 707a8d25e88..61906d3ce3d 100644 --- a/man/systemd-cryptenroll.xml +++ b/man/systemd-cryptenroll.xml @@ -270,6 +270,16 @@ The following options are understood that may be used to unlock the device in preparation of the enrollment operations: + + + + Use an empty password/passphrase to unlock the volume, instead of reading one from + stdin. This is useful to unlock volumes that are currently protected by an empty password, in order to + enroll a different, stronger unlock mechanism. + + + + diff --git a/src/cryptenroll/cryptenroll-password.c b/src/cryptenroll/cryptenroll-password.c index f58321063a6..595279c80d6 100644 --- a/src/cryptenroll/cryptenroll-password.c +++ b/src/cryptenroll/cryptenroll-password.c @@ -14,6 +14,30 @@ #include "string-util.h" #include "strv.h" +int load_volume_key_empty( + const EnrollContext *c, + struct crypt_device *cd, + struct iovec *ret_vk) { + + int r; + + assert_se(c); + assert_se(cd); + assert_se(ret_vk); + + r = sym_crypt_volume_key_get( + cd, + CRYPT_ANY_SLOT, + ret_vk->iov_base, + &ret_vk->iov_len, + "", + 0); + if (r < 0) + return log_error_errno(r, "Provided empty password did not work: %m"); + + return r; +} + int load_volume_key_keyfile( const EnrollContext *c, struct crypt_device *cd, diff --git a/src/cryptenroll/cryptenroll-password.h b/src/cryptenroll/cryptenroll-password.h index 35ae1760a8e..035a1becc5d 100644 --- a/src/cryptenroll/cryptenroll-password.h +++ b/src/cryptenroll/cryptenroll-password.h @@ -4,6 +4,7 @@ #include "cryptenroll.h" #include "shared-forward.h" +int load_volume_key_empty(const EnrollContext *c, struct crypt_device *cd, struct iovec *ret_vk); int load_volume_key_keyfile(const EnrollContext *c, struct crypt_device *cd, struct iovec *ret_vk); int load_volume_key_password(const EnrollContext *c, struct crypt_device *cd, struct iovec *ret_vk); diff --git a/src/cryptenroll/cryptenroll.c b/src/cryptenroll/cryptenroll.c index ce21f450ba9..4b8aa6c2417 100644 --- a/src/cryptenroll/cryptenroll.c +++ b/src/cryptenroll/cryptenroll.c @@ -334,6 +334,14 @@ static int parse_argv(int argc, char *argv[]) { OPTION_GROUP("Unlocking"): {} + OPTION_LONG("unlock-empty", NULL, "Use an empty password to unlock the volume"): + if (arg_unlock_type != UNLOCK_PASSWORD) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Multiple unlock methods specified at once, refusing."); + + arg_unlock_type = UNLOCK_EMPTY; + break; + OPTION_LONG("unlock-key-file", "PATH", "Use a file to unlock the volume"): if (arg_unlock_type != UNLOCK_PASSWORD) @@ -730,6 +738,10 @@ int prepare_luks( switch (c->unlock_type) { + case UNLOCK_EMPTY: + r = load_volume_key_empty(c, cd, &vk); + break; + case UNLOCK_PASSWORD: r = load_volume_key_password(c, cd, &vk); break; diff --git a/src/cryptenroll/cryptenroll.h b/src/cryptenroll/cryptenroll.h index 36aa852f424..49fa3b2a35e 100644 --- a/src/cryptenroll/cryptenroll.h +++ b/src/cryptenroll/cryptenroll.h @@ -19,6 +19,7 @@ typedef enum UnlockType { UNLOCK_KEYFILE, UNLOCK_FIDO2, UNLOCK_TPM2, + UNLOCK_EMPTY, _UNLOCK_TYPE_MAX, _UNLOCK_TYPE_INVALID = -EINVAL, } UnlockType;