aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Zatovic <daniel.zatovic@gmail.com>2024-01-10 16:56:50 +0100
committerDaniel Zaťovič <daniel.zatovic@gmail.com>2024-01-19 16:26:30 +0000
commit136ba21c65f46084ee7c3aa7cbb2e81efb4a3792 (patch)
tree266a5e30732653901071e899616eae4b06100e8e
parent7fb98caa7974d47224d4d882309a8c7e12b8fce3 (diff)
downloadcryptsetup-136ba21c65f46084ee7c3aa7cbb2e81efb4a3792.tar.gz
Add tests for device activation using multiple VKs.
-rw-r--r--tests/api-test-2.c150
-rwxr-xr-xtests/compat-test258
-rwxr-xr-xtests/luks2-reencryption-test72
3 files changed, 273 insertions, 7 deletions
diff --git a/tests/api-test-2.c b/tests/api-test-2.c
index 6a4344a1..c8032a24 100644
--- a/tests/api-test-2.c
+++ b/tests/api-test-2.c
@@ -94,7 +94,7 @@ typedef int32_t key_serial_t;
#define TEST_KEY_VK_LOGON "cs_api_test_prefix:api_test_logon_vk1"
#define TEST_KEY_VK_LOGON_NAME "\%logon:" TEST_KEY_VK_LOGON
#define TEST_KEY_VK_USER2 "api_test_user_vk2"
-#define TEST_KEY_VK_USER2_NAME "\%user:" TEST_KEY_VK_USER
+#define TEST_KEY_VK_USER2_NAME "\%user:" TEST_KEY_VK_USER2
#define TEST_KEY_VK_LOGON2 "cs_api_test_prefix:api_test_logon_vk2"
#define TEST_KEY_VK_LOGON2_NAME "\%logon:" TEST_KEY_VK_LOGON
@@ -5267,7 +5267,7 @@ static void KeyslotContextAndKeyringLink(void)
#ifdef KERNEL_KEYRING
const char *cipher = "aes";
const char *cipher_mode = "xts-plain64";
- struct crypt_keyslot_context *kc;
+ struct crypt_keyslot_context *kc, *kc2;
uint64_t r_payload_offset;
char key[128];
size_t key_size = 128;
@@ -5325,6 +5325,7 @@ static void KeyslotContextAndKeyringLink(void)
NOTFAIL_(keyring_in_session_id, "Test or kernel keyring are broken.");
// test passphrase
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, NULL, CRYPT_ANY_SLOT, NULL, 0), -EINVAL);
OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &kc));
EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
crypt_keyslot_context_free(kc);
@@ -5577,8 +5578,153 @@ static void KeyslotContextAndKeyringLink(void)
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 0);
NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ CRYPT_FREE(cd);
+
+ // Reenncryption: test reactivation using linked keys
+ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
+ OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "cbc-essiv:sha256", NULL, NULL, 32, &params2));
+ OK_(crypt_set_pbkdf_type(cd, &pbkdf));
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 64, PASSPHRASE, strlen(PASSPHRASE)), 1);
+ EQ_(crypt_keyslot_add_by_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE), CRYPT_VOLUME_KEY_NO_SEGMENT), 0);
+ rparams.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY;
+
+ EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 1, 0, "aes", "xts-plain64", &rparams), 2);
+ EQ_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, TEST_KEY_VK_USER2, "user", keyring_in_user_str_id), 0);
+ EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 0);
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
+ NOTFAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ OK_(crypt_keyslot_context_init_by_vk_in_keyring(cd, TEST_KEY_VK_USER_NAME , &kc));
+ OK_(crypt_keyslot_context_init_by_vk_in_keyring(cd, TEST_KEY_VK_USER2_NAME, &kc2));
+
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), -ENOKEY);
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc2, CRYPT_ANY_SLOT, NULL, 0), -ENOKEY);
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, NULL, CRYPT_ANY_SLOT, kc, 0), -EINVAL);
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, NULL, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);
+
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER2, keyring_in_user_id, "user"));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);
+
+ EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 0);
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
+ NOTFAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ GE_((vk_len = keyctl_read(linked_kid, vk_buf, sizeof(vk_buf))), 0);
+ vk_buf[0] = ~vk_buf[0];
+ OK_(keyctl_update(linked_kid, vk_buf, vk_len));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER2, keyring_in_user_id, "user"));
CRYPT_FREE(cd);
+
+ // Decryption: test reactivation using linked keys
+ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
+ OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "cbc-essiv:sha256", NULL, NULL, 32, &params2));
+ OK_(crypt_set_pbkdf_type(cd, &pbkdf));
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 64, PASSPHRASE, strlen(PASSPHRASE)), 1);
+ rparams.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY;
+ rparams.mode = CRYPT_REENCRYPT_DECRYPT;
+ EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 1, CRYPT_ANY_SLOT, NULL, NULL, &rparams), 0);
+ EQ_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, TEST_KEY_VK_USER2, "user", keyring_in_user_str_id), 0);
+ EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 1);
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
+ FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "second VK was linked to custom keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0));
+ OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc, 0));
+ // lazy evaluation, if the first context supplies key and only one key is required, the second (invalid) context is not invoked
+ OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0));
+ // first context takes precedence, if t fails, the second is not tried
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc2, CRYPT_ANY_SLOT, kc, 0), -EINVAL);
+
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);
+
+ EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 1);
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
+ FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ GE_((vk_len = keyctl_read(linked_kid, vk_buf, sizeof(vk_buf))), 0);
+ vk_buf[0] = ~vk_buf[0];
+ OK_(keyctl_update(linked_kid, vk_buf, vk_len));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);
+
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
+ CRYPT_FREE(cd);
+
+ // Encryption: test reactivation using linked keys
+ _cleanup_dmdevices();
+ OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size));
+ OK_(create_dmdevice_over_loop(L_DEVICE_OK, 12*1024*2));
+
+ OK_(crypt_init(&cd, DMDIR H_DEVICE));
+
+ memset(&rparams, 0, sizeof(rparams));
+ params2.sector_size = 512;
+ params2.data_device = DMDIR L_DEVICE_OK;
+ rparams.mode = CRYPT_REENCRYPT_ENCRYPT;
+ rparams.luks2 = &params2;
+ rparams.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY;
+ rparams.resilience = "checksum";
+ rparams.hash = "sha256";
+ OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, &params2));
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 64, PASSPHRASE, strlen(PASSPHRASE)), 1);
+ EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ANY_SLOT, 1, "aes", "xts-plain64", &rparams), 0);
+
+ EQ_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, TEST_KEY_VK_USER2, "user", keyring_in_user_str_id), 0);
+ EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 1);
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
+ FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "second VK was linked to custom keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0));
+ OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc, 0));
+ // lazy evaluation, if the first context supplies key and only one key is required, the second (invalid) context is not invoked
+ OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0));
+ // first context takes precedence, if t fails, the second is not tried
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc2, CRYPT_ANY_SLOT, kc, 0), -EINVAL);
+
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);
+
+ EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 1);
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
+ FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ GE_((vk_len = keyctl_read(linked_kid, vk_buf, sizeof(vk_buf))), 0);
+ vk_buf[0] = ~vk_buf[0];
+ OK_(keyctl_update(linked_kid, vk_buf, vk_len));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);
+
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
+ CRYPT_FREE(cd);
+
+ crypt_keyslot_context_free(kc);
+ crypt_keyslot_context_free(kc2);
+
_cleanup_dmdevices();
#else
printf("WARNING: cryptsetup compiled with kernel keyring service disabled, skipping test.\n");
diff --git a/tests/compat-test2 b/tests/compat-test2
index 8698dfdd..bc865638 100755
--- a/tests/compat-test2
+++ b/tests/compat-test2
@@ -318,7 +318,7 @@ test_vk_link() {
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME || fail
keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 && fail "VK is linked to the specified keyring before resume with linking."
- $CRYPTSETUP luksSuspend $DEV_NAME || fail
+ $CRYPTSETUP luksSuspend $DEV_NAME || fail
echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --link-vk-to-keyring "$2"::"$KEY_DESC" || fail
keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
$CRYPTSETUP close $DEV_NAME
@@ -394,6 +394,44 @@ test_reencrypt_vk_link() {
keyctl unlink $KEYCTL_KEY_NAME2 "$3" || fail
}
+# $1 first key name
+# $2 second key name
+# $3 keyring to link VK to
+# $4 key type (optional)
+test_reencrypt_vk_link_and_reactivate() {
+ KEY_TYPE=${4:-user}
+ if [ -z "$4" ]; then
+ KEY_DESC=$1
+ else
+ KEY_DESC="%$4:$1"
+ fi
+ if [ -z "$4" ]; then
+ KEY_DESC2=$2
+ else
+ KEY_DESC2="%$4:$2"
+ fi
+
+ KEYCTL_KEY_NAME="%$KEY_TYPE:$1"
+ KEYCTL_KEY_NAME2="%$KEY_TYPE:$2"
+
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "$3"::"$KEY_DESC" --link-vk-to-keyring "$3"::"$KEY_DESC2" || fail
+ keyctl search "$3" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
+
+ keyctl search "$3" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
+ keyctl search "$3" $KEY_TYPE $2 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
+ $CRYPTSETUP close $DEV_NAME || fail
+ keyctl search "$3" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+ keyctl search "$3" $KEY_TYPE $2 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring "$KEY_DESC" --volume-key-keyring "$KEY_DESC2" || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+
+ keyctl unlink $KEYCTL_KEY_NAME "$3" || fail
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring "$KEY_DESC" --volume-key-keyring "$KEY_DESC2" > /dev/null 2>&1 && fail
+ keyctl unlink $KEYCTL_KEY_NAME2 "$3" || fail
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring "$KEY_DESC" --volume-key-keyring "$KEY_DESC2" > /dev/null 2>&1 && fail
+}
+
function expect_run()
{
export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}"
@@ -1459,13 +1497,13 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@t::%blah:$KEY_NAME" > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@t::%userlogon:$KEY_NAME" > /dev/null 2>&1 && fail
- # test that only one VK name is used, when the device is not in reencryption
+ # test that only one VK name is used, when the device is not in reencryption
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@u::%user:$KEY_NAME" --link-vk-to-keyring "@u::%user:$KEY_NAME2" > /dev/null 2>&1 || fail
keyctl unlink "%user:$KEY_NAME" @u || fail
keyctl unlink "%user:$KEY_NAME2" @u > /dev/null 2>&1 && fail
$CRYPTSETUP close $DEV_NAME || fail
- # test linkning multiple VKs during reencryption
+ # test linkning multiple VKs during reencryption
echo $PWD1 | $CRYPTSETUP -q reencrypt $LOOPDEV --init-only
test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "@u"
@@ -1479,12 +1517,22 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
# explicitly specify keyring key type
test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "%keyring:$TEST_KEYRING_NAME"
- # the keyring and key type have to be the same for both keys
+ test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "@u"
+ test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "@u" "user"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "@s"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "@s" "user"
+ test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "%:$TEST_KEYRING_NAME"
+ test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "%:$TEST_KEYRING_NAME" "user"
+
+ # explicitly specify keyring key type
+ test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "%keyring:$TEST_KEYRING_NAME"
+
+ # the keyring and key type have to be the same for both keys
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@s::%user:$KEY_NAME" --link-vk-to-keyring "@u::%user:$KEY_NAME2" > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@u::%logon:$KEY_NAME" --link-vk-to-keyring "@u::%user:$KEY_NAME2" > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@s::%logon:$KEY_NAME" --link-vk-to-keyring "@u::%user:$KEY_NAME2" > /dev/null 2>&1 && fail
- # supply one/three key name(s) when two names are required
+ # supply one/three key name(s) when two names are required
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@s::%logon:$KEY_NAME" > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@s::%logon:$KEY_NAME" --link-vk-to-keyring "@s::%logon:$KEY_NAME2" --link-vk-to-keyring "@s::%logon:$KEY_NAME3" > /dev/null 2>&1 && fail
fi
diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test
index 65320447..61f0d2cb 100755
--- a/tests/luks2-reencryption-test
+++ b/tests/luks2-reencryption-test
@@ -30,6 +30,12 @@ PWD1="93R4P4pIqAH8"
PWD2="1cND4319812f"
PWD3="1-9Qu5Ejfnqv"
DEV_LINK="reenc-test-link"
+KEYRING="@u"
+KEY_TYPE="user"
+KEY_NAME1="luks2-reencryption-test1"
+KEY_NAME2="luks2-reencryption-test2"
+KEY_SPEC1="${KEYRING}::%${KEY_TYPE}:${KEY_NAME1}"
+KEY_SPEC2="${KEYRING}::%${KEY_TYPE}:${KEY_NAME2}"
FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
@@ -366,6 +372,38 @@ function reencrypt_recover_online() { # $1 sector size, $2 resilience, $3 digest
echo "[OK]"
}
+function reencrypt_recover_online_vk() { # $1 sector size, $2 resilience, $3 digest, [$4 header]
+ echo -n "resilience mode: $2 ..."
+ local _hdr=""
+ test -z "$4" || _hdr="--header $4"
+
+ echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail
+ echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON --init-only >/dev/null 2>&1 || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+
+ echo $PWD1 | $CRYPTSETUP open --link-vk-to-keyring $KEY_SPEC1 --link-vk-to-keyring $KEY_SPEC2 $DEV $_hdr $DEV_NAME || fail
+
+ error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH
+ echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail
+ $CRYPTSETUP status $DEV_NAME $_hdr | grep -q "reencryption: in-progress" || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+ fix_writes $OVRDEV $OLD_DEV
+
+ # recovery during activation
+ $CRYPTSETUP open --volume-key-keyring $KEY_NAME1 --volume-key-keyring $KEY_NAME2 $DEV $_hdr $DEV_NAME || fail
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+
+ $CRYPTSETUP luksDump ${4:-$DEV} | grep -q "online-reencrypt"
+ if [ $? -eq 0 ]; then
+ $CRYPTSETUP status $DEV_NAME $_hdr | grep -q "reencryption: in-progress" || fail
+ echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --resilience $2 --resume-only -q || fail
+ check_hash_dev /dev/mapper/$DEV_NAME $3
+ fi
+
+ $CRYPTSETUP close $DEV_NAME || fail
+ echo "[OK]"
+}
+
function encrypt_recover() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest
wipe_dev $DEV
check_hash_dev $DEV $5
@@ -1261,6 +1299,40 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
reencrypt_recover_online 4096 journal $HASH1
fi
+echo "sector size 512->512 (recovery by VK)"
+
+get_error_offsets 32 $OFFSET
+echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail
+wipe $PWD1
+
+echo "ERR writes to sectors (recovery by VK) [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+reencrypt_recover_online_vk 512 checksum $HASH1
+reencrypt_recover_online_vk 512 journal $HASH1
+
+if [ -n "$DM_SECTOR_SIZE" ]; then
+ echo "sector size 512->4096"
+
+ get_error_offsets 32 $OFFSET 4096
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail
+ wipe $PWD1
+
+ echo "ERR writes to sectors (recovery by VK) [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_online_vk 4096 checksum $HASH1
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail
+ wipe $PWD1
+ reencrypt_recover_online_vk 4096 journal $HASH1
+
+ echo "sector size 4096->4096"
+
+ get_error_offsets 32 $OFFSET 4096
+ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 --sector-size 4096 -c aes-cbc-essiv:sha256 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail
+ wipe $PWD1
+
+ echo "ERR writes to sectors (recovery by VK) [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]"
+ reencrypt_recover_online_vk 4096 checksum $HASH1
+ reencrypt_recover_online_vk 4096 journal $HASH1
+fi
+
echo "[8] Reencryption with detached header recovery"
prepare_linear_dev 31 opt_blks=64 $OPT_XFERLEN_EXP