summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/Makefile.am24
-rwxr-xr-xtests/align-test18
-rwxr-xr-xtests/align-test215
-rw-r--r--tests/all-symbols-test.c6
-rw-r--r--tests/api-test-2.c931
-rw-r--r--tests/api-test.c6
-rw-r--r--tests/api_test.h10
-rwxr-xr-xtests/bitlk-compat-test16
-rwxr-xr-xtests/blockwise-compat-test2
-rwxr-xr-xtests/compat-args-test13
-rwxr-xr-xtests/compat-test62
-rwxr-xr-xtests/compat-test-opal1329
-rwxr-xr-xtests/compat-test2370
-rw-r--r--tests/crypto-vectors.c105
-rwxr-xr-xtests/device-test66
-rw-r--r--tests/differ.c2
-rwxr-xr-xtests/discards-test19
-rw-r--r--tests/fake_systemd_tpm_path.c4
-rw-r--r--tests/fake_token_path.c6
-rw-r--r--tests/fuzz/LUKS2.proto6
-rw-r--r--tests/fuzz/LUKS2_plain_JSON.proto4
-rw-r--r--tests/fuzz/crypt2_load_fuzz.cc111
-rw-r--r--tests/fuzz/crypt2_load_proto_fuzz.cc4
-rw-r--r--tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc4
-rw-r--r--tests/fuzz/meson.build127
-rwxr-xr-xtests/fuzz/oss-fuzz-build.sh20
-rw-r--r--tests/fuzz/plain_json_proto_to_luks2.cc4
-rw-r--r--tests/fuzz/plain_json_proto_to_luks2_converter.cc19
-rw-r--r--tests/fuzz/plain_json_proto_to_luks2_converter.h4
-rw-r--r--tests/fuzz/proto_to_luks2.cc4
-rw-r--r--tests/fuzz/proto_to_luks2_converter.cc4
-rw-r--r--tests/fuzz/proto_to_luks2_converter.h4
-rwxr-xr-xtests/fvault2-compat-test13
-rwxr-xr-xtests/integrity-compat-test13
-rwxr-xr-xtests/keyring-compat-test15
-rwxr-xr-xtests/loopaes-test13
-rwxr-xr-xtests/luks1-compat-test13
-rwxr-xr-xtests/luks2-integrity-test30
-rwxr-xr-xtests/luks2-reencryption-mangle-test13
-rwxr-xr-xtests/luks2-reencryption-test119
-rwxr-xr-xtests/luks2-validation-test13
-rw-r--r--tests/luks2_invalid_cipher.img.xzbin0 -> 135372 bytes
-rw-r--r--tests/meson.build482
-rwxr-xr-xtests/mode-test23
-rwxr-xr-xtests/password-hash-test13
-rwxr-xr-xtests/reencryption-compat-test17
-rwxr-xr-xtests/run-all-symbols6
-rwxr-xr-xtests/ssh-test-plugin41
-rwxr-xr-xtests/systemd-test-plugin66
-rwxr-xr-xtests/tcrypt-compat-test28
-rw-r--r--tests/tcrypt-images.tar.xzbin308700 -> 325760 bytes
-rw-r--r--tests/test_utils.c36
-rw-r--r--tests/unit-utils-crypt.c2
-rw-r--r--tests/unit-utils-io.c2
-rwxr-xr-xtests/unit-wipe-test2
-rw-r--r--tests/unit-wipe.c2
-rwxr-xr-xtests/verity-compat-test14
57 files changed, 3840 insertions, 455 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c8a46a8..75c1d3d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,6 +4,7 @@ TESTS = 00modules-test \
compat-args-test \
compat-test \
compat-test2 \
+ compat-test-opal \
loopaes-test \
align-test \
align-test2 \
@@ -44,15 +45,7 @@ if EXTERNAL_TOKENS
TESTS += systemd-test-plugin
endif
-ssh-test-plugin: fake_token_path.so
-systemd-test-plugin: fake_token_path.so fake_systemd_tpm_path.so
-
-# Do not use global CFLAGS here as the *.so link does not support sanitizers
-fake_token_path.so: fake_token_path.c
- $(CC) $(LDFLAGS) -I $(top_srcdir)/lib -fPIC -shared -D_GNU_SOURCE \
- -Wl,--version-script=$(top_srcdir)/lib/libcryptsetup.sym \
- -o fake_token_path.so $(top_srcdir)/tests/fake_token_path.c \
- -DBUILD_DIR=\"$(abs_top_srcdir)/.libs/\"
+systemd-test-plugin: fake_systemd_tpm_path.so
fake_systemd_tpm_path.so: fake_systemd_tpm_path.c
$(CC) $(LDFLAGS) -fPIC -shared -D_GNU_SOURCE -o fake_systemd_tpm_path.so \
@@ -68,6 +61,7 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \
luks2_valid_hdr.img.xz \
luks2_header_requirements.tar.xz \
luks2_mda_images.tar.xz \
+ luks2_invalid_cipher.img.xz \
evil_hdr-payload_overwrite.xz \
evil_hdr-stripes_payload_dmg.xz \
evil_hdr-luks_hdr_damage.xz \
@@ -79,6 +73,7 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \
compat-args-test \
compat-test \
compat-test2 \
+ compat-test-opal \
loopaes-test align-test discards-test mode-test password-hash-test \
align-test2 verity-compat-test \
reencryption-compat-test \
@@ -103,14 +98,14 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \
ssh-test-plugin \
generate-symbols-list \
run-all-symbols \
- fake_token_path.c \
fake_systemd_tpm_path.c \
unit-wipe-test \
systemd-test-plugin
-CLEANFILES = cryptsetup-tst* valglog* *-fail-*.log test-symbols-list.h fake_token_path.so fake_systemd_tpm_path.so
+CLEANFILES = cryptsetup-tst* valglog* *-fail-*.log test-symbols-list.h fake_systemd_tpm_path.so
clean-local:
- -rm -rf tcrypt-images luks1-images luks2-images bitlk-images fvault2-images conversion_imgs luks2_valid_hdr.img blkid-luks2-pv-img blkid-luks2-pv-img.bcp external-tokens
+ -rm -rf tcrypt-images luks1-images luks2-images bitlk-images fvault2-images conversion_imgs \
+ luks2_valid_hdr.img blkid-luks2-pv-img blkid-luks2-pv-img.bcp external-tokens luks2_invalid_cipher.img
differ_SOURCES = differ.c
differ_CFLAGS = $(AM_CFLAGS) -Wall -O2
@@ -165,7 +160,7 @@ all_symbols_test_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE
check_PROGRAMS = api-test api-test-2 differ vectors-test unit-utils-io unit-utils-crypt-test unit-wipe all-symbols-test
-check-programs: test-symbols-list.h $(check_PROGRAMS) fake_token_path.so fake_systemd_tpm_path.so
+check-programs: test-symbols-list.h $(check_PROGRAMS) fake_systemd_tpm_path.so
conversion_imgs:
@tar xJf conversion_imgs.tar.xz
@@ -177,6 +172,7 @@ valgrind-check: api-test api-test-2 differ
@VALG=1 ./compat-args-test
@VALG=1 ./compat-test
@VALG=1 ./compat-test2
+ @[ -z "$(OPAL2_PSID_FILE)" ] || VALG=1 ./compat-test-opal
@VALG=1 ./luks2-validation-test
@VALG=1 ./verity-compat-test
@VALG=1 ./integrity-compat-test
@@ -198,7 +194,7 @@ valgrind-check: api-test api-test-2 differ
@VALG=1 ./password-hash-test
@VALG=1 ./reencryption-compat-test
@VALG=1 ./fvault2-compat-test
- @[ -z "$RUN_SSH_PLUGIN_TEST" ] || VALG=1 ./ssh-test-plugin
+ @[ -z "$(RUN_SSH_PLUGIN_TEST)" ] || VALG=1 ./ssh-test-plugin
@INFOSTRING="unit-utils-crypt-test" ./valg-api.sh ./unit-utils-crypt-test
@INFOSTRING="vectors-test" ./valg-api.sh ./vectors-test
@grep -l "ERROR SUMMARY: [^0][0-9]* errors" valglog* || echo "No leaks detected."
diff --git a/tests/align-test b/tests/align-test
index 5941cde..d2932ae 100755
--- a/tests/align-test
+++ b/tests/align-test
@@ -12,8 +12,13 @@ FAST_PBKDF="--pbkdf-force-iterations 1000"
FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
+
function fips_mode()
{
@@ -54,7 +59,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -92,7 +100,7 @@ add_device() {
exit 77
fi
- sleep 2
+ sleep 1
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
if [ ! -e /sys/block/$DEV/alignment_offset ] ; then
@@ -176,7 +184,7 @@ format_plain() # sector size
{
echo -n "Formatting plain device (sector size $1)..."
if [ -n "$DM_SECTOR_SIZE" ] ; then
- echo $PWD1 | $CRYPTSETUP open --type plain --hash sha256 --sector-size $1 $DEV $DEV_NAME || fail
+ echo $PWD1 | $CRYPTSETUP open --type plain --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha256 --sector-size $1 $DEV $DEV_NAME || fail
$CRYPTSETUP close $DEV_NAME || fail
echo "PASSED"
else
diff --git a/tests/align-test2 b/tests/align-test2
index 33126a4..23d418a 100755
--- a/tests/align-test2
+++ b/tests/align-test2
@@ -11,8 +11,12 @@ PWD1="93R4P4pIqAH8"
PWD2="mymJeD8ivEhE"
FAST_PBKDF="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
cleanup() {
udevadm settle >/dev/null 2>&1
@@ -49,7 +53,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -87,7 +94,7 @@ add_device() {
exit 77
fi
- sleep 2
+ sleep 1
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
if [ ! -e /sys/block/$DEV/alignment_offset ] ; then
diff --git a/tests/all-symbols-test.c b/tests/all-symbols-test.c
index 10c7fe2..8d75044 100644
--- a/tests/all-symbols-test.c
+++ b/tests/all-symbols-test.c
@@ -1,7 +1,7 @@
/*
* Test utility checking symbol versions in libcryptsetup.
*
- * Copyright (C) 2021-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2021-2024 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -85,6 +85,10 @@ static int check_dlvsym(void *h, const char *symbol, const char *version)
}
log_dbg("OK\n");
+#else
+ UNUSED(h);
+ UNUSED(symbol);
+ UNUSED(version);
#endif
return 0;
}
diff --git a/tests/api-test-2.c b/tests/api-test-2.c
index 824ae65..8a7a60e 100644
--- a/tests/api-test-2.c
+++ b/tests/api-test-2.c
@@ -1,9 +1,9 @@
/*
* cryptsetup library LUKS2 API check functions
*
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
- * Copyright (C) 2016-2023 Ondrej Kozina
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
+ * Copyright (C) 2016-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -59,10 +59,12 @@ typedef int32_t key_serial_t;
#define L_DEVICE_0S "luks_zerosec"
#define L_DEVICE_WRONG "luks_wr"
#define L_DEVICE_OK "luks_ok"
+#define L_PLACEHOLDER "bdev_reference_placeholder"
#define REQS_LUKS2_HEADER "luks2_header_requirements"
#define NO_REQS_LUKS2_HEADER "luks2_header_requirements_free"
#define BACKUP_FILE "csetup_backup_file"
#define IMAGE1 "compatimage2.img"
+#define EMPTY_HEADER "empty.hdr"
#define IMAGE_EMPTY "empty.img"
#define IMAGE_EMPTY_SMALL "empty_small.img"
#define IMAGE_EMPTY_SMALL_2 "empty_small2.img"
@@ -83,6 +85,19 @@ typedef int32_t key_serial_t;
#define DEVICE_CHAR "/dev/zero"
#define THE_LFILE_TEMPLATE "cryptsetup-tstlp.XXXXXX"
+#define TEST_KEYRING_USER "cs_apitest2_keyring_in_user"
+#define TEST_KEYRING_USER_NAME "%keyring:" TEST_KEYRING_USER
+#define TEST_KEYRING_SESSION "cs_apitest2_keyring_in_session"
+#define TEST_KEYRING_SESSION_NAME "%keyring:" TEST_KEYRING_SESSION
+#define TEST_KEY_VK_USER "api_test_user_vk1"
+#define TEST_KEY_VK_USER_NAME "\%user:" TEST_KEY_VK_USER
+#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_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
+
#define KEY_DESC_TEST0 "cs_token_test:test_key0"
#define KEY_DESC_TEST1 "cs_token_test:test_key1"
@@ -141,6 +156,10 @@ static uint32_t default_luks2_iter_time = 0;
static uint32_t default_luks2_memory_kb = 0;
static uint32_t default_luks2_parallel_threads = 0;
+#ifdef KERNEL_KEYRING
+static char keyring_in_user_str_id[32] = {0};
+#endif
+
static struct crypt_pbkdf_type min_pbkdf2 = {
.type = "pbkdf2",
.iterations = 1000,
@@ -196,7 +215,7 @@ static int get_luks2_offsets(int metadata_device,
uint64_t *r_header_size,
uint64_t *r_payload_offset)
{
- struct crypt_device *cd = NULL;
+ struct crypt_device *_cd = NULL;
static uint64_t default_header_size = 0;
if (r_header_size)
@@ -205,16 +224,16 @@ static int get_luks2_offsets(int metadata_device,
*r_payload_offset = 0;
if (!default_header_size) {
- if (crypt_init(&cd, THE_LOOP_DEV))
+ if (crypt_init(&_cd, THE_LOOP_DEV))
return -EINVAL;
- if (crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, NULL)) {
- crypt_free(cd);
+ if (crypt_format(_cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, NULL)) {
+ crypt_free(_cd);
return -EINVAL;
}
- default_header_size = crypt_get_data_offset(cd);
+ default_header_size = crypt_get_data_offset(_cd);
- crypt_free(cd);
+ crypt_free(_cd);
}
if (!sector_size)
@@ -225,7 +244,7 @@ static int get_luks2_offsets(int metadata_device,
if (r_payload_offset) {
if (metadata_device)
- *r_payload_offset = alignpayload_sec * sector_size;
+ *r_payload_offset = (uint64_t)alignpayload_sec * sector_size;
else
*r_payload_offset = DIV_ROUND_UP_MODULO(default_header_size * 512, (alignpayload_sec ?: 1) * sector_size);
@@ -278,6 +297,9 @@ static void _cleanup_dmdevices(void)
{
struct stat st;
+ if (!stat(DMDIR L_PLACEHOLDER, &st))
+ _system("dmsetup remove " DM_RETRY L_PLACEHOLDER DM_NOSTDERR, 0);
+
if (!stat(DMDIR H_DEVICE, &st))
_system("dmsetup remove " DM_RETRY H_DEVICE DM_NOSTDERR, 0);
@@ -299,80 +321,6 @@ static void _cleanup_dmdevices(void)
t_dev_offset = 0;
}
-static void _cleanup(void)
-{
- struct stat st;
-
- CRYPT_FREE(cd);
- CRYPT_FREE(cd2);
-
- //_system("udevadm settle", 0);
-
- if (!stat(DMDIR CDEVICE_1, &st))
- _system("dmsetup remove " DM_RETRY CDEVICE_1 DM_NOSTDERR, 0);
-
- if (!stat(DMDIR CDEVICE_2, &st))
- _system("dmsetup remove " DM_RETRY CDEVICE_2 DM_NOSTDERR, 0);
-
- if (!stat(DEVICE_EMPTY, &st))
- _system("dmsetup remove " DM_RETRY DEVICE_EMPTY_name DM_NOSTDERR, 0);
-
- if (!stat(DEVICE_ERROR, &st))
- _system("dmsetup remove " DM_RETRY DEVICE_ERROR_name DM_NOSTDERR, 0);
-
- _cleanup_dmdevices();
-
- if (loop_device(THE_LOOP_DEV))
- loop_detach(THE_LOOP_DEV);
-
- if (loop_device(DEVICE_1))
- loop_detach(DEVICE_1);
-
- if (loop_device(DEVICE_2))
- loop_detach(DEVICE_2);
-
- if (loop_device(DEVICE_3))
- loop_detach(DEVICE_3);
-
- if (loop_device(DEVICE_4))
- loop_detach(DEVICE_4);
-
- if (loop_device(DEVICE_5))
- loop_detach(DEVICE_5);
-
- if (loop_device(DEVICE_6))
- loop_detach(DEVICE_6);
-
- _system("rm -f " IMAGE_EMPTY, 0);
- _system("rm -f " IMAGE1, 0);
- _system("rm -rf " CONV_DIR, 0);
-
- if (test_loop_file)
- remove(test_loop_file);
- if (tmp_file_1)
- remove(tmp_file_1);
-
- remove(REQS_LUKS2_HEADER);
- remove(NO_REQS_LUKS2_HEADER);
- remove(BACKUP_FILE);
- remove(IMAGE_PV_LUKS2_SEC);
- remove(IMAGE_PV_LUKS2_SEC ".bcp");
- remove(IMAGE_EMPTY_SMALL);
- remove(IMAGE_EMPTY_SMALL_2);
-
- _remove_keyfiles();
-
- free(tmp_file_1);
- free(test_loop_file);
- free(THE_LOOP_DEV);
- free(DEVICE_1);
- free(DEVICE_2);
- free(DEVICE_3);
- free(DEVICE_4);
- free(DEVICE_5);
- free(DEVICE_6);
-}
-
static int _setup(void)
{
int fd, ro = 0;
@@ -429,6 +377,8 @@ static int _setup(void)
_system("dd if=/dev/zero of=" IMAGE_EMPTY_SMALL_2 " bs=512 count=2050 2>/dev/null", 1);
+ _system("dd if=/dev/zero of=" EMPTY_HEADER " bs=4K count=1 2>/dev/null", 1);
+
_system(" [ ! -e " NO_REQS_LUKS2_HEADER " ] && tar xJf " REQS_LUKS2_HEADER ".tar.xz", 1);
fd = loop_attach(&DEVICE_4, NO_REQS_LUKS2_HEADER, 0, 0, &ro);
close(fd);
@@ -467,7 +417,7 @@ static int _setup(void)
return 0;
}
-static int set_fast_pbkdf(struct crypt_device *cd)
+static int set_fast_pbkdf(struct crypt_device *_cd)
{
const struct crypt_pbkdf_type *pbkdf = &min_argon2;
@@ -475,7 +425,7 @@ static int set_fast_pbkdf(struct crypt_device *cd)
if (_fips_mode)
pbkdf = &min_pbkdf2;
- return crypt_set_pbkdf_type(cd, pbkdf);
+ return crypt_set_pbkdf_type(_cd, pbkdf);
}
#ifdef KERNEL_KEYRING
@@ -489,6 +439,21 @@ static key_serial_t keyctl_unlink(key_serial_t key, key_serial_t keyring)
return syscall(__NR_keyctl, KEYCTL_UNLINK, key, keyring);
}
+static key_serial_t keyctl_link(key_serial_t key, key_serial_t keyring)
+{
+ return syscall(__NR_keyctl, KEYCTL_LINK, key, keyring);
+}
+
+static long keyctl_update(key_serial_t id, const void *payload, size_t plen)
+{
+ return syscall(__NR_keyctl, KEYCTL_UPDATE, id, payload, plen);
+}
+
+static long keyctl_read(key_serial_t id, char *buffer, size_t buflen)
+{
+ return syscall(__NR_keyctl, KEYCTL_READ, id, buffer, buflen);
+}
+
static key_serial_t request_key(const char *type,
const char *description,
const char *callout_info,
@@ -497,33 +462,168 @@ static key_serial_t request_key(const char *type,
return syscall(__NR_request_key, type, description, callout_info, keyring);
}
-static key_serial_t _kernel_key_by_segment(struct crypt_device *cd, int segment)
+/* key handle permissions mask */
+typedef uint32_t key_perm_t;
+#define KEY_POS_ALL 0x3f000000
+#define KEY_USR_ALL 0x003f0000
+
+static key_serial_t add_key_set_perm(const char *type, const char *description, const void *payload, size_t plen, key_serial_t keyring, key_perm_t perm)
+{
+ long l;
+ key_serial_t kid = syscall(__NR_add_key, type, description, payload, plen, KEY_SPEC_THREAD_KEYRING);
+
+ if (kid < 0)
+ return kid;
+
+ l = syscall(__NR_keyctl, KEYCTL_SETPERM, kid, perm);
+ if (l == 0)
+ l = syscall(__NR_keyctl, KEYCTL_LINK, kid, keyring);
+
+ syscall(__NR_keyctl, KEYCTL_UNLINK, kid, KEY_SPEC_THREAD_KEYRING);
+
+ return l == 0 ? kid : -EINVAL;
+}
+
+static key_serial_t _kernel_key_by_segment_and_type(struct crypt_device *_cd, int segment,
+ const char* type)
{
char key_description[1024];
- if (snprintf(key_description, sizeof(key_description), "cryptsetup:%s-d%u", crypt_get_uuid(cd), segment) < 1)
+ if (snprintf(key_description, sizeof(key_description), "cryptsetup:%s-d%u", crypt_get_uuid(_cd), segment) < 1)
return -1;
- return request_key("logon", key_description, NULL, 0);
+ return request_key(type, key_description, NULL, 0);
}
-static int _volume_key_in_keyring(struct crypt_device *cd, int segment)
+static key_serial_t _kernel_key_by_segment(struct crypt_device *_cd, int segment)
{
- return _kernel_key_by_segment(cd, segment) >= 0 ? 0 : -1;
+ return _kernel_key_by_segment_and_type(_cd, segment, "logon");
+}
+
+static int _volume_key_in_keyring(struct crypt_device *_cd, int segment)
+{
+ return _kernel_key_by_segment(_cd, segment) >= 0 ? 0 : -1;
+}
+
+static int _drop_keyring_key_from_keyring_name(const char *key_description, key_serial_t keyring, const char* type)
+{
+ //key_serial_t kid = request_key(type, key_description, NULL, keyring);
+ key_serial_t kid = request_key(type, key_description, NULL, 0);
+
+ if (kid < 0)
+ return -2;
+
+ return keyctl_unlink(kid, keyring);
}
-static int _drop_keyring_key(struct crypt_device *cd, int segment)
+static int _drop_keyring_key_from_keyring_type(struct crypt_device *_cd, int segment,
+ key_serial_t keyring, const char* type)
{
- key_serial_t kid = _kernel_key_by_segment(cd, segment);
+ key_serial_t kid = _kernel_key_by_segment_and_type(_cd, segment, type);
if (kid < 0)
return -1;
- return keyctl_unlink(kid, KEY_SPEC_THREAD_KEYRING);
+ return keyctl_unlink(kid, keyring);
+}
+
+static int _drop_keyring_key(struct crypt_device *_cd, int segment)
+{
+ return _drop_keyring_key_from_keyring_type(_cd, segment, KEY_SPEC_THREAD_KEYRING, "logon");
}
#endif
-static int test_open(struct crypt_device *cd __attribute__((unused)),
+static void _cleanup(void)
+{
+ struct stat st;
+
+ CRYPT_FREE(cd);
+ CRYPT_FREE(cd2);
+
+ //_system("udevadm settle", 0);
+
+ if (!stat(DMDIR CDEVICE_1, &st))
+ _system("dmsetup remove " DM_RETRY CDEVICE_1 DM_NOSTDERR, 0);
+
+ if (!stat(DMDIR CDEVICE_2, &st))
+ _system("dmsetup remove " DM_RETRY CDEVICE_2 DM_NOSTDERR, 0);
+
+ if (!stat(DEVICE_EMPTY, &st))
+ _system("dmsetup remove " DM_RETRY DEVICE_EMPTY_name DM_NOSTDERR, 0);
+
+ if (!stat(DEVICE_ERROR, &st))
+ _system("dmsetup remove " DM_RETRY DEVICE_ERROR_name DM_NOSTDERR, 0);
+
+ _cleanup_dmdevices();
+
+ if (loop_device(THE_LOOP_DEV))
+ loop_detach(THE_LOOP_DEV);
+
+ if (loop_device(DEVICE_1))
+ loop_detach(DEVICE_1);
+
+ if (loop_device(DEVICE_2))
+ loop_detach(DEVICE_2);
+
+ if (loop_device(DEVICE_3))
+ loop_detach(DEVICE_3);
+
+ if (loop_device(DEVICE_4))
+ loop_detach(DEVICE_4);
+
+ if (loop_device(DEVICE_5))
+ loop_detach(DEVICE_5);
+
+ if (loop_device(DEVICE_6))
+ loop_detach(DEVICE_6);
+
+ _system("rm -f " IMAGE_EMPTY, 0);
+ _system("rm -f " IMAGE1, 0);
+ _system("rm -rf " CONV_DIR, 0);
+ _system("rm -f " EMPTY_HEADER, 0);
+
+ if (test_loop_file)
+ remove(test_loop_file);
+ if (tmp_file_1)
+ remove(tmp_file_1);
+
+ remove(REQS_LUKS2_HEADER);
+ remove(NO_REQS_LUKS2_HEADER);
+ remove(BACKUP_FILE);
+ remove(IMAGE_PV_LUKS2_SEC);
+ remove(IMAGE_PV_LUKS2_SEC ".bcp");
+ remove(IMAGE_EMPTY_SMALL);
+ remove(IMAGE_EMPTY_SMALL_2);
+
+ _remove_keyfiles();
+
+ free(tmp_file_1);
+ free(test_loop_file);
+ free(THE_LOOP_DEV);
+ free(DEVICE_1);
+ free(DEVICE_2);
+ free(DEVICE_3);
+ free(DEVICE_4);
+ free(DEVICE_5);
+ free(DEVICE_6);
+
+#ifdef KERNEL_KEYRING
+ char *end;
+ key_serial_t krid;
+
+ if (keyring_in_user_str_id[0] != '\0') {
+ krid = strtoul(keyring_in_user_str_id, &end, 0);
+ if (!*end)
+ (void)keyctl_unlink(krid, KEY_SPEC_USER_KEYRING);
+ }
+
+ krid = request_key("keyring", TEST_KEYRING_SESSION, NULL, 0);
+ if (krid > 0)
+ (void)keyctl_unlink(krid, KEY_SPEC_SESSION_KEYRING);
+#endif
+}
+
+static int test_open(struct crypt_device *_cd __attribute__((unused)),
int token __attribute__((unused)),
char **buffer,
size_t *buffer_len,
@@ -539,7 +639,35 @@ static int test_open(struct crypt_device *cd __attribute__((unused)),
return 0;
}
-static int test_validate(struct crypt_device *cd __attribute__((unused)), const char *json)
+static int test_open_pass(struct crypt_device *_cd __attribute__((unused)),
+ int token __attribute__((unused)),
+ char **buffer,
+ size_t *buffer_len,
+ void *usrptr __attribute__((unused)))
+{
+ *buffer = strdup(PASSPHRASE);
+ if (!*buffer)
+ return -ENOMEM;
+ *buffer_len = strlen(*buffer);
+
+ return 0;
+}
+
+static int test_open_pass1(struct crypt_device *_cd __attribute__((unused)),
+ int token __attribute__((unused)),
+ char **buffer,
+ size_t *buffer_len,
+ void *usrptr __attribute__((unused)))
+{
+ *buffer = strdup(PASSPHRASE1);
+ if (!*buffer)
+ return -ENOMEM;
+ *buffer_len = strlen(*buffer);
+
+ return 0;
+}
+
+static int test_validate(struct crypt_device *_cd __attribute__((unused)), const char *json)
{
return (strstr(json, "magic_string") == NULL);
}
@@ -1925,6 +2053,10 @@ static void Tokens(void)
#define LUKS2_KEYRING_TOKEN_JSON_BAD(x, y) "{\"type\":\"luks2-keyring\",\"keyslots\":[" x "]," \
"\"key_description\":" y ", \"some_field\":\"some_value\"}"
+#define TEST_TOKEN2_JSON(x) "{\"type\":\"test_token2\",\"keyslots\":[" x "] }"
+
+#define TEST_TOKEN3_JSON(x) "{\"type\":\"test_token3\",\"keyslots\":[" x "] }"
+
int ks, token_max;
const char *dummy;
@@ -1933,6 +2065,7 @@ static void Tokens(void)
char passptr[] = PASSPHRASE;
char passptr1[] = PASSPHRASE1;
struct crypt_active_device cad;
+ struct crypt_keyslot_context *kc;
static const crypt_token_handler th = {
.name = "test_token",
@@ -1948,6 +2081,12 @@ static void Tokens(void)
}, th_reserved = {
.name = "luks2-prefix",
.open = test_open
+ }, th4 = {
+ .name = "test_token2",
+ .open = test_open_pass, // PASSPHRASE
+ }, th5 = {
+ .name = "test_token3",
+ .open = test_open_pass1, // PASSPHRASE1
};
struct crypt_token_params_luks2_keyring params = {
@@ -2153,6 +2292,60 @@ static void Tokens(void)
OK_(crypt_deactivate(cd, CDEVICE_1));
CRYPT_FREE(cd);
+ // test token based API with keyslot parameter
+ OK_(crypt_token_register(&th4)); // PASSPHRASE
+ OK_(crypt_token_register(&th5)); // PASSPHRASE1
+ OK_(crypt_init(&cd, DMDIR L_DEVICE_1S));
+ OK_(set_fast_pbkdf(cd));
+ OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, 32, NULL));
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 0);
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 1);
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 2, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 2);
+
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 3, NULL, 32, PASSPHRASE1, strlen(PASSPHRASE1)), 3);
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 4, NULL, 32, PASSPHRASE1, strlen(PASSPHRASE1)), 4);
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 5, NULL, 32, PASSPHRASE1, strlen(PASSPHRASE1)), 5);
+
+ OK_(crypt_keyslot_set_priority(cd, 0, CRYPT_SLOT_PRIORITY_IGNORE));
+ OK_(crypt_keyslot_set_priority(cd, 3, CRYPT_SLOT_PRIORITY_IGNORE));
+
+ OK_(crypt_keyslot_set_priority(cd, 2, CRYPT_SLOT_PRIORITY_PREFER));
+ OK_(crypt_keyslot_set_priority(cd, 5, CRYPT_SLOT_PRIORITY_PREFER));
+
+ EQ_(crypt_keyslot_add_by_key(cd, 6, NULL, 32, PASSPHRASE, strlen(PASSPHRASE), CRYPT_VOLUME_KEY_NO_SEGMENT), 6);
+ EQ_(crypt_keyslot_add_by_key(cd, 7, NULL, 32, PASSPHRASE1, strlen(PASSPHRASE1), CRYPT_VOLUME_KEY_NO_SEGMENT), 7);
+
+ OK_(crypt_keyslot_set_priority(cd, 6, CRYPT_SLOT_PRIORITY_PREFER));
+ OK_(crypt_keyslot_set_priority(cd, 7, CRYPT_SLOT_PRIORITY_PREFER));
+
+ EQ_(crypt_token_json_set(cd, 0, TEST_TOKEN2_JSON("\"0\", \"5\", \"1\", \"6\"")), 0); // PASSPHRASE
+ EQ_(crypt_token_json_set(cd, 1, TEST_TOKEN3_JSON("\"4\", \"6\", \"0\", \"5\"")), 1); // PASSPHRASE1
+
+ /* keyslots:
+ *
+ * 0 ignore (token 0)
+ * 1 normal (token 0)
+ * 2 prefer -
+ * 3 ignore -
+ * 4 normal (token 1)
+ * 5 prefer (token 1, token 0 wrong passphrase)
+ * 6 prefer (unbound, token 0, token 1 wrong passphrase)
+ * 7 prefer (unbound)
+ */
+
+ OK_(crypt_keyslot_context_init_by_token(cd, 0, NULL, NULL, 0, NULL, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 1);
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), 6);
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, 7, kc, CRYPT_ANY_SLOT, NULL, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), -ENOENT);
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, 5, kc, CRYPT_ANY_SLOT, NULL, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), -EPERM);
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_token(cd, CRYPT_ANY_TOKEN, NULL, NULL, 0, NULL, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 5);
+ crypt_keyslot_context_free(kc);
+
+ CRYPT_FREE(cd);
+
EQ_(crypt_token_max(CRYPT_LUKS2), 32);
FAIL_(crypt_token_max(CRYPT_LUKS1), "No token support in LUKS1");
FAIL_(crypt_token_max(NULL), "No LUKS format specified");
@@ -2802,7 +2995,8 @@ static void Pbkdf(void)
OK_(strcmp(pbkdf->type, default_luks2_pbkdf));
OK_(strcmp(pbkdf->hash, default_luks1_hash));
EQ_(pbkdf->time_ms, default_luks2_iter_time);
- EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory());
+ GE_(pbkdf->max_memory_kb, 64 * 1024);
+ GE_(adjusted_pbkdf_memory(), pbkdf->max_memory_kb);
EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads));
// set and verify argon2 type
OK_(crypt_set_pbkdf_type(cd, &argon2));
@@ -2827,7 +3021,8 @@ static void Pbkdf(void)
OK_(strcmp(pbkdf->type, default_luks2_pbkdf));
OK_(strcmp(pbkdf->hash, default_luks1_hash));
EQ_(pbkdf->time_ms, default_luks2_iter_time);
- EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory());
+ GE_(pbkdf->max_memory_kb, 64 * 1024);
+ GE_(adjusted_pbkdf_memory(), pbkdf->max_memory_kb);
EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads));
// try to pass illegal values
argon2.parallel_threads = 0;
@@ -2858,14 +3053,16 @@ static void Pbkdf(void)
OK_(strcmp(pbkdf->type, default_luks2_pbkdf));
OK_(strcmp(pbkdf->hash, default_luks1_hash));
EQ_(pbkdf->time_ms, default_luks2_iter_time);
- EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory());
+ GE_(pbkdf->max_memory_kb, 64 * 1024);
+ GE_(adjusted_pbkdf_memory(), pbkdf->max_memory_kb);
EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads));
crypt_set_iteration_time(cd, 1);
OK_(crypt_load(cd, CRYPT_LUKS, NULL));
OK_(strcmp(pbkdf->type, default_luks2_pbkdf));
OK_(strcmp(pbkdf->hash, default_luks1_hash));
EQ_(pbkdf->time_ms, 1);
- EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory());
+ GE_(pbkdf->max_memory_kb, 64 * 1024);
+ GE_(adjusted_pbkdf_memory(), pbkdf->max_memory_kb);
EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads));
CRYPT_FREE(cd);
@@ -2913,6 +3110,17 @@ static void Pbkdf(void)
argon2.hash = NULL;
OK_(crypt_set_pbkdf_type(cd, &argon2));
+ argon2.flags = CRYPT_PBKDF_NO_BENCHMARK;
+ argon2.max_memory_kb = 2 * 1024 * 1024;
+ argon2.iterations = 6;
+ argon2.parallel_threads = 8;
+ OK_(crypt_set_pbkdf_type(cd, &argon2));
+ NOTNULL_(pbkdf = crypt_get_pbkdf_type(cd));
+ EQ_(pbkdf->iterations, 6);
+ EQ_(pbkdf->max_memory_kb, 2 * 1024 *1024);
+ EQ_(pbkdf->parallel_threads, 4); /* hard maximum*/
+ EQ_(pbkdf->flags, CRYPT_PBKDF_NO_BENCHMARK);
+
CRYPT_FREE(cd);
NOTNULL_(pbkdf = crypt_get_pbkdf_default(CRYPT_LUKS1));
@@ -3015,6 +3223,9 @@ static void Luks2KeyslotAdd(void)
OK_(crypt_deactivate(cd, CDEVICE_1));
EQ_(crypt_activate_by_passphrase(cd, NULL, 1, PASSPHRASE1, strlen(PASSPHRASE1), 0), 1);
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 1, PASSPHRASE1, strlen(PASSPHRASE1), 0), 1);
+ /* check we can resume device with new volume key */
+ OK_(crypt_suspend(cd, CDEVICE_1));
+ EQ_(crypt_resume_by_passphrase(cd, CDEVICE_1, 1, PASSPHRASE1, strlen(PASSPHRASE1)), 1);
OK_(crypt_deactivate(cd, CDEVICE_1));
/* old keyslot must be unusable */
FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "Key doesn't match volume key digest");
@@ -4332,6 +4543,52 @@ static void Luks2Reencryption(void)
CRYPT_FREE(cd);
_cleanup_dmdevices();
+ OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_header_size + 1));
+
+ /* offline in-place encryption with reserved space in the head of data device */
+ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
+ memset(&rparams, 0, sizeof(rparams));
+ params2.sector_size = 512;
+ rparams.mode = CRYPT_REENCRYPT_ENCRYPT;
+ rparams.direction = CRYPT_REENCRYPT_FORWARD;
+ rparams.resilience = "checksum";
+ rparams.hash = "sha256";
+ rparams.luks2 = &params2;
+ rparams.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY;
+ OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, &params2));
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 30, NULL, 64, PASSPHRASE, strlen(PASSPHRASE)), 30);
+ OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ANY_SLOT, 30, "aes", "xts-plain64", &rparams));
+ FAIL_(crypt_reencrypt_run(cd, NULL, NULL), "context not initialized");
+ rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY;
+ OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ANY_SLOT, 30, "aes", "xts-plain64", &rparams));
+ OK_(crypt_reencrypt_run(cd, NULL, NULL));
+ EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE);
+ CRYPT_FREE(cd);
+
+ /* wipe existing header from previous run */
+ _system("dd if=/dev/zero of=" DMDIR L_DEVICE_OK " bs=4K count=5 2>/dev/null", 1);
+ /* open existing device from kernel (simulate active filesystem) */
+ OK_(create_dmdevice_over_device(L_PLACEHOLDER, DMDIR L_DEVICE_OK, 1, r_header_size));
+
+ /* online in-place encryption with reserved space */
+ rparams.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY;
+ OK_(crypt_init(&cd, EMPTY_HEADER));
+ OK_(crypt_set_data_offset(cd, r_header_size));
+ OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, &params2));
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 30, NULL, 64, PASSPHRASE, strlen(PASSPHRASE)), 30);
+ OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ANY_SLOT, 30, "aes", "xts-plain64", &rparams));
+ CRYPT_FREE(cd);
+ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
+ OK_(crypt_header_restore(cd, CRYPT_LUKS2, EMPTY_HEADER));
+ NOTFAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_SHARED), "Failed to activate device in reencryption with shared flag.");
+ rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY;
+ OK_(crypt_reencrypt_init_by_passphrase(cd, CDEVICE_1, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ANY_SLOT, 30, "aes", "xts-plain64", &rparams));
+ OK_(crypt_reencrypt_run(cd, NULL, NULL));
+ EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ CRYPT_FREE(cd);
+
+ _cleanup_dmdevices();
OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size));
OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_header_size + 1));
@@ -5005,10 +5262,479 @@ static void VolumeKeyGet(void)
_cleanup_dmdevices();
}
-static int _crypt_load_check(struct crypt_device *cd)
+static void KeyslotContextAndKeyringLink(void)
+{
+#ifdef KERNEL_KEYRING
+ const char *cipher = "aes";
+ const char *cipher_mode = "xts-plain64";
+ struct crypt_keyslot_context *kc, *kc2;
+ uint64_t r_payload_offset;
+ char key[128];
+ size_t key_size = 128;
+ key_serial_t kid, keyring_in_user_id, keyring_in_session_id, linked_kid, linked_kid2;
+ int suspend_status;
+ struct crypt_active_device cad;
+ char vk_buf[1024];
+ long vk_len;
+
+ struct crypt_pbkdf_type pbkdf = {
+ .type = CRYPT_KDF_ARGON2I,
+ .hash = "sha256",
+ .parallel_threads = 1,
+ .max_memory_kb = 128,
+ .iterations = 4,
+ .flags = CRYPT_PBKDF_NO_BENCHMARK
+ };
+ struct crypt_params_luks2 params2 = {
+ .pbkdf = &pbkdf,
+ .sector_size = 4096
+ };
+ struct crypt_params_reencrypt rparams = {
+ .direction = CRYPT_REENCRYPT_FORWARD,
+ .resilience = "checksum",
+ .hash = "sha256",
+ .luks2 = &params2,
+ };
+ uint64_t r_header_size;
+
+ if (_fips_mode) {
+ pbkdf.type = CRYPT_KDF_PBKDF2;
+ pbkdf.parallel_threads = 0;
+ pbkdf.max_memory_kb = 0;
+ pbkdf.iterations = 1000;
+ }
+
+ OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset));
+ OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1));
+
+ // prepare the device
+ OK_(crypt_init(&cd, DMDIR L_DEVICE_1S));
+ OK_(set_fast_pbkdf(cd));
+ OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, 32, NULL));
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 0);
+ EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 32, KEY1, strlen(KEY1)), 1);
+ EQ_(0, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, NULL, 0));
+
+ kid = add_key("user", KEY_DESC_TEST0, PASSPHRASE, strlen(PASSPHRASE), KEY_SPEC_THREAD_KEYRING);
+ NOTFAIL_(kid, "Test or kernel keyring are broken.");
+
+ keyring_in_user_id = add_key_set_perm("keyring", TEST_KEYRING_USER, NULL, 0, KEY_SPEC_USER_KEYRING, KEY_POS_ALL | KEY_USR_ALL);
+ NOTFAIL_(keyring_in_user_id, "Test or kernel keyring are broken.");
+ NOTFAIL_(snprintf(keyring_in_user_str_id, sizeof(keyring_in_user_str_id)-1, "%u", keyring_in_user_id), "Failed to get string id.");
+ keyring_in_session_id = add_key_set_perm("keyring", TEST_KEYRING_SESSION, NULL, 0, KEY_SPEC_SESSION_KEYRING, KEY_POS_ALL | KEY_USR_ALL);
+ 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);
+
+ OK_(crypt_keyslot_context_init_by_passphrase(cd, KEY1, strlen(KEY1), &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 1);
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ crypt_keyslot_context_free(kc);
+
+ OK_(prepare_keyfile(KEYFILE1, KEY1, strlen(KEY1)));
+ OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 1);
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_keyring(cd, KEY_DESC_TEST0, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ crypt_keyslot_context_free(kc);
+
+ // test activation
+ OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ FAIL_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), "already active");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ FAIL_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), "already active");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 1);
+ FAIL_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), "already active");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_keyring(cd, KEY_DESC_TEST0, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ crypt_keyslot_context_free(kc);
+
+ // test linking to a custom keyring linked in user keyring
+ OK_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, NULL, "user", keyring_in_user_str_id /* TEST_KEYRING_USER_NAME */));
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+
+ /*
+ * Otherwise we will not be able to search the TEST_KEYRING_USER in current context (see request_key(2):
+ * "The keyrings are searched in the order: thread-specific keyring, process-specific keyring, and then session keyring."
+ */
+ NOTFAIL_(keyctl_link(keyring_in_user_id, KEY_SPEC_THREAD_KEYRING), "Failed to link in thread keyring.");
+
+ FAIL_((linked_kid = request_key("logon", TEST_KEY_VK_USER, NULL, 0)), "VK was linked to custom keyring under wrong key type.");
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
+ NOTFAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "dm-crypt VK was not uploaded in thread kernel keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ NOTFAIL_(keyctl_unlink(linked_kid, keyring_in_user_id), "VK was not linked to custom keyring after deactivation.");
+ FAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "dm-crypt VK remain linked in thread keyring.");
+
+ OK_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_LOGON, NULL, "logon", keyring_in_user_str_id /* TEST_KEYRING_USER_NAME */));
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+ NOTFAIL_((linked_kid = request_key("logon", TEST_KEY_VK_LOGON, NULL, 0)), "VK was not linked to custom keyring.");
+ NOTFAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "dm-crypt VK was not uploaded in thread kernel keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ NOTFAIL_(keyctl_unlink(linked_kid, keyring_in_user_id), "VK was not linked to custom keyring after deactivation.");
+ FAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "dm-crypt VK remain linked in thread keyring.");
+
+ OK_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_LOGON, NULL, "logon", TEST_KEYRING_SESSION_NAME));
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+ NOTFAIL_((linked_kid = request_key("logon", TEST_KEY_VK_LOGON, NULL, 0)), "VK was not linked to custom keyring.");
+ NOTFAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "dm-crypt VK was not uploaded in thread kernel keyring.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ NOTFAIL_(keyctl_unlink(linked_kid, keyring_in_session_id), "VK was not linked to custom keyring after deactivation.");
+ FAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "dm-crypt VK remain linked in thread keyring.");
+
+ // test repeated activation
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+ NOTFAIL_((linked_kid = request_key("logon", TEST_KEY_VK_LOGON, NULL, 0)), "VK was not linked to custom keyring after repeated activation.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ NOTFAIL_(request_key("logon", TEST_KEY_VK_LOGON, NULL, 0), "VK was not linked to custom keyring after deactivation.");
+ NOTFAIL_(keyctl_unlink(linked_kid, keyring_in_session_id), "VK was not linked to custom keyring after deactivation.");
+ FAIL_(request_key("logon", TEST_KEY_VK_LOGON, NULL, 0), "VK was probably wrongly linked in yet another keyring ");
+
+ // change key type to default (user)
+ OK_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, NULL, NULL, TEST_KEYRING_USER_NAME));
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring after resetting key type.");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ //NOTFAIL_(request_key("user", TEST_KEY_VK_USER, NULL, 0), "VK was not linked to custom keyring after deactivation.");
+ NOTFAIL_(keyctl_unlink(linked_kid, keyring_in_user_id), "VK was not linked to custom keyring after deactivation.");
+ FAIL_(request_key("user", TEST_KEY_VK_USER, NULL, 0), "VK was probably wrongly linked in yet another keyring ");
+
+ // disable linking to session keyring
+ crypt_set_keyring_to_link(cd, NULL, NULL, NULL, NULL);
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+ FAIL_(request_key("user", TEST_KEY_VK_USER, NULL, 0), "VK was probably wrongly linked in yet another keyring ");
+ FAIL_(request_key("logon", TEST_KEY_VK_LOGON, NULL, 0), "VK was probably wrongly linked in yet another keyring ");
+ NOTFAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "VK was not found in thread keyring");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ FAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "failed to unlink the key from thread keyring");
+
+ // link VK to keyring and re-activate by the linked VK
+ crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, NULL, "user", TEST_KEYRING_SESSION_NAME);
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ NOTFAIL_(request_key("user", TEST_KEY_VK_USER, NULL, 0), "VK was not linked to session keyring.");
+ OK_(crypt_keyslot_context_init_by_vk_in_keyring(cd, TEST_KEY_VK_USER_NAME, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ NOTFAIL_(request_key("user", TEST_KEY_VK_USER, NULL, 0), "VK was not linked to session keyring after deactivation.");
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_session_id, "user"));
+ FAIL_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), "activation via VK in keyring after dropping the key");
+
+ // load VK back to keyring by activating
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ // activate by bad VK in keyring (test if VK digest is verified)
+ NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to session keyring after activation.");
+ 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));
+ FAIL_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_session_id, "user"));
+ crypt_keyslot_context_free(kc);
+
+ // After this point put resume tests only!
+ OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ suspend_status = crypt_suspend(cd, CDEVICE_1);
+ if (suspend_status == -ENOTSUP) {
+ printf("WARNING: Suspend/Resume not supported, skipping test.\n");
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ NOTFAIL_(keyctl_unlink(kid, KEY_SPEC_THREAD_KEYRING), "Test or kernel keyring are broken.");
+ CRYPT_FREE(cd);
+ _cleanup_dmdevices();
+ return;
+ }
+ OK_(suspend_status);
+ OK_(crypt_get_active_device(cd, CDEVICE_1, &cad));
+ EQ_(CRYPT_ACTIVATE_SUSPENDED, cad.flags & CRYPT_ACTIVATE_SUSPENDED);
+ OK_(crypt_resume_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc));
+ OK_(crypt_get_active_device(cd, CDEVICE_1, &cad));
+ EQ_(0, cad.flags & CRYPT_ACTIVATE_SUSPENDED);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ OK_(crypt_suspend(cd, CDEVICE_1));
+ EQ_(crypt_resume_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 1);
+ OK_(crypt_suspend(cd, CDEVICE_1));
+ OK_(crypt_get_active_device(cd, CDEVICE_1, &cad));
+ EQ_(CRYPT_ACTIVATE_SUSPENDED, cad.flags & CRYPT_ACTIVATE_SUSPENDED);
+ EQ_(crypt_resume_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc), 1);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ crypt_keyslot_context_free(kc);
+
+ OK_(crypt_keyslot_context_init_by_keyring(cd, KEY_DESC_TEST0, &kc));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ OK_(crypt_suspend(cd, CDEVICE_1));
+ EQ_(crypt_resume_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ crypt_keyslot_context_free(kc);
+
+ // resume by VK keyring context
+ crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, NULL, "user", TEST_KEYRING_SESSION_NAME);
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0));
+ NOTFAIL_(request_key("user", TEST_KEY_VK_USER, NULL, 0), "VK was not linked to session keyring.");
+ OK_(crypt_suspend(cd, CDEVICE_1));
+ OK_(crypt_keyslot_context_init_by_vk_in_keyring(cd, TEST_KEY_VK_USER_NAME, &kc));
+ EQ_(crypt_resume_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ NOTFAIL_(request_key("user", TEST_KEY_VK_USER, NULL, 0), "VK was not linked to session keyring after deactivation.");
+ OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_session_id, "user"));
+ FAIL_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), "activation via VK in keyring after dropping the key");
+ crypt_keyslot_context_free(kc);
+
+ NOTFAIL_(keyctl_unlink(kid, KEY_SPEC_THREAD_KEYRING), "Test or kernel keyring are broken.");
+ CRYPT_FREE(cd);
+
+ // test storing two VKs in keyring during reencryption
+ OK_(get_luks2_offsets(1, 0, 0, &r_header_size, NULL));
+ OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_header_size + 16));
+
+ 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);
+
+ // when no key name is specified, don't allow specifying type and keyring
+ EQ_(crypt_set_keyring_to_link(cd, NULL, NULL, NULL, keyring_in_user_str_id), -EINVAL);
+ EQ_(crypt_set_keyring_to_link(cd, NULL, NULL, "user", NULL), -EINVAL);
+ EQ_(crypt_set_keyring_to_link(cd, NULL, NULL, "user", keyring_in_user_str_id), -EINVAL);
+
+ // key names have to be specified starting from the first
+ EQ_(crypt_set_keyring_to_link(cd, NULL, TEST_KEY_VK_USER, "user", keyring_in_user_str_id), -EINVAL);
+ EQ_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, NULL, "user", keyring_in_user_str_id), -ESRCH);
+
+ 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);
+ FAIL_((linked_kid = request_key("logon", TEST_KEY_VK_USER, NULL, 0)), "VK was linked to custom keyring under wrong key type.");
+ FAIL_((linked_kid2 = request_key("logon", TEST_KEY_VK_USER2, NULL, 0)), "VK was linked to custom keyring under wrong key type.");
+ 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.");
+ NOTFAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "dm-crypt VK was not uploaded in thread kernel keyring.");
+ NOTFAIL_(_kernel_key_by_segment_and_type(cd, 1, "logon"), "dm-crypt VK was not uploaded in thread kernel keyring.");
+
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+ NOTFAIL_(keyctl_unlink(linked_kid, keyring_in_user_id), "VK was not linked to custom keyring after deactivation.");
+ NOTFAIL_(keyctl_unlink(linked_kid2, keyring_in_user_id), "VK was not linked to custom keyring after deactivation.");
+ FAIL_(_kernel_key_by_segment_and_type(cd, 0, "logon"), "dm-crypt VK remain linked in thread keyring.");
+ // BUG: Reencryption code does not unlink the second VK
+ // FAIL_(_kernel_key_by_segment_and_type(cd, 1, "logon"), "dm-crypt VK remain linked in thread keyring.");
+
+ // check that VKs are linked without calling crypt_activate_by_passphrase again, when activate is called on the same context
+ 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));
+ NOTFAIL_(keyctl_unlink(linked_kid, keyring_in_user_id), "VK was not linked to custom keyring after deactivation.");
+ NOTFAIL_(keyctl_unlink(linked_kid2, keyring_in_user_id), "VK was not linked to custom keyring after deactivation.");
+
+ // verify that the VK is no longer stored in a custom keyring
+ EQ_(crypt_set_keyring_to_link(cd, NULL, NULL, NULL, NULL), 0);
+ EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 0);
+ FAIL_((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));
+
+ // test that after reencryption finishes (and there is only one VK), only one VK name is used
+ EQ_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, TEST_KEY_VK_USER2, "user", keyring_in_user_str_id), 0);
+ rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY;
+ EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 1, 0, "aes", "xts-plain64", &rparams), 2);
+ OK_(crypt_reencrypt_run(cd, NULL, NULL));
+ 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), -ESRCH);
+ EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc2, CRYPT_ANY_SLOT, NULL, 0), -ESRCH);
+ 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");
+#endif
+}
+
+static int _crypt_load_check(struct crypt_device *_cd)
{
#ifdef HAVE_BLKID
- return crypt_load(cd, CRYPT_LUKS, NULL);
+ return crypt_load(_cd, CRYPT_LUKS, NULL);
#else
return -ENOTSUP;
#endif
@@ -5132,6 +5858,7 @@ int main(int argc, char *argv[])
#endif
RUN_(LuksKeyslotAdd, "Adding keyslot via new API");
RUN_(VolumeKeyGet, "Getting volume key via keyslot context API");
+ RUN_(KeyslotContextAndKeyringLink, "Activate via keyslot context API and linking VK to a keyring");
RUN_(Luks2Repair, "LUKS2 repair"); // test disables metadata locking. Run always last!
_cleanup();
diff --git a/tests/api-test.c b/tests/api-test.c
index aa430dd..71f1270 100644
--- a/tests/api-test.c
+++ b/tests/api-test.c
@@ -1,9 +1,9 @@
/*
* cryptsetup library API check functions
*
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
- * Copyright (C) 2016-2023 Ondrej Kozina
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
+ * Copyright (C) 2016-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/api_test.h b/tests/api_test.h
index 14efead..462c9aa 100644
--- a/tests/api_test.h
+++ b/tests/api_test.h
@@ -1,9 +1,9 @@
/*
* cryptsetup library API check functions
*
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
- * Copyright (C) 2016-2023 Ondrej Kozina
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
+ * Copyright (C) 2016-2024 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -45,6 +45,8 @@ int t_set_readahead(const char *device, unsigned value);
int fips_mode(void);
+int create_dmdevice_over_device(const char *dm_name, const char *device, uint64_t size, uint64_t offset);
+
int create_dmdevice_over_loop(const char *dm_name, const uint64_t size);
int get_key_dm(const char *name, char *buffer, unsigned int buffer_size);
@@ -138,7 +140,7 @@ void xlog(const char *msg, const char *tst, const char *func, int line, const ch
#define T_DM_INTEGRITY_DISCARDS_SUPPORTED (1 << 23) /* dm-integrity discards/TRIM option is supported */
#define T_DM_INTEGRITY_RESIZE_SUPPORTED (1 << 23) /* dm-integrity resize of the integrity device supported (introduced in the same version as discards)*/
#define T_DM_VERITY_PANIC_CORRUPTION_SUPPORTED (1 << 24) /* dm-verity panic on corruption */
-#define T_DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */
+#define T_DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt support for bypassing workqueues */
#define T_DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */
#define T_DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */
#define T_DM_VERITY_TASKLETS_SUPPORTED (1 << 28) /* dm-verity tasklets supported */
diff --git a/tests/bitlk-compat-test b/tests/bitlk-compat-test
index 8559e06..aa4a71f 100755
--- a/tests/bitlk-compat-test
+++ b/tests/bitlk-compat-test
@@ -8,8 +8,12 @@ TST_DIR=bitlk-images
MAP=bitlktst
DUMP_VK_FILE=bitlk-test-vk
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
[ -z "$srcdir" ] && srcdir="."
@@ -93,7 +97,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -156,6 +163,9 @@ for file in $(ls $TST_DIR/bitlk-*) ; do
echo $PASSPHRASE | $CRYPTSETUP bitlkDump -r $file --dump-volume-key --volume-key-file $DUMP_VK_FILE >/dev/null 2>&1
ret=$?
[ $ret -eq 0 ] || fail " failed to dump volume key"
+ $CRYPTSETUP bitlkOpen -r $file $MAP --volume-key-file $DUMP_VK_FILE --test-passphrase >/dev/null 2>&1
+ ret=$?
+ [ $ret -eq 1 ] || fail " test passphrase with volume key unexpectedly succeeded"
$CRYPTSETUP bitlkOpen -r $file $MAP --volume-key-file $DUMP_VK_FILE >/dev/null 2>&1
ret=$?
[ $ret -eq 1 ] && ( echo "$file" | grep -q -e "aes-cbc" ) && echo " [N/A]" && continue
diff --git a/tests/blockwise-compat-test b/tests/blockwise-compat-test
index 11db493..8db91c9 100755
--- a/tests/blockwise-compat-test
+++ b/tests/blockwise-compat-test
@@ -68,7 +68,7 @@ add_device() {
if [ $? -ne 0 ] ; then
skip "This kernel seems to not support proper scsi_debug module."
fi
- grep -q scsi_debug /sys/block/*/device/model || sleep 2
+ sleep 1
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
DEV="/dev/$DEV"
[ -b $DEV ] || fail "Cannot find $DEV."
diff --git a/tests/compat-args-test b/tests/compat-args-test
index c41e942..788cc7c 100755
--- a/tests/compat-args-test
+++ b/tests/compat-args-test
@@ -4,8 +4,12 @@ PS4='$LINENO:'
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
TEST_UUID="12345678-1234-1234-1234-123456789abc"
@@ -37,7 +41,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
diff --git a/tests/compat-test b/tests/compat-test
index 6dc8004..433beb2 100755
--- a/tests/compat-test
+++ b/tests/compat-test
@@ -5,8 +5,12 @@ PS4='$LINENO:'
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
CRYPTSETUP_RAW=$CRYPTSETUP
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
DIFFER=./differ
DEV_NAME=dummy
@@ -28,6 +32,7 @@ PWDW="rUkL4RUryBom"
VK_FILE="compattest_vkfile"
FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
+PLAIN_OPT="--hash sha256 --cipher aes-cbc-essiv:sha256 --key-size 256"
LUKS_HEADER="S0-5 S6-7 S8-39 S40-71 S72-103 S104-107 S108-111 R112-131 R132-163 S164-167 S168-207 A0-591"
KEY_SLOT0="S208-211 S212-215 R216-247 A248-251 A251-255"
@@ -198,7 +203,10 @@ function valgrind_setup()
[ -n "$VALG" ] || return
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
CRYPTSETUP=valgrind_run
CRYPTSETUP_RAW="./valg.sh ${CRYPTSETUP_VALGRIND}"
}
@@ -538,8 +546,8 @@ $CRYPTSETUP luksKillSlot -q $LOOPDEV 1 || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: DISABLED" || fail
prepare "[19] create & status & resize" wipe
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash xxx 2>/dev/null && fail
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha256 --cipher aes-cbc-essiv:sha256 --offset 3 --skip 4 --readonly || fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash xxx --cipher aes-cbc-essiv:sha256 --key-size 256 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV $PLAIN_OPT --offset 3 --skip 4 --readonly || fail
$CRYPTSETUP -q status $DEV_NAME | grep "offset:" | grep -q "3 sectors" || fail
$CRYPTSETUP -q status $DEV_NAME | grep "skipped:" | grep -q "4 sectors" || fail
$CRYPTSETUP -q status $DEV_NAME | grep "mode:" | grep -q "readonly" || fail
@@ -559,15 +567,15 @@ $CRYPTSETUP -q resize $DEV_NAME || fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "32765 sectors" || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
$CRYPTSETUP -q status $DEV_NAME >/dev/null && fail
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha256 $LOOPDEV || fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME $PLAIN_OPT $LOOPDEV || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
-echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME --hash sha256 $LOOPDEV || fail
+echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME $PLAIN_OPT $LOOPDEV || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
-echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME --hash sha256 --size 100 $LOOPDEV || fail
+echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME $PLAIN_OPT --size 100 $LOOPDEV || fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
# 4k sector resize (if kernel supports it)
-echo $PWD1 | $CRYPTSETUP -q open --type plain --hash sha256 $LOOPDEV $DEV_NAME --sector-size 4096 --size 8 >/dev/null 2>&1
+echo $PWD1 | $CRYPTSETUP -q open --type plain $PLAIN_OPT $LOOPDEV $DEV_NAME --sector-size 4096 --size 8 >/dev/null 2>&1
if [ $? -eq 0 ] ; then
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "8 sectors" || fail
$CRYPTSETUP -q resize $DEV_NAME --size 16 || fail
@@ -580,7 +588,7 @@ if [ $? -eq 0 ] ; then
fi
# Resize not aligned to logical block size
add_scsi_device dev_size_mb=32 sector_size=4096
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha256 $DEV || fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME $PLAIN_OPT $DEV || fail
OLD_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/')
$CRYPTSETUP resize $DEV_NAME -b 7 2> /dev/null && fail
dmsetup info $DEV_NAME | grep -q SUSPENDED && fail
@@ -588,25 +596,25 @@ NEW_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+
test $OLD_SIZE -eq $NEW_SIZE || fail
$CRYPTSETUP close $DEV_NAME || fail
# Add check for unaligned plain crypt activation
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha256 $DEV -b 7 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME $PLAIN_OPT $DEV -b 7 2>/dev/null && fail
$CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail
# verify is ignored on non-tty input
echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha256 --verify-passphrase 2>/dev/null || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 --key-size 255 2>/dev/null && fail
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 --key-size -1 2>/dev/null && fail
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 -l -1 2>/dev/null && fail
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 || fail
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 2>/dev/null && fail
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d blah 2>/dev/null && fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d $KEY1 --key-size 255 2>/dev/null && fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d $KEY1 --key-size -1 2>/dev/null && fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d $KEY1 -l -1 2>/dev/null && fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d $KEY1 || fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d $KEY1 2>/dev/null && fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d blah 2>/dev/null && fail
$CRYPTSETUP -q remove $DEV_NAME || fail
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d /dev/urandom || fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d /dev/urandom || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
prepare "[20] Disallow open/create if already mapped." wipe
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 || fail
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 2>/dev/null && fail
-$CRYPTSETUP create $DEV_NAME2 $LOOPDEV -d $KEY1 2>/dev/null && fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d $KEY1 || fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME $LOOPDEV -d $KEY1 2>/dev/null && fail
+$CRYPTSETUP create --cipher aes-cbc-essiv:sha256 --key-size 256 $DEV_NAME2 $LOOPDEV -d $KEY1 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $LOOPDEV 2>/dev/null && fail
$CRYPTSETUP remove $DEV_NAME || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $LOOPDEV || fail
@@ -708,15 +716,15 @@ $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d /dev/mapper/$DEV_NAME2 \
dmsetup remove --retry $DEV_NAME2
prepare "[25] Create shared segments" wipe
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha256 --offset 0 --size 256 || fail
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV --hash sha256 --offset 512 --size 256 2>/dev/null && fail
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV --hash sha256 --offset 512 --size 256 --shared || fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV $PLAIN_OPT --offset 0 --size 256 || fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV $PLAIN_OPT --offset 512 --size 256 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV $PLAIN_OPT --offset 512 --size 256 --shared || fail
$CRYPTSETUP -q remove $DEV_NAME2 || fail
$CRYPTSETUP -q remove $DEV_NAME || fail
prepare "[26] Suspend/Resume" wipe
# only LUKS is supported
-echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha256 $LOOPDEV || fail
+echo $PWD1 | $CRYPTSETUP create $DEV_NAME $PLAIN_OPT $LOOPDEV || fail
$CRYPTSETUP luksSuspend $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP -q remove $DEV_NAME || fail
@@ -836,8 +844,8 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: DISABLED" || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: DISABLED" || fail
prepare "[31] Deferred removal of device" wipe
-echo $PWD1 | $CRYPTSETUP open --type plain --hash sha256 $LOOPDEV $DEV_NAME || fail
-echo $PWD2 | $CRYPTSETUP open --type plain --hash sha256 /dev/mapper/$DEV_NAME $DEV_NAME2 || fail
+echo $PWD1 | $CRYPTSETUP open --type plain $PLAIN_OPT $LOOPDEV $DEV_NAME || fail
+echo $PWD2 | $CRYPTSETUP open --type plain $PLAIN_OPT /dev/mapper/$DEV_NAME $DEV_NAME2 || fail
$CRYPTSETUP close $DEV_NAME >/dev/null 2>&1 && fail
$CRYPTSETUP -q status $DEV_NAME >/dev/null 2>&1 || fail
$CRYPTSETUP close --deferred $DEV_NAME >/dev/null 2>&1
diff --git a/tests/compat-test-opal b/tests/compat-test-opal
new file mode 100755
index 0000000..3d5c07c
--- /dev/null
+++ b/tests/compat-test-opal
@@ -0,0 +1,1329 @@
+#!/bin/bash
+
+PS4='$LINENO:'
+[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
+CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
+CRYPTSETUP_RAW=$CRYPTSETUP
+
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
+
+DEV_NAME=dummy
+DEV_NAME2=dummy2
+NO_HEADER_IMG=missing-header
+HEADER_IMG=luks-header
+HEADER_LUKS2_INV=luks2_invalid_cipher.img
+KEY1=key1
+KEY2=key2
+KEY5=key5
+KEYE=keye
+KEY_PWD1=key_pwd1
+OPAL2_ADMIN_PIN="adminPin01"
+PWD1="93R4P4pIqAH8"
+PWD2="mymJeD8ivEhE"
+PWD3="ocMakf3fAcQO"
+PWD4="Qx3qn46vq0v"
+PWDW="rUkL4RUryBom"
+TEST_KEYRING_NAME="compattest2_keyring"
+TEST_TOKEN0="compattest2_desc0"
+TEST_TOKEN1="compattest2_desc1"
+VK_FILE="compattest2_vkfile"
+IMPORT_TOKEN="{\"type\":\"some_type\",\"keyslots\":[],\"base64_data\":\"zxI7vKB1Qwl4VPB4D-N-OgcC14hPCG0IDu8O7eCqaQ\"}"
+TOKEN_FILE0=test-token-file0
+TOKEN_FILE1=test-token-file1
+KEY_FILE0=test-key-file0
+KEY_FILE1=test-key-file1
+
+FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
+
+TEST_UUID="12345678-1234-1234-1234-123456789abc"
+
+FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
+
+function remove_mapping()
+{
+ [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2
+ [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
+ [ -b /dev/mapper/"$DEV_NAME"_dif ] && dmsetup remove --retry "$DEV_NAME"_dif
+ rm -f $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $VK_FILE \
+ $HEADER_LUKS2_INV missing-file $TOKEN_FILE0 $TOKEN_FILE1 test_image_* \
+ $KEY_FILE0 $KEY_FILE1 $KEY_PWD1 $NO_HEADER_IMG >/dev/null 2>&1
+
+ # unlink whole test keyring
+ [ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null
+ unset TEST_KEYRING
+}
+
+function fail()
+{
+ [ -n "$1" ] && echo "$1"
+ remove_mapping
+ reset_device_psid_nofail
+ echo "FAILED backtrace:"
+ while caller $frame; do ((frame++)); done
+ exit 2
+}
+
+function fips_mode()
+{
+ [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ]
+}
+
+function can_fail_fips()
+{
+ # Ignore this fail if running in FIPS mode
+ fips_mode || fail $1
+}
+
+function skip()
+{
+ [ -n "$1" ] && echo "$1"
+ remove_mapping
+ exit 77
+}
+
+function reset_device_psid()
+{
+ $CRYPTSETUP_RAW luksErase --hw-opal-factory-reset --key-file $OPAL2_PSID_FILE $OPAL2_DEV -q || \
+ fail "PSID reset fail, wrong device used?"
+}
+
+function reset_device_psid_nofail()
+{
+ $CRYPTSETUP_RAW luksErase --hw-opal-factory-reset --key-file $OPAL2_PSID_FILE $OPAL2_DEV -q 2>/dev/null
+}
+
+function prepare()
+{
+ [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
+
+ case "$2" in
+ reset)
+ remove_mapping
+ reset_device_psid
+ ;;
+ wipe)
+ $CRYPTSETUP_RAW isLuks --type luks2 $HEADER_IMG -q 2>/dev/null
+ if [ $? -eq 0 ]; then
+ echo $OPAL2_ADMIN_PIN | $CRYPTSETUP_RAW luksErase $OPAL2_DEV -q --header $HEADER_IMG
+ else
+ echo $OPAL2_ADMIN_PIN | $CRYPTSETUP_RAW luksErase $OPAL2_DEV -q 2>/dev/null
+ fi
+ remove_mapping
+ ;;
+ new)
+ remove_mapping
+ ;;
+ reuse | *)
+ ;;
+ esac
+
+ if [ ! -e $KEY1 ]; then
+ echo -n $'\x48\xc6\x74\x4f\x41\x4e\x50\xc0\x79\xc2\x2d\x5b\x5f\x68\x84\x17' >$KEY1
+ echo -n $'\x9c\x03\x5e\x1b\x4d\x0f\x9a\x75\xb3\x90\x70\x32\x0a\xf8\xae\xc4'>>$KEY1
+ fi
+
+ if [ ! -e $KEY2 ]; then
+ dd if=/dev/urandom of=$KEY2 count=1 bs=64 >/dev/null 2>&1
+ fi
+
+ if [ ! -e $KEY5 ]; then
+ dd if=/dev/urandom of=$KEY5 count=1 bs=16 >/dev/null 2>&1
+ fi
+
+ if [ ! -e $KEY_PWD1 ]; then
+ echo -n "$PWD1" > $KEY_PWD1
+ fi
+
+ if [ ! -e $KEYE ]; then
+ touch $KEYE
+ fi
+
+ [ -n "$1" ] && echo "CASE: $1"
+}
+
+function check_exists()
+{
+ [ -b /dev/mapper/$DEV_NAME ] || fail
+}
+
+function valgrind_setup()
+{
+ command -v valgrind >/dev/null || fail "Cannot find valgrind."
+ [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
+}
+
+function valgrind_run()
+{
+ INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@"
+}
+
+function dm_crypt_keyring_support()
+{
+ VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
+ [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
+
+ VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
+ VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
+ VER_PTC=$(echo $VER_STR | cut -f 3 -d.)
+
+ test -d /proc/sys/kernel/keys || return 1
+
+ [ $VER_MAJ -gt 1 ] && return 0
+ [ $VER_MAJ -eq 1 -a $VER_MIN -gt 18 ] && return 0
+ [ $VER_MAJ -eq 1 -a $VER_MIN -eq 18 -a $VER_PTC -ge 1 ] && return 0
+ return 1
+}
+
+function dm_crypt_keyring_new_kernel()
+{
+ KER_STR=$(uname -r)
+ [ -z "$KER_STR" ] && fail "Failed to parse kernel version."
+ KER_MAJ=$(echo $KER_STR | cut -f 1 -d.)
+ KER_MIN=$(echo $KER_STR | cut -f 2 -d.)
+
+ [ $KER_MAJ -ge 5 ] && return 0
+ [ $KER_MAJ -eq 4 -a $KER_MIN -ge 15 ] && return 0
+ return 1
+}
+
+function test_and_prepare_keyring() {
+ command -v keyctl >/dev/null || skip "Cannot find keyctl, test skipped"
+ keyctl list "@s" > /dev/null || skip "Current session keyring is unreachable, test skipped"
+ TEST_KEYRING=$(keyctl newring $TEST_KEYRING_NAME "@u" 2> /dev/null)
+ test -n "$TEST_KEYRING" || skip "Failed to create keyring in user keyring"
+ keyctl search "@s" keyring "$TEST_KEYRING" > /dev/null 2>&1 || keyctl link "@u" "@s" > /dev/null 2>&1
+ load_key user test_key test_data "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped."
+}
+
+# $1 type
+# $2 description
+# $3 payload
+# $4 keyring
+function load_key()
+{
+ keyctl add $@ >/dev/null
+}
+
+function setup_luks2_env() {
+ echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $OPAL2_DEV || fail
+ $CRYPTSETUP luksDump $OPAL2_DEV >/dev/null || fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME || fail
+ HAVE_KEYRING=$($CRYPTSETUP status $DEV_NAME | grep "keyring")
+ if [ -n "$HAVE_KEYRING" ]; then
+ HAVE_KEYRING=1
+ else
+ HAVE_KEYRING=0
+ fi
+ if $($CRYPTSETUP --version | grep -q "BLKID"); then
+ HAVE_BLKID=1
+ else
+ HAVE_BLKID=0
+ fi
+ $CRYPTSETUP close $DEV_NAME || fail
+}
+
+# $1 key name
+# $2 keyring to link VK to
+# $3 key type (optional)
+test_vk_link() {
+ KEY_TYPE=${3:-user}
+ if [ -z "$3" ]; then
+ KEY_DESC=$1
+ else
+ KEY_DESC="%$3:$1"
+ fi
+
+ KEYCTL_KEY_NAME="%$KEY_TYPE:$1"
+
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $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
+ keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+ keyctl unlink "$KEYCTL_KEY_NAME" "$2" || fail
+}
+
+# $1 key name
+# $2 keyring to link VK to
+# $3 key type (optional)
+test_vk_link_and_reactivate() {
+ KEY_TYPE=${3:-user}
+ if [ -z "$3" ]; then
+ KEY_DESC=$1
+ else
+ KEY_DESC="%$3:$1"
+ fi
+
+ KEYCTL_KEY_NAME="%$KEY_TYPE:$1"
+
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $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 || fail
+ keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+ $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --volume-key-keyring $KEY_DESC <&-|| fail "Failed to unlock volume via a VK in keyring."
+ $CRYPTSETUP luksSuspend $DEV_NAME || fail "Failed to suspend device."
+ $CRYPTSETUP luksResume $DEV_NAME --volume-key-keyring $KEY_DESC <&- || fail "Failed to resume via a VK in keyring."
+
+ echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase 2>/dev/null || fail
+ echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase 2>/dev/null && fail
+ echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --volume-key-keyring $KEY_DESC $OPAL2_DEV --new-key-slot 1 || fail "Failed to add passphrase by VK in keyring."
+ echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase 2>/dev/null || fail
+ $CRYPTSETUP luksKillSlot -q $OPAL2_DEV 1 2>/dev/null || fail
+
+ $CRYPTSETUP close $DEV_NAME || fail
+ # zero-out the key in keyring
+ keyctl pipe $KEYCTL_KEY_NAME | tr -c '\0' '\0' | keyctl pupdate $KEYCTL_KEY_NAME
+ $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --volume-key-keyring $KEY_DESC <&- > /dev/null 2>&1 && fail "Unlocked volume via a bad VK in keyring."
+ keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after bad activation."
+ keyctl unlink $KEYCTL_KEY_NAME "$2" || fail
+}
+
+function test_reencryption_does_not_init()
+{
+ local _hdr=""
+ local _hdrdev=$NO_HEADER_IMG
+ if [ -n "$1" ]; then
+ _hdr="--header $1"
+ _hdrdev=$1
+ fi
+ local _dumpdev=${1:-$OPAL2_DEV}
+
+ # store sequence id to check if reencryption was aborted without metadata modifications
+ OLD_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$OLD_SEQID -gt 0 ] || fail
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $_hdr -q --init-only $OPAL2_DEV 2>/dev/null && fail
+ NEW_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$NEW_SEQID -gt 0 ] || fail
+ test $OLD_SEQID -eq $NEW_SEQID || fail "LUKS2 metadata was modified."
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $_hdr -q $OPAL2_DEV 2>/dev/null && fail
+ NEW_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$NEW_SEQID -gt 0 ] || fail
+ test $OLD_SEQID -eq $NEW_SEQID || fail "LUKS2 metadata was modified."
+
+ echo $PWD1 |$CRYPTSETUP reencrypt -q --decrypt --header $_hdrdev --init-only $OPAL2_DEV 2>/dev/null && fail
+ if [ $_hdrdev = $NO_HEADER_IMG ]; then
+ test -e $_hdrdev && fail "Decryption header was created."
+ fi
+ NEW_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$NEW_SEQID -gt 0 ] || fail
+ test $OLD_SEQID -eq $NEW_SEQID || fail "LUKS2 metadata was modified."
+
+ echo $PWD1 |$CRYPTSETUP reencrypt -q --decrypt --header $_hdrdev $OPAL2_DEV 2>/dev/null && fail
+ if [ $_hdrdev = $NO_HEADER_IMG ]; then
+ test -e $_hdrdev && fail "Decryption header was created."
+ fi
+ NEW_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$NEW_SEQID -gt 0 ] || fail
+ test $OLD_SEQID -eq $NEW_SEQID || fail "LUKS2 metadata was modified."
+
+ # repeat the test with active device
+ echo $PWD1 | $CRYPTSETUP open $_hdr $OPAL2_DEV $DEV_NAME -q || fail
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $_hdr -q --init-only --active-name $DEV_NAME 2>/dev/null && fail
+ NEW_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$NEW_SEQID -gt 0 ] || fail
+ test $OLD_SEQID -eq $NEW_SEQID || fail "LUKS2 metadata was modified."
+
+ echo $PWD1 | $CRYPTSETUP reencrypt $_hdr -q --active-name $DEV_NAME 2>/dev/null && fail
+ NEW_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$NEW_SEQID -gt 0 ] || fail
+ test $OLD_SEQID -eq $NEW_SEQID || fail "LUKS2 metadata was modified."
+
+ echo $PWD1 |$CRYPTSETUP reencrypt -q --decrypt --header $_hdrdev --init-only --active-name $DEV_NAME 2>/dev/null && fail
+ if [ $_hdrdev = $NO_HEADER_IMG ]; then
+ test -e $_hdrdev && fail "Decryption header was created."
+ fi
+ NEW_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$NEW_SEQID -gt 0 ] || fail
+ test $OLD_SEQID -eq $NEW_SEQID || fail "LUKS2 metadata was modified."
+
+ echo $PWD1 |$CRYPTSETUP reencrypt -q --decrypt --header $_hdrdev --active-name $DEV_NAME 2>/dev/null && fail
+ if [ $_hdrdev = $NO_HEADER_IMG ]; then
+ test -e $_hdrdev && fail "Decryption header was created."
+ fi
+ NEW_SEQID=0"$($CRYPTSETUP luksDump $_dumpdev | grep "Epoch:" | cut -d: -f 2 | sed -e 's/[[:space:]]*//g')"
+ [ 0$NEW_SEQID -gt 0 ] || fail
+ test $OLD_SEQID -eq $NEW_SEQID || fail "LUKS2 metadata was modified."
+
+ $CRYPTSETUP close $DEV_NAME || fail
+}
+
+function test_device() #opal_mode, #format_params, #--integrity-no-wipe
+{
+ echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat --type luks2 $1 $2 $3 -q $FAST_PBKDF_OPT $OPAL2_DEV || fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME || fail
+ test -z "$3" || dd if=/dev/zero of=/dev/mapper/$DEV_NAME bs=1M count=1 oflag=direct >/dev/null 2>&1 || fail
+ $CRYPTSETUP luksSuspend $DEV_NAME || fail
+ dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME || fail
+ dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+ dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
+ echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail
+}
+
+function test_device_detached_header() #hdr, #opal_mode, #format_params, #--integrity-no-wipe
+{
+ echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat --type luks2 --header $1 $2 $3 $4 -q $FAST_PBKDF_OPT $OPAL2_DEV || fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --header $1 || fail
+ test -z "$4" || dd if=/dev/zero of=/dev/mapper/$DEV_NAME bs=1M count=1 oflag=direct >/dev/null 2>&1 || fail
+ $CRYPTSETUP luksSuspend $DEV_NAME || fail
+ dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail
+ echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $1 || fail
+ dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+ dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --header $1 || fail
+ $CRYPTSETUP close $DEV_NAME --header $1 || fail
+ dd if=$OPAL2_DEV of=/dev/zero bs=1M count=1 iflag=direct >/dev/null 2>&1 && fail
+ echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q --header $1 || fail
+ rm -f $1
+}
+
+export LANG=C
+
+[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
+[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
+
+# Do not run automatically.
+[ -z "$OPAL2_DEV" ] && skip "WARNING: Variable OPAL2_DEV must be defined (partition or block dev), test skipped."
+[ -z "$OPAL2_PSID_FILE" ] && skip "WARNING: Variable OPAL2_PSID_FILE must be defined, test skipped."
+[ -f "$OPAL2_PSID_FILE" ] || skip "WARNING: $OPAL2_PSID_FILE is not reachable, test skipped."
+
+prepare "[0] Detect LUKS2 environment" reset
+setup_luks2_env
+
+[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run
+
+prepare "[1] Data offset"
+echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV -q --offset 1 2>/dev/null && fail
+
+prepare "[2] Sector size and old payload alignment" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV -q --sector-size 511 2>/dev/null && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV -q --sector-size 256 2>/dev/null && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV -q --sector-size 8192 2>/dev/null && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV -q --sector-size 512 || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV -q --sector-size 4096 >/dev/null || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV -q --sector-size 2048 >/dev/null || fail
+
+prepare "[3] format" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 --hw-opal $OPAL2_DEV || fail
+# FIXME: BUG (--hw-opal-only should reject --cipher, --key-size & co)
+#echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q $FAST_PBKDF_OPT --hw-opal-only -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 $OPAL2_DEV 2> /dev/null && fail
+prepare "[4] format using hash sha512" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP $FAST_PBKDF_OPT -h sha512 -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 --hw-opal $OPAL2_DEV || fail
+$CRYPTSETUP -q luksDump $OPAL2_DEV | grep "0: pbkdf2" -A2 | grep "Hash:" | grep -qe sha512 || fail
+# Check JSON dump for some mandatory section
+$CRYPTSETUP -q luksDump $OPAL2_DEV --dump-json-metadata | grep -q '"tokens":' || fail
+
+prepare "[5] open" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q $FAST_PBKDF_OPT luksFormat --type luks2 --hw-opal $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME --test-passphrase || fail
+echo $PWDW | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME --test-passphrase 2>/dev/null && fail
+[ $? -ne 2 ] && fail "luksOpen should return EPERM exit code"
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME || fail
+check_exists
+
+prepare "" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q $FAST_PBKDF_OPT luksFormat --type luks2 --hw-opal-only $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME --test-passphrase || fail
+echo $PWDW | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME --test-passphrase 2>/dev/null && fail
+[ $? -ne 2 ] && fail "luksOpen should return EPERM exit code"
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME || fail
+check_exists
+
+# Key Slot 1 and key material section 1 must change, the rest must not.
+prepare "[6] add key" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q $FAST_PBKDF_OPT luksFormat --type luks2 --hw-opal $OPAL2_DEV || fail
+echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $OPAL2_DEV $FAST_PBKDF_OPT || fail
+echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP close $DEV_NAME || fail
+
+# Unsuccessful Key Delete - nothing may change
+prepare "[7] unsuccessful delete" new
+echo $PWDW | $CRYPTSETUP luksKillSlot $OPAL2_DEV 1 2>/dev/null && fail
+[ $? -ne 2 ] && fail "luksKillSlot should return EPERM exit code"
+
+# Delete Key Test
+# Key Slot 1 and key material section 1 must change, the rest must not
+prepare "[8] successful delete"
+$CRYPTSETUP -q luksKillSlot $OPAL2_DEV 1 || fail
+echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME 2> /dev/null && fail
+[ $? -ne 2 ] && fail "luksOpen should return EPERM exit code"
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP close $DEV_NAME || fail
+
+# Key Slot 1 and key material section 1 must change, the rest must not
+prepare "[9] add key test for key files" new
+echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $OPAL2_DEV $KEY1 || fail
+$CRYPTSETUP -d $KEY1 luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP close $DEV_NAME || fail
+
+# Key Slot 1 and key material section 1 must change, the rest must not
+prepare "[10] delete key test with key1 as remaining key" new
+$CRYPTSETUP -d $KEY1 luksKillSlot $OPAL2_DEV 0 || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP luksOpen -d $KEY1 $OPAL2_DEV $DEV_NAME || fail
+
+# Delete last slot
+prepare "[11] delete last key" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat --type luks2 --hw-opal $OPAL2_DEV $FAST_PBKDF_OPT || fail
+echo $PWD1 | $CRYPTSETUP luksKillSlot $OPAL2_DEV 0 || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+
+prepare "[12] open/close - stacked devices" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal $OPAL2_DEV $FAST_PBKDF_OPT || fail
+echo $PWD1 | $CRYPTSETUP -q luksOpen $OPAL2_DEV $DEV_NAME || fail
+echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 /dev/mapper/$DEV_NAME $FAST_PBKDF_OPT || fail
+echo $PWD1 | $CRYPTSETUP -q luksOpen /dev/mapper/$DEV_NAME $DEV_NAME2 || fail
+$CRYPTSETUP -q luksClose $DEV_NAME2 || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+
+prepare "[13] UUID - use and report provided UUID" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --uuid blah --type luks2 --hw-opal $OPAL2_DEV 2>/dev/null && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --uuid $TEST_UUID --type luks2 --hw-opal $OPAL2_DEV || fail
+tst=$($CRYPTSETUP -q luksUUID $OPAL2_DEV)
+[ "$tst"x = "$TEST_UUID"x ] || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+$CRYPTSETUP -q luksUUID --uuid $TEST_UUID $OPAL2_DEV || fail
+tst=$($CRYPTSETUP -q luksUUID $OPAL2_DEV)
+[ "$tst"x = "$TEST_UUID"x ] || fail
+
+prepare "[14] luksFormat" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom --type luks2 --hw-opal $OPAL2_DEV || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom -s 512 --uuid $TEST_UUID --type luks2 --hw-opal $OPAL2_DEV || fail
+$CRYPTSETUP luksOpen -d $KEY_PWD1 $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+# open by UUID
+if [ -d /dev/disk/by-uuid ] ; then
+ $CRYPTSETUP luksOpen -d $KEY_PWD1 UUID=X$TEST_UUID $DEV_NAME 2>/dev/null && fail
+ $CRYPTSETUP luksOpen -d $KEY_PWD1 UUID=$TEST_UUID $DEV_NAME || fail
+ $CRYPTSETUP -q luksClose $DEV_NAME || fail
+fi
+# skip tests using empty passphrases
+if [ ! fips_mode ]; then
+# empty passphrase (OPAL admin pin cannot be empty)
+echo -e "\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+$CRYPTSETUP luksOpen -d $KEYE $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+fi
+
+# format hw-opal-only
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom --type luks2 --hw-opal-only $OPAL2_DEV || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom -s 512 --uuid $TEST_UUID --type luks2 --hw-opal-only $OPAL2_DEV || fail
+$CRYPTSETUP luksOpen -d $KEY_PWD1 $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+# open by UUID
+if [ -d /dev/disk/by-uuid ] ; then
+ $CRYPTSETUP luksOpen -d $KEY_PWD1 UUID=X$TEST_UUID $DEV_NAME 2>/dev/null && fail
+ $CRYPTSETUP luksOpen -d $KEY_PWD1 UUID=$TEST_UUID $DEV_NAME || fail
+ $CRYPTSETUP -q luksClose $DEV_NAME || fail
+fi
+# skip tests using empty passphrases
+if [ ! fips_mode ]; then
+# empty passphrase (OPAL admin pin cannot be empty)
+echo -e "\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV || fail
+$CRYPTSETUP luksOpen -d $KEYE $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+fi
+
+# open by volume key
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT -s 256 --volume-key-file $KEY2 --type luks2 --hw-opal $OPAL2_DEV || fail
+$CRYPTSETUP luksOpen --volume-key-file /dev/urandom $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP luksOpen --volume-key-file $KEY2 $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+
+prepare "[15] AddKey volume key, passphrase and keyfile" wipe
+# volumekey
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --volume-key-file /dev/zero --key-slot 3 || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "3: luks2" || fail
+echo $PWD2 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $OPAL2_DEV --volume-key-file /dev/zero --key-slot 4 || fail
+echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase --key-slot 4 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "4: luks2" || fail
+echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $OPAL2_DEV --volume-key-file /dev/null --key-slot 5 2>/dev/null && fail
+$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $OPAL2_DEV --volume-key-file /dev/zero --key-slot 5 $KEY1 || fail
+$CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase --key-slot 5 -d $KEY1 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "5: luks2" || fail
+
+# special "-" handling
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --key-slot 3 || fail
+echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $OPAL2_DEV -d $KEY_PWD1 - || fail
+echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase 2>/dev/null && fail
+echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV -d - --test-passphrase || fail
+echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $OPAL2_DEV -d - $KEY2 || fail
+$CRYPTSETUP luksOpen $OPAL2_DEV -d $KEY2 --test-passphrase || fail
+echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV -d - -d $KEY1 --test-passphrase 2>/dev/null && fail
+echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV -d $KEY1 -d $KEY1 --test-passphrase 2>/dev/null && fail
+
+# [0]PWD3 [1]PWD2 [3]PWD1 [4]KEY2
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --key-slot 3 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "3: luks2" || fail
+$CRYPTSETUP luksAddKey -q $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY_PWD1 $KEY2 --key-slot 3 2>/dev/null && fail
+# keyfile/keyfile
+$CRYPTSETUP luksAddKey -q $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY_PWD1 $KEY2 --key-slot 4 || fail
+$CRYPTSETUP luksOpen $OPAL2_DEV -d $KEY2 --test-passphrase --key-slot 4 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "4: luks2" || fail
+# passphrase/keyfile
+echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $OPAL2_DEV -d $KEY_PWD1 --key-slot 0 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "0: luks2" || fail
+echo $PWD3 | $CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase --key-slot 0 || fail
+# passphrase/passphrase
+echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $OPAL2_DEV --key-slot 1 || fail
+echo $PWD2 | $CRYPTSETUP luksOpen $OPAL2_DEV --test-passphrase --key-slot 1 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "1: luks2" || fail
+# keyfile/passphrase
+echo -e "$PWD2\n" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $OPAL2_DEV $KEY_PWD1 --key-slot 2 --new-keyfile-size 8 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "2: luks2" || fail
+
+prepare "[16] RemoveKey passphrase and keyfile" reuse
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "3: luks2" || fail
+$CRYPTSETUP luksRemoveKey $OPAL2_DEV $KEY_PWD1 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "3: luks2" && fail
+$CRYPTSETUP luksRemoveKey $OPAL2_DEV $KEY_PWD1 2>/dev/null && fail
+[ $? -ne 2 ] && fail "luksRemoveKey should return EPERM exit code"
+$CRYPTSETUP luksRemoveKey $OPAL2_DEV $KEY2 --keyfile-size 1 2>/dev/null && fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "4: luks2" || fail
+$CRYPTSETUP luksRemoveKey $OPAL2_DEV $KEY2 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "4: luks2" && fail
+# if password or keyfile is provided, batch mode must not suppress it
+echo "badpw" | $CRYPTSETUP luksKillSlot $OPAL2_DEV 2 2>/dev/null && fail
+echo "badpw" | $CRYPTSETUP luksKillSlot $OPAL2_DEV 2 -q 2>/dev/null && fail
+echo "badpw" | $CRYPTSETUP luksKillSlot $OPAL2_DEV 2 --key-file=- 2>/dev/null && fail
+echo "badpw" | $CRYPTSETUP luksKillSlot $OPAL2_DEV 2 --key-file=- -q 2>/dev/null && fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "2: luks2" || fail
+# kill slot using passphrase from 1
+echo $PWD2 | $CRYPTSETUP luksKillSlot $OPAL2_DEV 2 2>/dev/null || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "2: luks2" && fail
+# remove key0 / slot 0
+echo $PWD3 | $CRYPTSETUP luksRemoveKey $OPAL2_DEV || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "0: luks2" && fail
+# last keyslot, in batch mode no passphrase needed...
+$CRYPTSETUP luksKillSlot -q $OPAL2_DEV 1 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "1: luks2" && fail
+
+prepare "[17] create & resize" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME || fail
+# OPAL2 devices cannot be resized
+$CRYPTSETUP -q resize --size 99 $DEV_NAME <&- 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP -q resize --size 99 $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP close $DEV_NAME || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT -q --type luks2 --hw-opal-only $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME || fail
+# OPAL2 devices cannot be resized
+$CRYPTSETUP -q resize --size 99 $DEV_NAME <&- 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP -q resize --size 99 $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP close $DEV_NAME || fail
+echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail
+
+prepare "[18] Disallow open/create if already mapped." wipe
+$CRYPTSETUP create -q $DEV_NAME $OPAL2_DEV -d $KEY1 2>/dev/null || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV 2>/dev/null && fail
+$CRYPTSETUP remove $DEV_NAME || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV $DEV_NAME || fail
+echo $PWD1 | $CRYPTSETUP luksOpen -q $OPAL2_DEV $DEV_NAME2 >/dev/null 2>&1 && fail
+dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 || fail "OPAL segment perhaps locked after failed activation over already active device."
+$CRYPTSETUP luksClose $DEV_NAME || fail
+
+prepare "[19] luksDump" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --key-size 256 $FAST_PBKDF_OPT --uuid $TEST_UUID --type luks2 --hw-opal $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $OPAL2_DEV -d $KEY_PWD1 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "0: luks2" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q $TEST_UUID || fail
+echo $PWDW | $CRYPTSETUP luksDump $OPAL2_DEV --dump-volume-key 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP luksDump $OPAL2_DEV --dump-volume-key | grep -q "MK dump:" || fail
+$CRYPTSETUP luksDump -q $OPAL2_DEV --dump-volume-key -d $KEY_PWD1 | grep -q "MK dump:" || fail
+echo $PWD1 | $CRYPTSETUP luksDump -q $OPAL2_DEV --dump-master-key --master-key-file $VK_FILE >/dev/null || fail
+rm -f $VK_FILE
+echo $PWD1 | $CRYPTSETUP luksDump -q $OPAL2_DEV --dump-volume-key --volume-key-file $VK_FILE >/dev/null || fail
+echo $PWD1 | $CRYPTSETUP luksDump -q $OPAL2_DEV --dump-volume-key --volume-key-file $VK_FILE 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --volume-key-file $VK_FILE $OPAL2_DEV || fail
+# Use volume key file without keyslots
+echo $PWD1 | $CRYPTSETUP luksRemoveKey -q $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksRemoveKey -q $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksRemoveKey -q $OPAL2_DEV || fail
+$CRYPTSETUP luksOpen --volume-key-file $VK_FILE --key-size 512 --test-passphrase $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --volume-key-file $VK_FILE --key-size 512 $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksOpen --test-passphrase $OPAL2_DEV || fail
+
+prepare "[20] ChangeKey passphrase and keyfile" wipe
+# [0]PWD1 [1]PWD2
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal $OPAL2_DEV $FAST_PBKDF_OPT --key-slot 0 --key-size 256 --luks2-keyslots-size 756k >/dev/null || fail
+echo $PWD2 | $CRYPTSETUP luksAddKey -q $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY_PWD1 --key-slot 1 || fail
+# [0]KEY2 [1]PWD2
+$CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY_PWD1 $KEY2 --key-slot 0 || fail
+# [0]KEY2 [1]PWD1
+echo -e "$PWD2\n$PWD1" | $CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT --key-slot 1 || fail
+# [0]KEY1 [1]PWD1 - with LUKS2 it should stay
+$CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY2 $KEY1 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "0: luks2" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "2: luks2" && fail
+# [0]KEY1 [1]PWD2
+echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT $OPAL2_DEV || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "1: luks2" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "2: luks2" && fail
+# test out of raw area, change in-place (space only for 2 keyslots)
+$CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "0: luks2" || fail
+$CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 2>/dev/null && fail
+# make a free space in keyslot area
+echo $PWD2 | $CRYPTSETUP luksKillSlot -q $OPAL2_DEV 0 || fail
+
+# assert LUKS2 does not overwrite existing area with specific keyslot id
+AREA_OFFSET_OLD=$($CRYPTSETUP luksDump $OPAL2_DEV | grep -e "1: luks2" -A12 | grep -e "Area offset:" | cut -d: -f 2 | sed -e 's/[[:space:]]*\[bytes\]//g')
+[ 0$AREA_OFFSET_OLD -gt 0 ] || fail
+echo -e "$PWD2\n$PWD1\n" | $CRYPTSETUP luksChangeKey --key-slot 1 $OPAL2_DEV $FAST_PBKDF_OPT || fail
+AREA_OFFSET_NEW=$($CRYPTSETUP luksDump $OPAL2_DEV | grep -e "1: luks2" -A12 | grep -e "Area offset:" | cut -d: -f 2 | sed -e 's/[[:space:]]*\[bytes\]//g')
+[ 0$AREA_OFFSET_NEW -gt 0 ] || fail
+[ $AREA_OFFSET_OLD -ne $AREA_OFFSET_NEW ] || fail "Area offsets remained same: old area $AREA_OFFSET_OLD, new area $AREA_OFFSET_NEW"
+
+# assert LUKS2 does not overwrite existing area with any sklot
+AREA_OFFSET_OLD=$($CRYPTSETUP luksDump $OPAL2_DEV | grep -e "1: luks2" -A12 | grep -e "Area offset:" | cut -d: -f 2 | sed -e 's/[[:space:]]*\[bytes\]//g')
+[ 0$AREA_OFFSET_OLD -gt 0 ] || fail
+echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT || fail
+AREA_OFFSET_NEW=$($CRYPTSETUP luksDump $OPAL2_DEV | grep -e "1: luks2" -A12 | grep -e "Area offset:" | cut -d: -f 2 | sed -e 's/[[:space:]]*\[bytes\]//g')
+[ 0$AREA_OFFSET_NEW -gt 0 ] || fail
+[ $AREA_OFFSET_OLD -ne $AREA_OFFSET_NEW ] || fail "Area offsets remained same: old area $AREA_OFFSET_OLD, new area $AREA_OFFSET_NEW"
+
+prepare "[21] Keyfile limit" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --key-slot 0 || fail
+echo $PWD1 | $CRYPTSETUP luksChangeKey $OPAL2_DEV $KEY1 --new-keyfile-size 13 $FAST_PBKDF_OPT || fail
+echo $PWD1 | $CRYPTSETUP open --test-passphrase $OPAL2_DEV -q 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY1 luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY1 -l 0 luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY1 -l -1 luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY1 -l 14 luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY1 -l 13 --keyfile-offset 1 luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY1 -l 13 --keyfile-offset -1 luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY1 -l 13 luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP luksClose $DEV_NAME || fail
+$CRYPTSETUP luksAddKey $OPAL2_DEV -d $KEY1 $KEY2 2>/dev/null && fail
+$CRYPTSETUP luksAddKey $OPAL2_DEV -d $KEY1 $KEY2 -l 14 2>/dev/null && fail
+$CRYPTSETUP luksAddKey $OPAL2_DEV -d $KEY1 $KEY2 -l -1 2>/dev/null && fail
+$CRYPTSETUP luksAddKey $OPAL2_DEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT -l 13 --new-keyfile-size 12 || fail
+$CRYPTSETUP luksRemoveKey $OPAL2_DEV $KEY2 2>/dev/null && fail
+$CRYPTSETUP luksRemoveKey $OPAL2_DEV $KEY2 -l 12 || fail
+$CRYPTSETUP luksChangeKey $OPAL2_DEV -d $KEY1 $KEY2 2>/dev/null && fail
+[ $? -ne 2 ] && fail "luksChangeKey should return EPERM exit code"
+$CRYPTSETUP luksChangeKey $OPAL2_DEV -d $KEY1 $KEY2 -l 14 2>/dev/null && fail
+$CRYPTSETUP luksChangeKey $OPAL2_DEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT -l 13 || fail
+# -l is ignored for stdin if _only_ passphrase is used
+echo $PWD1 | $CRYPTSETUP luksAddKey $OPAL2_DEV -d $KEY2 $FAST_PBKDF_OPT || fail
+# this is stupid, but expected
+echo $PWD1 | $CRYPTSETUP luksRemoveKey $OPAL2_DEV -l 11 2>/dev/null && fail
+echo $PWDW"0" | $CRYPTSETUP luksRemoveKey $OPAL2_DEV -l 12 2>/dev/null && fail
+echo -e "$PWD1\n" | $CRYPTSETUP luksRemoveKey $OPAL2_DEV -d- -l 12 || fail
+# offset
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --key-slot 0 || fail
+echo $PWD1 | $CRYPTSETUP luksChangeKey $OPAL2_DEV $KEY1 --new-keyfile-offset 16 --new-keyfile-size 13 $FAST_PBKDF_OPT || fail
+$CRYPTSETUP --key-file=$KEY1 -l 13 --keyfile-offset 15 luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY1 -l 13 --keyfile-offset 16 luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP luksClose $DEV_NAME || fail
+$CRYPTSETUP luksAddKey $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY1 -l 13 --keyfile-offset 16 $KEY2 --new-keyfile-offset 1 || fail
+$CRYPTSETUP --key-file=$KEY2 --keyfile-offset 11 luksOpen $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP --key-file=$KEY2 --keyfile-offset 1 luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP luksClose $DEV_NAME || fail
+$CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY2 --keyfile-offset 1 $KEY2 --new-keyfile-offset 0 || fail
+$CRYPTSETUP luksOpen -d $KEY2 $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP luksClose $DEV_NAME || fail
+
+prepare "[22] Suspend/Resume" wipe
+# OPAL+dm-crypt
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP -q luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP luksSuspend $DEV_NAME || fail
+$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail
+dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
+$CRYPTSETUP -q resize $DEV_NAME 2>/dev/null && fail
+echo $PWDW | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail
+[ $? -ne 2 ] && fail "luksResume should return EPERM exit code"
+echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME || fail
+dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat -c null $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP -q luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP luksSuspend $DEV_NAME || fail
+$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail
+dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
+echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME || fail
+dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+
+# OPAL only
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP -q luksOpen $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP luksSuspend $DEV_NAME || fail
+$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail
+dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
+$CRYPTSETUP -q resize $DEV_NAME 2>/dev/null && fail
+echo $PWDW | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail
+[ $? -ne 2 ] && fail "luksResume should return EPERM exit code"
+echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME || fail
+dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 || fail
+$CRYPTSETUP -q luksClose $DEV_NAME || fail
+
+prepare "[23] luksOpen/Resume with specified key slot number" wipe
+# first, let's try passphrase option
+echo -e "$PWD3\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT -S 5 --type luks2 --hw-opal $OPAL2_DEV || fail
+echo $PWD3 | $CRYPTSETUP luksOpen -S 4 $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+[ -b /dev/mapper/$DEV_NAME ] && fail
+echo $PWD3 | $CRYPTSETUP luksOpen -S 5 $OPAL2_DEV $DEV_NAME || fail
+check_exists
+$CRYPTSETUP luksSuspend $DEV_NAME || fail
+echo $PWD3 | $CRYPTSETUP luksResume -S 4 $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail
+dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
+echo $PWD3 | $CRYPTSETUP luksResume -S 5 $DEV_NAME || fail
+dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 || fail
+$CRYPTSETUP luksClose $DEV_NAME || fail
+echo -e "$PWD3\n$PWD1" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 0 $OPAL2_DEV || fail
+echo $PWD3 | $CRYPTSETUP luksOpen -S 0 $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+[ -b /dev/mapper/$DEV_NAME ] && fail
+echo $PWD1 | $CRYPTSETUP luksOpen -S 5 $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+[ -b /dev/mapper/$DEV_NAME ] && fail
+# second, try it with keyfiles
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat -q -S 5 $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+echo "$PWD1" | $CRYPTSETUP luksChangeKey -q -S 5 $FAST_PBKDF_OPT $OPAL2_DEV $KEY5 || fail
+$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 1 -d $KEY5 $OPAL2_DEV $KEY1 || fail
+$CRYPTSETUP luksOpen -S 5 -d $KEY5 $OPAL2_DEV $DEV_NAME || fail
+check_exists
+$CRYPTSETUP luksSuspend $DEV_NAME || fail
+dd if=$OPAL2_DEV of=/dev/zero bs=1M skip=16 count=1 iflag=direct >/dev/null 2>&1 && fail
+$CRYPTSETUP luksResume -S 1 -d $KEY5 $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail
+$CRYPTSETUP luksResume -S 5 -d $KEY5 $DEV_NAME || fail
+dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 || fail
+$CRYPTSETUP luksClose $DEV_NAME || fail
+$CRYPTSETUP luksOpen -S 1 -d $KEY5 $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+[ -b /dev/mapper/$DEV_NAME ] && fail
+$CRYPTSETUP luksOpen -S 5 -d $KEY1 $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+[ -b /dev/mapper/$DEV_NAME ] && fail
+
+prepare "[24] Detached LUKS header" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --header $HEADER_IMG || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --header $HEADER_IMG --align-payload 1 >/dev/null 2>&1 && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --header $HEADER_IMG --align-payload 8192 || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --header $HEADER_IMG --align-payload 4096 >/dev/null || fail
+$CRYPTSETUP luksDump $HEADER_IMG | grep -e "0: hw-opal-crypt" -A1 | grep -qe $((4096*512)) || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --header $HEADER_IMG --align-payload 0 --sector-size 512 || fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV-missing --header $HEADER_IMG $DEV_NAME 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP luksOpen $OPAL2_DEV --header $HEADER_IMG $DEV_NAME || fail
+$CRYPTSETUP -q status $DEV_NAME | grep "type:" | grep -q "n/a" || fail
+$CRYPTSETUP luksSuspend $DEV_NAME --header $HEADER_IMG || fail
+dd if=$OPAL2_DEV of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 && fail
+echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail
+dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 || fail
+$CRYPTSETUP luksSuspend $DEV_NAME || fail
+dd if=$OPAL2_DEV of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 && fail
+echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail
+dd if=/dev/mapper/$DEV_NAME of=/dev/zero bs=4K count=1 iflag=direct >/dev/null 2>&1 || fail
+$CRYPTSETUP luksClose $DEV_NAME || fail
+echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 5 _fakedev_ --header $HEADER_IMG $KEY5 || fail
+$CRYPTSETUP luksDump _fakedev_ --header $HEADER_IMG | grep -q "5: luks2" || fail
+$CRYPTSETUP luksKillSlot -q _fakedev_ --header $HEADER_IMG 5 || fail
+$CRYPTSETUP luksDump _fakedev_ --header $HEADER_IMG | grep -q "5: luks2" && fail
+echo $PWD1 | $CRYPTSETUP open --test-passphrase $HEADER_IMG || fail
+rm $HEADER_IMG || fail
+# create exactly 16 MiBs LUKS2 header
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --header $HEADER_IMG --luks2-keyslots-size 16352k --luks2-metadata-size 16k --offset 131072 >/dev/null || fail
+SIZE=$(stat --printf=%s $HEADER_IMG)
+test $SIZE -eq 16777216 || fail
+$CRYPTSETUP -q luksDump $HEADER_IMG | grep -q "offset: $((512 * 131072)) \[bytes\]" || fail
+
+prepare "[25] LUKS erase" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase -q $OPAL2_DEV || fail
+$CRYPTSETUP isLuks -q $OPAL2_DEV && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV || fail
+echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase -q $OPAL2_DEV || fail
+$CRYPTSETUP isLuks -q $OPAL2_DEV && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+# test psid reset once with valgrind
+$CRYPTSETUP luksErase --hw-opal-factory-reset --key-file $OPAL2_PSID_FILE $OPAL2_DEV -q || fail
+
+prepare "[26] LUKS convert" wipe
+# create almost compatible LUKS2 device except OPAL segment
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --sector-size 512 -s256 --hw-opal $OPAL2_DEV || fail
+$CRYPTSETUP -q convert --type luks1 $OPAL2_DEV >/dev/null 2>&1 && fail
+$CRYPTSETUP isLuks --type luks2 $OPAL2_DEV || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --sector-size 512 -s256 --hw-opal-only $OPAL2_DEV || fail
+$CRYPTSETUP -q convert --type luks1 $OPAL2_DEV >/dev/null 2>&1 && fail
+$CRYPTSETUP isLuks --type luks2 $OPAL2_DEV || fail
+
+if dm_crypt_keyring_support && dm_crypt_keyring_new_kernel; then
+ prepare "[27] LUKS2 key in keyring" wipe
+ echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --header $HEADER_IMG || fail
+
+ # check keyring support detection works as expected
+ rmmod dm-crypt >/dev/null 2>&1 || true
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV --header $HEADER_IMG $DEV_NAME || fail
+ $CRYPTSETUP -q status $DEV_NAME | grep "key location:" | grep -q "keyring" || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV --disable-keyring --header $HEADER_IMG $DEV_NAME || fail
+ $CRYPTSETUP -q status $DEV_NAME | grep "key location:" | grep -q "dm-crypt" || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV --disable-keyring --header $HEADER_IMG $DEV_NAME || fail
+ $CRYPTSETUP luksSuspend $DEV_NAME || fail
+ echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail
+ $CRYPTSETUP -q status $DEV_NAME | grep "key location:" | grep -q "keyring" || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV --header $HEADER_IMG $DEV_NAME || fail
+ $CRYPTSETUP luksSuspend $DEV_NAME || fail
+ echo $PWD1 | $CRYPTSETUP luksResume --disable-keyring $DEV_NAME --header $HEADER_IMG || fail
+ $CRYPTSETUP -q status $DEV_NAME | grep "key location:" | grep -q "dm-crypt" || fail
+ $CRYPTSETUP close $DEV_NAME || fail
+fi
+
+prepare "[28] tokens" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
+
+ test_and_prepare_keyring
+
+ $CRYPTSETUP token add $OPAL2_DEV --key-description $TEST_TOKEN0 --token-id 3 || fail
+ $CRYPTSETUP luksDump $OPAL2_DEV | grep -q -e "3: luks2-keyring" || fail
+ # keyslot 5 is inactive
+ $CRYPTSETUP token add $OPAL2_DEV --key-description $TEST_TOKEN1 --key-slot 5 2> /dev/null && fail
+ # key description is not reachable
+ $CRYPTSETUP open --token-only $OPAL2_DEV --test-passphrase && fail
+ # wrong passphrase
+ load_key user $TEST_TOKEN0 "blabla" "$TEST_KEYRING" || fail "Cannot load 32 byte user key type"
+ $CRYPTSETUP open --token-only $OPAL2_DEV --test-passphrase 2>/dev/null && fail
+ load_key user $TEST_TOKEN0 $PWD1 "$TEST_KEYRING" || fail "Cannot load 32 byte user key type"
+ $CRYPTSETUP open --token-only $OPAL2_DEV --test-passphrase || fail
+ $CRYPTSETUP open --token-only $OPAL2_DEV $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)
+ echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $OPAL2_DEV --token-id 22 || fail
+ # this excludes keyring tokens from unlocking device
+ $CRYPTSETUP open --token-only --token-type some_type $OPAL2_DEV --test-passphrase && fail
+ $CRYPTSETUP open --token-only --token-type some_type $OPAL2_DEV $DEV_NAME && fail
+ $CRYPTSETUP status $DEV_NAME > /dev/null && fail
+
+ $CRYPTSETUP token remove --token-id 3 $OPAL2_DEV || fail
+ $CRYPTSETUP luksDump $OPAL2_DEV | grep -q -e "3: luks2-keyring" && fail
+
+ # test we can remove keyslot with token
+ echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -q -S4 $FAST_PBKDF_OPT $OPAL2_DEV || fail
+ $CRYPTSETUP token add $OPAL2_DEV --key-description $TEST_TOKEN1 --key-slot 4 --token-id 0 || fail
+ $CRYPTSETUP -q luksKillSlot $OPAL2_DEV 4 || fail
+ $CRYPTSETUP token remove --token-id 0 $OPAL2_DEV || fail
+
+ # test we can add unassigned token
+ $CRYPTSETUP token add $OPAL2_DEV --key-description $TEST_TOKEN0 --unbound --token-id 0 || fail
+ $CRYPTSETUP open --token-only --token-id 0 --test-passphrase $OPAL2_DEV && fail
+ $CRYPTSETUP token remove --token-id 0 $OPAL2_DEV || fail
+
+ # test token unassign works
+ $CRYPTSETUP token add $OPAL2_DEV --key-description $TEST_TOKEN0 -S0 --token-id 0 || fail
+ $CRYPTSETUP open --token-only --token-id 0 --test-passphrase $OPAL2_DEV || fail
+ $CRYPTSETUP token unassign --token-id 0 $OPAL2_DEV 2>/dev/null && fail
+ $CRYPTSETUP token unassign -S0 $OPAL2_DEV 2>/dev/null && fail
+ $CRYPTSETUP token unassign --token-id 0 -S0 $OPAL2_DEV || fail
+ $CRYPTSETUP open --token-only --token-id 0 --test-passphrase $OPAL2_DEV && fail
+ $CRYPTSETUP token unassign --token-id 0 -S0 $OPAL2_DEV 2>/dev/null && fail
+ $CRYPTSETUP token unassign --token-id 0 -S44 $OPAL2_DEV 2>/dev/null && fail
+ $CRYPTSETUP token unassign --token-id 44 -S0 $OPAL2_DEV 2>/dev/null && fail
+fi
+echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $OPAL2_DEV --token-id 10 || fail
+echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $OPAL2_DEV --token-id 11 --json-file - || fail
+echo -n "$IMPORT_TOKEN" > $TOKEN_FILE0
+$CRYPTSETUP token import $OPAL2_DEV --token-id 12 --json-file $TOKEN_FILE0 || fail
+$CRYPTSETUP token import $OPAL2_DEV --token-id 12 --json-file $TOKEN_FILE0 2>/dev/null && fail
+$CRYPTSETUP token export $OPAL2_DEV --token-id 10 >$TOKEN_FILE1 || fail
+diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
+$CRYPTSETUP token export $OPAL2_DEV --token-id 11 >$TOKEN_FILE1 || fail
+diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
+$CRYPTSETUP token export $OPAL2_DEV --token-id 12 >$TOKEN_FILE1 || fail
+diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
+$CRYPTSETUP token export $OPAL2_DEV --token-id 12 --json-file $TOKEN_FILE1 || fail
+diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
+$CRYPTSETUP token export $OPAL2_DEV --token-id 12 > $TOKEN_FILE1 || fail
+diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
+
+prepare "[29] LUKS keyslot priority" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV -S 1 || fail
+echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -q $OPAL2_DEV $FAST_PBKDF_OPT -S 5 || fail
+$CRYPTSETUP config $OPAL2_DEV -S 0 --priority prefer && fail
+$CRYPTSETUP config $OPAL2_DEV -S 1 --priority bla >/dev/null 2>&1 && fail
+$CRYPTSETUP config $OPAL2_DEV -S 1 --priority ignore || fail
+echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV --test-passphrase 2>/dev/null && fail
+echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV --test-passphrase -S 1 || fail
+echo $PWD2 | $CRYPTSETUP open $OPAL2_DEV --test-passphrase || fail
+$CRYPTSETUP config $OPAL2_DEV -S 1 --priority normal || fail
+echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV --test-passphrase || fail
+$CRYPTSETUP config $OPAL2_DEV -S 1 --priority ignore || fail
+echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV --test-passphrase 2>/dev/null && fail
+
+prepare "[30] LUKS label and subsystem" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Subsystem:" | grep -q "HW-OPAL" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Label:" | grep -q "(no label)" || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --subsystem SatelliteTwo --label TheLabel || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Subsystem:" | grep -q "SatelliteTwo" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Label:" | grep -q "TheLabel" || fail
+$CRYPTSETUP config $OPAL2_DEV --subsystem SatelliteThree
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Subsystem:" | grep -q "SatelliteThree" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Label:" | grep -q "(no label)" || fail
+$CRYPTSETUP config $OPAL2_DEV --subsystem SatelliteThree --label TheLabel
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Subsystem:" | grep -q "SatelliteThree" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Label:" | grep -q "TheLabel" || fail
+
+prepare "[31] LUKS PBKDF setting" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat --type luks2 --hw-opal --pbkdf bla $OPAL2_DEV >/dev/null 2>&1 && fail
+# Force setting, no benchmark. PBKDF2 has 1000 iterations as a minimum
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" |$CRYPTSETUP luksFormat --type luks2 --hw-opal --pbkdf pbkdf2 --pbkdf-force-iterations 999 $OPAL2_DEV 2>/dev/null && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal --pbkdf pbkdf2 --pbkdf-force-iterations 1234 $OPAL2_DEV || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Iterations:" | grep -q "1234" || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal --pbkdf argon2id --pbkdf-force-iterations 3 $OPAL2_DEV 2>/dev/null && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal --pbkdf argon2id --pbkdf-force-iterations 4 --pbkdf-memory 100000 $OPAL2_DEV || can_fail_fips
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "PBKDF:" | grep -q "argon2id" || can_fail_fips
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal --pbkdf argon2i --pbkdf-force-iterations 4 \
+ --pbkdf-memory 1234 --pbkdf-parallel 1 $OPAL2_DEV || can_fail_fips
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "PBKDF:" | grep -q "argon2i" || can_fail_fips
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Time cost:" | grep -q "4" || can_fail_fips
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Memory:" | grep -q "1234" || can_fail_fips
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Threads:" | grep -q "1" || can_fail_fips
+# Benchmark
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal --pbkdf argon2i -i 500 --pbkdf-memory 1234 --pbkdf-parallel 1 $OPAL2_DEV || can_fail_fips
+[ 0"$($CRYPTSETUP luksDump $OPAL2_DEV | grep "Time cost:" | cut -d: -f 2 | sed -e 's/\ //g')" -gt 0 ] || can_fail_fips
+[ 0"$($CRYPTSETUP luksDump $OPAL2_DEV | grep "Memory:" | cut -d: -f 2 | sed -e 's/\ //g')" -gt 0 ] || can_fail_fips
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal --pbkdf pbkdf2 -i 500 $OPAL2_DEV || fail
+[ 0"$($CRYPTSETUP luksDump $OPAL2_DEV | grep -m1 "Iterations:" | cut -d' ' -f 2 | sed -e 's/\ //g')" -gt 1000 ] || fail
+
+prepare "[32] LUKS Keyslot convert" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --key-slot 0 || fail
+echo "$PWD1" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S0 --new-key-slot 5 $OPAL2_DEV $KEY5 || fail
+$CRYPTSETUP -q luksKillSlot $OPAL2_DEV 0 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "5: luks2" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "PBKDF:" | grep -q "pbkdf2" || fail
+$CRYPTSETUP -q luksConvertKey $OPAL2_DEV -S 5 --key-file $KEY5 --pbkdf argon2i -i1 --pbkdf-memory 32 || can_fail_fips
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "5: luks2" || can_fail_fips
+echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $OPAL2_DEV -S 1 --key-file $KEY5 || fail
+$CRYPTSETUP -q luksKillSlot $OPAL2_DEV 5 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "1: luks2" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "PBKDF:" | grep -q "pbkdf2" || fail
+echo $PWD1 | $CRYPTSETUP -q luksConvertKey $OPAL2_DEV -S 1 --pbkdf argon2i -i1 --pbkdf-memory 32 || can_fail_fips
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "1: luks2" || can_fail_fips
+echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 21 --unbound -s 72 $OPAL2_DEV || fail
+echo $PWD3 | $CRYPTSETUP luksConvertKey --pbkdf-force-iterations 1001 --pbkdf pbkdf2 -S 21 $OPAL2_DEV || fail
+
+prepare "[33] luksAddKey unbound tests" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --key-slot 5 || fail
+# unbound key may have arbitrary size
+echo $PWD1 | $CRYPTSETUP luksChangeKey -q $OPAL2_DEV $FAST_PBKDF_OPT -S5 $KEY5 || fail
+echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --unbound -s 72 $OPAL2_DEV || fail
+echo $PWD2 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --unbound -s 72 -S 2 $OPAL2_DEV || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "2: luks2 (unbound)" || fail
+dd if=/dev/urandom of=$KEY_FILE0 bs=64 count=1 > /dev/null 2>&1 || fail
+echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --unbound -s 512 -S 3 --volume-key-file $KEY_FILE0 $OPAL2_DEV || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "3: luks2 (unbound)" || fail
+# unbound key size is required
+echo $PWD1 | $CRYPTSETUP -q luksAddKey --unbound $OPAL2_DEV 2>/dev/null && fail
+echo $PWD3 | $CRYPTSETUP -q luksAddKey --unbound --volume-key-file /dev/urandom $OPAL2_DEV 2> /dev/null && fail
+# do not allow one to replace keyslot by unbound slot
+echo $PWD1 | $CRYPTSETUP -q luksAddKey -S5 --unbound -s 32 $OPAL2_DEV 2>/dev/null && fail
+echo $PWD2 | $CRYPTSETUP -q open $OPAL2_DEV $DEV_NAME 2> /dev/null && fail
+echo $PWD2 | $CRYPTSETUP -q open -S2 $OPAL2_DEV $DEV_NAME 2> /dev/null && fail
+echo $PWD2 | $CRYPTSETUP -q open -S2 $OPAL2_DEV --test-passphrase || fail
+echo $PWD1 | $CRYPTSETUP -q open $OPAL2_DEV $DEV_NAME 2> /dev/null && fail
+# check we're able to change passphrase for unbound keyslot
+echo -e "$PWD2\n$PWD3" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT -S 2 $OPAL2_DEV || fail
+echo $PWD3 | $CRYPTSETUP open --test-passphrase -S 2 $OPAL2_DEV || fail
+echo $PWD3 | $CRYPTSETUP -q open -S 2 $OPAL2_DEV $DEV_NAME 2> /dev/null && fail
+# do not allow adding keyslot by unbound keyslot
+echo -e "$PWD3\n$PWD1" | $CRYPTSETUP -q luksAddKey $OPAL2_DEV 2> /dev/null && fail
+# check adding keyslot works when there's unbound keyslot
+echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $OPAL2_DEV --key-file $KEY5 -S8 || fail
+echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME || fail
+$CRYPTSETUP close $DEV_NAME || fail
+$CRYPTSETUP luksKillSlot -q $OPAL2_DEV 2
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "2: luks2 (unbound)" && fail
+echo $PWD3 | $CRYPTSETUP luksDump --unbound --volume-key-file $KEY_FILE1 $OPAL2_DEV 2> /dev/null && fail
+echo $PWD3 | $CRYPTSETUP luksDump --unbound 2> /dev/null $OPAL2_DEV 2> /dev/null && fail
+echo $PWD3 | $CRYPTSETUP luksDump --unbound --volume-key-file $KEY_FILE1 -S3 $OPAL2_DEV > /dev/null || fail
+diff $KEY_FILE0 $KEY_FILE1 || fail
+echo $PWD3 | $CRYPTSETUP luksDump --unbound --volume-key-file $KEY_FILE1 -S3 $OPAL2_DEV 2> /dev/null && fail
+diff $KEY_FILE0 $KEY_FILE1 || fail
+rm $KEY_FILE1 || fail
+echo $PWD3 | $CRYPTSETUP luksDump --unbound --volume-key-file $KEY_FILE1 -S3 $OPAL2_DEV | grep -q "Unbound Key:" && fail
+echo $PWD3 | $CRYPTSETUP luksDump --unbound -S3 $OPAL2_DEV | grep -q "Unbound Key:" || fail
+$CRYPTSETUP luksKillSlot -q $OPAL2_DEV 3 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep -q "3: luks2 (unbound)" && fail
+
+prepare "[34] LUKS2 metadata areas" wipe
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV 2> /dev/null || fail
+DEFAULT_OFFSET=$($CRYPTSETUP luksDump $OPAL2_DEV | grep "offset: " | cut -f 2 -d ' ')
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=127k 2> /dev/null && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-metadata-size=127k --luks2-keyslots-size=128k 2> /dev/null && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=128M >/dev/null 2>&1 && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-metadata-size=128k --luks2-keyslots-size=128k >/dev/null || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail
+echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal $OPAL2_DEV --key-size 256 --luks2-metadata-size=128k || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Keyslots area:" | grep -q "$((DEFAULT_OFFSET-2*131072)) \[bytes\]" || fail
+echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --luks2-keyslots-size=128k >/dev/null || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Metadata area:" | grep -q "16384 \[bytes\]" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail
+echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --offset 16384 || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Metadata area:" | grep -q "16384 \[bytes\]" || fail
+$CRYPTSETUP luksDump $OPAL2_DEV | grep "Keyslots area:" | grep -q "8355840 \[bytes\]" || fail
+echo $OPAL2_ADMIN_PIN | $CRYPTSETUP luksErase $OPAL2_DEV -q || fail
+# data offset vs area size
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --offset 64 --luks2-keyslots-size=8192 >/dev/null 2>&1 && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --offset $((256+56)) >/dev/null 2>&1 && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --hw-opal-only $OPAL2_DEV --key-size 256 --offset $((256+64)) >/dev/null || fail
+
+prepare "[35] Per-keyslot encryption parameters" wipe
+KEYSLOT_CIPHER="aes-cbc-plain64"
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal-only $OPAL2_DEV $FAST_PBKDF_OPT --key-slot 0 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 || fail
+echo $PWD1 | $CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT --key-slot 0 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 $KEY1 || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "0: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "0: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail
+$CRYPTSETUP luksAddKey -q $OPAL2_DEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT --key-slot 1 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "1: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "1: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail
+$CRYPTSETUP luksAddKey -q $OPAL2_DEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT --key-slot 2 || fail
+$CRYPTSETUP luksChangeKey $OPAL2_DEV $FAST_PBKDF_OPT -d $KEY2 $KEY1 --key-slot 2 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "2: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "2: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail
+# unbound keyslot
+echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --key-slot 21 --unbound -s 72 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 $OPAL2_DEV || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "21: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "21: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail
+echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --key-slot 22 --unbound -s 72 $OPAL2_DEV || fail
+echo $PWD3 | $CRYPTSETUP luksConvertKey --key-slot 22 $OPAL2_DEV --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 $OPAL2_DEV || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "22: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail
+[ "$($CRYPTSETUP luksDump $OPAL2_DEV | grep -A8 -m1 "22: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail
+
+prepare "[36] Some encryption compatibility mode tests" wipe
+CIPHERS="aes-ecb aes-cbc-null aes-cbc-plain64 aes-cbc-essiv:sha256 aes-xts-plain64"
+key_size=256
+for cipher in $CIPHERS ; do
+ echo -n "[$cipher/$key_size]"
+ echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat --type luks2 --hw-opal $OPAL2_DEV $FAST_PBKDF_OPT --cipher $cipher --key-size $key_size || fail
+done
+echo
+
+prepare "[37] New luksAddKey options." wipe
+rm -f $VK_FILE
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP luksFormat -q --type luks2 --hw-opal-only $FAST_PBKDF_OPT $OPAL2_DEV || fail
+echo $PWD1 | $CRYPTSETUP luksDump -q $OPAL2_DEV --dump-volume-key --volume-key-file $VK_FILE >/dev/null || fail
+
+# pass pass
+echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -q -S1 $FAST_PBKDF_OPT $OPAL2_DEV || fail
+echo $PWD2 | $CRYPTSETUP open -q --test-passphrase -S1 $OPAL2_DEV || fail
+
+# pass file
+echo "$PWD2" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S1 --new-key-slot 2 $OPAL2_DEV $KEY1 || fail
+$CRYPTSETUP open --test-passphrase -q -S2 -d $KEY1 $OPAL2_DEV || fail
+
+# file pass
+echo "$PWD3" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S2 -d $KEY1 --new-key-slot 3 $OPAL2_DEV || fail
+echo $PWD3 | $CRYPTSETUP open -q --test-passphrase -S3 $OPAL2_DEV || fail
+
+# file file
+$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S2 --new-key-slot 4 -d $KEY1 --new-keyfile $KEY2 $OPAL2_DEV || fail
+$CRYPTSETUP open --test-passphrase -q -S4 -d $KEY2 $OPAL2_DEV || fail
+
+# vk pass
+echo $PWD4 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S5 --volume-key-file $VK_FILE $OPAL2_DEV || fail
+echo $PWD4 | $CRYPTSETUP open -q --test-passphrase -S5 $OPAL2_DEV || fail
+
+# vk file
+$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S6 --volume-key-file $VK_FILE --new-keyfile $KEY5 $OPAL2_DEV || fail
+$CRYPTSETUP open --test-passphrase -q -S6 -d $KEY5 $OPAL2_DEV || fail
+
+if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
+ test_and_prepare_keyring
+ load_key user $TEST_TOKEN0 $PWD1 "$TEST_KEYRING" || fail "Cannot load 32 byte user key type"
+ load_key user $TEST_TOKEN1 $PWDW "$TEST_KEYRING" || fail "Cannot load 32 byte user key type"
+ $CRYPTSETUP token add $OPAL2_DEV --key-description $TEST_TOKEN0 --token-id 0 -S0 || fail
+ $CRYPTSETUP token add $OPAL2_DEV --key-description $TEST_TOKEN1 --token-id 1 --unbound || fail
+
+ # pass token
+ echo -e "$PWD1" | $CRYPTSETUP luksAddKey -q -S7 --new-token-id 1 $FAST_PBKDF_OPT $OPAL2_DEV || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $OPAL2_DEV || fail
+ echo $PWD1 | $CRYPTSETUP luksKillSlot $OPAL2_DEV 7 || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $OPAL2_DEV && fail
+
+ # file token
+ $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S2 --new-key-slot 7 --new-token-id 1 -d $KEY1 $OPAL2_DEV || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $OPAL2_DEV || fail
+ echo $PWD1 | $CRYPTSETUP luksKillSlot $OPAL2_DEV 7 || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $OPAL2_DEV && fail
+
+ # vk token
+ $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S7 --volume-key-file $VK_FILE --new-token-id 1 $OPAL2_DEV || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $OPAL2_DEV || fail
+ echo $PWD1 | $CRYPTSETUP luksKillSlot $OPAL2_DEV 7 || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $OPAL2_DEV && fail
+
+ # token pass
+ echo $PWD4 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S7 --token-id 0 $OPAL2_DEV || fail
+ echo $PWD4 | $CRYPTSETUP open -q --test-passphrase -S7 $OPAL2_DEV || fail
+
+ # token file
+ echo $PWD4 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S8 --token-id 0 $OPAL2_DEV $KEY2 || fail
+ $CRYPTSETUP open -q --test-passphrase -S8 --key-file $KEY2 $OPAL2_DEV || fail
+
+ # token token
+ $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S9 --token-id 0 --new-token-id 1 $OPAL2_DEV || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $OPAL2_DEV || fail
+ echo $PWD1 | $CRYPTSETUP luksKillSlot $OPAL2_DEV 9 || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $OPAL2_DEV && fail
+
+ # reuse same token
+ $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S0 --new-key-slot 9 --token-id 0 --new-token-id 0 $OPAL2_DEV || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 0 -q $OPAL2_DEV || fail
+ echo $PWD1 | $CRYPTSETUP luksKillSlot $OPAL2_DEV 9 || fail
+
+ # reuse same token
+ $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --token-id 0 --new-token-id 0 $OPAL2_DEV || fail
+ echo $PWD1 | $CRYPTSETUP luksKillSlot $OPAL2_DEV 9 || fail
+ $CRYPTSETUP open -q --test-passphrase --token-only --token-id 0 -q $OPAL2_DEV || fail
+fi
+
+if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
+ prepare "[38] Link VK to a keyring and use custom VK type." wipe
+
+ echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $OPAL2_DEV 2> /dev/null || fail
+ KEY_NAME="cryptsetup:test_volume_key_id"
+ test_and_prepare_keyring
+ KID=$(echo -n test | keyctl padd user my_token @s)
+ keyctl unlink $KID >/dev/null 2>&1 @s && SESSION_KEYRING_WORKS=1
+ KID=$(echo -n test | keyctl padd user my_token @us)
+ keyctl unlink $KID >/dev/null 2>&1 @us && USER_SESSION_KEYRING_WORKS=1
+
+ test_vk_link $KEY_NAME "@u"
+ test_vk_link $KEY_NAME "@u" "user"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_vk_link $KEY_NAME "@s"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_vk_link $KEY_NAME "@s" "logon"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_vk_link $KEY_NAME "@s" "user"
+ test_vk_link $KEY_NAME "%:$TEST_KEYRING_NAME"
+ test_vk_link $KEY_NAME "%:$TEST_KEYRING_NAME" "user"
+ test_vk_link $KEY_NAME "%:$TEST_KEYRING_NAME" "logon"
+ # explicitly specify keyring key type
+ test_vk_link $KEY_NAME "%keyring:$TEST_KEYRING_NAME"
+
+ test_vk_link_and_reactivate $KEY_NAME "@u" "user"
+ test_vk_link_and_reactivate $KEY_NAME "@u"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_vk_link_and_reactivate $KEY_NAME "@s" "user"
+ test_vk_link_and_reactivate $KEY_NAME "%:$TEST_KEYRING_NAME" "user"
+ # explicitly specify keyring key type
+ test_vk_link_and_reactivate $KEY_NAME "%keyring:$TEST_KEYRING_NAME" "user"
+ test_vk_link_and_reactivate $KEY_NAME "%keyring:$TEST_KEYRING_NAME"
+
+ # test numeric keyring name -5 is user session (@us) keyring
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring -5::%logon:$KEY_NAME || fail
+ keyctl search @us logon $KEY_NAME > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
+ $CRYPTSETUP close $DEV_NAME
+ keyctl search @us logon $KEY_NAME > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+ keyctl unlink "%logon:$KEY_NAME" @us || fail
+
+ # test malformed keyring descriptions and key types
+ # missing key description
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "%$TEST_KEYRING_NAME::" > /dev/null 2>&1 && fail
+ # malformed keyring description
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring ":$TEST_KEYRING_NAME::$KEY_NAME" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "@uuu::$KEY_NAME" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "@usu::$KEY_NAME" > /dev/null 2>&1 && fail
+
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "$TEST_KEYRING_NAME::%user" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "$TEST_KEYRING_NAME::%user:" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "%user:$KEY_NAME" > /dev/null 2>&1 && fail
+
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "@t::%0:$KEY_NAME" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "@t::%blah:$KEY_NAME" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $OPAL2_DEV $DEV_NAME --link-vk-to-keyring "@t::%userlogon:$KEY_NAME" > /dev/null 2>&1 && fail
+
+fi
+
+if ! fips_mode; then
+prepare "[39] LUKS2 reencryption/decryption blocked" wipe
+
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal $OPAL2_DEV || fail
+test_reencryption_does_not_init
+
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal-only $OPAL2_DEV || fail
+test_reencryption_does_not_init
+
+prepare "[40] LUKS2 reencryption/decryption blocked (detached header)" wipe
+
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --header $HEADER_IMG --type luks2 -s256 --hw-opal $OPAL2_DEV || fail
+test_reencryption_does_not_init $HEADER_IMG
+
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --header $HEADER_IMG --type luks2 -s256 --hw-opal-only $OPAL2_DEV || fail
+test_reencryption_does_not_init $HEADER_IMG
+
+prepare "[41] LUKS2 encryption blocked" wipe
+
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal $OPAL2_DEV 2>/dev/null && fail
+$CRYPTSETUP isLuks $OPAL2_DEV && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP isLuks $OPAL2_DEV && fail
+test -b $DEV_NAME && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal $OPAL2_DEV 2>/dev/null && fail
+$CRYPTSETUP isLuks $OPAL2_DEV && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal-only $OPAL2_DEV 2>/dev/null && fail
+$CRYPTSETUP isLuks $OPAL2_DEV && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal-only $OPAL2_DEV $DEV_NAME 2>/dev/null && fail
+$CRYPTSETUP isLuks $OPAL2_DEV && fail
+test -b $DEV_NAME && fail
+echo -e "$PWD1\n$OPAL2_ADMIN_PIN" | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 32m $FAST_PBKDF_OPT --type luks2 -s256 --hw-opal-only $OPAL2_DEV 2>/dev/null && fail
+$CRYPTSETUP isLuks $OPAL2_DEV && fail
+fi
+
+prepare "[42] OPAL2 HW only test." wipe
+test_device --hw-opal-only
+
+prepare "[43] OPAL2 + dmcrypt test." wipe
+test_device --hw-opal
+
+prepare "[44] OPAL2 + auth encryption" wipe
+test_device --hw-opal "-c aes-gcm-random --integrity aead" --integrity-no-wipe
+test_device --hw-opal "-s 280 -c aes-ccm-random --integrity aead" --integrity-no-wipe
+
+prepare "[45] OPAL2 HW only test (detached header)" wipe
+test_device_detached_header $HEADER_IMG --hw-opal-only
+
+prepare "[46] OPAL2 + dmcrypt test (detached header)" wipe
+test_device_detached_header $HEADER_IMG --hw-opal
+
+prepare "[47] OPAL2 + auth encryption test (detached header)" wipe
+test_device_detached_header $HEADER_IMG --hw-opal "-c aes-gcm-random --integrity aead" --integrity-no-wipe
+test_device_detached_header $HEADER_IMG --hw-opal "-s 280 -c aes-ccm-random --integrity aead" --integrity-no-wipe
+
+# FIXME: Add partition based tests
+
+remove_mapping
+reset_device_psid_nofail
+exit 0
diff --git a/tests/compat-test2 b/tests/compat-test2
index c54dc7e..bc86563 100755
--- a/tests/compat-test2
+++ b/tests/compat-test2
@@ -3,9 +3,14 @@
PS4='$LINENO:'
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
+CRYPTSETUP_RAW=$CRYPTSETUP
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
DEV_NAME=dummy
DEV_NAME2=dummy2
@@ -16,6 +21,7 @@ IMG10=luks-test-v10
HEADER_IMG=luks-header
HEADER_KEYU=luks2_keyslot_unassigned.img
HEADER_LUKS2_PV=blkid-luks2-pv.img
+HEADER_LUKS2_INV=luks2_invalid_cipher.img
KEY1=key1
KEY2=key2
KEY5=key5
@@ -50,7 +56,9 @@ function remove_mapping()
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
losetup -d $LOOPDEV >/dev/null 2>&1
- rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE $HEADER_LUKS2_PV missing-file $TOKEN_FILE0 $TOKEN_FILE1 test_image_* $KEY_FILE0 $KEY_FILE1 >/dev/null 2>&1
+ rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE \
+ $HEADER_LUKS2_PV $HEADER_LUKS2_INV missing-file $TOKEN_FILE0 $TOKEN_FILE1 test_image_* \
+ $KEY_FILE0 $KEY_FILE1 >/dev/null 2>&1
# unlink whole test keyring
[ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null
@@ -154,7 +162,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -164,6 +175,8 @@ function valgrind_run()
function dm_crypt_keyring_support()
{
+ $CRYPTSETUP --version | grep -q KEYRING || return 1
+
VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
[ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
@@ -284,6 +297,171 @@ function add_scsi_device() {
[ -b $DEV ] || fail "Cannot find $DEV."
}
+# $1 key name
+# $2 keyring to link VK to
+# $3 key type (optional)
+test_vk_link() {
+ KEY_TYPE=${3:-user}
+ if [ -z "$3" ]; then
+ KEY_DESC=$1
+ else
+ KEY_DESC="%$3:$1"
+ fi
+
+ KEYCTL_KEY_NAME="%$KEY_TYPE:$1"
+
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $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
+ keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+ keyctl unlink "$KEYCTL_KEY_NAME" "$2" || fail
+
+ 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
+ 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
+ keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+ keyctl unlink "$KEYCTL_KEY_NAME" "$2" || fail
+}
+
+# $1 key name
+# $2 keyring to link VK to
+# $3 key type (optional)
+test_vk_link_and_reactivate() {
+ KEY_TYPE=${3:-user}
+ if [ -z "$3" ]; then
+ KEY_DESC=$1
+ else
+ KEY_DESC="%$3:$1"
+ fi
+
+ KEYCTL_KEY_NAME="%$KEY_TYPE:$1"
+
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $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 || fail
+ keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+ $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring $KEY_DESC <&-|| fail "Failed to unlock volume via a VK in keyring."
+ $CRYPTSETUP luksSuspend $DEV_NAME || fail "Failed to suspend device."
+ $CRYPTSETUP luksResume $DEV_NAME --volume-key-keyring $KEY_DESC <&- || fail "Failed to resume via a VK in keyring."
+
+ echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase 2>/dev/null || fail
+ echo $PWD2 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase 2>/dev/null && fail
+ echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --volume-key-keyring $KEY_DESC $LOOPDEV --new-key-slot 1 || fail "Failed to add passphrase by VK in keyring."
+ echo $PWD2 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase 2>/dev/null || fail
+ $CRYPTSETUP luksKillSlot -q $LOOPDEV 1 2>/dev/null || fail
+
+ $CRYPTSETUP close $DEV_NAME || fail
+ # zero-out the key in keyring
+ keyctl pipe $KEYCTL_KEY_NAME | tr -c '\0' '\0' | keyctl pupdate $KEYCTL_KEY_NAME
+ $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring $KEY_DESC <&- > /dev/null 2>&1 && fail "Unlocked volume via a bad VK in keyring."
+ keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after bad activation."
+ keyctl unlink $KEYCTL_KEY_NAME "$2" || fail
+}
+
+# $1 first key name
+# $2 second key name
+# $3 keyring to link VK to
+# $4 key type (optional)
+test_reencrypt_vk_link() {
+ 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."
+
+ keyctl unlink $KEYCTL_KEY_NAME "$3" || fail
+ 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]}"
+ expect "$@"
+}
+
+# expected unlocked keyslot id
+# command arguments
+function expect_unlocked_keyslot()
+{
+ command -v expect >/dev/null || {
+ echo "WARNING: expect tool missing, interactive test will be skipped."
+ return 0
+ }
+
+ EXPECT_TIMEOUT=60
+ EXPECT_KEY=$1
+
+ expect_run - >/dev/null <<EOF
+proc abort {} { send_error "Timeout. "; exit 2 }
+set timeout $EXPECT_TIMEOUT
+eval spawn $CRYPTSETUP_RAW $2
+expect timeout abort "Key slot $EXPECT_KEY unlocked."
+expect timeout abort "Command successful."
+expect timeout abort eof
+exit
+EOF
+ [ $? -eq 0 ] || return 1
+}
+
export LANG=C
[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
@@ -569,7 +747,7 @@ test $OLD_SIZE -eq $NEW_SIZE || fail
$CRYPTSETUP close $DEV_NAME || fail
prepare "[20] Disallow open/create if already mapped." wipe
-$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 || fail
+$CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 --cipher aes-cbc-essiv:sha256 --key-size 256 || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV 2>/dev/null && fail
$CRYPTSETUP remove $DEV_NAME || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail
@@ -626,6 +804,24 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2" && fail
$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" || fail
$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 2>/dev/null && fail
+# make a free space in keyslot area
+echo $PWD1 | $CRYPTSETUP luksKillSlot -q $LOOPDEV 0 || fail
+
+# assert LUKS2 does not overwrite existing area with specific keyslot id
+AREA_OFFSET_OLD=$($CRYPTSETUP luksDump $LOOPDEV | grep -e "1: luks2" -A12 | grep -e "Area offset:" | cut -d: -f 2 | sed -e 's/[[:space:]]*\[bytes\]//g')
+[ 0$AREA_OFFSET_OLD -gt 0 ] || fail
+echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksChangeKey --key-slot 1 $LOOPDEV $FAST_PBKDF_OPT
+AREA_OFFSET_NEW=$($CRYPTSETUP luksDump $LOOPDEV | grep -e "1: luks2" -A12 | grep -e "Area offset:" | cut -d: -f 2 | sed -e 's/[[:space:]]*\[bytes\]//g')
+[ 0$AREA_OFFSET_NEW -gt 0 ] || fail
+[ $AREA_OFFSET_OLD -ne $AREA_OFFSET_NEW ] || fail "Area offsets remained same: old area $AREA_OFFSET_OLD, new area $AREA_OFFSET_NEW"
+
+# assert LUKS2 does not overwrite existing area with any sklot
+AREA_OFFSET_OLD=$($CRYPTSETUP luksDump $LOOPDEV | grep -e "1: luks2" -A12 | grep -e "Area offset:" | cut -d: -f 2 | sed -e 's/[[:space:]]*\[bytes\]//g')
+[ 0$AREA_OFFSET_OLD -gt 0 ] || fail
+echo -e "$PWD2\n$PWD1\n" | $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT
+AREA_OFFSET_NEW=$($CRYPTSETUP luksDump $LOOPDEV | grep -e "1: luks2" -A12 | grep -e "Area offset:" | cut -d: -f 2 | sed -e 's/[[:space:]]*\[bytes\]//g')
+[ 0$AREA_OFFSET_NEW -gt 0 ] || fail
+[ $AREA_OFFSET_OLD -ne $AREA_OFFSET_NEW ] || fail "Area offsets remained same: old area $AREA_OFFSET_OLD, new area $AREA_OFFSET_NEW"
prepare "[24] Keyfile limit" wipe
$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY1 --key-slot 0 -l 13 || fail
@@ -924,6 +1120,40 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
$CRYPTSETUP token unassign --token-id 0 -S0 $LOOPDEV 2>/dev/null && fail
$CRYPTSETUP token unassign --token-id 0 -S44 $LOOPDEV 2>/dev/null && fail
$CRYPTSETUP token unassign --token-id 44 -S0 $LOOPDEV 2>/dev/null && fail
+
+ $CRYPTSETUP token remove $LOOPDEV --token-id 0 || fail
+ $CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN0 -S0 --token-id 0 || fail
+
+ # token 8 assigned to keyslot 0 and 5. Unlocks only 5
+ echo "$PWD2" | $CRYPTSETUP luksAddKey -q -S5 $FAST_PBKDF_OPT --token-id 0 $LOOPDEV || fail
+ echo -n "{\"type\":\"luks2-keyring\",\"keyslots\":[\"0\",\"5\"],\"key_description\":\"$TEST_TOKEN1\"}" | $CRYPTSETUP token import $LOOPDEV --token-id 8 || fail
+ load_key user $TEST_TOKEN1 "$PWD2" "$TEST_KEYRING" || fail "Cannot load 32 byte user key type"
+
+ # token 3 assigned to keyslot 1 (wrong passphrase)
+ echo "$PWD3" | $CRYPTSETUP luksAddKey -q -S1 $FAST_PBKDF_OPT --token-id 0 $LOOPDEV || fail
+ $CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN2 -S1 --token-id 3 || fail
+ load_key user $TEST_TOKEN2 "$PWDW" "$TEST_KEYRING" || fail "Cannot load 32 byte user key type"
+
+ # specific token, specific keyslot
+ $CRYPTSETUP open --test-passphrase --token-id 0 -S0 $LOOPDEV --token-only <&- || fail
+ # specific keyslot unlocked by any token
+ $CRYPTSETUP open --test-passphrase -S0 $LOOPDEV --token-only <&- || fail
+
+ # token 0 unusable for keyslot 5
+ $CRYPTSETUP open --test-passphrase --token-id 0 -S5 $LOOPDEV --token-only <&- >/dev/null && fail
+ # backup interactive prompt should work
+ echo $PWD2 | $CRYPTSETUP open --test-passphrase --token-id 0 -S5 $LOOPDEV || fail
+
+ $CRYPTSETUP open --test-passphrase -S5 --token-id 8 $LOOPDEV <&- || fail
+ $CRYPTSETUP open --test-passphrase -S5 $LOOPDEV <&- || fail
+
+ expect_unlocked_keyslot 5 "open -v --test-passphrase --token-id 8 -S5 $LOOPDEV" || fail
+ expect_unlocked_keyslot 5 "open -v --test-passphrase --token-id 8 $LOOPDEV" || fail
+
+ $CRYPTSETUP open --test-passphrase -S0 --token-id 8 $LOOPDEV --token-only >/dev/null && fail
+ [ $? -ne 2 ] && fail "open should return EPERM exit code."
+ $CRYPTSETUP open --test-passphrase -S1 $LOOPDEV --token-only && fail
+ [ $? -ne 2 ] && fail "open should return EPERM exit code."
fi
echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 10 || fail
echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 11 --json-file - || fail
@@ -1200,5 +1430,135 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
$CRYPTSETUP open -q --test-passphrase --token-only --token-id 0 -q $IMG || fail
fi
+prepare "[44] LUKS2 invalid cipher (kernel cipher driver name)" wipe
+xz -dk $HEADER_LUKS2_INV.xz
+dd if=$HEADER_LUKS2_INV of=$IMG conv=notrunc >/dev/null 2>&1
+$CRYPTSETUP -q luksDump $LOOPDEV | grep -q "capi:xts(ecb(aes-generic))-plain64" || fail
+echo $PWD1 | $CRYPTSETUP open $LOOPDEV --test-passphrase || fail
+echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME 2>&1 | grep -q "No known cipher specification pattern" || fail
+echo $PWD1 | $CRYPTSETUP reencrypt $LOOPDEV >/dev/null 2>&1 && fail
+dmsetup create $DEV_NAME --uuid CRYPT-LUKS2-3d20686f551748cb89911ad32379821b-test --table \
+ "0 8 crypt capi:xts(ecb(aes-generic))-plain64 edaa40709797973715e572bf7d86fcbb9cfe2051083c33c28d58fe4e1e7ff642 0 $LOOPDEV 32768"
+$CRYPTSETUP status $DEV_NAME | grep -q "n/a" || fail
+$CRYPTSETUP close $DEV_NAME ||fail
+
+if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
+ prepare "[45] Link VK to a keyring and use custom VK type." wipe
+
+ echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV 2> /dev/null || fail
+ KEY_NAME="cryptsetup:test_volume_key_id"
+ KEY_NAME2="cryptsetup:test_volume_key_id2"
+ KEY_NAME3="cryptsetup:test_volume_key_id3"
+ test_and_prepare_keyring
+ KID=$(echo -n test | keyctl padd user my_token @s)
+ keyctl unlink $KID >/dev/null 2>&1 @s && SESSION_KEYRING_WORKS=1
+ KID=$(echo -n test | keyctl padd user my_token @us)
+ keyctl unlink $KID >/dev/null 2>&1 @us && USER_SESSION_KEYRING_WORKS=1
+
+ test_vk_link $KEY_NAME "@u"
+ test_vk_link $KEY_NAME "@u" "user"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_vk_link $KEY_NAME "@s"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_vk_link $KEY_NAME "@s" "logon"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_vk_link $KEY_NAME "@s" "user"
+ test_vk_link $KEY_NAME "%:$TEST_KEYRING_NAME"
+ test_vk_link $KEY_NAME "%:$TEST_KEYRING_NAME" "user"
+ test_vk_link $KEY_NAME "%:$TEST_KEYRING_NAME" "logon"
+ # explicitly specify keyring key type
+ test_vk_link $KEY_NAME "%keyring:$TEST_KEYRING_NAME"
+
+ test_vk_link_and_reactivate $KEY_NAME "@u" "user"
+ test_vk_link_and_reactivate $KEY_NAME "@u"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_vk_link_and_reactivate $KEY_NAME "@s" "user"
+ test_vk_link_and_reactivate $KEY_NAME "%:$TEST_KEYRING_NAME" "user"
+ # explicitly specify keyring key type
+ test_vk_link_and_reactivate $KEY_NAME "%keyring:$TEST_KEYRING_NAME" "user"
+ test_vk_link_and_reactivate $KEY_NAME "%keyring:$TEST_KEYRING_NAME"
+
+ # test numeric keyring name -5 is user session (@us) keyring
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring -5::%logon:$KEY_NAME || fail
+ keyctl search @us logon $KEY_NAME > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
+ $CRYPTSETUP close $DEV_NAME
+ keyctl search @us logon $KEY_NAME > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
+ keyctl unlink "%logon:$KEY_NAME" @us || fail
+
+ # test malformed keyring descriptions and key types
+ # missing key description
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "%$TEST_KEYRING_NAME::" > /dev/null 2>&1 && fail
+ # malformed keyring description
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring ":$TEST_KEYRING_NAME::$KEY_NAME" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@uuu::$KEY_NAME" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@usu::$KEY_NAME" > /dev/null 2>&1 && fail
+
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "$TEST_KEYRING_NAME::%user" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "$TEST_KEYRING_NAME::%user:" > /dev/null 2>&1 && fail
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "%user:$KEY_NAME" > /dev/null 2>&1 && fail
+
+ echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@t::%0:$KEY_NAME" > /dev/null 2>&1 && fail
+ 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
+ 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
+ echo $PWD1 | $CRYPTSETUP -q reencrypt $LOOPDEV --init-only
+
+ test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "@u"
+ test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "@u" "user"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "@s"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "@s" "logon"
+ [[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "@s" "user"
+ test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "%:$TEST_KEYRING_NAME"
+ test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "%:$TEST_KEYRING_NAME" "user"
+ test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "%:$TEST_KEYRING_NAME" "logon"
+ # explicitly specify keyring key type
+ test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "%keyring:$TEST_KEYRING_NAME"
+
+ 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
+ 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
+
+prepare "[45] Blkid disable check" wipe
+if [ "$HAVE_BLKID" -gt 0 ]; then
+ xz -dkf $HEADER_LUKS2_PV.xz
+ # batch mode disables blkid print, use --debug to check it
+ echo $PWD1 | $CRYPTSETUP -q --debug luksFormat $FAST_PBKDF_OPT --type luks2 $HEADER_LUKS2_PV 2>&1 | grep -q "LVM2_member" || fail
+ xz -dkf $HEADER_LUKS2_PV.xz
+ echo $PWD1 | $CRYPTSETUP -q --debug --disable-blkid luksFormat $FAST_PBKDF_OPT --type luks2 $HEADER_LUKS2_PV 2>&1 | grep -q "LVM2_member" && fail
+fi
+
+prepare "[46] Init from suspended device" wipe
+dmsetup create $DEV_NAME --table "0 39998 linear $LOOPDEV 2" || fail
+echo $PWD1 | $CRYPTSETUP -q $FAST_PBKDF_OPT luksFormat --type luks2 --header $HEADER_IMG /dev/mapper/$DEV_NAME || fail
+echo $PWD1 | $CRYPTSETUP -q luksOpen --header $HEADER_IMG /dev/mapper/$DEV_NAME $DEV_NAME2 || fail
+# underlying device now returns error but node is still present
+dmsetup load $DEV_NAME --table "0 40000 error" || fail
+dmsetup resume $DEV_NAME || fail
+dmsetup suspend $DEV_NAME || fail
+# status must print data even if data device is suspended
+$CRYPTSETUP -q status --debug --header $HEADER_IMG $DEV_NAME2 | grep "type:" | grep -q "LUKS2" || fail
+dmsetup resume $DEV_NAME || fail
+$CRYPTSETUP -q luksClose $DEV_NAME2 || fail
+dmsetup remove --retry $DEV_NAME || fail
+
remove_mapping
exit 0
diff --git a/tests/crypto-vectors.c b/tests/crypto-vectors.c
index ae8dd68..02e6be3 100644
--- a/tests/crypto-vectors.c
+++ b/tests/crypto-vectors.c
@@ -1,7 +1,7 @@
/*
* cryptsetup crypto backend test vectors
*
- * Copyright (C) 2018-2023 Milan Broz
+ * Copyright (C) 2018-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -74,12 +74,9 @@ struct kdf_test_vector {
unsigned int password_length;
const char *salt;
unsigned int salt_length;
-// const char *key;
-// unsigned int key_length;
-// const char *ad;
-// unsigned int ad_length;
const char *output;
unsigned int output_length;
+ bool can_fail_fips; /* violates minimal length check */
};
static struct kdf_test_vector kdf_test_vectors[] = {
@@ -92,17 +89,11 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x01\x01\x01\x01\x01\x01\x01\x01", 32,
"\x02\x02\x02\x02\x02\x02\x02\x02"
"\x02\x02\x02\x02\x02\x02\x02\x02", 16,
-// "\x03\x03\x03\x03\x03\x03\x03\x03", 8,
-// "\x04\x04\x04\x04\x04\x04\x04\x04"
-// "\x04\x04\x04\x04", 12,
"\xa9\xa7\x51\x0e\x6d\xb4\xd5\x88"
"\xba\x34\x14\xcd\x0e\x09\x4d\x48"
"\x0d\x68\x3f\x97\xb9\xcc\xb6\x12"
- "\xa5\x44\xfe\x8e\xf6\x5b\xa8\xe0", 32
-// "\xc8\x14\xd9\xd1\xdc\x7f\x37\xaa"
-// "\x13\xf0\xd7\x7f\x24\x94\xbd\xa1"
-// "\xc8\xde\x6b\x01\x6d\xd3\x88\xd2"
-// "\x99\x52\xa4\xc4\x67\x2b\x6c\xe8", 32
+ "\xa5\x44\xfe\x8e\xf6\x5b\xa8\xe0", 32,
+ true
},
{
"argon2id", NULL, 0, 3, 32, 4,
@@ -112,17 +103,11 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x01\x01\x01\x01\x01\x01\x01\x01", 32,
"\x02\x02\x02\x02\x02\x02\x02\x02"
"\x02\x02\x02\x02\x02\x02\x02\x02", 16,
-// "\x03\x03\x03\x03\x03\x03\x03\x03", 8,
-// "\x04\x04\x04\x04\x04\x04\x04\x04"
-// "\x04\x04\x04\x04", 12,
"\x03\xaa\xb9\x65\xc1\x20\x01\xc9"
"\xd7\xd0\xd2\xde\x33\x19\x2c\x04"
"\x94\xb6\x84\xbb\x14\x81\x96\xd7"
- "\x3c\x1d\xf1\xac\xaf\x6d\x0c\x2e", 32
-// "\x0d\x64\x0d\xf5\x8d\x78\x76\x6c"
-// "\x08\xc0\x37\xa3\x4a\x8b\x53\xc9"
-// "\xd0\x1e\xf0\x45\x2d\x75\xb6\x5e"
-// "\xb5\x25\x20\xe9\x6b\x01\xe6\x59", 32
+ "\x3c\x1d\xf1\xac\xaf\x6d\x0c\x2e", 32,
+ true
},
/* empty password */
{
@@ -133,7 +118,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\xbb\x1f\xf2\xb9\x9f\xd4\x4a\xd9"
"\xdf\x7f\xb9\x54\x55\x9e\xb8\xeb"
"\xb5\x9d\xab\xce\x2e\x62\x9f\x9b"
- "\x89\x09\xfe\xde\x57\xcc\x63\x86", 32
+ "\x89\x09\xfe\xde\x57\xcc\x63\x86", 32,
+ true
},
{
"argon2id", NULL, 0, 3, 128, 1,
@@ -143,7 +129,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x09\x2f\x38\x35\xac\xb2\x43\x92"
"\x93\xeb\xcd\xe8\x04\x16\x6a\x31"
"\xce\x14\xd4\x55\xdb\xd8\xf7\xe6"
- "\xb4\xf5\x9d\x64\x8e\xd0\x3a\xdb", 32
+ "\xb4\xf5\x9d\x64\x8e\xd0\x3a\xdb", 32,
+ true
},
/* RFC 3962 */
{
@@ -153,7 +140,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\xcd\xed\xb5\x28\x1b\xb2\xf8\x01"
"\x56\x5a\x11\x22\xb2\x56\x35\x15"
"\x0a\xd1\xf7\xa0\x4b\xb9\xf3\xa3"
- "\x33\xec\xc0\xe2\xe1\xf7\x08\x37", 32
+ "\x33\xec\xc0\xe2\xe1\xf7\x08\x37", 32,
+ true
}, {
"pbkdf2", "sha1", 64, 2, 0, 0,
"password", 8,
@@ -161,7 +149,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x01\xdb\xee\x7f\x4a\x9e\x24\x3e"
"\x98\x8b\x62\xc7\x3c\xda\x93\x5d"
"\xa0\x53\x78\xb9\x32\x44\xec\x8f"
- "\x48\xa9\x9e\x61\xad\x79\x9d\x86", 32
+ "\x48\xa9\x9e\x61\xad\x79\x9d\x86", 32,
+ true
}, {
"pbkdf2", "sha1", 64, 1200, 0, 0,
"password", 8,
@@ -169,7 +158,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x5c\x08\xeb\x61\xfd\xf7\x1e\x4e"
"\x4e\xc3\xcf\x6b\xa1\xf5\x51\x2b"
"\xa7\xe5\x2d\xdb\xc5\xe5\x14\x2f"
- "\x70\x8a\x31\xe2\xe6\x2b\x1e\x13", 32
+ "\x70\x8a\x31\xe2\xe6\x2b\x1e\x13", 32,
+ false
}, {
"pbkdf2", "sha1", 64, 5, 0, 0,
"password", 8,
@@ -177,7 +167,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\xd1\xda\xa7\x86\x15\xf2\x87\xe6"
"\xa1\xc8\xb1\x20\xd7\x06\x2a\x49"
"\x3f\x98\xd2\x03\xe6\xbe\x49\xa6"
- "\xad\xf4\xfa\x57\x4b\x6e\x64\xee", 32
+ "\xad\xf4\xfa\x57\x4b\x6e\x64\xee", 32,
+ true
}, {
"pbkdf2", "sha1", 64, 1200, 0, 0,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
@@ -186,7 +177,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x13\x9c\x30\xc0\x96\x6b\xc3\x2b"
"\xa5\x5f\xdb\xf2\x12\x53\x0a\xc9"
"\xc5\xec\x59\xf1\xa4\x52\xf5\xcc"
- "\x9a\xd9\x40\xfe\xa0\x59\x8e\xd1", 32
+ "\x9a\xd9\x40\xfe\xa0\x59\x8e\xd1", 32,
+ false
}, {
"pbkdf2", "sha1", 64, 1200, 0, 0,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
@@ -195,7 +187,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x9c\xca\xd6\xd4\x68\x77\x0c\xd5"
"\x1b\x10\xe6\xa6\x87\x21\xbe\x61"
"\x1a\x8b\x4d\x28\x26\x01\xdb\x3b"
- "\x36\xbe\x92\x46\x91\x5e\xc8\x2a", 32
+ "\x36\xbe\x92\x46\x91\x5e\xc8\x2a", 32,
+ false
}, {
"pbkdf2", "sha1", 64, 50, 0, 0,
"\360\235\204\236", 4, // g-clef ("\xf09d849e)
@@ -203,52 +196,60 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x6b\x9c\xf2\x6d\x45\x45\x5a\x43"
"\xa5\xb8\xbb\x27\x6a\x40\x3b\x39"
"\xe7\xfe\x37\xa0\xc4\x1e\x02\xc2"
- "\x81\xff\x30\x69\xe1\xe9\x4f\x52", 32
+ "\x81\xff\x30\x69\xe1\xe9\x4f\x52", 32,
+ true
}, {
/* RFC-6070 */
"pbkdf2", "sha1", 64, 1, 0, 0,
"password", 8,
"salt", 4,
"\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
- "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6", 20
+ "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6", 20,
+ true
}, {
"pbkdf2", "sha1", 64, 2, 0, 0,
"password", 8,
"salt", 4,
"\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
- "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57", 20
+ "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57", 20,
+ true
}, {
"pbkdf2", "sha1", 64, 4096, 0, 0,
"password", 8,
"salt", 4,
"\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
- "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1", 20
+ "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1", 20,
+ true
}, {
"pbkdf2", "sha1", 64, 16777216, 0, 0,
"password", 8,
"salt", 4,
"\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
- "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84", 20
+ "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84", 20,
+ true
}, {
"pbkdf2", "sha1", 64, 4096, 0, 0,
"passwordPASSWORDpassword", 24,
"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
"\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8"
"\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96"
- "\x4c\xf2\xf0\x70\x38", 25
+ "\x4c\xf2\xf0\x70\x38", 25,
+ false
}, {
"pbkdf2", "sha1", 64, 4096, 0, 0,
"pass\0word", 9,
"sa\0lt", 5,
"\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37"
- "\xd7\xf0\x34\x25\xe0\xc3", 16
+ "\xd7\xf0\x34\x25\xe0\xc3", 16,
+ true
}, {
/* empty password test */
"pbkdf2", "sha1", 64, 2, 0, 0,
"", 0,
"salt", 4,
"\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2"
- "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97", 20
+ "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97", 20,
+ true
}, {
/* Password exceeds block size test */
"pbkdf2", "sha256", 64, 1200, 0, 0,
@@ -258,7 +259,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x22\x34\x4b\xc4\xb6\xe3\x26\x75"
"\xa8\x09\x0f\x3e\xa8\x0b\xe0\x1d"
"\x5f\x95\x12\x6a\x2c\xdd\xc3\xfa"
- "\xcc\x4a\x5e\x6d\xca\x04\xec\x58", 32
+ "\xcc\x4a\x5e\x6d\xca\x04\xec\x58", 32,
+ false
}, {
"pbkdf2", "sha512", 128, 1200, 0, 0,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
@@ -269,7 +271,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x0f\xb2\xed\x2c\x0e\x6e\xfb\x7d"
"\x7d\x8e\xdd\x58\x01\xb4\x59\x72"
"\x99\x92\x16\x30\x5e\xa4\x36\x8d"
- "\x76\x14\x80\xf3\xe3\x7a\x22\xb9", 32
+ "\x76\x14\x80\xf3\xe3\x7a\x22\xb9", 32,
+ false
}, {
"pbkdf2", "whirlpool", 64, 1200, 0, 0,
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
@@ -278,7 +281,8 @@ static struct kdf_test_vector kdf_test_vectors[] = {
"\x9c\x1c\x74\xf5\x88\x26\xe7\x6a"
"\x53\x58\xf4\x0c\x39\xe7\x80\x89"
"\x07\xc0\x31\x19\x9a\x50\xa2\x48"
- "\xf1\xd9\xfe\x78\x64\xe5\x84\x50", 32
+ "\xf1\xd9\xfe\x78\x64\xe5\x84\x50", 32,
+ true
}
};
@@ -1024,23 +1028,38 @@ static int pbkdf_test_vectors(void)
{
char result[256];
unsigned int i;
+ struct crypt_hash *h;
const struct kdf_test_vector *vec;
for (i = 0; i < ARRAY_SIZE(kdf_test_vectors); i++) {
crypt_backend_memzero(result, sizeof(result));
vec = &kdf_test_vectors[i];
- printf("PBKDF vector %02d %s ", i, vec->type);
+ if (vec->hash)
+ printf("PBKDF vector %02d %s-%s ", i, vec->type, vec->hash);
+ else
+ printf("PBKDF vector %02d %s ", i, vec->type);
if (vec->hash && crypt_hmac_size(vec->hash) < 0) {
printf("[%s N/A]\n", vec->hash);
continue;
}
+ if (vec->hash) {
+ if (crypt_hash_init(&h, vec->hash) < 0) {
+ printf("[%s N/A (init)]\n", vec->hash);
+ continue;
+ }
+ crypt_hash_destroy(h);
+ }
if (crypt_pbkdf(vec->type, vec->hash,
vec->password, vec->password_length,
vec->salt, vec->salt_length,
result, vec->output_length,
vec->iterations, vec->memory, vec->parallelism) < 0) {
- printf("[%s-%s N/A]\n", vec->type, vec->hash);
- continue;
+ if (vec->can_fail_fips && fips_mode()) {
+ printf("[API FAILED, IGNORED (FIPS mode)]\n");
+ continue;
+ }
+ printf("[API FAILED]\n");
+ return EXIT_FAILURE;
}
if (memcmp(result, vec->output, vec->output_length)) {
printf("[FAILED]\n");
diff --git a/tests/device-test b/tests/device-test
index c8b53bb..9aaf03c 100755
--- a/tests/device-test
+++ b/tests/device-test
@@ -8,10 +8,15 @@ DEV_NAME2="ymmud"
PWD1="93R4P4pIqAH8"
PWD2="mymJeD8ivEhE"
FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
+PLAIN_OPT="--type plain --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha256"
SKIP_COUNT=0
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
cleanup() {
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
@@ -43,7 +48,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -100,21 +108,6 @@ function dm_crypt_features()
DM_PERF_NO_WORKQUEUE=1
}
-function dm_crypt_keyring_support()
-{
- VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
- [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
-
- VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
- VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
-
- # run the test with dm-crypt v1.15.0+ on purpose
- # the fix is in dm-crypt v1.18.1+
- [ $VER_MAJ -gt 1 ] && return 0
- [ $VER_MAJ -lt 1 ] && return 1
- [ $VER_MIN -ge 15 ]
-}
-
format() # format
{
add_image
@@ -165,33 +158,33 @@ if [ -z "$DM_PERF_CPU" ]; then
SKIP_COUNT=$((SKIP_COUNT+1))
else
echo -n "PLAIN: same_cpu_crypt submit_from_cpus "
- echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus || fail
+ echo -e "$PWD1" | $CRYPTSETUP open -q $PLAIN_OPT $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus || fail
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
$CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
check_io
$CRYPTSETUP close $DEV_NAME || fail
echo -n "allow_discards "
- echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
+ echo -e "$PWD1" | $CRYPTSETUP open -q $PLAIN_OPT $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
$CRYPTSETUP status $DEV_NAME | grep -q discards || fail
check_io
$CRYPTSETUP close $DEV_NAME || fail
- echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME || fail
- echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
+ echo -e "$PWD1" | $CRYPTSETUP open -q $PLAIN_OPT $DEV $DEV_NAME || fail
+ echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT -q $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
# Hash affects volume key for plain device. Check we can detect it
- echo -e "$PWD1" | $CRYPTSETUP refresh -q $DEV_NAME --hash sha512 --perf-same_cpu_crypt --allow-discards 2>/dev/null && fail
+ echo -e "$PWD1" | $CRYPTSETUP refresh -q $DEV_NAME --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha512 --perf-same_cpu_crypt --allow-discards 2>/dev/null && fail
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
$CRYPTSETUP status $DEV_NAME | grep -q discards || fail
- echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME --allow-discards || fail
+ echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT -q $DEV_NAME --allow-discards || fail
$CRYPTSETUP status $DEV_NAME | grep -q discards || fail
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail
- echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME || fail
+ echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT -q $DEV_NAME || fail
$CRYPTSETUP status $DEV_NAME | grep -q discards && fail
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail
- echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 $DEV $DEV_NAME2 2>/dev/null && fail
+ echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT $DEV $DEV_NAME2 2>/dev/null && fail
if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then
echo -n "no_read_workqueue no_write_workqueue"
- echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME --perf-no_read_workqueue --perf-no_write_workqueue || fail
+ echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT -q $DEV_NAME --perf-no_read_workqueue --perf-no_write_workqueue || fail
$CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail
$CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail
check_io
@@ -279,9 +272,12 @@ else
echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --disable-keyring || fail
$CRYPTSETUP status $DEV_NAME | grep -q keyring && fail
if [ -n "$DM_KEYRING" ]; then
- echo -n "keyring "
- echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME || fail
- $CRYPTSETUP status $DEV_NAME | grep -q keyring || fail
+ $CRYPTSETUP --version | grep -q KEYRING
+ if [ $? -eq 0 ]; then
+ echo -n "keyring "
+ echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME || fail
+ $CRYPTSETUP status $DEV_NAME | grep -q keyring || fail
+ fi
fi
if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then
echo -n "no_read_workqueue no_write_workqueue"
@@ -299,7 +295,7 @@ else
fi
echo "[3] Kernel dmcrypt sector size options"
-echo -e "$PWD1" | $CRYPTSETUP open --type plain --hash sha256 $DEV $DEV_NAME --sector-size 4096 >/dev/null 2>&1
+echo -e "$PWD1" | $CRYPTSETUP open $PLAIN_OPT $DEV $DEV_NAME --sector-size 4096 >/dev/null 2>&1
ret=$?
[ -z "$DM_SECTOR_SIZE" -a $ret -eq 0 ] && fail "cryptsetup activated device with --sector-size option on incompatible kernel!"
if [ $ret -ne 0 ] ; then
@@ -312,18 +308,18 @@ else
$CRYPTSETUP close $DEV_NAME || fail
echo -n "PLAIN sector size:"
- echo -e "$PWD1" | $CRYPTSETUP open --type plain --hash sha256 $DEV $DEV_NAME --sector-size 1234 >/dev/null 2>&1 && fail
+ echo -e "$PWD1" | $CRYPTSETUP open $PLAIN_OPT $DEV $DEV_NAME --sector-size 1234 >/dev/null 2>&1 && fail
for S in 512 1024 2048 4096; do
echo -n "[$S]"
- echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --sector-size $S || fail
+ echo -e "$PWD1" | $CRYPTSETUP open -q $PLAIN_OPT $DEV $DEV_NAME --sector-size $S || fail
check_sector_size $S
$CRYPTSETUP close $DEV_NAME || fail
done
- echo -e "$PWD1" | $CRYPTSETUP open --type plain --hash sha256 $DEV $DEV_NAME --iv-large-sectors >/dev/null 2>&1 && fail
+ echo -e "$PWD1" | $CRYPTSETUP open $PLAIN_OPT $DEV $DEV_NAME --iv-large-sectors >/dev/null 2>&1 && fail
for S in 1024 2048 4096; do
echo -n "[$S/IV]"
- echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --sector-size $S --iv-large-sectors || fail
+ echo -e "$PWD1" | $CRYPTSETUP open -q $PLAIN_OPT $DEV $DEV_NAME --sector-size $S --iv-large-sectors || fail
check_sector_size $S
dmsetup table $DEV_NAME | grep -q "iv_large_sectors" || fail
$CRYPTSETUP close $DEV_NAME || fail
diff --git a/tests/differ.c b/tests/differ.c
index 95da8e5..0045b04 100644
--- a/tests/differ.c
+++ b/tests/differ.c
@@ -1,7 +1,7 @@
/*
* cryptsetup file differ check (rewritten Clemens' fileDiffer in Python)
*
- * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/discards-test b/tests/discards-test
index 870f74d..27e5a5b 100755
--- a/tests/discards-test
+++ b/tests/discards-test
@@ -6,14 +6,18 @@ DEV_NAME="discard-t3st"
DEV=""
PWD1="93R4P4pIqAH8"
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
cleanup() {
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
udevadm settle >/dev/null 2>&1
rmmod scsi_debug >/dev/null 2>&1
- sleep 2
+ sleep 1
}
fail()
@@ -34,7 +38,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -54,7 +61,7 @@ add_device() {
exit 77
fi
- sleep 2
+ sleep 1
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
DEV="/dev/$DEV"
@@ -103,7 +110,7 @@ dmsetup table $DEV_NAME | grep allow_discards >/dev/null || fail
$CRYPTSETUP luksClose $DEV_NAME || fail
echo "[2] Allowing discards for plain device"
-echo $PWD1 | $CRYPTSETUP create -q $DEV_NAME $DEV --hash sha256 --allow-discards || fail
+echo $PWD1 | $CRYPTSETUP create -q $DEV_NAME $DEV --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha256 --allow-discards || fail
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
$CRYPTSETUP resize $DEV_NAME --size 100 || fail
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
diff --git a/tests/fake_systemd_tpm_path.c b/tests/fake_systemd_tpm_path.c
index 6d82989..3dff718 100644
--- a/tests/fake_systemd_tpm_path.c
+++ b/tests/fake_systemd_tpm_path.c
@@ -2,9 +2,9 @@
#include <stdlib.h>
/* systemd tpm2-util.h */
-int tpm2_find_device_auto(int log_level, char **ret);
+int tpm2_find_device_auto(char **ret);
-extern int tpm2_find_device_auto(int log_level __attribute__((unused)), char **ret)
+extern int tpm2_find_device_auto(char **ret)
{
const char *path = getenv("TPM_PATH");
diff --git a/tests/fake_token_path.c b/tests/fake_token_path.c
deleted file mode 100644
index 7b2bad3..0000000
--- a/tests/fake_token_path.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <libcryptsetup.h>
-
-const char *crypt_token_external_path(void)
-{
- return BUILD_DIR;
-}
diff --git a/tests/fuzz/LUKS2.proto b/tests/fuzz/LUKS2.proto
index 3a0f287..f54ed6b 100644
--- a/tests/fuzz/LUKS2.proto
+++ b/tests/fuzz/LUKS2.proto
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 custom mutator
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -229,7 +229,7 @@ enum keyslot_af_type {
KEYSLOT_AF_TYPE_LUKS1 = 1;
}
-// The af (anti-forensic splitter) object contains this madatory field:
+// The af (anti-forensic splitter) object contains this mandatory field:
// - type [string] the anti-forensic function type.
// AF type luks1 (compatible with LUKS1 [1]) contains these additional fields:
// - stripes [integer] the number of stripes, for historical reasons only the 4000 value is supported.
diff --git a/tests/fuzz/LUKS2_plain_JSON.proto b/tests/fuzz/LUKS2_plain_JSON.proto
index 59096b7..da8ea00 100644
--- a/tests/fuzz/LUKS2_plain_JSON.proto
+++ b/tests/fuzz/LUKS2_plain_JSON.proto
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 custom mutator
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/fuzz/crypt2_load_fuzz.cc b/tests/fuzz/crypt2_load_fuzz.cc
index 1251d72..2195b40 100644
--- a/tests/fuzz/crypt2_load_fuzz.cc
+++ b/tests/fuzz/crypt2_load_fuzz.cc
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 fuzz target
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -22,91 +22,88 @@
extern "C" {
#define FILESIZE (16777216)
#include "src/cryptsetup.h"
-#include <err.h>
#include "luks2/luks2.h"
#include "crypto_backend/crypto_backend.h"
#include "FuzzerInterface.h"
-static int calculate_checksum(const uint8_t* data, size_t size) {
- struct crypt_hash *hd = NULL;
- struct luks2_hdr_disk *hdr = NULL;
- int hash_size;
- uint64_t hdr_size1, hdr_size2;
- int r = 0;
-
- /* primary header */
- if (sizeof(struct luks2_hdr_disk) > size)
- return 0;
- hdr = CONST_CAST(struct luks2_hdr_disk *) data;
-
- hdr_size1 = be64_to_cpu(hdr->hdr_size);
- if (hdr_size1 > size)
- return 0;
- memset(&hdr->csum, 0, LUKS2_CHECKSUM_L);
- if ((r = crypt_hash_init(&hd, "sha256")))
- goto out;
- if ((r = crypt_hash_write(hd, CONST_CAST(char*) data, hdr_size1)))
- goto out;
- hash_size = crypt_hash_size("sha256");
- if (hash_size <= 0) {
- r = 1;
- goto out;
- }
- if ((r = crypt_hash_final(hd, (char*)&hdr->csum, (size_t)hash_size)))
- goto out;
- crypt_hash_destroy(hd);
+#define CHKSUM_ALG "sha256"
+#define CHKSUM_SIZE 32
- /* secondary header */
- if (hdr_size1 < sizeof(struct luks2_hdr_disk))
- hdr_size1 = sizeof(struct luks2_hdr_disk);
+static bool fix_checksum_hdr(struct luks2_hdr_disk *hdr, const char *data, size_t len)
+{
+ char *csum = (char *)&hdr->csum;
+ struct crypt_hash *hd = NULL;
+ bool r = false;
- if (hdr_size1 + sizeof(struct luks2_hdr_disk) > size)
- return 0;
- hdr = CONST_CAST(struct luks2_hdr_disk *) (data + hdr_size1);
+ if (crypt_hash_init(&hd, CHKSUM_ALG))
+ return false;
- hdr_size2 = be64_to_cpu(hdr->hdr_size);
- if (hdr_size2 > size || (hdr_size1 + hdr_size2) > size)
- return 0;
+ memset(csum, 0, LUKS2_CHECKSUM_L);
- memset(&hdr->csum, 0, LUKS2_CHECKSUM_L);
- if ((r = crypt_hash_init(&hd, "sha256")))
- goto out;
- if ((r = crypt_hash_write(hd, (char*) hdr, hdr_size2)))
- goto out;
- if ((r = crypt_hash_final(hd, (char*)&hdr->csum, (size_t)hash_size)))
- goto out;
+ if (!crypt_hash_write(hd, data, len) &&
+ !crypt_hash_final(hd, csum, CHKSUM_SIZE))
+ r = true;
-out:
- if (hd)
- crypt_hash_destroy(hd);
+ crypt_hash_destroy(hd);
return r;
}
-int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- int fd;
+static bool calculate_checksum(const char *data, size_t size, struct luks2_hdr_disk *hdr_rw)
+{
+ uint64_t hdr_size;
+
+ /* Primary header cannot fit in data */
+ if (sizeof(*hdr_rw) > size)
+ return false;
+
+ hdr_size = be64_to_cpu(((struct luks2_hdr_disk *)data)->hdr_size);
+ if (hdr_size > size || hdr_size <= sizeof(*hdr_rw))
+ return false;
+
+ /* Calculate checksum for primary header */
+ memcpy(hdr_rw, data, sizeof(*hdr_rw));
+ return fix_checksum_hdr(hdr_rw, data, (size_t)hdr_size);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+ int fd, r = EXIT_FAILURE;
struct crypt_device *cd = NULL;
char name[] = "/tmp/test-script-fuzz.XXXXXX";
+ struct luks2_hdr_disk hdr_rw;
+ size_t modified_data_size;
- if (calculate_checksum(data, size))
- return 0;
+ /* if csum calculation fails, keep fuzzer running on original input */
+ if (size >= sizeof(hdr_rw) && calculate_checksum((const char *)data, size, &hdr_rw))
+ modified_data_size = sizeof(hdr_rw);
+ else
+ modified_data_size = 0;
+ /* create file with LUKS header for libcryptsetup */
fd = mkostemp(name, O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC);
if (fd == -1)
- err(EXIT_FAILURE, "mkostemp() failed");
+ return r;
/* enlarge header */
if (ftruncate(fd, FILESIZE) == -1)
goto out;
- if (write_buffer(fd, data, size) != (ssize_t)size)
+ if (modified_data_size &&
+ write_buffer(fd, &hdr_rw, modified_data_size) != (ssize_t)modified_data_size)
+ goto out;
+
+ if (write_buffer(fd, data + modified_data_size, size - modified_data_size) != (ssize_t)size)
goto out;
+ /* Actual fuzzing */
if (crypt_init(&cd, name) == 0)
(void)crypt_load(cd, CRYPT_LUKS2, NULL);
crypt_free(cd);
+ r = 0;
out:
close(fd);
unlink(name);
- return 0;
+
+ return r;
}
}
diff --git a/tests/fuzz/crypt2_load_proto_fuzz.cc b/tests/fuzz/crypt2_load_proto_fuzz.cc
index 498c006..aaabfe8 100644
--- a/tests/fuzz/crypt2_load_proto_fuzz.cc
+++ b/tests/fuzz/crypt2_load_proto_fuzz.cc
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 custom mutator fuzz target
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc
index f3565ab..227c49a 100644
--- a/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc
+++ b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 custom mutator fuzz target
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/fuzz/meson.build b/tests/fuzz/meson.build
new file mode 100644
index 0000000..95ea382
--- /dev/null
+++ b/tests/fuzz/meson.build
@@ -0,0 +1,127 @@
+if get_option('fuzz-targets')
+ crypt2_load_fuzz = executable('crypt2_load_fuzz',
+ [
+ 'crypt2_load_fuzz.cc',
+ ],
+ dependencies: [
+ devmapper,
+ fuzzing_engine,
+ ],
+ link_with: [
+ libcryptsetup,
+ libcrypto_backend,
+ libutils_io,
+ ],
+ link_args: [
+ link_args,
+ ],
+ include_directories: includes_tools)
+
+ crypt2_load_ondisk_fuzz = executable('crypt2_load_ondisk_fuzz',
+ [
+ 'crypt2_load_ondisk_fuzz.cc',
+ ],
+ dependencies: [
+ devmapper,
+ fuzzing_engine,
+ ],
+ link_with: [
+ libcryptsetup,
+ libcrypto_backend,
+ libutils_io,
+ ],
+ link_args: [
+ link_args,
+ ],
+ include_directories: includes_tools)
+
+ luks2_generated = protoc_generator.process('LUKS2.proto')
+ crypt2_load_proto_fuzz = executable('crypt2_load_proto_fuzz',
+ [
+ 'crypt2_load_proto_fuzz.cc',
+ 'proto_to_luks2_converter.cc',
+ luks2_generated,
+ ],
+ dependencies: [
+ devmapper,
+ protobuf,
+ libprotobuf_mutator,
+ fuzzing_engine,
+ ],
+ link_with: [
+ libcryptsetup,
+ libcrypto_backend,
+ libutils_io,
+ ],
+ link_args: [
+ link_args,
+ ],
+ include_directories: includes_tools)
+
+ luks2_plain_json_generated = protoc_generator.process('LUKS2_plain_JSON.proto')
+ crypt2_load_proto_plain_fuzz = executable('crypt2_load_proto_plain_fuzz',
+ [
+ 'crypt2_load_proto_plain_json_fuzz.cc',
+ 'json_proto_converter.cc',
+ 'plain_json_proto_to_luks2_converter.cc',
+ luks2_plain_json_generated,
+ ],
+ dependencies: [
+ devmapper,
+ protobuf,
+ libprotobuf_mutator,
+ fuzzing_engine,
+ ],
+ link_with: [
+ libcryptsetup,
+ libcrypto_backend,
+ libutils_io,
+ ],
+ link_args: [
+ link_args,
+ ],
+ include_directories: includes_tools)
+
+ proto_to_luks2 = executable('proto_to_luks2',
+ [
+ 'proto_to_luks2.cc',
+ 'proto_to_luks2_converter.cc',
+ luks2_generated,
+ ],
+ dependencies: [
+ devmapper,
+ protobuf,
+ libprotobuf_mutator,
+ ],
+ link_with: [
+ libcryptsetup,
+ libcrypto_backend,
+ libutils_io,
+ ],
+ link_args: [
+ link_args,
+ ],
+ include_directories: includes_tools)
+
+ plain_json_proto_to_luks2 = executable('plain_json_proto_to_luks2',
+ [
+ 'plain_json_proto_to_luks2.cc',
+ 'plain_json_proto_to_luks2_converter.cc',
+ 'json_proto_converter.cc',
+ luks2_plain_json_generated,
+ ],
+ dependencies: [
+ devmapper,
+ protobuf,
+ libprotobuf_mutator,
+ ],
+ link_with: [
+ libcryptsetup,
+ libcrypto_backend,
+ libutils_io,
+ ],
+ link_args: [
+ link_args,
+ ],
+ include_directories: includes_tools)
+endif
diff --git a/tests/fuzz/oss-fuzz-build.sh b/tests/fuzz/oss-fuzz-build.sh
index b2f643f..cf0cfde 100755
--- a/tests/fuzz/oss-fuzz-build.sh
+++ b/tests/fuzz/oss-fuzz-build.sh
@@ -42,14 +42,16 @@ in_oss_fuzz && LIBFUZZER_PATCH="$PWD/cryptsetup/tests/fuzz/unpoison-mutated-buff
in_oss_fuzz && apt-get update && apt-get install -y \
make autoconf automake autopoint libtool pkg-config \
sharutils gettext expect keyutils ninja-build \
- bison
+ bison flex
[ ! -d zlib ] && git clone --depth 1 https://github.com/madler/zlib.git
[ ! -d xz ] && git clone https://git.tukaani.org/xz.git
[ ! -d json-c ] && git clone --depth 1 https://github.com/json-c/json-c.git
-[ ! -d lvm2 ] && git clone --depth 1 https://sourceware.org/git/lvm2.git
+[ ! -d lvm2 ] && git clone --depth 1 https://gitlab.com/lvmteam/lvm2
[ ! -d popt ] && git clone --depth 1 https://github.com/rpm-software-management/popt.git
-[ ! -d libprotobuf-mutator ] && git clone --depth 1 https://github.com/google/libprotobuf-mutator.git \
+# FIXME: temporary fix until libprotobuf stops shuffling C++ requirements
+# [ ! -d libprotobuf-mutator ] && git clone --depth 1 https://github.com/google/libprotobuf-mutator.git \
+[ ! -d libprotobuf-mutator ] && git clone --depth 1 --branch v1.1 https://github.com/google/libprotobuf-mutator.git \
&& [ "$SANITIZER" == "memory" ] && ( cd libprotobuf-mutator; patch -p1 < $LIBFUZZER_PATCH )
[ ! -d openssl ] && git clone --depth 1 https://github.com/openssl/openssl
[ ! -d util-linux ] && git clone --depth 1 https://github.com/util-linux/util-linux
@@ -76,8 +78,8 @@ make install
cd ..
cd xz
-./autogen.sh --no-po4a
-./configure --prefix="$DEPS_PATH" --enable-static --disable-shared
+./autogen.sh --no-po4a --no-doxygen
+./configure --prefix="$DEPS_PATH" --enable-static --disable-shared --disable-ifunc --disable-sandbox
make -j
make install
cd ..
@@ -94,16 +96,14 @@ cd ../..
cd lvm2
./configure --prefix="$DEPS_PATH" --enable-static_link --disable-udev_sync --enable-pkgconfig --disable-selinux
make -j libdm.device-mapper
-# build of dmsetup.static is broken
-# make install_device-mapper
-cp ./libdm/ioctl/libdevmapper.a "$DEPS_PATH"/lib/
-cp ./libdm/libdevmapper.h "$DEPS_PATH"/include/
-cp ./libdm/libdevmapper.pc "$PKG_CONFIG_PATH"
+make -C libdm install_static install_pkgconfig install_include
cd ..
cd popt
# --no-undefined is incompatible with sanitizers
sed -i -e 's/-Wl,--no-undefined //' src/CMakeLists.txt
+# force static build of popt
+sed -i 's/add_library(popt SHARED/add_library(popt STATIC/' src/CMakeLists.txt
mkdir -p build
rm -fr build/*
cd build
diff --git a/tests/fuzz/plain_json_proto_to_luks2.cc b/tests/fuzz/plain_json_proto_to_luks2.cc
index 8c56c15..a0f02c5 100644
--- a/tests/fuzz/plain_json_proto_to_luks2.cc
+++ b/tests/fuzz/plain_json_proto_to_luks2.cc
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 protobuf to image converter
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/fuzz/plain_json_proto_to_luks2_converter.cc b/tests/fuzz/plain_json_proto_to_luks2_converter.cc
index 823c0c5..6f756a9 100644
--- a/tests/fuzz/plain_json_proto_to_luks2_converter.cc
+++ b/tests/fuzz/plain_json_proto_to_luks2_converter.cc
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 custom mutator fuzz target
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -32,6 +32,8 @@ namespace json_proto {
void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_proto, int fd, uint64_t offset, uint64_t seqid, const std::string &json_text) {
struct luks2_hdr_disk hdr = {};
+ size_t hdr_json_area_len, write_size;
+ uint8_t csum[LUKS2_CHECKSUM_L];
int r;
if (hd)
@@ -63,7 +65,6 @@ void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_pr
strncpy(hdr.uuid, "af7f64ea-3233-4581-946b-6187d812841e", LUKS2_UUID_L);
memset(hdr.salt, 1, LUKS2_SALT_L);
-
if (header_proto.has_selected_offset())
hdr.hdr_offset = cpu_to_be64(header_proto.selected_offset());
else
@@ -74,10 +75,13 @@ void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_pr
if (crypt_hash_write(hd, (char*)&hdr, LUKS2_HDR_BIN_LEN))
err(EXIT_FAILURE, "crypt_hash_write failed");
- size_t hdr_json_area_len = header_proto.hdr_size() - LUKS2_HDR_BIN_LEN;
- uint8_t csum[LUKS2_CHECKSUM_L];
+ if (header_proto.hdr_size() <= LUKS2_HDR_BIN_LEN ||
+ header_proto.hdr_size() > LUKS2_DEFAULT_HDR_SIZE)
+ hdr_json_area_len = LUKS2_DEFAULT_HDR_SIZE - LUKS2_HDR_BIN_LEN;
+ else
+ hdr_json_area_len = header_proto.hdr_size() - LUKS2_HDR_BIN_LEN;
- size_t write_size = json_text.length() > hdr_json_area_len - 1 ? hdr_json_area_len - 1 : json_text.length();
+ write_size = json_text.length() > hdr_json_area_len - 1 ? hdr_json_area_len - 1 : json_text.length();
if (write_buffer(fd, json_text.c_str(), write_size) != (ssize_t)write_size)
err(EXIT_FAILURE, "write_buffer failed");
if (crypt_hash_write(hd, json_text.c_str(), write_size))
@@ -113,6 +117,9 @@ void LUKS2ProtoConverter::convert(const LUKS2_both_headers &headers, int fd) {
size_t out_size = headers.primary_header().hdr_size() + headers.secondary_header().hdr_size();
+ if (out_size < 4096 || out_size > 2 * LUKS2_DEFAULT_HDR_SIZE)
+ out_size = LUKS2_DEFAULT_HDR_SIZE;
+
if (!write_headers_only)
out_size += KEYSLOTS_SIZE + DATA_SIZE;
diff --git a/tests/fuzz/plain_json_proto_to_luks2_converter.h b/tests/fuzz/plain_json_proto_to_luks2_converter.h
index 7decf9f..aa1b594 100644
--- a/tests/fuzz/plain_json_proto_to_luks2_converter.h
+++ b/tests/fuzz/plain_json_proto_to_luks2_converter.h
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 custom mutator fuzz target
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/fuzz/proto_to_luks2.cc b/tests/fuzz/proto_to_luks2.cc
index 4a27cad..720d25b 100644
--- a/tests/fuzz/proto_to_luks2.cc
+++ b/tests/fuzz/proto_to_luks2.cc
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 protobuf to image converter
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/fuzz/proto_to_luks2_converter.cc b/tests/fuzz/proto_to_luks2_converter.cc
index 96a70b7..10f2b83 100644
--- a/tests/fuzz/proto_to_luks2_converter.cc
+++ b/tests/fuzz/proto_to_luks2_converter.cc
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 custom mutator fuzz target
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/fuzz/proto_to_luks2_converter.h b/tests/fuzz/proto_to_luks2_converter.h
index 9f926d0..5547ca7 100644
--- a/tests/fuzz/proto_to_luks2_converter.h
+++ b/tests/fuzz/proto_to_luks2_converter.h
@@ -1,8 +1,8 @@
/*
* cryptsetup LUKS2 custom mutator fuzz target
*
- * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com>
- * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2022-2024 Daniel Zatovic <daniel.zatovic@gmail.com>
+ * Copyright (C) 2022-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/fvault2-compat-test b/tests/fvault2-compat-test
index 45022d2..047798a 100755
--- a/tests/fvault2-compat-test
+++ b/tests/fvault2-compat-test
@@ -5,8 +5,12 @@ CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
MAP=fvault2test
TST_DIR=fvault2-images
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
[ -z "$srcdir" ] && srcdir="."
@@ -83,7 +87,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
diff --git a/tests/integrity-compat-test b/tests/integrity-compat-test
index 208eafb..a2aae8d 100755
--- a/tests/integrity-compat-test
+++ b/tests/integrity-compat-test
@@ -5,8 +5,12 @@
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
INTSETUP=$CRYPTSETUP_PATH/integritysetup
-INTSETUP_VALGRIND=../.libs/integritysetup
-INTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ INTSETUP_VALGRIND=$INTSETUP
+else
+ INTSETUP_VALGRIND=../.libs/integritysetup
+ INTSETUP_LIB_VALGRIND=../.libs
+fi
DEV_NAME=dmc_test
DEV_NAME2=dmc_fake
@@ -115,7 +119,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $INTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$INTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$INTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
diff --git a/tests/keyring-compat-test b/tests/keyring-compat-test
index ea88c21..dc4787d 100755
--- a/tests/keyring-compat-test
+++ b/tests/keyring-compat-test
@@ -26,8 +26,12 @@ PWD="aaablabl"
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
@@ -54,7 +58,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -123,7 +130,7 @@ add_device() {
exit 77
fi
- sleep 2
+ sleep 1
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
DEV="/dev/$DEV"
diff --git a/tests/loopaes-test b/tests/loopaes-test
index fdb4cd3..62fe772 100755
--- a/tests/loopaes-test
+++ b/tests/loopaes-test
@@ -3,8 +3,12 @@
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
# try to validate using loop-AES losetup/kernel if available
LOSETUP_AES=/losetup-aes.old
@@ -49,7 +53,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
diff --git a/tests/luks1-compat-test b/tests/luks1-compat-test
index 18afcd5..c0de983 100755
--- a/tests/luks1-compat-test
+++ b/tests/luks1-compat-test
@@ -6,8 +6,12 @@ TST_DIR=luks1-images
MAP=luks1tst
KEYFILE=keyfile1
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
[ -z "$srcdir" ] && srcdir="."
@@ -38,7 +42,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
diff --git a/tests/luks2-integrity-test b/tests/luks2-integrity-test
index a8082f8..ff41ebf 100755
--- a/tests/luks2-integrity-test
+++ b/tests/luks2-integrity-test
@@ -11,8 +11,12 @@ PWD1=nHjJHjI23JK
KEY_FILE=key.img
FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
dmremove() { # device
udevadm settle >/dev/null 2>&1
@@ -45,7 +49,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -60,6 +67,11 @@ add_device() {
sync
}
+set_LO_DEV() { # file
+ # support both /dev/loopX and /dev/loop/X
+ LO_DEV=$(losetup -l -O NAME -n -j $1 2>/dev/null | sed -e 's/loop\//loop/')
+}
+
status_check() # name value [detached]
{
if [ -n "$3" ]; then
@@ -122,10 +134,12 @@ intformat() # alg integrity integrity_out key_size int_key_size sector_size csum
dump_check "Key:" $(($4 + $5))
echo -n "[ACTIVATE]"
$CRYPTSETUP open -d $KEY_FILE $DEV $DEV_NAME || fail "Cannot activate device."
+ set_LO_DEV $DEV
status_check "cipher" $1
status_check "sector size" $6
status_check "integrity:" $3
status_check "keysize:" $(($4 + $5))
+ [ -n "$LO_DEV" ] && status_check "device:" $LO_DEV
[ $5 -gt 0 ] && status_check "integrity keysize:" $5
int_check_sum $1 $7
echo -n "[REMOVE]"
@@ -137,12 +151,21 @@ intformat() # alg integrity integrity_out key_size int_key_size sector_size csum
$CRYPTSETUP luksHeaderBackup -q --header-backup-file $HEADER_IMG $DEV || fail
wipefs -a $DEV >/dev/null 2>&1 || fail
$CRYPTSETUP open --header $HEADER_IMG -d $KEY_FILE $DEV $DEV_NAME || fail "Cannot activate device."
+ set_LO_DEV $DEV
status_check "cipher" $1 1
status_check "sector size" $6 1
status_check "integrity:" $3 1
status_check "keysize:" $(($4 + $5)) 1
+ [ -n "$LO_DEV" ] && status_check "device:" $LO_DEV 1
[ $5 -gt 0 ] && status_check "integrity keysize:" $5 1
int_check_sum $1 $7
+ # check status returns values even if no --header is set
+ status_check "cipher" $1
+ status_check "sector size" $6
+ status_check "integrity:" $3
+ status_check "keysize:" $(($4 + $5))
+ [ -n "$LO_DEV" ] && status_check "device:" $LO_DEV
+ [ $5 -gt 0 ] && status_check "integrity keysize:" $5
$CRYPTSETUP close $DEV_NAME || fail "Cannot deactivate device."
$CRYPTSETUP luksHeaderRestore -q --header-backup-file $HEADER_IMG $DEV || fail
rm -f $HEADER_IMG
@@ -169,6 +192,7 @@ intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 512 256 512 ee501705a
intformat aes-xts-random hmac-sha256 hmac\(sha256\) 512 256 512 492c2d1cc9e222a850c399bfef4ed5a86bf5afc59e54f0f0c7ba8e2a64548323
intformat aes-cbc-essiv:sha256 hmac-sha256 hmac\(sha256\) 128 256 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b
intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 256 256 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b
+intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 256 256 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b 1
intformat aes-xts-random hmac-sha256 hmac\(sha256\) 256 256 4096 8c0463f5ac09613674bdf40b0ff6f985edbc3de04e51fdc688873cb333ef3cda
intformat aes-cbc-essiv:sha256 hmac-sha256 hmac\(sha256\) 256 256 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b
intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 512 256 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b
diff --git a/tests/luks2-reencryption-mangle-test b/tests/luks2-reencryption-mangle-test
index 5aa62e4..79b813d 100755
--- a/tests/luks2-reencryption-mangle-test
+++ b/tests/luks2-reencryption-mangle-test
@@ -5,8 +5,12 @@ PS4='$LINENO:'
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
CRYPTSETUP_RAW=$CRYPTSETUP
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
IMG=reenc-mangle-data
IMG_HDR=$IMG.hdr
IMG_HDR_BCP=$IMG_HDR.bcp
@@ -210,7 +214,10 @@ function valgrind_setup()
{
bin_check valgrind
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
CRYPTSETUP=valgrind_run
CRYPTSETUP_RAW="./valg.sh ${CRYPTSETUP_VALGRIND}"
}
diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test
index a647a8c..57acae0 100755
--- a/tests/luks2-reencryption-test
+++ b/tests/luks2-reencryption-test
@@ -4,8 +4,12 @@
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
FAST_PBKDF2="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
FAST_PBKDF_ARGON="--pbkdf-force-iterations 4 --pbkdf-memory 32 --pbkdf-parallel 1"
@@ -26,6 +30,13 @@ PWD1="93R4P4pIqAH8"
PWD2="1cND4319812f"
PWD3="1-9Qu5Ejfnqv"
DEV_LINK="reenc-test-link"
+KEYRING="luks2_reencryption_test_kr"
+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}"
+HAVE_KEYRING=0
FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
@@ -105,6 +116,13 @@ function remove_mapping()
scsi_debug_teardown $DEV
}
+function cleanup_keyring()
+{
+ if [ $HAVE_KEYRING -eq 1 ]; then
+ keyctl unlink %:$KEYRING "@s" >/dev/null 2>&1 || echo "Failed to unlink test keyring."
+ fi
+}
+
function fail()
{
local frame=0
@@ -112,6 +130,7 @@ function fail()
echo "FAILED backtrace:"
while caller $frame; do ((frame++)); done
remove_mapping
+ cleanup_keyring
exit 2
}
@@ -119,6 +138,7 @@ function skip()
{
[ -n "$1" ] && echo "$1"
remove_mapping
+ cleanup_keyring
exit 77
}
@@ -362,6 +382,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
@@ -787,14 +839,27 @@ function reencrypt_online_fixed_size() {
[ -n "$7" -a -f "$7" ] && rm -f $7
}
+function prepare_vk_keyring()
+{
+ local s_desc=$(keyctl rdescribe @s | cut -d';' -f5)
+ local us_desc=$(keyctl rdescribe @us | cut -d';' -f5)
+
+ if [ "$s_desc" = "$us_desc" -a -n "$s_desc" ]; then
+ echo "Session keyring is missing. Giving new one to parent process..."
+ keyctl new_session > /dev/null || fail
+ fi
+
+ keyctl newring $KEYRING "@s" >/dev/null || fail "Failed to setup test keyring environment"
+ keyctl search "@s" keyring $KEYRING >/dev/null 2>&1 || fail "Could not find test keyring in a session keyring."
+}
+
function setup_luks2_env() {
echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c aes-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail
echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail
- HAVE_KEYRING=$($CRYPTSETUP status $DEV_NAME | grep "key location: keyring")
- if [ -n "$HAVE_KEYRING" ]; then
+ local check_keyring=$($CRYPTSETUP status $DEV_NAME | grep "key location: keyring")
+ if [ -n "$check_keyring" ]; then
HAVE_KEYRING=1
- else
- HAVE_KEYRING=0
+ prepare_vk_keyring
fi
DEF_XTS_KEY=$($CRYPTSETUP status $DEV_NAME | grep "keysize:" | sed 's/\( keysize: \)\([0-9]\+\)\(.*\)/\2/')
[ -n "$DEF_XTS_KEY" ] || fail "Failed to parse xts mode key size."
@@ -819,7 +884,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -1254,6 +1322,42 @@ if [ -n "$DM_SECTOR_SIZE" ]; then
reencrypt_recover_online 4096 journal $HASH1
fi
+if [ $HAVE_KEYRING -eq 1 ]; then
+ 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
+fi
+
echo "[8] Reencryption with detached header recovery"
prepare_linear_dev 31 opt_blks=64 $OPT_XFERLEN_EXP
@@ -2204,4 +2308,5 @@ echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail
check_hash_dev_head $DEV 2048 $HASH2
remove_mapping
+cleanup_keyring
exit 0
diff --git a/tests/luks2-validation-test b/tests/luks2-validation-test
index cd9f0a6..545c38e 100755
--- a/tests/luks2-validation-test
+++ b/tests/luks2-validation-test
@@ -6,8 +6,12 @@ PS4='$LINENO:'
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
START_DIR=$(pwd)
@@ -106,7 +110,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
diff --git a/tests/luks2_invalid_cipher.img.xz b/tests/luks2_invalid_cipher.img.xz
new file mode 100644
index 0000000..52ce436
--- /dev/null
+++ b/tests/luks2_invalid_cipher.img.xz
Binary files differ
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 0000000..43fff9a
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,482 @@
+fs = import('fs')
+
+# copy images and generators to build directory from where tests run
+test_files_to_copy = [
+ 'bitlk-images.tar.xz',
+ 'blkid-luks2-pv.img.xz',
+ 'compatimage.img.xz',
+ 'compatimage2.img.xz',
+ 'compatv10image.img.xz',
+ 'conversion_imgs.tar.xz',
+ 'evil_hdr-keyslot_overlap.xz',
+ 'evil_hdr-luks_hdr_damage.xz',
+ 'evil_hdr-payload_overwrite.xz',
+ 'evil_hdr-small_luks_device.xz',
+ 'evil_hdr-stripes_payload_dmg.xz',
+ 'fvault2-images.tar.xz',
+ 'generators/generate-luks2-area-in-json-hdr-space-json0.img.sh',
+ 'img_fs_ext4.img.xz',
+ 'luks1-images.tar.xz',
+ 'luks2_header_requirements.tar.xz',
+ 'luks2_keyslot_unassigned.img.xz',
+ 'luks2_mda_images.tar.xz',
+ 'luks2_valid_hdr.img.xz',
+ 'luks2_invalid_cipher.img.xz',
+ 'tcrypt-images.tar.xz',
+ 'valid_header_file.xz',
+ 'xfs_512_block_size.img.xz',
+ 'valg.sh',
+ 'cryptsetup-valg-supps',
+]
+
+foreach file : test_files_to_copy
+ fs.copyfile(file)
+endforeach
+
+api_test = executable('api-test',
+ [
+ 'api-test.c',
+ 'test_utils.c',
+ ],
+ dependencies: devmapper,
+ link_with: libcryptsetup,
+ c_args: ['-DNO_CRYPTSETUP_PATH'],
+ include_directories: includes_lib)
+
+api_test_2 = executable('api-test-2',
+ [
+ 'api-test-2.c',
+ 'test_utils.c',
+ ],
+ dependencies: devmapper,
+ link_with: libcryptsetup,
+ c_args: [
+ '-DNO_CRYPTSETUP_PATH',
+ ],
+ include_directories: includes_lib)
+
+vectors_test = executable('vectors-test',
+ [
+ 'crypto-vectors.c',
+ ],
+ link_with: libcrypto_backend,
+ c_args: [
+ '-DNO_CRYPTSETUP_PATH',
+ ],
+ include_directories: includes_lib)
+
+differ = executable('differ',
+ [
+ 'differ.c',
+ ],
+ c_args: [
+ '-Wall',
+ '-O2',
+ ])
+
+unit_utils_io = executable('unit-utils-io',
+ [
+ 'unit-utils-io.c',
+ ],
+ link_with: libutils_io,
+ c_args: [
+ '-DNO_CRYPTSETUP_PATH',
+ ],
+ include_directories: includes_lib)
+
+unit_utils_crypt_test = files('unit-utils-crypt.c',) + lib_utils_crypt_files
+unit_utils_crypt_test = executable('unit-utils-crypt-test-test',
+ unit_utils_crypt_test,
+ link_with: libcryptsetup,
+ c_args: [
+ '-DNO_CRYPTSETUP_PATH',
+ ],
+ include_directories: includes_lib)
+
+unit_wipe = executable('unit-wipe',
+ [
+ 'unit-wipe.c',
+ ],
+ link_with: libcryptsetup,
+ c_args: [
+ '-DNO_CRYPTSETUP_PATH',
+ ],
+ include_directories: includes_lib)
+
+generate_symbols_list = find_program('generate-symbols-list')
+test_symbols_list_h = custom_target('test-symbols-list.h',
+ output: 'test-symbols-list.h',
+ input: [
+ libcryptsetup_sym_path,
+ ],
+ # the scripts writes the output to stdout, capture and write to output file
+ capture: true,
+ command: [
+ generate_symbols_list,
+ '@INPUT@',
+ ])
+all_symbols_test = executable('all-symbols-test',
+ [
+ 'all-symbols-test.c',
+ test_symbols_list_h,
+ ],
+ dependencies: dl,
+ link_with: libcryptsetup,
+ c_args: [
+ '-DNO_CRYPTSETUP_PATH',
+ ],
+ include_directories: includes_lib)
+
+fake_systemd_tpm_path = shared_library('fake_systemd_tpm_path',
+ [
+ 'fake_systemd_tpm_path.c',
+ ],
+ name_prefix: '',
+ build_by_default: not enable_static)
+
+tests_env = environment()
+tests_env.set('CRYPTSETUP_PATH', src_build_dir)
+tests_env.set('LIBCRYPTSETUP_DIR', lib_build_dir)
+tests_env.set('srcdir', meson.current_source_dir())
+tests_env.set('SSH_BUILD_DIR', tokens_ssh_build_dir)
+tests_env.set('CRYPTSETUP_TESTS_RUN_IN_MESON', '1')
+
+valgrind_tests_env = tests_env
+valgrind_tests_env.set('VALG', '1')
+
+add_test_setup('default',
+ is_default: true,
+ env: tests_env,
+ exclude_suites: [ 'valgrind-only' ]
+)
+
+add_test_setup('valgrind',
+ env: valgrind_tests_env,
+ exclude_suites: [ 'not-in-valgrind' ]
+)
+
+test('00modules-test',
+ find_program('./00modules-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind',
+ priority: 9999)
+test('api-test',
+ api_test,
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind')
+test('valg-api-test',
+ find_program('./valg-api.sh'),
+ args: [ './api-test'],
+ depends: [ api_test ],
+ workdir: meson.current_build_dir(),
+ env: 'INFOSTRING=api-test-000',
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'valgrind-only')
+test('api-test-2',
+ api_test_2,
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind')
+test('valg-api-test-2',
+ find_program('./valg-api.sh'),
+ args: [ './api-test-2'],
+ depends: [ api_test_2 ],
+ workdir: meson.current_build_dir(),
+ env: 'INFOSTRING=api-test-002',
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'valgrind-only')
+test('blockwise-compat-test',
+ find_program('./blockwise-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind',
+ depends: [
+ unit_utils_io,
+ ])
+test('keyring-test',
+ find_program('./keyring-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind')
+test('vectors-test',
+ vectors_test,
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind')
+test('valg-vectors-test',
+ find_program('./valg-api.sh'),
+ args: [ './vectors-test' ],
+ depends: [ vectors_test ],
+ workdir: meson.current_build_dir(),
+ env: 'INFOSTRING=vectors-test',
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'valgrind-only')
+test('unit-wipe-test',
+ find_program('./unit-wipe-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind',
+ depends: [
+ unit_wipe,
+ ])
+test('unit-utils-crypt-test',
+ unit_utils_crypt_test,
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind')
+test('valg-unit-utils-crypt-test',
+ find_program('./valg-api.sh'),
+ args: [ './unit-utils-crypt-test' ],
+ depends: [ unit_utils_crypt_test ],
+ workdir: meson.current_build_dir(),
+ env: 'INFOSTRING=unit-utils-crypt-test',
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'valgrind-only')
+
+if not enable_static
+ test('run-all-symbols',
+ find_program('./run-all-symbols'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind',
+ depends: [
+ all_symbols_test,
+ libcryptsetup,
+ ])
+endif
+
+if get_option('cryptsetup')
+ test('compat-args-test',
+ find_program('./compat-args-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ test_symbols_list_h,
+ ])
+ test('compat-test',
+ find_program('./compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ differ,
+ ])
+ test('compat-test2',
+ find_program('./compat-test2'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('compat-test-opal',
+ find_program('./compat-test-opal'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('loopaes-test',
+ find_program('./loopaes-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('align-test',
+ find_program('./align-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('align-test2',
+ find_program('./align-test2'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('discards-test',
+ find_program('./discards-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('mode-test',
+ find_program('./mode-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('password-hash-test',
+ find_program('./password-hash-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('tcrypt-compat-test',
+ find_program('./tcrypt-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('luks1-compat-test',
+ find_program('./luks1-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('device-test',
+ find_program('./device-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('keyring-compat-test',
+ find_program('./keyring-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('luks2-validation-test',
+ find_program('./luks2-validation-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('luks2-integrity-test',
+ find_program('./luks2-integrity-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('bitlk-compat-test',
+ find_program('./bitlk-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('fvault2-compat-test',
+ find_program('./fvault2-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('reencryption-compat-test',
+ find_program('./reencryption-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('luks2-reencryption-test',
+ find_program('./luks2-reencryption-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+ test('luks2-reencryption-mangle-test',
+ find_program('./luks2-reencryption-mangle-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup,
+ ])
+endif
+
+if get_option('veritysetup')
+ test('verity-compat-test',
+ find_program('verity-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ veritysetup,
+ ])
+endif
+
+if get_option('integritysetup')
+ test('integrity-compat-test',
+ find_program('integrity-compat-test'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ integritysetup,
+ ])
+endif
+
+if get_option('ssh-token') and not enable_static
+ test('ssh-test-plugin',
+ find_program('ssh-test-plugin'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ depends: [
+ cryptsetup_ssh,
+ libcryptsetup_token_ssh,
+ ])
+endif
+
+if get_option('external-tokens') and not enable_static
+ test('systemd-test-plugin',
+ find_program('systemd-test-plugin'),
+ workdir: meson.current_build_dir(),
+ timeout: 14400,
+ is_parallel: false,
+ suite: 'not-in-valgrind',
+ depends: [
+ fake_systemd_tpm_path,
+ ])
+endif
+
+subdir('fuzz')
diff --git a/tests/mode-test b/tests/mode-test
index 82171fb..81780cd 100755
--- a/tests/mode-test
+++ b/tests/mode-test
@@ -8,6 +8,7 @@ DEV_NAME=dmc_test
HEADER_IMG=mode-test.img
PASSWORD=3xrododenron
PASSWORD1=$PASSWORD
+KEY="7c0dc5dfd0c9191381d92e6ebb3b29e7f0dba53b0de132ae23f5726727173540"
FAST_PBKDF2="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
# cipher-chainmode-ivopts:ivmode
@@ -17,8 +18,12 @@ IVMODES="null benbi plain plain64 essiv:sha256"
LOOPDEV=$(losetup -f 2>/dev/null)
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
dmremove() { # device
udevadm settle >/dev/null 2>&1
@@ -51,7 +56,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -184,4 +192,13 @@ done
dmcrypt xchacha12,aes-adiantum-plain64
dmcrypt xchacha20,aes-adiantum-plain64
+echo -n "CAPI format:"
+echo $PASSWORD | $CRYPTSETUP create -h sha256 -c 'capi:xts(aes)-plain64' -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME || fail
+$CRYPTSETUP close "$DEV_NAME"_tstdev || fail
+echo $PASSWORD | $CRYPTSETUP create -h sha256 -c 'capi:xts(ecb(aes-generic))-plain64' -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME 2>/dev/null && fail
+dmsetup create "$DEV_NAME"_tstdev --table "0 8 crypt capi:xts(ecb(aes-generic))-plain64 $KEY 0 /dev/mapper/$DEV_NAME 0" || fail
+$CRYPTSETUP status "$DEV_NAME"_tstdev 2>/dev/null | grep "type:" | grep -q "n/a" || fail
+$CRYPTSETUP close "$DEV_NAME"_tstdev 2>/dev/null || fail
+echo [OK]
+
cleanup
diff --git a/tests/password-hash-test b/tests/password-hash-test
index 6e3c78c..e777390 100755
--- a/tests/password-hash-test
+++ b/tests/password-hash-test
@@ -9,8 +9,12 @@ KEY_FILE=keyfile
DEV2=$DEV_NAME"_x"
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
dmremove() { # device
udevadm settle >/dev/null 2>&1
@@ -42,7 +46,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
diff --git a/tests/reencryption-compat-test b/tests/reencryption-compat-test
index 453831d..68a8c1f 100755
--- a/tests/reencryption-compat-test
+++ b/tests/reencryption-compat-test
@@ -6,8 +6,12 @@ REENC_BIN=$CRYPTSETUP
REENC="$REENC_BIN reencrypt"
FAST_PBKDF="--pbkdf-force-iterations 1000 --pbkdf pbkdf2"
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
DEV_NAME=reenc9768
DEV_NAME2=reenc1273
@@ -33,7 +37,7 @@ function fips_mode()
function del_scsi_device()
{
rmmod scsi_debug >/dev/null 2>&1
- sleep 2
+ sleep 1
}
function remove_mapping()
@@ -68,7 +72,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -88,7 +95,7 @@ function add_scsi_device() {
exit 77
fi
- sleep 2
+ sleep 1
SCSI_DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
[ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV."
}
diff --git a/tests/run-all-symbols b/tests/run-all-symbols
index 775d5bb..58a1ba6 100755
--- a/tests/run-all-symbols
+++ b/tests/run-all-symbols
@@ -1,7 +1,7 @@
#!/bin/bash
-DIR=../.libs
-FILE=$DIR/libcryptsetup.so
+[ -z "$LIBCRYPTSETUP_DIR" ] && LIBCRYPTSETUP_DIR=../.libs
+FILE=$LIBCRYPTSETUP_DIR/libcryptsetup.so
function fail()
{
@@ -15,7 +15,7 @@ function skip()
exit 77
}
-test -d $DIR || fail "Directory $DIR is missing."
+test -d $LIBCRYPTSETUP_DIR || fail "Directory $LIBCRYPTSETUP_DIR is missing."
test -f $FILE || skip "WARNING: Shared $FILE is missing, test skipped."
./all-symbols-test $FILE $@
diff --git a/tests/ssh-test-plugin b/tests/ssh-test-plugin
index 5b3966e..2475034 100755
--- a/tests/ssh-test-plugin
+++ b/tests/ssh-test-plugin
@@ -1,10 +1,10 @@
#!/bin/bash
[ -z "$CRYPTSETUP_PATH" ] && {
- TOKEN_PATH="./fake_token_path.so"
- [ ! -f $TOKEN_PATH ] && { echo "Please compile $TOKEN_PATH."; exit 77; }
- export LD_PRELOAD=$TOKEN_PATH
CRYPTSETUP_PATH=".."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ SSH_BUILD_DIR="$PWD/../.libs"
+ fi
}
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
CRYPTSETUP_SSH=$CRYPTSETUP_PATH/cryptsetup-ssh
@@ -21,12 +21,24 @@ SSH_KEY_PATH="$HOME/sshtest-key"
FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_SSH_VALGRIND=../.libs/cryptsetup-ssh
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+ CRYPTSETUP_SSH=$CRYPTSETUP_PATH/../tokens/ssh/cryptsetup-ssh
+ CRYPTSETUP_SSH_VALGRIND=$CRYPTSETUP_SSH
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_SSH_VALGRIND=../.libs/cryptsetup-ssh
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
[ -z "$srcdir" ] && srcdir="."
+[ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ] || {
+ # test runs on meson build
+ CRYPTSETUP_SSH="$CRYPTSETUP_PATH/../tokens/ssh/cryptsetup-ssh"
+}
+
function remove_mapping()
{
[ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP
@@ -104,7 +116,9 @@ function valgrind_setup()
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
[ ! -f $CRYPTSETUP_SSH_VALGRIND ] && fail "Unable to get location of cryptsetup-ssh executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
@@ -152,6 +166,9 @@ check_dump()
[ "$keyslot_dump" = "$keyslot" ] || fail " keyslot check from dump failed."
}
+if [ -n "$SSH_BUILD_DIR" ]; then
+ CUSTOM_TOKENS_PATH="--external-tokens-path $SSH_BUILD_DIR"
+fi
[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run && CRYPTSETUP_SSH=valgrind_run_ssh
[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
@@ -174,17 +191,17 @@ ssh_check
create_user
ssh_setup
-$CRYPTSETUP_SSH add $IMG --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH
+$CRYPTSETUP_SSH add $IMG --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH $CUSTOM_TOKENS_PATH
[ $? -ne 0 ] && fail "Failed to add SSH token to $IMG"
-out=$($CRYPTSETUP luksDump $IMG)
+out=$($CRYPTSETUP luksDump $CUSTOM_TOKENS_PATH $IMG)
check_dump "$out" 0
echo "[OK]"
echo -n "Activating using SSH token: "
$CRYPTSETUP luksOpen --token-only --disable-external-tokens -r $IMG $MAP && fail "Tokens should be disabled"
-$CRYPTSETUP luksOpen -r $IMG $MAP -q >/dev/null 2>&1 <&-
+$CRYPTSETUP luksOpen $CUSTOM_TOKENS_PATH -r $IMG $MAP -q >/dev/null 2>&1 <&-
[ $? -ne 0 ] && fail "Failed to open $IMG using SSH token"
echo "[OK]"
@@ -193,10 +210,10 @@ $CRYPTSETUP token remove --token-id 0 $IMG || fail "Failed to remove token"
echo -n "Adding SSH token with --key-slot: "
-$CRYPTSETUP_SSH add $IMG --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH --key-slot 1
+$CRYPTSETUP_SSH add $IMG --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH --key-slot 1 $CUSTOM_TOKENS_PATH
[ $? -ne 0 ] && fail "Failed to add SSH token to $IMG"
-out=$($CRYPTSETUP luksDump $IMG)
+out=$($CRYPTSETUP luksDump $CUSTOM_TOKENS_PATH $IMG)
check_dump "$out" 1
echo "[OK]"
diff --git a/tests/systemd-test-plugin b/tests/systemd-test-plugin
index 5f37324..7515f76 100755
--- a/tests/systemd-test-plugin
+++ b/tests/systemd-test-plugin
@@ -61,14 +61,51 @@ CRYPTENROLL_LD_PRELOAD=""
# if CRYPTSETUP_PATH is defined, we run against installed binaries,
# otherwise we compile systemd tokens from source
+[ ! -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ] && {
+ bin_check git
+ bin_check meson
+ bin_check ninja
+ bin_check pkgconf
+
+ INSTALL_PATH=$CRYPTSETUP_PATH/../external-tokens/install
+ mkdir -p $INSTALL_PATH
+ DESTDIR=$INSTALL_PATH meson install -C ..
+ PC_FILE="$(find $INSTALL_PATH -name 'libcryptsetup.pc')"
+ echo "INSTALL_PATH $INSTALL_PATH"
+ echo "PC_FILE $PC_FILE"
+ sed -i "s/^prefix=/prefix=${INSTALL_PATH//\//\\\/}/g" "$PC_FILE"
+ export PKG_CONFIG_PATH=$(dirname $PC_FILE)
+
+ # systemd build system misses libcryptsetup.h if it is installed in non-default path
+ export CFLAGS="${CFLAGS:-} $(pkgconf --cflags libcryptsetup)"
+
+ SYSTEMD_PATH=$CRYPTSETUP_PATH/../external-tokens/systemd
+ SYSTEMD_CRYPTENROLL=$SYSTEMD_PATH/build/systemd-cryptenroll
+
+ mkdir -p $SYSTEMD_PATH
+ [ -d $SYSTEMD_PATH/.git ] || git clone --depth=1 https://github.com/systemd/systemd.git $SYSTEMD_PATH
+ cd $SYSTEMD_PATH
+ meson setup build/ -D tpm2=true -D libcryptsetup=true -D libcryptsetup-plugins=true || skip "Failed to configure systemd via meson, some dependencies are probably missing."
+ ninja -C build/ systemd-cryptenroll libcryptsetup-token-systemd-tpm2.so || skip "Failed to build systemd."
+
+ CRYPTSETUP_TOKENS_PATH=$CRYPTSETUP_PATH/../tokens/ssh
+
+ cd $CRYPTSETUP_PATH/../tests
+ cp $SYSTEMD_PATH/build/libcryptsetup-token-*.so $CRYPTSETUP_TOKENS_PATH
+ cp $SYSTEMD_PATH/build/src/shared/*.so $CRYPTSETUP_TOKENS_PATH
+ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$CRYPTSETUP_PATH/../tests"
+
+ CRYPTENROLL_LD_PRELOAD="$CRYPTSETUP_PATH/../lib/libcryptsetup.so"
+
+ echo "CRYPTENROLL_LD_PRELOAD $CRYPTENROLL_LD_PRELOAD"
+}
+
[ -z "$CRYPTSETUP_PATH" ] && {
bin_check git
bin_check meson
bin_check ninja
bin_check pkgconf
- TOKEN_PATH=fake_token_path.so
- [ -f $TOKEN_PATH ] || skip "Please compile $TOKEN_PATH."
INSTALL_PATH=$(pwd)/external-tokens/install
make -C .. install DESTDIR=$INSTALL_PATH
PC_FILE="$(find $INSTALL_PATH -name 'libcryptsetup.pc')"
@@ -83,16 +120,17 @@ CRYPTENROLL_LD_PRELOAD=""
SYSTEMD_CRYPTENROLL=$SYSTEMD_PATH/build/systemd-cryptenroll
mkdir -p $SYSTEMD_PATH
- [ "$(ls -A $SYSTEMD_PATH)" ] || git clone --depth=1 https://github.com/systemd/systemd.git $SYSTEMD_PATH
+ [ -d $SYSTEMD_PATH/.git ] || git clone --depth=1 https://github.com/systemd/systemd.git $SYSTEMD_PATH
cd $SYSTEMD_PATH
- meson -D tpm2=true -D libcryptsetup=true -D libcryptsetup-plugins=true build/ || skip "Failed to configure systemd via meson, some dependencies are probably missing."
+ meson setup build/ -D tpm2=true -D libcryptsetup=true -D libcryptsetup-plugins=true || skip "Failed to configure systemd via meson, some dependencies are probably missing."
ninja -C build/ systemd-cryptenroll libcryptsetup-token-systemd-tpm2.so || skip "Failed to build systemd."
+ CRYPTSETUP_TOKENS_PATH=$CRYPTSETUP_PATH/.libs
+
cd $CRYPTSETUP_PATH/tests
- cp $SYSTEMD_PATH/build/libcryptsetup-token-*.so ../.libs/
- cp $SYSTEMD_PATH/build/src/shared/*.so ../.libs/
+ cp $SYSTEMD_PATH/build/libcryptsetup-token-*.so $CRYPTSETUP_TOKENS_PATH
+ cp $SYSTEMD_PATH/build/src/shared/*.so $CRYPTSETUP_TOKENS_PATH
- export LD_PRELOAD="${LD_PRELOAD-}:$CRYPTSETUP_PATH/tests/$TOKEN_PATH"
CRYPTENROLL_LD_PRELOAD="$CRYPTSETUP_PATH/.libs/libcryptsetup.so"
}
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
@@ -115,7 +153,11 @@ CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
echo "Virtual TPM set up at $TPM_PATH"
}
+if [ -n "$SSH_BUILD_DIR" ]; then
+ CUSTOM_TOKENS_PATH="--external-tokens-path $SSH_BUILD_DIR"
+fi
FAKE_TPM_PATH="$(pwd)/fake_systemd_tpm_path.so"
+[ ! -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ] && FAKE_TPM_PATH="$CRYPTSETUP_PATH/../tests/fake_systemd_tpm_path.so"
[ -f $FAKE_TPM_PATH ] || skip "Please compile $FAKE_TPM_PATH."
export LD_PRELOAD="$LD_PRELOAD:$FAKE_TPM_PATH"
@@ -128,23 +170,23 @@ echo $PASSWD | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $IMG --force-
echo "Enrolling the device to TPM 2 using systemd-cryptenroll.."
LD_PRELOAD="$LD_PRELOAD:$CRYPTENROLL_LD_PRELOAD" PASSWORD="$PASSWD" $SYSTEMD_CRYPTENROLL $IMG --tpm2-device=$TPM_PATH >/dev/null 2>&1
-$CRYPTSETUP luksDump $IMG | grep -q "tpm2-blob" || fail "Failed to dump $IMG using systemd_tpm2 token (no tpm2-blob in output)."
+$CRYPTSETUP luksDump --external-tokens-path $CRYPTSETUP_TOKENS_PATH $IMG | grep -q "tpm2-blob" || fail "Failed to dump $IMG using systemd_tpm2 token (no tpm2-blob in output)."
echo "Activating the device via TPM2 external token.."
-$CRYPTSETUP open --token-only $IMG $MAP >/dev/null 2>&1 || fail "Failed to open $IMG using systemd_tpm2 token."
+$CRYPTSETUP open --external-tokens-path $CRYPTSETUP_TOKENS_PATH --token-only $IMG $MAP >/dev/null 2>&1 || fail "Failed to open $IMG using systemd_tpm2 token."
$CRYPTSETUP close $MAP >/dev/null 2>&1 || fail "Failed to close $MAP."
echo "Adding passphrase via TPM2 token.."
-echo $PASSWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $IMG --force-password -q --token-only >/dev/null 2>&1 || fail "Failed to add passphrase by tpm2 token."
+echo $PASSWD2 | $CRYPTSETUP luksAddKey --external-tokens-path $CRYPTSETUP_TOKENS_PATH $FAST_PBKDF_OPT $IMG --force-password -q --token-only >/dev/null 2>&1 || fail "Failed to add passphrase by tpm2 token."
echo $PASSWD2 | $CRYPTSETUP open $IMG --test-passphrase --disable-external-tokens >/dev/null 2>&1 || fail "Failed to test passphrase added by tpm2 token."
echo "Exporting and removing TPM2 token.."
EXPORTED_TOKEN=$($CRYPTSETUP token export $IMG --token-id 0)
$CRYPTSETUP token remove $IMG --token-id 0
-$CRYPTSETUP open $IMG --test-passphrase --token-only >/dev/null 2>&1 && fail "Activating without passphrase should fail after TPM2 token removal."
+$CRYPTSETUP open --external-tokens-path $CRYPTSETUP_TOKENS_PATH $IMG --test-passphrase --token-only >/dev/null 2>&1 && fail "Activating without passphrase should fail after TPM2 token removal."
echo "Re-importing TPM2 token.."
echo $EXPORTED_TOKEN | $CRYPTSETUP token import $IMG --token-id 0 || fail "Failed to re-import deleted token."
-$CRYPTSETUP open $IMG --test-passphrase --token-only >/dev/null 2>&1 || fail "Failed to activate after re-importing deleted token."
+$CRYPTSETUP open --external-tokens-path $CRYPTSETUP_TOKENS_PATH $IMG --test-passphrase --token-only >/dev/null 2>&1 || fail "Failed to activate after re-importing deleted token."
cleanup
exit 0
diff --git a/tests/tcrypt-compat-test b/tests/tcrypt-compat-test
index c0fc50a..0708b32 100755
--- a/tests/tcrypt-compat-test
+++ b/tests/tcrypt-compat-test
@@ -11,8 +11,12 @@ PASSWORD_HIDDEN="bbbbbbbbbbbb"
PASSWORD_72C="aaaaaaaaaaaabbbbbbbbbbbbccccccccccccddddddddddddeeeeeeeeeeeeffffffffffff"
PIM=1234
-CRYPTSETUP_VALGRIND=../.libs/cryptsetup
-CRYPTSETUP_LIB_VALGRIND=../.libs
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ CRYPTSETUP_VALGRIND=$CRYPTSETUP
+else
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+fi
[ -z "$srcdir" ] && srcdir="."
@@ -54,12 +58,12 @@ function test_one() # cipher mode keysize rm_pattern
fi
}
-function test_kdf() # hash
+function test_kdf() # hash img_hash
{
$CRYPTSETUP benchmark -h "$1" >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo "pbkdf2-$1 [N/A]"
- IMGS=$(ls $TST_DIR/[tv]c* | grep "$1")
+ IMGS=$(ls $TST_DIR/[tv]c* | grep "$2")
[ -n "$IMGS" ] && rm $IMGS
else
echo "pbkdf2-$1 [OK]"
@@ -78,11 +82,12 @@ function test_required()
command -v blkid >/dev/null || skip "blkid tool required, test skipped."
echo "REQUIRED KDF TEST"
- test_kdf sha256
- test_kdf sha512
- test_kdf ripemd160
- test_kdf whirlpool
- test_kdf stribog512
+ test_kdf sha256 sha256
+ test_kdf sha512 sha512
+ test_kdf blake2s-256 blake2
+ test_kdf ripemd160 ripemd160
+ test_kdf whirlpool whirlpool
+ test_kdf stribog512 stribog
echo "REQUIRED CIPHERS TEST"
test_one aes cbc 256 cbc-aes
@@ -114,7 +119,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
- export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()
diff --git a/tests/tcrypt-images.tar.xz b/tests/tcrypt-images.tar.xz
index 1841870..5ccef08 100644
--- a/tests/tcrypt-images.tar.xz
+++ b/tests/tcrypt-images.tar.xz
Binary files differ
diff --git a/tests/test_utils.c b/tests/test_utils.c
index 97c62a0..d06e738 100644
--- a/tests/test_utils.c
+++ b/tests/test_utils.c
@@ -1,8 +1,8 @@
/*
* cryptsetup library API test utilities
*
- * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2023 Milan Broz
+ * Copyright (C) 2009-2024 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -201,25 +201,39 @@ int fips_mode(void)
*/
int create_dmdevice_over_loop(const char *dm_name, const uint64_t size)
{
+ int r;
+
+ r = create_dmdevice_over_device(dm_name, THE_LOOP_DEV, size, t_dev_offset);
+ if (r != 0)
+ return r;
+
+ t_dev_offset += size;
+
+ return r;
+}
+
+/*
+ * Creates dm-linear target over the desired block device.
+ */
+int create_dmdevice_over_device(const char *dm_name, const char *device, uint64_t size, uint64_t offset)
+{
char cmd[128];
int r;
uint64_t r_size;
- if (t_device_size(THE_LOOP_DEV, &r_size) < 0 || r_size <= t_dev_offset || !size)
+ if (!device || t_device_size(device, &r_size) < 0 || r_size <= offset || !size)
return -1;
- if ((r_size - t_dev_offset) < size) {
- printf("No enough space on backing loop device\n.");
+ if ((r_size - offset) < size) {
+ printf("No enough space on device %s\n.", device);
return -2;
}
r = snprintf(cmd, sizeof(cmd),
"dmsetup create %s --table \"0 %" PRIu64 " linear %s %" PRIu64 "\"",
- dm_name, size, THE_LOOP_DEV, t_dev_offset);
+ dm_name, size, device, offset);
if (r < 0 || (size_t)r >= sizeof(cmd))
return -3;
- if (!(r = _system(cmd, 1)))
- t_dev_offset += size;
- return r;
+ return _system(cmd, 1);
}
__attribute__((format(printf, 3, 4)))
@@ -450,12 +464,12 @@ void global_log_callback(int level, const char *msg, void *usrptr __attribute__(
len = strlen(global_log);
- if (len + strlen(msg) > sizeof(global_log)) {
+ if (len + strlen(msg) >= sizeof(global_log)) {
printf("Log buffer is too small, fix the test.\n");
return;
}
- strncat(global_log, msg, sizeof(global_log) - len);
+ strncat(global_log, msg, sizeof(global_log) - len - 1);
global_lines++;
if (level == CRYPT_LOG_ERROR) {
len = strlen(msg);
diff --git a/tests/unit-utils-crypt.c b/tests/unit-utils-crypt.c
index 4ab3c96..22b8788 100644
--- a/tests/unit-utils-crypt.c
+++ b/tests/unit-utils-crypt.c
@@ -1,7 +1,7 @@
/*
* cryptsetup crypto name and hex conversion helper test vectors
*
- * Copyright (C) 2022-2023 Milan Broz
+ * Copyright (C) 2022-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/unit-utils-io.c b/tests/unit-utils-io.c
index 3bfc762..642f778 100644
--- a/tests/unit-utils-io.c
+++ b/tests/unit-utils-io.c
@@ -1,7 +1,7 @@
/*
* simple unit test for utils_io.c (blockwise low level functions)
*
- * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/unit-wipe-test b/tests/unit-wipe-test
index 4d0a078..a898354 100755
--- a/tests/unit-wipe-test
+++ b/tests/unit-wipe-test
@@ -41,7 +41,7 @@ function add_device()
if [ $? -ne 0 ] ; then
skip "This kernel seems to not support proper scsi_debug module."
fi
- grep -q scsi_debug /sys/block/*/device/model || sleep 2
+ sleep 1
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
DEV="/dev/$DEV"
[ -b $DEV ] || fail "Cannot find $DEV."
diff --git a/tests/unit-wipe.c b/tests/unit-wipe.c
index c3019c7..d381a83 100644
--- a/tests/unit-wipe.c
+++ b/tests/unit-wipe.c
@@ -1,7 +1,7 @@
/*
* unit test helper for crypt_wipe API call
*
- * Copyright (C) 2022-2023 Milan Broz
+ * Copyright (C) 2022-2024 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/tests/verity-compat-test b/tests/verity-compat-test
index 8a28a12..82c49d3 100755
--- a/tests/verity-compat-test
+++ b/tests/verity-compat-test
@@ -2,8 +2,13 @@
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
VERITYSETUP=$CRYPTSETUP_PATH/veritysetup
-VERITYSETUP_VALGRIND=../.libs/veritysetup
-VERITYSETUP_LIB_VALGRIND=../.libs
+
+if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ VERITYSETUP_VALGRIND=$VERITYSETUP
+else
+ VERITYSETUP_VALGRIND=../.libs/veritysetup
+ VERITYSETUP_LIB_VALGRIND=../.libs
+fi
DEV_NAME=verity3273
DEV_NAME2=verity3273x
@@ -304,7 +309,10 @@ function valgrind_setup()
{
command -v valgrind >/dev/null || fail "Cannot find valgrind."
[ ! -f $VERITYSETUP_VALGRIND ] && fail "Unable to get location of veritysetup executable."
- export LD_LIBRARY_PATH="$VERITYSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ [ ! -f valg.sh ] && fail "Unable to get location of valg runner script."
+ if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
+ export LD_LIBRARY_PATH="$VERITYSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
+ fi
}
function valgrind_run()