From 768bca1df52e931c1788e0c98747fbfcadaff7ca Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Tue, 19 Nov 2024 13:13:25 +0100 Subject: [PATCH] Support plain resize with keyring key. --- lib/setup.c | 15 +++++++++------ man/common_options.adoc | 11 ++++++++--- man/cryptsetup-resize.8.adoc | 2 +- src/cryptsetup.c | 34 ++++++++++++++++++---------------- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/lib/setup.c b/lib/setup.c index 15716741..b1f08bdb 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -1412,6 +1412,8 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name) cd->u.plain.cipher = strdup(cipher); MOVE_REF(cd->u.plain.cipher_spec, cipher_spec); 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) { cd->u.loopaes.hdr.offset = tgt->u.crypt.offset; 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 (!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; - goto out; - } - r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr, - tgt->u.crypt.vk, CRYPT_DEFAULT_SEGMENT); - if (r) + if (r < 0) goto out; dmdq.flags |= CRYPT_ACTIVATE_KEYRING_KEY; diff --git a/man/common_options.adoc b/man/common_options.adoc index b98f5468..38a4507e 100644 --- a/man/common_options.adoc +++ b/man/common_options.adoc @@ -1312,12 +1312,17 @@ partially predictable volume key which will compromise security. endif::[] endif::[] -ifdef::ACTION_OPEN,ACTION_LUKSRESUME,ACTION_LUKSADDKEY[] +ifdef::ACTION_OPEN,ACTION_RESIZE,ACTION_LUKSRESUME,ACTION_LUKSADDKEY[] *--volume-key-keyring* __:: Use a volume key stored in a keyring. -This allows one to open _luks_ and device types without giving a passphrase. -The key and associated type has to be readable from userspace so that volume +This allows one to open _luks_ and _plain_ device types without giving a passphrase. ++ +For LUKS, the key and associated type has to be readable from userspace so that volume 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 __ uses keyctl-compatible syntax. This can either be a numeric key ID or a string name in the format _%:_. See diff --git a/man/cryptsetup-resize.8.adoc b/man/cryptsetup-resize.8.adoc index b9a55022..e0a6aaed 100644 --- a/man/cryptsetup-resize.8.adoc +++ b/man/cryptsetup-resize.8.adoc @@ -36,7 +36,7 @@ keyring is used by default for LUKS2 devices. ** can be [--size, --device-size, --token-id, --token-only, --token-type, --key-slot, --key-file, --keyfile-size, --keyfile-offset, --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_footer.adoc[] diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 5cad7957..0b415a73 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -974,25 +974,27 @@ static int action_resize(void) goto out; } - /* try load VK in kernel keyring using token */ - r = _try_token_unlock(cd, ARG_INT32(OPT_KEY_SLOT_ID), ARG_INT32(OPT_TOKEN_ID_ID), - NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY, - 1, true, ARG_SET(OPT_TOKEN_ONLY_ID)); + if (isLUKS2(crypt_get_type(cd))) { + /* try load VK in kernel keyring using token */ + r = _try_token_unlock(cd, ARG_INT32(OPT_KEY_SLOT_ID), ARG_INT32(OPT_TOKEN_ID_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)) - goto out; + if (r >= 0 || quit || ARG_SET(OPT_TOKEN_ONLY_ID)) + goto out; - r = init_keyslot_context(cd, NULL, &password, &passwordLen, verify_passphrase(0), - false, false, &kc); - crypt_safe_free(password); - if (r < 0) - goto out; + r = init_keyslot_context(cd, NULL, &password, &passwordLen, verify_passphrase(0), + false, false, &kc); + crypt_safe_free(password); + if (r < 0) + goto out; - r = crypt_activate_by_keyslot_context(cd, NULL,ARG_INT32(OPT_KEY_SLOT_ID), - kc, CRYPT_ANY_SLOT, NULL, - CRYPT_ACTIVATE_KEYRING_KEY); - tools_passphrase_msg(r); - tools_keyslot_msg(r, UNLOCKED); + r = crypt_activate_by_keyslot_context(cd, NULL,ARG_INT32(OPT_KEY_SLOT_ID), + kc, CRYPT_ANY_SLOT, NULL, + CRYPT_ACTIVATE_KEYRING_KEY); + tools_passphrase_msg(r); + tools_keyslot_msg(r, UNLOCKED); + } } out: