]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptenroll: add --unlock-empty to unlock via an empty password
authorLennart Poettering <lennart@amutable.com>
Fri, 29 May 2026 09:29:32 +0000 (11:29 +0200)
committerLennart Poettering <lennart@amutable.com>
Sat, 27 Jun 2026 15:28:39 +0000 (17:28 +0200)
man/systemd-cryptenroll.xml
src/cryptenroll/cryptenroll-password.c
src/cryptenroll/cryptenroll-password.h
src/cryptenroll/cryptenroll.c
src/cryptenroll/cryptenroll.h

index 707a8d25e88bda5f824f6dce197c30877a380dff..61906d3ce3d1bdbe405bd623598d423f11a68ad6 100644 (file)
     <para>The following options are understood that may be used to unlock the device in preparation of the enrollment operations:</para>
 
     <variablelist>
+      <varlistentry>
+        <term><option>--unlock-empty</option></term>
+
+        <listitem><para>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.</para>
+
+        <xi:include href="version-info.xml" xpointer="v262"/></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--unlock-key-file=<replaceable>PATH</replaceable></option></term>
 
index f58321063a6a2259a257c712a98cb5496b7b71d8..595279c80d6b8f0b98d1c07505e1304f36451f73 100644 (file)
 #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,
index 35ae1760a8ecd3a8e017ce1342341396d3dfc2fa..035a1becc5d1a481924e164f4c77162ac7785b7b 100644 (file)
@@ -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);
index ce21f450ba9e9c052709164585a06bab5fe7e4ec..4b8aa6c2417d1c2a75506fe28f3f0f5b8792d35f 100644 (file)
@@ -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;
index 36aa852f4246d597a38068052b557518e65258a3..49fa3b2a35e85a1a55c71c1eca1c1081f9c91ee9 100644 (file)
@@ -19,6 +19,7 @@ typedef enum UnlockType {
         UNLOCK_KEYFILE,
         UNLOCK_FIDO2,
         UNLOCK_TPM2,
+        UNLOCK_EMPTY,
         _UNLOCK_TYPE_MAX,
         _UNLOCK_TYPE_INVALID = -EINVAL,
 } UnlockType;