diff --git a/man/crypttab.xml b/man/crypttab.xml
index 955111fe94..3aa809e667 100644
--- a/man/crypttab.xml
+++ b/man/crypttab.xml
@@ -768,6 +768,41 @@
+
+
+
+ Controls whether to require the user to enter a PIN when unlocking the volume (the
+ FIDO2 clientPin feature). This option only applies when in manual mode, i.e.
+ when option is set. Defaults to neither true or false, but rather to
+ v248 behavior, that is: try with no PIN first, but if token reports that PIN
+ is required, try again asking for PIN.
+
+
+
+
+
+
+
+ Controls whether to require the user to verify presence (tap the token, the FIDO2
+ up feature) when unlocking the volume. This option only applies when in manual
+ mode, i.e. when option is set. Defaults to neither true or false,
+ but rather to v248 behavior, that is: try with no UP first, but if token reports
+ that UP is required, try again with UP enabled.
+
+
+
+
+
+
+
+ Controls whether to require user verification (the FIDO2 uv feature)
+ when unlocking the volume. This option only applies when in manual mode, i.e. when
+ option is set. Defaults to neither true or false, but rather to
+ v248 behavior, that is: omit configuring UV whatsoever.
+
+
+
+
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 42586a0aee..ac46793e05 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -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,