Support plain resize with keyring key.

This commit is contained in:
Milan Broz
2024-11-19 13:13:25 +01:00
parent 4b7920975c
commit 768bca1df5
4 changed files with 36 additions and 26 deletions

View File

@@ -1412,6 +1412,8 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
cd->u.plain.cipher = strdup(cipher); cd->u.plain.cipher = strdup(cipher);
MOVE_REF(cd->u.plain.cipher_spec, cipher_spec); MOVE_REF(cd->u.plain.cipher_spec, cipher_spec);
cd->u.plain.cipher_mode = cd->u.plain.cipher_spec + strlen(cipher) + 1; cd->u.plain.cipher_mode = cd->u.plain.cipher_spec + strlen(cipher) + 1;
if (dmd.flags & CRYPT_ACTIVATE_KEYRING_KEY)
crypt_set_key_in_keyring(cd, 1);
} else if (isLOOPAES(cd->type) && single_segment(&dmd) && tgt->type == DM_CRYPT) { } else if (isLOOPAES(cd->type) && single_segment(&dmd) && tgt->type == DM_CRYPT) {
cd->u.loopaes.hdr.offset = tgt->u.crypt.offset; cd->u.loopaes.hdr.offset = tgt->u.crypt.offset;
cd->u.loopaes.cipher = strdup(cipher); cd->u.loopaes.cipher = strdup(cipher);
@@ -3609,13 +3611,14 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
} }
if (crypt_key_in_keyring(cd)) { if (crypt_key_in_keyring(cd)) {
if (!isLUKS2(cd->type)) { if (isLUKS2(cd->type))
r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr,
tgt->u.crypt.vk, CRYPT_DEFAULT_SEGMENT);
else if (isPLAIN(cd->type))
r = 0; /* key description was set on table load */
else
r = -EINVAL; r = -EINVAL;
goto out; if (r < 0)
}
r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr,
tgt->u.crypt.vk, CRYPT_DEFAULT_SEGMENT);
if (r)
goto out; goto out;
dmdq.flags |= CRYPT_ACTIVATE_KEYRING_KEY; dmdq.flags |= CRYPT_ACTIVATE_KEYRING_KEY;

View File

@@ -1312,12 +1312,17 @@ partially predictable volume key which will compromise security.
endif::[] endif::[]
endif::[] endif::[]
ifdef::ACTION_OPEN,ACTION_LUKSRESUME,ACTION_LUKSADDKEY[] ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSRESUME,ACTION_LUKSADDKEY[]
*--volume-key-keyring* _<key description>_:: *--volume-key-keyring* _<key description>_::
Use a volume key stored in a keyring. Use a volume key stored in a keyring.
This allows one to open _luks_ and device types without giving a passphrase. This allows one to open _luks_ and _plain_ device types without giving a passphrase.
The key and associated type has to be readable from userspace so that volume +
For LUKS, the key and associated type has to be readable from userspace so that volume
key digest may be verified in before activation. key digest may be verified in before activation.
+
For PLAIN type, the user must ensure that the key in the keyring is unchanged since activation.
Otherwise, reloading the key can cause data corruption after an unexpected key change.
+ +
The _<key description>_ uses keyctl-compatible syntax. This can either be a The _<key description>_ uses keyctl-compatible syntax. This can either be a
numeric key ID or a string name in the format _%<key type>:<key name>_. See numeric key ID or a string name in the format _%<key type>:<key name>_. See

View File

@@ -36,7 +36,7 @@ keyring is used by default for LUKS2 devices.
*<options>* can be [--size, --device-size, --token-id, --token-only, *<options>* can be [--size, --device-size, --token-id, --token-only,
--token-type, --key-slot, --key-file, --keyfile-size, --keyfile-offset, --token-type, --key-slot, --key-file, --keyfile-size, --keyfile-offset,
--timeout, --disable-external-tokens, --disable-locks, --disable-keyring, --timeout, --disable-external-tokens, --disable-locks, --disable-keyring,
--verify-passphrase, --timeout, --external-tokens-path]. --volume-key-keyring, --verify-passphrase, --timeout, --external-tokens-path].
include::man/common_options.adoc[] include::man/common_options.adoc[]
include::man/common_footer.adoc[] include::man/common_footer.adoc[]

View File

@@ -974,25 +974,27 @@ static int action_resize(void)
goto out; goto out;
} }
/* try load VK in kernel keyring using token */ if (isLUKS2(crypt_get_type(cd))) {
r = _try_token_unlock(cd, ARG_INT32(OPT_KEY_SLOT_ID), ARG_INT32(OPT_TOKEN_ID_ID), /* try load VK in kernel keyring using token */
NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY, r = _try_token_unlock(cd, ARG_INT32(OPT_KEY_SLOT_ID), ARG_INT32(OPT_TOKEN_ID_ID),
1, true, ARG_SET(OPT_TOKEN_ONLY_ID)); NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY,
1, true, ARG_SET(OPT_TOKEN_ONLY_ID));
if (r >= 0 || quit || ARG_SET(OPT_TOKEN_ONLY_ID)) if (r >= 0 || quit || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out; goto out;
r = init_keyslot_context(cd, NULL, &password, &passwordLen, verify_passphrase(0), r = init_keyslot_context(cd, NULL, &password, &passwordLen, verify_passphrase(0),
false, false, &kc); false, false, &kc);
crypt_safe_free(password); crypt_safe_free(password);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_activate_by_keyslot_context(cd, NULL,ARG_INT32(OPT_KEY_SLOT_ID), r = crypt_activate_by_keyslot_context(cd, NULL,ARG_INT32(OPT_KEY_SLOT_ID),
kc, CRYPT_ANY_SLOT, NULL, kc, CRYPT_ANY_SLOT, NULL,
CRYPT_ACTIVATE_KEYRING_KEY); CRYPT_ACTIVATE_KEYRING_KEY);
tools_passphrase_msg(r); tools_passphrase_msg(r);
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
}
} }
out: out: