summaryrefslogtreecommitdiff
path: root/src/shared/libfido2-util.c
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2021-04-12 21:06:59 +0100
committerLuca Boccassi <bluca@debian.org>2021-05-07 21:36:27 +0100
commitcde2f8605e0c3842f9a87785dd758f955f2d04ba (patch)
tree26d259cdb23f9ace361340a87d584ab379259fde /src/shared/libfido2-util.c
parentcd5f57bda71dc9485d7eddf6cfcbfba843f5126c (diff)
downloadsystemd-cde2f8605e0c3842f9a87785dd758f955f2d04ba.tar.gz
FIDO2: support pin-less LUKS enroll/unlock
Closes: https://github.com/systemd/systemd/issues/19246 Some FIDO2 devices allow the user to choose whether to use a PIN or not and will HMAC with a different secret depending on the choice. Some other devices (or some device-specific configuration) can instead make it mandatory. Allow the cryptenroll user to choose whether to use a PIN or not, but fail immediately if it is a hard requirement. Record the choice in the JSON-encoded LUKS header metadata so that the right set of options can be used on unlock.
Diffstat (limited to 'src/shared/libfido2-util.c')
-rw-r--r--src/shared/libfido2-util.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/shared/libfido2-util.c b/src/shared/libfido2-util.c
index 951ed09899..66a312bfb6 100644
--- a/src/shared/libfido2-util.c
+++ b/src/shared/libfido2-util.c
@@ -219,6 +219,7 @@ static int fido2_use_hmac_hash_specific_token(
size_t cid_size,
char **pins,
bool up, /* user presence permitted */
+ Fido2EnrollFlags required, /* client pin required */
void **ret_hmac,
size_t *ret_hmac_size) {
@@ -250,6 +251,11 @@ static int fido2_use_hmac_hash_specific_token(
if (r < 0)
return r;
+ if (!has_client_pin && FLAGS_SET(required, FIDO2ENROLL_PIN))
+ return log_error_errno(SYNTHETIC_ERRNO(EHWPOISON),
+ "PIN required to unlock, but FIDO2 device %s does not support it.",
+ path);
+
a = sym_fido_assert_new();
if (!a)
return log_oom();
@@ -303,7 +309,7 @@ static int fido2_use_hmac_hash_specific_token(
r = sym_fido_dev_get_assert(d, a, NULL); /* try without pin but with up now */
}
- if (r == FIDO_ERR_PIN_REQUIRED) {
+ if (FLAGS_SET(required, FIDO2ENROLL_PIN)) {
char **i;
if (!has_client_pin)
@@ -367,6 +373,7 @@ int fido2_use_hmac_hash(
size_t cid_size,
char **pins,
bool up, /* user presence permitted */
+ Fido2EnrollFlags required, /* client pin required */
void **ret_hmac,
size_t *ret_hmac_size) {
@@ -379,7 +386,7 @@ int fido2_use_hmac_hash(
return log_error_errno(r, "FIDO2 support is not installed.");
if (device)
- return fido2_use_hmac_hash_specific_token(device, rp_id, salt, salt_size, cid, cid_size, pins, up, ret_hmac, ret_hmac_size);
+ return fido2_use_hmac_hash_specific_token(device, rp_id, salt, salt_size, cid, cid_size, pins, up, required, ret_hmac, ret_hmac_size);
di = sym_fido_dev_info_new(allocated);
if (!di)
@@ -414,7 +421,7 @@ int fido2_use_hmac_hash(
goto finish;
}
- r = fido2_use_hmac_hash_specific_token(path, rp_id, salt, salt_size, cid, cid_size, pins, up, ret_hmac, ret_hmac_size);
+ r = fido2_use_hmac_hash_specific_token(path, rp_id, salt, salt_size, cid, cid_size, pins, up, required, ret_hmac, ret_hmac_size);
if (!IN_SET(r,
-EBADSLT, /* device doesn't understand our credential hash */
-ENODEV /* device is not a FIDO2 device with HMAC-SECRET */))
@@ -439,6 +446,7 @@ int fido2_generate_hmac_hash(
const char *user_display_name,
const char *user_icon,
const char *askpw_icon_name,
+ Fido2EnrollFlags lock_with,
void **ret_cid, size_t *ret_cid_size,
void **ret_salt, size_t *ret_salt_size,
void **ret_secret, size_t *ret_secret_size,
@@ -503,6 +511,11 @@ int fido2_generate_hmac_hash(
if (r < 0)
return r;
+ if (!has_client_pin && FLAGS_SET(lock_with, FIDO2ENROLL_PIN))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Requested to lock with PIN, but FIDO2 device %s does not support it.",
+ device);
+
c = sym_fido_cred_new();
if (!c)
return log_oom();
@@ -648,7 +661,7 @@ int fido2_generate_hmac_hash(
log_info("Generating secret key on FIDO2 security token.");
- r = sym_fido_dev_get_assert(d, a, used_pin);
+ r = sym_fido_dev_get_assert(d, a, FLAGS_SET(lock_with, FIDO2ENROLL_PIN) ? used_pin : NULL);
if (r == FIDO_ERR_UP_REQUIRED) {
if (!has_up)
@@ -663,7 +676,7 @@ int fido2_generate_hmac_hash(
emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "",
emoji_enabled() ? " " : "");
- r = sym_fido_dev_get_assert(d, a, used_pin);
+ r = sym_fido_dev_get_assert(d, a, FLAGS_SET(lock_with, FIDO2ENROLL_PIN) ? used_pin : NULL);
}
if (r == FIDO_ERR_ACTION_TIMEOUT)
return log_error_errno(SYNTHETIC_ERRNO(ENOSTR),