Add support for crypt_resume_by_token_pin in cryptsetup.

This commit is contained in:
Ondrej Kozina
2021-08-26 15:10:19 +02:00
parent ce6f6a48e8
commit fea648cb1d
3 changed files with 40 additions and 13 deletions

View File

@@ -341,10 +341,12 @@ the mapped device.
\fIluksResume\fR <name>
.IP
Resumes a suspended device and reinstates the encryption key.
Prompts interactively for a passphrase if \-\-key-file is not given.
Prompts interactively for a passphrase if no token is usable
(LUKS2 only) or \-\-key-file is not given.
\fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-size, \-\-header,
\-\-disable\-keyring, \-\-disable\-locks, \-\-type]
\-\-disable\-keyring, \-\-disable\-locks, \-\-token\-id,
\-\-token\-only, \-\-token\-type, \-\-type]
.PP
\fIluksAddKey\fR <device> [<key file with new key>]
.IP
@@ -1362,14 +1364,14 @@ The \fIignored\fR priority means, that slot is never used, if not explicitly
requested by \fI\-\-key\-slot\fR option.
.TP
.B "\-\-token\-id"
Specify what token to use in actions \fItoken\fR, \fIopen\fR or \fIresize\fR.
If omitted, all available tokens will be checked before proceeding further with
passphrase prompt.
Specify what token to use in actions \fItoken\fR, \fIopen\fR, \fIresize\fR or
\fIluksResume\fR. If omitted, all available tokens will be checked before
proceeding further with passphrase prompt.
.TP
.B "\-\-token\-only"
Do not proceed further with action (any of \fItoken\fR, \fIopen\fR or
\fIresize\fR) if token activation failed. Without the option,
action asks for passphrase to proceed further.
Do not proceed further with action (any of \fItoken\fR, \fIopen\fR,
\fIresize\fR or \fIluksResume\fR) if token based keyslot unlock failed.
Without the option, action asks for passphrase to proceed further.
.TP
.B "\-\-token\-type"
Restrict tokens eligible for operation to specific token type (name). Mostly

View File

@@ -94,7 +94,8 @@ static int _try_token_pin_unlock(struct crypt_device *cd,
const char *activated_name,
const char *token_type,
uint32_t activate_flags,
int tries)
int tries,
bool activation)
{
size_t pin_len;
char msg[64], *pin = NULL;
@@ -116,8 +117,14 @@ static int _try_token_pin_unlock(struct crypt_device *cd,
if (r < 0)
break;
r = crypt_activate_by_token_pin(cd, activated_name, token_type, ARG_INT32(OPT_TOKEN_ID_ID),
pin, pin_len, NULL, activate_flags);
if (activation)
r = crypt_activate_by_token_pin(cd, activated_name, token_type,
ARG_INT32(OPT_TOKEN_ID_ID),
pin, pin_len, NULL, activate_flags);
else
r = crypt_resume_by_token_pin(cd, activated_name, token_type,
ARG_INT32(OPT_TOKEN_ID_ID),
pin, pin_len, NULL);
crypt_safe_free(pin);
pin = NULL;
tools_keyslot_msg(r, UNLOCKED);
@@ -710,7 +717,7 @@ static int action_resize(void)
/* Token requires PIN, but ask only if there is no password query later */
if (ARG_SET(OPT_TOKEN_ONLY_ID) && r == -ENOANO)
r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY, 1);
r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY, 1, true);
if (r >= 0 || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out;
@@ -1476,7 +1483,7 @@ static int action_open_luks(void)
/* Token requires PIN, but ask only if there is no password query later */
if (ARG_SET(OPT_TOKEN_ONLY_ID) && r == -ENOANO)
r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), activated_name, ARG_STR(OPT_TOKEN_TYPE_ID), activate_flags, set_tries_tty());
r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), activated_name, ARG_STR(OPT_TOKEN_TYPE_ID), activate_flags, set_tries_tty(), true);
if (r >= 0 || r == -EEXIST || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out;
@@ -2201,6 +2208,19 @@ static int action_luksResume(void)
goto out;
}
/* try to resume LUKS2 device by token first */
r = crypt_resume_by_token_pin(cd, action_argv[0], ARG_STR(OPT_TOKEN_TYPE_ID),
ARG_INT32(OPT_TOKEN_ID_ID), NULL, 0, NULL);
tools_keyslot_msg(r, UNLOCKED);
tools_token_error_msg(r, ARG_STR(OPT_TOKEN_TYPE_ID), ARG_INT32(OPT_TOKEN_ID_ID), false);
/* Token requires PIN, but ask only if there is no password query later */
if (ARG_SET(OPT_TOKEN_ONLY_ID) && r == -ENOANO)
r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), action_argv[0], ARG_STR(OPT_TOKEN_TYPE_ID), 0, set_tries_tty(), false);
if (r >= 0 || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out;
tries = set_tries_tty();
do {
r = tools_get_key(NULL, &password, &passwordLen,

View File

@@ -853,6 +853,11 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
$CRYPTSETUP open --token-only $LOOPDEV --test-passphrase || fail
$CRYPTSETUP open --token-only $LOOPDEV $DEV_NAME || fail
$CRYPTSETUP status $DEV_NAME > /dev/null || fail
$CRYPTSETUP luksSuspend $DEV_NAME || fail
$CRYPTSETUP luksResume $DEV_NAME <&- || fail
$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" && fail
$CRYPTSETUP luksSuspend $DEV_NAME || fail
$CRYPTSETUP luksResume $DEV_NAME --token-type luks2-keyring <&- || fail
$CRYPTSETUP close $DEV_NAME || fail
# check --token-type sort of works (TODO: extend tests when native systemd tokens are available)