]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptsetup: manual FIDO2 PIN, UP and UV configuration
authorKamil Szczęk <kamil@szczek.dev>
Fri, 7 Jun 2024 14:48:41 +0000 (16:48 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 13 Jun 2024 11:50:39 +0000 (13:50 +0200)
When in FIDO2 mode with manual parameters, i.e. when not reading the
parameters off the LUKS2 header, the current behavior in regards to PIN,
UP and UV features is to default to v248 logic, where we use PIN + UP
when needed, and do not configure UV at all. Let's allow users to
configure those features in manual mode too.

man/crypttab.xml
src/cryptsetup/cryptsetup.c

index 955111fe940a2af40cc7d53ba85b8b8595a33f2c..3aa809e6672ce4baac35d864b8817e5f28b1a7fe 100644 (file)
         <xi:include href="version-info.xml" xpointer="v248"/></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>fido2-pin=</option></term>
+
+        <listitem><para>Controls whether to require the user to enter a PIN when unlocking the volume (the
+        FIDO2 <literal>clientPin</literal> feature). This option only applies when in manual mode, i.e.
+        when <option>fido2-cid=</option> option is set. Defaults to neither true or false, but rather to
+        <constant>v248</constant> behavior, that is: try with no PIN first, but if token reports that PIN
+        is required, try again asking for PIN.</para>
+
+        <xi:include href="version-info.xml" xpointer="v257"/></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>fido2-up=</option></term>
+
+        <listitem><para>Controls whether to require the user to verify presence (tap the token, the FIDO2
+        <literal>up</literal> feature) when unlocking the volume. This option only applies when in manual
+        mode, i.e. when <option>fido2-cid=</option> option is set. Defaults to neither true or false,
+        but rather to <constant>v248</constant> behavior, that is: try with no UP first, but if token reports
+        that UP is required, try again with UP enabled.</para>
+
+        <xi:include href="version-info.xml" xpointer="v257"/></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>fido2-uv=</option></term>
+
+        <listitem><para>Controls whether to require user verification (the FIDO2 <literal>uv</literal> feature)
+        when unlocking the volume. This option only applies when in manual mode, i.e. when
+        <option>fido2-cid=</option> option is set. Defaults to neither true or false, but rather to
+        <constant>v248</constant> behavior, that is: omit configuring UV whatsoever.</para>
+
+        <xi:include href="version-info.xml" xpointer="v257"/></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>tpm2-device=</option></term>
 
index 42586a0aee56e7b50bbafc2fa44cffdc08915cf5..ac46793e05757aab5b423ded6652de2298a40c3d 100644 (file)
@@ -97,6 +97,10 @@ static bool arg_fido2_device_auto = false;
 static void *arg_fido2_cid = NULL;
 static size_t arg_fido2_cid_size = 0;
 static char *arg_fido2_rp_id = NULL;
+/* For now and for compatibility, if the user explicitly configured FIDO2 support and we do
+ * not read FIDO2 metadata off the LUKS2 header, default to the systemd 248 logic, where we
+ * use PIN + UP when needed, and do not configure UV at all. */
+static Fido2EnrollFlags arg_fido2_manual_flags = FIDO2ENROLL_PIN_IF_NEEDED | FIDO2ENROLL_UP_IF_NEEDED | FIDO2ENROLL_UV_OMIT;
 static char *arg_tpm2_device = NULL; /* These and the following fields are about locking an encrypted volume to the local TPM */
 static bool arg_tpm2_device_auto = false;
 static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
@@ -394,6 +398,39 @@ static int parse_one_option(const char *option) {
                 if (r < 0)
                         return log_oom();
 
+        } else if ((val = startswith(option, "fido2-pin="))) {
+
+                r = parse_boolean(val);
+                if (r < 0) {
+                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
+                        return 0;
+                }
+
+                arg_fido2_manual_flags &= ~FIDO2ENROLL_PIN_IF_NEEDED;
+                SET_FLAG(arg_fido2_manual_flags, FIDO2ENROLL_PIN, r);
+
+        } else if ((val = startswith(option, "fido2-up="))) {
+
+                r = parse_boolean(val);
+                if (r < 0) {
+                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
+                        return 0;
+                }
+
+                arg_fido2_manual_flags &= ~FIDO2ENROLL_UP_IF_NEEDED;
+                SET_FLAG(arg_fido2_manual_flags, FIDO2ENROLL_UP, r);
+
+        } else if ((val = startswith(option, "fido2-uv="))) {
+
+                r = parse_boolean(val);
+                if (r < 0) {
+                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
+                        return 0;
+                }
+
+                arg_fido2_manual_flags &= ~FIDO2ENROLL_UV_OMIT;
+                SET_FLAG(arg_fido2_manual_flags, FIDO2ENROLL_UV, r);
+
         } else if ((val = startswith(option, "tpm2-device="))) {
 
                 if (streq(val, "auto")) {
@@ -1361,33 +1398,18 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
         _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
         _cleanup_(erase_and_freep) void *decrypted_key = NULL;
         _cleanup_(sd_event_unrefp) sd_event *event = NULL;
-        size_t decrypted_key_size, cid_size = 0;
+        size_t decrypted_key_size;
         _cleanup_free_ char *friendly = NULL;
         int keyslot = arg_key_slot, r;
-        const char *rp_id = NULL;
-        const void *cid = NULL;
-        Fido2EnrollFlags required;
         bool use_libcryptsetup_plugin = libcryptsetup_plugins_support();
 
         assert(cd);
         assert(name);
         assert(arg_fido2_device || arg_fido2_device_auto);
 
-        if (arg_fido2_cid) {
-                if (!key_file && !key_data)
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                               "FIDO2 mode with manual parameters selected, but no keyfile specified, refusing.");
-
-                rp_id = arg_fido2_rp_id;
-                cid = arg_fido2_cid;
-                cid_size = arg_fido2_cid_size;
-
-                /* For now and for compatibility, if the user explicitly configured FIDO2 support and we do
-                 * not read FIDO2 metadata off the LUKS2 header, default to the systemd 248 logic, where we
-                 * use PIN + UP when needed, and do not configure UV at all. Eventually, we should make this
-                 * explicitly configurable. */
-                required = FIDO2ENROLL_PIN_IF_NEEDED | FIDO2ENROLL_UP_IF_NEEDED | FIDO2ENROLL_UV_OMIT;
-        }
+        if (arg_fido2_cid && !key_file && !key_data)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                        "FIDO2 mode with manual parameters selected, but no keyfile specified, refusing.");
 
         friendly = friendly_disk_name(crypt_get_device_name(cd), name);
         if (!friendly)
@@ -1401,17 +1423,17 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
                                                        "Automatic FIDO2 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
 
                 } else {
-                        if (cid)
+                        if (arg_fido2_cid)
                                 r = acquire_fido2_key(
                                                 name,
                                                 friendly,
                                                 arg_fido2_device,
-                                                rp_id,
-                                                cid, cid_size,
+                                                arg_fido2_rp_id,
+                                                arg_fido2_cid, arg_fido2_cid_size,
                                                 key_file, arg_keyfile_size, arg_keyfile_offset,
                                                 key_data, key_data_size,
                                                 until,
-                                                required,
+                                                arg_fido2_manual_flags,
                                                 "cryptsetup.fido2-pin",
                                                 arg_ask_password_flags,
                                                 &decrypted_key,