diff options
author | Karol Lewandowski <k.lewandowsk@samsung.com> | 2023-02-16 16:19:43 +0100 |
---|---|---|
committer | Karol Lewandowski <k.lewandowsk@samsung.com> | 2023-02-16 16:19:43 +0100 |
commit | f7fc3bb4e50cce23dd95111b246b6e034537e2cf (patch) | |
tree | ab99d614969f6ed28f4cf95b09053f62feb370a1 /tests | |
parent | 322b430a2589cdc7985e98a14ec12322b91c9d5e (diff) | |
download | cryptsetup-f7fc3bb4e50cce23dd95111b246b6e034537e2cf.tar.gz cryptsetup-f7fc3bb4e50cce23dd95111b246b6e034537e2cf.tar.bz2 cryptsetup-f7fc3bb4e50cce23dd95111b246b6e034537e2cf.zip |
Imported Upstream version 2.3.7upstream/2.3.7
Diffstat (limited to 'tests')
28 files changed, 1630 insertions, 292 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 5a7e21d..4688bff 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -25,7 +25,7 @@ TESTS += verity-compat-test endif if REENCRYPT -TESTS += reencryption-compat-test reencryption-compat-test2 luks2-reencryption-test +TESTS += reencryption-compat-test reencryption-compat-test2 luks2-reencryption-test luks2-reencryption-mangle-test endif if INTEGRITYSETUP @@ -57,6 +57,7 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ reencryption-compat-test \ reencryption-compat-test2 \ luks2-reencryption-test \ + luks2-reencryption-mangle-test \ tcrypt-compat-test \ luks1-compat-test \ luks2-validation-test generators \ @@ -76,6 +77,8 @@ CLEANFILES = cryptsetup-tst* valglog* *-fail-*.log clean-local: -rm -rf tcrypt-images luks1-images luks2-images bitlk-images conversion_imgs luks2_valid_hdr.img blkid-luks2-pv-img blkid-luks2-pv-img.bcp +LDADD = $(LTLIBINTL) + differ_SOURCES = differ.c differ_CFLAGS = $(AM_CFLAGS) -Wall -O2 @@ -112,6 +115,7 @@ compatimage.img: @xz -k -d compatimage.img.xz valgrind-check: api-test api-test-2 differ + @VALG=1 ./compat-test @VALG=1 ./compat-test2 @VALG=1 ./luks2-validation-test @VALG=1 ./verity-compat-test @@ -119,6 +123,8 @@ valgrind-check: api-test api-test-2 differ @INFOSTRING="api-test-000" ./valg-api.sh ./api-test @INFOSTRING="api-test-002" ./valg-api.sh ./api-test-2 @VALG=1 ./luks2-reencryption-test - @VALG=1 ./compat-test + @VALG=1 ./luks2-reencryption-mangle-test + @VALG=1 ./bitlk-compat-test + @grep -l "ERROR SUMMARY: [^0] errors" valglog* || echo "No leaks detected." .PHONY: valgrind-check diff --git a/tests/Makefile.in b/tests/Makefile.in index 19c0000..c63cdc3 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.2 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -95,7 +95,7 @@ TESTS = 00modules-test api-test$(EXEEXT) api-test-2$(EXEEXT) \ vectors-test$(EXEEXT) blockwise-compat bitlk-compat-test \ $(am__append_1) $(am__append_2) $(am__append_3) @VERITYSETUP_TRUE@am__append_1 = verity-compat-test -@REENCRYPT_TRUE@am__append_2 = reencryption-compat-test reencryption-compat-test2 luks2-reencryption-test +@REENCRYPT_TRUE@am__append_2 = reencryption-compat-test reencryption-compat-test2 luks2-reencryption-test luks2-reencryption-mangle-test @INTEGRITYSETUP_TRUE@am__append_3 = integrity-compat-test check_PROGRAMS = api-test$(EXEEXT) api-test-2$(EXEEXT) differ$(EXEEXT) \ vectors-test$(EXEEXT) unit-utils-io$(EXEEXT) @@ -119,7 +119,9 @@ CONFIG_CLEAN_VPATH_FILES = am_api_test_OBJECTS = api_test-api-test.$(OBJEXT) \ api_test-test_utils.$(OBJEXT) api_test_OBJECTS = $(am_api_test_OBJECTS) -api_test_DEPENDENCIES = ../libcryptsetup.la +am__DEPENDENCIES_1 = +am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +api_test_DEPENDENCIES = $(am__DEPENDENCIES_2) ../libcryptsetup.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -130,13 +132,14 @@ api_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ am_api_test_2_OBJECTS = api_test_2-api-test-2.$(OBJEXT) \ api_test_2-test_utils.$(OBJEXT) api_test_2_OBJECTS = $(am_api_test_2_OBJECTS) -api_test_2_DEPENDENCIES = ../libcryptsetup.la +api_test_2_DEPENDENCIES = $(am__DEPENDENCIES_2) ../libcryptsetup.la api_test_2_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(api_test_2_CFLAGS) \ $(CFLAGS) $(api_test_2_LDFLAGS) $(LDFLAGS) -o $@ am_differ_OBJECTS = differ-differ.$(OBJEXT) differ_OBJECTS = $(am_differ_OBJECTS) differ_LDADD = $(LDADD) +differ_DEPENDENCIES = $(am__DEPENDENCIES_1) differ_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(differ_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -220,8 +223,6 @@ am__define_uniq_tagged_files = \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no @@ -264,6 +265,8 @@ CPPFLAGS = @CPPFLAGS@ CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPTO_STATIC_LIBS = @CRYPTO_STATIC_LIBS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_LUKS2_LOCK_DIR_PERMS = @DEFAULT_LUKS2_LOCK_DIR_PERMS@ DEFAULT_LUKS2_LOCK_PATH = @DEFAULT_LUKS2_LOCK_PATH@ @@ -281,6 +284,7 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ @@ -441,6 +445,7 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ reencryption-compat-test \ reencryption-compat-test2 \ luks2-reencryption-test \ + luks2-reencryption-mangle-test \ tcrypt-compat-test \ luks1-compat-test \ luks2-validation-test generators \ @@ -457,6 +462,7 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ bitlk-images.tar.xz CLEANFILES = cryptsetup-tst* valglog* *-fail-*.log +LDADD = $(LTLIBINTL) differ_SOURCES = differ.c differ_CFLAGS = $(AM_CFLAGS) -Wall -O2 api_test_SOURCES = api-test.c api_test.h test_utils.c @@ -834,7 +840,6 @@ check-TESTS: $(TESTS) echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am @@ -1016,6 +1021,7 @@ compatimage.img: @xz -k -d compatimage.img.xz valgrind-check: api-test api-test-2 differ + @VALG=1 ./compat-test @VALG=1 ./compat-test2 @VALG=1 ./luks2-validation-test @VALG=1 ./verity-compat-test @@ -1023,7 +1029,9 @@ valgrind-check: api-test api-test-2 differ @INFOSTRING="api-test-000" ./valg-api.sh ./api-test @INFOSTRING="api-test-002" ./valg-api.sh ./api-test-2 @VALG=1 ./luks2-reencryption-test - @VALG=1 ./compat-test + @VALG=1 ./luks2-reencryption-mangle-test + @VALG=1 ./bitlk-compat-test + @grep -l "ERROR SUMMARY: [^0] errors" valglog* || echo "No leaks detected." .PHONY: valgrind-check diff --git a/tests/align-test2 b/tests/align-test2 index f1b387e..75d9cf4 100755 --- a/tests/align-test2 +++ b/tests/align-test2 @@ -100,7 +100,7 @@ format() # expected [forced] [encryption_sector_size] if [ -z "$2" ] ; then echo -n "Formatting using topology info$_smsg..." - echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --sector-size $_sec_size >/dev/null || fail + echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --sector-size $_sec_size >/dev/null 2>&1 || fail else echo -n "Formatting using forced sector alignment $2$_smsg..." echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --align-payload=$2 --sector-size $_sec_size >/dev/null || fail @@ -222,6 +222,31 @@ format $EXPCT $EXPCT s2048 format $EXPCT $EXPCT s4096 cleanup +echo "# Create drive with misaligned opt-io to page-size (some bad USB enclosures)" +echo "# (logical_block_size=512, physical_block_size=512, alignment_offset=0, opt-io=33553920)" +add_device dev_size_mb=32 sector_size=512 num_tgts=1 opt_blks=65535 +format $EXPCT +format $EXPCT s1024 +format $EXPCT s2048 +format $EXPCT s4096 +format $EXPCT 1 +format $EXPCT 1 s1024 +format $EXPCT 1 s2048 +format $EXPCT 1 s4096 +format $EXPCT 8 +format $EXPCT 8 s1024 +format $EXPCT 8 s2048 +format $EXPCT 8 s4096 +format $((EXPCT+1)) $((EXPCT+1)) +format_fail $((EXPCT+1)) $((EXPCT+1)) s1024 +format_fail $((EXPCT+1)) $((EXPCT+1)) s2048 +format_fail $((EXPCT+1)) $((EXPCT+1)) s4096 +format $EXPCT $EXPCT +format $EXPCT $EXPCT s1024 +format $EXPCT $EXPCT s2048 +format $EXPCT $EXPCT s4096 +cleanup + echo "# Create desktop-class 4K drive w/ 1-sector shift (original bug report)" echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=512)" add_device dev_size_mb=32 sector_size=512 physblk_exp=3 lowest_aligned=1 num_tgts=1 diff --git a/tests/api-test-2.c b/tests/api-test-2.c index 8386c08..c0bfc9a 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-2020 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2020 Milan Broz - * Copyright (C) 2016-2020 Ondrej Kozina + * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2021 Milan Broz + * Copyright (C) 2016-2021 Ondrej Kozina * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -212,9 +212,9 @@ static int get_luks2_offsets(int metadata_device, if (r_payload_offset) { if (metadata_device) - *r_payload_offset = DIV_ROUND_UP_MODULO(default_header_size * 512, (alignpayload_sec ?: 1) * sector_size); - else *r_payload_offset = alignpayload_sec * sector_size; + else + *r_payload_offset = DIV_ROUND_UP_MODULO(default_header_size * 512, (alignpayload_sec ?: 1) * sector_size); *r_payload_offset /= sector_size; } @@ -493,7 +493,7 @@ static void UseLuks2Device(void) OK_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0)); OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0)); FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0), "already open"); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); FAIL_(crypt_deactivate(cd, CDEVICE_1), "no such device"); @@ -525,7 +525,7 @@ static void UseLuks2Device(void) OK_(crypt_volume_key_verify(cd, key, key_size)); OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); key[1] = ~key[1]; @@ -541,6 +541,13 @@ static void SuspendDevice(void) char key[128]; size_t key_size; int suspend_status; + uint64_t r_payload_offset; + const struct crypt_pbkdf_type fast_pbkdf = { + .type = "pbkdf2", + .hash = "sha256", + .iterations = 1000, + .flags = CRYPT_PBKDF_NO_BENCHMARK + }; OK_(crypt_init(&cd, DEVICE_1)); OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); @@ -602,11 +609,31 @@ static void SuspendDevice(void) FAIL_(crypt_resume_by_volume_key(cd, CDEVICE_1, key, key_size), "wrong key"); OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, KEY1, strlen(KEY1))); OK_(crypt_resume_by_volume_key(cd, CDEVICE_1, key, key_size)); + OK_(crypt_deactivate(cd, CDEVICE_1)); + CRYPT_FREE(cd); + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); + OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1)); + + /* Resume device with cipher_null */ + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); + OK_(crypt_format(cd, CRYPT_LUKS2, "cipher_null", "ecb", NULL, key, key_size, NULL)); + EQ_(0, crypt_keyslot_add_by_volume_key(cd, 0, key, key_size, PASSPHRASE, strlen(PASSPHRASE))); + OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); + OK_(crypt_suspend(cd, CDEVICE_1)); + OK_(crypt_resume_by_volume_key(cd, CDEVICE_1, key, key_size)); + OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); + EQ_(0, cad.flags & CRYPT_ACTIVATE_SUSPENDED); + OK_(crypt_suspend(cd, CDEVICE_1)); + OK_(crypt_resume_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE))); + OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); + EQ_(0, cad.flags & CRYPT_ACTIVATE_SUSPENDED); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); _remove_keyfiles(); + _cleanup_dmdevices(); } static void AddDeviceLuks2(void) @@ -645,7 +672,7 @@ static void AddDeviceLuks2(void) crypt_decode_key(key3, mk_hex2, key_size); // init test devices - OK_(get_luks2_offsets(1, 0, 0, &r_header_size, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, &r_header_size, &r_payload_offset)); OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); OK_(create_dmdevice_over_loop(H_DEVICE_WRONG, r_header_size - 1)); @@ -700,7 +727,7 @@ static void AddDeviceLuks2(void) * test limit values for backing device size */ params.data_alignment = OFFSET_4M; - OK_(get_luks2_offsets(1, params.data_alignment, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, params.data_alignment, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_0S, r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1)); OK_(create_dmdevice_over_loop(L_DEVICE_WRONG, r_payload_offset - 1)); @@ -721,7 +748,7 @@ static void AddDeviceLuks2(void) OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); EQ_(crypt_get_data_offset(cd), r_payload_offset); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(t_device_size(DMDIR CDEVICE_1, &r_size_1)); EQ_(r_size_1, SECTOR_SIZE); OK_(crypt_deactivate(cd, CDEVICE_1)); @@ -761,11 +788,11 @@ static void AddDeviceLuks2(void) CRYPT_FREE(cd); OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DMDIR H_DEVICE)); FAIL_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms), "Context is already formatted"); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); CRYPT_FREE(cd); // check active status without header OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, NULL)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); NULL_(crypt_get_type(cd)); OK_(strcmp(cipher, crypt_get_cipher(cd))); OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd))); @@ -788,7 +815,7 @@ static void AddDeviceLuks2(void) CRYPT_FREE(cd); // there we've got uuid mismatch OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DMDIR H_DEVICE)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); NULL_(crypt_get_type(cd)); FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "Device is active"); FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0), "Device is active"); @@ -804,14 +831,14 @@ static void AddDeviceLuks2(void) // even with no keyslots defined it can be activated by volume key OK_(crypt_volume_key_verify(cd, key, key_size)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_2)); // now with keyslot EQ_(7, crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase))); EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 7)); EQ_(7, crypt_activate_by_passphrase(cd, CDEVICE_2, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0)); - EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_2)); crypt_set_iteration_time(cd, 1); @@ -969,7 +996,7 @@ static void Luks2MetadataSize(void) crypt_decode_key(key, mk_hex, key_size); // init test devices - OK_(get_luks2_offsets(1, 0, 0, &r_header_size, NULL)); + OK_(get_luks2_offsets(0, 0, 0, &r_header_size, NULL)); OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); OK_(create_dmdevice_over_loop(H_DEVICE_WRONG, r_header_wrong_size)); /* 7 MiBs only */ //default metadata sizes @@ -1083,7 +1110,7 @@ static void UseTempVolumes(void) FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0), "not yet formatted"); OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "cbc-essiv:sha256", NULL, NULL, 16, NULL)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0)); - EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); CRYPT_FREE(cd); OK_(crypt_init_by_name(&cd, CDEVICE_2)); @@ -1160,7 +1187,7 @@ static void Luks2HeaderRestore(void) crypt_decode_key(key, mk_hex, key_size); - OK_(get_luks2_offsets(1, params.data_alignment, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, params.data_alignment, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 5000)); // do not restore header over plain device @@ -1169,7 +1196,7 @@ static void Luks2HeaderRestore(void) OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); FAIL_(crypt_header_restore(cd, CRYPT_PLAIN, NO_REQS_LUKS2_HEADER), "Cannot restore header to PLAIN type device"); FAIL_(crypt_header_restore(cd, CRYPT_LUKS2, NO_REQS_LUKS2_HEADER), "Cannot restore header over PLAIN type device"); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1265,7 +1292,7 @@ static void Luks2HeaderLoad(void) // hardcoded values for existing image IMAGE1 img_size = 8192; // prepare test env - OK_(get_luks2_offsets(1, 0, 0, &r_header_size, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, &r_header_size, &r_payload_offset)); // external header device OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); // prepared header on a device too small to contain header and payload @@ -1290,7 +1317,7 @@ static void Luks2HeaderLoad(void) OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(!crypt_get_metadata_device_name(cd)); EQ_(strcmp(DMDIR H_DEVICE, crypt_get_metadata_device_name(cd)), 0); OK_(crypt_deactivate(cd, CDEVICE_1)); @@ -1394,7 +1421,7 @@ static void Luks2HeaderBackup(void) crypt_decode_key(key, mk_hex, key_size); - OK_(get_luks2_offsets(0, params.data_alignment, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(1, params.data_alignment, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1)); // create LUKS device and backup the header @@ -1412,7 +1439,7 @@ static void Luks2HeaderBackup(void) OK_(crypt_header_restore(cd, CRYPT_LUKS2, BACKUP_FILE)); OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1421,7 +1448,7 @@ static void Luks2HeaderBackup(void) OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1429,7 +1456,7 @@ static void Luks2HeaderBackup(void) OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase), 0), 7); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1441,7 +1468,7 @@ static void Luks2HeaderBackup(void) OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1449,7 +1476,7 @@ static void Luks2HeaderBackup(void) OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase), 0), 7); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1488,8 +1515,8 @@ static void ResizeDeviceLuks2(void) crypt_decode_key(key, mk_hex, key_size); // prepare env - OK_(get_luks2_offsets(1, params.data_alignment, 0, NULL, &r_payload_offset)); - OK_(get_luks2_offsets(1, 0, 0, &r_header_size, NULL)); + OK_(get_luks2_offsets(0, params.data_alignment, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, &r_header_size, NULL)); OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1000)); OK_(create_dmdevice_over_loop(L_DEVICE_0S, 1000)); @@ -1513,7 +1540,7 @@ static void ResizeDeviceLuks2(void) FAIL_(crypt_resize(cd, CDEVICE_1, 1001), "Device too small"); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) EQ_(1000, r_size >> SECTOR_SHIFT); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1533,7 +1560,7 @@ static void ResizeDeviceLuks2(void) FAIL_(crypt_resize(cd, CDEVICE_1, 1001), "Device too small"); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) EQ_(1000, r_size >> SECTOR_SHIFT); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1644,7 +1671,7 @@ static void TokenActivationByKeyring(void) kid = add_key("user", KEY_DESC_TEST0, PASSPHRASE, strlen(PASSPHRASE), KEY_SPEC_THREAD_KEYRING); NOTFAIL_(kid, "Test or kernel keyring are broken."); - OK_(get_luks2_offsets(1, 0, 0, NULL, &r_payload_offset)); + 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 @@ -1803,6 +1830,7 @@ static void Tokens(void) "\"key_description\":" y ", \"some_field\":\"some_value\"}" + int ks; const char *dummy; const char *cipher = "aes"; const char *cipher_mode = "xts-plain64"; @@ -1835,7 +1863,7 @@ static void Tokens(void) FAIL_(crypt_token_register(&th_reserved), "luks2- is reserved prefix"); - OK_(get_luks2_offsets(1, 0, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1)); // basic token API tests @@ -1947,6 +1975,13 @@ static void Tokens(void) EQ_(crypt_token_is_assigned(cd, -1, -1), -EINVAL); EQ_(crypt_token_is_assigned(cd, 32, 32), -EINVAL); + // test crypt_keyslot_change_by_passphrase does not erase token references + EQ_(crypt_keyslot_change_by_passphrase(cd, 1, 5, PASSPHRASE1, strlen(PASSPHRASE1), PASSPHRASE1, strlen(PASSPHRASE1)), 5); + OK_(crypt_token_is_assigned(cd, 10, 5)); + ks = crypt_keyslot_change_by_passphrase(cd, 5, CRYPT_ANY_SLOT, PASSPHRASE1, strlen(PASSPHRASE1), PASSPHRASE1, strlen(PASSPHRASE1)); + NOTFAIL_(ks, "Failed to change keyslot passphrase."); + OK_(crypt_token_is_assigned(cd, 10, ks)); + CRYPT_FREE(cd); _cleanup_dmdevices(); @@ -2104,7 +2139,7 @@ static void LuksConvert(void) CRYPT_FREE(cd); // should be enough for both luks1 and luks2 devices with all vk lengths - OK_(get_luks2_offsets(1, 0, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1)); // do not allow conversion for legacy luks1 device (non-aligned keyslot offset) @@ -2506,7 +2541,7 @@ static void Pbkdf(void) .size = 0 }; struct crypt_params_luks1 luks1 = { - .hash = "whirlpool", // test non-standard hash + .hash = "sha512", // test non-standard hash .data_alignment = 2048, }; @@ -2516,7 +2551,7 @@ static void Pbkdf(void) if (_fips_mode) return; - OK_(get_luks2_offsets(1, 0, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1)); NULL_(crypt_get_pbkdf_type_params(NULL)); @@ -2761,7 +2796,7 @@ static void Luks2KeyslotAdd(void) pbkdf.iterations = 1000; } - OK_(get_luks2_offsets(1, 0, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1)); /* test crypt_keyslot_add_by_key */ @@ -2876,6 +2911,12 @@ static void Luks2KeyslotParams(void) const char *mk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; size_t key_size_ret, key_size = strlen(mk_hex) / 2, keyslot_key_size = 16; uint64_t r_payload_offset; + const struct crypt_pbkdf_type fast_pbkdf = { + .type = "pbkdf2", + .hash = "sha256", + .iterations = 1000, + .flags = CRYPT_PBKDF_NO_BENCHMARK + }; crypt_decode_key(key, mk_hex, key_size); crypt_decode_key(key2, mk_hex2, key_size); @@ -2883,13 +2924,13 @@ static void Luks2KeyslotParams(void) OK_(prepare_keyfile(KEYFILE1, PASSPHRASE, strlen(PASSPHRASE))); OK_(prepare_keyfile(KEYFILE2, PASSPHRASE1, strlen(PASSPHRASE1))); - OK_(get_luks2_offsets(1, 0, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1)); EQ_(key_size, 2 * keyslot_key_size); /* test crypt_keyslot_add_by_key */ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); - crypt_set_iteration_time(cd, 1); + OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, NULL)); NULL_(crypt_keyslot_get_encryption(cd, 0, &key_size_ret)); OK_(strcmp(crypt_keyslot_get_encryption(cd, CRYPT_ANY_SLOT, &key_size_ret), cipher_spec)); @@ -2948,7 +2989,7 @@ static void Luks2KeyslotParams(void) OK_(strcmp(crypt_keyslot_get_encryption(cd, 7, &key_size_ret), cipher_keyslot)); EQ_(key_size_ret, keyslot_key_size); - crypt_set_iteration_time(cd, 1); + OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); EQ_(8, crypt_keyslot_change_by_passphrase(cd, 1, 8, PASSPHRASE1, strlen(PASSPHRASE1), PASSPHRASE, strlen(PASSPHRASE))); OK_(strcmp(crypt_keyslot_get_encryption(cd, 8, &key_size_ret), cipher_spec)); EQ_(key_size_ret, key_size); @@ -2977,7 +3018,7 @@ static void Luks2KeyslotParams(void) /* LUKS1 compatible calls */ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); - crypt_set_iteration_time(cd, 1); + OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, NULL)); NULL_(crypt_keyslot_get_encryption(cd, 0, &key_size_ret)); OK_(strcmp(crypt_keyslot_get_encryption(cd, CRYPT_ANY_SLOT, &key_size_ret), cipher_spec)); @@ -2987,6 +3028,18 @@ static void Luks2KeyslotParams(void) EQ_(key_size_ret, key_size); CRYPT_FREE(cd); + /* LUKS2 cipher null checks */ + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); + OK_(crypt_format(cd, CRYPT_LUKS2, "cipher_null", "ecb", NULL, key, key_size, NULL)); + FAIL_(crypt_keyslot_set_encryption(cd, "null", 32), "cipher null is not allowed"); + FAIL_(crypt_keyslot_set_encryption(cd, "cipher_null", 32), "cipher null is not allowed"); + FAIL_(crypt_keyslot_set_encryption(cd, "cipher_null-ecb", 32), "cipher null is not allowed"); + EQ_(0, crypt_keyslot_add_by_volume_key(cd, 0, key, key_size, PASSPHRASE, strlen(PASSPHRASE))); + NOTNULL_(crypt_keyslot_get_encryption(cd, 0, &key_size_ret)); + NULL_(strstr(crypt_keyslot_get_encryption(cd, 0, &key_size_ret), "null")); + CRYPT_FREE(cd); + _cleanup_dmdevices(); _remove_keyfiles(); } @@ -3011,7 +3064,7 @@ static void Luks2ActivateByKeyring(void) kid1 = add_key("user", KEY_DESC_TEST1, PASSPHRASE1, strlen(PASSPHRASE1), KEY_SPEC_THREAD_KEYRING); NOTFAIL_(kid1, "Test or kernel keyring are broken."); - OK_(get_luks2_offsets(1, 0, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1)); // prepare the device @@ -3029,7 +3082,7 @@ static void Luks2ActivateByKeyring(void) OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); EQ_(crypt_activate_by_keyring(cd, NULL, KEY_DESC_TEST0, 0, 0), 0); EQ_(crypt_activate_by_keyring(cd, CDEVICE_1, KEY_DESC_TEST0, 0, 0), 0); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); FAIL_(crypt_activate_by_keyring(cd, CDEVICE_1, KEY_DESC_TEST0, 0, 0), "already open"); OK_(crypt_deactivate(cd, CDEVICE_1)); EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE); @@ -3037,7 +3090,7 @@ static void Luks2ActivateByKeyring(void) EQ_(crypt_activate_by_keyring(cd, NULL, KEY_DESC_TEST1, 2, 0), 2); FAIL_(crypt_activate_by_keyring(cd, CDEVICE_1, KEY_DESC_TEST1, 1, 0), "Keyslot not assigned to volume"); EQ_(crypt_activate_by_keyring(cd, CDEVICE_1, KEY_DESC_TEST1, 2, 0), 2); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); EQ_(crypt_activate_by_keyring(cd, CDEVICE_1, KEY_DESC_TEST1, CRYPT_ANY_SLOT, 0), 2); OK_(crypt_deactivate(cd, CDEVICE_1)); @@ -3296,7 +3349,7 @@ static void Luks2Requirements(void) OK_(crypt_activate_by_token(cd, NULL, 1, NULL, CRYPT_ACTIVATE_KEYRING_KEY)); } #endif - OK_(get_luks2_offsets(1, 8192, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 8192, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 2)); //OK_(_system("dd if=" NO_REQS_LUKS2_HEADER " of=" NO_REQS_LUKS2_HEADER " bs=4096 2>/dev/null", 1)); OK_(_system("dd if=" NO_REQS_LUKS2_HEADER " of=" DMDIR L_DEVICE_OK " bs=1M count=4 oflag=direct 2>/dev/null", 1)); @@ -3367,7 +3420,7 @@ static void Luks2Requirements(void) /* crypt_resize (restricted) */ FAIL_((r = crypt_resize(cd, CDEVICE_1, 1)), "Unmet requirements detected"); EQ_(r, -ETXTBSY); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); /* crypt_get_active_device (unrestricted) */ OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); @@ -3415,7 +3468,7 @@ static void Luks2Integrity(void) EQ_(crypt_keyslot_add_by_volume_key(cd, 7, NULL, key_size, passphrase, strlen(passphrase)), 7); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_2, 7, passphrase, strlen(passphrase) ,0), 7); - EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); CRYPT_FREE(cd); OK_(crypt_init_by_name_and_header(&cd, CDEVICE_2, NULL)); @@ -3477,7 +3530,7 @@ static void Luks2Refresh(void) crypt_decode_key(key, mk_hex, key_size); crypt_decode_key(key1, mk_hex2, key_size); - OK_(get_luks2_offsets(1, 0, 0, NULL, &r_payload_offset)); + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1000)); OK_(create_dmdevice_over_loop(L_DEVICE_WRONG, r_payload_offset + 5000)); OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1)); @@ -3639,6 +3692,7 @@ static void Luks2Flags(void) CRYPT_FREE(cd); } +#if KERNEL_KEYRING && USE_LUKS2_REENCRYPTION static int test_progress(uint64_t size, uint64_t offset, void *usrptr) { while (--test_progress_steps) @@ -3649,7 +3703,6 @@ static int test_progress(uint64_t size, uint64_t offset, void *usrptr) static void Luks2Reencryption(void) { /* reencryption currently depends on kernel keyring support */ -#if KERNEL_KEYRING /* NOTES: * - reencryption requires luks2 parameters. can we avoid it? */ @@ -3675,6 +3728,12 @@ static void Luks2Reencryption(void) .luks2 = ¶ms2, }; + const char *mk_hex = "bb21babe733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(mk_hex) / 2; + char key[128]; + + crypt_decode_key(key, mk_hex, key_size); + /* reencryption currently depends on kernel keyring support in dm-crypt */ if (!t_dm_crypt_keyring_support()) return; @@ -3687,7 +3746,7 @@ static void Luks2Reencryption(void) pbkdf.iterations = 1000; } - OK_(get_luks2_offsets(0, 0, 0, &r_header_size, NULL)); + OK_(get_luks2_offsets(1, 0, 0, &r_header_size, NULL)); OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_header_size + 16)); @@ -4318,8 +4377,35 @@ static void Luks2Reencryption(void) CRYPT_FREE(cd); _cleanup_dmdevices(); -#endif + OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_header_size + 16)); + + rparams.mode = CRYPT_REENCRYPT_REENCRYPT; + rparams.direction = CRYPT_REENCRYPT_FORWARD; + rparams.resilience = "none"; + rparams.hash = NULL; + rparams.data_shift = 0; + rparams.max_hotzone_size = 0; + rparams.device_size = 0; + rparams.luks2 = ¶ms2; + rparams.flags = 0; + + /* Test support for specific key reencryption */ + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(crypt_set_pbkdf_type(cd, &pbkdf)); + OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "cbc-essiv:sha256", NULL, NULL, 32, ¶ms2)); + EQ_(crypt_keyslot_add_by_volume_key(cd, 3, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 3); + EQ_(crypt_keyslot_add_by_key(cd, 9, key, key_size, PASSPHRASE, strlen(PASSPHRASE), CRYPT_VOLUME_KEY_NO_SEGMENT), 9); + EQ_(crypt_keyslot_add_by_key(cd, 10, key, key_size, PASSPHRASE, strlen(PASSPHRASE), CRYPT_VOLUME_KEY_NO_SEGMENT | CRYPT_VOLUME_KEY_DIGEST_REUSE ), 10); + OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 3, 9, "aes", "xts-plain64", &rparams)); + OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0)); + OK_(crypt_keyslot_destroy(cd, 9)); + OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0)); + crypt_free(cd); + + _cleanup_dmdevices(); } +#endif static void Luks2Repair(void) { @@ -4435,7 +4521,9 @@ int main(int argc, char *argv[]) RUN_(Luks2Integrity, "LUKS2 with data integrity"); RUN_(Luks2Refresh, "Active device table refresh"); RUN_(Luks2Flags, "LUKS2 persistent flags"); +#if KERNEL_KEYRING && USE_LUKS2_REENCRYPTION RUN_(Luks2Reencryption, "LUKS2 reencryption"); +#endif 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 81501eb..85f7a93 100644 --- a/tests/api-test.c +++ b/tests/api-test.c @@ -1,9 +1,9 @@ /* * cryptsetup library API check functions * - * Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2020 Milan Broz - * Copyright (C) 2016-2020 Ondrej Kozina + * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2021 Milan Broz + * Copyright (C) 2016-2021 Ondrej Kozina * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -357,7 +357,7 @@ static void AddDevicePlain(void) OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, NULL)); FAIL_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0), "cannot verify key with plain"); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -379,7 +379,7 @@ static void AddDevicePlain(void) OK_(crypt_init(&cd, DEVICE_1)); OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1); if (t_device_size(path, &r_size) >= 0) EQ_(r_size>>SECTOR_SHIFT, 1); @@ -428,7 +428,7 @@ static void AddDevicePlain(void) crypt_init(&cd, DEVICE_1); OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); if (!t_device_size(path, &r_size)) EQ_((r_size >> SECTOR_SHIFT),params.size); OK_(crypt_deactivate(cd,CDEVICE_1)); @@ -447,7 +447,7 @@ static void AddDevicePlain(void) OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0)); // device status check - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1); fd = open(path, O_RDONLY); EQ_(crypt_status(cd, CDEVICE_1), CRYPT_BUSY); @@ -492,7 +492,7 @@ static void AddDevicePlain(void) OK_(strcmp(crypt_get_type(cd),CRYPT_PLAIN)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); // crypt_resize() OK_(crypt_resize(cd,CDEVICE_1,size>>SECTOR_SHIFT)); // same size @@ -531,7 +531,7 @@ static void AddDevicePlain(void) FAIL_(crypt_resize(cd,CDEVICE_1,params.size + 11), "new device size overlaps backing device"); // with respect to offset if (!t_device_size(path,&r_size)) EQ_(r_size>>SECTOR_SHIFT, params.size + 10); - EQ_(crypt_status(cd,CDEVICE_1),CRYPT_ACTIVE); + GE_(crypt_status(cd,CDEVICE_1),CRYPT_ACTIVE); fd = open(path, O_RDONLY); NOTFAIL_(fd, "Bad loop device."); close(fd); @@ -555,9 +555,9 @@ static void AddDevicePlain(void) // suspend/resume tests FAIL_(crypt_suspend(cd,CDEVICE_1),"cannot suspend plain device"); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); FAIL_(crypt_resume_by_passphrase(cd,CDEVICE_1,CRYPT_ANY_SLOT,passphrase, strlen(passphrase)),"cannot resume plain device"); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); // retrieve volume key check memset(key2, 0, key_size); @@ -579,7 +579,7 @@ static void AddDevicePlain(void) OK_(prepare_keyfile(KEYFILE2, KEY2, strlen(KEY2))); FAIL_(crypt_activate_by_keyfile(cd, NULL, CRYPT_ANY_SLOT, KEYFILE1, 0, 0), "cannot verify key with plain"); EQ_(0, crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); FAIL_(crypt_activate_by_keyfile_offset(cd, NULL, CRYPT_ANY_SLOT, KEYFILE1, 0, strlen(KEY1) + 1, 0), "cannot seek"); FAIL_(crypt_activate_by_keyfile_device_offset(cd, NULL, CRYPT_ANY_SLOT, KEYFILE1, 0, strlen(KEY1) + 1, 0), "cannot seek"); @@ -631,7 +631,7 @@ static void CallbacksTest(void) EQ_(new_messages, 0); OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); EQ_(new_messages, 0); FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0), "already exists"); EQ_(new_messages, 1); @@ -651,7 +651,7 @@ static void UseLuksDevice(void) OK_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0)); OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0)); FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0), "already open"); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); FAIL_(crypt_deactivate(cd, CDEVICE_1), "no such device"); @@ -666,7 +666,7 @@ static void UseLuksDevice(void) OK_(crypt_volume_key_verify(cd, key, key_size)); OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); key[1] = ~key[1]; @@ -682,6 +682,13 @@ static void SuspendDevice(void) char key[128]; size_t key_size; int suspend_status; + uint64_t r_payload_offset; + const struct crypt_pbkdf_type fast_pbkdf = { + .type = "pbkdf2", + .hash = "sha256", + .iterations = 1000, + .flags = CRYPT_PBKDF_NO_BENCHMARK + }; OK_(crypt_init(&cd, DEVICE_1)); OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); @@ -742,11 +749,31 @@ static void SuspendDevice(void) FAIL_(crypt_resume_by_volume_key(cd, CDEVICE_1, key, key_size), "wrong key"); OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, KEY1, strlen(KEY1))); OK_(crypt_resume_by_volume_key(cd, CDEVICE_1, key, key_size)); + OK_(crypt_deactivate(cd, CDEVICE_1)); + CRYPT_FREE(cd); + OK_(get_luks_offsets(0, key_size, 1024*2, 0, NULL, &r_payload_offset)); + OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1)); + + /* Resume device with cipher_null */ + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); + OK_(crypt_format(cd, CRYPT_LUKS1, "cipher_null", "ecb", NULL, key, key_size, NULL)); + EQ_(0, crypt_keyslot_add_by_volume_key(cd, 0, key, key_size, "", 0)); + OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); + OK_(crypt_suspend(cd, CDEVICE_1)); + OK_(crypt_resume_by_volume_key(cd, CDEVICE_1, key, key_size)); + OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); + EQ_(0, cad.flags & CRYPT_ACTIVATE_SUSPENDED); + OK_(crypt_suspend(cd, CDEVICE_1)); + OK_(crypt_resume_by_passphrase(cd, CDEVICE_1, 0, "", 0)); + OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); + EQ_(0, cad.flags & CRYPT_ACTIVATE_SUSPENDED); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); _remove_keyfiles(); + _cleanup_dmdevices(); } static void AddDeviceLuks(void) @@ -848,7 +875,7 @@ static void AddDeviceLuks(void) OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); EQ_(crypt_get_data_offset(cd), params.data_alignment); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(t_device_size(DMDIR CDEVICE_1, &r_size_1)); EQ_(r_size_1, SECTOR_SIZE); OK_(crypt_deactivate(cd, CDEVICE_1)); @@ -875,11 +902,11 @@ static void AddDeviceLuks(void) CRYPT_FREE(cd); OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DMDIR H_DEVICE)); FAIL_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms), "Context is already formatted"); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); CRYPT_FREE(cd); // check active status without header OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, NULL)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); NULL_(crypt_get_type(cd)); OK_(strcmp(cipher, crypt_get_cipher(cd))); OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd))); @@ -902,7 +929,7 @@ static void AddDeviceLuks(void) CRYPT_FREE(cd); // there we've got uuid mismatch OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DMDIR H_DEVICE)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); NULL_(crypt_get_type(cd)); FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "Device is active"); FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0), "Device is active"); @@ -918,14 +945,14 @@ static void AddDeviceLuks(void) // even with no keyslots defined it can be activated by volume key OK_(crypt_volume_key_verify(cd, key, key_size)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_2)); // now with keyslot EQ_(7, crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase))); EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 7)); EQ_(7, crypt_activate_by_passphrase(cd, CDEVICE_2, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0)); - EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_2)); crypt_set_iteration_time(cd, 1); @@ -1027,7 +1054,7 @@ static void UseTempVolumes(void) FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0), "not yet formatted"); OK_(crypt_format(cd, CRYPT_LUKS1, "aes", "cbc-essiv:sha256", NULL, NULL, 16, NULL)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0)); - EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); CRYPT_FREE(cd); OK_(crypt_init_by_name(&cd, CDEVICE_2)); @@ -1069,7 +1096,7 @@ static void UseTempVolumes(void) FAIL_(crypt_volume_key_verify(cd, "xxx", 3), "cannot verify key with plain"); FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, "xxx", 3, 0), "wrong key length"); OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, "volumekeyvolumek", 16, 0)); - EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_2)); CRYPT_FREE(cd); } @@ -1105,7 +1132,7 @@ static void LuksHeaderRestore(void) OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); FAIL_(crypt_header_restore(cd, CRYPT_PLAIN, VALID_HEADER), "Cannot restore header to PLAIN type device"); FAIL_(crypt_header_restore(cd, CRYPT_LUKS1, VALID_HEADER), "Cannot restore header over PLAIN type device"); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1211,7 +1238,7 @@ static void LuksHeaderLoad(void) OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(!crypt_get_metadata_device_name(cd)); EQ_(strcmp(DMDIR H_DEVICE, crypt_get_metadata_device_name(cd)), 0); OK_(crypt_deactivate(cd, CDEVICE_1)); @@ -1313,7 +1340,7 @@ static void LuksHeaderBackup(void) OK_(crypt_header_restore(cd, CRYPT_LUKS1, BACKUP_FILE)); OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1322,7 +1349,7 @@ static void LuksHeaderBackup(void) OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1330,7 +1357,7 @@ static void LuksHeaderBackup(void) OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase), 0), 7); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1342,7 +1369,7 @@ static void LuksHeaderBackup(void) OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1350,7 +1377,7 @@ static void LuksHeaderBackup(void) OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); OK_(crypt_set_data_device(cd, DMDIR L_DEVICE_OK)); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase), 0), 7); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1395,7 +1422,7 @@ static void ResizeDeviceLuks(void) FAIL_(crypt_resize(cd, CDEVICE_1, 1001), "Device too small"); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) EQ_(1000, r_size >> SECTOR_SHIFT); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1415,7 +1442,7 @@ static void ResizeDeviceLuks(void) FAIL_(crypt_resize(cd, CDEVICE_1, 1001), "Device too small"); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) EQ_(1000, r_size >> SECTOR_SHIFT); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1750,7 +1777,7 @@ static void TcryptTest(void) CRYPT_FREE(cd); OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, NULL)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, NULL, 0), "Need crypt_load"); @@ -1837,7 +1864,7 @@ static void IntegrityTest(void) params.tag_size = 4; OK_(crypt_load(cd, CRYPT_INTEGRITY, ¶ms)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, NULL, 0, 0)); - EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); CRYPT_FREE(cd); memset(&ip, 0, sizeof(ip)); diff --git a/tests/api_test.h b/tests/api_test.h index d1d9b00..91b47b7 100644 --- a/tests/api_test.h +++ b/tests/api_test.h @@ -1,9 +1,9 @@ /* * cryptsetup library API check functions * - * Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2020 Milan Broz - * Copyright (C) 2016-2020 Ondrej Kozina + * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2021 Milan Broz + * Copyright (C) 2016-2021 Ondrej Kozina * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -61,6 +61,7 @@ void check_ok(int status, int line, const char *func); void check_ok_return(int status, int line, const char *func); void check_ko(int status, int line, const char *func); void check_equal(int line, const char *func, int64_t x, int64_t y); +void check_ge_equal(int line, const char *func, int64_t x, int64_t y); void check_null(int line, const char *func, const void *x); void check_notnull(int line, const char *func, const void *x); void xlog(const char *msg, const char *tst, const char *func, int line, const char *txt); @@ -79,6 +80,10 @@ void xlog(const char *msg, const char *tst, const char *func, int line, const ch xlog("(equal) ", #x " == " #y, __FUNCTION__, __LINE__, NULL); \ if (_x != _y) check_equal(__LINE__, __FUNCTION__, _x, _y); \ } while(0) +#define GE_(x, y) do { int64_t _x = (x), _y = (y); \ + xlog("(g_equal)", #x " == " #y, __FUNCTION__, __LINE__, NULL); \ + if (_x < _y) check_ge_equal(__LINE__, __FUNCTION__, _x, _y); \ + } while(0) #define NULL_(x) do { xlog("(null) ", #x, __FUNCTION__, __LINE__, NULL); \ check_null(__LINE__, __FUNCTION__, (x)); \ } while(0) diff --git a/tests/bitlk-compat-test b/tests/bitlk-compat-test index 38efd0b..c8210b5 100755 --- a/tests/bitlk-compat-test +++ b/tests/bitlk-compat-test @@ -7,6 +7,9 @@ CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup TST_DIR=bitlk-images MAP=bitlktst +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + [ -z "$srcdir" ] && srcdir="." function remove_mapping() @@ -59,6 +62,10 @@ function check_dump() # smart card protected VMK GUID dump_sc_vmk=$(echo "$dump" | grep "VMK protected with smart card" -B 1 | head -1 | cut -d: -f2 | tr -d "\t ") [ ! -z "$SC_VMK_GUID" -a "$dump_sc_vmk" = "$SC_VMK_GUID" ] || fail " smart card protected VMK GUID check from dump failed." + elif echo "$file" | grep -q -e "startup-key"; then + # startup key protected VMK GUID + dump_sk_vmk=$(echo "$dump" | grep "VMK protected with startup key" -B 1 | head -1 | cut -d: -f2 | tr -d "\t ") + [ ! -z "$SK_VMK_GUID" -a "$dump_sk_vmk" = "$SK_VMK_GUID" ] || fail " startup key protected VMK GUID check from dump failed." else # password protected VMK GUID dump_pw_vmk=$(echo "$dump" | grep "VMK protected with passphrase" -B 1 | head -1 | cut -d: -f2 | tr -d "\t ") @@ -71,9 +78,23 @@ function check_dump() } +function valgrind_setup() +{ + which valgrind >/dev/null 2>&1 || 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" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + export LANG=C [ ! -d $TST_DIR ] && tar xJSf $srcdir/bitlk-images.tar.xz --no-same-owner +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run + echo "HEADER CHECK" for file in $(ls $TST_DIR/bitlk-*) ; do echo -n " $file" @@ -117,4 +138,25 @@ for file in $(ls $TST_DIR/bitlk-*) ; do [ "$sha256sum" = "$SHA256SUM" ] || fail " SHA256 sum check failed." echo " [OK]" done + + # startup key test -- we need to use BEK file from the archive + if echo "$file" | grep -q -e "startup-key"; then + echo -n " $file" + bek_file=$(echo $SK_VMK_GUID.BEK | tr /a-z/ /A-Z/) + $CRYPTSETUP bitlkOpen -r $file --test-passphrase --key-file $TST_DIR/$bek_file + ret=$? + [ $ret -eq 1 ] && echo " [N/A]" && continue + $CRYPTSETUP bitlkOpen -r $file $MAP --key-file $TST_DIR/$bek_file >/dev/null 2>&1 + ret=$? + [ $ret -eq 0 ] || fail " failed to open $file ($ret)" + $CRYPTSETUP status $MAP >/dev/null || fail + $CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail + uuid=$(lsblk -n -o UUID /dev/mapper/$MAP) + sha256sum=$(sha256sum /dev/mapper/$MAP | cut -d" " -f1) + $CRYPTSETUP remove $MAP || fail + [ "$uuid" = "$UUID" ] || fail " UUID check failed." + [ "$sha256sum" = "$SHA256SUM" ] || fail " SHA256 sum check failed." + echo " [OK]" + + fi done diff --git a/tests/bitlk-images.tar.xz b/tests/bitlk-images.tar.xz Binary files differindex e3f07d7..eea33ed 100644 --- a/tests/bitlk-images.tar.xz +++ b/tests/bitlk-images.tar.xz diff --git a/tests/compat-test b/tests/compat-test index a61453e..6059880 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -3,6 +3,7 @@ PS4='$LINENO:' [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup +CRYPTSETUP_RAW=$CRYPTSETUP CRYPTSETUP_VALGRIND=../.libs/cryptsetup CRYPTSETUP_LIB_VALGRIND=../.libs @@ -189,19 +190,28 @@ function add_scsi_device() { function valgrind_setup() { + [ -n "$VALG" ] || return which valgrind >/dev/null 2>&1 || 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" + CRYPTSETUP=valgrind_run + CRYPTSETUP_RAW="./valg.sh ${CRYPTSETUP_VALGRIND}" } function valgrind_run() { - INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" + export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" + $CRYPTSETUP_RAW "$@" } -export LANG=C +function expect_run() +{ + export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" + expect "$@" +} -[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run +export LANG=C +valgrind_setup # LUKS non-root-tests if [ $(id -u) != 0 ]; then @@ -702,6 +712,12 @@ 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 $CRYPTSETUP -q luksClose $DEV_NAME || fail +echo | $CRYPTSETUP -q luksFormat -c null $FAST_PBKDF_OPT --type luks1 $LOOPDEV || fail +echo | $CRYPTSETUP -q luksOpen $LOOPDEV $DEV_NAME || fail +$CRYPTSETUP luksSuspend $DEV_NAME || fail +$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail +echo | $CRYPTSETUP luksResume $DEV_NAME || fail +$CRYPTSETUP -q luksClose $DEV_NAME || fail prepare "[27] luksOpen with specified key slot number" wipe # first, let's try passphrase option @@ -751,7 +767,7 @@ $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail $CRYPTSETUP luksSuspend $DEV_NAME --header $HEADER_IMG || fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail $CRYPTSETUP luksSuspend $DEV_NAME || fail -echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME && fail +echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail $CRYPTSETUP luksClose $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 5 _fakedev_ --header $HEADER_IMG $KEY5 || fail @@ -800,11 +816,13 @@ which expect >/dev/null 2>&1 || skip "WARNING: expect tool missing, interactive prepare "[32] Interactive password retry from terminal." new EXPECT_DEV=$(losetup $LOOPDEV | sed -e "s/.*(\(.*\))/\1/") +EXPECT_TIMEOUT=10 +[ -n "$VALG" ] && EXPECT_TIMEOUT=60 -expect - >/dev/null <<EOF +expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } -set timeout 10 -eval spawn $CRYPTSETUP luksOpen -v -T 2 $LOOPDEV $DEV_NAME +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW luksOpen -v -T 2 $LOOPDEV $DEV_NAME expect timeout abort "Enter passphrase for $EXPECT_DEV:" sleep 0.1 send "$PWD0 x\n" @@ -822,10 +840,10 @@ check_exists $CRYPTSETUP -q luksClose $DEV_NAME || fail prepare "[33] Interactive unsuccessful password retry from terminal." new -expect - >/dev/null <<EOF +expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } -set timeout 10 -eval spawn $CRYPTSETUP luksOpen -v -T 2 $LOOPDEV $DEV_NAME +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW luksOpen -v -T 2 $LOOPDEV $DEV_NAME expect timeout abort "Enter passphrase for $EXPECT_DEV:" sleep 0.1 send "$PWD0 x\n" @@ -840,10 +858,10 @@ EOF [ $? -eq 0 ] || fail "Expect script failed." prepare "[34] Interactive kill of last key slot." new -expect - >/dev/null <<EOF +expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } -set timeout 10 -eval spawn $CRYPTSETUP luksKillSlot -v $LOOPDEV 0 +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW luksKillSlot -v $LOOPDEV 0 expect timeout abort "Are you sure? (Type 'yes' in capital letters):" send "YES\n" expect timeout abort "Enter any remaining passphrase:" @@ -851,7 +869,7 @@ sleep 0.1 send "$PWD0\n" expect timeout abort "Command successful." expect timeout abort eof -eval spawn $CRYPTSETUP luksKillSlot -v $LOOPDEV 0 +eval spawn $CRYPTSETUP_RAW luksKillSlot -v $LOOPDEV 0 expect timeout abort "Keyslot 0 is not active." expect timeout abort eof exit @@ -859,10 +877,10 @@ EOF [ $? -eq 0 ] || fail "Expect script failed." prepare "[35] Interactive format of device." wipe -expect - >/dev/null <<EOF +expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } -set timeout 10 -eval spawn $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT -v $LOOPDEV +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW luksFormat --type luks1 $FAST_PBKDF_OPT -v $LOOPDEV expect timeout abort "Are you sure? (Type 'yes' in capital letters):" send "YES\n" expect timeout abort "Enter passphrase for $EXPECT_DEV:" @@ -873,7 +891,7 @@ sleep 0.1 send "$PWD0\n" expect timeout abort "Command successful." expect timeout abort eof -eval spawn $CRYPTSETUP luksOpen -v $LOOPDEV --test-passphrase +eval spawn $CRYPTSETUP_RAW luksOpen -v $LOOPDEV --test-passphrase expect timeout abort "Enter passphrase for $EXPECT_DEV:" sleep 0.1 send "$PWD0\n" @@ -884,15 +902,15 @@ EOF [ $? -eq 0 ] || fail "Expect script failed." prepare "[36] Interactive unsuccessful format of device." new -expect - >/dev/null <<EOF +expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } -set timeout 10 -eval spawn $CRYPTSETUP erase -v $LOOPDEV +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW erase -v $LOOPDEV expect timeout abort "Are you sure? (Type 'yes' in capital letters):" send "YES\n" expect timeout abort "Command successful." expect timeout abort eof -eval spawn $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT -v $LOOPDEV +eval spawn $CRYPTSETUP_RAW luksFormat --type luks1 $FAST_PBKDF_OPT -v $LOOPDEV expect timeout abort "Are you sure? (Type 'yes' in capital letters):" send "YES\n" expect timeout abort "Enter passphrase for $EXPECT_DEV:" @@ -903,7 +921,7 @@ sleep 0.1 send "$PWD0 x\n" expect timeout abort "Passphrases do not match." expect timeout abort eof -eval spawn $CRYPTSETUP luksOpen -v $LOOPDEV -T 1 --test-passphrase +eval spawn $CRYPTSETUP_RAW luksOpen -v $LOOPDEV -T 1 --test-passphrase expect timeout abort "Enter passphrase for $EXPECT_DEV:" sleep 0.1 send "$PWD0\n" @@ -914,10 +932,10 @@ EOF [ $? -eq 0 ] || fail "Expect script failed." prepare "[37] Interactive add key." new -expect - >/dev/null <<EOF +expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } -set timeout 10 -eval spawn $CRYPTSETUP luksAddKey -S 2 $FAST_PBKDF_OPT -v $LOOPDEV +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW luksAddKey -S 2 $FAST_PBKDF_OPT -v $LOOPDEV expect timeout abort "Enter any existing passphrase:" sleep 0.1 send "$PWD0\n" @@ -929,16 +947,16 @@ sleep 0.1 send "$PWD1\n" expect timeout abort "Command successful." expect timeout abort eof -eval spawn $CRYPTSETUP luksOpen $FAST_PBKDF_OPT -v $LOOPDEV --test-passphrase +eval spawn $CRYPTSETUP_RAW luksOpen $FAST_PBKDF_OPT -v $LOOPDEV --test-passphrase expect timeout abort "Enter passphrase" sleep 0.1 send "$PWD1\n" expect timeout abort "Command successful." expect timeout abort eof -eval spawn $CRYPTSETUP luksKillSlot -v $LOOPDEV 1 +eval spawn $CRYPTSETUP_RAW luksKillSlot -v $LOOPDEV 1 expect timeout abort "Keyslot 1 is not active." expect timeout abort eof -eval spawn $CRYPTSETUP luksKillSlot -v $LOOPDEV 2 +eval spawn $CRYPTSETUP_RAW luksKillSlot -v $LOOPDEV 2 expect timeout abort "Enter any remaining passphrase:" sleep 0.1 send "$PWD0\n" @@ -949,10 +967,10 @@ EOF [ $? -eq 0 ] || fail "Expect script failed." prepare "[38] Interactive change key." new -expect - >/dev/null <<EOF +expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } -set timeout 10 -eval spawn $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT -v $LOOPDEV +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW luksChangeKey $FAST_PBKDF_OPT -v $LOOPDEV expect timeout abort "Enter passphrase to be changed:" sleep 0.1 send "$PWD0\n" @@ -964,7 +982,7 @@ sleep 0.1 send "$PWD1\n" expect timeout abort "Command successful." expect timeout abort eof -eval spawn $CRYPTSETUP luksOpen -v $LOOPDEV --test-passphrase +eval spawn $CRYPTSETUP_RAW luksOpen -v $LOOPDEV --test-passphrase expect timeout abort "Enter passphrase for $EXPECT_DEV:" sleep 0.1 send "$PWD1\n" @@ -976,13 +994,13 @@ EOF prepare "[39] Interactive suspend and resume." new echo $PWD0 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail -expect - >/dev/null <<EOF +expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } -set timeout 10 -eval spawn $CRYPTSETUP luksSuspend -v $DEV_NAME +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW luksSuspend -v $DEV_NAME expect timeout abort "Command successful." expect timeout abort eof -eval spawn $CRYPTSETUP luksResume -v -T 3 $DEV_NAME +eval spawn $CRYPTSETUP_RAW luksResume -v -T 3 $DEV_NAME expect timeout abort "Enter passphrase for $EXPECT_DEV:" sleep 0.1 send "$PWD0 x\n" @@ -996,7 +1014,7 @@ sleep 0.1 send "$PWD0 y\n" expect timeout abort "No key available with this passphrase." expect timeout abort eof -eval spawn $CRYPTSETUP luksResume -v $DEV_NAME +eval spawn $CRYPTSETUP_RAW luksResume -v $DEV_NAME expect timeout abort "Enter passphrase for $EXPECT_DEV:" sleep 0.1 send "$PWD0\n" @@ -1007,5 +1025,41 @@ EOF [ $? -eq 0 ] || fail "Expect script failed." $CRYPTSETUP remove $DEV_NAME || fail +prepare "[40] Long passphrase from TTY." wipe +EXPECT_DEV=$(losetup $LOOPDEV | sed -e "s/.*(\(.*\))/\1/") + +# Password of maximal length 512 characters +LONG_PWD=\ +"0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF"\ +"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "\ +"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut e"\ +"nim ad minim veniam, quis nostrud exercitation ullamco laboris n"\ +"isi ut aliquip ex ea commodo consequat. Duis aute irure dolor in"\ +" reprehenderit in voluptate velit esse cillum dolore eu fugiat n"\ +"ulla pariatur. Excepteur sint occaecat cupidatat non proident, s"\ +"unt in culpa qui officia deserunt mollit anim id est laborum.DEF" + +echo -n "$LONG_PWD" >$KEYE + +expect_run - >/dev/null <<EOF +proc abort {} { send_error "Timeout. "; exit 2 } +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW luksFormat --type luks1 $FAST_PBKDF_OPT -v $LOOPDEV +expect timeout abort "Are you sure? (Type 'yes' in capital letters):" +send "YES\n" +expect timeout abort "Enter passphrase for $EXPECT_DEV:" +sleep 0.1 +send "$LONG_PWD\n" +expect timeout abort "Verify passphrase:" +sleep 0.1 +send "$LONG_PWD\n" +expect timeout abort "Command successful." +expect timeout abort eof +eval spawn $CRYPTSETUP_RAW luksOpen -v $LOOPDEV --test-passphrase --key-file $KEYE +expect timeout abort "Command successful." +expect timeout abort eof +EOF +[ $? -eq 0 ] || fail "Expect script failed." + remove_mapping exit 0 diff --git a/tests/compat-test2 b/tests/compat-test2 index fd8d6f0..1612569 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -29,6 +29,7 @@ PWDW="rUkL4RUryBom" TEST_KEYRING_NAME="compattest2_keyring" TEST_TOKEN0="compattest2_desc0" TEST_TOKEN1="compattest2_desc1" +TEST_TOKEN2="compattest2_desc2" VK_FILE="compattest2_vkfile" IMPORT_TOKEN="{\"type\":\"some_type\",\"keyslots\":[],\"base64_data\":\"zxI7vKB1Qwl4VPB4D-N-OgcC14hPCG0IDu8O7eCqaQ\"}" TOKEN_FILE0=test-token-file0 @@ -496,6 +497,18 @@ echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fai echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail if dm_crypt_keyring_support; then echo | $CRYPTSETUP -q resize --size 100 $DEV_NAME 2>/dev/null && fail + if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then + test_and_prepare_keyring + load_key user $TEST_TOKEN2 $PWD1 "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped." + $CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN2 --token-id 1 || fail + $CRYPTSETUP -q resize --size 99 $DEV_NAME <&- || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "99 sectors" || fail + #replace kernel key with wrong pass + load_key user $TEST_TOKEN2 $PWD2 "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped." + # must fail due to --token-only + echo $PWD1 | $CRYPTSETUP -q resize --token-only --size 100 $DEV_NAME && fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" && fail + fi fi echo $PWD1 | $CRYPTSETUP -q resize --size 100 $DEV_NAME || fail $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail @@ -649,6 +662,12 @@ 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 $CRYPTSETUP -q luksClose $DEV_NAME || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat -c null $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP -q luksOpen $LOOPDEV $DEV_NAME || fail +$CRYPTSETUP luksSuspend $DEV_NAME || fail +$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail +echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME || fail +$CRYPTSETUP -q luksClose $DEV_NAME || fail prepare "[27] luksOpen with specified key slot number" wipe # first, let's try passphrase option @@ -705,7 +724,7 @@ $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail $CRYPTSETUP luksSuspend $DEV_NAME --header $HEADER_IMG || fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail $CRYPTSETUP luksSuspend $DEV_NAME || fail -echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME && fail +echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --header $HEADER_IMG || fail $CRYPTSETUP luksClose $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 5 _fakedev_ --header $HEADER_IMG $KEY5 || fail @@ -713,6 +732,12 @@ $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 $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --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 "[29] Repair metadata" wipe xz -dk $HEADER_LUKS2_PV.xz @@ -1017,5 +1042,14 @@ echo $PWD3 | $CRYPTSETUP luksConvertKey --key-slot 22 $LOOPDEV --keyslot-cipher [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "22: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "22: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail +prepare "[42] 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]" + $CRYPTSETUP -q luksFormat --type luks2 $LOOPDEV $KEY1 $FAST_PBKDF_OPT --cipher $cipher --key-size $key_size || fail +done +echo + remove_mapping exit 0 diff --git a/tests/crypto-vectors.c b/tests/crypto-vectors.c index a8f3797..004e426 100644 --- a/tests/crypto-vectors.c +++ b/tests/crypto-vectors.c @@ -1,7 +1,7 @@ /* * cryptsetup crypto backend test vectors * - * Copyright (C) 2018-2020 Milan Broz + * Copyright (C) 2018-2021 Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -251,7 +251,7 @@ struct hash_test_vector { const char *name; unsigned int length; const char *out; - } out[6]; + } out[8]; }; static struct hash_test_vector hash_test_vectors[] = { @@ -270,6 +270,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\xc5\x30\x23\x21\x30\xd4\x07\xf8\x9a\xfe\xe0\x96\x49\x97\xf7\xa7" "\x3e\x83\xbe\x69\x8b\x28\x8f\xeb\xcf\x88\xe3\xe0\x3c\x4f\x07\x57" "\xea\x89\x64\xe5\x9b\x63\xd9\x37\x08\xb1\x38\xcc\x42\xa6\x6e\xb3" }, + { "blake2b-512",64,"\x78\x6a\x02\xf7\x42\x01\x59\x03\xc6\xc6\xfd\x85\x25\x52\xd2\x72" + "\x91\x2f\x47\x40\xe1\x58\x47\x61\x8a\x86\xe2\x17\xf7\x1f\x54\x19" + "\xd2\x5e\x10\x31\xaf\xee\x58\x53\x13\x89\x64\x44\x93\x4e\xb0\x4b" + "\x90\x3a\x68\x5b\x14\x48\xb7\x55\xd5\x6f\x70\x1a\xfe\x9b\xe2\xce" }, + { "blake2s-256",32,"\x69\x21\x7a\x30\x79\x90\x80\x94\xe1\x11\x21\xd0\x42\x35\x4a\x7c" + "\x1f\x55\xb6\x48\x2c\xa1\xa5\x1e\x1b\x25\x0d\xfd\x1e\xd0\xee\xf9" }, }},{ "a", 1, { { "crc32", 4, "\xe8\xb7\xbe\x43" }, @@ -285,6 +291,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\xf0\xdf\xf5\x94\x13\x14\x5e\x69\x73\xc4\x50\x01\xd0\x08\x7b\x42" "\xd1\x1b\xc6\x45\x41\x3a\xef\xf6\x3a\x42\x39\x1a\x39\x14\x5a\x59" "\x1a\x92\x20\x0d\x56\x01\x95\xe5\x3b\x47\x85\x84\xfd\xae\x23\x1a" }, + { "blake2b-512",64,"\x33\x3f\xcb\x4e\xe1\xaa\x7c\x11\x53\x55\xec\x66\xce\xac\x91\x7c" + "\x8b\xfd\x81\x5b\xf7\x58\x7d\x32\x5a\xec\x18\x64\xed\xd2\x4e\x34" + "\xd5\xab\xe2\xc6\xb1\xb5\xee\x3f\xac\xe6\x2f\xed\x78\xdb\xef\x80" + "\x2f\x2a\x85\xcb\x91\xd4\x55\xa8\xf5\x24\x9d\x33\x08\x53\xcb\x3c" }, + { "blake2s-256",32,"\x4a\x0d\x12\x98\x73\x40\x30\x37\xc2\xcd\x9b\x90\x48\x20\x36\x87" + "\xf6\x23\x3f\xb6\x73\x89\x56\xe0\x34\x9b\xd4\x32\x0f\xec\x3e\x90" }, }},{ "abc", 3, { { "crc32", 4, "\x35\x24\x41\xc2" }, @@ -300,6 +312,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\xf3\x04\x3e\x3a\x73\x1b\xce\x72\x1a\xe1\xb3\x03\xd9\x7e\x6d\x4c" "\x71\x81\xee\xbd\xb6\xc5\x7e\x27\x7d\x0e\x34\x95\x71\x14\xcb\xd6" "\xc7\x97\xfc\x9d\x95\xd8\xb5\x82\xd2\x25\x29\x20\x76\xd4\xee\xf5" }, + { "blake2b-512",64,"\xba\x80\xa5\x3f\x98\x1c\x4d\x0d\x6a\x27\x97\xb6\x9f\x12\xf6\xe9" + "\x4c\x21\x2f\x14\x68\x5a\xc4\xb7\x4b\x12\xbb\x6f\xdb\xff\xa2\xd1" + "\x7d\x87\xc5\x39\x2a\xab\x79\x2d\xc2\x52\xd5\xde\x45\x33\xcc\x95" + "\x18\xd3\x8a\xa8\xdb\xf1\x92\x5a\xb9\x23\x86\xed\xd4\x00\x99\x23" }, + { "blake2s-256",32,"\x50\x8c\x5e\x8c\x32\x7c\x14\xe2\xe1\xa7\x2b\xa3\x4e\xeb\x45\x2f" + "\x37\x45\x8b\x20\x9e\xd6\x3a\x29\x4d\x99\x9b\x4c\x86\x67\x59\x82" }, }},{ "abcdefghijklmnopqrstuvwxyz", 26, { { "crc32", 4, "\x4c\x27\x50\xbd" }, @@ -315,6 +333,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\x8d\x38\x63\x1e\xad\x42\x38\xf5\x44\x2e\xe1\x3b\x80\x54\xe4\x1b" "\x08\xbf\x2a\x92\x51\xc3\x0b\x6a\x0b\x8a\xae\x86\x17\x7a\xb4\xa6" "\xf6\x8f\x67\x3e\x72\x07\x86\x5d\x5d\x98\x19\xa3\xdb\xa4\xeb\x3b" }, + { "blake2b-512",64,"\xc6\x8e\xde\x14\x3e\x41\x6e\xb7\xb4\xaa\xae\x0d\x8e\x48\xe5\x5d" + "\xd5\x29\xea\xfe\xd1\x0b\x1d\xf1\xa6\x14\x16\x95\x3a\x2b\x0a\x56" + "\x66\xc7\x61\xe7\xd4\x12\xe6\x70\x9e\x31\xff\xe2\x21\xb7\xa7\xa7" + "\x39\x08\xcb\x95\xa4\xd1\x20\xb8\xb0\x90\xa8\x7d\x1f\xbe\xdb\x4c" }, + { "blake2s-256",32,"\xbd\xf8\x8e\xb1\xf8\x6a\x0c\xdf\x0e\x84\x0b\xa8\x8f\xa1\x18\x50" + "\x83\x69\xdf\x18\x6c\x73\x55\xb4\xb1\x6c\xf7\x9f\xa2\x71\x0a\x12" }, }},{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, { { "crc32", 4, "\x1f\xc2\xe6\xd2" }, @@ -330,6 +354,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\x1d\xd7\xc2\x8c\xde\xc0\x66\xcc\x6a\xf4\x2e\x40\xf8\x2f\x3a\x1e" "\x08\xeb\xa2\x66\x29\x12\x9d\x8f\xb7\xcb\x57\x21\x1b\x92\x81\xa6" "\x55\x17\xcc\x87\x9d\x7b\x96\x21\x42\xc6\x5f\x5a\x7a\xf0\x14\x67" }, + { "blake2b-512",64,"\x99\x96\x48\x02\xe5\xc2\x5e\x70\x37\x22\x90\x5d\x3f\xb8\x00\x46" + "\xb6\xbc\xa6\x98\xca\x9e\x2c\xc7\xe4\x9b\x4f\xe1\xfa\x08\x7c\x2e" + "\xdf\x03\x12\xdf\xbb\x27\x5c\xf2\x50\xa1\xe5\x42\xfd\x5d\xc2\xed" + "\xd3\x13\xf9\xc4\x91\x12\x7c\x2e\x8c\x0c\x9b\x24\x16\x8e\x2d\x50" }, + { "blake2s-256",32,"\xc7\x54\x39\xea\x17\xe1\xde\x6f\xa4\x51\x0c\x33\x5d\xc3\xd3\xf3" + "\x43\xe6\xf9\xe1\xce\x27\x73\xe2\x5b\x41\x74\xf1\xdf\x8b\x11\x9b" }, }},{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, { { "crc32", 4, "\x17\x1a\x3f\x5f" }, @@ -345,6 +375,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\x02\x7f\x61\x36\x6a\x14\x07\x26\x2d\xc2\xa6\xa3\x45\xd9\xe2\x40" "\xc0\x17\xc1\x83\x3d\xb1\xe6\xdb\x6a\x46\xbd\x44\x4b\x0c\x69\x52" "\x0c\x85\x6e\x7c\x6e\x9c\x36\x6d\x15\x0a\x7d\xa3\xae\xb1\x60\xd1" }, + { "blake2b-512",64,"\x72\x85\xff\x3e\x8b\xd7\x68\xd6\x9b\xe6\x2b\x3b\xf1\x87\x65\xa3" + "\x25\x91\x7f\xa9\x74\x4a\xc2\xf5\x82\xa2\x08\x50\xbc\x2b\x11\x41" + "\xed\x1b\x3e\x45\x28\x59\x5a\xcc\x90\x77\x2b\xdf\x2d\x37\xdc\x8a" + "\x47\x13\x0b\x44\xf3\x3a\x02\xe8\x73\x0e\x5a\xd8\xe1\x66\xe8\x88" }, + { "blake2s-256",32,"\x6f\x4d\xf5\x11\x6a\x6f\x33\x2e\xda\xb1\xd9\xe1\x0e\xe8\x7d\xf6" + "\x55\x7b\xea\xb6\x25\x9d\x76\x63\xf3\xbc\xd5\x72\x2c\x13\xf1\x89" }, }},{ "message digest", 14, { { "crc32", 4, "\x20\x15\x9d\x7f" }, @@ -360,6 +396,12 @@ static struct hash_test_vector hash_test_vectors[] = { "\x83\x8d\x00\x03\x22\x30\xf5\x3c\xe1\xf5\x70\x0c\x0f\xfb\x4d\x3b" "\x84\x21\x55\x76\x59\xef\x55\xc1\x06\xb4\xb5\x2a\xc5\xa4\xaa\xa6" "\x92\xed\x92\x00\x52\x83\x8f\x33\x62\xe8\x6d\xbd\x37\xa8\x90\x3e" }, + { "blake2b-512",64,"\x3c\x26\xce\x48\x7b\x1c\x0f\x06\x23\x63\xaf\xa3\xc6\x75\xeb\xdb" + "\xf5\xf4\xef\x9b\xdc\x02\x2c\xfb\xef\x91\xe3\x11\x1c\xdc\x28\x38" + "\x40\xd8\x33\x1f\xc3\x0a\x8a\x09\x06\xcf\xf4\xbc\xdb\xcd\x23\x0c" + "\x61\xaa\xec\x60\xfd\xfa\xd4\x57\xed\x96\xb7\x09\xa3\x82\x35\x9a" }, + { "blake2s-256",32,"\xfa\x10\xab\x77\x5a\xcf\x89\xb7\xd3\xc8\xa6\xe8\x23\xd5\x86\xf6" + "\xb6\x7b\xdb\xac\x4c\xe2\x07\xfe\x14\x5b\x7d\x3a\xc2\x5c\xd2\x8c" }, }}}; /* @@ -660,31 +702,37 @@ struct cipher_iv_test_vector { const char in_sha256[32]; struct { size_t sector_size; + bool large_iv; const char out_sha256[32]; - } out[4]; + } out[7]; }; static struct cipher_iv_test_vector cipher_iv_test_vectors[] = { { "aes", "cbc", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, - "null", 0, 8192, + "null", UINT32_MAX-7, 8192, "\x9f\x1d\xcb\xc3\x5c\x35\x0d\x60\x27\xf9\x8b\xe0\xf5\xc8\xb4\x3b" "\x42\xca\x52\xb7\x60\x44\x59\xc0\xc4\x2b\xe3\xaa\x88\x91\x3d\x47", { - { - 512, + { 512, false, "\xfd\x05\xd0\x4d\x51\xb9\xd4\x87\xa4\x57\x9a\x62\x07\x39\xc9\x4a" "\x00\x90\x3e\xaf\xe8\xb2\xac\x12\xca\xeb\x58\xf9\x48\xf6\xef\x08" - },{ - 1024, + },{ 1024, false, "\x55\x87\x5c\xde\x86\x6a\x8b\xab\x08\xbe\x5b\x38\x17\x53\xdf\xe5" "\x7e\xb9\x5f\x59\xaf\x07\xa4\xca\x6a\x24\xd1\x12\xa9\x15\x25\xf4" - },{ - 2048, + },{ 1024, true, + "\x55\x87\x5c\xde\x86\x6a\x8b\xab\x08\xbe\x5b\x38\x17\x53\xdf\xe5" + "\x7e\xb9\x5f\x59\xaf\x07\xa4\xca\x6a\x24\xd1\x12\xa9\x15\x25\xf4" + },{ 2048, false, "\x55\x5b\x8e\x74\x90\x9d\x0d\x4b\x74\x8c\x16\x7e\x29\xcf\xa9\xa3" "\xf3\x42\x8b\x62\xda\x2d\x8c\xda\xc9\x32\xc8\x78\xe2\x7e\xd2\x70" - },{ - 4096, + },{ 2048, true, + "\x55\x5b\x8e\x74\x90\x9d\x0d\x4b\x74\x8c\x16\x7e\x29\xcf\xa9\xa3" + "\xf3\x42\x8b\x62\xda\x2d\x8c\xda\xc9\x32\xc8\x78\xe2\x7e\xd2\x70" + },{ 4096, false, + "\xc6\x45\xba\xe0\x40\x3a\x96\x09\x5e\x46\x0d\x19\x9d\x58\x4b\x93" + "\x78\xc5\x3f\xa4\x2e\x9e\xb0\x19\x04\x4b\x73\x26\xf4\xa6\xb5\xc3" + },{ 4096, true, "\xc6\x45\xba\xe0\x40\x3a\x96\x09\x5e\x46\x0d\x19\x9d\x58\x4b\x93" "\x78\xc5\x3f\xa4\x2e\x9e\xb0\x19\x04\x4b\x73\x26\xf4\xa6\xb5\xc3" }, @@ -692,73 +740,88 @@ static struct cipher_iv_test_vector cipher_iv_test_vectors[] = { { "aes", "cbc", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, - "plain", UINT32_MAX-1, 8192, + "plain", UINT32_MAX-7, 8192, "\x9f\x1d\xcb\xc3\x5c\x35\x0d\x60\x27\xf9\x8b\xe0\xf5\xc8\xb4\x3b" "\x42\xca\x52\xb7\x60\x44\x59\xc0\xc4\x2b\xe3\xaa\x88\x91\x3d\x47", { - { - 512, - "\x4e\xa0\x9e\x5b\xf2\x27\x88\xdb\xe9\x05\xfb\x34\xa1\x88\x3b\xa3" - "\xda\x3e\x98\x50\x5d\x52\x68\x72\xc8\xac\x21\x88\x77\x35\x67\xad" - },{ - 1024, - "\x0e\x4d\xba\x93\xef\x44\x06\x3b\xac\x92\x29\x97\xde\x75\xe7\x18" - "\x26\x06\x5c\x8f\x23\xf2\xf8\xe5\xee\xfe\xf7\x9a\xdf\xc7\xd4\x2d" - },{ - 2048, - "\x6f\xd7\x56\x23\x51\x65\x20\x8f\xd2\x11\x35\xe1\xd2\x05\x40\xc3" - "\xd3\x18\xc1\xed\xf0\x1c\xbe\x0e\xdd\xd5\xca\x39\x21\xe0\xe4\x68" - },{ - 4096, - "\x80\xaa\x75\x69\x39\x29\x8f\x93\xbd\x09\x51\x96\x9b\x7d\x0f\xd0" - "\xf5\xb5\xdf\xf4\x48\x8c\x21\x26\x2e\xa7\x5c\x52\x75\xaa\xfc\xe3" + { 512, false, + "\x43\xfd\x6e\x25\x80\xb2\x13\xf5\xca\x71\x79\x18\xe4\x12\x91\xe0" + "\x6e\x37\x24\x32\xfd\x40\x4b\x42\xcb\xc1\x72\x1a\xc7\x5a\x19\xc8" + },{ 1024, false, + "\x18\x79\x8d\xad\xf2\x7b\x38\x03\x27\xa5\x76\x19\x07\xcd\x12\x62" + "\x03\x36\x57\x85\x88\x50\xd0\x6c\xf6\xdf\xf1\xcf\xb8\xcf\x01\x77" + },{ 1024, true, + "\xd0\x21\xcf\xb2\x7a\x01\xa8\x94\xb2\x87\x49\xc4\x9f\x9c\xb2\x3a" + "\x7c\xc4\x0d\x50\x08\xea\x4d\xfb\x87\xe4\x49\x8c\x1a\xd6\xec\x16" + },{ 2048, false, + "\xa4\x89\x72\xb9\xcf\x78\x0c\x2a\xc8\x20\x4f\xd5\x13\xcb\x75\x30" + "\x90\xd2\x4a\xfd\xd3\xb2\xe8\xf0\xd2\xb7\x9d\x07\xbd\xa9\x70\x97" + },{ 2048, true, + "\x2a\xcf\x07\x57\xc8\xea\x64\xc7\xd0\xd5\x28\xe6\xd1\x9a\xb5\x7d" + "\xe4\xb9\x63\xa2\x66\x5a\x3d\x14\xbd\x27\xc7\x09\xc0\x3c\xd9\x00" + },{ 4096, false, + "\x12\x1b\x00\x54\x6e\x2d\x08\xc1\x15\x8b\x15\x57\xc5\x11\x30\x8b" + "\x63\x33\x64\xa0\xd1\x45\xd6\xcb\xdd\x49\x91\x04\x29\xe6\x93\x08" + },{ 4096, true, + "\x44\xaa\xf1\x23\x0c\x34\x32\x2a\xfa\xe3\xf7\x95\x7a\x7c\xa8\x8b" + "\x34\x78\xbd\x12\x5c\xae\x4a\x65\x23\x8a\x6f\x3a\x96\x05\xfa\xae" }, }}, { "aes", "cbc", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, - "plain64", UINT32_MAX-1, 8192, + "plain64", UINT32_MAX-7, 8192, "\x9f\x1d\xcb\xc3\x5c\x35\x0d\x60\x27\xf9\x8b\xe0\xf5\xc8\xb4\x3b" "\x42\xca\x52\xb7\x60\x44\x59\xc0\xc4\x2b\xe3\xaa\x88\x91\x3d\x47", { - { - 512, - "\x60\xe5\xc9\xf8\xcd\x48\x06\x3c\x96\x11\xc8\xbf\x1e\x67\x60\x21" - "\x0c\x1f\x1a\x8b\x03\x00\x0d\xc1\x39\xc9\x27\xb8\xa8\x73\x17\x69" - },{ - 1024, - "\x25\xc1\x6b\x78\x8a\x22\x72\xb5\x5c\xfb\x3f\xe9\x16\x8b\x89\x96" - "\xfa\x80\xed\xf4\x83\xab\x1c\x79\xd2\xc7\x44\x27\x89\x99\xbb\x83" - },{ - 2048, - "\xb3\x42\x15\xd7\x86\xf6\xdf\x45\x49\x78\x18\x73\xa8\x7f\x3e\xb3" - "\x0b\xb8\x64\x91\x7c\xf1\x5a\x5b\x6d\x20\xbc\x0b\xe2\xab\x9b\xe6" - },{ - 4096, - "\x6b\x45\x5c\x24\x97\xb4\x87\x49\x99\x16\x69\x59\x72\x6b\xd7\xc9" - "\xc9\x90\xec\x7f\x3b\xfb\xe9\xea\x9d\xb4\x39\x62\x4d\x22\xe5\x43" + { 512, false, + "\xb3\x65\x7e\x6c\xba\xe0\x39\xcd\x1e\x1d\xaf\x65\xae\xb7\xda\x20" + "\x25\x17\x6a\x38\x75\x79\x68\x4c\x9a\x75\xc7\xfb\x2b\xa2\x17\xd2" + },{ 1024, false, + "\x0a\xa3\x23\x72\x80\xd3\x76\x33\x8b\x2b\xae\x01\x03\x99\xa5\xca" + "\xcd\x95\x27\x40\x27\xec\x14\x90\xfd\x58\xb0\x08\x9b\x99\x27\xe2" + },{ 1024, true, + "\xd0\x21\xcf\xb2\x7a\x01\xa8\x94\xb2\x87\x49\xc4\x9f\x9c\xb2\x3a" + "\x7c\xc4\x0d\x50\x08\xea\x4d\xfb\x87\xe4\x49\x8c\x1a\xd6\xec\x16" + },{ 2048, false, + "\x67\x87\xeb\xed\xe1\x16\x85\x0a\x3f\xb2\x5c\xbc\x27\x61\x99\x52" + "\xfe\x64\xb9\xab\x24\xdd\x2c\x1a\x2c\xff\xcd\x7e\x2e\x74\xb5\xd4" + },{ 2048, true, + "\x2a\xcf\x07\x57\xc8\xea\x64\xc7\xd0\xd5\x28\xe6\xd1\x9a\xb5\x7d" + "\xe4\xb9\x63\xa2\x66\x5a\x3d\x14\xbd\x27\xc7\x09\xc0\x3c\xd9\x00" + },{ 4096, false, + "\xb2\xf1\x0e\x66\xd4\x58\x4e\x93\xe7\x98\xae\x9c\x3e\xa7\xad\xf2" + "\x93\x1a\xaa\x3c\xc4\x90\x12\x05\x00\x58\x25\x8f\x1f\x5d\xc6\x67" + },{ 4096, true, + "\x44\xaa\xf1\x23\x0c\x34\x32\x2a\xfa\xe3\xf7\x95\x7a\x7c\xa8\x8b" + "\x34\x78\xbd\x12\x5c\xae\x4a\x65\x23\x8a\x6f\x3a\x96\x05\xfa\xae" }, }}, { "aes", "cbc", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, - "plain64be", UINT32_MAX-1, 8192, + "plain64be", UINT32_MAX-7, 8192, "\x9f\x1d\xcb\xc3\x5c\x35\x0d\x60\x27\xf9\x8b\xe0\xf5\xc8\xb4\x3b" "\x42\xca\x52\xb7\x60\x44\x59\xc0\xc4\x2b\xe3\xaa\x88\x91\x3d\x47", { - { - 512, - "\x7f\xf9\xdb\xe1\xf6\x8c\x4d\xb4\x33\x9d\x61\x7b\x67\x5c\xef\x69" - "\xea\x94\x32\x3d\xa7\x70\x01\xe0\x06\x4c\xf8\x56\x64\xd0\xb7\xdf" - },{ - 1024, - "\x8e\x33\x0b\xa2\x45\x78\x5a\x3d\x5e\xf7\x74\xf9\x75\xb5\xbd\x06" - "\x38\x78\x74\x4f\xd8\xec\x11\x96\xf7\x92\x2b\xb1\x9a\xc2\xc3\xef" - },{ - 2048, - "\xad\x94\xcb\x8d\x96\x47\x10\x5c\x54\xce\x74\xca\xc8\xa3\xbd\x3e" - "\xdf\xa7\xf5\x14\x2a\x77\x4c\x50\xb8\x01\x46\xc3\x89\x50\xa7\x46" - },{ - 4096, - "\x3b\xdb\xbe\x01\x09\xd9\xda\xf7\x77\x85\xe2\x30\xaf\x21\xe7\x70" - "\x51\x2c\x6b\xcc\x75\x40\x7e\x8d\xdc\x90\xab\xaf\x6d\x2e\x0b\x49" + { 512, false, + "\x28\xbf\x09\xe1\x68\xcc\x05\x1b\x20\xaf\x8d\x01\x36\x21\x8a\x8d" + "\x7a\x94\x98\xa8\x99\xe9\xf4\x66\xd8\xb7\x99\xca\x04\x58\x83\x90" + },{ 1024, false, + "\x9b\x74\xf7\xd5\x5a\x6b\xb2\x3a\xd2\x09\xdd\x80\x59\x28\x70\x8f" + "\x3a\x61\xf2\x14\xc3\x0d\xa8\xd7\xd9\xcb\x57\x26\x73\x88\x93\xd2" + },{ 1024, true, + "\x36\xb5\x68\x08\x29\x55\xb9\xe9\x01\xc1\xa8\xcf\x3e\x5b\x00\x28" + "\xb6\xd1\x35\xc5\xf7\x0c\xf6\x59\xb5\x8f\xb9\xa2\x00\x43\x29\x48" + },{ 2048, false, + "\x94\x4f\xc8\xb4\xfe\xad\xdc\x56\xf0\x62\x00\x8d\x52\x0b\x2d\x58" + "\xc0\x05\xd6\x1d\x47\x35\xc6\x6a\x42\xec\x98\xee\x21\x74\x7b\xe5" + },{ 2048, true, + "\x14\x6b\xaa\x2f\xf4\xa8\x24\x3f\x4e\x92\x97\x1a\xca\x1c\xbb\x46" + "\xa7\x08\xbb\xc5\x95\xac\x73\x81\x25\x34\x33\x41\x95\x71\xd9\xe7" + },{ 4096, false, + "\xa8\x17\x5d\x84\xc8\x16\x06\x7f\xa2\x68\xdd\x1e\x7d\x63\x34\x93" + "\x7b\x45\x2d\xf4\x10\x0b\x90\xfa\x14\x8b\x73\x86\xbc\x09\x4a\xe3" + },{ 4096, true, + "\xe2\xc3\x30\xd8\xa1\xb3\xa8\xeb\xde\xdc\xfe\x9b\xe0\x0b\x62\x4e" + "\x38\x2f\xa1\x45\x0e\x8f\x6c\xf0\x4e\x88\x58\x17\x13\xb5\x10\x98" }, }}, { @@ -767,22 +830,27 @@ static struct cipher_iv_test_vector cipher_iv_test_vectors[] = { "essiv:sha256", 0, 8192, "\x9f\x1d\xcb\xc3\x5c\x35\x0d\x60\x27\xf9\x8b\xe0\xf5\xc8\xb4\x3b" "\x42\xca\x52\xb7\x60\x44\x59\xc0\xc4\x2b\xe3\xaa\x88\x91\x3d\x47", { - { - 512, + { 512, false, "\xa5\x3e\x74\xc4\x1a\x5c\xf3\x6b\x63\x49\xd5\xd9\xbb\x7a\x89\x5a" "\xd5\x3e\x76\x6f\x4c\x2d\x0b\xd3\x8b\x5e\x0e\x91\xa3\x8c\x2a\xde" - },{ - 1024, + },{ 1024, false, "\x41\x6b\xc6\x75\x2e\x99\x76\xa1\x83\xea\xd5\x97\x64\x0e\x24\x8c" "\x91\x17\x03\x38\xe7\xd8\x66\x64\xaa\xd7\x27\x50\x2a\xd3\x0b\xe6" - },{ - 2048, + },{ 1024, true, + "\x02\x3c\xbe\xe6\x1e\x9a\xf3\x14\xab\x16\xff\x6f\xb6\xa2\x3e\x03" + "\xa1\xbd\xe9\xe4\xfa\x44\x5b\x22\xc6\x53\xe8\x60\x58\x15\x99\xea" + },{ 2048, false, "\x84\xdc\x45\xd3\x61\x03\xa8\x51\x85\x5b\xef\xf8\x92\x6b\x12\x06" "\x2c\xfe\x75\x3e\xcf\x28\xd1\x8b\x4d\xcb\x88\x9e\x31\xb0\x0b\x92" - },{ - 4096, + },{ 2048, true, + "\x4b\x9d\xe4\x3c\xe2\x4e\x7a\x13\x72\x02\x48\xf8\x7a\x7e\x15\xe8" + "\x3a\xc3\x92\x0b\xe8\x30\xac\xb7\x9a\xe0\xcf\xf9\xb1\xf5\x61\x5b" + },{ 4096, false, "\xbb\x1b\xa3\xa9\x41\xbf\x17\xd8\x76\x19\x08\x8e\x3f\x50\xed\xfd" "\x57\x1d\xd2\xc2\x8a\x32\x01\xb9\xd9\x8a\xcc\x0d\xa0\x65\x8b\x6d" + },{ 4096, true, + "\xa6\xdc\x7d\xc8\xc4\x9b\x78\x81\x72\xe9\xdd\x35\x6c\x07\xeb\x7b" + "\xd6\x56\x9e\xe4\xdf\xf5\xdd\x2e\x2c\x19\x8f\x63\x58\xdb\xa7\xd0" }, }}, { @@ -791,22 +859,27 @@ static struct cipher_iv_test_vector cipher_iv_test_vectors[] = { "benbi", 0, 8192, "\x9f\x1d\xcb\xc3\x5c\x35\x0d\x60\x27\xf9\x8b\xe0\xf5\xc8\xb4\x3b" "\x42\xca\x52\xb7\x60\x44\x59\xc0\xc4\x2b\xe3\xaa\x88\x91\x3d\x47", { - { - 512, + { 512, false, "\x3c\xe3\x94\xe3\x6d\x68\x5b\xdb\x5a\x8d\x71\xbf\xd3\xa6\x68\xb9" "\x1f\x33\x0f\x97\xe2\xd6\xe8\xe2\xe1\xfc\x7e\x80\x28\xf1\x73\xbd" - },{ - 1024, + },{ 1024, false, "\x0f\x27\xa7\xae\x31\x9e\x71\x02\x12\x16\x44\x5f\xbb\xc6\xcb\x78" "\xd4\x84\x49\xe0\x88\x85\x04\xbf\x6d\xea\x60\x76\x98\x34\x0a\x7e" - },{ - 2048, + },{ 1024, true, + "\x3e\xf3\x08\x8d\x3b\x20\x4b\x51\x54\xde\x7f\x77\x5b\xcf\x02\x8b" + "\x0e\xb0\x74\x2e\x8e\x29\xfa\x5e\x86\xb4\xab\x65\x18\x59\x48\xb1" + },{ 2048, false, "\xb0\x9a\xe5\x31\x5f\x2e\x9d\x13\x04\x08\x2a\x02\x71\x3d\xdb\x5d" "\xb2\xc9\x68\x5b\xdc\xd1\x38\xc2\x96\xb3\x3b\x72\xda\x9d\xcb\xe6" - },{ - 4096, + },{ 2048, true, + "\x6f\x34\xf0\xc1\xea\x72\xe4\xdc\x91\x91\x78\xb3\x7c\xb0\x9d\x41" + "\x94\xf6\xb8\xad\x05\xc4\x0e\x49\x05\x31\x90\xf0\x56\xfe\x21\x3f" + },{ 4096, false, "\xaa\x74\x7d\xd6\x73\xa7\x77\xe1\x7f\xb9\x76\xf7\x5c\xcf\xc0\xb7" "\xfa\x7b\xed\x15\xc2\x32\x7c\x27\xbb\x35\xfc\xfe\x12\xee\x14\x2d" + },{ 4096, true, + "\x71\x1b\x3d\x26\xf4\x44\x82\x72\x1b\x7a\x65\x0b\x37\x8c\x94\x5b" + "\x1c\xd3\x30\x2f\xf6\xce\xa4\x24\x25\xeb\x9b\xb9\x83\xe5\x71\xbb" }, }}, { @@ -815,22 +888,27 @@ static struct cipher_iv_test_vector cipher_iv_test_vectors[] = { "eboiv", 0, 8192, "\x9f\x1d\xcb\xc3\x5c\x35\x0d\x60\x27\xf9\x8b\xe0\xf5\xc8\xb4\x3b" "\x42\xca\x52\xb7\x60\x44\x59\xc0\xc4\x2b\xe3\xaa\x88\x91\x3d\x47", { - { - 512, + { 512, false, "\x04\x4e\x92\x9f\x79\x66\xfe\x93\x1b\xa5\xb8\x02\xfe\x7e\xf9\x26" "\x7b\x64\x39\xe7\xb3\xca\xc4\x6e\xca\x27\xa0\x2f\xe2\xea\x91\x16" - },{ - 1024, + },{ 1024, false, "\xb0\x4a\xa4\xb5\xd6\x45\x7a\x86\xe9\x43\x3d\xd6\x01\xf7\x68\x8e" "\xe6\x81\x8d\x50\x55\x18\x8e\x4b\xb6\xa7\x89\xdf\xe2\x4b\x94\xe2" - },{ - 2048, + },{ 1024, true, + "\x95\x08\x4d\x4e\x89\xab\x91\x4e\xae\x56\x5d\xec\xf2\x78\x13\xb1" + "\x82\xf7\xc8\xb5\x03\xd6\xfa\xb0\xe3\xf9\xc1\x01\xc0\x0c\x35\xa4" + },{ 2048, false, "\xd4\x00\x1f\x26\x18\xd1\x6d\xd5\xc4\xbf\x4a\x13\x30\xae\xd7\x4b" "\x33\x1e\xd5\xe8\x43\x2d\x95\x84\x67\x39\x04\x51\x5f\x1f\x49\xe4" - },{ - 4096, + },{ 2048, true, + "\x89\x8d\xa2\xec\x45\x7f\xf0\xac\xfc\x70\xb6\x36\xf0\x89\xca\x86" + "\x6b\xbf\x09\xd2\x54\xa0\x7c\xbc\x17\xd3\x4e\xb8\x10\x8a\x3f\x5d" + },{ 4096, false, "\xd1\xd7\x4f\x70\x9a\xa0\x22\x27\x60\xdb\x40\x5a\x84\xce\x89\x2c" "\x4f\x98\x55\xd2\x2d\xd1\xea\x9e\x47\xae\x8a\x83\xb5\x90\xbb\x49" + },{ 4096, true, + "\xdb\xe7\xd2\x25\xb0\x4f\x5d\x36\x20\xc4\xc2\xb4\xe8\x7e\xae\xe9" + "\x95\x10\x45\x5d\xdd\xc4\xcd\x33\xad\xbd\x39\x49\xf2\x85\x82\x4c" }, }}}; @@ -1106,12 +1184,12 @@ static int cipher_iv_test(void) snprintf(mode_iv, sizeof(mode_iv)-2, "%s-%s", vector->cipher_mode, vector->iv_name); r = crypt_storage_init(&storage, vector->out[j].sector_size, vector->cipher_name, mode_iv, - vector->key, vector->key_length); + vector->key, vector->key_length, vector->out[j].large_iv); if (r == -ENOENT || r == -ENOTSUP) { printf("[N/A]"); continue; } else { - printf("[%i]", (int)vector->out[j].sector_size); + printf("[%i%s]", (int)vector->out[j].sector_size, vector->out[j].large_iv ? "L" : ""); if (r) return EXIT_FAILURE; } diff --git a/tests/cryptsetup-valg-supps b/tests/cryptsetup-valg-supps index b2530f7..493e125 100644 --- a/tests/cryptsetup-valg-supps +++ b/tests/cryptsetup-valg-supps @@ -12,25 +12,3 @@ fun:init_crypto ... } -# following leaks/errors are addressed to libpopt... -{ - popt_read_error - Memcheck:Addr4 - obj:/lib*/libpopt.so* - fun:poptGetNextOpt - fun:main -} -{ - popt_leak_poptGetNextOpt_00 - Memcheck:Leak - fun:realloc - fun:poptGetNextOpt - fun:main -} -{ - popt_leak_poptGetNextOpt_01 - Memcheck:Leak - fun:malloc - fun:poptGetNextOpt - fun:main -} diff --git a/tests/device-test b/tests/device-test index 0898b45..617f16a 100755 --- a/tests/device-test +++ b/tests/device-test @@ -17,7 +17,7 @@ cleanup() { umount -f $MNT_DIR 2>/dev/null rmdir $MNT_DIR 2>/dev/null fi - sleep 2 + rmmod scsi_debug 2>/dev/null } fail() @@ -36,8 +36,19 @@ skip() exit 77 } +add_device() { + modprobe scsi_debug $@ delay=0 + [ $? -ne 0 ] && skip "This kernel seems to not support proper scsi_debug module." + + sleep 1 + SCSI_DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) + + [ -b "/dev/$SCSI_DEV" ] || fail "Cannot find $SCSI_DEV." +} + function dm_crypt_features() { + modprobe dm-crypt || fail "dm-crypt failed to load" VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." @@ -61,6 +72,9 @@ function dm_crypt_features() if [ $VER_MIN -gt 18 -o \( $VER_MIN -eq 18 -a $VER_PTC -ge 1 \) ]; then test -d /proc/sys/kernel/keys && DM_KEYRING=1 fi + + [ $VER_MIN -lt 22 ] && return + DM_PERF_NO_WORKQUEUE=1 } function dm_crypt_keyring_support() @@ -119,11 +133,12 @@ if [ -z "$DM_PERF_CPU" ]; then echo "TEST SKIPPED: dmcrypt options not available" SKIP_COUNT=$((SKIP_COUNT+1)) else - # plain + 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 $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail $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 $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail $CRYPTSETUP status $DEV_NAME | grep -q discards || fail @@ -141,12 +156,21 @@ else $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 + 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 + $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail + $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail + fi $CRYPTSETUP close $DEV_NAME || fail - # LUKS + echo + + echo -n "LUKS: same_cpu_crypt submit_from_cpus " echo -e "$PWD1" | $CRYPTSETUP open --type luks1 $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 $CRYPTSETUP close $DEV_NAME || fail + echo -n "allow_discards " echo -e "$PWD1" | $CRYPTSETUP open --type luks1 $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 @@ -162,9 +186,17 @@ else $CRYPTSETUP status $DEV_NAME | grep -q discards && fail $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail echo -e "$PWD1" | $CRYPTSETUP refresh $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 $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 + fi $CRYPTSETUP close $DEV_NAME || fail + echo format luks2 + echo -n "LUKS2: same_cpu_crypt submit_from_cpus " echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus --persistent || fail $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail @@ -174,6 +206,7 @@ else $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail $CRYPTSETUP close $DEV_NAME || fail + echo -n "allow_discards [persistent flags] " echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards --persistent || fail $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail $CRYPTSETUP status $DEV_NAME | grep -q discards || fail @@ -211,11 +244,23 @@ 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 fi + if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then + echo -n "no_read_workqueue no_write_workqueue" + echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --perf-no_read_workqueue --perf-no_write_workqueue --persistent || fail + $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail + $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail + $CRYPTSETUP close $DEV_NAME || fail + echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail + $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail + $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail + fi echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME2 2>/dev/null && fail $CRYPTSETUP close $DEV_NAME || fail + echo fi echo "[3] Kernel dmcrypt sector size options" @@ -262,4 +307,22 @@ else echo fi +echo "[4] Disappeared device test:" +KEY="00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" +for F in LUKS1 LUKS2 BITLK TCRYPT; do + echo -n "$F" + add_device dev_size_mb=1 sector_size=512 num_tgts=1 lbpu=1 + # Fake CRYPT UUID to force code to parse type-specific path + dmsetup create $DEV_NAME --uuid CRYPT-$F-$DEV_NAME --table "0 1024 crypt aes-xts-plain64 $KEY 16 /dev/$SCSI_DEV 16" + $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail + echo 1 > /sys/block/$SCSI_DEV/device/delete + udevadm settle >/dev/null 2>&1 + $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail + dmsetup remove $DEV_NAME --retry || fail + rmmod scsi_debug + echo -n "[OK] " +done +echo + cleanup +exit 0 diff --git a/tests/differ.c b/tests/differ.c index 827b319..ec811a4 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-2020 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2021 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/generators/generate-luks2-segment-wrong-backup-key-0.img.sh b/tests/generators/generate-luks2-segment-wrong-backup-key-0.img.sh new file mode 100755 index 0000000..2499a5e --- /dev/null +++ b/tests/generators/generate-luks2-segment-wrong-backup-key-0.img.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate primary header with wrong backup segment id +# +# secondary header is corrupted on purpose as well +# + +# $1 full target dir +# $2 full source luks2 image + +function prepare() +{ + cp $SRC_IMG $TGT_IMG + test -d $TMPDIR || mkdir $TMPDIR + read_luks2_json0 $TGT_IMG $TMPDIR/json0 + read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0 + read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1 +} + +function generate() +{ + # create illegal backup segment key (used to be bug in 32bit implementations) + json_str=$(jq -c '.segments[(.segments | length + 1 | tostring)] = { "type" : "linear", "offset" : "512", "size" : "512", "flags":["backup-x"]}' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + + merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 + erase_checksum $TMPDIR/area0 + chks0=$(calc_sha256_checksum_file $TMPDIR/area0) + write_checksum $chks0 $TMPDIR/area0 + write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG + kill_bin_hdr $TMPDIR/hdr1 + write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG +} + +function check() +{ + read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 + local str_res1=$(head -c 6 $TMPDIR/hdr_res1) + test "$str_res1" = "VACUUM" || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if .segments | length < 2 + then error("Unexpected segments count") else empty end' $TMPDIR/json_res0 || exit 5 +} + +function cleanup() +{ + rm -f $TMPDIR/* + rm -fd $TMPDIR +} + +test $# -eq 2 || exit 1 + +TGT_IMG=$1/$(test_img_name $0) +SRC_IMG=$2 + +prepare +generate +check +cleanup diff --git a/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh b/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh new file mode 100755 index 0000000..702fe71 --- /dev/null +++ b/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate primary header with wrong backup segment id +# +# secondary header is corrupted on purpose as well +# + +# $1 full target dir +# $2 full source luks2 image + +function prepare() +{ + cp $SRC_IMG $TGT_IMG + test -d $TMPDIR || mkdir $TMPDIR + read_luks2_json0 $TGT_IMG $TMPDIR/json0 + read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0 + read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1 +} + +function generate() +{ + # create illegal backup segment key (used to be bug in 32bit implementations) + json_str=$(jq -c '(.segments."0".offset | tonumber) as $i | .segments[range(1;65) | tostring] = { "type" : "linear", "offset" : ($i + 512 | tostring), "size" : "512" } | .segments."268435472" = { "type":"linear","offset":"512","size":"512","flags":["backup-x"]}' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + + merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 + erase_checksum $TMPDIR/area0 + chks0=$(calc_sha256_checksum_file $TMPDIR/area0) + write_checksum $chks0 $TMPDIR/area0 + write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG + kill_bin_hdr $TMPDIR/hdr1 + write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG +} + +function check() +{ + read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 + local str_res1=$(head -c 6 $TMPDIR/hdr_res1) + test "$str_res1" = "VACUUM" || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if .segments | length < 64 + then error("Unexpected segments count") else empty end' $TMPDIR/json_res0 || exit 5 +} + +function cleanup() +{ + rm -f $TMPDIR/* + rm -fd $TMPDIR +} + +test $# -eq 2 || exit 1 + +TGT_IMG=$1/$(test_img_name $0) +SRC_IMG=$2 + +prepare +generate +check +cleanup diff --git a/tests/integrity-compat-test b/tests/integrity-compat-test index 8607e85..a3d3b8c 100755 --- a/tests/integrity-compat-test +++ b/tests/integrity-compat-test @@ -14,6 +14,7 @@ DEV_LOOP="" DEV=test123.img DEV2=test124.img KEY_FILE=key.img +KEY_FILE2=key2.img dmremove() { # device udevadm settle >/dev/null 2>&1 @@ -25,12 +26,12 @@ cleanup() { [ -b /dev/mapper/$DEV_NAME_BIG ] && dmremove $DEV_NAME_BIG [ -n "$DEV_LOOP" ] && losetup -d "$DEV_LOOP" DEV_LOOP="" - rm -f $DEV $DEV2 $KEY_FILE >/dev/null 2>&1 + rm -f $DEV $DEV2 $KEY_FILE $KEY_FILE2 >/dev/null 2>&1 } fail() { - echo + [ -n "$1" ] && echo "$1" echo "FAILED backtrace:" while caller $frame; do ((frame++)); done cleanup @@ -60,11 +61,15 @@ function dm_integrity_features() [ $VER_MIN -gt 2 ] && { DM_INTEGRITY_BITMAP=1 } + [ $VER_MIN -gt 6 ] && { + DM_INTEGRITY_HMAC_FIX=1 + } } add_device() { cleanup - dd if=/dev/urandom of=$KEY_FILE bs=1 count=512 >/dev/null 2>&1 + dd if=/dev/urandom of=$KEY_FILE bs=4096 count=1 >/dev/null 2>&1 + dd if=/dev/urandom of=$KEY_FILE2 bs=1 count=32 >/dev/null 2>&1 dd if=/dev/zero of=$DEV bs=1M count=32 >/dev/null 2>&1 dd if=/dev/zero of=$DEV2 bs=1M count=32 >/dev/null 2>&1 sync @@ -156,12 +161,27 @@ intformat() # alg alg_out tagsize outtagsize sector_size csum [keyfile keysize] fi echo -n "[INTEGRITY:$2:$4:$5]" + [ -n "$8" ] && echo -n "[KEYFILE:$8]" echo -n "[FORMAT]" - $INTSETUP format --integrity-legacy-padding -q --integrity $1 $TAG_PARAMS --sector-size $5 $KEY_PARAMS $DEV >/dev/null || fail "Cannot format device." + $INTSETUP format --integrity-legacy-padding -q --integrity $1 $TAG_PARAMS --sector-size $5 $KEY_PARAMS $DEV >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + ALG=$(echo $1 | sed -e 's/hmac-//') + if ! grep -q $ALG /proc/crypto ; then + echo "[N/A]" + return + fi + fail "Cannot format device." + fi + dump_check "tag_size" $4 dump_check "sector_size" $5 echo -n "[ACTIVATE]" $INTSETUP open $DEV $DEV_NAME --integrity $1 $KEY_PARAMS || fail "Cannot activate device." + if [ -n "$8" ]; then + KEY_HEX=$(xxd -c 4096 -l $8 -p $7) + [ -z "$KEY_HEX" ] && fail "Cannot decode key." + dmsetup table --showkeys $DEV_NAME | grep -q $KEY_HEX || fail "Key mismatch." + fi status_check "tag size" $4 status_check "integrity" $2 status_check "sector size" "$5 bytes" @@ -225,7 +245,7 @@ int_error_detection() # mode alg tagsize outtagsize sector_size key_file key_siz int_journal() # 1 alg, 2 tagsize, 3 sector_size, 4 watermark, 5 commit_time, 6 journal_integrity, 7 key-file, 8 key-size, 9 journal_integrity_out { - echo -n "[INTEGRITY JOURNAL:$6:${4}%:${5}ms]" + echo -n "[INTEGRITY JOURNAL:$6:${4}%:${5}ms:$8]" echo -n "[FORMAT]" ARGS="--integrity $1 --journal-watermark $4 --journal-commit-time $5 --journal-integrity $6 --journal-integrity-key-file $7 --journal-integrity-key-size $8" $INTSETUP format -q --tag-size $2 --sector-size $3 $ARGS $DEV || fail "Cannot format device." @@ -235,7 +255,7 @@ int_journal() # 1 alg, 2 tagsize, 3 sector_size, 4 watermark, 5 commit_time, 6 j $INTSETUP open $DEV $DEV_NAME $ARGS || fail "Cannot activate device." echo -n "[KEYED HASH]" - KEY_HEX=$(xxd -c 256 -l $8 -p $7) + KEY_HEX=$(xxd -c 4096 -l $8 -p $7) [ -z "$KEY_HEX" ] && fail "Cannot decode key." dmsetup table --showkeys $DEV_NAME | grep -q $KEY_HEX || fail "Key mismatch." @@ -286,7 +306,7 @@ int_mode() # alg tag_size sector_size [keyfile keysize] status_check "mode" "read/write" kernel_param_check 7 "J" - $INTSETUP close $DEV_NAME fail "Cannot deactivate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo -n "[DIRECT WRITES]" $INTSETUP open $DEV $DEV_NAME --integrity $1 $KEY_PARAMS --integrity-no-journal || fail "Cannot activate device without journal." @@ -294,14 +314,14 @@ int_mode() # alg tag_size sector_size [keyfile keysize] status_check "journal" "not active" kernel_param_check 7 "D" - $INTSETUP close $DEV_NAME fail "Cannot deactivate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo -n "[RECOVERY MODE]" $INTSETUP open $DEV $DEV_NAME --integrity $1 $KEY_PARAMS --integrity-recovery-mode || fail "Cannot activate device in recovery mode." status_check "mode" "read/write recovery" kernel_param_check 7 "R" - $INTSETUP close $DEV_NAME fail "Cannot deactivate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo "[OK]" } @@ -316,6 +336,8 @@ modprobe dm-integrity >/dev/null 2>&1 dm_integrity_features add_device +intformat blake2s-256 blake2s-256 32 32 512 8e5fe4119558e117bfc40e3b0f13ade3abe497b52604d4c7cca0cfd6c7f4cf11 +intformat blake2b-256 blake2b-256 32 32 512 8e5fe4119558e117bfc40e3b0f13ade3abe497b52604d4c7cca0cfd6c7f4cf11 intformat crc32c crc32c 0 4 512 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7 intformat crc32 crc32 0 4 512 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7 intformat sha1 sha1 0 20 512 6eedd6344dab8875cd185fcd6565dfc869ab36bc57e577f40c685290b1fa7fe7 @@ -324,6 +346,7 @@ intformat sha256 sha256 0 32 512 8e5fe4119558e117bfc40e3b0f13ade3 intformat hmac-sha256 hmac\(sha256\) 0 32 512 8e5fe4119558e117bfc40e3b0f13ade3abe497b52604d4c7cca0cfd6c7f4cf11 $KEY_FILE 32 intformat sha256 sha256 0 32 4096 33f7dfa5163ca9f740383fb8b0919574e38a7b20a94a4170fde4238196b7c4b4 intformat hmac-sha256 hmac\(sha256\) 0 32 4096 33f7dfa5163ca9f740383fb8b0919574e38a7b20a94a4170fde4238196b7c4b4 $KEY_FILE 32 +intformat hmac-sha256 hmac\(sha256\) 0 32 4096 33f7dfa5163ca9f740383fb8b0919574e38a7b20a94a4170fde4238196b7c4b4 $KEY_FILE 4096 echo "Error detection tests:" int_error_detection J crc32c 0 4 512 @@ -345,6 +368,7 @@ echo "Journal parameters tests:" int_journal crc32 4 512 66 1000 hmac-sha256 $KEY_FILE 32 hmac\(sha256\) int_journal sha256 32 4096 34 5000 hmac-sha1 $KEY_FILE 16 hmac\(sha1\) int_journal sha1 20 512 75 9999 hmac-sha256 $KEY_FILE 32 hmac\(sha256\) +int_journal sha1 20 512 75 9999 hmac-sha256 $KEY_FILE 4096 hmac\(sha256\) echo "Journal encryption tests:" int_journal_crypt cbc-aes cbc\(aes\) $KEY_FILE 32 @@ -367,7 +391,7 @@ if [ -n "$DM_INTEGRITY_RECALC" ] ; then $INTSETUP open $DEV $DEV_NAME --integrity-recalculate || fail "Cannot activate device." dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M 2>/dev/null || fail "Cannot recalculate tags in-kernel" int_check_sum_only 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7 - $INTSETUP close $DEV_NAME fail "Cannot deactivate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo "[OK]" else echo "[N/A]" @@ -380,7 +404,7 @@ if [ -n "$DM_INTEGRITY_META" ] ; then $INTSETUP open $DEV --data-device $DEV2 $DEV_NAME || fail "Cannot activate device." int_check_sum_only 83ee47245398adee79bd9c0a8bc57b821e92aba10f5f9ade8a5d1fae4d8c4302 $INTSETUP status $DEV_NAME | grep -q 'metadata device:' || fail - $INTSETUP close $DEV_NAME fail "Cannot deactivate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo "[OK]" else echo "[N/A]" @@ -393,7 +417,7 @@ if [ -n "$DM_INTEGRITY_BITMAP" ] ; then $INTSETUP open $DEV --integrity-bitmap-mode --bitmap-sectors-per-bit 65536 --bitmap-flush-time 5000 $DEV_NAME || fail "Cannot activate device." $INTSETUP status $DEV_NAME | grep -q 'bitmap 512-byte sectors per bit: 65536' || fail $INTSETUP status $DEV_NAME | grep -q 'bitmap flush interval: 5000 ms' || fail - $INTSETUP close $DEV_NAME fail "Cannot deactivate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." echo "[OK]" echo "Bitmap error detection tests:" int_error_detection B crc32c 0 4 512 @@ -426,4 +450,35 @@ else echo "[N/A]" fi +echo -n "Fixed HMAC and legacy flags:" +if [ -n "$DM_INTEGRITY_HMAC_FIX" ] ; then + add_device + # only data HMAC + ARGS="--integrity hmac-sha256 --integrity-key-file $KEY_FILE --integrity-key-size 32" + $INTSETUP format -q $DEV --integrity-legacy-hmac --no-wipe --tag-size 32 $ARGS || fail "Cannot format device." + $INTSETUP open $DEV $DEV_NAME --integrity-recalculate $ARGS >/dev/null 2>&1 && fail "Cannot activate device." + $INTSETUP open $DEV $DEV_NAME --integrity-legacy-recalculate $ARGS || fail "Cannot activate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." + # New version - must fail (no journal HMAC) + $INTSETUP format -q $DEV --no-wipe --tag-size 32 $ARGS || fail "Cannot format device." + $INTSETUP open $DEV $DEV_NAME --integrity-recalculate $ARGS >/dev/null 2>&1 && fail "Cannot activate device." + $INTSETUP open $DEV $DEV_NAME --integrity-legacy-recalculate $ARGS || fail "Cannot activate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." + + # data and journal HMAC + ARGS="$ARGS --journal-integrity hmac-sha256 --journal-integrity-key-file $KEY_FILE2 --journal-integrity-key-size 32" + $INTSETUP format -q $DEV --integrity-legacy-hmac --no-wipe --tag-size 32 $ARGS || fail "Cannot format device." + $INTSETUP open $DEV $DEV_NAME --integrity-recalculate $ARGS >/dev/null 2>&1 && fail "Cannot activate device." + $INTSETUP open $DEV $DEV_NAME --integrity-legacy-recalculate $ARGS || fail "Cannot activate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." + # New fixed version + $INTSETUP format -q $DEV --no-wipe --tag-size 32 $ARGS || fail "Cannot format device." + $INTSETUP dump $DEV | grep "flags" | grep -q "fix_hmac" || fail "Flag for HMAC not set." + $INTSETUP open $DEV $DEV_NAME --integrity-recalculate $ARGS || fail "Cannot activate device." + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." + echo "[OK]" +else + echo "[N/A]" +fi + cleanup diff --git a/tests/loopaes-test b/tests/loopaes-test index 9c69192..5c28be3 100755 --- a/tests/loopaes-test +++ b/tests/loopaes-test @@ -91,10 +91,7 @@ function get_expsum() # $offset function check_sum() # $key $keysize $offset [stdin|keyfile] { - # Fill device with zeroes and reopen it - dd if=/dev/zero of=/dev/mapper/$DEV_NAME bs=1k $LOOP_DD_PARAM >/dev/null 2>&1 - sync - dmremove $DEV_NAME + $CRYPTSETUP close $DEV_NAME || fail EXPSUM=$(get_expsum $3) if [ "$4" == "stdin" ] ; then @@ -163,8 +160,9 @@ for key_size in $KEY_SIZES ; do 2>/dev/null [ $? -ne 0 ] && echo "[SKIPPED]" && continue check_exists + # Fill device with zeroes and reopen it + dd if=/dev/zero of=/dev/mapper/$DEV_NAME $LOOP_DD_PARAM >/dev/null 2>&1 check_sum $key $key_size $offset keyfile - $CRYPTSETUP loopaesClose $DEV_NAME || fail check_sum $key $key_size $offset stdin $CRYPTSETUP loopaesClose $DEV_NAME || fail check_sum_losetup $key AES$key_size $offset diff --git a/tests/luks2-reencryption-mangle-test b/tests/luks2-reencryption-mangle-test new file mode 100755 index 0000000..8f308f5 --- /dev/null +++ b/tests/luks2-reencryption-mangle-test @@ -0,0 +1,506 @@ +#!/bin/bash + +PS4='$LINENO:' +[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." +CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup +CRYPTSETUP_RAW=$CRYPTSETUP + +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs +IMG=reenc-mangle-data +IMG_HDR=$IMG.hdr +IMG_JSON=$IMG.json +KEY1=key1 +DEV_NAME=reenc3492834 + +FAST_PBKDF2="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" +CS_PWPARAMS="--disable-keyring --key-file $KEY1" +CS_PARAMS="-q --disable-locks $CS_PWPARAMS" +JSON_MSIZE=16384 + +function remove_mapping() +{ + [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME + rm -f $IMG $IMG_HDR $IMG_JSON $KEY1 >/dev/null 2>&1 +} + +function fail() +{ + local frame=0 + [ -n "$1" ] && echo "$1" + echo "FAILED backtrace:" + while caller $frame; do ((frame++)); done + remove_mapping + exit 2 +} + +function skip() +{ + [ -n "$1" ] && echo "$1" + remove_mapping + exit 77 +} + +function bin_check() +{ + which $1 >/dev/null 2>&1 || skip "WARNING: test require $1 binary, test skipped." +} + +function img_json_save() +{ + # FIXME: why --json-file cannot be used? + #$CRYPTSETUP luksDump --dump-json-metadata $IMG | jq -c -M | tr -d '\n' >$IMG_JSON + local LUKS2_JSON_SIZE=$(($JSON_MSIZE - 4096)) + _dd if=$IMG count=$LUKS2_JSON_SIZE skip=4096 | jq -c -M . | tr -d '\n' >$IMG_JSON +} + +function img_json_dump() +{ + img_json_save + jq . $IMG_JSON +} + +function img_hash_save() +{ + IMG_HASH=$(sha256sum $IMG | cut -d' ' -f 1) +} + +function img_hash_unchanged() +{ + local IMG_HASH2=$(sha256sum $IMG | cut -d' ' -f 1) + [ "$IMG_HASH" != "$IMG_HASH2" ] && fail "Image changed!" +} + +function img_prepare_raw() # $1 options +{ + remove_mapping + + if [ ! -e $KEY1 ]; then + dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1 + fi + + truncate -s 32M $IMG || fail + $CRYPTSETUP luksFormat $FAST_PBKDF2 $CS_PARAMS --luks2-metadata-size $JSON_MSIZE $IMG $1 || fail +} + +function img_prepare() # $1 options +{ + img_prepare_raw + # FIXME: resilience is not saved here (always none)? + $CRYPTSETUP reencrypt $IMG $CS_PARAMS -q --init-only --resilience none $1 >/dev/null 2>&1 + [ $? -ne 0 ] && skip "Reencryption unsupported, test skipped." + img_json_save + img_hash_save +} + +function _dd() +{ + dd $@ status=none conv=notrunc bs=1 +} + +# header mangle functions +function img_update_json() +{ + local LUKS2_BIN1_OFFSET=448 + local LUKS2_BIN2_OFFSET=$((LUKS2_BIN1_OFFSET + $JSON_MSIZE)) + local LUKS2_JSON_SIZE=$(($JSON_MSIZE - 4096)) + + # if present jq script, mangle JSON + if [ -n "$1" ]; then + local JSON=$(cat $IMG_JSON) + echo $JSON | jq -M -c "$1" >$IMG_JSON || fail + local JSON=$(cat $IMG_JSON) + echo $JSON | tr -d '\n' >$IMG_JSON || fail + fi + + # wipe JSON areas + _dd if=/dev/zero of=$IMG count=$LUKS2_JSON_SIZE seek=4096 + _dd if=/dev/zero of=$IMG count=$LUKS2_JSON_SIZE seek=$(($JSON_MSIZE + 4096)) + + # write JSON data + _dd if=$IMG_JSON of=$IMG count=$LUKS2_JSON_SIZE seek=4096 + _dd if=$IMG_JSON of=$IMG count=$LUKS2_JSON_SIZE seek=$(($JSON_MSIZE + 4096)) + + # erase sha256 checksums + _dd if=/dev/zero of=$IMG count=64 seek=$LUKS2_BIN1_OFFSET + _dd if=/dev/zero of=$IMG count=64 seek=$LUKS2_BIN2_OFFSET + + # calculate sha256 and write chexksums + local SUM1_HEX=$(_dd if=$IMG count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) + echo $SUM1_HEX | xxd -r -p | _dd of=$IMG seek=$LUKS2_BIN1_OFFSET count=64 || fail + + local SUM2_HEX=$(_dd if=$IMG skip=$JSON_MSIZE count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) + echo $SUM2_HEX | xxd -r -p | _dd of=$IMG seek=$LUKS2_BIN2_OFFSET count=64 || fail + + img_hash_save +} + +function img_check_ok() +{ + if [ $(id -u) == 0 ]; then + $CRYPTSETUP open $CS_PWPARAMS $IMG $DEV_NAME || fail + $CRYPTSETUP close $DEV_NAME || fail + fi + + $CRYPTSETUP repair $IMG $CS_PARAMS || fail +} + +function img_check_fail() +{ + if [ $(id -u) == 0 ]; then + $CRYPTSETUP open $CS_PWPARAMS $IMG $DEV_NAME 2>/dev/null && fail + fi + + $CRYPTSETUP repair $IMG $CS_PARAMS 2>/dev/null && fail + img_hash_unchanged +} + +function img_run_reenc_ok() +{ +local EXPECT_TIMEOUT=5 +[ -n "$VALG" ] && EXPECT_TIMEOUT=60 +# For now, we cannot run reencryption in batch mode for non-block device. Just fake the terminal here. +expect_run - >/dev/null <<EOF +proc abort {} { send_error "Timeout. "; exit 2 } +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --disable-locks --resilience none +expect timeout abort "Are you sure? (Type 'yes' in capital letters):" +send "YES\n" +expect timeout abort eof +exit +EOF +[ $? -eq 0 ] || fail "Expect script failed." +} + +function img_run_reenc_fail() +{ +local EXPECT_TIMEOUT=5 +[ -n "$VALG" ] && EXPECT_TIMEOUT=60 +# For now, we cannot run reencryption in batch mode for non-block device. Just fake the terminal here. +expect_run - >/dev/null <<EOF +proc abort {} { send_error "Timeout. "; exit 42 } +set timeout $EXPECT_TIMEOUT +eval spawn $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --disable-locks +expect timeout abort "Are you sure? (Type 'yes' in capital letters):" +send "YES\n" +expect timeout abort eof +catch wait result +exit [lindex \$result 3] +EOF +local ret=$? +[ $ret -eq 0 ] && fail "Reencryption passed (should have failed)." +[ $ret -eq 42 ] && fail "Expect script failed." +img_hash_unchanged +} + +function img_check_fail_repair_ok() +{ + if [ $(id -u) == 0 ]; then + $CRYPTSETUP open $CS_PWPARAMS $IMG $DEV_NAME 2>/dev/null && fail + fi + + img_run_reenc_fail + + # repair metadata + $CRYPTSETUP repair $IMG $CS_PARAMS || fail + + img_check_ok + img_run_reenc_ok +} + +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" + CRYPTSETUP=valgrind_run + CRYPTSETUP_RAW="./valg.sh ${CRYPTSETUP_VALGRIND}" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + +function expect_run() +{ + export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" + expect "$@" +} + +bin_check jq +bin_check sha256sum +bin_check xxd +bin_check expect + +export LANG=C + +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run + +#while false; do + +echo "[1] Reencryption with old flag is rejected" +img_prepare +img_update_json '.config.requirements.mandatory = ["online-reencryptx"]' +img_check_fail +img_update_json '.config.requirements.mandatory = ["online-reencrypt-v2"]' +img_check_ok +img_run_reenc_ok +img_check_ok + +# Simulate old reencryption with no digest (repairable) +img_prepare +img_update_json 'del(.digests."2") | .config.requirements.mandatory = ["online-reencrypt"]' +img_check_fail_repair_ok + +# This must fail for new releases +echo "[2] Old reencryption in-progress (journal)" +img_prepare +img_update_json ' + del(.digests."2") | + .keyslots."2".area.type = "journal" | + .segments = { + "0" : (.segments."0" + + {"size" : .keyslots."2".area.size} + + {"flags" : ["in-reencryption"]}), + "1" : (.segments."0" + + {"offset" : ((.segments."0".offset|tonumber) + + (.keyslots."2".area.size|tonumber))|tostring}), + "2" : .segments."1", + "3" : .segments."2" + } | + .digests."0".segments = ["1","2"] | + .digests."1".segments = ["0","3"] | + .config.requirements.mandatory = ["online-reencrypt"]' +img_check_fail_repair_ok + +echo "[3] Old reencryption in-progress (checksum)" +img_prepare +img_update_json ' + del(.digests."2") | + .keyslots."2".area.type = "checksum" | + .keyslots."2".area.hash = "sha256" | + .keyslots."2".area.sector_size = 4096 | + .segments = { + "0" : (.segments."0" + + {"size" : .keyslots."2".area.size} + + {"flags" : ["in-reencryption"]}), + "1" : (.segments."0" + + {"offset": ((.segments."0".offset|tonumber) + + (.keyslots."2".area.size|tonumber))|tostring}), + "2" : .segments."1", + "3" : .segments."2" + } | + .digests."0".segments = ["1","2"] | + .digests."1".segments = ["0","3"] | + .config.requirements.mandatory = ["online-reencrypt"]' +img_check_fail_repair_ok + +# Note: older tools cannot create this from commandline +echo "[4] Old decryption in-progress (journal)" +img_prepare +img_update_json ' + del(.digests."1") | + del(.digests."2") | + del(.keyslots."1") | + .keyslots."2".mode = "decrypt" | + .keyslots."2".area.type = "journal" | + .segments = { + "0" : { + "type" : "linear", + "offset" : .segments."0".offset, + "size" : .keyslots."2".area.size, + "flags" : ["in-reencryption"] + }, + "1" : (.segments."0" + + {"offset" : ((.segments."0".offset|tonumber) + + (.keyslots."2".area.size|tonumber))|tostring}), + "2" : .segments."1", + "3" : { + "type" : "linear", + "offset" : .segments."0".offset, + "size" : "dynamic", + "flags" : ["backup-final"] + } + } | + .digests."0".segments = ["1","2"] | + .config.requirements.mandatory = ["online-reencrypt"]' +img_check_fail_repair_ok + +echo "[5] Old decryption in-progress (checksum)" +img_prepare +img_update_json ' + del(.digests."1") | + del(.digests."2") | + del(.keyslots."1") | + .keyslots."2".mode = "decrypt" | + .keyslots."2".area.type = "checksum" | + .keyslots."2".area.hash = "sha256" | + .keyslots."2".area.sector_size = 4096 | + .segments = { + "0" : { + "type" : "linear", + "offset" : .segments."0".offset, + "size" : .keyslots."2".area.size, + "flags" : ["in-reencryption"] + }, + "1" : (.segments."0" + + {"offset" : ((.segments."0".offset|tonumber) + + (.keyslots."2".area.size|tonumber))|tostring}), + "2" : .segments."1", + "3" : { + "type" : "linear", + "offset" : .segments."0".offset, + "size" : "dynamic", + "flags" : ["backup-final"] + } + } | + .digests."0".segments = ["1","2"] | + .config.requirements.mandatory = ["online-reencrypt"]' +img_check_fail_repair_ok + +# Note - offset is set to work with the old version (with a datashift bug) +echo "[6] Old reencryption in-progress (datashift)" +img_prepare +img_update_json ' + del(.digests."2") | + .keyslots."2".direction = "backward" | + .keyslots."2".area.type = "datashift" | + .keyslots."2".area.size = "4096" | + .keyslots."2".area.shift_size = ((1 * 1024 * 1024)|tostring) | + .segments = { + "0" : (.segments."0" + + {"size" : ((13 * 1024 * 1024)|tostring)}), + "1" : (.segments."0" + + {"offset" : ((30 * 1024 * 1024)|tostring)}), + "2" : .segments."1", + "3" : (.segments."2" + + {"offset" : ((17 * 1024 * 1024)|tostring)}), + } | + .digests."0".segments = ["0","2"] | + .digests."1".segments = ["1","3"] | + .config.requirements.mandatory = ["online-reencrypt"]' +img_check_fail_repair_ok + +# +# NEW metadata (with reenc digest) +# +echo "[7] Reencryption with various mangled metadata" + +# Normal situation +img_prepare +img_run_reenc_ok +img_check_ok + +# The same in various steps. +# Repair must validate not only metadata, but also reencryption digest. +img_prepare +img_update_json 'del(.digests."2")' +img_check_fail_repair_ok + +img_prepare '--reduce-device-size 2M' +img_update_json '.keyslots."2".area.shift_size = ((.keyslots."2".area.shift_size|tonumber / 2)|tostring)' +img_check_fail + +#FIXME: cannot check with correct digest for now (--init-only does not store area type) +img_prepare +img_update_json ' + .keyslots."2".area.type = "checksum" | + .keyslots."2".area.hash = "sha256" | + .keyslots."2".area.sector_size = 4096' +img_check_fail + +img_prepare +img_update_json '.keyslots."2".area.type = "journal"' +img_check_fail + +img_prepare +img_update_json '.keyslots."2".mode = "decrypt"' +img_check_fail + +img_prepare +img_update_json '.keyslots."2".direction = "backward"' +img_check_fail + +# key_size must be 1 +img_prepare +img_update_json '.keyslots."2".key_size = 16' +img_check_fail + +# Mangling segments +img_prepare +img_update_json 'del(.segments."1")' +img_check_fail + +img_prepare +img_update_json '.segments."0".encryption = "aes-cbc-null"' +img_check_fail + +img_prepare +img_update_json '.segments."1".encryption = "aes-cbc-null"' +img_check_fail + +img_prepare +img_update_json '.segments."2".encryption = "aes-cbc-null"' +img_check_fail + +# Mangling digests +img_prepare +img_update_json ' + .digests."2" = .digests."0" | + .digests."2".keyslots = ["2"] | + .digests."2".segments = []' +img_check_fail + +img_prepare +img_update_json '.digests."2".iterations = 1111' +img_check_fail + +# Simulate correct progress +img_prepare +img_update_json ' + .segments = { + "0" : (.segments."0" + + {"size" : ((1 * 1024 * 1024)|tostring)}), + "1" : (.segments."0" + + {"offset" : ((17 * 1024 * 1024)|tostring)}), + "2" : .segments."1", + "3" : .segments."2" + } | + .digests."0".segments = ["1","2"] | + .digests."1".segments = ["0","3"]' +img_check_ok + +# Mangling keyslots + +# Set reencrypt slot to non-ignore priority +# This should be benign, just avoid noisy messages +img_prepare +img_update_json 'del(.keyslots."2".priority)' +img_check_ok + +# Flags + +# Remove mandatory reenc flag, but keep reenc metadata +img_prepare +img_update_json '.config.requirements.mandatory = []' +img_check_fail + +# Unknown segment flag, should be ignored +img_prepare +img_update_json '.segments."0".flags = ["dead-parrot"]' +img_check_ok + +echo "[8] Reencryption with AEAD is not supported" +img_prepare_raw +img_json_save +img_update_json ' + .segments."0".integrity = { + "type" : "hmac(sha256)", + "journal_encryption": "none", + "journal_integrity": "none" + }' +$CRYPTSETUP reencrypt $IMG $CS_PARAMS >/dev/null 2>&1 && fail + +remove_mapping +exit 0 diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test index e0529c9..92f223d 100755 --- a/tests/luks2-reencryption-test +++ b/tests/luks2-reencryption-test @@ -19,6 +19,7 @@ DEV_NAME2=reenc97682 IMG=reenc-data IMG_HDR=/tmp/$IMG.hdr KEY1=key1 +VKEY1=vkey1 PWD1="93R4P4pIqAH8" PWD2="1cND4319812f" PWD3="1-9Qu5Ejfnqv" @@ -96,7 +97,7 @@ function remove_mapping() [ -b /dev/mapper/$OVRDEV-err ] && dmsetup remove --retry $OVRDEV-err 2>/dev/null [ -n "$LOOPDEV" ] && losetup -d $LOOPDEV unset LOOPDEV - rm -f $IMG $IMG_HDR $KEY1 $DEVBIG >/dev/null 2>&1 + rm -f $IMG $IMG_HDR $KEY1 $VKEY1 $DEVBIG >/dev/null 2>&1 rmmod scsi_debug 2> /dev/null scsi_debug_teardown $DEV } @@ -114,6 +115,7 @@ function fail() function skip() { [ -n "$1" ] && echo "$1" + remove_mapping exit 77 } @@ -173,6 +175,11 @@ function prepare() # $1 dev1_siz dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1 fi + if [ ! -e $VKEY1 ]; then + echo -n $'\x44\xc6\x74\x4f\x41\x4e\x50\xc0\x79\xc2\x2d\x5b\x5f\x68\x84\x17' >$VKEY1 + echo -n $'\x9c\x03\xba\xbe\x4d\x0f\x9a\x75\xb3\x90\x70\x32\x0a\xf8\xae\xc4'>>$VKEY1 + fi + add_scsi_device $@ } @@ -269,7 +276,7 @@ function prepare_linear_dev() { DEV=/dev/mapper/$OVRDEV } -function get_error_offsets() # $1 devsize, $2 minimal offset, $3 sector_size [512 if ommited], $4 max offset +function get_error_offsets() # $1 devsize, $2 minimal offset, $3 sector_size [512 if omitted], $4 max offset { local _devsize=$(($1*1024*2)) local _sector_size=${3:-512} @@ -290,7 +297,7 @@ function reencrypt_recover() { # $1 sector size, $2 resilience, $3 digest, [$4 h test -z "$4" || _hdr="--header $4" error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH - echo $PWD1 | $CRYPTSETUP reencrypt $DEV $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON 2>/dev/null && fail + echo $PWD1 | $CRYPTSETUP reencrypt $DEV $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail fix_writes $OVRDEV $OLD_DEV echo $PWD1 | $CRYPTSETUP -q repair $DEV $_hdr || fail @@ -311,7 +318,7 @@ function reencrypt_recover_online() { # $1 sector size, $2 resilience, $3 digest echo $PWD1 | $CRYPTSETUP open $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 2>/dev/null && fail + 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 @@ -647,6 +654,20 @@ function reencrypt_online_fixed_size() { fi } +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 + HAVE_KEYRING=1 + else + HAVE_KEYRING=0 + 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." + $CRYPTSETUP close $DEV_NAME || fail +} + function valgrind_setup() { which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind." @@ -698,12 +719,15 @@ HASH7=18a393d1a505e22ccf3e29effe3005ea8627e4c36b7cca0e53f58121f49b67e1 # 60 MiBs of zeroes HASH8=cf5ac69ca412f9b3b1a8b8de27d368c5c05ed4b1b6aa40e6c38d9cbf23711342 +prepare dev_size_mb=32 +setup_luks2_env + echo "[1] Reencryption" echo -n "[512 sector]" -prepare dev_size_mb=32 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON 2>&1 | tail -1 | grep -q "not supported" && skip " No reenryption support, test skipped." echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON || fail check_hash $PWD1 $HASH1 echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal $FAST_PBKDF_ARGON || fail @@ -716,6 +740,8 @@ check_hash $PWD1 $HASH1 echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -c aes-xts-plain64 --init-only $FAST_PBKDF_ARGON || fail echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP reencrypt --active-name /dev/mapper/$DEV_NAME --resilience none -q || fail +XTS_KEY=$($CRYPTSETUP status $DEV_NAME | grep "keysize:" | sed 's/\( keysize: \)\([0-9]\+\)\(.*\)/\2/') +[ "$XTS_KEY" -eq "$DEF_XTS_KEY" ] || fail "xts mode has wrong key size after reencryption ($XTS_KEY != expected $DEF_XTS_KEY)" echo $PWD1 | $CRYPTSETUP close $DEV_NAME || fail echo -n "[OK][4096 sector]" prepare sector_size=4096 dev_size_mb=32 @@ -918,6 +944,17 @@ $CRYPTSETUP status $DEV_NAME >/dev/null || fail dmsetup remove --retry $DEV_NAME2 $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail +# check tool can block some funny user ideas +preparebig 64 +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c serpent-xts-plain -q $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $DEV -q 2>/dev/null && fail +open_crypt $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --active-name $DEV_NAME -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --active-name $DEV_NAME --header $DEV -q 2>/dev/null && fail +$CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail +$CRYPTSETUP close $DEV_NAME + if ! dm_delay_features; then echo "dm-delay target is missing, skipping recovery tests." remove_mapping @@ -1366,5 +1403,148 @@ echo -e "$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$ echo $PWD1 | $CRYPTSETUP reencrypt $DEV --resume-only -q 2>/dev/null && fail echo -e "$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1" | $CRYPTSETUP reencrypt $DEV -q || fail +echo "[23] Reencryption with specified new volume key" +prepare dev_size_mb=32 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 256 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -S0 $FAST_PBKDF_ARGON --master-key-file $VKEY1 -s 128 || fail +check_hash $PWD1 $HASH1 +$CRYPTSETUP luksErase -q $DEV || fail +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_ARGON --master-key-file $VKEY1 -s 128 $DEV || fail +check_hash $PWD1 $HASH1 + +echo "[24] Reencryption with initial cipher_null" +# aka custom encryption +prepare dev_size_mb=32 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c cipher_null-ecb --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -c aes-xts-plain64 -q $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 + +# online +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c cipher_null-ecb --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -c aes-xts-plain64 -q $FAST_PBKDF_ARGON || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH1 +if [ $HAVE_KEYRING -gt 0 ]; then + $CRYPTSETUP status $DEV_NAME | grep -q "key location: keyring" || fail +fi +$CRYPTSETUP close $DEV_NAME + +# simulate LUKS2 device with cipher_null in both keyslot and segment (it can be created only by up conversion from LUKS1) +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 -s 128 -c cipher_null-ecb --offset 8192 $FAST_PBKDF2 $DEV || fail +$CRYPTSETUP convert -q --type luks2 $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON >/dev/null || fail +check_hash $PWD1 $HASH1 +# both keyslot and segment cipher must not be null after reencryption with default params +$CRYPTSETUP luksDump $DEV | grep -q "cipher_null" && fail + +# multistep reencryption with initial cipher_null +preparebig 64 +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $DEV -c null --offset 16384 -q $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --hotzone-size 1M --resilience none -q $FAST_PBKDF_ARGON >/dev/null || fail +$CRYPTSETUP close $DEV_NAME +check_hash $PWD1 $HASH5 + +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $DEV -c null --offset 16384 -q $FAST_PBKDF_ARGON || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --hotzone-size 1M --resilience none -q $FAST_PBKDF_ARGON >/dev/null || fail +check_hash $PWD1 $HASH5 + +echo "[25] Reencryption recovery with cipher_null" +# (check opt-io size optimization in reencryption code does not affect recovery) +# device with opt-io size 32k +prepare_linear_dev 32 opt_blks=64 $OPT_XFERLEN_EXP +OFFSET=8192 + +echo "sector size 512->512" + +get_error_offsets 32 $OFFSET +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +check_hash $PWD1 $HASH1 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +reencrypt_recover 512 checksum $HASH1 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +reencrypt_recover 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 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + check_hash $PWD1 $HASH1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover 4096 checksum $HASH1 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + check_hash $PWD1 $HASH1 + reencrypt_recover 4096 journal $HASH1 + + echo "sector size 4096->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + check_hash $PWD1 $HASH1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover 4096 checksum $HASH1 + reencrypt_recover 4096 journal $HASH1 +fi + +echo "[26] Reencryption recovery with cipher_null (online i/o error)" + +echo "sector size 512->512" + +get_error_offsets 32 $OFFSET +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 -c null --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +check_hash $PWD1 $HASH1 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +reencrypt_recover_online 512 checksum $HASH1 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 -c null --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +reencrypt_recover_online 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 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + check_hash $PWD1 $HASH1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover_online 4096 checksum $HASH1 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + check_hash $PWD1 $HASH1 + reencrypt_recover_online 4096 journal $HASH1 + + echo "sector size 4096->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + check_hash $PWD1 $HASH1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover_online 4096 checksum $HASH1 + reencrypt_recover_online 4096 journal $HASH1 +fi + remove_mapping exit 0 diff --git a/tests/luks2-validation-test b/tests/luks2-validation-test index 52945ba..04183fb 100755 --- a/tests/luks2-validation-test +++ b/tests/luks2-validation-test @@ -199,6 +199,8 @@ RUN luks2-segment-unknown-type.img "R" "Validation rejected segment with all m RUN luks2-segment-two.img "R" "Validation rejected two valid segments" RUN luks2-segment-wrong-flags.img "F" "Failed to detect invalid flags field" RUN luks2-segment-wrong-flags-element.img "F" "Failed to detect invalid flags content" +RUN luks2-segment-wrong-backup-key-0.img "F" "Failed to detect gap in backup segments" +RUN luks2-segment-wrong-backup-key-1.img "F" "Failed to detect gap in backup segments" echo "[6] Test metadata size and keyslots size (config section)" RUN luks2-invalid-keyslots-size-c0.img "F" "Failed to detect too large keyslots_size in config section" diff --git a/tests/reencryption-compat-test b/tests/reencryption-compat-test index 263da0d..6dc85bd 100755 --- a/tests/reencryption-compat-test +++ b/tests/reencryption-compat-test @@ -352,7 +352,7 @@ echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key $FAST_PBKDF check_hash $PWD1 $HASH1 $CRYPTSETUP --type luks1 luksDump $LOOPDEV1 > /dev/null || fail -echo "[9] Test log I/Os on various underlaying block devices" +echo "[9] Test log I/Os on various underlying block devices" prepare 8192 echo $PWD2 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF $LOOPDEV1 || fail add_scsi_device sector_size=512 dev_size_mb=32 diff --git a/tests/reencryption-compat-test2 b/tests/reencryption-compat-test2 index 4ec26fa..812788a 100755 --- a/tests/reencryption-compat-test2 +++ b/tests/reencryption-compat-test2 @@ -370,7 +370,7 @@ check_hash $PWD2 $HASH5 check_slot 21 || fail "Only keyslot 21 expected to be enabled" $CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail -echo "[9] Test log I/Os on various underlaying block devices" +echo "[9] Test log I/Os on various underlying block devices" echo $PWD2 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG --offset 8192 || fail add_scsi_device sector_size=512 dev_size_mb=32 test_logging "[512 sector]" || fail diff --git a/tests/test_utils.c b/tests/test_utils.c index 0b00005..9f070e9 100644 --- a/tests/test_utils.c +++ b/tests/test_utils.c @@ -1,8 +1,8 @@ /* * cryptsetup library API test utilities * - * Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2020 Milan Broz + * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2021 Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -95,6 +95,14 @@ void check_equal(int line, const char *func, int64_t x, int64_t y) exit(-1); } +void check_ge_equal(int line, const char *func, int64_t x, int64_t y) +{ + printf("FAIL line %d [%s]: expected greater or equal values differs: %" + PRIi64 " < %" PRIi64 "\n", line, func, x, y); + _cleanup(); + exit(-1); +} + void check_null(int line, const char *func, const void *x) { if (x) { @@ -279,7 +287,14 @@ void global_log_callback(int level, const char *msg, void *usrptr) if (level <= CRYPT_LOG_DEBUG) return; - strncat(global_log, msg, sizeof(global_log) - strlen(global_log)); + len = strlen(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); global_lines++; if (level == CRYPT_LOG_ERROR) { len = strlen(msg); diff --git a/tests/unit-utils-io.c b/tests/unit-utils-io.c index ff5be52..8120842 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-2020 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2021 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 @@ -99,7 +99,7 @@ static int test_write_buffer(void) if (ret < 0) goto out; - return (size_t) ret == test_length ? 0 : -EIO; + ret = (size_t) ret == test_length ? 0 : -EIO; out: if (fd >= 0) close(fd); diff --git a/tests/valg-api.sh b/tests/valg-api.sh index e27a269..fcd59a8 100755 --- a/tests/valg-api.sh +++ b/tests/valg-api.sh @@ -5,7 +5,7 @@ MALLOC="--malloc-fill=aa" FREE="--free-fill=21" STACK="--max-stackframe=300000" EXTRAS="--read-var-info=yes --show-reachable=yes" -LOGFILE="--log-file=./valglog.$(date +%s)_${INFOSTRING}" +LOGFILE="--log-file=./valglog.$(date +%H:%M:%S:%N)_${INFOSTRING}" LEAKCHECK="--leak-check=full --track-origins=yes" exec valgrind $SUP $GETSUP $CHILD $MALLOC $FREE $STACK $EXTRAS $LOGFILE $LEAKCHECK "$@" diff --git a/tests/valg.sh b/tests/valg.sh index 3dc0784..888efcc 100755 --- a/tests/valg.sh +++ b/tests/valg.sh @@ -5,7 +5,7 @@ MALLOC="--malloc-fill=aa" FREE="--free-fill=21" STACK="--max-stackframe=2000000" EXTRAS="--read-var-info=yes --show-reachable=yes" -LOGFILE="--log-file=./valglog.$(date +%s)_${INFOSTRING}" +LOGFILE="--log-file=./valglog.$(date +%H:%M:%S:%N)_${INFOSTRING}" LEAKCHECK="--leak-check=full --track-origins=yes" exec valgrind $SUP $GETSUP $CHILD $MALLOC $FREE $STACK $EXTRAS $LOGFILE $LEAKCHECK "$@" diff --git a/tests/verity-compat-test b/tests/verity-compat-test index 4ce70f9..7f381e7 100755 --- a/tests/verity-compat-test +++ b/tests/verity-compat-test @@ -84,6 +84,30 @@ function compare_out() # $1 what, $2 expected [ $OPT != $2 ] && fail "$1 differs ($2)" } +function check_root_hash_fail() +{ + echo -n "Root hash check " + ARR=(`$VERITYSETUP format $IMG $IMG_HASH --fec-device $FEC_DEV --fec-roots 2 -h sha256`) + ROOT_HASH=${ARR[28]} + ROOT_HASH_BAD=abcdef0000000000000000000000000000000000000000000000000000000000 + + $VERITYSETUP verify $IMG $IMG_HASH $ROOT_HASH || fail + $VERITYSETUP verify $IMG $IMG_HASH $ROOT_HASH_BAD >/dev/null 2>&1 && fail + $VERITYSETUP verify $IMG $IMG_HASH $ROOT_HASH_BAD --fec-device $FEC_DEV --fec-roots 2 >/dev/null 2>&1 && fail + + $VERITYSETUP open $IMG $DEV_NAME $IMG_HASH $ROOT_HASH || fail + check_exists + dmsetup status $DEV_NAME | grep "verity V" >/dev/null || fail + $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail + + $VERITYSETUP open $IMG $DEV_NAME $IMG_HASH $ROOT_HASH_BAD >/dev/null 2>&1 || fail + check_exists + dmsetup status $DEV_NAME | grep "verity C" >/dev/null || fail + $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail + + echo "[OK]" +} + function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 offset] { if [ -z "$LOOPDEV2" ] ; then @@ -228,14 +252,20 @@ function check_fec() HASH_REPAIRED=${ARR[0]} $VERITYSETUP close $DEV_NAME - rm $1 $2 $3 $IMG_TMP > /dev/null 2>&1 if [ "$HASH_ORIG" != "$HASH_REPAIRED" ]; then - echo -n "[correction failed]" - return 1 - fi - - echo "[file was repaired][OK]" + echo -n "[kernel correction failed]" + $VERITYSETUP verify $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS >/dev/null 2>&1 && fail "Userspace verify should fail" + echo -n "[userspace verify failed]" + RET=1 + else + echo -n "[repaired in kernel]" + $VERITYSETUP verify $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS >/dev/null 2>&1 || fail "Userspace verify failed" + echo "[userspace verify][OK]" + RET=0 + fi + rm $1 $2 $3 $IMG_TMP > /dev/null 2>&1 + return $RET } function check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 CLI option, $7 status option @@ -363,6 +393,8 @@ SALT=e48da609055204e89ae53b655ca2216dd983cf3cb829f34f63a297d106d53e2d echo "Verity tests [separate devices]" prepare 8192 1024 +check_root_hash_fail + check_root_hash 512 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 $SALT 1 sha256 check_root_hash 1024 54d92778750495d1f80832b486ebd007617d746271511bbf0e295e143da2b3df $SALT 1 sha256 check_root_hash 4096 e522df0f97da4febb882ac40f30b37dc0b444bf6df418929463fa25280f09d5c $SALT 1 sha256 @@ -399,6 +431,9 @@ if check_version 1 3; then if check_version 1 4; then check_option 512 $HASH $SALT 1 sha256 "--check-at-most-once" "check_at_most_once" fi + if check_version 1 7; then + check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption" + fi fi echo "Veritysetup [hash-offset bigger than 2G works] " @@ -421,6 +456,11 @@ if check_version 1 3; then [ "$RET" -eq "3" ] && break [ "$RET" -eq "0" ] || fail "FEC repair failed" + (check_fec $IMG $IMG $IMG 512 500 50000 2457600 4915200 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'n' $SALT) || fail "FEC repair failed" + (check_fec $IMG $IMG $IMG 512 500 50000 2457600 4915200 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'y' $SALT) || fail "FEC repair failed" + (check_fec $IMG $IMG $IMG 4096 64 6250 4194304 8388608 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'n' $SALT) || fail "FEC repair failed" + (check_fec $IMG $IMG $IMG 4096 64 6250 4194304 8388608 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'y' $SALT) || fail "FEC repair failed" + (check_fec $IMG $IMG_HASH $FEC_DEV 4096 30 30 0 0 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'n' $SALT) || fail "FEC repair failed" (check_fec $IMG $IMG_HASH $FEC_DEV 4096 35 35 0 0 $(($RANDOM % 23 + 2)) $(($INDEX * 4))) || fail "FEC repair failed" (check_fec $IMG $IMG_HASH $FEC_DEV 512 2000 2000 0 0 $(($RANDOM % 23 + 2)) $(($INDEX * 4))) || fail "FEC repair failed" @@ -438,7 +478,7 @@ checkUserSpaceRepair 400 512 2 256000 0 2 50 checkUserSpaceRepair 500 512 2 2457600 4915200 1 1 checkUserSpaceRepair -1 4096 2 0 0 3 10 checkUserSpaceRepair 400 4096 2 2048000 0 2 1 -#checkUserSpaceRepair 500 4096 2 2457600 4915200 1 2 # FIXME +checkUserSpaceRepair 500 4096 2 2457600 4915200 1 2 remove_mapping exit 0 |