From: Kamil Szczęk Date: Fri, 7 Jun 2024 14:48:41 +0000 (+0200) Subject: cryptsetup: manual FIDO2 PIN, UP and UV configuration X-Git-Tag: v257-rc1~1169 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5fa6e6ca785140b50cb30361e9ddc4e538c3f40;p=thirdparty%2Fsystemd.git cryptsetup: manual FIDO2 PIN, UP and UV configuration 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. --- diff --git a/man/crypttab.xml b/man/crypttab.xml index 955111fe940..3aa809e6672 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 42586a0aee5..ac46793e057 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,